chart_info.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. package range_analysis
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_chart_lib/models"
  6. "eta/eta_chart_lib/models/data_manage"
  7. "eta/eta_chart_lib/services/alarm_msg"
  8. "eta/eta_chart_lib/services/data"
  9. "eta/eta_chart_lib/utils"
  10. "fmt"
  11. "github.com/shopspring/decimal"
  12. "math"
  13. "time"
  14. )
  15. // HandleDataByCalculateType 根据计算公式处理数据
  16. func HandleDataByCalculateType(originList []*models.ChartRangeAnalysisDateDataItem, calculateType int) (newList []*models.EdbDataList, err error) {
  17. if len(originList) == 0 {
  18. return
  19. }
  20. switch calculateType {
  21. case 0: //均值
  22. var sum float64
  23. for _, item := range originList {
  24. sum = 0
  25. for k, v := range item.DataList {
  26. sum += v.Value
  27. val := sum / float64(k+1)
  28. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  29. newList = append(newList, &models.EdbDataList{
  30. DataTime: v.DataTime,
  31. Value: val,
  32. DataTimestamp: v.DataTimestamp,
  33. })
  34. }
  35. }
  36. case 1: //累计值
  37. var sum float64
  38. for _, item := range originList {
  39. sum = 0
  40. for _, v := range item.DataList {
  41. sum += v.Value
  42. val := sum
  43. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  44. newList = append(newList, &models.EdbDataList{
  45. DataTime: v.DataTime,
  46. Value: val,
  47. DataTimestamp: v.DataTimestamp,
  48. })
  49. }
  50. }
  51. case 2: //涨幅
  52. for _, item := range originList {
  53. var baseVal float64
  54. for k, v := range item.DataList {
  55. if k == 0 {
  56. baseVal = v.Value
  57. if baseVal == 0 {
  58. break
  59. }
  60. }
  61. val := (v.Value - baseVal) / baseVal
  62. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  63. newList = append(newList, &models.EdbDataList{
  64. DataTime: v.DataTime,
  65. Value: val,
  66. DataTimestamp: v.DataTimestamp,
  67. })
  68. }
  69. }
  70. case 3: //复合增长率
  71. for _, item := range originList {
  72. var baseVal float64
  73. var baseDate string
  74. for k, v := range item.DataList {
  75. if k == 0 {
  76. baseVal = v.Value
  77. baseDate = v.DataTime
  78. if baseVal == 0 {
  79. break
  80. }
  81. continue
  82. }
  83. baseDateT, e := time.ParseInLocation(utils.FormatDate, baseDate, time.Local)
  84. if e != nil {
  85. err = fmt.Errorf("time.ParseInLocation err: %v", e)
  86. return
  87. }
  88. tmpT, e := time.ParseInLocation(utils.FormatDate, baseDate, time.Local)
  89. if e != nil {
  90. err = fmt.Errorf("time.ParseInLocation err: %v", e)
  91. return
  92. }
  93. // 计算两个日期相差的天数
  94. diff := tmpT.Sub(baseDateT).Hours() / 24
  95. val := v.Value / baseVal
  96. val = math.Pow(val, diff) - 1
  97. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  98. newList = append(newList, &models.EdbDataList{DataTime: v.DataTime, Value: val, DataTimestamp: v.DataTimestamp})
  99. }
  100. }
  101. case 4: //最大值
  102. var maxVal float64
  103. for _, item := range originList {
  104. for k, v := range item.DataList {
  105. if k == 0 {
  106. maxVal = v.Value
  107. }
  108. if v.Value > maxVal {
  109. maxVal = v.Value
  110. }
  111. val := maxVal
  112. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  113. newList = append(newList, &models.EdbDataList{DataTime: v.DataTime, Value: val, DataTimestamp: v.DataTimestamp})
  114. }
  115. }
  116. case 5: //最小值
  117. var minVal float64
  118. for _, item := range originList {
  119. for k, v := range item.DataList {
  120. if k == 0 {
  121. minVal = v.Value
  122. }
  123. if v.Value < minVal {
  124. minVal = v.Value
  125. }
  126. val := minVal
  127. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  128. newList = append(newList, &models.EdbDataList{DataTime: v.DataTime, Value: val, DataTimestamp: v.DataTimestamp})
  129. }
  130. }
  131. }
  132. return
  133. }
  134. // MoveDataDaysToNewDataList 平移指标数据生成新的数据序列
  135. func MoveDataDaysToNewDataList(dataList []*models.EdbDataList, moveDay int) (newDataList []models.EdbDataList, dateDataMap map[string]float64) {
  136. dateMap := make(map[time.Time]float64)
  137. var minDate, maxDate time.Time
  138. dateDataMap = make(map[string]float64)
  139. for _, v := range dataList {
  140. currDate, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  141. if minDate.IsZero() || currDate.Before(minDate) {
  142. minDate = currDate
  143. }
  144. if maxDate.IsZero() || currDate.After(maxDate) {
  145. maxDate = currDate
  146. }
  147. dateMap[currDate] = v.Value
  148. }
  149. // 处理领先、滞后数据
  150. newDateMap := make(map[time.Time]float64)
  151. for currDate, value := range dateMap {
  152. newDate := currDate.AddDate(0, 0, moveDay)
  153. newDateMap[newDate] = value
  154. }
  155. minDate = minDate.AddDate(0, 0, moveDay)
  156. maxDate = maxDate.AddDate(0, 0, moveDay)
  157. // 获取日期相差日
  158. dayNum := utils.GetTimeSubDay(minDate, maxDate)
  159. for i := 0; i <= dayNum; i++ {
  160. currDate := minDate.AddDate(0, 0, i)
  161. tmpValue, ok := newDateMap[currDate]
  162. if !ok {
  163. //找不到数据,那么就用前面的数据吧
  164. if len(newDataList)-1 < 0 {
  165. tmpValue = 0
  166. } else {
  167. tmpValue = newDataList[len(newDataList)-1].Value
  168. }
  169. }
  170. tmpData := models.EdbDataList{
  171. DataTime: currDate.Format(utils.FormatDate),
  172. Value: tmpValue,
  173. }
  174. dateDataMap[tmpData.DataTime] = tmpData.Value
  175. newDataList = append(newDataList, tmpData)
  176. }
  177. return
  178. }
  179. // GetChartEdbInfoFormat 区间计算图表-获取指标信息
  180. func GetChartEdbInfoFormat(chartInfoId int, edbInfoMappingList []*models.ChartEdbInfoMapping) (edbList []*models.ChartEdbInfoMapping, err error) {
  181. edbList = make([]*models.ChartEdbInfoMapping, 0)
  182. for _, edbInfoMapping := range edbInfoMappingList {
  183. if edbInfoMapping == nil {
  184. err = fmt.Errorf("指标信息有误")
  185. return
  186. }
  187. edbInfoMapping.FrequencyEn = data.GetFrequencyEn(edbInfoMapping.Frequency)
  188. if edbInfoMapping.Unit == `无` {
  189. edbInfoMapping.Unit = ``
  190. }
  191. if chartInfoId <= 0 {
  192. edbInfoMapping.IsAxis = 1
  193. edbInfoMapping.LeadValue = 0
  194. edbInfoMapping.LeadUnit = ""
  195. edbInfoMapping.ChartEdbMappingId = 0
  196. edbInfoMapping.ChartInfoId = 0
  197. edbInfoMapping.IsOrder = false
  198. edbInfoMapping.EdbInfoType = 1
  199. edbInfoMapping.ChartStyle = ""
  200. edbInfoMapping.ChartColor = ""
  201. edbInfoMapping.ChartWidth = 0
  202. } else {
  203. edbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(edbInfoMapping.LeadUnit)
  204. }
  205. edbList = append(edbList, edbInfoMapping)
  206. }
  207. return
  208. }
  209. // GetChartDataByEdbInfoList 区间计算图表-根据指标信息获取x轴和y轴
  210. func GetChartDataByEdbInfoList(chartInfoId int, dateType, startYear int, startDate, endDate string, edbInfoMappingList []*models.ChartEdbInfoMapping, req *models.ChartRangeAnalysisExtraConf) (edbList []*models.ChartEdbInfoMapping, xEdbIdValue []int, dataResp models.ChartRangeAnalysisDataResp, err error) {
  211. if chartInfoId > 0 && req.EdbInfoMode == 1 {
  212. edbList, xEdbIdValue, dataResp, err = GetChartDataByEdbInfoListBySeries(chartInfoId, dateType, startYear, startDate, endDate, edbInfoMappingList, req)
  213. return
  214. }
  215. for _, edbInfoMapping := range edbInfoMappingList {
  216. edbInfoMapping, err = getChartDataByEdbInfo(edbInfoMapping, req)
  217. if err != nil {
  218. return
  219. }
  220. dataList := edbInfoMapping.DataList.([]*models.EdbDataList)
  221. // 处理上下限
  222. var maxData, minData float64
  223. if len(dataList) > 0 {
  224. maxData = dataList[0].Value
  225. minData = dataList[0].Value
  226. for _, v := range dataList {
  227. if v.Value > maxData {
  228. maxData = v.Value
  229. }
  230. if v.Value < minData {
  231. minData = v.Value
  232. }
  233. }
  234. }
  235. edbInfoMapping.MaxData = maxData
  236. edbInfoMapping.MinData = minData
  237. xEdbIdValue = append(xEdbIdValue, edbInfoMapping.EdbInfoId)
  238. }
  239. //根据时间类型来筛选最终的数据
  240. yearMax := 0
  241. if dateType == utils.DateTypeNYears {
  242. for _, v := range edbInfoMappingList {
  243. dataList := v.DataList.([]*models.EdbDataList)
  244. if len(dataList) > 0 {
  245. latestDate := dataList[0].DataTime
  246. if latestDate != "" {
  247. lastDateT, tErr := time.Parse(utils.FormatDate, latestDate)
  248. if tErr != nil {
  249. err = fmt.Errorf("获取图表日期信息失败,Err:" + tErr.Error())
  250. return
  251. }
  252. if lastDateT.Year() > yearMax {
  253. yearMax = lastDateT.Year()
  254. }
  255. }
  256. }
  257. }
  258. }
  259. startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, yearMax)
  260. if startDate != "" {
  261. for k, v := range edbInfoMappingList {
  262. var maxData, minData float64
  263. dataList := v.DataList.([]*models.EdbDataList)
  264. newDataList := make([]*models.EdbDataList, 0)
  265. if len(dataList) == 0 {
  266. newDataList = dataList
  267. } else {
  268. firstFlag := true
  269. for _, d := range dataList {
  270. if endDate != "" && d.DataTime > endDate {
  271. continue
  272. }
  273. if d.DataTime < startDate {
  274. continue
  275. }
  276. newDataList = append(newDataList, d)
  277. if firstFlag {
  278. maxData = d.Value
  279. minData = d.Value
  280. firstFlag = false
  281. } else {
  282. if d.Value > maxData {
  283. maxData = d.Value
  284. }
  285. if d.Value < minData {
  286. minData = d.Value
  287. }
  288. }
  289. }
  290. }
  291. edbInfoMappingList[k].DataList = newDataList
  292. edbInfoMappingList[k].MinData = minData
  293. edbInfoMappingList[k].MaxData = maxData
  294. }
  295. }
  296. dataResp = models.ChartRangeAnalysisDataResp{ChartRangeAnalysisExtraConf: req}
  297. if req.MultipleGraphConfigId > 0 {
  298. multipleGraphConfigEdbMappingList, e := data_manage.GetMultipleGraphConfigEdbMappingListByIdAndSource(req.MultipleGraphConfigId, utils.CHART_SOURCE_RANGE_ANALYSIS)
  299. if e != nil && e.Error() != utils.ErrNoRow() {
  300. err = fmt.Errorf("获取区间计算图表, 指标信息失败, Err:" + e.Error())
  301. return
  302. }
  303. // 查询是否已经生成指标
  304. dataResp.ConfigEdbNum = len(multipleGraphConfigEdbMappingList)
  305. }
  306. edbList, err = GetChartEdbInfoFormat(chartInfoId, edbInfoMappingList)
  307. if err != nil {
  308. err = fmt.Errorf("获取区间计算图表, 完善指标信息失败, Err:" + err.Error())
  309. return
  310. }
  311. return
  312. }
  313. func GetChartDataByEdbInfoListBySeries(chartInfoId int, dateType, startYear int, startDate, endDate string, edbInfoMappingList []*models.ChartEdbInfoMapping, req *models.ChartRangeAnalysisExtraConf) (edbList []*models.ChartEdbInfoMapping, xEdbIdValue []int, dataResp models.ChartRangeAnalysisDataResp, err error) {
  314. //查询seriesId
  315. chartSeriesOb := new(data_manage.FactorEdbSeriesChartMapping)
  316. seriesMappingItem, err := chartSeriesOb.GetItemByChartInfoId(chartInfoId)
  317. if err != nil {
  318. if err.Error() == utils.ErrNoRow() {
  319. err = fmt.Errorf("图表关联关系不存在")
  320. return
  321. } else {
  322. err = fmt.Errorf("获取图表关联失败, Err: " + err.Error())
  323. return
  324. }
  325. }
  326. //根据seriesId查询数据
  327. //并把数据放到dataList中
  328. for _, edbInfoMapping := range edbInfoMappingList {
  329. dataOb := new(models.FactorEdbSeriesCalculateDataQjjs)
  330. dataList, e := dataOb.GetEdbDataList(seriesMappingItem.FactorEdbSeriesId, edbInfoMapping.EdbInfoId, startDate, endDate)
  331. if e != nil {
  332. err = e
  333. return
  334. }
  335. edbInfoMapping.DataList = dataList
  336. // 处理上下限
  337. var maxData, minData float64
  338. if len(dataList) > 0 {
  339. maxData = dataList[0].Value
  340. minData = dataList[0].Value
  341. for _, v := range dataList {
  342. if v.Value > maxData {
  343. maxData = v.Value
  344. }
  345. if v.Value < minData {
  346. minData = v.Value
  347. }
  348. }
  349. }
  350. edbInfoMapping.MaxData = maxData
  351. edbInfoMapping.MinData = minData
  352. xEdbIdValue = append(xEdbIdValue, edbInfoMapping.EdbInfoId)
  353. }
  354. yearMax := 0
  355. if dateType == utils.DateTypeNYears {
  356. for _, v := range edbInfoMappingList {
  357. dataList := v.DataList.([]*models.EdbDataList)
  358. latestDate := dataList[0].DataTime
  359. if latestDate != "" {
  360. lastDateT, tErr := time.Parse(utils.FormatDate, latestDate)
  361. if tErr != nil {
  362. err = fmt.Errorf("获取图表日期信息失败,Err:" + tErr.Error())
  363. return
  364. }
  365. if lastDateT.Year() > yearMax {
  366. yearMax = lastDateT.Year()
  367. }
  368. }
  369. }
  370. }
  371. startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, yearMax)
  372. if startDate != "" {
  373. for k, v := range edbInfoMappingList {
  374. var maxData, minData float64
  375. dataList := v.DataList.([]*models.EdbDataList)
  376. newDataList := make([]*models.EdbDataList, 0)
  377. if len(dataList) == 0 {
  378. newDataList = dataList
  379. } else {
  380. firstFlag := true
  381. for _, d := range dataList {
  382. if endDate != "" && d.DataTime > endDate {
  383. continue
  384. }
  385. if d.DataTime < startDate {
  386. continue
  387. }
  388. newDataList = append(newDataList, d)
  389. if firstFlag {
  390. maxData = d.Value
  391. minData = d.Value
  392. firstFlag = false
  393. } else {
  394. if d.Value > maxData {
  395. maxData = d.Value
  396. }
  397. if d.Value < minData {
  398. minData = d.Value
  399. }
  400. }
  401. }
  402. }
  403. edbInfoMappingList[k].DataList = newDataList
  404. edbInfoMappingList[k].MinData = minData
  405. edbInfoMappingList[k].MaxData = maxData
  406. }
  407. }
  408. dataResp = models.ChartRangeAnalysisDataResp{ChartRangeAnalysisExtraConf: req, SeriesId: seriesMappingItem.FactorEdbSeriesId}
  409. // 查询配置关联关系
  410. if req.MultipleGraphConfigId > 0 {
  411. multipleGraphConfigEdbMappingList, e := data_manage.GetMultipleGraphConfigEdbMappingListByIdAndSource(req.MultipleGraphConfigId, utils.CHART_SOURCE_RANGE_ANALYSIS)
  412. if e != nil && e.Error() != utils.ErrNoRow() {
  413. err = fmt.Errorf("获取区间计算图表, 指标信息失败, Err:" + e.Error())
  414. return
  415. }
  416. // 查询是否已经生成指标
  417. dataResp.ConfigEdbNum = len(multipleGraphConfigEdbMappingList)
  418. }
  419. edbList, err = GetChartEdbInfoFormat(chartInfoId, edbInfoMappingList)
  420. if err != nil {
  421. err = fmt.Errorf("获取区间计算图表, 完善指标信息失败, Err:" + err.Error())
  422. return
  423. }
  424. return
  425. }
  426. // getChartDataByEdbInfo 区间计算图表-根据指标信息获取x轴和y轴
  427. func getChartDataByEdbInfo(edbInfoMapping *models.ChartEdbInfoMapping, req *models.ChartRangeAnalysisExtraConf) (newEdbInfoMapping *models.ChartEdbInfoMapping, err error) {
  428. newEdbInfoMapping = edbInfoMapping
  429. // 指标的开始日期和结束日期
  430. edbStartDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfoMapping.StartDate, time.Local)
  431. //edbStartDate := edbStartDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  432. edbEndDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfoMapping.EndDate, time.Local)
  433. edbEndDate := edbEndDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  434. // 获取时间基准指标在时间区间内的值
  435. dataList := make([]*models.EdbDataList, 0)
  436. switch edbInfoMapping.EdbInfoCategoryType {
  437. case 0:
  438. dataList, err = models.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.SubSource, edbInfoMapping.EdbInfoId, "", "")
  439. case 1:
  440. _, dataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfoMapping.EdbInfoId, "", "", false)
  441. default:
  442. err = errors.New("指标base类型异常")
  443. return
  444. }
  445. dateList := make([]*models.ChartRangeAnalysisDateDataItem, 0)
  446. switch req.DateRangeType {
  447. case 0:
  448. // 智能划分得到一个开始日期,和结束日期
  449. var startDateTime, endDateTime time.Time
  450. if req.AutoDateConf.IsAutoStartDate == 0 { //固定设置
  451. startDate := req.AutoDateConf.StartDate
  452. if startDate == "" {
  453. startDate = "2020-01-01"
  454. }
  455. startDateTime, _ = time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  456. } else {
  457. startConf := req.AutoDateConf.StartDateConf
  458. startDate := ""
  459. if startConf.BaseDateType == 0 { //
  460. startDate = edbEndDate
  461. } else if startConf.BaseDateType == 1 {
  462. startDate = time.Now().Format(utils.FormatDate)
  463. }
  464. if startConf.MoveForward > 0 {
  465. startDate = GetEdbDateByMoveForward(startConf.MoveForward, dataList)
  466. }
  467. if len(startConf.DateChange) > 0 {
  468. startDate, err = HandleEdbDateChange(startDate, startConf.DateChange)
  469. if err != nil {
  470. err = fmt.Errorf("智能划分开始日期处理失败:%s", err.Error())
  471. return
  472. }
  473. }
  474. startDateTime, _ = time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  475. }
  476. if req.AutoDateConf.IsAutoEndDate == 0 { //固定设置
  477. endDate := req.AutoDateConf.EndDate
  478. if endDate == "" {
  479. err = fmt.Errorf("智能划分截止日期处理失败:请输入截止日期")
  480. return
  481. }
  482. // todo 如果截止日期比指标日期还要大,则用指标的最新日期
  483. endDateTime, _ = time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  484. } else {
  485. endConf := req.AutoDateConf.EndDateConf
  486. endDate := edbEndDate
  487. if endConf.MoveForward > 0 {
  488. endDate = GetEdbDateByMoveForward(endConf.MoveForward, dataList)
  489. }
  490. if len(endConf.DateChange) > 0 {
  491. endDate, err = HandleEdbDateChange(endDate, endConf.DateChange)
  492. if err != nil {
  493. err = fmt.Errorf("智能划分结束日期处理失败:%s", err.Error())
  494. return
  495. }
  496. }
  497. endDateTime, _ = time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  498. }
  499. dateList = append(dateList, &models.ChartRangeAnalysisDateDataItem{
  500. StartDate: startDateTime,
  501. EndDate: endDateTime})
  502. case 1:
  503. // 手工划分得到多个开始日期和结束日期(已排序)
  504. for _, v := range req.ManualDateConf {
  505. startDateT, _ := time.ParseInLocation(utils.FormatDate, v.StartDate, time.Local)
  506. endDateT, _ := time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
  507. tmp := &models.ChartRangeAnalysisDateDataItem{
  508. StartDate: startDateT,
  509. EndDate: endDateT,
  510. }
  511. dateList = append(dateList, tmp)
  512. }
  513. case 2:
  514. // 跨年划分得到多个开始日期和结束日期
  515. startYear := edbStartDateTime.Year()
  516. endYear := edbEndDateTime.Year()
  517. startDay := req.YearDateConf.StartDay
  518. endDay := req.YearDateConf.EndDay
  519. for year := startYear; year <= endYear; year++ {
  520. startDate := fmt.Sprintf("%d-%s", year, startDay)
  521. endDate := fmt.Sprintf("%d-%s", year+1, endDay)
  522. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  523. endDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  524. if startDateTime.Before(edbStartDateTime) {
  525. break
  526. }
  527. tmp := &models.ChartRangeAnalysisDateDataItem{
  528. StartDate: startDateTime,
  529. EndDate: endDateTime,
  530. }
  531. dateList = append(dateList, tmp)
  532. }
  533. }
  534. // 根据日期,获取数据
  535. for _, v := range dateList {
  536. for _, vv := range dataList {
  537. dataTimeT, _ := time.ParseInLocation(utils.FormatDate, vv.DataTime, time.Local)
  538. if dataTimeT.After(v.StartDate) && dataTimeT.Before(v.EndDate) ||
  539. dataTimeT.Equal(v.StartDate) ||
  540. dataTimeT.Equal(v.EndDate) {
  541. v.DataList = append(v.DataList, vv)
  542. }
  543. }
  544. }
  545. // 根据时间区间类型来获取数据的计算窗口,然后再拼接成整段数据
  546. newDataList, err := HandleDataByCalculateType(dateList, req.CalculateType)
  547. if err != nil {
  548. return
  549. }
  550. if req.UnNormalDataDealType > 0 {
  551. switch req.UnNormalDataDealType { //0:不处理,1:剔除,2替换
  552. case 1:
  553. dealDataList := make([]*models.EdbDataList, 0)
  554. for _, v := range newDataList {
  555. if !utils.CompareFloatByOpStrings(req.UnNormalDataConf.Formula, v.Value, req.UnNormalDataConf.Value) {
  556. dealDataList = append(dealDataList, v)
  557. }
  558. }
  559. case 2:
  560. for i, v := range newDataList {
  561. if utils.CompareFloatByOpStrings(req.UnNormalDataConf.Formula, v.Value, req.UnNormalDataConf.Value) {
  562. newDataList[i].Value = req.UnNormalDataConf.ReplaceValue
  563. }
  564. }
  565. }
  566. }
  567. if req.DataConvertType > 0 {
  568. // 数据转换类型 0不转, 1乘 2除 3对数
  569. switch req.DataConvertType {
  570. case 1:
  571. for i, v := range newDataList {
  572. val := v.Value * req.DataConvertConf.Value
  573. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  574. newDataList[i].Value = val
  575. }
  576. //item.MaxData = item.MaxData * v.ConvertValue
  577. //item.MinData = item.MinData * v.ConvertValue
  578. case 2:
  579. for i, v := range newDataList {
  580. val := v.Value / req.DataConvertConf.Value
  581. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  582. newDataList[i].Value = val
  583. }
  584. //item.MaxData = item.MaxData / v.ConvertValue
  585. //item.MinData = item.MinData / v.ConvertValue
  586. case 3:
  587. for i, v := range newDataList {
  588. if v.Value <= 0 {
  589. err = errors.New("数据中含有负数或0,无法对数运算")
  590. return
  591. }
  592. val := math.Log(v.Value) / math.Log(req.DataConvertConf.Value)
  593. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  594. newDataList[i].Value = val
  595. }
  596. //item.MaxData = math.Log(item.MaxData) / math.Log(v.ConvertValue)
  597. //item.MinData = math.Log(item.MinData) / math.Log(v.ConvertValue)
  598. }
  599. }
  600. newEdbInfoMapping.DataList = newDataList
  601. //时间处理
  602. return
  603. }
  604. // RollingCorrelationChartDataResp 滚动区间计算图表数据
  605. type RollingCorrelationChartDataResp struct {
  606. MaxData float64
  607. MinData float64
  608. LatestDate string `description:"真实数据的最后日期"`
  609. EdbInfoCategoryType int
  610. ChartColor string
  611. ChartStyle string
  612. PredictChartColor string
  613. ChartType int
  614. ChartWidth int
  615. EdbName string
  616. EdbNameEn string
  617. Unit string
  618. UnitEn string
  619. IsAxis int
  620. DataList []models.EdbDataList
  621. }
  622. // ChartInfoRefresh 图表刷新
  623. func ChartInfoRefresh(chartInfoId int, uniqueCode string) (isAsync bool, err error) {
  624. var errMsg string
  625. defer func() {
  626. if err != nil {
  627. tips := fmt.Sprintf("CorrelationChartInfoRefresh: %s", errMsg)
  628. utils.FileLog.Info(tips)
  629. go alarm_msg.SendAlarmMsg(tips, 3)
  630. }
  631. }()
  632. var chartInfo *models.ChartInfo
  633. if chartInfoId > 0 {
  634. chartInfo, err = models.GetChartInfoById(chartInfoId)
  635. if err != nil {
  636. if err.Error() == utils.ErrNoRow() {
  637. errMsg = "图表已被删除,请刷新页面"
  638. err = errors.New(errMsg)
  639. return
  640. }
  641. errMsg = "获取图表信息失败"
  642. err = errors.New("获取图表信息失败,Err:" + err.Error())
  643. return
  644. }
  645. } else {
  646. chartInfo, err = models.GetChartInfoByUniqueCode(uniqueCode)
  647. if err != nil {
  648. if err.Error() == utils.ErrNoRow() {
  649. errMsg = "图表已被删除,请刷新页面"
  650. err = errors.New(errMsg)
  651. return
  652. }
  653. errMsg = "获取图表信息失败"
  654. err = errors.New("获取图表信息失败,Err:" + err.Error())
  655. return
  656. }
  657. }
  658. // 1.刷新图表关联的指标
  659. mappings, e := data_manage.GetChartEdbMappingList(chartInfoId)
  660. if e != nil {
  661. utils.FileLog.Info(fmt.Sprintf("获取图表关联指标失败, err: %v", e))
  662. return
  663. }
  664. if len(mappings) == 0 {
  665. utils.FileLog.Info("图表无关联指标")
  666. return
  667. }
  668. var edbIds []int
  669. for _, v := range mappings {
  670. edbIds = append(edbIds, v.EdbInfoId)
  671. }
  672. if e, _ = data.EdbInfoRefreshAllFromBase(edbIds, false); e != nil {
  673. utils.FileLog.Info(fmt.Sprintf("批量刷新指标失败, err: %v", e))
  674. return
  675. }
  676. // todo 重新计算
  677. // 区间计算图表配置校验
  678. var extraConfig models.ChartRangeAnalysisExtraConf
  679. err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &extraConfig)
  680. if err != nil {
  681. errMsg = "配置信息错误"
  682. err = errors.New(errMsg + ", Err: " + err.Error())
  683. return
  684. }
  685. chartSeriesOb := new(data_manage.FactorEdbSeriesChartMapping)
  686. seriesMappingItem, err := chartSeriesOb.GetItemByChartInfoId(chartInfo.ChartInfoId)
  687. if err != nil {
  688. if err.Error() == utils.ErrNoRow() {
  689. err = nil
  690. } else {
  691. err = fmt.Errorf("获取图表关联失败, Err: " + err.Error())
  692. return
  693. }
  694. } else {
  695. _, e = FactorEdbStepCalculateRange(seriesMappingItem.FactorEdbSeriesId, edbIds, extraConfig, true)
  696. if e != nil {
  697. err = fmt.Errorf("计算因子指标失败, Err: " + e.Error())
  698. return
  699. }
  700. }
  701. // 4.清除图表缓存
  702. key := utils.HZ_CHART_LIB_DETAIL + uniqueCode
  703. _ = utils.Rc.Delete(key)
  704. return
  705. }
  706. func GetEdbDateByMoveForward(moveForward int, edbDataList []*models.EdbDataList) (date string) {
  707. moveForward = 0
  708. // 根据日期进行排序
  709. index := len(edbDataList) - 1 - moveForward
  710. for k, v := range edbDataList {
  711. if k == index {
  712. date = v.DataTime
  713. return
  714. }
  715. }
  716. return
  717. }
  718. // HandleEdbDateChange 处理日期变换
  719. func HandleEdbDateChange(date string, dateChange []*models.EdbDateConfDateChange) (newDate string, err error) {
  720. newDate = date
  721. if newDate != "" {
  722. if len(dateChange) > 0 {
  723. var dateTime time.Time
  724. dateTime, err = time.ParseInLocation(utils.FormatDate, newDate, time.Local)
  725. if err != nil {
  726. err = fmt.Errorf("日期解析失败: %s", err.Error())
  727. return
  728. }
  729. for _, v := range dateChange {
  730. if v.ChangeType == 1 {
  731. dateTime = dateTime.AddDate(v.Year, v.Month, v.Day)
  732. newDate = dateTime.Format(utils.FormatDate)
  733. } else if v.ChangeType == 2 {
  734. newDate, err, _ = utils.HandleSystemAppointDateT(dateTime, v.FrequencyDay, v.Frequency)
  735. if err != nil {
  736. return
  737. }
  738. dateTime, err = time.ParseInLocation(utils.FormatDate, newDate, time.Local)
  739. if err != nil {
  740. err = fmt.Errorf("日期解析失败: %s", err.Error())
  741. return
  742. }
  743. }
  744. }
  745. }
  746. }
  747. return
  748. }
  749. // FactorEdbStepCalculateRange 因子指标-区间计算
  750. func FactorEdbStepCalculateRange(seriesId int, edbArr []int, extraConf models.ChartRangeAnalysisExtraConf, recalculate bool) (calculateResp data_manage.FactorEdbSeriesStepCalculateResp, err error) {
  751. // todo 如果指标已保存,则用指标数据还是图表指标数据?
  752. // 获取图表x轴y轴
  753. defer func() {
  754. if err != nil {
  755. tips := fmt.Sprintf("StepCalculate计算失败, ErrMsg: %v", err)
  756. fmt.Println(tips)
  757. utils.FileLog.Info(tips)
  758. go alarm_msg.SendAlarmMsg(tips, 3)
  759. }
  760. /*if len(calculateResp.Fail) > 0 {
  761. tips := "StepCalculate计算失败, ErrMsg: "
  762. for _, f := range calculateResp.Fail {
  763. tips += fmt.Sprintf("code: %s, err: %s\n", f.EdbCode, f.ErrMsg)
  764. }
  765. fmt.Println(tips)
  766. utils.FileLog.Info(tips)
  767. go alarm_msg.SendAlarmMsg(tips, 2)
  768. }*/
  769. }()
  770. edbInfoMappingList, e := models.GetChartEdbMappingListByEdbInfoIdList(edbArr)
  771. if e != nil {
  772. err = fmt.Errorf("获取区间计算图表, A指标mapping信息失败, Err:%v", e)
  773. return
  774. }
  775. _, _, _, err = GetChartDataByEdbInfoList(0, 0, 0, "", "", edbInfoMappingList, &extraConf)
  776. if err != nil {
  777. err = fmt.Errorf("获取图表数据失败, ErrMsg: %v", err)
  778. return
  779. }
  780. // 重新计算-先清除原数据
  781. calculateDataOb := new(models.FactorEdbSeriesCalculateDataQjjs)
  782. cond := fmt.Sprintf("%s = ?", calculateDataOb.Cols().FactorEdbSeriesId)
  783. pars := make([]interface{}, 0)
  784. pars = append(pars, seriesId)
  785. if e := calculateDataOb.RemoveByCondition(cond, pars); e != nil {
  786. err = fmt.Errorf("清除原数据失败, err: %v", e)
  787. return
  788. }
  789. // 计算成功的保存结果
  790. dataArr := make([]*models.FactorEdbSeriesCalculateDataQjjs, 0)
  791. for _, v := range edbInfoMappingList {
  792. dataList := v.DataList.([]*models.EdbDataList)
  793. for _, dataItem := range dataList {
  794. dataTime, _ := time.ParseInLocation(utils.FormatDate, dataItem.DataTime, time.Local)
  795. dataArr = append(dataArr, &models.FactorEdbSeriesCalculateDataQjjs{
  796. FactorEdbSeriesId: seriesId,
  797. EdbInfoId: v.EdbInfoId,
  798. EdbCode: v.EdbCode,
  799. DataTime: dataTime,
  800. Value: dataItem.Value,
  801. CreateTime: time.Now().Local(),
  802. ModifyTime: time.Now().Local(),
  803. DataTimestamp: dataItem.DataTimestamp,
  804. })
  805. }
  806. }
  807. if len(dataArr) == 0 {
  808. err = fmt.Errorf("计算结果无数据, seriesId: %d", seriesId)
  809. return
  810. }
  811. if e = calculateDataOb.CreateMulti(dataArr); e != nil {
  812. err = fmt.Errorf("保存计算结果失败, seriesId: %d, err: %v, ", seriesId, e)
  813. return
  814. }
  815. return
  816. }