chart_info.go 33 KB

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