ai_predict_model_index.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package services
  2. import (
  3. "encoding/json"
  4. aiPredictModel "eta/eta_mobile/models/ai_predict_model"
  5. "eta/eta_mobile/models/data_manage"
  6. "eta/eta_mobile/services/data"
  7. "eta/eta_mobile/utils"
  8. "fmt"
  9. "sort"
  10. "time"
  11. )
  12. func GetAiPredictChartDetailByData(indexItem *aiPredictModel.AiPredictModelIndex, indexData []*aiPredictModel.AiPredictModelData, source int) (resp *data_manage.ChartInfoDetailResp, err error) {
  13. resp = new(data_manage.ChartInfoDetailResp)
  14. // 标的配置
  15. var extraConfig aiPredictModel.AiPredictModelIndexExtraConfig
  16. if indexItem.ExtraConfig != "" {
  17. if e := json.Unmarshal([]byte(indexItem.ExtraConfig), &extraConfig); e != nil {
  18. err = fmt.Errorf("标的额外配置解析失败, Config: %s, Err: %v", indexItem.ExtraConfig, e)
  19. return
  20. }
  21. }
  22. // 图表信息
  23. var predictLegendName, confLeftMin, confLeftMax, unit string
  24. if source == aiPredictModel.ModelDataSourceDaily {
  25. predictLegendName = extraConfig.DailyChart.PredictLegendName
  26. if predictLegendName == "" {
  27. predictLegendName = "Predicted"
  28. }
  29. unit = extraConfig.DailyChart.Unit
  30. confLeftMin = extraConfig.DailyChart.LeftMin
  31. confLeftMax = extraConfig.DailyChart.LeftMax
  32. }
  33. if source == aiPredictModel.ModelDataSourceMonthly {
  34. predictLegendName = "预测值"
  35. unit = extraConfig.MonthlyChart.Unit
  36. confLeftMin = extraConfig.MonthlyChart.LeftMin
  37. confLeftMax = extraConfig.MonthlyChart.LeftMax
  38. }
  39. // 这里简单兼容下吧,暂时就不修数据了
  40. if confLeftMin == "" {
  41. confLeftMin = indexItem.LeftMin
  42. }
  43. if confLeftMax == "" {
  44. confLeftMax = indexItem.LeftMax
  45. }
  46. // 获取指标对应的图表
  47. chartSourceMapping := map[int]int{
  48. aiPredictModel.ModelDataSourceMonthly: utils.CHART_SOURCE_AI_PREDICT_MODEL_MONTHLY,
  49. aiPredictModel.ModelDataSourceDaily: utils.CHART_SOURCE_AI_PREDICT_MODEL_DAILY,
  50. }
  51. chartInfo, e := data_manage.GetAiPredictChartInfoByIndexId(chartSourceMapping[source], indexItem.AiPredictModelIndexId)
  52. if e != nil && e.Error() != utils.ErrNoRow() {
  53. err = fmt.Errorf("获取标的图表失败, %v", e)
  54. return
  55. }
  56. // 获取曲线图主题样式
  57. chartView := new(data_manage.ChartInfoView)
  58. if chartInfo != nil && chartInfo.ChartInfoId > 0 {
  59. chartView.ChartInfoId = chartInfo.ChartInfoId
  60. chartView.ChartName = chartInfo.ChartName
  61. chartView.ChartNameEn = chartInfo.ChartNameEn
  62. chartView.Source = chartInfo.Source
  63. chartView.ChartImage = chartInfo.ChartImage
  64. chartView.HaveOperaAuth = true
  65. chartView.UniqueCode = chartInfo.UniqueCode
  66. chartView.ChartSource = "AI预测模型"
  67. chartView.ChartSourceEn = "AI预测模型"
  68. chartView.SysUserId = chartInfo.SysUserId
  69. chartView.SysUserRealName = chartInfo.SysUserRealName
  70. chartView.Button.IsEdit = true
  71. } else {
  72. chartView.ChartName = indexItem.IndexName
  73. chartView.ChartNameEn = indexItem.IndexName
  74. }
  75. chartView.ChartType = utils.CHART_SOURCE_DEFAULT
  76. chartTheme, e := data.GetChartThemeConfig(0, chartView.ChartType, utils.CHART_TYPE_CURVE)
  77. if e != nil {
  78. err = fmt.Errorf("获取图表主题样式失败, %v", e)
  79. return
  80. }
  81. chartView.ChartThemeStyle = chartTheme.Config
  82. chartView.ChartThemeId = chartTheme.ChartThemeId
  83. chartView.DateType = 3
  84. chartView.Calendar = "公历"
  85. chartView.ChartSource = "AI预测模型"
  86. chartView.ChartSourceEn = "AI预测模型"
  87. chartView.Unit = unit
  88. chartView.UnitEn = unit
  89. // EdbList-固定一条为标的实际值、一条为预测值
  90. edbList := make([]*data_manage.ChartEdbInfoMapping, 0)
  91. edbActual, edbPredict := new(data_manage.ChartEdbInfoMapping), new(data_manage.ChartEdbInfoMapping)
  92. edbActual.EdbName = indexItem.IndexName
  93. edbActual.EdbNameEn = indexItem.IndexName
  94. edbActual.IsAxis = 1
  95. edbActual.Unit = unit
  96. edbActual.UnitEn = unit
  97. edbPredict.EdbName = predictLegendName
  98. edbPredict.EdbNameEn = predictLegendName
  99. edbPredict.IsAxis = 1
  100. edbPredict.Unit = unit
  101. edbPredict.UnitEn = unit
  102. actualData, predictData := make([]*data_manage.EdbDataList, 0), make([]*data_manage.EdbDataList, 0)
  103. var startDate, endDate time.Time
  104. var actualValues, predictValues []float64
  105. var actualNewest, predictNewest bool
  106. var actualLatestTimestamp int64 // 实际值最后一天的时间戳,作为日度图表的分割线
  107. for k, v := range indexData {
  108. // 如果实际值和预测值都是null那么该日期无效直接忽略
  109. if !v.Value.Valid && !v.PredictValue.Valid {
  110. continue
  111. }
  112. // 将有效值加入[]float64,最后取极值
  113. if v.Value.Valid {
  114. actualValues = append(actualValues, v.Value.Float64)
  115. }
  116. if v.PredictValue.Valid {
  117. predictValues = append(predictValues, v.PredictValue.Float64)
  118. }
  119. // 开始结束时间
  120. if k == 0 {
  121. startDate = v.DataTime
  122. endDate = v.CreateTime
  123. }
  124. if v.DataTime.Before(startDate) {
  125. startDate = v.DataTime
  126. }
  127. if v.DataTime.After(endDate) {
  128. endDate = v.DataTime
  129. }
  130. // 指标数据
  131. if v.Value.Valid {
  132. if !actualNewest {
  133. edbActual.LatestDate = v.DataTime.Format(utils.FormatDate)
  134. edbActual.LatestValue = v.Value.Float64
  135. actualLatestTimestamp = v.DataTime.UnixNano() / 1e6
  136. actualNewest = true
  137. }
  138. actualData = append(actualData, &data_manage.EdbDataList{
  139. DataTime: v.DataTime.Format(utils.FormatDate),
  140. Value: v.Value.Float64,
  141. DataTimestamp: v.DataTimestamp,
  142. })
  143. }
  144. if v.PredictValue.Valid {
  145. if !predictNewest {
  146. edbPredict.LatestDate = v.DataTime.Format(utils.FormatDate)
  147. edbPredict.LatestValue = v.Value.Float64
  148. predictNewest = true
  149. }
  150. predictData = append(predictData, &data_manage.EdbDataList{
  151. DataTime: v.DataTime.Format(utils.FormatDate),
  152. Value: v.PredictValue.Float64,
  153. DataTimestamp: v.DataTimestamp,
  154. })
  155. }
  156. }
  157. // 图表数据这里均做一个升序排序
  158. sort.Slice(actualData, func(i, j int) bool {
  159. return actualData[i].DataTimestamp < actualData[j].DataTimestamp
  160. })
  161. sort.Slice(predictData, func(i, j int) bool {
  162. return predictData[i].DataTimestamp < predictData[j].DataTimestamp
  163. })
  164. // 极值
  165. actualMin, actualMax := utils.FindMinMax(actualValues)
  166. predictMin, predictMax := utils.FindMinMax(predictValues)
  167. edbActual.MinData = actualMin
  168. edbActual.MaxData = actualMax
  169. edbPredict.MinData = predictMin
  170. edbPredict.MaxData = predictMax
  171. edbActual.DataList = actualData
  172. edbPredict.DataList = predictData
  173. edbList = append(edbList, edbActual, edbPredict)
  174. // 上下限
  175. if confLeftMin != "" {
  176. chartView.LeftMin = confLeftMin
  177. } else {
  178. leftMin := actualMin
  179. if leftMin > predictMin {
  180. leftMin = predictMin
  181. }
  182. chartView.LeftMin = fmt.Sprint(leftMin)
  183. }
  184. if confLeftMax != "" {
  185. chartView.LeftMax = confLeftMax
  186. } else {
  187. leftMax := actualMax
  188. if leftMax < predictMax {
  189. leftMax = predictMax
  190. }
  191. chartView.LeftMax = fmt.Sprint(leftMax)
  192. }
  193. chartView.StartDate = startDate.Format(utils.FormatDate)
  194. chartView.EndDate = endDate.Format(utils.FormatDate)
  195. // 日度图表的分割线日期
  196. if source == aiPredictModel.ModelDataSourceDaily {
  197. var dataResp struct {
  198. ActualLatestTimestamp int64
  199. }
  200. dataResp.ActualLatestTimestamp = actualLatestTimestamp
  201. resp.DataResp = dataResp
  202. }
  203. resp.ChartInfo = chartView
  204. resp.EdbInfoList = edbList
  205. // 此处返回标的ID,我的图表-编辑按钮需要通过标的ID跳至标的编辑页=_=!
  206. type dataResp struct {
  207. AiPredictModelIndexId int
  208. }
  209. resp.DataResp = &dataResp{AiPredictModelIndexId: indexItem.AiPredictModelIndexId}
  210. return
  211. }