chart_info.go 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367
  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. item.MoveLatestDate = item.LatestDate
  505. var startDateReal string
  506. var diffSeconds int64
  507. if chartType == 2 { //季节性图
  508. startDateReal = startDate
  509. } else {
  510. if v.EdbInfoType == 0 && v.LeadUnit != "" && v.LeadValue > 0 { //领先指标
  511. var startTimeRealTemp time.Time
  512. startDateParse, _ := time.Parse(utils.FormatDate, startDate)
  513. switch v.LeadUnit {
  514. case "天":
  515. startTimeRealTemp = startDateParse.AddDate(0, 0, -v.LeadValue)
  516. case "月":
  517. startTimeRealTemp = startDateParse.AddDate(0, -v.LeadValue, 0)
  518. case "季":
  519. startTimeRealTemp = startDateParse.AddDate(0, -3*v.LeadValue, 0)
  520. case "周":
  521. startTimeRealTemp = startDateParse.AddDate(0, 0, -7*v.LeadValue)
  522. case "年":
  523. startTimeRealTemp = startDateParse.AddDate(-v.LeadValue, 0, 0)
  524. }
  525. if startTimeRealTemp.Before(startDateParse) {
  526. startDateReal = startTimeRealTemp.Format(utils.FormatDate)
  527. diffSeconds = (int64(startTimeRealTemp.UnixNano()) - int64(startDateParse.UnixNano())) / 1e6
  528. } else {
  529. startDateReal = startDate
  530. diffSeconds = 0
  531. }
  532. // 预测指标的开始日期也要偏移
  533. {
  534. day, tmpErr := utils.GetDaysBetween2Date(utils.FormatDate, startDate, startDateReal)
  535. if tmpErr != nil {
  536. err = tmpErr
  537. return
  538. }
  539. item.MoveLatestDate = item.MoveLatestDate.AddDate(0, 0, day)
  540. }
  541. } else {
  542. startDateReal = startDate
  543. }
  544. }
  545. //fmt.Println("line 1011 chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
  546. calendarPreYear := 0
  547. if calendar == "农历" {
  548. newStartDateReal, err := time.Parse(utils.FormatDate, startDateReal)
  549. if err != nil {
  550. fmt.Println("time.Parse:" + err.Error())
  551. }
  552. calendarPreYear = newStartDateReal.Year() - 1
  553. newStartDateReal = newStartDateReal.AddDate(-1, 0, 0)
  554. startDateReal = newStartDateReal.Format(utils.FormatDate)
  555. }
  556. dataList := make([]*edbDataModel.EdbDataList, 0)
  557. //fmt.Println("chart:", v.Source, v.EdbInfoId, startDateReal, endDate, ";EdbInfoCategoryType:", v.EdbInfoCategoryType)
  558. //var newEdbInfo *edbInfoModel.EdbInfo
  559. switch v.EdbInfoCategoryType {
  560. case 0:
  561. dataList, err = edbDataModel.GetEdbDataList(v.Source, v.EdbInfoId, startDateReal, endDate)
  562. case 1:
  563. _, dataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(v.EdbInfoId, startDateReal, endDate, false)
  564. //if item.MaxValue < newEdbInfo.MaxValue {
  565. // item.MaxData = newEdbInfo.MaxValue
  566. //}
  567. //if item.MinData > newEdbInfo.MinValue {
  568. // item.MinData = newEdbInfo.MinValue
  569. //}
  570. default:
  571. err = errors.New(fmt.Sprint("获取失败,指标类型异常", v.EdbInfoCategoryType))
  572. }
  573. if err != nil {
  574. return
  575. }
  576. edbDataListMap[v.EdbInfoId] = dataList
  577. if diffSeconds != 0 && v.EdbInfoType == 0 {
  578. dataListLen := len(dataList)
  579. for i := 0; i < dataListLen; i++ {
  580. dataList[i].DataTimestamp = dataList[i].DataTimestamp - diffSeconds
  581. }
  582. }
  583. if chartType == 2 {
  584. latestDateStr := v.LatestDate.Format(utils.FormatDate) //实际数据的截止日期
  585. latestDate := v.LatestDate
  586. //latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
  587. //if tmpErr != nil {
  588. // err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + v.LatestDate))
  589. // return
  590. //}
  591. latestDateYear := latestDate.Year() //实际数据截止年份
  592. if calendar == "农历" {
  593. if len(dataList) <= 0 {
  594. result := new(edbDataModel.EdbDataResult)
  595. item.DataList = result
  596. } else {
  597. result, tmpErr := edbDataService.AddCalculateQuarter(dataList)
  598. if tmpErr != nil {
  599. err = errors.New("获取农历数据失败,Err:" + tmpErr.Error())
  600. return
  601. }
  602. // 处理季节图的截止日期
  603. for k, edbDataItems := range result.List {
  604. var cuttingDataTimestamp int64
  605. // 切割的日期时间字符串
  606. cuttingDataTimeStr := latestDate.AddDate(0, 0, edbDataItems.BetweenDay).Format(utils.FormatDate)
  607. //如果等于最后的实际日期,那么遍历找到该日期对应的时间戳,并将其赋值为 切割时间戳
  608. if edbDataItems.Year >= latestDateYear {
  609. for _, tmpData := range edbDataItems.Items {
  610. if tmpData.DataTime == cuttingDataTimeStr {
  611. cuttingDataTimestamp = tmpData.DataTimestamp
  612. break
  613. }
  614. }
  615. }
  616. edbDataItems.CuttingDataTimestamp = cuttingDataTimestamp
  617. result.List[k] = edbDataItems
  618. }
  619. if result.List[0].Year != calendarPreYear {
  620. itemList := make([]*edbDataModel.EdbDataList, 0)
  621. items := new(edbDataModel.EdbDataItems)
  622. //items.Year = calendarPreYear
  623. items.Items = itemList
  624. newResult := new(edbDataModel.EdbDataResult)
  625. newResult.List = append(newResult.List, items)
  626. newResult.List = append(newResult.List, result.List...)
  627. item.DataList = newResult
  628. } else {
  629. item.DataList = result
  630. }
  631. }
  632. } else {
  633. currentYear := time.Now().Year()
  634. quarterDataList := make([]*edbDataModel.QuarterData, 0)
  635. quarterMap := make(map[int][]*edbDataModel.EdbDataList)
  636. var quarterArr []int
  637. for _, v := range dataList {
  638. itemDate, tmpErr := time.Parse(utils.FormatDate, v.DataTime)
  639. if tmpErr != nil {
  640. err = errors.New("季度指标日期转换,Err:" + tmpErr.Error() + ";DataTime:" + v.DataTime)
  641. return
  642. }
  643. year := itemDate.Year()
  644. newItemDate := itemDate.AddDate(currentYear-year, 0, 0)
  645. timestamp := newItemDate.UnixNano() / 1e6
  646. v.DataTimestamp = timestamp
  647. if findVal, ok := quarterMap[year]; !ok {
  648. quarterArr = append(quarterArr, year)
  649. findVal = append(findVal, v)
  650. quarterMap[year] = findVal
  651. } else {
  652. findVal = append(findVal, v)
  653. quarterMap[year] = findVal
  654. }
  655. }
  656. for _, v := range quarterArr {
  657. itemList := quarterMap[v]
  658. quarterItem := new(edbDataModel.QuarterData)
  659. quarterItem.Year = v
  660. quarterItem.DataList = itemList
  661. //如果等于最后的实际日期,那么将切割时间戳记录
  662. if v == latestDateYear {
  663. var cuttingDataTimestamp int64
  664. for _, tmpData := range itemList {
  665. if tmpData.DataTime == latestDateStr {
  666. cuttingDataTimestamp = tmpData.DataTimestamp
  667. break
  668. }
  669. }
  670. quarterItem.CuttingDataTimestamp = cuttingDataTimestamp
  671. } else if v > latestDateYear {
  672. //如果大于最后的实际日期,那么第一个点就是切割的时间戳
  673. if len(itemList) > 0 {
  674. quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
  675. }
  676. }
  677. quarterDataList = append(quarterDataList, quarterItem)
  678. }
  679. item.DataList = quarterDataList
  680. }
  681. } else if chartType == 7 { //柱方图
  682. //item.DataList = dataList
  683. } else {
  684. item.DataList = dataList
  685. }
  686. edbList = append(edbList, item)
  687. }
  688. return
  689. }
  690. // BarChartData 柱方图的数据处理
  691. func BarChartData(mappingList []*chartEdbMappingModel.ChartEdbInfoMapping, edbDataListMap map[int][]*edbDataModel.EdbDataList, barChartInfoDateList []request.BarChartInfoDateReq, barChartInfoSort request.BarChartInfoSortReq) (edbIdList []int, yDataList []chart_info.YData, err error) {
  692. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  693. edbDataMap := make(map[int]map[string]float64)
  694. for edbInfoId, edbDataList := range edbDataListMap {
  695. edbDateData := make(map[string]float64)
  696. for _, edbData := range edbDataList {
  697. edbDateData[edbData.DataTime] = edbData.Value
  698. }
  699. edbDataMap[edbInfoId] = edbDateData
  700. }
  701. // edbIdList 指标展示顺序;x轴的指标顺序
  702. edbIdList = make([]int, 0)
  703. //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
  704. dateData := make(map[int]float64)
  705. if barChartInfoSort.Sort == 0 {
  706. for _, v := range mappingList {
  707. edbIdList = append(edbIdList, v.EdbInfoId)
  708. }
  709. } else {
  710. lenBarChartInfoDateList := len(barChartInfoDateList)
  711. if barChartInfoSort.DateIndex >= lenBarChartInfoDateList {
  712. err = errors.New("排序日期异常")
  713. return
  714. }
  715. notDataEdbIdList := make([]int, 0) //没有数据的指标id
  716. // 日期配置
  717. barChartInfoDate := barChartInfoDateList[barChartInfoSort.DateIndex]
  718. for edbInfoId, dataList := range edbDataListMap {
  719. if len(dataList) <= 0 {
  720. // 没有数据的指标id
  721. notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
  722. continue
  723. }
  724. findDate := barChartInfoDate.Date
  725. switch barChartInfoDate.Type {
  726. case 1: //最新值
  727. findDate = dataList[len(dataList)-1].DataTime
  728. case 2: //近期几天
  729. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  730. if tmpErr != nil {
  731. err = tmpErr
  732. return
  733. }
  734. findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  735. lenData := len(dataList) - 1
  736. for i := lenData; i >= 0; i-- {
  737. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  738. if tmpErr != nil {
  739. err = tmpErr
  740. return
  741. }
  742. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  743. findDate = dataList[i].DataTime
  744. break
  745. }
  746. }
  747. case 3: // 固定日期
  748. //最早的日期
  749. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  750. if tmpErr != nil {
  751. err = tmpErr
  752. return
  753. }
  754. //寻找固定日期的数据
  755. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  756. if tmpErr != nil {
  757. err = tmpErr
  758. return
  759. }
  760. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  761. tmpDate := tmpDateTime.Format(utils.FormatDate)
  762. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  763. findDate = tmpDate
  764. break
  765. }
  766. }
  767. default:
  768. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  769. return
  770. }
  771. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  772. dateData[edbInfoId] = tmpValue
  773. } else {
  774. // 没有数据的指标id
  775. notDataEdbIdList = append(notDataEdbIdList, edbInfoId)
  776. }
  777. }
  778. //Sort int `description:"排序类型,0:默认,1:升序,2:降序"`
  779. // 排序
  780. dateDataSort := utils.NewMapSorter(dateData)
  781. sort.Sort(dateDataSort)
  782. if barChartInfoSort.Sort == 1 {
  783. // 先将没有数据的指标id放在最前面
  784. if len(notDataEdbIdList) > 0 {
  785. edbIdList = append(edbIdList, notDataEdbIdList...)
  786. }
  787. for _, v := range dateDataSort {
  788. edbIdList = append(edbIdList, v.Key)
  789. }
  790. } else {
  791. for i := len(dateDataSort) - 1; i >= 0; i-- {
  792. edbIdList = append(edbIdList, dateDataSort[i].Key)
  793. }
  794. // 再将没有数据的指标id放在最后面
  795. if len(notDataEdbIdList) > 0 {
  796. edbIdList = append(edbIdList, notDataEdbIdList...)
  797. }
  798. }
  799. }
  800. yDataList = make([]chart_info.YData, 0) //y轴的数据列表
  801. for _, barChartInfoDate := range barChartInfoDateList {
  802. var maxDate time.Time
  803. findDataList := make([]float64, 0) // 当前日期的数据值
  804. for _, edbInfoId := range edbIdList {
  805. findDate := barChartInfoDate.Date //需要的日期值
  806. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  807. if len(dataList) <= 0 {
  808. // 没有数据的指标id
  809. findDataList = append(findDataList, 0)
  810. continue
  811. }
  812. switch barChartInfoDate.Type {
  813. case 1: //最新值
  814. dataList := edbDataListMap[edbInfoId]
  815. findDate = dataList[len(dataList)-1].DataTime
  816. case 2: //近期几天
  817. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  818. if tmpErr != nil {
  819. err = tmpErr
  820. return
  821. }
  822. findDateTime = findDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  823. lenData := len(dataList) - 1
  824. for i := lenData; i >= 0; i-- {
  825. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  826. if tmpErr != nil {
  827. err = tmpErr
  828. return
  829. }
  830. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  831. findDate = dataList[i].DataTime
  832. break
  833. }
  834. }
  835. case 3: // 固定日期
  836. //最早的日期
  837. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  838. if tmpErr != nil {
  839. err = tmpErr
  840. return
  841. }
  842. //寻找固定日期的数据
  843. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  844. if tmpErr != nil {
  845. err = tmpErr
  846. return
  847. }
  848. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  849. tmpDate := tmpDateTime.Format(utils.FormatDate)
  850. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  851. findDate = tmpDate
  852. break
  853. }
  854. }
  855. default:
  856. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  857. return
  858. }
  859. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  860. if maxDate.IsZero() {
  861. maxDate = findDateTime
  862. } else {
  863. if findDateTime.After(maxDate) {
  864. maxDate = findDateTime
  865. }
  866. }
  867. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  868. findDataList = append(findDataList, tmpValue)
  869. } else {
  870. findDataList = append(findDataList, 0)
  871. }
  872. }
  873. yDate := "0000-00-00"
  874. if !maxDate.IsZero() {
  875. yDate = maxDate.Format(utils.FormatDate)
  876. }
  877. yDataList = append(yDataList, chart_info.YData{
  878. Date: yDate,
  879. Value: findDataList,
  880. Color: barChartInfoDate.Color,
  881. Name: barChartInfoDate.Name,
  882. })
  883. }
  884. return
  885. }
  886. // 获取频度的英文版
  887. func GetFrequencyEn(frequency string) (frequencyEn string) {
  888. switch frequency {
  889. case "日度":
  890. frequencyEn = "day"
  891. return
  892. case "周度":
  893. frequencyEn = "week"
  894. return
  895. case "旬度":
  896. frequencyEn = "ten days"
  897. return
  898. case "月度":
  899. frequencyEn = "month"
  900. return
  901. case "季度":
  902. frequencyEn = "quarter"
  903. return
  904. case "年度":
  905. frequencyEn = "year"
  906. return
  907. }
  908. return
  909. }
  910. func GetLeadUnitEn(unit string) (unitEn string) {
  911. switch unit {
  912. case "天":
  913. unitEn = "day"
  914. return
  915. case "周":
  916. unitEn = "week"
  917. return
  918. case "月":
  919. unitEn = "month"
  920. return
  921. case "季":
  922. unitEn = "quarter"
  923. return
  924. case "年":
  925. unitEn = "year"
  926. return
  927. }
  928. return
  929. }
  930. // ChartInfoRefreshV2 图表刷新
  931. // @author Roc
  932. // @datetime 2022-09-16 10:15:38
  933. // @description 将原来自己写的一套获取所有关联指标,然后刷新指标逻辑 改成 只获取使用的指标id,然后遍历去调用“指标刷新服务”
  934. func ChartInfoRefreshV2(chartInfoId int) (err error) {
  935. var errmsg string
  936. defer func() {
  937. if err != nil {
  938. go alarm_msg.SendAlarmMsg("ChartInfoRefresh:"+errmsg, 3)
  939. //go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "ChartInfoRefresh:"+errmsg, utils.EmailSendToUsers)
  940. fmt.Println("ChartInfoRefresh Err:" + errmsg)
  941. }
  942. }()
  943. edbMappingList, err := chartEdbMappingModel.GetMappingListByChartInfoId(chartInfoId)
  944. if err != nil {
  945. errmsg = "获取需要刷新的指标失败:Err:" + err.Error()
  946. return
  947. }
  948. edbIdList := make([]int, 0)
  949. for _, v := range edbMappingList {
  950. edbIdList = append(edbIdList, v.EdbInfoId)
  951. }
  952. // 批量刷新
  953. err, errmsg = EdbInfoRefreshAllFromBase(edbIdList, false)
  954. if err != nil {
  955. return
  956. }
  957. return
  958. }
  959. // CheckChartExtraConfig 校验图表额外配置的信息,并且获取相关联的指标id
  960. func CheckChartExtraConfig(chartType int, extraConfigStr string) (edbIdList []int, err error, errMsg string) {
  961. switch chartType {
  962. case 10: //截面散点
  963. var extraConfig request.SectionScatterReq
  964. err = json.Unmarshal([]byte(extraConfigStr), &extraConfig)
  965. if err != nil {
  966. return
  967. }
  968. // 判断是否有配置日期序列
  969. if len(extraConfig.SeriesList) <= 0 {
  970. errMsg = `请配置序列`
  971. err = errors.New(errMsg)
  972. return
  973. }
  974. // 判断是否有填写指标
  975. if len(extraConfig.SeriesList[0].EdbInfoList) <= 0 {
  976. errMsg = `请选择指标`
  977. err = errors.New(errMsg)
  978. return
  979. }
  980. // 遍历指标列表获取指标id
  981. edbIdMap := make(map[int]int)
  982. for _, v := range extraConfig.SeriesList[0].EdbInfoList {
  983. // X 轴的指标id
  984. if _, ok := edbIdMap[v.XEdbInfoId]; !ok {
  985. edbIdMap[v.XEdbInfoId] = v.XEdbInfoId
  986. edbIdList = append(edbIdList, v.XEdbInfoId)
  987. }
  988. // Y 轴的指标id
  989. if _, ok := edbIdMap[v.YEdbInfoId]; !ok {
  990. edbIdMap[v.YEdbInfoId] = v.YEdbInfoId
  991. edbIdList = append(edbIdList, v.YEdbInfoId)
  992. }
  993. }
  994. }
  995. return
  996. }
  997. // GetSectionScatterChartData 柱方图的数据处理
  998. func GetSectionScatterChartData(mappingList []*chartEdbMappingModel.ChartEdbInfoMapping, edbDataListMap map[int][]*edbDataModel.EdbDataList, extraConfig request.SectionScatterReq) (edbIdList []int, chartDataResp request.SectionScatterInfoResp, err error) {
  999. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  1000. edbDataMap := make(map[int]map[string]float64)
  1001. for edbInfoId, edbDataList := range edbDataListMap {
  1002. edbDateData := make(map[string]float64)
  1003. for _, edbData := range edbDataList {
  1004. edbDateData[edbData.DataTime] = edbData.Value
  1005. }
  1006. edbDataMap[edbInfoId] = edbDateData
  1007. }
  1008. // edbIdList 指标展示顺序;x轴的指标顺序
  1009. edbIdList = make([]int, 0)
  1010. edbMappingMap := make(map[int]*chartEdbMappingModel.ChartEdbInfoMapping)
  1011. for _, v := range mappingList {
  1012. edbIdList = append(edbIdList, v.EdbInfoId)
  1013. edbMappingMap[v.EdbInfoId] = v
  1014. }
  1015. //SectionScatterSeriesInfoResp
  1016. dataListResp := make([]request.SectionScatterSeriesItemResp, 0) //y轴的数据列表
  1017. for _, seriesItem := range extraConfig.SeriesList {
  1018. var maxDate time.Time
  1019. // 系列中的指标数据
  1020. tmpSeriesEdbInfoList := make([]request.SectionScatterEdbItemResp, 0)
  1021. var minXVal, maxXVal, minYVal, maxYVal float64
  1022. for _, edbConf := range seriesItem.EdbInfoList {
  1023. tmpItem := request.SectionScatterEdbItemResp{
  1024. IsShow: edbConf.IsShow,
  1025. Name: edbConf.Name,
  1026. NameEn: edbConf.NameEn,
  1027. } //单个坐标点的数据
  1028. //X轴的数据
  1029. {
  1030. edbInfoId := edbConf.XEdbInfoId //X轴的指标
  1031. edbMappingInfo, ok := edbMappingMap[edbInfoId]
  1032. if !ok {
  1033. continue
  1034. }
  1035. findDate := edbConf.XDate //需要的日期值
  1036. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  1037. if len(dataList) <= 0 {
  1038. // 没有数据的指标id
  1039. //findDataList = append(findDataList, 0)
  1040. continue
  1041. }
  1042. tmpItem.XEdbInfoId = edbInfoId
  1043. tmpItem.XName = edbMappingInfo.EdbName
  1044. tmpItem.XNameEn = edbMappingInfo.EdbNameEn
  1045. switch edbConf.XDateType {
  1046. case 1: //最新值
  1047. dataList := edbDataListMap[edbInfoId]
  1048. findDate = dataList[len(dataList)-1].DataTime
  1049. case 2: //近期几天
  1050. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  1051. if tmpErr != nil {
  1052. err = tmpErr
  1053. return
  1054. }
  1055. findDateTime = findDateTime.AddDate(0, 0, -edbConf.XDateValue)
  1056. lenData := len(dataList) - 1
  1057. for i := lenData; i >= 0; i-- {
  1058. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  1059. if tmpErr != nil {
  1060. err = tmpErr
  1061. return
  1062. }
  1063. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  1064. findDate = dataList[i].DataTime
  1065. break
  1066. }
  1067. }
  1068. case 3: // 固定日期
  1069. //最早的日期
  1070. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  1071. if tmpErr != nil {
  1072. err = tmpErr
  1073. return
  1074. }
  1075. //寻找固定日期的数据
  1076. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.XDate, time.Local)
  1077. if tmpErr != nil {
  1078. err = tmpErr
  1079. return
  1080. }
  1081. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  1082. tmpDate := tmpDateTime.Format(utils.FormatDate)
  1083. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  1084. findDate = tmpDate
  1085. break
  1086. }
  1087. }
  1088. default:
  1089. err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.XDate))
  1090. return
  1091. }
  1092. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  1093. if maxDate.IsZero() {
  1094. maxDate = findDateTime
  1095. } else {
  1096. if findDateTime.After(maxDate) {
  1097. maxDate = findDateTime
  1098. }
  1099. }
  1100. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  1101. tmpItem.XDate = findDate
  1102. tmpItem.XValue = tmpValue
  1103. } else {
  1104. continue
  1105. }
  1106. }
  1107. //Y轴的数据
  1108. {
  1109. edbInfoId := edbConf.YEdbInfoId //Y轴的指标
  1110. edbMappingInfo, ok := edbMappingMap[edbInfoId]
  1111. if !ok {
  1112. continue
  1113. }
  1114. findDate := edbConf.YDate //需要的日期值
  1115. dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  1116. if len(dataList) <= 0 {
  1117. // 没有数据的指标id
  1118. //findDataList = append(findDataList, 0)
  1119. continue
  1120. }
  1121. tmpItem.YEdbInfoId = edbInfoId
  1122. tmpItem.YName = edbMappingInfo.EdbName
  1123. tmpItem.YNameEn = edbMappingInfo.EdbNameEn
  1124. switch edbConf.YDateType {
  1125. case 1: //最新值
  1126. dataList := edbDataListMap[edbInfoId]
  1127. findDate = dataList[len(dataList)-1].DataTime
  1128. case 2: //近期几天
  1129. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
  1130. if tmpErr != nil {
  1131. err = tmpErr
  1132. return
  1133. }
  1134. findDateTime = findDateTime.AddDate(0, 0, -edbConf.YDateValue)
  1135. lenData := len(dataList) - 1
  1136. for i := lenData; i >= 0; i-- {
  1137. currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
  1138. if tmpErr != nil {
  1139. err = tmpErr
  1140. return
  1141. }
  1142. if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
  1143. findDate = dataList[i].DataTime
  1144. break
  1145. }
  1146. }
  1147. case 3: // 固定日期
  1148. //最早的日期
  1149. minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  1150. if tmpErr != nil {
  1151. err = tmpErr
  1152. return
  1153. }
  1154. //寻找固定日期的数据
  1155. findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.YDate, time.Local)
  1156. if tmpErr != nil {
  1157. err = tmpErr
  1158. return
  1159. }
  1160. for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  1161. tmpDate := tmpDateTime.Format(utils.FormatDate)
  1162. if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
  1163. findDate = tmpDate
  1164. break
  1165. }
  1166. }
  1167. default:
  1168. err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.YDate))
  1169. return
  1170. }
  1171. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  1172. if maxDate.IsZero() {
  1173. maxDate = findDateTime
  1174. } else {
  1175. if findDateTime.After(maxDate) {
  1176. maxDate = findDateTime
  1177. }
  1178. }
  1179. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  1180. tmpItem.YDate = findDate
  1181. tmpItem.YValue = tmpValue
  1182. } else {
  1183. continue
  1184. }
  1185. }
  1186. // 获取当前系列的X轴的最大最小值
  1187. {
  1188. if tmpItem.XValue < minXVal {
  1189. minXVal = tmpItem.XValue
  1190. }
  1191. if tmpItem.XValue > maxXVal {
  1192. maxXVal = tmpItem.XValue
  1193. }
  1194. if tmpItem.YValue < minYVal {
  1195. minYVal = tmpItem.YValue
  1196. }
  1197. if tmpItem.YValue > maxYVal {
  1198. maxYVal = tmpItem.YValue
  1199. }
  1200. }
  1201. tmpSeriesEdbInfoList = append(tmpSeriesEdbInfoList, tmpItem)
  1202. }
  1203. trendLimitData := make([]request.CoordinatePoint, 0) //趋势线的前后坐标点
  1204. var trendLine, rSquare string
  1205. // 生成线性方程式
  1206. var a, b float64
  1207. {
  1208. coordinateData := make([]utils.Coordinate, 0)
  1209. for _, tmpSeriesEdbInfo := range tmpSeriesEdbInfoList {
  1210. tmpCoordinate1 := utils.Coordinate{
  1211. X: tmpSeriesEdbInfo.XValue,
  1212. Y: tmpSeriesEdbInfo.YValue,
  1213. }
  1214. coordinateData = append(coordinateData, tmpCoordinate1)
  1215. }
  1216. // 只有存在两个坐标点的时候,才能去计算线性方程和R平方
  1217. if len(coordinateData) >= 2 {
  1218. a, b = utils.GetLinearResult(coordinateData)
  1219. if !math.IsNaN(a) && !math.IsNaN(b) {
  1220. if b > 0 {
  1221. trendLine = fmt.Sprintf("y=%sx+%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
  1222. } else {
  1223. trendLine = fmt.Sprintf("y=%sx%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
  1224. }
  1225. minYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(minXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
  1226. maxYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(maxXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
  1227. }
  1228. // 计算R平方
  1229. rSquare = fmt.Sprint(utils.CalculationDecisive(coordinateData))
  1230. }
  1231. trendLimitData = append(trendLimitData, request.CoordinatePoint{
  1232. X: minXVal,
  1233. Y: minYVal,
  1234. }, request.CoordinatePoint{
  1235. X: maxXVal,
  1236. Y: maxYVal,
  1237. })
  1238. }
  1239. dataListResp = append(dataListResp, request.SectionScatterSeriesItemResp{
  1240. Name: seriesItem.Name,
  1241. NameEn: seriesItem.NameEn,
  1242. Color: seriesItem.Color,
  1243. EdbInfoList: tmpSeriesEdbInfoList,
  1244. ShowTrendLine: seriesItem.ShowTrendLine,
  1245. ShowFitEquation: seriesItem.ShowFitEquation,
  1246. ShowRSquare: seriesItem.ShowRSquare,
  1247. TrendLine: trendLine,
  1248. RSquare: rSquare,
  1249. TrendLimitData: trendLimitData,
  1250. })
  1251. }
  1252. chartDataResp = request.SectionScatterInfoResp{
  1253. XName: extraConfig.XName,
  1254. XNameEn: extraConfig.XNameEn,
  1255. XUnitName: extraConfig.XUnitName,
  1256. XUnitNameEn: extraConfig.XUnitNameEn,
  1257. YName: extraConfig.YName,
  1258. YNameEn: extraConfig.YNameEn,
  1259. YUnitName: extraConfig.YUnitName,
  1260. YUnitNameEn: extraConfig.YUnitNameEn,
  1261. XMinValue: extraConfig.XMinValue,
  1262. XMaxValue: extraConfig.XMaxValue,
  1263. YMinValue: extraConfig.YMinValue,
  1264. YMaxValue: extraConfig.YMaxValue,
  1265. DataList: dataListResp,
  1266. }
  1267. return
  1268. }