chart_info.go 33 KB

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