chart_info.go 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  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 {
  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 {
  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 {
  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 {
  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 {
  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 {
  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. dataList := edbInfoMapping.DataList.([]*models.EdbDataList)
  395. // 处理上下限
  396. var maxData, minData float64
  397. if len(dataList) > 0 {
  398. maxData = dataList[0].Value
  399. minData = dataList[0].Value
  400. for _, v := range dataList {
  401. if v.Value > maxData {
  402. maxData = v.Value
  403. }
  404. if v.Value < minData {
  405. minData = v.Value
  406. }
  407. }
  408. }
  409. edbInfoMapping.MaxData = maxData
  410. edbInfoMapping.MinData = minData
  411. xEdbIdValue = append(xEdbIdValue, edbInfoMapping.EdbInfoId)
  412. }
  413. //根据时间类型来筛选最终的数据
  414. yearMax := 0
  415. if dateType == utils.DateTypeNYears {
  416. for _, v := range edbInfoMappingList {
  417. dataList := v.DataList.([]*models.EdbDataList)
  418. if len(dataList) > 0 {
  419. latestDate := dataList[0].DataTime
  420. if latestDate != "" {
  421. lastDateT, tErr := time.Parse(utils.FormatDate, latestDate)
  422. if tErr != nil {
  423. err = fmt.Errorf("获取图表日期信息失败,Err:" + tErr.Error())
  424. return
  425. }
  426. if lastDateT.Year() > yearMax {
  427. yearMax = lastDateT.Year()
  428. }
  429. }
  430. }
  431. }
  432. }
  433. startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, yearMax)
  434. if startDate != "" {
  435. for k, v := range edbInfoMappingList {
  436. var maxData, minData float64
  437. dataList := v.DataList.([]*models.EdbDataList)
  438. newDataList := make([]*models.EdbDataList, 0)
  439. if len(dataList) == 0 {
  440. newDataList = dataList
  441. } else {
  442. firstFlag := true
  443. for _, d := range dataList {
  444. if endDate != "" && d.DataTime > endDate {
  445. continue
  446. }
  447. if d.DataTime < startDate {
  448. continue
  449. }
  450. newDataList = append(newDataList, d)
  451. if firstFlag {
  452. maxData = d.Value
  453. minData = d.Value
  454. firstFlag = false
  455. } else {
  456. if d.Value > maxData {
  457. maxData = d.Value
  458. }
  459. if d.Value < minData {
  460. minData = d.Value
  461. }
  462. }
  463. }
  464. }
  465. edbInfoMappingList[k].DataList = newDataList
  466. edbInfoMappingList[k].MinData = minData
  467. edbInfoMappingList[k].MaxData = maxData
  468. }
  469. }
  470. dataResp = models.ChartRangeAnalysisDataResp{ChartRangeAnalysisExtraConf: req}
  471. if req.MultipleGraphConfigId > 0 {
  472. multipleGraphConfigEdbMappingList, e := data_manage.GetMultipleGraphConfigEdbMappingListByIdAndSource(req.MultipleGraphConfigId, utils.CHART_SOURCE_RANGE_ANALYSIS)
  473. if e != nil && e.Error() != utils.ErrNoRow() {
  474. err = fmt.Errorf("获取区间计算图表, 指标信息失败, Err:" + e.Error())
  475. return
  476. }
  477. // 查询是否已经生成指标
  478. dataResp.ConfigEdbNum = len(multipleGraphConfigEdbMappingList)
  479. }
  480. edbList, err = GetChartEdbInfoFormat(chartInfoId, edbInfoMappingList)
  481. if err != nil {
  482. err = fmt.Errorf("获取区间计算图表, 完善指标信息失败, Err:" + err.Error())
  483. return
  484. }
  485. return
  486. }
  487. 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) {
  488. //查询seriesId
  489. chartSeriesOb := new(data_manage.FactorEdbSeriesChartMapping)
  490. seriesMappingItem, err := chartSeriesOb.GetItemByChartInfoId(chartInfoId)
  491. if err != nil {
  492. if err.Error() == utils.ErrNoRow() {
  493. err = fmt.Errorf("图表关联关系不存在")
  494. return
  495. } else {
  496. err = fmt.Errorf("获取图表关联失败, Err: " + err.Error())
  497. return
  498. }
  499. }
  500. //根据seriesId查询数据
  501. //并把数据放到dataList中
  502. for _, edbInfoMapping := range edbInfoMappingList {
  503. dataOb := new(models.FactorEdbSeriesCalculateDataQjjs)
  504. dataList, e := dataOb.GetEdbDataList(seriesMappingItem.FactorEdbSeriesId, edbInfoMapping.EdbInfoId, startDate, endDate)
  505. if e != nil {
  506. err = e
  507. return
  508. }
  509. edbInfoMapping.DataList = dataList
  510. // 处理上下限
  511. var maxData, minData float64
  512. if len(dataList) > 0 {
  513. maxData = dataList[0].Value
  514. minData = dataList[0].Value
  515. for _, v := range dataList {
  516. if v.Value > maxData {
  517. maxData = v.Value
  518. }
  519. if v.Value < minData {
  520. minData = v.Value
  521. }
  522. }
  523. }
  524. edbInfoMapping.MaxData = maxData
  525. edbInfoMapping.MinData = minData
  526. xEdbIdValue = append(xEdbIdValue, edbInfoMapping.EdbInfoId)
  527. }
  528. yearMax := 0
  529. if dateType == utils.DateTypeNYears {
  530. for _, v := range edbInfoMappingList {
  531. dataList := v.DataList.([]*models.EdbDataList)
  532. latestDate := dataList[0].DataTime
  533. if latestDate != "" {
  534. lastDateT, tErr := time.Parse(utils.FormatDate, latestDate)
  535. if tErr != nil {
  536. err = fmt.Errorf("获取图表日期信息失败,Err:" + tErr.Error())
  537. return
  538. }
  539. if lastDateT.Year() > yearMax {
  540. yearMax = lastDateT.Year()
  541. }
  542. }
  543. }
  544. }
  545. startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, yearMax)
  546. if startDate != "" {
  547. for k, v := range edbInfoMappingList {
  548. var maxData, minData float64
  549. dataList := v.DataList.([]*models.EdbDataList)
  550. newDataList := make([]*models.EdbDataList, 0)
  551. if len(dataList) == 0 {
  552. newDataList = dataList
  553. } else {
  554. firstFlag := true
  555. for _, d := range dataList {
  556. if endDate != "" && d.DataTime > endDate {
  557. continue
  558. }
  559. if d.DataTime < startDate {
  560. continue
  561. }
  562. newDataList = append(newDataList, d)
  563. if firstFlag {
  564. maxData = d.Value
  565. minData = d.Value
  566. firstFlag = false
  567. } else {
  568. if d.Value > maxData {
  569. maxData = d.Value
  570. }
  571. if d.Value < minData {
  572. minData = d.Value
  573. }
  574. }
  575. }
  576. }
  577. edbInfoMappingList[k].DataList = newDataList
  578. edbInfoMappingList[k].MinData = minData
  579. edbInfoMappingList[k].MaxData = maxData
  580. }
  581. }
  582. dataResp = models.ChartRangeAnalysisDataResp{ChartRangeAnalysisExtraConf: req, SeriesId: seriesMappingItem.FactorEdbSeriesId}
  583. // 查询配置关联关系
  584. if req.MultipleGraphConfigId > 0 {
  585. multipleGraphConfigEdbMappingList, e := data_manage.GetMultipleGraphConfigEdbMappingListByIdAndSource(req.MultipleGraphConfigId, utils.CHART_SOURCE_RANGE_ANALYSIS)
  586. if e != nil && e.Error() != utils.ErrNoRow() {
  587. err = fmt.Errorf("获取区间计算图表, 指标信息失败, Err:" + e.Error())
  588. return
  589. }
  590. // 查询是否已经生成指标
  591. dataResp.ConfigEdbNum = len(multipleGraphConfigEdbMappingList)
  592. }
  593. edbList, err = GetChartEdbInfoFormat(chartInfoId, edbInfoMappingList)
  594. if err != nil {
  595. err = fmt.Errorf("获取区间计算图表, 完善指标信息失败, Err:" + err.Error())
  596. return
  597. }
  598. return
  599. }
  600. // getChartDataByEdbInfo 区间计算图表-根据指标信息获取x轴和y轴
  601. func getChartDataByEdbInfo(edbInfoMapping *models.ChartEdbInfoMapping, req *models.ChartRangeAnalysisExtraConf) (newEdbInfoMapping *models.ChartEdbInfoMapping, err error) {
  602. newEdbInfoMapping = edbInfoMapping
  603. // 指标的开始日期和结束日期
  604. edbStartDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfoMapping.StartDate, time.Local)
  605. //edbStartDate := edbStartDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  606. edbEndDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfoMapping.EndDate, time.Local)
  607. edbEndDate := edbEndDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
  608. // 获取时间基准指标在时间区间内的值
  609. dataListTmp := make([]*models.EdbDataList, 0)
  610. switch edbInfoMapping.EdbInfoCategoryType {
  611. case 0:
  612. dataListTmp, err = models.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.SubSource, edbInfoMapping.EdbInfoId, "", "")
  613. case 1:
  614. _, dataListTmp, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfoMapping.EdbInfoId, "", "", false)
  615. default:
  616. err = errors.New("指标base类型异常")
  617. return
  618. }
  619. var dataList models.SortEdbDataList
  620. dataList = dataListTmp
  621. sort.Sort(dataList)
  622. dateList := make([]*models.ChartRangeAnalysisDateDataItem, 0)
  623. switch req.DateRangeType {
  624. case 0:
  625. // 智能划分得到一个开始日期,和结束日期
  626. var startDateTime, endDateTime time.Time
  627. startDateTime = edbStartDateTime
  628. if req.AutoDateConf.IsAutoEndDate == 0 { //固定设置
  629. endDate := req.AutoDateConf.EndDate
  630. if endDate == "" {
  631. err = fmt.Errorf("智能划分截止日期处理失败:请输入截止日期")
  632. return
  633. }
  634. // todo 如果截止日期比指标日期还要大,则用指标的最新日期
  635. endDateTime, _ = time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  636. } else {
  637. endConf := req.AutoDateConf.EndDateConf
  638. endDate := edbEndDate
  639. if endConf.MoveForward > 0 {
  640. endDate = GetEdbDateByMoveForward(endDate, endConf.MoveForward, dataList)
  641. }
  642. if len(endConf.DateChange) > 0 {
  643. endDate, err = HandleEdbDateChange(endDate, endConf.DateChange)
  644. if err != nil {
  645. err = fmt.Errorf("智能划分结束日期处理失败:%s", err.Error())
  646. return
  647. }
  648. }
  649. endDateTime, _ = time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  650. }
  651. dateList = append(dateList, &models.ChartRangeAnalysisDateDataItem{
  652. StartDate: startDateTime,
  653. EndDate: endDateTime})
  654. case 1:
  655. // 手工划分得到多个开始日期和结束日期(已排序)
  656. for _, v := range req.ManualDateConf {
  657. startDateT, _ := time.ParseInLocation(utils.FormatDate, v.StartDate, time.Local)
  658. endDateT, _ := time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
  659. tmp := &models.ChartRangeAnalysisDateDataItem{
  660. StartDate: startDateT,
  661. EndDate: endDateT,
  662. }
  663. dateList = append(dateList, tmp)
  664. }
  665. case 2:
  666. // 跨年划分得到多个开始日期和结束日期
  667. startYear := edbStartDateTime.Year()
  668. endYear := edbEndDateTime.Year()
  669. startDay := req.YearDateConf.StartDay
  670. endDay := req.YearDateConf.EndDay
  671. for year := startYear; year <= endYear; year++ {
  672. startDate := fmt.Sprintf("%d-%s", year, startDay)
  673. endDate := fmt.Sprintf("%d-%s", year+1, endDay)
  674. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  675. endDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  676. if startDateTime.Before(edbStartDateTime) {
  677. break
  678. }
  679. tmp := &models.ChartRangeAnalysisDateDataItem{
  680. StartDate: startDateTime,
  681. EndDate: endDateTime,
  682. }
  683. dateList = append(dateList, tmp)
  684. }
  685. }
  686. // 根据日期,获取数据
  687. for _, v := range dateList {
  688. for _, vv := range dataList {
  689. dataTimeT, _ := time.ParseInLocation(utils.FormatDate, vv.DataTime, time.Local)
  690. if dataTimeT.After(v.StartDate) && dataTimeT.Before(v.EndDate) ||
  691. dataTimeT.Equal(v.StartDate) ||
  692. dataTimeT.Equal(v.EndDate) {
  693. v.DataList = append(v.DataList, vv)
  694. }
  695. }
  696. }
  697. // 根据时间区间类型来获取数据的计算窗口,然后再拼接成整段数据
  698. newDataList, err := HandleDataByCalculateType(dateList, dataList, req)
  699. if err != nil {
  700. return
  701. }
  702. if req.UnNormalDataDealType > 0 {
  703. switch req.UnNormalDataDealType { //0:不处理,1:剔除,2替换
  704. case 1:
  705. dealDataList := make([]*models.EdbDataList, 0)
  706. for _, v := range newDataList {
  707. if !utils.CompareFloatByOpStrings(req.UnNormalDataConf.Formula, v.Value, req.UnNormalDataConf.Value) {
  708. dealDataList = append(dealDataList, v)
  709. }
  710. }
  711. case 2:
  712. for i, v := range newDataList {
  713. if utils.CompareFloatByOpStrings(req.UnNormalDataConf.Formula, v.Value, req.UnNormalDataConf.Value) {
  714. newDataList[i].Value = req.UnNormalDataConf.ReplaceValue
  715. }
  716. }
  717. }
  718. }
  719. if req.DataConvertType > 0 {
  720. // 数据转换类型 0不转, 1乘 2除 3对数
  721. switch req.DataConvertType {
  722. case 1:
  723. for i, v := range newDataList {
  724. val := v.Value * req.DataConvertConf.Value
  725. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  726. newDataList[i].Value = val
  727. }
  728. //item.MaxData = item.MaxData * v.ConvertValue
  729. //item.MinData = item.MinData * v.ConvertValue
  730. case 2:
  731. for i, v := range newDataList {
  732. val := v.Value / req.DataConvertConf.Value
  733. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  734. newDataList[i].Value = val
  735. }
  736. //item.MaxData = item.MaxData / v.ConvertValue
  737. //item.MinData = item.MinData / v.ConvertValue
  738. case 3:
  739. for i, v := range newDataList {
  740. if v.Value <= 0 {
  741. err = errors.New("数据中含有负数或0,无法对数运算")
  742. return
  743. }
  744. val := math.Log(v.Value) / math.Log(req.DataConvertConf.Value)
  745. val, _ = decimal.NewFromFloat(val).Round(4).Float64()
  746. newDataList[i].Value = val
  747. }
  748. //item.MaxData = math.Log(item.MaxData) / math.Log(v.ConvertValue)
  749. //item.MinData = math.Log(item.MinData) / math.Log(v.ConvertValue)
  750. }
  751. }
  752. newEdbInfoMapping.DataList = newDataList
  753. //时间处理
  754. return
  755. }
  756. // RollingCorrelationChartDataResp 滚动区间计算图表数据
  757. type RollingCorrelationChartDataResp struct {
  758. MaxData float64
  759. MinData float64
  760. LatestDate string `description:"真实数据的最后日期"`
  761. EdbInfoCategoryType int
  762. ChartColor string
  763. ChartStyle string
  764. PredictChartColor string
  765. ChartType int
  766. ChartWidth int
  767. EdbName string
  768. EdbNameEn string
  769. Unit string
  770. UnitEn string
  771. IsAxis int
  772. DataList []models.EdbDataList
  773. }
  774. // ChartInfoRefresh 图表刷新
  775. func ChartInfoRefresh(chartInfoId int, uniqueCode string) (isAsync bool, err error) {
  776. var errMsg string
  777. defer func() {
  778. if err != nil {
  779. tips := fmt.Sprintf("CorrelationChartInfoRefresh: %s", errMsg)
  780. utils.FileLog.Info(tips)
  781. go alarm_msg.SendAlarmMsg(tips, 3)
  782. }
  783. }()
  784. var chartInfo *models.ChartInfo
  785. if chartInfoId > 0 {
  786. chartInfo, err = models.GetChartInfoById(chartInfoId)
  787. if err != nil {
  788. if err.Error() == utils.ErrNoRow() {
  789. errMsg = "图表已被删除,请刷新页面"
  790. err = errors.New(errMsg)
  791. return
  792. }
  793. errMsg = "获取图表信息失败"
  794. err = errors.New("获取图表信息失败,Err:" + err.Error())
  795. return
  796. }
  797. } else {
  798. chartInfo, err = models.GetChartInfoByUniqueCode(uniqueCode)
  799. if err != nil {
  800. if err.Error() == utils.ErrNoRow() {
  801. errMsg = "图表已被删除,请刷新页面"
  802. err = errors.New(errMsg)
  803. return
  804. }
  805. errMsg = "获取图表信息失败"
  806. err = errors.New("获取图表信息失败,Err:" + err.Error())
  807. return
  808. }
  809. }
  810. // 1.刷新图表关联的指标
  811. mappings, e := data_manage.GetChartEdbMappingList(chartInfoId)
  812. if e != nil {
  813. utils.FileLog.Info(fmt.Sprintf("获取图表关联指标失败, err: %v", e))
  814. return
  815. }
  816. if len(mappings) == 0 {
  817. utils.FileLog.Info("图表无关联指标")
  818. return
  819. }
  820. var edbIds []int
  821. for _, v := range mappings {
  822. edbIds = append(edbIds, v.EdbInfoId)
  823. }
  824. if e, _ = data.EdbInfoRefreshAllFromBase(edbIds, false); e != nil {
  825. utils.FileLog.Info(fmt.Sprintf("批量刷新指标失败, err: %v", e))
  826. return
  827. }
  828. // todo 重新计算
  829. // 区间计算图表配置校验
  830. var extraConfig models.ChartRangeAnalysisExtraConf
  831. err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &extraConfig)
  832. if err != nil {
  833. errMsg = "配置信息错误"
  834. err = errors.New(errMsg + ", Err: " + err.Error())
  835. return
  836. }
  837. chartSeriesOb := new(data_manage.FactorEdbSeriesChartMapping)
  838. seriesMappingItem, err := chartSeriesOb.GetItemByChartInfoId(chartInfo.ChartInfoId)
  839. if err != nil {
  840. if err.Error() == utils.ErrNoRow() {
  841. err = nil
  842. } else {
  843. err = fmt.Errorf("获取图表关联失败, Err: " + err.Error())
  844. return
  845. }
  846. } else {
  847. _, e = FactorEdbStepCalculateRange(seriesMappingItem.FactorEdbSeriesId, edbIds, extraConfig, true)
  848. if e != nil {
  849. err = fmt.Errorf("计算因子指标失败, Err: " + e.Error())
  850. return
  851. }
  852. }
  853. // 4.清除图表缓存
  854. key := utils.HZ_CHART_LIB_DETAIL + uniqueCode
  855. _ = utils.Rc.Delete(key)
  856. return
  857. }
  858. func GetEdbDateByMoveForward(startDate string, moveForward int, edbDataList []*models.EdbDataList) (date string) {
  859. // 根据日期进行排序
  860. index := 0
  861. for _, v := range edbDataList {
  862. if v.DataTime == startDate {
  863. index += 1
  864. }
  865. if index > 0 {
  866. index += 1
  867. }
  868. if index == moveForward {
  869. date = v.DataTime
  870. break
  871. }
  872. }
  873. return
  874. }
  875. // HandleEdbDateChange 处理日期变换
  876. func HandleEdbDateChange(date string, dateChange []*models.EdbDateConfDateChange) (newDate string, err error) {
  877. newDate = date
  878. if newDate != "" {
  879. if len(dateChange) > 0 {
  880. var dateTime time.Time
  881. dateTime, err = time.ParseInLocation(utils.FormatDate, newDate, time.Local)
  882. if err != nil {
  883. err = fmt.Errorf("日期解析失败: %s", err.Error())
  884. return
  885. }
  886. for _, v := range dateChange {
  887. if v.ChangeType == 1 {
  888. dateTime = dateTime.AddDate(v.Year, v.Month, v.Day)
  889. newDate = dateTime.Format(utils.FormatDate)
  890. } else if v.ChangeType == 2 {
  891. newDate, err, _ = utils.HandleSystemAppointDateT(dateTime, v.FrequencyDay, v.Frequency)
  892. if err != nil {
  893. return
  894. }
  895. dateTime, err = time.ParseInLocation(utils.FormatDate, newDate, time.Local)
  896. if err != nil {
  897. err = fmt.Errorf("日期解析失败: %s", err.Error())
  898. return
  899. }
  900. }
  901. }
  902. }
  903. }
  904. return
  905. }
  906. // FactorEdbStepCalculateRange 因子指标-区间计算
  907. func FactorEdbStepCalculateRange(seriesId int, edbArr []int, extraConf models.ChartRangeAnalysisExtraConf, recalculate bool) (calculateResp data_manage.FactorEdbSeriesStepCalculateResp, err error) {
  908. // todo 如果指标已保存,则用指标数据还是图表指标数据?
  909. // 获取图表x轴y轴
  910. defer func() {
  911. if err != nil {
  912. tips := fmt.Sprintf("FactorEdbStepCalculateRange 区间计算, ErrMsg: %v", err)
  913. fmt.Println(tips)
  914. utils.FileLog.Info(tips)
  915. go alarm_msg.SendAlarmMsg(tips, 3)
  916. }
  917. /*if len(calculateResp.Fail) > 0 {
  918. tips := "StepCalculate计算失败, ErrMsg: "
  919. for _, f := range calculateResp.Fail {
  920. tips += fmt.Sprintf("code: %s, err: %s\n", f.EdbCode, f.ErrMsg)
  921. }
  922. fmt.Println(tips)
  923. utils.FileLog.Info(tips)
  924. go alarm_msg.SendAlarmMsg(tips, 2)
  925. }*/
  926. }()
  927. edbInfoMappingList, e := models.GetChartEdbMappingListByEdbInfoIdList(edbArr)
  928. if e != nil {
  929. err = fmt.Errorf("获取区间计算图表, A指标mapping信息失败, Err:%v", e)
  930. return
  931. }
  932. _, _, _, err = GetChartDataByEdbInfoList(0, 0, 0, "", "", edbInfoMappingList, &extraConf)
  933. if err != nil {
  934. err = fmt.Errorf("获取图表数据失败, ErrMsg: %v", err)
  935. return
  936. }
  937. // 重新计算-先清除原数据
  938. calculateDataOb := new(models.FactorEdbSeriesCalculateDataQjjs)
  939. cond := fmt.Sprintf("%s = ?", calculateDataOb.Cols().FactorEdbSeriesId)
  940. pars := make([]interface{}, 0)
  941. pars = append(pars, seriesId)
  942. if e := calculateDataOb.RemoveByCondition(cond, pars); e != nil {
  943. err = fmt.Errorf("清除原数据失败, err: %v", e)
  944. return
  945. }
  946. // 计算成功的保存结果
  947. dataArr := make([]*models.FactorEdbSeriesCalculateDataQjjs, 0)
  948. for _, v := range edbInfoMappingList {
  949. dataList := v.DataList.([]*models.EdbDataList)
  950. for _, dataItem := range dataList {
  951. dataTime, _ := time.ParseInLocation(utils.FormatDate, dataItem.DataTime, time.Local)
  952. dataArr = append(dataArr, &models.FactorEdbSeriesCalculateDataQjjs{
  953. FactorEdbSeriesId: seriesId,
  954. EdbInfoId: v.EdbInfoId,
  955. EdbCode: v.EdbCode,
  956. DataTime: dataTime,
  957. Value: dataItem.Value,
  958. CreateTime: time.Now().Local(),
  959. ModifyTime: time.Now().Local(),
  960. DataTimestamp: dataItem.DataTimestamp,
  961. })
  962. }
  963. }
  964. if len(dataArr) == 0 {
  965. err = fmt.Errorf("计算结果无数据, seriesId: %d", seriesId)
  966. return
  967. }
  968. if e = calculateDataOb.CreateMulti(dataArr); e != nil {
  969. err = fmt.Errorf("保存计算结果失败, seriesId: %d, err: %v, ", seriesId, e)
  970. return
  971. }
  972. return
  973. }