chart_info.go 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. package data
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "github.com/shopspring/decimal"
  7. "hongze/hongze_chart_lib/models"
  8. "hongze/hongze_chart_lib/models/data_manage"
  9. "hongze/hongze_chart_lib/services/alarm_msg"
  10. "hongze/hongze_chart_lib/utils"
  11. "math"
  12. "sort"
  13. "time"
  14. )
  15. // ChartInfoRefreshV1 图表刷新
  16. func ChartInfoRefreshV1(chartInfoId int) (err error) {
  17. var errmsg string
  18. defer func() {
  19. if err != nil {
  20. go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "ChartInfoRefresh:"+errmsg, utils.EmailSendToUsers)
  21. fmt.Println("ChartInfoRefresh Err:" + errmsg)
  22. }
  23. }()
  24. baseEdbInfoArr, calculateInfoArr, err := data_manage.GetChartInfoRefreshData(chartInfoId)
  25. if err != nil {
  26. errmsg = "获取需要刷新的指标失败:Err:" + err.Error()
  27. return
  28. }
  29. var startDate string
  30. newBaseEdbInfoArr := make([]*data_manage.EdbInfo, 0)
  31. baseMap := make(map[int]*data_manage.EdbInfo)
  32. for _, bv := range baseEdbInfoArr {
  33. // 如果不是普通指标,那么过滤
  34. if bv.EdbInfoType != 0 {
  35. continue
  36. }
  37. if _, ok := baseMap[bv.EdbInfoId]; !ok {
  38. newBaseEdbInfoArr = append(newBaseEdbInfoArr, bv)
  39. }
  40. baseMap[bv.EdbInfoId] = bv
  41. }
  42. fmt.Println("calculateInfoArr:", len(calculateInfoArr))
  43. newCalculateInfoArr := make([]*data_manage.EdbInfo, 0)
  44. calculateMap := make(map[int]*data_manage.EdbInfo)
  45. var calculateArr []int
  46. for _, bv := range calculateInfoArr {
  47. if _, ok := calculateMap[bv.EdbInfoId]; !ok {
  48. newCalculateInfoArr = append(newCalculateInfoArr, bv)
  49. calculateArr = append(calculateArr, bv.EdbInfoId)
  50. }
  51. calculateMap[bv.EdbInfoId] = bv
  52. }
  53. sort.Ints(calculateArr)
  54. for _, bv := range newBaseEdbInfoArr {
  55. source := bv.Source
  56. edbInfoId := bv.EdbInfoId
  57. edbCode := bv.EdbCode
  58. startDate = bv.StartDate
  59. frequency := bv.Frequency
  60. if bv.StartDate == "0000-00-00" {
  61. continue
  62. }
  63. sTime, err := time.Parse(utils.FormatDate, bv.EndDate)
  64. if err != nil {
  65. return err
  66. }
  67. var limitDay int
  68. startDate := ""
  69. switch frequency {
  70. case "日度":
  71. limitDay = utils.DATA_REFRESH
  72. case "周度":
  73. limitDay = utils.DATA_REFRESH * 7
  74. case "月度":
  75. limitDay = utils.DATA_REFRESH * 30
  76. case "季度":
  77. limitDay = utils.DATA_REFRESH * 90
  78. case "年度":
  79. limitDay = utils.DATA_REFRESH * 365
  80. default:
  81. limitDay = utils.DATA_REFRESH
  82. }
  83. startDate = sTime.AddDate(0, 0, -limitDay).Format(utils.FormatDate)
  84. fmt.Println("source:", source)
  85. respItem, err := RefreshEdbData(edbInfoId, source, edbCode, startDate)
  86. if err != nil {
  87. errmsg = errors.New("RefreshEdbData Err:" + err.Error()).Error()
  88. return err
  89. }
  90. if respItem.Ret != 200 {
  91. errmsg = errors.New(respItem.ErrMsg + ";EdbCode:" + edbCode).Error()
  92. return err
  93. }
  94. //maxAndMinItem, err := data_manage.GetEdbInfoMaxAndMinInfo(source, edbCode)
  95. //if err != nil {
  96. // return err
  97. //}
  98. //if maxAndMinItem != nil {
  99. // err = data_manage.ModifyEdbInfoMaxAndMinInfo(edbInfoId, maxAndMinItem)
  100. // if err != nil {
  101. // return err
  102. // }
  103. //}
  104. }
  105. //刷新相关计算指标
  106. for _, v := range calculateArr {
  107. edbInfo := calculateMap[v]
  108. if edbInfo == nil {
  109. return err
  110. }
  111. startDate = edbInfo.StartDate
  112. source := edbInfo.Source
  113. if source == utils.DATA_SOURCE_CALCULATE {
  114. startDate = edbInfo.StartDate
  115. sTime, err := time.Parse(utils.FormatDate, edbInfo.EndDate)
  116. if err != nil {
  117. return err
  118. }
  119. startDate = sTime.Format(utils.FormatDate)
  120. }
  121. result, err := RefreshEdbCalculateData(edbInfo.EdbInfoId, edbInfo.EdbCode, startDate)
  122. if err != nil {
  123. fmt.Println(v, "RefreshEdbCalculateData err", time.Now())
  124. errmsg = "RefreshEdbCalculateData Err:" + err.Error()
  125. return err
  126. }
  127. if result.Ret != 200 {
  128. fmt.Println(v, "RefreshEdbCalculateData err;msg:", result.Msg, ";errMsg:", result.ErrMsg)
  129. errmsg = fmt.Sprint(v, "RefreshEdbCalculateData err;msg:", result.Msg, ";errMsg:", result.ErrMsg)
  130. return fmt.Errorf("刷新失败" + errmsg)
  131. }
  132. fmt.Println("end calculateArr:", v, time.Now())
  133. }
  134. return err
  135. }
  136. // GetFrequencyEn 获取频度的英文版
  137. func GetFrequencyEn(frequency string) (frequencyEn string) {
  138. switch frequency {
  139. case "日度":
  140. frequencyEn = "day"
  141. return
  142. case "周度":
  143. frequencyEn = "week"
  144. return
  145. case "旬度":
  146. frequencyEn = "ten days"
  147. return
  148. case "月度":
  149. frequencyEn = "month"
  150. return
  151. case "季度":
  152. frequencyEn = "quarter"
  153. return
  154. case "年度":
  155. frequencyEn = "year"
  156. return
  157. }
  158. return
  159. }
  160. func GetLeadUnitEn(unit string) (unitEn string) {
  161. switch unit {
  162. case "天":
  163. unitEn = "day"
  164. return
  165. case "周":
  166. unitEn = "week"
  167. return
  168. case "月":
  169. unitEn = "month"
  170. return
  171. case "季":
  172. unitEn = "quarter"
  173. return
  174. case "年":
  175. unitEn = "year"
  176. return
  177. }
  178. return
  179. }
  180. // GetChartEdbData 获取图表的指标数据
  181. func GetChartEdbData(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, extraConfigStr string) (edbList []*models.ChartEdbInfoMapping, xEdbIdValue []int, yDataList []models.YData, dataResp interface{}, err error, errMsg string) {
  182. edbList = make([]*models.ChartEdbInfoMapping, 0)
  183. // 指标对应的所有数据
  184. xEdbIdValue = make([]int, 0)
  185. yDataList = make([]models.YData, 0)
  186. var extraConfig interface{}
  187. switch chartType {
  188. case 7: // 柱形图
  189. var barConfig data_manage.BarChartInfoReq
  190. if extraConfigStr == `` {
  191. errMsg = "柱方图未配置"
  192. err = errors.New(errMsg)
  193. return
  194. }
  195. err = json.Unmarshal([]byte(extraConfigStr), &barConfig)
  196. if err != nil {
  197. errMsg = "柱方图配置异常"
  198. err = errors.New(errMsg)
  199. return
  200. }
  201. extraConfig = barConfig
  202. case 10: // 截面散点图
  203. var tmpExtraConfig data_manage.SectionScatterReq
  204. if extraConfigStr == `` {
  205. errMsg = "截面散点图未配置"
  206. err = errors.New(errMsg)
  207. return
  208. }
  209. err = json.Unmarshal([]byte(extraConfigStr), &tmpExtraConfig)
  210. if err != nil {
  211. errMsg = "截面散点配置异常"
  212. err = errors.New(errMsg)
  213. return
  214. }
  215. extraConfig = tmpExtraConfig
  216. default:
  217. xEdbIdValue = make([]int, 0)
  218. yDataList = make([]models.YData, 0)
  219. }
  220. // 指标对应的所有数据
  221. edbDataListMap, edbList, err := getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList)
  222. if err != nil {
  223. return
  224. }
  225. // 特殊图形数据处理
  226. switch chartType {
  227. case 7: // 柱形图
  228. barChartConf := extraConfig.(data_manage.BarChartInfoReq)
  229. xEdbIdValue, yDataList, err = BarChartData(mappingList, edbDataListMap, barChartConf.DateList, barChartConf.Sort)
  230. for _, v := range edbList {
  231. // 指标别名
  232. if barChartConf.EdbInfoIdList != nil && len(barChartConf.EdbInfoIdList) > 0 {
  233. for _, reqEdb := range barChartConf.EdbInfoIdList {
  234. if v.EdbInfoId == reqEdb.EdbInfoId {
  235. v.EdbAliasName = reqEdb.Name
  236. }
  237. }
  238. }
  239. }
  240. case 10: // 截面散点图
  241. sectionScatterConf := extraConfig.(data_manage.SectionScatterReq)
  242. xEdbIdValue, dataResp, err = GetSectionScatterChartData(mappingList, edbDataListMap, sectionScatterConf)
  243. // 这个数据没有必要返回给前端
  244. for _, v := range edbList {
  245. v.DataList = nil
  246. }
  247. }
  248. return
  249. }
  250. // GetEdbDataMapList 获取指标最后的基础数据
  251. func GetEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
  252. edbDataListMap, edbList, err = getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList)
  253. return
  254. }
  255. // getEdbDataMapList 获取指标最后的基础数据
  256. func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
  257. // 指标对应的所有数据
  258. edbDataListMap = make(map[int][]*models.EdbDataList)
  259. for _, v := range mappingList {
  260. //fmt.Println("v:", v.EdbInfoId)
  261. item := new(models.ChartEdbInfoMapping)
  262. item.EdbInfoId = v.EdbInfoId
  263. item.SourceName = v.SourceName
  264. item.Source = v.Source
  265. item.EdbCode = v.EdbCode
  266. item.EdbName = v.EdbName
  267. item.EdbType = v.EdbType
  268. item.EdbNameEn = v.EdbNameEn
  269. item.Frequency = v.Frequency
  270. item.FrequencyEn = GetFrequencyEn(v.Frequency)
  271. if v.Unit != `无` {
  272. item.Unit = v.Unit
  273. }
  274. item.UnitEn = v.UnitEn
  275. item.StartDate = v.StartDate
  276. item.EndDate = v.EndDate
  277. item.ModifyTime = v.ModifyTime
  278. item.EdbInfoCategoryType = v.EdbInfoCategoryType
  279. item.PredictChartColor = v.PredictChartColor
  280. if chartInfoId <= 0 {
  281. item.IsAxis = 1
  282. item.LeadValue = 0
  283. item.LeadUnit = ""
  284. //item.ChartEdbMappingId = 0
  285. item.ChartInfoId = 0
  286. item.IsOrder = false
  287. item.EdbInfoType = 1
  288. item.ChartStyle = ""
  289. item.ChartColor = ""
  290. item.ChartWidth = 0
  291. item.MaxData = v.MaxValue
  292. item.MinData = v.MinValue
  293. } else {
  294. item.IsAxis = v.IsAxis
  295. item.EdbInfoType = v.EdbInfoType
  296. item.LeadValue = v.LeadValue
  297. item.LeadUnit = v.LeadUnit
  298. item.LeadUnitEn = GetLeadUnitEn(v.LeadUnit)
  299. //item.ChartEdbMappingId = v.ChartEdbMappingId
  300. item.ChartInfoId = v.ChartInfoId
  301. item.ChartStyle = v.ChartStyle
  302. item.ChartColor = v.ChartColor
  303. item.ChartWidth = v.ChartWidth
  304. item.IsOrder = v.IsOrder
  305. item.MaxData = v.MaxData
  306. item.MinData = v.MinData
  307. }
  308. item.LatestValue = v.LatestValue
  309. item.LatestDate = v.LatestDate
  310. item.UniqueCode = v.UniqueCode
  311. var startDateReal string
  312. var diffSeconds int64
  313. if chartType == 2 { //季节性图
  314. startDateReal = startDate
  315. } else {
  316. if v.EdbInfoType == 0 && v.LeadUnit != "" && v.LeadValue > 0 { //领先指标
  317. var startTimeRealTemp time.Time
  318. startDateParse, _ := time.Parse(utils.FormatDate, startDate)
  319. switch v.LeadUnit {
  320. case "天":
  321. startTimeRealTemp = startDateParse.AddDate(0, 0, -v.LeadValue)
  322. case "月":
  323. startTimeRealTemp = startDateParse.AddDate(0, -v.LeadValue, 0)
  324. case "季":
  325. startTimeRealTemp = startDateParse.AddDate(0, -3*v.LeadValue, 0)
  326. case "周":
  327. startTimeRealTemp = startDateParse.AddDate(0, 0, -7*v.LeadValue)
  328. case "年":
  329. startTimeRealTemp = startDateParse.AddDate(-v.LeadValue, 0, 0)
  330. }
  331. if startTimeRealTemp.Before(startDateParse) {
  332. startDateReal = startTimeRealTemp.Format(utils.FormatDate)
  333. diffSeconds = (int64(startTimeRealTemp.UnixNano()) - int64(startDateParse.UnixNano())) / 1e6
  334. } else {
  335. startDateReal = startDate
  336. diffSeconds = 0
  337. }
  338. // 预测指标的开始日期也要偏移
  339. {
  340. day, tmpErr := utils.GetDaysBetween2Date(utils.FormatDate, startDate, startDateReal)
  341. if tmpErr != nil {
  342. err = tmpErr
  343. return
  344. }
  345. latestDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, v.LatestDate, time.Local)
  346. if tmpErr != nil {
  347. err = tmpErr
  348. return
  349. }
  350. item.LatestDate = latestDateTime.AddDate(0, 0, day).Format(utils.FormatDate)
  351. }
  352. } else {
  353. startDateReal = startDate
  354. }
  355. }
  356. //fmt.Println("line 1011 chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
  357. calendarPreYear := 0
  358. if calendar == "农历" {
  359. newStartDateReal, err := time.Parse(utils.FormatDate, startDateReal)
  360. if err != nil {
  361. fmt.Println("time.Parse:" + err.Error())
  362. }
  363. calendarPreYear = newStartDateReal.Year() - 1
  364. newStartDateReal = newStartDateReal.AddDate(-1, 0, 0)
  365. startDateReal = newStartDateReal.Format(utils.FormatDate)
  366. }
  367. dataList := make([]*models.EdbDataList, 0)
  368. //fmt.Println("chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
  369. switch v.EdbInfoCategoryType {
  370. case 0:
  371. dataList, err = models.GetEdbDataList(v.Source, v.EdbInfoId, startDateReal, endDate)
  372. case 1:
  373. _, dataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(v.EdbInfoId, startDateReal, endDate, false)
  374. default:
  375. err = errors.New(fmt.Sprint("获取失败,指标类型异常", v.EdbInfoCategoryType))
  376. }
  377. if err != nil {
  378. return
  379. }
  380. edbDataListMap[v.EdbInfoId] = dataList
  381. if diffSeconds != 0 && v.EdbInfoType == 0 {
  382. dataListLen := len(dataList)
  383. for i := 0; i < dataListLen; i++ {
  384. dataList[i].DataTimestamp = dataList[i].DataTimestamp - diffSeconds
  385. }
  386. }
  387. if chartType == 2 {
  388. latestDateStr := v.LatestDate //实际数据的截止日期
  389. latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
  390. if tmpErr != nil {
  391. err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + v.LatestDate))
  392. return
  393. }
  394. latestDateYear := latestDate.Year() //实际数据截止年份
  395. if calendar == "农历" {
  396. if len(dataList) <= 0 {
  397. result := new(models.EdbDataResult)
  398. item.DataList = result
  399. } else {
  400. result, tmpErr := models.AddCalculateQuarterV5(dataList)
  401. if tmpErr != nil {
  402. err = errors.New("获取农历数据失败,Err:" + tmpErr.Error())
  403. return
  404. }
  405. // 处理季节图的截止日期
  406. for k, edbDataItems := range result.List {
  407. var cuttingDataTimestamp int64
  408. // 切割的日期时间字符串
  409. cuttingDataTimeStr := latestDate.AddDate(0, 0, edbDataItems.BetweenDay).Format(utils.FormatDate)
  410. //如果等于最后的实际日期,那么遍历找到该日期对应的时间戳,并将其赋值为 切割时间戳
  411. if edbDataItems.Year >= latestDateYear {
  412. for _, tmpData := range edbDataItems.Items {
  413. if tmpData.DataTime == cuttingDataTimeStr {
  414. cuttingDataTimestamp = tmpData.DataTimestamp
  415. break
  416. }
  417. }
  418. }
  419. edbDataItems.CuttingDataTimestamp = cuttingDataTimestamp
  420. result.List[k] = edbDataItems
  421. }
  422. if result.List[0].Year != calendarPreYear {
  423. itemList := make([]*models.EdbDataList, 0)
  424. items := new(models.EdbDataItems)
  425. //items.Year = calendarPreYear
  426. items.Items = itemList
  427. newResult := new(models.EdbDataResult)
  428. newResult.List = append(newResult.List, items)
  429. newResult.List = append(newResult.List, result.List...)
  430. item.DataList = newResult
  431. } else {
  432. item.DataList = result
  433. }
  434. }
  435. } else {
  436. currentYear := time.Now().Year()
  437. quarterDataList := make([]*models.QuarterData, 0)
  438. quarterMap := make(map[int][]*models.EdbDataList)
  439. var quarterArr []int
  440. for _, v := range dataList {
  441. itemDate, tmpErr := time.Parse(utils.FormatDate, v.DataTime)
  442. if tmpErr != nil {
  443. err = errors.New("季度指标日期转换,Err:" + tmpErr.Error() + ";DataTime:" + v.DataTime)
  444. return
  445. }
  446. year := itemDate.Year()
  447. newItemDate := itemDate.AddDate(currentYear-year, 0, 0)
  448. timestamp := newItemDate.UnixNano() / 1e6
  449. v.DataTimestamp = timestamp
  450. if findVal, ok := quarterMap[year]; !ok {
  451. quarterArr = append(quarterArr, year)
  452. findVal = append(findVal, v)
  453. quarterMap[year] = findVal
  454. } else {
  455. findVal = append(findVal, v)
  456. quarterMap[year] = findVal
  457. }
  458. }
  459. for _, v := range quarterArr {
  460. itemList := quarterMap[v]
  461. quarterItem := new(models.QuarterData)
  462. quarterItem.Year = v
  463. quarterItem.DataList = itemList
  464. //如果等于最后的实际日期,那么将切割时间戳记录
  465. if v == latestDateYear {
  466. var cuttingDataTimestamp int64
  467. for _, tmpData := range itemList {
  468. if tmpData.DataTime == latestDateStr {
  469. cuttingDataTimestamp = tmpData.DataTimestamp
  470. break
  471. }
  472. }
  473. quarterItem.CuttingDataTimestamp = cuttingDataTimestamp
  474. } else if v > latestDateYear {
  475. //如果大于最后的实际日期,那么第一个点就是切割的时间戳
  476. if len(itemList) > 0 {
  477. quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
  478. }
  479. }
  480. quarterDataList = append(quarterDataList, quarterItem)
  481. }
  482. item.DataList = quarterDataList
  483. }
  484. } else if chartType == 7 { //柱方图
  485. //item.DataList = dataList
  486. } else {
  487. item.DataList = dataList
  488. }
  489. edbList = append(edbList, item)
  490. }
  491. return
  492. }
  493. // BarChartData 柱方图的数据处理
  494. func BarChartData(mappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, barChartInfoDateList []data_manage.BarChartInfoDateReq, barChartInfoSort data_manage.BarChartInfoSortReq) (edbIdList []int, yDataList []models.YData, err error) {
  495. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  496. edbDataMap := make(map[int]map[string]float64)
  497. for edbInfoId, edbDataList := range edbDataListMap {
  498. edbDateData := make(map[string]float64)
  499. for _, edbData := range edbDataList {
  500. edbDateData[edbData.DataTime] = edbData.Value
  501. }
  502. edbDataMap[edbInfoId] = edbDateData
  503. }
  504. // edbIdList 指标展示顺序;x轴的指标顺序
  505. edbIdList = make([]int, 0)
  506. //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
  507. dateData := make(map[int]float64)
  508. if barChartInfoSort.Sort == 0 {
  509. for _, v := range mappingList {
  510. edbIdList = append(edbIdList, v.EdbInfoId)
  511. }
  512. } else {
  513. lenBarChartInfoDateList := len(barChartInfoDateList)
  514. if barChartInfoSort.DateIndex >= lenBarChartInfoDateList {
  515. err = errors.New("排序日期异常")
  516. return
  517. }
  518. notDataEdbIdList := make([]int, 0) //没有数据的指标id
  519. // 日期配置
  520. barChartInfoDate := barChartInfoDateList[barChartInfoSort.DateIndex]
  521. for edbInfoId, dataList := range edbDataListMap {
  522. if len(dataList) <= 0 {
  523. // 没有数据的指标id
  524. notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
  525. continue
  526. }
  527. findDate := barChartInfoDate.Date
  528. switch barChartInfoDate.Type {
  529. case 1: //最新值
  530. findDate = dataList[len(dataList)-1].DataTime
  531. case 2: //近期几天
  532. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  533. if tmpErr != nil {
  534. err = tmpErr
  535. return
  536. }
  537. findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  538. lenData := len(dataList) - 1
  539. for i := lenData; i >= 0; i-- {
  540. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  541. if tmpErr != nil {
  542. err = tmpErr
  543. return
  544. }
  545. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  546. findDate = dataList[i].DataTime
  547. break
  548. }
  549. }
  550. case 3: // 固定日期
  551. //最早的日期
  552. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  553. if tmpErr != nil {
  554. err = tmpErr
  555. return
  556. }
  557. //寻找固定日期的数据
  558. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  559. if tmpErr != nil {
  560. err = tmpErr
  561. return
  562. }
  563. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  564. tmpDate := tmpDateTime.Format(utils.FormatDate)
  565. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  566. findDate = tmpDate
  567. break
  568. }
  569. }
  570. default:
  571. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  572. return
  573. }
  574. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  575. dateData[edbInfoId] = tmpValue
  576. } else {
  577. // 没有数据的指标id
  578. notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
  579. }
  580. }
  581. //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
  582. // 排序
  583. dateDataSort := utils.NewMapSorter(dateData)
  584. sort.Sort(dateDataSort)
  585. if barChartInfoSort.Sort == 1 {
  586. // 先将没有数据的指标id放在最前面
  587. if len(notDataEdbIdList) > 0 {
  588. edbIdList = append(edbIdList, notDataEdbIdList...)
  589. }
  590. for _, v := range dateDataSort {
  591. edbIdList = append(edbIdList, v.Key)
  592. }
  593. } else {
  594. for i := len(dateDataSort) - 1; i >= 0; i-- {
  595. edbIdList = append(edbIdList, dateDataSort[i].Key)
  596. }
  597. // 再将没有数据的指标id放在最后面
  598. if len(notDataEdbIdList) > 0 {
  599. edbIdList = append(edbIdList, notDataEdbIdList...)
  600. }
  601. }
  602. }
  603. yDataList = make([]models.YData, 0) //y轴的数据列表
  604. for _, barChartInfoDate := range barChartInfoDateList {
  605. var maxDate time.Time
  606. findDataList := make([]float64, 0) // 当前日期的数据值
  607. for _, edbInfoId := range edbIdList {
  608. findDate := barChartInfoDate.Date //需要的日期值
  609. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  610. if len(dataList) <= 0 {
  611. // 没有数据的指标id
  612. findDataList = append(findDataList, 0)
  613. continue
  614. }
  615. switch barChartInfoDate.Type {
  616. case 1: //最新值
  617. dataList := edbDataListMap[edbInfoId]
  618. findDate = dataList[len(dataList)-1].DataTime
  619. case 2: //近期几天
  620. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  621. if tmpErr != nil {
  622. err = tmpErr
  623. return
  624. }
  625. findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  626. lenData := len(dataList) - 1
  627. for i := lenData; i >= 0; i-- {
  628. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  629. if tmpErr != nil {
  630. err = tmpErr
  631. return
  632. }
  633. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  634. findDate = dataList[i].DataTime
  635. break
  636. }
  637. }
  638. case 3: // 固定日期
  639. //最早的日期
  640. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  641. if tmpErr != nil {
  642. err = tmpErr
  643. return
  644. }
  645. //寻找固定日期的数据
  646. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  647. if tmpErr != nil {
  648. err = tmpErr
  649. return
  650. }
  651. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  652. tmpDate := tmpDateTime.Format(utils.FormatDate)
  653. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  654. findDate = tmpDate
  655. break
  656. }
  657. }
  658. default:
  659. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  660. return
  661. }
  662. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  663. if maxDate.IsZero() {
  664. maxDate = findDateTime
  665. } else {
  666. if findDateTime.After(maxDate) {
  667. maxDate = findDateTime
  668. }
  669. }
  670. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  671. findDataList = append(findDataList, tmpValue)
  672. } else {
  673. findDataList = append(findDataList, 0)
  674. }
  675. }
  676. yDate := "0000-00-00"
  677. if !maxDate.IsZero() {
  678. yDate = maxDate.Format(utils.FormatDate)
  679. }
  680. yDataList = append(yDataList, models.YData{
  681. Date: yDate,
  682. Value: findDataList,
  683. Color: barChartInfoDate.Color,
  684. Name: barChartInfoDate.Name,
  685. })
  686. }
  687. return
  688. }
  689. // ChartInfoRefreshV2 图表刷新
  690. // @author Roc
  691. // @datetime 2022-09-16 10:15:38
  692. // @description 将原来自己写的一套获取所有关联指标,然后刷新指标逻辑 改成 只获取使用的指标id,然后遍历去调用“指标刷新服务”
  693. func ChartInfoRefreshV2(chartInfoId int) (err error) {
  694. var errmsg string
  695. defer func() {
  696. if err != nil {
  697. go alarm_msg.SendAlarmMsg("ChartInfoRefresh:"+errmsg, 3)
  698. //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "ChartInfoRefresh:"+errmsg, utils.EmailSendToUsers)
  699. fmt.Println("ChartInfoRefresh Err:" + errmsg)
  700. }
  701. }()
  702. edbMappingList, err := data_manage.GetChartEdbMappingList(chartInfoId)
  703. if err != nil {
  704. errmsg = "获取需要刷新的指标失败:Err:" + err.Error()
  705. return
  706. }
  707. edbIdList := make([]int, 0)
  708. for _, v := range edbMappingList {
  709. edbIdList = append(edbIdList, v.EdbInfoId)
  710. }
  711. // 批量刷新
  712. err, errmsg = EdbInfoRefreshAllFromBase(edbIdList, false)
  713. if err != nil {
  714. return
  715. }
  716. return
  717. }
  718. // GetSectionScatterChartData 柱方图的数据处理
  719. func GetSectionScatterChartData(mappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, extraConfig data_manage.SectionScatterReq) (edbIdList []int, chartDataResp data_manage.SectionScatterInfoResp, err error) {
  720. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  721. edbDataMap := make(map[int]map[string]float64)
  722. for edbInfoId, edbDataList := range edbDataListMap {
  723. edbDateData := make(map[string]float64)
  724. for _, edbData := range edbDataList {
  725. edbDateData[edbData.DataTime] = edbData.Value
  726. }
  727. edbDataMap[edbInfoId] = edbDateData
  728. }
  729. // edbIdList 指标展示顺序;x轴的指标顺序
  730. edbIdList = make([]int, 0)
  731. edbMappingMap := make(map[int]*models.ChartEdbInfoMapping)
  732. for _, v := range mappingList {
  733. edbIdList = append(edbIdList, v.EdbInfoId)
  734. edbMappingMap[v.EdbInfoId] = v
  735. }
  736. //SectionScatterSeriesInfoResp
  737. dataListResp := make([]data_manage.SectionScatterSeriesItemResp, 0) //y轴的数据列表
  738. for _, seriesItem := range extraConfig.SeriesList {
  739. var maxDate time.Time
  740. // 系列中的指标数据
  741. tmpSeriesEdbInfoList := make([]data_manage.SectionScatterEdbItemResp, 0)
  742. var minXVal, maxXVal, minYVal, maxYVal float64
  743. for _, edbConf := range seriesItem.EdbInfoList {
  744. tmpItem := data_manage.SectionScatterEdbItemResp{
  745. IsShow: edbConf.IsShow,
  746. Name: edbConf.Name,
  747. NameEn: edbConf.NameEn,
  748. } //单个坐标点的数据
  749. //X轴的数据
  750. {
  751. edbInfoId := edbConf.XEdbInfoId //X轴的指标
  752. edbMappingInfo, ok := edbMappingMap[edbInfoId]
  753. if !ok {
  754. continue
  755. }
  756. findDate := edbConf.XDate //需要的日期值
  757. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  758. if len(dataList) <= 0 {
  759. // 没有数据的指标id
  760. //findDataList = append(findDataList, 0)
  761. continue
  762. }
  763. tmpItem.XEdbInfoId = edbInfoId
  764. tmpItem.XName = edbMappingInfo.EdbName
  765. tmpItem.XNameEn = edbMappingInfo.EdbNameEn
  766. switch edbConf.XDateType {
  767. case 1: //最新值
  768. dataList := edbDataListMap[edbInfoId]
  769. findDate = dataList[len(dataList)-1].DataTime
  770. case 2: //近期几天
  771. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  772. if tmpErr != nil {
  773. err = tmpErr
  774. return
  775. }
  776. findDateTime = findDateTime.AddDate(0, 0, -edbConf.XDateValue)
  777. lenData := len(dataList) - 1
  778. for i := lenData; i >= 0; i-- {
  779. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  780. if tmpErr != nil {
  781. err = tmpErr
  782. return
  783. }
  784. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  785. findDate = dataList[i].DataTime
  786. break
  787. }
  788. }
  789. case 3: // 固定日期
  790. //最早的日期
  791. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  792. if tmpErr != nil {
  793. err = tmpErr
  794. return
  795. }
  796. //寻找固定日期的数据
  797. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.XDate, time.Local)
  798. if tmpErr != nil {
  799. err = tmpErr
  800. return
  801. }
  802. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  803. tmpDate := tmpDateTime.Format(utils.FormatDate)
  804. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  805. findDate = tmpDate
  806. break
  807. }
  808. }
  809. default:
  810. err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.XDate))
  811. return
  812. }
  813. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  814. if maxDate.IsZero() {
  815. maxDate = findDateTime
  816. } else {
  817. if findDateTime.After(maxDate) {
  818. maxDate = findDateTime
  819. }
  820. }
  821. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  822. tmpItem.XDate = findDate
  823. tmpItem.XValue = tmpValue
  824. } else {
  825. continue
  826. }
  827. }
  828. //Y轴的数据
  829. {
  830. edbInfoId := edbConf.YEdbInfoId //Y轴的指标
  831. edbMappingInfo, ok := edbMappingMap[edbInfoId]
  832. if !ok {
  833. continue
  834. }
  835. findDate := edbConf.YDate //需要的日期值
  836. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  837. if len(dataList) <= 0 {
  838. // 没有数据的指标id
  839. //findDataList = append(findDataList, 0)
  840. continue
  841. }
  842. tmpItem.YEdbInfoId = edbInfoId
  843. tmpItem.YName = edbMappingInfo.EdbName
  844. tmpItem.YNameEn = edbMappingInfo.EdbNameEn
  845. switch edbConf.YDateType {
  846. case 1: //最新值
  847. dataList := edbDataListMap[edbInfoId]
  848. findDate = dataList[len(dataList)-1].DataTime
  849. case 2: //近期几天
  850. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  851. if tmpErr != nil {
  852. err = tmpErr
  853. return
  854. }
  855. findDateTime = findDateTime.AddDate(0, 0, -edbConf.YDateValue)
  856. lenData := len(dataList) - 1
  857. for i := lenData; i >= 0; i-- {
  858. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  859. if tmpErr != nil {
  860. err = tmpErr
  861. return
  862. }
  863. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  864. findDate = dataList[i].DataTime
  865. break
  866. }
  867. }
  868. case 3: // 固定日期
  869. //最早的日期
  870. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  871. if tmpErr != nil {
  872. err = tmpErr
  873. return
  874. }
  875. //寻找固定日期的数据
  876. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.YDate, time.Local)
  877. if tmpErr != nil {
  878. err = tmpErr
  879. return
  880. }
  881. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  882. tmpDate := tmpDateTime.Format(utils.FormatDate)
  883. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  884. findDate = tmpDate
  885. break
  886. }
  887. }
  888. default:
  889. err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.YDate))
  890. return
  891. }
  892. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  893. if maxDate.IsZero() {
  894. maxDate = findDateTime
  895. } else {
  896. if findDateTime.After(maxDate) {
  897. maxDate = findDateTime
  898. }
  899. }
  900. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  901. tmpItem.YDate = findDate
  902. tmpItem.YValue = tmpValue
  903. } else {
  904. continue
  905. }
  906. }
  907. // 获取当前系列的X轴的最大最小值
  908. {
  909. if tmpItem.XValue < minXVal {
  910. minXVal = tmpItem.XValue
  911. }
  912. if tmpItem.XValue > maxXVal {
  913. maxXVal = tmpItem.XValue
  914. }
  915. if tmpItem.YValue < minYVal {
  916. minYVal = tmpItem.YValue
  917. }
  918. if tmpItem.YValue > maxYVal {
  919. maxYVal = tmpItem.YValue
  920. }
  921. }
  922. tmpSeriesEdbInfoList = append(tmpSeriesEdbInfoList, tmpItem)
  923. }
  924. trendLimitData := make([]data_manage.CoordinatePoint, 0) //趋势线的前后坐标点
  925. var trendLine, rSquare string
  926. // 生成线性方程式
  927. var a, b float64
  928. {
  929. coordinateData := make([]utils.Coordinate, 0)
  930. for _, tmpSeriesEdbInfo := range tmpSeriesEdbInfoList {
  931. tmpCoordinate1 := utils.Coordinate{
  932. X: tmpSeriesEdbInfo.XValue,
  933. Y: tmpSeriesEdbInfo.YValue,
  934. }
  935. coordinateData = append(coordinateData, tmpCoordinate1)
  936. }
  937. // 只有存在两个坐标点的时候,才能去计算线性方程和R平方
  938. if len(coordinateData) >= 2 {
  939. a, b = utils.GetLinearResult(coordinateData)
  940. if !math.IsNaN(a) || !math.IsNaN(b) {
  941. if b > 0 {
  942. trendLine = fmt.Sprintf("y=%sx+%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
  943. } else {
  944. trendLine = fmt.Sprintf("y=%sx%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
  945. }
  946. minYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(minXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
  947. maxYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(maxXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
  948. }
  949. // 计算R平方
  950. rSquare = fmt.Sprint(utils.CalculationDecisive(coordinateData))
  951. }
  952. trendLimitData = append(trendLimitData, data_manage.CoordinatePoint{
  953. X: minXVal,
  954. Y: minYVal,
  955. }, data_manage.CoordinatePoint{
  956. X: maxXVal,
  957. Y: maxYVal,
  958. })
  959. }
  960. dataListResp = append(dataListResp, data_manage.SectionScatterSeriesItemResp{
  961. Name: seriesItem.Name,
  962. NameEn: seriesItem.NameEn,
  963. Color: seriesItem.Color,
  964. EdbInfoList: tmpSeriesEdbInfoList,
  965. ShowTrendLine: seriesItem.ShowTrendLine,
  966. ShowFitEquation: seriesItem.ShowFitEquation,
  967. ShowRSquare: seriesItem.ShowRSquare,
  968. TrendLine: trendLine,
  969. RSquare: rSquare,
  970. TrendLimitData: trendLimitData,
  971. })
  972. }
  973. chartDataResp = data_manage.SectionScatterInfoResp{
  974. XName: extraConfig.XName,
  975. XNameEn: extraConfig.XNameEn,
  976. XUnitName: extraConfig.XUnitName,
  977. XUnitNameEn: extraConfig.XUnitNameEn,
  978. YName: extraConfig.YName,
  979. YNameEn: extraConfig.YNameEn,
  980. YUnitName: extraConfig.YUnitName,
  981. YUnitNameEn: extraConfig.YUnitNameEn,
  982. XMinValue: extraConfig.XMinValue,
  983. XMaxValue: extraConfig.XMaxValue,
  984. YMinValue: extraConfig.YMinValue,
  985. YMaxValue: extraConfig.YMaxValue,
  986. DataList: dataListResp,
  987. }
  988. return
  989. }