chart_info.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044
  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. // 指标对应的所有数据
  253. edbDataListMap = make(map[int][]*models.EdbDataList)
  254. for _, v := range mappingList {
  255. //fmt.Println("v:", v.EdbInfoId)
  256. item := new(models.ChartEdbInfoMapping)
  257. item.EdbInfoId = v.EdbInfoId
  258. item.SourceName = v.SourceName
  259. item.Source = v.Source
  260. item.EdbCode = v.EdbCode
  261. item.EdbName = v.EdbName
  262. item.EdbType = v.EdbType
  263. item.EdbNameEn = v.EdbNameEn
  264. item.Frequency = v.Frequency
  265. item.FrequencyEn = GetFrequencyEn(v.Frequency)
  266. if v.Unit != `无` {
  267. item.Unit = v.Unit
  268. }
  269. item.UnitEn = v.UnitEn
  270. item.StartDate = v.StartDate
  271. item.EndDate = v.EndDate
  272. item.ModifyTime = v.ModifyTime
  273. item.EdbInfoCategoryType = v.EdbInfoCategoryType
  274. item.PredictChartColor = v.PredictChartColor
  275. if chartInfoId <= 0 {
  276. item.IsAxis = 1
  277. item.LeadValue = 0
  278. item.LeadUnit = ""
  279. //item.ChartEdbMappingId = 0
  280. item.ChartInfoId = 0
  281. item.IsOrder = false
  282. item.EdbInfoType = 1
  283. item.ChartStyle = ""
  284. item.ChartColor = ""
  285. item.ChartWidth = 0
  286. item.MaxData = v.MaxValue
  287. item.MinData = v.MinValue
  288. } else {
  289. item.IsAxis = v.IsAxis
  290. item.EdbInfoType = v.EdbInfoType
  291. item.LeadValue = v.LeadValue
  292. item.LeadUnit = v.LeadUnit
  293. item.LeadUnitEn = GetLeadUnitEn(v.LeadUnit)
  294. //item.ChartEdbMappingId = v.ChartEdbMappingId
  295. item.ChartInfoId = v.ChartInfoId
  296. item.ChartStyle = v.ChartStyle
  297. item.ChartColor = v.ChartColor
  298. item.ChartWidth = v.ChartWidth
  299. item.IsOrder = v.IsOrder
  300. item.MaxData = v.MaxData
  301. item.MinData = v.MinData
  302. }
  303. item.LatestValue = v.LatestValue
  304. item.LatestDate = v.LatestDate
  305. item.UniqueCode = v.UniqueCode
  306. var startDateReal string
  307. var diffSeconds int64
  308. if chartType == 2 { //季节性图
  309. startDateReal = startDate
  310. } else {
  311. if v.EdbInfoType == 0 && v.LeadUnit != "" && v.LeadValue > 0 { //领先指标
  312. var startTimeRealTemp time.Time
  313. startDateParse, _ := time.Parse(utils.FormatDate, startDate)
  314. switch v.LeadUnit {
  315. case "天":
  316. startTimeRealTemp = startDateParse.AddDate(0, 0, -v.LeadValue)
  317. case "月":
  318. startTimeRealTemp = startDateParse.AddDate(0, -v.LeadValue, 0)
  319. case "季":
  320. startTimeRealTemp = startDateParse.AddDate(0, -3*v.LeadValue, 0)
  321. case "周":
  322. startTimeRealTemp = startDateParse.AddDate(0, 0, -7*v.LeadValue)
  323. case "年":
  324. startTimeRealTemp = startDateParse.AddDate(-v.LeadValue, 0, 0)
  325. }
  326. if startTimeRealTemp.Before(startDateParse) {
  327. startDateReal = startTimeRealTemp.Format(utils.FormatDate)
  328. diffSeconds = (int64(startTimeRealTemp.UnixNano()) - int64(startDateParse.UnixNano())) / 1e6
  329. } else {
  330. startDateReal = startDate
  331. diffSeconds = 0
  332. }
  333. } else {
  334. startDateReal = startDate
  335. }
  336. }
  337. //fmt.Println("line 1011 chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
  338. calendarPreYear := 0
  339. if calendar == "农历" {
  340. newStartDateReal, err := time.Parse(utils.FormatDate, startDateReal)
  341. if err != nil {
  342. fmt.Println("time.Parse:" + err.Error())
  343. }
  344. calendarPreYear = newStartDateReal.Year() - 1
  345. newStartDateReal = newStartDateReal.AddDate(-1, 0, 0)
  346. startDateReal = newStartDateReal.Format(utils.FormatDate)
  347. }
  348. dataList := make([]*models.EdbDataList, 0)
  349. //fmt.Println("chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
  350. switch v.EdbInfoCategoryType {
  351. case 0:
  352. dataList, err = models.GetEdbDataList(v.Source, v.EdbInfoId, startDateReal, endDate)
  353. case 1:
  354. _, dataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(v.EdbInfoId, startDateReal, endDate, false)
  355. default:
  356. err = errors.New(fmt.Sprint("获取失败,指标类型异常", v.EdbInfoCategoryType))
  357. }
  358. if err != nil {
  359. return
  360. }
  361. edbDataListMap[v.EdbInfoId] = dataList
  362. if diffSeconds != 0 && v.EdbInfoType == 0 {
  363. dataListLen := len(dataList)
  364. for i := 0; i < dataListLen; i++ {
  365. dataList[i].DataTimestamp = dataList[i].DataTimestamp - diffSeconds
  366. }
  367. }
  368. if chartType == 2 {
  369. latestDateStr := v.LatestDate //实际数据的截止日期
  370. latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
  371. if tmpErr != nil {
  372. err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + v.LatestDate))
  373. return
  374. }
  375. latestDateYear := latestDate.Year() //实际数据截止年份
  376. if calendar == "农历" {
  377. if len(dataList) <= 0 {
  378. result := new(models.EdbDataResult)
  379. item.DataList = result
  380. } else {
  381. result, tmpErr := models.AddCalculateQuarterV5(dataList)
  382. if tmpErr != nil {
  383. err = errors.New("获取农历数据失败,Err:" + tmpErr.Error())
  384. return
  385. }
  386. // 处理季节图的截止日期
  387. for k, edbDataItems := range result.List {
  388. var cuttingDataTimestamp int64
  389. // 切割的日期时间字符串
  390. cuttingDataTimeStr := latestDate.AddDate(0, 0, edbDataItems.BetweenDay).Format(utils.FormatDate)
  391. //如果等于最后的实际日期,那么遍历找到该日期对应的时间戳,并将其赋值为 切割时间戳
  392. if edbDataItems.Year >= latestDateYear {
  393. for _, tmpData := range edbDataItems.Items {
  394. if tmpData.DataTime == cuttingDataTimeStr {
  395. cuttingDataTimestamp = tmpData.DataTimestamp
  396. break
  397. }
  398. }
  399. }
  400. edbDataItems.CuttingDataTimestamp = cuttingDataTimestamp
  401. result.List[k] = edbDataItems
  402. }
  403. if result.List[0].Year != calendarPreYear {
  404. itemList := make([]*models.EdbDataList, 0)
  405. items := new(models.EdbDataItems)
  406. //items.Year = calendarPreYear
  407. items.Items = itemList
  408. newResult := new(models.EdbDataResult)
  409. newResult.List = append(newResult.List, items)
  410. newResult.List = append(newResult.List, result.List...)
  411. item.DataList = newResult
  412. } else {
  413. item.DataList = result
  414. }
  415. }
  416. } else {
  417. currentYear := time.Now().Year()
  418. quarterDataList := make([]*models.QuarterData, 0)
  419. quarterMap := make(map[int][]*models.EdbDataList)
  420. var quarterArr []int
  421. for _, v := range dataList {
  422. itemDate, tmpErr := time.Parse(utils.FormatDate, v.DataTime)
  423. if tmpErr != nil {
  424. err = errors.New("季度指标日期转换,Err:" + tmpErr.Error() + ";DataTime:" + v.DataTime)
  425. return
  426. }
  427. year := itemDate.Year()
  428. newItemDate := itemDate.AddDate(currentYear-year, 0, 0)
  429. timestamp := newItemDate.UnixNano() / 1e6
  430. v.DataTimestamp = timestamp
  431. if findVal, ok := quarterMap[year]; !ok {
  432. quarterArr = append(quarterArr, year)
  433. findVal = append(findVal, v)
  434. quarterMap[year] = findVal
  435. } else {
  436. findVal = append(findVal, v)
  437. quarterMap[year] = findVal
  438. }
  439. }
  440. for _, v := range quarterArr {
  441. itemList := quarterMap[v]
  442. quarterItem := new(models.QuarterData)
  443. quarterItem.Year = v
  444. quarterItem.DataList = itemList
  445. //如果等于最后的实际日期,那么将切割时间戳记录
  446. if v == latestDateYear {
  447. var cuttingDataTimestamp int64
  448. for _, tmpData := range itemList {
  449. if tmpData.DataTime == latestDateStr {
  450. cuttingDataTimestamp = tmpData.DataTimestamp
  451. break
  452. }
  453. }
  454. quarterItem.CuttingDataTimestamp = cuttingDataTimestamp
  455. } else if v > latestDateYear {
  456. //如果大于最后的实际日期,那么第一个点就是切割的时间戳
  457. if len(itemList) > 0 {
  458. quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
  459. }
  460. }
  461. quarterDataList = append(quarterDataList, quarterItem)
  462. }
  463. item.DataList = quarterDataList
  464. }
  465. } else if chartType == 7 { //柱方图
  466. //item.DataList = dataList
  467. } else {
  468. item.DataList = dataList
  469. }
  470. edbList = append(edbList, item)
  471. }
  472. return
  473. }
  474. // BarChartData 柱方图的数据处理
  475. 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) {
  476. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  477. edbDataMap := make(map[int]map[string]float64)
  478. for edbInfoId, edbDataList := range edbDataListMap {
  479. edbDateData := make(map[string]float64)
  480. for _, edbData := range edbDataList {
  481. edbDateData[edbData.DataTime] = edbData.Value
  482. }
  483. edbDataMap[edbInfoId] = edbDateData
  484. }
  485. // edbIdList 指标展示顺序;x轴的指标顺序
  486. edbIdList = make([]int, 0)
  487. //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
  488. dateData := make(map[int]float64)
  489. if barChartInfoSort.Sort == 0 {
  490. for _, v := range mappingList {
  491. edbIdList = append(edbIdList, v.EdbInfoId)
  492. }
  493. } else {
  494. lenBarChartInfoDateList := len(barChartInfoDateList)
  495. if barChartInfoSort.DateIndex >= lenBarChartInfoDateList {
  496. err = errors.New("排序日期异常")
  497. return
  498. }
  499. notDataEdbIdList := make([]int, 0) //没有数据的指标id
  500. // 日期配置
  501. barChartInfoDate := barChartInfoDateList[barChartInfoSort.DateIndex]
  502. for edbInfoId, dataList := range edbDataListMap {
  503. if len(dataList) <= 0 {
  504. // 没有数据的指标id
  505. notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
  506. continue
  507. }
  508. findDate := barChartInfoDate.Date
  509. switch barChartInfoDate.Type {
  510. case 1: //最新值
  511. findDate = dataList[len(dataList)-1].DataTime
  512. case 2: //近期几天
  513. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  514. if tmpErr != nil {
  515. err = tmpErr
  516. return
  517. }
  518. findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  519. lenData := len(dataList) - 1
  520. for i := lenData; i >= 0; i-- {
  521. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  522. if tmpErr != nil {
  523. err = tmpErr
  524. return
  525. }
  526. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  527. findDate = dataList[i].DataTime
  528. break
  529. }
  530. }
  531. case 3: // 固定日期
  532. //最早的日期
  533. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  534. if tmpErr != nil {
  535. err = tmpErr
  536. return
  537. }
  538. //寻找固定日期的数据
  539. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  540. if tmpErr != nil {
  541. err = tmpErr
  542. return
  543. }
  544. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  545. tmpDate := tmpDateTime.Format(utils.FormatDate)
  546. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  547. findDate = tmpDate
  548. break
  549. }
  550. }
  551. default:
  552. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  553. return
  554. }
  555. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  556. dateData[edbInfoId] = tmpValue
  557. } else {
  558. // 没有数据的指标id
  559. notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
  560. }
  561. }
  562. //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
  563. // 排序
  564. dateDataSort := utils.NewMapSorter(dateData)
  565. sort.Sort(dateDataSort)
  566. if barChartInfoSort.Sort == 1 {
  567. // 先将没有数据的指标id放在最前面
  568. if len(notDataEdbIdList) > 0 {
  569. edbIdList = append(edbIdList, notDataEdbIdList...)
  570. }
  571. for _, v := range dateDataSort {
  572. edbIdList = append(edbIdList, v.Key)
  573. }
  574. } else {
  575. for i := len(dateDataSort) - 1; i >= 0; i-- {
  576. edbIdList = append(edbIdList, dateDataSort[i].Key)
  577. }
  578. // 再将没有数据的指标id放在最后面
  579. if len(notDataEdbIdList) > 0 {
  580. edbIdList = append(edbIdList, notDataEdbIdList...)
  581. }
  582. }
  583. }
  584. yDataList = make([]models.YData, 0) //y轴的数据列表
  585. for _, barChartInfoDate := range barChartInfoDateList {
  586. var maxDate time.Time
  587. findDataList := make([]float64, 0) // 当前日期的数据值
  588. for _, edbInfoId := range edbIdList {
  589. findDate := barChartInfoDate.Date //需要的日期值
  590. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  591. if len(dataList) <= 0 {
  592. // 没有数据的指标id
  593. findDataList = append(findDataList, 0)
  594. continue
  595. }
  596. switch barChartInfoDate.Type {
  597. case 1: //最新值
  598. dataList := edbDataListMap[edbInfoId]
  599. findDate = dataList[len(dataList)-1].DataTime
  600. case 2: //近期几天
  601. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  602. if tmpErr != nil {
  603. err = tmpErr
  604. return
  605. }
  606. findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  607. lenData := len(dataList) - 1
  608. for i := lenData; i >= 0; i-- {
  609. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  610. if tmpErr != nil {
  611. err = tmpErr
  612. return
  613. }
  614. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  615. findDate = dataList[i].DataTime
  616. break
  617. }
  618. }
  619. case 3: // 固定日期
  620. //最早的日期
  621. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  622. if tmpErr != nil {
  623. err = tmpErr
  624. return
  625. }
  626. //寻找固定日期的数据
  627. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  628. if tmpErr != nil {
  629. err = tmpErr
  630. return
  631. }
  632. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  633. tmpDate := tmpDateTime.Format(utils.FormatDate)
  634. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  635. findDate = tmpDate
  636. break
  637. }
  638. }
  639. default:
  640. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  641. return
  642. }
  643. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  644. if maxDate.IsZero() {
  645. maxDate = findDateTime
  646. } else {
  647. if findDateTime.After(maxDate) {
  648. maxDate = findDateTime
  649. }
  650. }
  651. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  652. findDataList = append(findDataList, tmpValue)
  653. } else {
  654. findDataList = append(findDataList, 0)
  655. }
  656. }
  657. yDate := "0000-00-00"
  658. if !maxDate.IsZero() {
  659. yDate = maxDate.Format(utils.FormatDate)
  660. }
  661. yDataList = append(yDataList, models.YData{
  662. Date: yDate,
  663. Value: findDataList,
  664. Color: barChartInfoDate.Color,
  665. Name: barChartInfoDate.Name,
  666. })
  667. }
  668. return
  669. }
  670. // ChartInfoRefreshV2 图表刷新
  671. // @author Roc
  672. // @datetime 2022-09-16 10:15:38
  673. // @description 将原来自己写的一套获取所有关联指标,然后刷新指标逻辑 改成 只获取使用的指标id,然后遍历去调用“指标刷新服务”
  674. func ChartInfoRefreshV2(chartInfoId int) (err error) {
  675. var errmsg string
  676. defer func() {
  677. if err != nil {
  678. go alarm_msg.SendAlarmMsg("ChartInfoRefresh:"+errmsg, 3)
  679. //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "ChartInfoRefresh:"+errmsg, utils.EmailSendToUsers)
  680. fmt.Println("ChartInfoRefresh Err:" + errmsg)
  681. }
  682. }()
  683. edbMappingList, err := data_manage.GetChartEdbMappingList(chartInfoId)
  684. if err != nil {
  685. errmsg = "获取需要刷新的指标失败:Err:" + err.Error()
  686. return
  687. }
  688. edbIdList := make([]int, 0)
  689. for _, v := range edbMappingList {
  690. edbIdList = append(edbIdList, v.EdbInfoId)
  691. }
  692. // 批量刷新
  693. err, errmsg = EdbInfoRefreshAllFromBase(edbIdList, false)
  694. if err != nil {
  695. return
  696. }
  697. return
  698. }
  699. // GetSectionScatterChartData 柱方图的数据处理
  700. func GetSectionScatterChartData(mappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, extraConfig data_manage.SectionScatterReq) (edbIdList []int, chartDataResp data_manage.SectionScatterInfoResp, err error) {
  701. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  702. edbDataMap := make(map[int]map[string]float64)
  703. for edbInfoId, edbDataList := range edbDataListMap {
  704. edbDateData := make(map[string]float64)
  705. for _, edbData := range edbDataList {
  706. edbDateData[edbData.DataTime] = edbData.Value
  707. }
  708. edbDataMap[edbInfoId] = edbDateData
  709. }
  710. // edbIdList 指标展示顺序;x轴的指标顺序
  711. edbIdList = make([]int, 0)
  712. edbMappingMap := make(map[int]*models.ChartEdbInfoMapping)
  713. for _, v := range mappingList {
  714. edbIdList = append(edbIdList, v.EdbInfoId)
  715. edbMappingMap[v.EdbInfoId] = v
  716. }
  717. //SectionScatterSeriesInfoResp
  718. dataListResp := make([]data_manage.SectionScatterSeriesItemResp, 0) //y轴的数据列表
  719. for _, seriesItem := range extraConfig.SeriesList {
  720. var maxDate time.Time
  721. // 系列中的指标数据
  722. tmpSeriesEdbInfoList := make([]data_manage.SectionScatterEdbItemResp, 0)
  723. var minXVal, maxXVal, minYVal, maxYVal float64
  724. for _, edbConf := range seriesItem.EdbInfoList {
  725. tmpItem := data_manage.SectionScatterEdbItemResp{
  726. IsShow: edbConf.IsShow,
  727. Name: edbConf.Name,
  728. NameEn: edbConf.NameEn,
  729. } //单个坐标点的数据
  730. //X轴的数据
  731. {
  732. edbInfoId := edbConf.XEdbInfoId //X轴的指标
  733. edbMappingInfo, ok := edbMappingMap[edbInfoId]
  734. if !ok {
  735. continue
  736. }
  737. findDate := edbConf.XDate //需要的日期值
  738. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  739. if len(dataList) <= 0 {
  740. // 没有数据的指标id
  741. //findDataList = append(findDataList, 0)
  742. continue
  743. }
  744. tmpItem.XEdbInfoId = edbInfoId
  745. tmpItem.XName = edbMappingInfo.EdbName
  746. tmpItem.XNameEn = edbMappingInfo.EdbNameEn
  747. switch edbConf.XDateType {
  748. case 1: //最新值
  749. dataList := edbDataListMap[edbInfoId]
  750. findDate = dataList[len(dataList)-1].DataTime
  751. case 2: //近期几天
  752. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  753. if tmpErr != nil {
  754. err = tmpErr
  755. return
  756. }
  757. findDateTime = findDateTime.AddDate(0, 0, -edbConf.XDateValue)
  758. lenData := len(dataList) - 1
  759. for i := lenData; i >= 0; i-- {
  760. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  761. if tmpErr != nil {
  762. err = tmpErr
  763. return
  764. }
  765. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  766. findDate = dataList[i].DataTime
  767. break
  768. }
  769. }
  770. case 3: // 固定日期
  771. //最早的日期
  772. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  773. if tmpErr != nil {
  774. err = tmpErr
  775. return
  776. }
  777. //寻找固定日期的数据
  778. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.XDate, time.Local)
  779. if tmpErr != nil {
  780. err = tmpErr
  781. return
  782. }
  783. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  784. tmpDate := tmpDateTime.Format(utils.FormatDate)
  785. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  786. findDate = tmpDate
  787. break
  788. }
  789. }
  790. default:
  791. err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.XDate))
  792. return
  793. }
  794. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  795. if maxDate.IsZero() {
  796. maxDate = findDateTime
  797. } else {
  798. if findDateTime.After(maxDate) {
  799. maxDate = findDateTime
  800. }
  801. }
  802. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  803. tmpItem.XDate = findDate
  804. tmpItem.XValue = tmpValue
  805. } else {
  806. continue
  807. }
  808. }
  809. //Y轴的数据
  810. {
  811. edbInfoId := edbConf.YEdbInfoId //Y轴的指标
  812. edbMappingInfo, ok := edbMappingMap[edbInfoId]
  813. if !ok {
  814. continue
  815. }
  816. findDate := edbConf.YDate //需要的日期值
  817. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  818. if len(dataList) <= 0 {
  819. // 没有数据的指标id
  820. //findDataList = append(findDataList, 0)
  821. continue
  822. }
  823. tmpItem.YEdbInfoId = edbInfoId
  824. tmpItem.YName = edbMappingInfo.EdbName
  825. tmpItem.YNameEn = edbMappingInfo.EdbNameEn
  826. switch edbConf.YDateType {
  827. case 1: //最新值
  828. dataList := edbDataListMap[edbInfoId]
  829. findDate = dataList[len(dataList)-1].DataTime
  830. case 2: //近期几天
  831. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  832. if tmpErr != nil {
  833. err = tmpErr
  834. return
  835. }
  836. findDateTime = findDateTime.AddDate(0, 0, -edbConf.YDateValue)
  837. lenData := len(dataList) - 1
  838. for i := lenData; i >= 0; i-- {
  839. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  840. if tmpErr != nil {
  841. err = tmpErr
  842. return
  843. }
  844. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  845. findDate = dataList[i].DataTime
  846. break
  847. }
  848. }
  849. case 3: // 固定日期
  850. //最早的日期
  851. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  852. if tmpErr != nil {
  853. err = tmpErr
  854. return
  855. }
  856. //寻找固定日期的数据
  857. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.YDate, time.Local)
  858. if tmpErr != nil {
  859. err = tmpErr
  860. return
  861. }
  862. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  863. tmpDate := tmpDateTime.Format(utils.FormatDate)
  864. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  865. findDate = tmpDate
  866. break
  867. }
  868. }
  869. default:
  870. err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.YDate))
  871. return
  872. }
  873. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  874. if maxDate.IsZero() {
  875. maxDate = findDateTime
  876. } else {
  877. if findDateTime.After(maxDate) {
  878. maxDate = findDateTime
  879. }
  880. }
  881. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  882. tmpItem.YDate = findDate
  883. tmpItem.YValue = tmpValue
  884. } else {
  885. continue
  886. }
  887. }
  888. // 获取当前系列的X轴的最大最小值
  889. {
  890. if tmpItem.XValue < minXVal {
  891. minXVal = tmpItem.XValue
  892. }
  893. if tmpItem.XValue > maxXVal {
  894. maxXVal = tmpItem.XValue
  895. }
  896. if tmpItem.YValue < minYVal {
  897. minYVal = tmpItem.YValue
  898. }
  899. if tmpItem.YValue > maxYVal {
  900. maxYVal = tmpItem.YValue
  901. }
  902. }
  903. tmpSeriesEdbInfoList = append(tmpSeriesEdbInfoList, tmpItem)
  904. }
  905. trendLimitData := make([]data_manage.CoordinatePoint, 0) //趋势线的前后坐标点
  906. var trendLine, rSquare string
  907. // 生成线性方程式
  908. var a, b float64
  909. {
  910. coordinateData := make([]utils.Coordinate, 0)
  911. for _, tmpSeriesEdbInfo := range tmpSeriesEdbInfoList {
  912. tmpCoordinate1 := utils.Coordinate{
  913. X: tmpSeriesEdbInfo.XValue,
  914. Y: tmpSeriesEdbInfo.YValue,
  915. }
  916. coordinateData = append(coordinateData, tmpCoordinate1)
  917. }
  918. // 只有存在两个坐标点的时候,才能去计算线性方程和R平方
  919. if len(coordinateData) >= 2 {
  920. a, b = utils.GetLinearResult(coordinateData)
  921. if !math.IsNaN(a) || !math.IsNaN(b) {
  922. if b > 0 {
  923. trendLine = fmt.Sprintf("y=%sx+%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
  924. } else {
  925. trendLine = fmt.Sprintf("y=%sx%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
  926. }
  927. minYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(minXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
  928. maxYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(maxXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
  929. }
  930. // 计算R平方
  931. rSquare = fmt.Sprint(utils.CalculationDecisive(coordinateData))
  932. }
  933. trendLimitData = append(trendLimitData, data_manage.CoordinatePoint{
  934. X: minXVal,
  935. Y: minYVal,
  936. }, data_manage.CoordinatePoint{
  937. X: maxXVal,
  938. Y: maxYVal,
  939. })
  940. }
  941. dataListResp = append(dataListResp, data_manage.SectionScatterSeriesItemResp{
  942. Name: seriesItem.Name,
  943. NameEn: seriesItem.NameEn,
  944. Color: seriesItem.Color,
  945. EdbInfoList: tmpSeriesEdbInfoList,
  946. ShowTrendLine: seriesItem.ShowTrendLine,
  947. ShowFitEquation: seriesItem.ShowFitEquation,
  948. ShowRSquare: seriesItem.ShowRSquare,
  949. TrendLine: trendLine,
  950. RSquare: rSquare,
  951. TrendLimitData: trendLimitData,
  952. })
  953. }
  954. chartDataResp = data_manage.SectionScatterInfoResp{
  955. XName: extraConfig.XName,
  956. XNameEn: extraConfig.XNameEn,
  957. XUnitName: extraConfig.XUnitName,
  958. XUnitNameEn: extraConfig.XUnitNameEn,
  959. YName: extraConfig.YName,
  960. YNameEn: extraConfig.YNameEn,
  961. YUnitName: extraConfig.YUnitName,
  962. YUnitNameEn: extraConfig.YUnitNameEn,
  963. XMinValue: extraConfig.XMinValue,
  964. XMaxValue: extraConfig.XMaxValue,
  965. YMinValue: extraConfig.YMinValue,
  966. YMaxValue: extraConfig.YMaxValue,
  967. DataList: dataListResp,
  968. }
  969. return
  970. }