chart_info.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. package future_good
  2. import (
  3. "errors"
  4. "fmt"
  5. "hongze/hongze_chart_lib/models"
  6. "hongze/hongze_chart_lib/models/data_manage"
  7. efuture_good "hongze/hongze_chart_lib/models/data_manage/future_good"
  8. "hongze/hongze_chart_lib/services/alarm_msg"
  9. "hongze/hongze_chart_lib/services/data"
  10. "hongze/hongze_chart_lib/utils"
  11. "sort"
  12. "strconv"
  13. "time"
  14. )
  15. // GetChartEdbData 获取图表的指标数据
  16. func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping, futureGoodEdbInfoMapping *models.ChartEdbInfoMapping, barChartInfoDateList []data_manage.BarChartInfoDateReq, barChartInfoSort data_manage.BarChartInfoSortReq) (barConfigEdbInfoIdList []data_manage.BarChartInfoEdbItemReq, edbList []*models.ChartEdbInfoMapping, xEdbIdValue []int, yDataList []models.YData, err error) {
  17. edbList = make([]*models.ChartEdbInfoMapping, 0)
  18. if futureGoodEdbInfoMapping == nil {
  19. err = errors.New("商品指标未选取")
  20. return
  21. }
  22. if edbInfoMapping == nil {
  23. err = errors.New("ETA指标未选取")
  24. return
  25. }
  26. // 指标对应的所有数据
  27. edbDataListMap := make(map[int][]*models.EdbDataList)
  28. item := new(data_manage.ChartEdbInfoMapping)
  29. edbInfoMapping.FrequencyEn = data.GetFrequencyEn(edbInfoMapping.Frequency)
  30. if edbInfoMapping.Unit == `无` {
  31. edbInfoMapping.Unit = ``
  32. }
  33. if futureGoodEdbInfoMapping.Unit == `无` {
  34. futureGoodEdbInfoMapping.Unit = ``
  35. }
  36. if chartInfoId <= 0 {
  37. edbInfoMapping.IsAxis = 1
  38. edbInfoMapping.LeadValue = 0
  39. edbInfoMapping.LeadUnit = ""
  40. edbInfoMapping.ChartEdbMappingId = 0
  41. edbInfoMapping.ChartInfoId = 0
  42. edbInfoMapping.IsOrder = false
  43. edbInfoMapping.EdbInfoType = 1
  44. edbInfoMapping.ChartStyle = ""
  45. edbInfoMapping.ChartColor = ""
  46. edbInfoMapping.ChartWidth = 0
  47. futureGoodEdbInfoMapping.IsAxis = 1
  48. futureGoodEdbInfoMapping.LeadValue = 0
  49. futureGoodEdbInfoMapping.LeadUnit = ""
  50. futureGoodEdbInfoMapping.ChartEdbMappingId = 0
  51. futureGoodEdbInfoMapping.ChartInfoId = 0
  52. futureGoodEdbInfoMapping.IsOrder = false
  53. futureGoodEdbInfoMapping.EdbInfoType = 1
  54. futureGoodEdbInfoMapping.ChartStyle = ""
  55. futureGoodEdbInfoMapping.ChartColor = ""
  56. futureGoodEdbInfoMapping.ChartWidth = 0
  57. } else {
  58. edbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(edbInfoMapping.LeadUnit)
  59. futureGoodEdbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(futureGoodEdbInfoMapping.LeadUnit)
  60. }
  61. // 普通的指标数据
  62. {
  63. dataList := make([]*models.EdbDataList, 0)
  64. dataList, err = models.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.EdbInfoId, startDate, endDate)
  65. edbDataListMap[edbInfoMapping.EdbInfoId] = dataList
  66. item.DataList = dataList
  67. edbList = append(edbList, edbInfoMapping)
  68. barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, data_manage.BarChartInfoEdbItemReq{
  69. EdbInfoId: edbInfoMapping.EdbInfoId,
  70. //Name: edbInfoMapping.EdbName,
  71. Name: "现货价",
  72. NameEn: "Spot Price",
  73. Source: edbInfoMapping.Source,
  74. })
  75. }
  76. nowMonth := time.Now().Month()
  77. // 获取期货指标以及期货数据
  78. futureGoodEdbInfoList, err := efuture_good.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
  79. if err != nil {
  80. return
  81. }
  82. futureGoodMappingList := make([]*models.ChartEdbInfoMapping, 0)
  83. //当前月份之后的月
  84. nextFutureGoodEdbInfoList := make([]*efuture_good.FutureGoodEdbInfo, 0)
  85. for k, v := range futureGoodEdbInfoList {
  86. // 过滤当前月
  87. if v.Month == int(nowMonth) {
  88. continue
  89. }
  90. if v.Month < int(nowMonth) {
  91. nextFutureGoodEdbInfoList = append(nextFutureGoodEdbInfoList, v)
  92. continue
  93. }
  94. newMappingInfo := &models.ChartEdbInfoMapping{
  95. EdbInfoId: v.FutureGoodEdbInfoId,
  96. SourceName: v.Exchange,
  97. Source: utils.CHART_SOURCE_FUTURE_GOOD,
  98. EdbCode: v.FutureGoodEdbCode,
  99. EdbName: v.FutureGoodEdbName,
  100. EdbAliasName: v.FutureGoodEdbName,
  101. EdbNameEn: v.FutureGoodEdbNameEn,
  102. EdbType: edbInfoMapping.EdbType,
  103. Frequency: edbInfoMapping.Frequency,
  104. FrequencyEn: edbInfoMapping.FrequencyEn,
  105. Unit: edbInfoMapping.Unit,
  106. UnitEn: edbInfoMapping.UnitEn,
  107. StartDate: v.StartDate,
  108. EndDate: v.EndDate,
  109. ModifyTime: v.ModifyTime.Format(utils.FormatDateTime),
  110. ChartEdbMappingId: v.FutureGoodEdbInfoId,
  111. ChartInfoId: edbInfoMapping.ChartInfoId,
  112. MaxData: v.MaxValue,
  113. MinData: v.MinValue,
  114. IsOrder: edbInfoMapping.IsOrder,
  115. IsAxis: edbInfoMapping.IsAxis,
  116. EdbInfoType: edbInfoMapping.EdbInfoType,
  117. EdbInfoCategoryType: edbInfoMapping.EdbInfoCategoryType,
  118. LeadValue: edbInfoMapping.LeadValue,
  119. LeadUnit: edbInfoMapping.LeadUnit,
  120. LeadUnitEn: edbInfoMapping.LeadUnitEn,
  121. ChartStyle: edbInfoMapping.ChartStyle,
  122. ChartColor: edbInfoMapping.ChartColor,
  123. PredictChartColor: edbInfoMapping.PredictChartColor,
  124. ChartWidth: edbInfoMapping.ChartWidth,
  125. ChartType: edbInfoMapping.ChartType,
  126. LatestDate: v.LatestDate.Format(utils.FormatDateTime),
  127. LatestValue: v.LatestValue,
  128. UniqueCode: futureGoodEdbInfoMapping.UniqueCode + strconv.Itoa(k),
  129. MinValue: v.MinValue,
  130. MaxValue: v.MaxValue,
  131. DataList: nil,
  132. IsNullData: false,
  133. }
  134. futureGoodMappingList = append(futureGoodMappingList, newMappingInfo)
  135. barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, data_manage.BarChartInfoEdbItemReq{
  136. EdbInfoId: newMappingInfo.EdbInfoId,
  137. Name: fmt.Sprint("M+", v.Month),
  138. NameEn: fmt.Sprint("M+", v.Month),
  139. Source: newMappingInfo.Source,
  140. })
  141. }
  142. //当前月份之前的月
  143. for k, v := range nextFutureGoodEdbInfoList {
  144. newMappingInfo := &models.ChartEdbInfoMapping{
  145. EdbInfoId: v.FutureGoodEdbInfoId,
  146. SourceName: v.Exchange,
  147. Source: utils.CHART_SOURCE_FUTURE_GOOD,
  148. EdbCode: v.FutureGoodEdbCode,
  149. EdbName: v.FutureGoodEdbName,
  150. EdbAliasName: v.FutureGoodEdbName,
  151. EdbNameEn: v.FutureGoodEdbNameEn,
  152. EdbType: edbInfoMapping.EdbType,
  153. Frequency: edbInfoMapping.Frequency,
  154. FrequencyEn: edbInfoMapping.FrequencyEn,
  155. Unit: edbInfoMapping.Unit,
  156. UnitEn: edbInfoMapping.UnitEn,
  157. StartDate: v.StartDate,
  158. EndDate: v.EndDate,
  159. ModifyTime: v.ModifyTime.Format(utils.FormatDateTime),
  160. ChartEdbMappingId: v.FutureGoodEdbInfoId,
  161. ChartInfoId: edbInfoMapping.ChartInfoId,
  162. MaxData: v.MaxValue,
  163. MinData: v.MinValue,
  164. IsOrder: edbInfoMapping.IsOrder,
  165. IsAxis: edbInfoMapping.IsAxis,
  166. EdbInfoType: edbInfoMapping.EdbInfoType,
  167. EdbInfoCategoryType: edbInfoMapping.EdbInfoCategoryType,
  168. LeadValue: edbInfoMapping.LeadValue,
  169. LeadUnit: edbInfoMapping.LeadUnit,
  170. LeadUnitEn: edbInfoMapping.LeadUnitEn,
  171. ChartStyle: edbInfoMapping.ChartStyle,
  172. ChartColor: edbInfoMapping.ChartColor,
  173. PredictChartColor: edbInfoMapping.PredictChartColor,
  174. ChartWidth: edbInfoMapping.ChartWidth,
  175. ChartType: edbInfoMapping.ChartType,
  176. LatestDate: v.LatestDate.Format(utils.FormatDateTime),
  177. LatestValue: v.LatestValue,
  178. UniqueCode: futureGoodEdbInfoMapping.UniqueCode + "1" + strconv.Itoa(k),
  179. MinValue: v.MinValue,
  180. MaxValue: v.MaxValue,
  181. DataList: nil,
  182. IsNullData: false,
  183. }
  184. futureGoodMappingList = append(futureGoodMappingList, newMappingInfo)
  185. barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, data_manage.BarChartInfoEdbItemReq{
  186. EdbInfoId: newMappingInfo.EdbInfoId,
  187. Name: fmt.Sprint("M+", v.Month),
  188. NameEn: fmt.Sprint("M+", v.Month),
  189. Source: newMappingInfo.Source,
  190. })
  191. }
  192. // 获取数据
  193. for _, v := range futureGoodMappingList {
  194. dataList := make([]*models.EdbDataList, 0)
  195. tmpDataList, tmpErr := efuture_good.GetFutureGoodEdbDataListByDate(v.EdbInfoId, startDate, endDate)
  196. if tmpErr != nil {
  197. return
  198. }
  199. for _, tmpData := range tmpDataList {
  200. dataList = append(dataList, &models.EdbDataList{
  201. EdbDataId: tmpData.FutureGoodEdbDataId,
  202. EdbInfoId: tmpData.FutureGoodEdbInfoId,
  203. DataTime: tmpData.DataTime.Format(utils.FormatDate),
  204. DataTimestamp: tmpData.DataTimestamp,
  205. Value: tmpData.Close,
  206. })
  207. }
  208. edbDataListMap[v.EdbInfoId] = dataList
  209. v.DataList = dataList
  210. }
  211. edbList = append(edbList, futureGoodMappingList...)
  212. xEdbIdValue, yDataList, err = BarChartData(edbList, edbDataListMap, barChartInfoDateList, barChartInfoSort)
  213. return
  214. }
  215. // BarChartData 柱方图的数据处理
  216. 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) {
  217. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  218. edbDataMap := make(map[int]map[string]float64)
  219. for edbInfoId, edbDataList := range edbDataListMap {
  220. edbDateData := make(map[string]float64)
  221. for _, edbData := range edbDataList {
  222. edbDateData[edbData.DataTime] = edbData.Value
  223. }
  224. edbDataMap[edbInfoId] = edbDateData
  225. }
  226. // edbIdList 指标展示顺序;x轴的指标顺序
  227. edbIdList = make([]int, 0)
  228. //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
  229. dateData := make(map[int]float64)
  230. if barChartInfoSort.Sort == 0 {
  231. for _, v := range mappingList {
  232. edbIdList = append(edbIdList, v.EdbInfoId)
  233. }
  234. } else {
  235. lenBarChartInfoDateList := len(barChartInfoDateList)
  236. if barChartInfoSort.DateIndex >= lenBarChartInfoDateList {
  237. err = errors.New("排序日期异常")
  238. return
  239. }
  240. notDataEdbIdList := make([]int, 0) //没有数据的指标id
  241. // 日期配置
  242. barChartInfoDate := barChartInfoDateList[barChartInfoSort.DateIndex]
  243. for edbInfoId, dataList := range edbDataListMap {
  244. if len(dataList) <= 0 {
  245. // 没有数据的指标id
  246. notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
  247. continue
  248. }
  249. findDate := barChartInfoDate.Date
  250. switch barChartInfoDate.Type {
  251. case 1: //最新值
  252. findDate = dataList[len(dataList)-1].DataTime
  253. case 2: //近期几天
  254. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  255. if tmpErr != nil {
  256. err = tmpErr
  257. return
  258. }
  259. findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  260. lenData := len(dataList) - 1
  261. for i := lenData; i >= 0; i-- {
  262. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  263. if tmpErr != nil {
  264. err = tmpErr
  265. return
  266. }
  267. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  268. findDate = dataList[i].DataTime
  269. break
  270. }
  271. }
  272. case 3: // 固定日期
  273. //最早的日期
  274. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  275. if tmpErr != nil {
  276. err = tmpErr
  277. return
  278. }
  279. //寻找固定日期的数据
  280. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  281. if tmpErr != nil {
  282. err = tmpErr
  283. return
  284. }
  285. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  286. tmpDate := tmpDateTime.Format(utils.FormatDate)
  287. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  288. findDate = tmpDate
  289. break
  290. }
  291. }
  292. default:
  293. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  294. return
  295. }
  296. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  297. dateData[edbInfoId] = tmpValue
  298. } else {
  299. // 没有数据的指标id
  300. notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
  301. }
  302. }
  303. //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
  304. // 排序
  305. dateDataSort := utils.NewMapSorter(dateData)
  306. sort.Sort(dateDataSort)
  307. if barChartInfoSort.Sort == 1 {
  308. // 先将没有数据的指标id放在最前面
  309. if len(notDataEdbIdList) > 0 {
  310. edbIdList = append(edbIdList, notDataEdbIdList...)
  311. }
  312. for _, v := range dateDataSort {
  313. edbIdList = append(edbIdList, v.Key)
  314. }
  315. } else {
  316. for i := len(dateDataSort) - 1; i >= 0; i-- {
  317. edbIdList = append(edbIdList, dateDataSort[i].Key)
  318. }
  319. // 再将没有数据的指标id放在最后面
  320. if len(notDataEdbIdList) > 0 {
  321. edbIdList = append(edbIdList, notDataEdbIdList...)
  322. }
  323. }
  324. }
  325. yDataList = make([]models.YData, 0) //y轴的数据列表
  326. for _, barChartInfoDate := range barChartInfoDateList {
  327. var maxDate time.Time
  328. findDataList := make([]float64, 0) // 当前日期的数据值
  329. for _, edbInfoId := range edbIdList {
  330. findDate := barChartInfoDate.Date //需要的日期值
  331. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  332. if len(dataList) <= 0 {
  333. // 没有数据的指标id
  334. findDataList = append(findDataList, 0)
  335. continue
  336. }
  337. switch barChartInfoDate.Type {
  338. case 1: //最新值
  339. dataList := edbDataListMap[edbInfoId]
  340. findDate = dataList[len(dataList)-1].DataTime
  341. case 2: //近期几天
  342. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  343. if tmpErr != nil {
  344. err = tmpErr
  345. return
  346. }
  347. findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  348. lenData := len(dataList) - 1
  349. for i := lenData; i >= 0; i-- {
  350. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  351. if tmpErr != nil {
  352. err = tmpErr
  353. return
  354. }
  355. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  356. findDate = dataList[i].DataTime
  357. break
  358. }
  359. }
  360. case 3: // 固定日期
  361. //最早的日期
  362. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  363. if tmpErr != nil {
  364. err = tmpErr
  365. return
  366. }
  367. //寻找固定日期的数据
  368. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  369. if tmpErr != nil {
  370. err = tmpErr
  371. return
  372. }
  373. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  374. tmpDate := tmpDateTime.Format(utils.FormatDate)
  375. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  376. findDate = tmpDate
  377. break
  378. }
  379. }
  380. default:
  381. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  382. return
  383. }
  384. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  385. if maxDate.IsZero() {
  386. maxDate = findDateTime
  387. } else {
  388. if findDateTime.After(maxDate) {
  389. maxDate = findDateTime
  390. }
  391. }
  392. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  393. findDataList = append(findDataList, tmpValue)
  394. } else {
  395. findDataList = append(findDataList, 0)
  396. }
  397. }
  398. yName := barChartInfoDate.Name
  399. yNameEn := barChartInfoDate.Name
  400. if yName == `` {
  401. if barChartInfoDate.Type == 2 {
  402. yName = strconv.Itoa(barChartInfoDate.Value) + "天前"
  403. if barChartInfoDate.Value == 1 {
  404. yNameEn = strconv.Itoa(barChartInfoDate.Value) + "day ago"
  405. } else {
  406. yNameEn = strconv.Itoa(barChartInfoDate.Value) + " days ago"
  407. }
  408. } else {
  409. yName = maxDate.Format(utils.FormatDate)
  410. yNameEn = maxDate.Format(utils.FormatDate)
  411. }
  412. }
  413. yDataList = append(yDataList, models.YData{
  414. Date: maxDate.Format(utils.FormatDate),
  415. Value: findDataList,
  416. Color: barChartInfoDate.Color,
  417. Name: yName,
  418. NameEn: yNameEn,
  419. })
  420. }
  421. return
  422. }
  423. // FutureGoodChartInfoRefresh
  424. // @author Roc
  425. // @datetime 2023-2-2 18:44:46
  426. // @description 商品价格曲线图表刷新
  427. func FutureGoodChartInfoRefresh(chartInfoId int) (err error) {
  428. var errMsg string
  429. defer func() {
  430. if err != nil {
  431. go alarm_msg.SendAlarmMsg("ChartInfoRefresh:"+errMsg, 3)
  432. fmt.Println("ChartInfoRefresh Err:" + errMsg)
  433. }
  434. }()
  435. edbInfoMapping, err := models.GetEtaEdbChartEdbMapping(chartInfoId)
  436. if err != nil {
  437. errMsg = "获取需要刷新的ETA指标失败:Err:" + err.Error()
  438. return
  439. }
  440. // 获取期货指标
  441. futureGoodEdbInfoMapping, err := models.GetFutureGoodEdbChartEdbMapping(chartInfoId)
  442. if err != nil {
  443. errMsg = "获取需要刷新的商品期货指标失败:Err:" + err.Error()
  444. return
  445. }
  446. // 获取期货指标以及期货数据
  447. futureGoodEdbInfoList, err := efuture_good.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
  448. if err != nil {
  449. return
  450. }
  451. // 批量刷新ETA指标
  452. err, _ = data.EdbInfoRefreshAllFromBase([]int{edbInfoMapping.EdbInfoId}, false)
  453. if err != nil {
  454. return
  455. }
  456. // 批量刷新期货指标
  457. err = FutureGoodEdbInfoRefreshAllFromBase(futureGoodEdbInfoList, false)
  458. if err != nil {
  459. return
  460. }
  461. return
  462. }