chart_info.go 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  1. package chart
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "github.com/shopspring/decimal"
  7. "hongze/hongze_yb/global"
  8. "hongze/hongze_yb/models/request"
  9. "hongze/hongze_yb/models/response/chart_info"
  10. chartEdbMappingModel "hongze/hongze_yb/models/tables/chart_edb_mapping"
  11. chartInfoModel "hongze/hongze_yb/models/tables/chart_info"
  12. company2 "hongze/hongze_yb/models/tables/company"
  13. edbDataModel "hongze/hongze_yb/models/tables/edb_data"
  14. edbInfoModel "hongze/hongze_yb/models/tables/edb_info"
  15. "hongze/hongze_yb/models/tables/my_chart_classify"
  16. "hongze/hongze_yb/models/tables/yb_chart_daily_visit_log"
  17. "hongze/hongze_yb/models/tables/yb_chart_visit_log"
  18. "hongze/hongze_yb/services/alarm_msg"
  19. edbDataService "hongze/hongze_yb/services/edb_data"
  20. "hongze/hongze_yb/services/user"
  21. "hongze/hongze_yb/utils"
  22. "math"
  23. "sort"
  24. "strconv"
  25. "strings"
  26. "time"
  27. )
  28. // ModifyChartInfoAndMapping 修改图表信息
  29. func ModifyChartInfoAndMapping(edbInfoIdStr string, req *chartInfoModel.SaveChartInfoReq, chartType int, chartEdbInfoList []*chartInfoModel.ChartSaveItem) (err error) {
  30. // 开启事务
  31. tx := global.MYSQL["data"].Begin()
  32. defer func() {
  33. if err != nil {
  34. tx.Rollback()
  35. } else {
  36. tx.Commit()
  37. }
  38. }()
  39. // 更新图表信息
  40. if chartType == 1 {
  41. sql := ` UPDATE chart_info
  42. SET
  43. edb_info_ids = ?,
  44. modify_time = NOW(),
  45. date_type = ?,
  46. start_date = ?,
  47. end_date = ?,
  48. left_min = ?,
  49. left_max = ?,
  50. right_min = ?,
  51. right_max = ?,extra_config = ?
  52. WHERE chart_info_id = ?`
  53. err = tx.Exec(sql, edbInfoIdStr, req.DateType, req.StartDate, req.EndDate, req.LeftMin, req.LeftMax, req.RightMin, req.RightMax, req.ExtraConfig, req.ChartInfoId).Error
  54. } else {
  55. sql := ` UPDATE chart_info
  56. SET
  57. edb_info_ids = ?,
  58. modify_time = NOW(),
  59. calendar = ?,
  60. season_start_date = ?,
  61. season_end_date = ?,
  62. left_min = ?,
  63. left_max = ?,
  64. right_min = ?,
  65. right_max = ?,extra_config = ?
  66. WHERE chart_info_id = ?`
  67. err = tx.Exec(sql, edbInfoIdStr, req.Calendar, req.SeasonStartDate, req.SeasonEndDate, req.LeftMin, req.LeftMax, req.RightMin, req.RightMax, req.ExtraConfig, req.ChartInfoId).Error
  68. }
  69. if err != nil {
  70. fmt.Println("UPDATE chart_info Err:", err.Error())
  71. return
  72. }
  73. // 修改图表关联指标
  74. chartEdbMappingIdList := make([]string, 0)
  75. for _, v := range chartEdbInfoList {
  76. var tmpChartEdbMapping *chartEdbMappingModel.ChartEdbMapping
  77. csql := `SELECT * FROM chart_edb_mapping WHERE chart_info_id=? AND edb_info_id=? AND source = ? `
  78. err = tx.Raw(csql, req.ChartInfoId, v.EdbInfoId, utils.CHART_SOURCE_DEFAULT).First(&tmpChartEdbMapping).Error
  79. if err != nil && err != utils.ErrNoRow {
  80. fmt.Println("QueryRow Err:", err.Error())
  81. return err
  82. }
  83. if tmpChartEdbMapping == nil || tmpChartEdbMapping.ChartEdbMappingId == 0 {
  84. mapItem := new(chartEdbMappingModel.ChartEdbMapping)
  85. mapItem.ChartInfoId = req.ChartInfoId
  86. mapItem.EdbInfoId = v.EdbInfoId
  87. mapItem.CreateTime = time.Now()
  88. mapItem.ModifyTime = time.Now()
  89. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  90. mapItem.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
  91. mapItem.MaxData = v.MaxData
  92. mapItem.MinData = v.MinData
  93. mapItem.IsOrder = 0
  94. if v.IsOrder {
  95. mapItem.IsOrder = 1
  96. }
  97. mapItem.IsAxis = v.IsAxis
  98. mapItem.EdbInfoType = v.EdbInfoType
  99. mapItem.LeadValue = v.LeadValue
  100. mapItem.LeadUnit = v.LeadUnit
  101. mapItem.ChartStyle = v.ChartStyle
  102. mapItem.ChartColor = v.ChartColor
  103. mapItem.ChartWidth = v.ChartWidth
  104. mapItem.Source = utils.CHART_SOURCE_DEFAULT
  105. err = tx.Create(mapItem).Error
  106. if err != nil {
  107. return
  108. }
  109. chartEdbMappingIdList = append(chartEdbMappingIdList, strconv.Itoa(mapItem.ChartEdbMappingId))
  110. } else {
  111. chartEdbMappingIdList = append(chartEdbMappingIdList, strconv.Itoa(tmpChartEdbMapping.ChartEdbMappingId))
  112. tmpChartEdbMapping.ModifyTime = time.Now()
  113. tmpChartEdbMapping.MaxData = v.MaxData
  114. tmpChartEdbMapping.MinData = v.MinData
  115. tmpChartEdbMapping.IsOrder = 0
  116. if v.IsOrder {
  117. tmpChartEdbMapping.IsOrder = 1
  118. }
  119. tmpChartEdbMapping.IsAxis = v.IsAxis
  120. tmpChartEdbMapping.EdbInfoType = v.EdbInfoType
  121. tmpChartEdbMapping.LeadValue = v.LeadValue
  122. tmpChartEdbMapping.LeadUnit = v.LeadUnit
  123. tmpChartEdbMapping.ChartStyle = v.ChartStyle
  124. tmpChartEdbMapping.ChartColor = v.ChartColor
  125. //tmpChartEdbMapping.PredictChartColor = v.PredictChartColor
  126. tmpChartEdbMapping.ChartWidth = v.ChartWidth
  127. err = tx.Model(tmpChartEdbMapping).Select([]string{"ModifyTime", "MaxData", "MinData", "IsOrder", "IsAxis", "EdbInfoType", "LeadValue", "LeadUnit", "ChartStyle", "ChartColor", "PredictChartColor", "ChartWidth"}).Updates(*tmpChartEdbMapping).Error
  128. if err != nil {
  129. fmt.Println("chart_edb_mapping Err:" + err.Error())
  130. return err
  131. }
  132. }
  133. }
  134. // 清除原图表指标
  135. if len(chartEdbMappingIdList) > 0 {
  136. chartEdbMappingIdStr := strings.Join(chartEdbMappingIdList, ",")
  137. dsql := `DELETE FROM chart_edb_mapping WHERE chart_info_id=? AND chart_edb_mapping_id NOT IN(` + chartEdbMappingIdStr + `)`
  138. err = tx.Exec(dsql, req.ChartInfoId).Error
  139. if err != nil {
  140. fmt.Println("delete err:" + err.Error())
  141. return err
  142. }
  143. }
  144. return
  145. }
  146. // GetChartInfoRefreshData 获取需要刷新的指标
  147. func GetChartInfoRefreshData(chartInfoId int) (baseEdbInfoArr, calculateInfoArr []*edbInfoModel.EdbInfo, err error) {
  148. sql := ` SELECT b.* FROM chart_edb_mapping AS a
  149. INNER JOIN edb_info AS b ON a.edb_info_id=b.edb_info_id
  150. WHERE a.chart_info_id=? `
  151. edbInfoList := make([]*edbInfoModel.EdbInfo, 0)
  152. err = global.MYSQL["data"].Raw(sql, chartInfoId).Scan(&edbInfoList).Error
  153. if err != nil {
  154. return
  155. }
  156. for _, v := range edbInfoList {
  157. fmt.Println(v.EdbInfoId, v.EdbType)
  158. if v.EdbType == 1 {
  159. baseEdbInfoArr = append(baseEdbInfoArr, v)
  160. } else {
  161. calculateInfoArr = append(calculateInfoArr, v)
  162. newBaseEdbInfoArr, newCalculateInfoArr, err := GetChartRefreshEdbInfo(v.EdbInfoId, v.Source, 0)
  163. if err != nil {
  164. return baseEdbInfoArr, calculateInfoArr, err
  165. }
  166. baseEdbInfoArr = append(baseEdbInfoArr, newBaseEdbInfoArr...)
  167. calculateInfoArr = append(calculateInfoArr, newCalculateInfoArr...)
  168. }
  169. }
  170. return
  171. }
  172. // GetChartRefreshEdbInfo
  173. func GetChartRefreshEdbInfo(edbInfoId, source, n int) (baseEdbInfoArr, calculateInfoArr []*edbInfoModel.EdbInfo, err error) {
  174. calculateList, err := GetEdbInfoCalculateMap(edbInfoId, source)
  175. if err != nil && err != utils.ErrNoRow {
  176. return
  177. }
  178. n++
  179. for _, item := range calculateList {
  180. fmt.Println(item.EdbInfoId)
  181. if item.EdbType == 1 {
  182. baseEdbInfoArr = append(baseEdbInfoArr, item)
  183. } else {
  184. calculateInfoArr = append(calculateInfoArr, item)
  185. if n > 10 {
  186. return
  187. }
  188. newBaseEdbInfoArr, newCalculateInfoArr, _ := GetChartRefreshEdbInfo(item.EdbInfoId, item.Source, n)
  189. baseEdbInfoArr = append(baseEdbInfoArr, newBaseEdbInfoArr...)
  190. calculateInfoArr = append(calculateInfoArr, newCalculateInfoArr...)
  191. }
  192. }
  193. return
  194. }
  195. func GetEdbInfoCalculateMap(edbInfoId, source int) (list []*edbInfoModel.EdbInfo, err error) {
  196. sql := ` SELECT b.* FROM edb_info_calculate_mapping AS a
  197. INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
  198. WHERE a.edb_info_id=? ORDER BY sort ASC `
  199. err = global.MYSQL["data"].Exec(sql, edbInfoId).Error
  200. return
  201. }
  202. // SaveChartVisitLog 保存图表访问记录
  203. func SaveChartVisitLog(userInfo user.UserInfo, chartInfo *chartInfoModel.ChartInfoView, myChartClassifyId int) (err error) {
  204. userId := int(userInfo.UserID)
  205. companyId := int(userInfo.CompanyID)
  206. chartInfoId := chartInfo.ChartInfoId
  207. // 访问记录
  208. visitLog := new(yb_chart_visit_log.YbChartVisitLog)
  209. visitLog.CompanyId = companyId
  210. companyInfo, err := company2.GetByCompanyId(userInfo.CompanyID)
  211. if err == nil {
  212. visitLog.CompanyName = companyInfo.CompanyName
  213. }
  214. visitLog.UserId = userId
  215. visitLog.RealName = userInfo.RealName
  216. visitLog.Mobile = userInfo.Mobile
  217. visitLog.Email = userInfo.Email
  218. visitLog.ChartInfoId = chartInfoId
  219. visitLog.ChartName = chartInfo.ChartName
  220. visitLog.CreateTime = time.Now().Local()
  221. visitLog.Create()
  222. // 每日访问记录,用户/天/图仅记录一次
  223. if myChartClassifyId > 0 {
  224. // 今日是否已访问
  225. nowTime := time.Now().Local()
  226. startTime := time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 0, 0, 0, 0, time.Local)
  227. endTime := time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 23, 59, 59, 0, time.Local)
  228. _, tmpErr := yb_chart_daily_visit_log.GetTodayVisitLog(userId, chartInfoId, myChartClassifyId, startTime, endTime)
  229. if tmpErr == nil {
  230. return
  231. }
  232. myChartClassify, tmpErr := my_chart_classify.GetClassifyById(myChartClassifyId)
  233. if tmpErr != nil {
  234. return
  235. }
  236. dailyLog := new(yb_chart_daily_visit_log.YbChartDailyVisitLog)
  237. dailyLog.CompanyId = companyId
  238. if companyInfo != nil {
  239. dailyLog.CompanyName = companyInfo.CompanyName
  240. }
  241. dailyLog.UserId = userId
  242. dailyLog.RealName = userInfo.RealName
  243. dailyLog.Mobile = userInfo.Mobile
  244. dailyLog.Email = userInfo.Email
  245. dailyLog.ChartInfoId = chartInfoId
  246. dailyLog.ChartName = chartInfo.ChartName
  247. dailyLog.MyChartClassifyId = myChartClassifyId
  248. dailyLog.MyChartClassifyName = myChartClassify.MyChartClassifyName
  249. dailyLog.CreateTime = time.Now().Local()
  250. dailyLog.Create()
  251. }
  252. return
  253. }
  254. // RefreshChart 图表刷新
  255. func RefreshChart(chartInfoId int) (err error) {
  256. var errMsg string
  257. defer func() {
  258. if err != nil {
  259. if global.CONFIG.Serve.RunMode == "release" {
  260. //go services.SendEmail(utils.APPNAME+"【"+global.CONFIG.Serve.RunMode+"】"+"失败提醒", "RefreshChart:"+errMsg, utils.EmailSendToUsers)
  261. go alarm_msg.SendAlarmMsg("RefreshChart Err:"+errMsg, 3)
  262. }
  263. fmt.Println("RefreshChart Err:" + errMsg)
  264. }
  265. }()
  266. // 获取需要刷新的指标
  267. baseEdbInfoArr, calculateInfoArr, err := GetChartInfoRefreshData(chartInfoId)
  268. if err != nil {
  269. errMsg = "获取需要刷新的指标失败:Err:" + err.Error()
  270. return
  271. }
  272. newBaseEdbInfoArr := make([]*edbInfoModel.EdbInfo, 0)
  273. baseMap := make(map[int]*edbInfoModel.EdbInfo)
  274. for _, bv := range baseEdbInfoArr {
  275. // 如果不是普通指标,那么过滤
  276. if bv.EdbInfoType != 0 {
  277. continue
  278. }
  279. if _, ok := baseMap[bv.EdbInfoId]; !ok {
  280. newBaseEdbInfoArr = append(newBaseEdbInfoArr, bv)
  281. }
  282. baseMap[bv.EdbInfoId] = bv
  283. }
  284. newCalculateInfoArr := make([]*edbInfoModel.EdbInfo, 0)
  285. calculateMap := make(map[int]*edbInfoModel.EdbInfo)
  286. var calculateArr []int
  287. for _, bv := range calculateInfoArr {
  288. if _, ok := calculateMap[bv.EdbInfoId]; !ok {
  289. newCalculateInfoArr = append(newCalculateInfoArr, bv)
  290. calculateArr = append(calculateArr, bv.EdbInfoId)
  291. }
  292. calculateMap[bv.EdbInfoId] = bv
  293. }
  294. sort.Ints(calculateArr)
  295. // 刷新指标
  296. var startDate string
  297. for _, bv := range newBaseEdbInfoArr {
  298. source := bv.Source
  299. edbInfoId := bv.EdbInfoId
  300. edbCode := bv.EdbCode
  301. startDate = bv.StartDate.Format(utils.FormatDate)
  302. frequency := bv.Frequency
  303. if startDate == "0000-00-00" {
  304. continue
  305. }
  306. sTime := bv.EndDate
  307. var limitDay int
  308. startDate := ""
  309. switch frequency {
  310. case "日度":
  311. limitDay = utils.DATA_START_REFRESH_LIMIT
  312. case "周度":
  313. limitDay = utils.DATA_START_REFRESH_LIMIT * 7
  314. case "月度":
  315. limitDay = utils.DATA_START_REFRESH_LIMIT * 30
  316. case "季度":
  317. limitDay = utils.DATA_START_REFRESH_LIMIT * 90
  318. case "年度":
  319. limitDay = utils.DATA_START_REFRESH_LIMIT * 365
  320. default:
  321. limitDay = utils.DATA_START_REFRESH_LIMIT
  322. }
  323. startDate = sTime.AddDate(0, 0, -limitDay).Format(utils.FormatDate)
  324. fmt.Println("source:", source)
  325. respItem, err := RefreshEdbData(edbInfoId, source, edbCode, startDate)
  326. if err != nil {
  327. errMsg = errors.New("RefreshEdbData Err:" + err.Error()).Error()
  328. return err
  329. }
  330. if respItem.Ret != 200 {
  331. errMsg = errors.New(respItem.ErrMsg + ";EdbCode:" + edbCode).Error()
  332. return err
  333. }
  334. //maxAndMinItem, err := edbDataModel.GetEdbInfoMaxAndMinInfo(source, edbCode)
  335. //if err != nil {
  336. // return err
  337. //}
  338. //if maxAndMinItem != nil {
  339. // err = edbDataModel.ModifyEdbInfoMaxAndMinInfo(edbInfoId, maxAndMinItem)
  340. // if err != nil {
  341. // return err
  342. // }
  343. //}
  344. }
  345. // 刷新计算指标
  346. for _, v := range calculateArr {
  347. edbInfo := calculateMap[v]
  348. if edbInfo == nil {
  349. return err
  350. }
  351. startDate = edbInfo.StartDate.Format(utils.FormatDate)
  352. source := edbInfo.Source
  353. if source == utils.DATA_SOURCE_CALCULATE {
  354. sTime := edbInfo.EndDate
  355. startDate = sTime.Format(utils.FormatDate)
  356. }
  357. result, err := RefreshEdbCalculateData(edbInfo.EdbInfoId, edbInfo.EdbCode, startDate)
  358. if err != nil {
  359. fmt.Println(v, "RefreshEdbCalculateData err", time.Now())
  360. errMsg = "RefreshEdbCalculateData Err:" + err.Error()
  361. return err
  362. }
  363. if result.Ret != 200 {
  364. fmt.Println(v, "RefreshEdbCalculateData err;msg:", result.Msg, ";errMsg:", result.ErrMsg)
  365. errMsg = fmt.Sprint(v, "RefreshEdbCalculateData err;msg:", result.Msg, ";errMsg:", result.ErrMsg)
  366. return fmt.Errorf("刷新失败")
  367. }
  368. }
  369. return
  370. }
  371. // GetChartEdbData 获取图表的指标数据
  372. func GetChartEdbData(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*chartEdbMappingModel.ChartEdbInfoMapping, extraConfigStr string) (edbList []*chartEdbMappingModel.ChartEdbInfoMappingList, xEdbIdValue []int, yDataList []chart_info.YData, sourceArr []string, dataResp interface{}, err error, errMsg string) {
  373. edbList = make([]*chartEdbMappingModel.ChartEdbInfoMappingList, 0)
  374. xEdbIdValue = make([]int, 0)
  375. yDataList = make([]chart_info.YData, 0)
  376. var extraConfig interface{}
  377. switch chartType {
  378. case 7: // 柱形图
  379. var barConfig request.BarChartInfoReq
  380. if extraConfigStr == `` {
  381. errMsg = "柱方图未配置"
  382. err = errors.New(errMsg)
  383. return
  384. }
  385. err = json.Unmarshal([]byte(extraConfigStr), &barConfig)
  386. if err != nil {
  387. errMsg = "柱方图配置异常"
  388. err = errors.New(errMsg)
  389. return
  390. }
  391. extraConfig = barConfig
  392. case 10: // 截面散点图
  393. var tmpExtraConfig request.SectionScatterReq
  394. if extraConfigStr == `` {
  395. errMsg = "截面散点图未配置"
  396. err = errors.New(errMsg)
  397. return
  398. }
  399. err = json.Unmarshal([]byte(extraConfigStr), &tmpExtraConfig)
  400. if err != nil {
  401. errMsg = "截面散点配置异常"
  402. err = errors.New(errMsg)
  403. return
  404. }
  405. extraConfig = tmpExtraConfig
  406. }
  407. // 指标对应的所有数据
  408. edbDataListMap, edbList, sourceArr, err := getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList)
  409. if err != nil {
  410. return
  411. }
  412. // 特殊图形数据处理
  413. switch chartType {
  414. case 7: // 柱形图
  415. barChartConf := extraConfig.(request.BarChartInfoReq)
  416. xEdbIdValue, yDataList, err = BarChartData(mappingList, edbDataListMap, barChartConf.DateList, barChartConf.Sort)
  417. for _, v := range edbList {
  418. // 指标别名
  419. if barChartConf.EdbInfoIdList != nil && len(barChartConf.EdbInfoIdList) > 0 {
  420. for _, reqEdb := range barChartConf.EdbInfoIdList {
  421. if v.EdbInfoId == reqEdb.EdbInfoId {
  422. v.EdbAliasName = reqEdb.Name
  423. }
  424. }
  425. }
  426. }
  427. case 10: // 截面散点图
  428. sectionScatterConf := extraConfig.(request.SectionScatterReq)
  429. xEdbIdValue, dataResp, err = GetSectionScatterChartData(mappingList, edbDataListMap, sectionScatterConf)
  430. // 这个数据没有必要返回给前端
  431. for _, v := range edbList {
  432. v.DataList = nil
  433. }
  434. }
  435. return
  436. }
  437. // GetEdbDataMapList 获取指标最后的基础数据
  438. func GetEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*chartEdbMappingModel.ChartEdbInfoMapping) (edbDataListMap map[int][]*edbDataModel.EdbDataList, edbList []*chartEdbMappingModel.ChartEdbInfoMappingList, sourceArr []string, err error) {
  439. edbDataListMap, edbList, sourceArr, err = getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList)
  440. return
  441. }
  442. // getEdbDataMapList 获取指标最后的基础数据
  443. func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*chartEdbMappingModel.ChartEdbInfoMapping) (edbDataListMap map[int][]*edbDataModel.EdbDataList, edbList []*chartEdbMappingModel.ChartEdbInfoMappingList, sourceArr []string, err error) {
  444. // 关联指标来源
  445. sourceArr = make([]string, 0)
  446. // 指标对应的所有数据
  447. edbDataListMap = make(map[int][]*edbDataModel.EdbDataList)
  448. for _, v := range mappingList {
  449. //fmt.Println("v:", v.EdbInfoId)
  450. item := new(chartEdbMappingModel.ChartEdbInfoMappingList)
  451. item.EdbInfoId = v.EdbInfoId
  452. item.SourceName = v.SourceName
  453. item.Source = v.Source
  454. item.EdbCode = v.EdbCode
  455. item.EdbName = v.EdbName
  456. item.EdbNameEn = v.EdbNameEn
  457. item.Frequency = v.Frequency
  458. item.FrequencyEn = GetFrequencyEn(v.Frequency)
  459. if v.Unit != `无` {
  460. item.Unit = v.Unit
  461. }
  462. item.UnitEn = v.UnitEn
  463. item.StartDate = v.StartDate
  464. item.EndDate = v.EndDate
  465. item.ModifyTime = v.ModifyTime
  466. item.EdbInfoCategoryType = v.EdbInfoCategoryType
  467. item.PredictChartColor = v.PredictChartColor
  468. if !utils.InArray(v.Source, utils.SystemSourceList) { //来源于系统的指标,都展示为弘则研究
  469. if !utils.InArray(v.SourceName, sourceArr) {
  470. sourceArr = append(sourceArr, v.SourceName)
  471. }
  472. }
  473. if chartInfoId <= 0 {
  474. item.IsAxis = 1
  475. item.LeadValue = 0
  476. item.LeadUnit = ""
  477. item.ChartEdbMappingId = 0
  478. item.ChartInfoId = 0
  479. item.IsOrder = false
  480. item.EdbInfoType = 1
  481. item.ChartStyle = ""
  482. item.ChartColor = ""
  483. item.ChartWidth = 0
  484. item.MaxData = v.MaxValue
  485. item.MinData = v.MinValue
  486. } else {
  487. item.IsAxis = v.IsAxis
  488. item.EdbInfoType = v.EdbInfoType
  489. item.LeadValue = v.LeadValue
  490. item.LeadUnit = v.LeadUnit
  491. item.LeadUnitEn = GetLeadUnitEn(v.LeadUnit)
  492. item.ChartEdbMappingId = v.ChartEdbMappingId
  493. item.ChartInfoId = v.ChartInfoId
  494. item.ChartStyle = v.ChartStyle
  495. item.ChartColor = v.ChartColor
  496. item.ChartWidth = v.ChartWidth
  497. item.IsOrder = v.IsOrder
  498. item.MaxData = v.MaxData
  499. item.MinData = v.MinData
  500. }
  501. item.LatestValue = v.LatestValue
  502. item.LatestDate = v.LatestDate
  503. item.UniqueCode = v.UniqueCode
  504. var startDateReal string
  505. var diffSeconds int64
  506. if chartType == 2 { //季节性图
  507. startDateReal = startDate
  508. } else {
  509. if v.EdbInfoType == 0 && v.LeadUnit != "" && v.LeadValue > 0 { //领先指标
  510. var startTimeRealTemp time.Time
  511. startDateParse, _ := time.Parse(utils.FormatDate, startDate)
  512. switch v.LeadUnit {
  513. case "天":
  514. startTimeRealTemp = startDateParse.AddDate(0, 0, -v.LeadValue)
  515. case "月":
  516. startTimeRealTemp = startDateParse.AddDate(0, -v.LeadValue, 0)
  517. case "季":
  518. startTimeRealTemp = startDateParse.AddDate(0, -3*v.LeadValue, 0)
  519. case "周":
  520. startTimeRealTemp = startDateParse.AddDate(0, 0, -7*v.LeadValue)
  521. case "年":
  522. startTimeRealTemp = startDateParse.AddDate(-v.LeadValue, 0, 0)
  523. }
  524. if startTimeRealTemp.Before(startDateParse) {
  525. startDateReal = startTimeRealTemp.Format(utils.FormatDate)
  526. diffSeconds = (int64(startTimeRealTemp.UnixNano()) - int64(startDateParse.UnixNano())) / 1e6
  527. } else {
  528. startDateReal = startDate
  529. diffSeconds = 0
  530. }
  531. } else {
  532. startDateReal = startDate
  533. }
  534. }
  535. //fmt.Println("line 1011 chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
  536. calendarPreYear := 0
  537. if calendar == "农历" {
  538. newStartDateReal, err := time.Parse(utils.FormatDate, startDateReal)
  539. if err != nil {
  540. fmt.Println("time.Parse:" + err.Error())
  541. }
  542. calendarPreYear = newStartDateReal.Year() - 1
  543. newStartDateReal = newStartDateReal.AddDate(-1, 0, 0)
  544. startDateReal = newStartDateReal.Format(utils.FormatDate)
  545. }
  546. dataList := make([]*edbDataModel.EdbDataList, 0)
  547. //fmt.Println("chart:", v.Source, v.EdbInfoId, startDateReal, endDate, ";EdbInfoCategoryType:", v.EdbInfoCategoryType)
  548. //var newEdbInfo *edbInfoModel.EdbInfo
  549. switch v.EdbInfoCategoryType {
  550. case 0:
  551. dataList, err = edbDataModel.GetEdbDataList(v.Source, v.EdbInfoId, startDateReal, endDate)
  552. case 1:
  553. _, dataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(v.EdbInfoId, startDateReal, endDate, false)
  554. //if item.MaxValue < newEdbInfo.MaxValue {
  555. // item.MaxData = newEdbInfo.MaxValue
  556. //}
  557. //if item.MinData > newEdbInfo.MinValue {
  558. // item.MinData = newEdbInfo.MinValue
  559. //}
  560. default:
  561. err = errors.New(fmt.Sprint("获取失败,指标类型异常", v.EdbInfoCategoryType))
  562. }
  563. if err != nil {
  564. return
  565. }
  566. edbDataListMap[v.EdbInfoId] = dataList
  567. if diffSeconds != 0 && v.EdbInfoType == 0 {
  568. dataListLen := len(dataList)
  569. for i := 0; i < dataListLen; i++ {
  570. dataList[i].DataTimestamp = dataList[i].DataTimestamp - diffSeconds
  571. }
  572. }
  573. if chartType == 2 {
  574. latestDateStr := v.LatestDate.Format(utils.FormatDate) //实际数据的截止日期
  575. latestDate := v.LatestDate
  576. //latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
  577. //if tmpErr != nil {
  578. // err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + v.LatestDate))
  579. // return
  580. //}
  581. latestDateYear := latestDate.Year() //实际数据截止年份
  582. if calendar == "农历" {
  583. if len(dataList) <= 0 {
  584. result := new(edbDataModel.EdbDataResult)
  585. item.DataList = result
  586. } else {
  587. result, tmpErr := edbDataService.AddCalculateQuarter(dataList)
  588. if tmpErr != nil {
  589. err = errors.New("获取农历数据失败,Err:" + tmpErr.Error())
  590. return
  591. }
  592. // 处理季节图的截止日期
  593. for k, edbDataItems := range result.List {
  594. var cuttingDataTimestamp int64
  595. // 切割的日期时间字符串
  596. cuttingDataTimeStr := latestDate.AddDate(0, 0, edbDataItems.BetweenDay).Format(utils.FormatDate)
  597. //如果等于最后的实际日期,那么遍历找到该日期对应的时间戳,并将其赋值为 切割时间戳
  598. if edbDataItems.Year >= latestDateYear {
  599. for _, tmpData := range edbDataItems.Items {
  600. if tmpData.DataTime == cuttingDataTimeStr {
  601. cuttingDataTimestamp = tmpData.DataTimestamp
  602. break
  603. }
  604. }
  605. }
  606. edbDataItems.CuttingDataTimestamp = cuttingDataTimestamp
  607. result.List[k] = edbDataItems
  608. }
  609. if result.List[0].Year != calendarPreYear {
  610. itemList := make([]*edbDataModel.EdbDataList, 0)
  611. items := new(edbDataModel.EdbDataItems)
  612. //items.Year = calendarPreYear
  613. items.Items = itemList
  614. newResult := new(edbDataModel.EdbDataResult)
  615. newResult.List = append(newResult.List, items)
  616. newResult.List = append(newResult.List, result.List...)
  617. item.DataList = newResult
  618. } else {
  619. item.DataList = result
  620. }
  621. }
  622. } else {
  623. currentYear := time.Now().Year()
  624. quarterDataList := make([]*edbDataModel.QuarterData, 0)
  625. quarterMap := make(map[int][]*edbDataModel.EdbDataList)
  626. var quarterArr []int
  627. for _, v := range dataList {
  628. itemDate, tmpErr := time.Parse(utils.FormatDate, v.DataTime)
  629. if tmpErr != nil {
  630. err = errors.New("季度指标日期转换,Err:" + tmpErr.Error() + ";DataTime:" + v.DataTime)
  631. return
  632. }
  633. year := itemDate.Year()
  634. newItemDate := itemDate.AddDate(currentYear-year, 0, 0)
  635. timestamp := newItemDate.UnixNano() / 1e6
  636. v.DataTimestamp = timestamp
  637. if findVal, ok := quarterMap[year]; !ok {
  638. quarterArr = append(quarterArr, year)
  639. findVal = append(findVal, v)
  640. quarterMap[year] = findVal
  641. } else {
  642. findVal = append(findVal, v)
  643. quarterMap[year] = findVal
  644. }
  645. }
  646. for _, v := range quarterArr {
  647. itemList := quarterMap[v]
  648. quarterItem := new(edbDataModel.QuarterData)
  649. quarterItem.Year = v
  650. quarterItem.DataList = itemList
  651. //如果等于最后的实际日期,那么将切割时间戳记录
  652. if v == latestDateYear {
  653. var cuttingDataTimestamp int64
  654. for _, tmpData := range itemList {
  655. if tmpData.DataTime == latestDateStr {
  656. cuttingDataTimestamp = tmpData.DataTimestamp
  657. break
  658. }
  659. }
  660. quarterItem.CuttingDataTimestamp = cuttingDataTimestamp
  661. } else if v > latestDateYear {
  662. //如果大于最后的实际日期,那么第一个点就是切割的时间戳
  663. if len(itemList) > 0 {
  664. quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
  665. }
  666. }
  667. quarterDataList = append(quarterDataList, quarterItem)
  668. }
  669. item.DataList = quarterDataList
  670. }
  671. } else if chartType == 7 { //柱方图
  672. //item.DataList = dataList
  673. } else {
  674. item.DataList = dataList
  675. }
  676. edbList = append(edbList, item)
  677. }
  678. return
  679. }
  680. // BarChartData 柱方图的数据处理
  681. func BarChartData(mappingList []*chartEdbMappingModel.ChartEdbInfoMapping, edbDataListMap map[int][]*edbDataModel.EdbDataList, barChartInfoDateList []request.BarChartInfoDateReq, barChartInfoSort request.BarChartInfoSortReq) (edbIdList []int, yDataList []chart_info.YData, err error) {
  682. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  683. edbDataMap := make(map[int]map[string]float64)
  684. for edbInfoId, edbDataList := range edbDataListMap {
  685. edbDateData := make(map[string]float64)
  686. for _, edbData := range edbDataList {
  687. edbDateData[edbData.DataTime] = edbData.Value
  688. }
  689. edbDataMap[edbInfoId] = edbDateData
  690. }
  691. // edbIdList 指标展示顺序;x轴的指标顺序
  692. edbIdList = make([]int, 0)
  693. //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
  694. dateData := make(map[int]float64)
  695. if barChartInfoSort.Sort == 0 {
  696. for _, v := range mappingList {
  697. edbIdList = append(edbIdList, v.EdbInfoId)
  698. }
  699. } else {
  700. lenBarChartInfoDateList := len(barChartInfoDateList)
  701. if barChartInfoSort.DateIndex >= lenBarChartInfoDateList {
  702. err = errors.New("排序日期异常")
  703. return
  704. }
  705. notDataEdbIdList := make([]int, 0) //没有数据的指标id
  706. // 日期配置
  707. barChartInfoDate := barChartInfoDateList[barChartInfoSort.DateIndex]
  708. for edbInfoId, dataList := range edbDataListMap {
  709. if len(dataList) <= 0 {
  710. // 没有数据的指标id
  711. notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
  712. continue
  713. }
  714. findDate := barChartInfoDate.Date
  715. switch barChartInfoDate.Type {
  716. case 1: //最新值
  717. findDate = dataList[len(dataList)-1].DataTime
  718. case 2: //近期几天
  719. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  720. if tmpErr != nil {
  721. err = tmpErr
  722. return
  723. }
  724. findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  725. lenData := len(dataList) - 1
  726. for i := lenData; i >= 0; i-- {
  727. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  728. if tmpErr != nil {
  729. err = tmpErr
  730. return
  731. }
  732. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  733. findDate = dataList[i].DataTime
  734. break
  735. }
  736. }
  737. case 3: // 固定日期
  738. //最早的日期
  739. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  740. if tmpErr != nil {
  741. err = tmpErr
  742. return
  743. }
  744. //寻找固定日期的数据
  745. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  746. if tmpErr != nil {
  747. err = tmpErr
  748. return
  749. }
  750. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  751. tmpDate := tmpDateTime.Format(utils.FormatDate)
  752. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  753. findDate = tmpDate
  754. break
  755. }
  756. }
  757. default:
  758. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  759. return
  760. }
  761. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  762. dateData[edbInfoId] = tmpValue
  763. } else {
  764. // 没有数据的指标id
  765. notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
  766. }
  767. }
  768. //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
  769. // 排序
  770. dateDataSort := utils.NewMapSorter(dateData)
  771. sort.Sort(dateDataSort)
  772. if barChartInfoSort.Sort == 1 {
  773. // 先将没有数据的指标id放在最前面
  774. if len(notDataEdbIdList) > 0 {
  775. edbIdList = append(edbIdList, notDataEdbIdList...)
  776. }
  777. for _, v := range dateDataSort {
  778. edbIdList = append(edbIdList, v.Key)
  779. }
  780. } else {
  781. for i := len(dateDataSort) - 1; i >= 0; i-- {
  782. edbIdList = append(edbIdList, dateDataSort[i].Key)
  783. }
  784. // 再将没有数据的指标id放在最后面
  785. if len(notDataEdbIdList) > 0 {
  786. edbIdList = append(edbIdList, notDataEdbIdList...)
  787. }
  788. }
  789. }
  790. yDataList = make([]chart_info.YData, 0) //y轴的数据列表
  791. for _, barChartInfoDate := range barChartInfoDateList {
  792. var maxDate time.Time
  793. findDataList := make([]float64, 0) // 当前日期的数据值
  794. for _, edbInfoId := range edbIdList {
  795. findDate := barChartInfoDate.Date //需要的日期值
  796. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  797. if len(dataList) <= 0 {
  798. // 没有数据的指标id
  799. findDataList = append(findDataList, 0)
  800. continue
  801. }
  802. switch barChartInfoDate.Type {
  803. case 1: //最新值
  804. dataList := edbDataListMap[edbInfoId]
  805. findDate = dataList[len(dataList)-1].DataTime
  806. case 2: //近期几天
  807. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  808. if tmpErr != nil {
  809. err = tmpErr
  810. return
  811. }
  812. findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  813. lenData := len(dataList) - 1
  814. for i := lenData; i >= 0; i-- {
  815. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  816. if tmpErr != nil {
  817. err = tmpErr
  818. return
  819. }
  820. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  821. findDate = dataList[i].DataTime
  822. break
  823. }
  824. }
  825. case 3: // 固定日期
  826. //最早的日期
  827. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  828. if tmpErr != nil {
  829. err = tmpErr
  830. return
  831. }
  832. //寻找固定日期的数据
  833. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  834. if tmpErr != nil {
  835. err = tmpErr
  836. return
  837. }
  838. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  839. tmpDate := tmpDateTime.Format(utils.FormatDate)
  840. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  841. findDate = tmpDate
  842. break
  843. }
  844. }
  845. default:
  846. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  847. return
  848. }
  849. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  850. if maxDate.IsZero() {
  851. maxDate = findDateTime
  852. } else {
  853. if findDateTime.After(maxDate) {
  854. maxDate = findDateTime
  855. }
  856. }
  857. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  858. findDataList = append(findDataList, tmpValue)
  859. } else {
  860. findDataList = append(findDataList, 0)
  861. }
  862. }
  863. yDate := "0000-00-00"
  864. if !maxDate.IsZero() {
  865. yDate = maxDate.Format(utils.FormatDate)
  866. }
  867. yDataList = append(yDataList, chart_info.YData{
  868. Date: yDate,
  869. Value: findDataList,
  870. Color: barChartInfoDate.Color,
  871. Name: barChartInfoDate.Name,
  872. })
  873. }
  874. return
  875. }
  876. // 获取频度的英文版
  877. func GetFrequencyEn(frequency string) (frequencyEn string) {
  878. switch frequency {
  879. case "日度":
  880. frequencyEn = "day"
  881. return
  882. case "周度":
  883. frequencyEn = "week"
  884. return
  885. case "旬度":
  886. frequencyEn = "ten days"
  887. return
  888. case "月度":
  889. frequencyEn = "month"
  890. return
  891. case "季度":
  892. frequencyEn = "quarter"
  893. return
  894. case "年度":
  895. frequencyEn = "year"
  896. return
  897. }
  898. return
  899. }
  900. func GetLeadUnitEn(unit string) (unitEn string) {
  901. switch unit {
  902. case "天":
  903. unitEn = "day"
  904. return
  905. case "周":
  906. unitEn = "week"
  907. return
  908. case "月":
  909. unitEn = "month"
  910. return
  911. case "季":
  912. unitEn = "quarter"
  913. return
  914. case "年":
  915. unitEn = "year"
  916. return
  917. }
  918. return
  919. }
  920. // ChartInfoRefreshV2 图表刷新
  921. // @author Roc
  922. // @datetime 2022-09-16 10:15:38
  923. // @description 将原来自己写的一套获取所有关联指标,然后刷新指标逻辑 改成 只获取使用的指标id,然后遍历去调用“指标刷新服务”
  924. func ChartInfoRefreshV2(chartInfoId int) (err error) {
  925. var errmsg string
  926. defer func() {
  927. if err != nil {
  928. go alarm_msg.SendAlarmMsg("ChartInfoRefresh:"+errmsg, 3)
  929. //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "ChartInfoRefresh:"+errmsg, utils.EmailSendToUsers)
  930. fmt.Println("ChartInfoRefresh Err:" + errmsg)
  931. }
  932. }()
  933. edbMappingList, err := chartEdbMappingModel.GetMappingListByChartInfoId(chartInfoId)
  934. if err != nil {
  935. errmsg = "获取需要刷新的指标失败:Err:" + err.Error()
  936. return
  937. }
  938. edbIdList := make([]int, 0)
  939. for _, v := range edbMappingList {
  940. edbIdList = append(edbIdList, v.EdbInfoId)
  941. }
  942. // 批量刷新
  943. err, errmsg = EdbInfoRefreshAllFromBase(edbIdList, false)
  944. if err != nil {
  945. return
  946. }
  947. return
  948. }
  949. // CheckChartExtraConfig 校验图表额外配置的信息,并且获取相关联的指标id
  950. func CheckChartExtraConfig(chartType int, extraConfigStr string) (edbIdList []int, err error, errMsg string) {
  951. switch chartType {
  952. case 10: //截面散点
  953. var extraConfig request.SectionScatterReq
  954. err = json.Unmarshal([]byte(extraConfigStr), &extraConfig)
  955. if err != nil {
  956. return
  957. }
  958. // 判断是否有配置日期序列
  959. if len(extraConfig.SeriesList) <= 0 {
  960. errMsg = `请配置序列`
  961. err = errors.New(errMsg)
  962. return
  963. }
  964. // 判断是否有填写指标
  965. if len(extraConfig.SeriesList[0].EdbInfoList) <= 0 {
  966. errMsg = `请选择指标`
  967. err = errors.New(errMsg)
  968. return
  969. }
  970. // 遍历指标列表获取指标id
  971. edbIdMap := make(map[int]int)
  972. for _, v := range extraConfig.SeriesList[0].EdbInfoList {
  973. // X 轴的指标id
  974. if _, ok := edbIdMap[v.XEdbInfoId]; !ok {
  975. edbIdMap[v.XEdbInfoId] = v.XEdbInfoId
  976. edbIdList = append(edbIdList, v.XEdbInfoId)
  977. }
  978. // Y 轴的指标id
  979. if _, ok := edbIdMap[v.YEdbInfoId]; !ok {
  980. edbIdMap[v.YEdbInfoId] = v.YEdbInfoId
  981. edbIdList = append(edbIdList, v.YEdbInfoId)
  982. }
  983. }
  984. }
  985. return
  986. }
  987. // GetSectionScatterChartData 柱方图的数据处理
  988. func GetSectionScatterChartData(mappingList []*chartEdbMappingModel.ChartEdbInfoMapping, edbDataListMap map[int][]*edbDataModel.EdbDataList, extraConfig request.SectionScatterReq) (edbIdList []int, chartDataResp request.SectionScatterInfoResp, err error) {
  989. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  990. edbDataMap := make(map[int]map[string]float64)
  991. for edbInfoId, edbDataList := range edbDataListMap {
  992. edbDateData := make(map[string]float64)
  993. for _, edbData := range edbDataList {
  994. edbDateData[edbData.DataTime] = edbData.Value
  995. }
  996. edbDataMap[edbInfoId] = edbDateData
  997. }
  998. // edbIdList 指标展示顺序;x轴的指标顺序
  999. edbIdList = make([]int, 0)
  1000. edbMappingMap := make(map[int]*chartEdbMappingModel.ChartEdbInfoMapping)
  1001. for _, v := range mappingList {
  1002. edbIdList = append(edbIdList, v.EdbInfoId)
  1003. edbMappingMap[v.EdbInfoId] = v
  1004. }
  1005. //SectionScatterSeriesInfoResp
  1006. dataListResp := make([]request.SectionScatterSeriesItemResp, 0) //y轴的数据列表
  1007. for _, seriesItem := range extraConfig.SeriesList {
  1008. var maxDate time.Time
  1009. // 系列中的指标数据
  1010. tmpSeriesEdbInfoList := make([]request.SectionScatterEdbItemResp, 0)
  1011. var minXVal, maxXVal, minYVal, maxYVal float64
  1012. for _, edbConf := range seriesItem.EdbInfoList {
  1013. tmpItem := request.SectionScatterEdbItemResp{
  1014. IsShow: edbConf.IsShow,
  1015. Name: edbConf.Name,
  1016. NameEn: edbConf.NameEn,
  1017. } //单个坐标点的数据
  1018. //X轴的数据
  1019. {
  1020. edbInfoId := edbConf.XEdbInfoId //X轴的指标
  1021. edbMappingInfo, ok := edbMappingMap[edbInfoId]
  1022. if !ok {
  1023. continue
  1024. }
  1025. findDate := edbConf.XDate //需要的日期值
  1026. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  1027. if len(dataList) <= 0 {
  1028. // 没有数据的指标id
  1029. //findDataList = append(findDataList, 0)
  1030. continue
  1031. }
  1032. tmpItem.XEdbInfoId = edbInfoId
  1033. tmpItem.XName = edbMappingInfo.EdbName
  1034. tmpItem.XNameEn = edbMappingInfo.EdbNameEn
  1035. switch edbConf.XDateType {
  1036. case 1: //最新值
  1037. dataList := edbDataListMap[edbInfoId]
  1038. findDate = dataList[len(dataList)-1].DataTime
  1039. case 2: //近期几天
  1040. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  1041. if tmpErr != nil {
  1042. err = tmpErr
  1043. return
  1044. }
  1045. findDateTime = findDateTime.AddDate(0, 0, -edbConf.XDateValue)
  1046. lenData := len(dataList) - 1
  1047. for i := lenData; i >= 0; i-- {
  1048. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  1049. if tmpErr != nil {
  1050. err = tmpErr
  1051. return
  1052. }
  1053. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  1054. findDate = dataList[i].DataTime
  1055. break
  1056. }
  1057. }
  1058. case 3: // 固定日期
  1059. //最早的日期
  1060. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  1061. if tmpErr != nil {
  1062. err = tmpErr
  1063. return
  1064. }
  1065. //寻找固定日期的数据
  1066. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.XDate, time.Local)
  1067. if tmpErr != nil {
  1068. err = tmpErr
  1069. return
  1070. }
  1071. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  1072. tmpDate := tmpDateTime.Format(utils.FormatDate)
  1073. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  1074. findDate = tmpDate
  1075. break
  1076. }
  1077. }
  1078. default:
  1079. err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.XDate))
  1080. return
  1081. }
  1082. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  1083. if maxDate.IsZero() {
  1084. maxDate = findDateTime
  1085. } else {
  1086. if findDateTime.After(maxDate) {
  1087. maxDate = findDateTime
  1088. }
  1089. }
  1090. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  1091. tmpItem.XDate = findDate
  1092. tmpItem.XValue = tmpValue
  1093. } else {
  1094. continue
  1095. }
  1096. }
  1097. //Y轴的数据
  1098. {
  1099. edbInfoId := edbConf.YEdbInfoId //Y轴的指标
  1100. edbMappingInfo, ok := edbMappingMap[edbInfoId]
  1101. if !ok {
  1102. continue
  1103. }
  1104. findDate := edbConf.YDate //需要的日期值
  1105. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  1106. if len(dataList) <= 0 {
  1107. // 没有数据的指标id
  1108. //findDataList = append(findDataList, 0)
  1109. continue
  1110. }
  1111. tmpItem.YEdbInfoId = edbInfoId
  1112. tmpItem.YName = edbMappingInfo.EdbName
  1113. tmpItem.YNameEn = edbMappingInfo.EdbNameEn
  1114. switch edbConf.YDateType {
  1115. case 1: //最新值
  1116. dataList := edbDataListMap[edbInfoId]
  1117. findDate = dataList[len(dataList)-1].DataTime
  1118. case 2: //近期几天
  1119. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  1120. if tmpErr != nil {
  1121. err = tmpErr
  1122. return
  1123. }
  1124. findDateTime = findDateTime.AddDate(0, 0, -edbConf.YDateValue)
  1125. lenData := len(dataList) - 1
  1126. for i := lenData; i >= 0; i-- {
  1127. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  1128. if tmpErr != nil {
  1129. err = tmpErr
  1130. return
  1131. }
  1132. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  1133. findDate = dataList[i].DataTime
  1134. break
  1135. }
  1136. }
  1137. case 3: // 固定日期
  1138. //最早的日期
  1139. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  1140. if tmpErr != nil {
  1141. err = tmpErr
  1142. return
  1143. }
  1144. //寻找固定日期的数据
  1145. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.YDate, time.Local)
  1146. if tmpErr != nil {
  1147. err = tmpErr
  1148. return
  1149. }
  1150. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  1151. tmpDate := tmpDateTime.Format(utils.FormatDate)
  1152. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  1153. findDate = tmpDate
  1154. break
  1155. }
  1156. }
  1157. default:
  1158. err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.YDate))
  1159. return
  1160. }
  1161. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  1162. if maxDate.IsZero() {
  1163. maxDate = findDateTime
  1164. } else {
  1165. if findDateTime.After(maxDate) {
  1166. maxDate = findDateTime
  1167. }
  1168. }
  1169. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  1170. tmpItem.YDate = findDate
  1171. tmpItem.YValue = tmpValue
  1172. } else {
  1173. continue
  1174. }
  1175. }
  1176. // 获取当前系列的X轴的最大最小值
  1177. {
  1178. if tmpItem.XValue < minXVal {
  1179. minXVal = tmpItem.XValue
  1180. }
  1181. if tmpItem.XValue > maxXVal {
  1182. maxXVal = tmpItem.XValue
  1183. }
  1184. if tmpItem.YValue < minYVal {
  1185. minYVal = tmpItem.YValue
  1186. }
  1187. if tmpItem.YValue > maxYVal {
  1188. maxYVal = tmpItem.YValue
  1189. }
  1190. }
  1191. tmpSeriesEdbInfoList = append(tmpSeriesEdbInfoList, tmpItem)
  1192. }
  1193. trendLimitData := make([]request.CoordinatePoint, 0) //趋势线的前后坐标点
  1194. var trendLine, rSquare string
  1195. // 生成线性方程式
  1196. var a, b float64
  1197. {
  1198. coordinateData := make([]utils.Coordinate, 0)
  1199. for _, tmpSeriesEdbInfo := range tmpSeriesEdbInfoList {
  1200. tmpCoordinate1 := utils.Coordinate{
  1201. X: tmpSeriesEdbInfo.XValue,
  1202. Y: tmpSeriesEdbInfo.YValue,
  1203. }
  1204. coordinateData = append(coordinateData, tmpCoordinate1)
  1205. }
  1206. // 只有存在两个坐标点的时候,才能去计算线性方程和R平方
  1207. if len(coordinateData) >= 2 {
  1208. a, b = utils.GetLinearResult(coordinateData)
  1209. if !math.IsNaN(a) && !math.IsNaN(b) {
  1210. if b > 0 {
  1211. trendLine = fmt.Sprintf("y=%sx+%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
  1212. } else {
  1213. trendLine = fmt.Sprintf("y=%sx%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
  1214. }
  1215. minYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(minXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
  1216. maxYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(maxXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
  1217. }
  1218. // 计算R平方
  1219. rSquare = fmt.Sprint(utils.CalculationDecisive(coordinateData))
  1220. }
  1221. trendLimitData = append(trendLimitData, request.CoordinatePoint{
  1222. X: minXVal,
  1223. Y: minYVal,
  1224. }, request.CoordinatePoint{
  1225. X: maxXVal,
  1226. Y: maxYVal,
  1227. })
  1228. }
  1229. dataListResp = append(dataListResp, request.SectionScatterSeriesItemResp{
  1230. Name: seriesItem.Name,
  1231. NameEn: seriesItem.NameEn,
  1232. Color: seriesItem.Color,
  1233. EdbInfoList: tmpSeriesEdbInfoList,
  1234. ShowTrendLine: seriesItem.ShowTrendLine,
  1235. ShowFitEquation: seriesItem.ShowFitEquation,
  1236. ShowRSquare: seriesItem.ShowRSquare,
  1237. TrendLine: trendLine,
  1238. RSquare: rSquare,
  1239. TrendLimitData: trendLimitData,
  1240. })
  1241. }
  1242. chartDataResp = request.SectionScatterInfoResp{
  1243. XName: extraConfig.XName,
  1244. XNameEn: extraConfig.XNameEn,
  1245. XUnitName: extraConfig.XUnitName,
  1246. XUnitNameEn: extraConfig.XUnitNameEn,
  1247. YName: extraConfig.YName,
  1248. YNameEn: extraConfig.YNameEn,
  1249. YUnitName: extraConfig.YUnitName,
  1250. YUnitNameEn: extraConfig.YUnitNameEn,
  1251. XMinValue: extraConfig.XMinValue,
  1252. XMaxValue: extraConfig.XMaxValue,
  1253. YMinValue: extraConfig.YMinValue,
  1254. YMaxValue: extraConfig.YMaxValue,
  1255. DataList: dataListResp,
  1256. }
  1257. return
  1258. }