chart_extra_config.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. package data
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_api/models/data_manage"
  6. "eta/eta_api/services/google"
  7. "eta/eta_api/utils"
  8. "fmt"
  9. "strconv"
  10. "strings"
  11. "time"
  12. )
  13. func HandleExtraConfig(chartType int, extraConfigStr string) (newExtraConfigStr string, err error, errMsg string) {
  14. newExtraConfigStr = extraConfigStr
  15. switch chartType {
  16. case 10: // 截面散点图
  17. var tmpExtraConfig data_manage.SectionScatterReq
  18. if extraConfigStr == `` {
  19. errMsg = "截面散点图未配置"
  20. err = errors.New(errMsg)
  21. return
  22. }
  23. err = json.Unmarshal([]byte(extraConfigStr), &tmpExtraConfig)
  24. if err != nil {
  25. errMsg = "截面散点配置异常"
  26. err = errors.New(errMsg)
  27. return
  28. }
  29. newExtraConfigStr, err, errMsg = handleSectionScatterChartData(tmpExtraConfig)
  30. }
  31. return
  32. }
  33. // handleSectionScatterChartData 截面散点图的数据处理
  34. func handleSectionScatterChartData(extraConfig data_manage.SectionScatterReq) (extraConfigStr string, err error, errMsg string) {
  35. translateNameList := make([]string, 0)
  36. translateNameMap := make(map[string]bool, 0)
  37. if extraConfig.XNameEn == `` {
  38. if _, ok := translateNameMap[extraConfig.XName]; !ok {
  39. translateNameMap[extraConfig.XName] = true
  40. tmpName := strings.TrimSuffix(extraConfig.XName, " ")
  41. tmpName = strings.TrimPrefix(tmpName, " ")
  42. translateNameList = append(translateNameList, tmpName)
  43. }
  44. }
  45. if extraConfig.XUnitNameEn == `` {
  46. if _, ok := translateNameMap[extraConfig.XUnitName]; !ok {
  47. translateNameMap[extraConfig.XUnitName] = true
  48. tmpName := strings.TrimSuffix(extraConfig.XUnitName, " ")
  49. tmpName = strings.TrimPrefix(tmpName, " ")
  50. translateNameList = append(translateNameList, tmpName)
  51. }
  52. }
  53. if extraConfig.YNameEn == `` {
  54. if _, ok := translateNameMap[extraConfig.YName]; !ok {
  55. translateNameMap[extraConfig.YName] = true
  56. tmpName := strings.TrimSuffix(extraConfig.YName, " ")
  57. tmpName = strings.TrimPrefix(tmpName, " ")
  58. translateNameList = append(translateNameList, tmpName)
  59. }
  60. }
  61. if extraConfig.YUnitNameEn == `` {
  62. if _, ok := translateNameMap[extraConfig.YUnitName]; !ok {
  63. translateNameMap[extraConfig.YUnitName] = true
  64. tmpName := strings.TrimSuffix(extraConfig.YUnitName, " ")
  65. tmpName = strings.TrimPrefix(tmpName, " ")
  66. translateNameList = append(translateNameList, tmpName)
  67. }
  68. }
  69. for _, v := range extraConfig.SeriesList {
  70. if v.NameEn == `` {
  71. if _, ok := translateNameMap[v.Name]; !ok {
  72. translateNameMap[v.Name] = true
  73. tmpName := strings.TrimSuffix(v.Name, " ")
  74. tmpName = strings.TrimPrefix(tmpName, " ")
  75. translateNameList = append(translateNameList, tmpName)
  76. }
  77. }
  78. for _, edbInfo := range v.EdbInfoList {
  79. if edbInfo.NameEn == `` {
  80. if _, ok := translateNameMap[edbInfo.Name]; !ok {
  81. translateNameMap[edbInfo.Name] = true
  82. tmpName := strings.TrimSuffix(edbInfo.Name, " ")
  83. tmpName = strings.TrimPrefix(tmpName, " ")
  84. translateNameList = append(translateNameList, tmpName)
  85. }
  86. }
  87. }
  88. }
  89. // 获取英文名称map
  90. enNameMap, _, _ := GetEnNameMapByCnNameList(translateNameList)
  91. for k, seriesItem := range extraConfig.SeriesList {
  92. if len(seriesItem.EdbInfoList) <= 0 {
  93. errMsg = "指标不能为空"
  94. err = errors.New(errMsg)
  95. return
  96. }
  97. for edbIndex, edbConf := range seriesItem.EdbInfoList {
  98. if edbConf.NameEn == `` { //标签英文名称
  99. if tmpNameEn, ok := enNameMap[edbConf.Name]; ok {
  100. edbConf.NameEn = tmpNameEn
  101. }
  102. }
  103. seriesItem.EdbInfoList[edbIndex] = edbConf
  104. }
  105. if seriesItem.NameEn == `` { //系列英文名称
  106. if tmpNameEn, ok := enNameMap[seriesItem.Name]; ok {
  107. seriesItem.NameEn = tmpNameEn
  108. }
  109. }
  110. extraConfig.SeriesList[k] = seriesItem
  111. }
  112. if extraConfig.XNameEn == `` {
  113. if tmpNameEn, ok := enNameMap[extraConfig.XName]; ok {
  114. extraConfig.XNameEn = tmpNameEn
  115. }
  116. }
  117. if extraConfig.XUnitNameEn == `` {
  118. if tmpNameEn, ok := enNameMap[extraConfig.XUnitName]; ok {
  119. extraConfig.XUnitNameEn = tmpNameEn
  120. }
  121. }
  122. if extraConfig.YNameEn == `` {
  123. if tmpNameEn, ok := enNameMap[extraConfig.YName]; ok {
  124. extraConfig.YNameEn = tmpNameEn
  125. }
  126. }
  127. if extraConfig.YUnitNameEn == `` {
  128. if tmpNameEn, ok := enNameMap[extraConfig.YUnitName]; ok {
  129. extraConfig.YUnitNameEn = tmpNameEn
  130. }
  131. }
  132. extraConfigByte, err := json.Marshal(extraConfig)
  133. if err != nil {
  134. return
  135. }
  136. extraConfigStr = string(extraConfigByte)
  137. return
  138. }
  139. // GetEnNameMapByCnNameList 根据中文名称列表获取英文名称map
  140. func GetEnNameMapByCnNameList(cnNameList []string) (contentEnMap map[string]string, err error, errMsg string) {
  141. // 返回参初始化
  142. contentEnMap = make(map[string]string)
  143. // 英文临时赋值变量
  144. tmpContentEnMapAll := make(map[string]string)
  145. count := 0
  146. contentMap := make(map[string]string, 0)
  147. for k, v := range cnNameList {
  148. //如果单条翻译的字符数超过1000,则直接翻译,否则批量翻译
  149. if count >= 50 { //待翻译的条数不能超过50; 单条翻译字符数不能超过1000字符
  150. tmpContentEnMap, tmpErr, tmpErrMsg := google.BatchTranslateHandlerByGoogle(contentMap)
  151. if tmpErr != nil {
  152. err = tmpErr
  153. errMsg = tmpErrMsg
  154. return
  155. }
  156. for tmpK, contentEn := range tmpContentEnMap {
  157. tmpContentEnMapAll[tmpK] = contentEn
  158. }
  159. contentMap = make(map[string]string, 0)
  160. count = 0
  161. }
  162. contentMap[strconv.Itoa(k)] = v
  163. count += 1
  164. }
  165. //剩余不满50条的content
  166. if count > 0 {
  167. tmpContentEnMap, tmpErr, tmpErrMsg := google.BatchTranslateHandlerByGoogle(contentMap)
  168. if tmpErr != nil {
  169. err = tmpErr
  170. errMsg = tmpErrMsg
  171. return
  172. }
  173. for tmpK, contentEn := range tmpContentEnMap {
  174. tmpContentEnMapAll[tmpK] = contentEn
  175. }
  176. }
  177. // 重新组装拼接返回
  178. lenCnNameList := len(cnNameList)
  179. for k, v := range tmpContentEnMapAll {
  180. tmpIndex, _ := strconv.Atoi(k)
  181. if tmpIndex < lenCnNameList {
  182. contentEnMap[cnNameList[tmpIndex]] = v
  183. }
  184. }
  185. return
  186. }
  187. // GetChartSectionCombineData 截面组合图的数据处理
  188. func GetChartSectionCombineData(chartInfoId int, mappingList []*data_manage.ChartEdbInfoMapping, edbDataListMap map[int][]*data_manage.EdbDataList, extraConfig data_manage.ChartSectionAllExtraConf) (edbIdList []int, chartDataResp data_manage.SectionScatterInfoResp, err error) {
  189. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  190. edbDataMap := make(map[int]map[string]float64)
  191. for edbInfoId, edbDataList := range edbDataListMap {
  192. edbDateData := make(map[string]float64)
  193. for _, edbData := range edbDataList {
  194. edbDateData[edbData.DataTime] = edbData.Value
  195. }
  196. edbDataMap[edbInfoId] = edbDateData
  197. }
  198. // edbIdList 指标展示顺序;x轴的指标顺序
  199. edbIdList = make([]int, 0)
  200. edbMappingMap := make(map[int]*data_manage.ChartEdbInfoMapping)
  201. for _, v := range mappingList {
  202. edbIdList = append(edbIdList, v.EdbInfoId)
  203. edbMappingMap[v.EdbInfoId] = v
  204. }
  205. // 确定好截面散点图返回的数据格式
  206. // 获取所有的引用日期设置
  207. DateConfListMap := make(map[string]*data_manage.ChartSectionDateConfItem)
  208. for _, v := range extraConfig.DateConfList {
  209. DateConfListMap[v.DateConfName] = v
  210. }
  211. // 遍历每个系列
  212. // 遍历每个指标,根据选中的日期,进行日期变换得到最终的日期,根据最终的日期获取对应的值
  213. // 组装数据
  214. dataListResp := new(data_manage.ChartSectionCombineDataResp) //y轴的数据列表
  215. for _, seriesItem := range extraConfig.SeriesList {
  216. var maxDate time.Time
  217. var minVal, maxVal float64
  218. noDataEdbIdList := make([]int, 0)
  219. dataList := make([]float64, len(seriesItem.EdbInfoList))
  220. for index, edbConf := range seriesItem.EdbInfoList {
  221. edbInfoId := edbConf.EdbInfoId //X轴的指标
  222. _, ok := edbMappingMap[edbInfoId]
  223. if !ok {
  224. continue
  225. }
  226. edbDataList, ok3 := edbDataListMap[edbInfoId]
  227. if !ok3 {
  228. err = fmt.Errorf("指标%d的日期数据不存在", edbInfoId)
  229. return
  230. }
  231. /*dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  232. if len(dataList) <= 0 {
  233. // 没有数据的指标id
  234. //findDataList = append(findDataList, 0)
  235. continue
  236. }*/
  237. //日期变换处理,判断用指标的最新日期还是,直接获取引用日期
  238. var findDate string
  239. if edbConf.DateConfName == "" {
  240. findDate, err = GetChartSectionSeriesDateByDateChange(edbInfoId, edbDataList, edbConf.DateConf.DateChange, edbConf.DateConf.MoveForward)
  241. } else {
  242. // 获取日期配置
  243. dateConfItem, ok1 := DateConfListMap[edbConf.DateConfName]
  244. if !ok1 {
  245. err = fmt.Errorf("引用日期配置不存在")
  246. return
  247. }
  248. // todo 根据日期变换得到最终日期
  249. edbDataListTmp := make([]*data_manage.EdbDataList, 0)
  250. if dateConfItem.EdbInfoId > 0 {
  251. edbDataListTmp, ok1 = edbDataListMap[dateConfItem.EdbInfoId]
  252. if !ok1 {
  253. err = fmt.Errorf("指标%d的日期数据不存在", dateConfItem.EdbInfoId)
  254. return
  255. }
  256. }
  257. findDate, err = GetChartSectionSeriesDateByDateChange(dateConfItem.EdbInfoId, edbDataListTmp, dateConfItem.DateChange, dateConfItem.MoveForward)
  258. }
  259. findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
  260. if maxDate.IsZero() {
  261. maxDate = findDateTime
  262. } else {
  263. if findDateTime.After(maxDate) {
  264. maxDate = findDateTime
  265. }
  266. }
  267. if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
  268. dataList[index] = tmpValue
  269. if index == 0 {
  270. minVal = tmpValue
  271. maxVal = tmpValue
  272. } else {
  273. if tmpValue < minVal {
  274. minVal = tmpValue
  275. }
  276. if tmpValue > maxVal {
  277. maxVal = tmpValue
  278. }
  279. }
  280. } else {
  281. noDataEdbIdList = append(noDataEdbIdList, edbInfoId)
  282. continue
  283. }
  284. }
  285. seriesItem.DataList = dataList
  286. seriesItem.MinData = minVal
  287. seriesItem.MaxData = maxVal
  288. seriesItem.NoDataEdbIdList = noDataEdbIdList
  289. }
  290. dataListResp.XDataList = extraConfig.XDataList
  291. dataListResp.SeriesList = extraConfig.SeriesList
  292. dataListResp.DateConfList = extraConfig.DateConfList
  293. dataListResp.BaseChartSeriesName = extraConfig.BaseChartSeriesName
  294. dataListResp.UnitList = extraConfig.UnitList
  295. dataListResp.IsHeap = extraConfig.IsHeap
  296. dataListResp.SortType = extraConfig.SortType
  297. return
  298. }
  299. // GetChartSectionSeriesDateByDateChange 获取日期变换后的日期edbInfoId 1指标日期,2 系统日期
  300. func GetChartSectionSeriesDateByDateChange(edbInfoId int, dataList []*data_manage.EdbDataList, dateChange []*data_manage.ChartSectionDateChange, moveForward int) (newDate string, err error) {
  301. if edbInfoId > 0 { //指标日期
  302. newDate = GetEdbDateByMoveForward(moveForward, dataList)
  303. } else {
  304. //系统日期
  305. newDate = time.Now().Format(utils.FormatDate)
  306. }
  307. if newDate != "" && len(dateChange) > 0 {
  308. newDate, err = HandleChartSectionSeriesDateChange(newDate, dateChange)
  309. }
  310. return
  311. }
  312. func GetEdbDateByMoveForward(moveForward int, edbDataList []*data_manage.EdbDataList) (date string) {
  313. dateList := make([]string, 0)
  314. for _, v := range edbDataList {
  315. dateList = append(dateList, v.DataTime)
  316. }
  317. date = GetEdbDateByMoveForwardByDateList(moveForward, dateList)
  318. return
  319. }
  320. func GetEdbDateByMoveForwardByDateList(moveForward int, dateList []string) (date string) {
  321. // 根据日期进行排序
  322. index := len(dateList) - 1 - moveForward
  323. for k, v := range dateList {
  324. if k == index {
  325. date = v
  326. return
  327. }
  328. }
  329. return
  330. }
  331. // HandleChartSectionSeriesDateChange 处理日期变换
  332. func HandleChartSectionSeriesDateChange(date string, dateChange []*data_manage.ChartSectionDateChange) (newDate string, err error) {
  333. newDate = date
  334. if newDate != "" {
  335. if len(dateChange) > 0 {
  336. var dateTime time.Time
  337. dateTime, err = time.ParseInLocation(utils.FormatDate, newDate, time.Local)
  338. if err != nil {
  339. err = fmt.Errorf("日期解析失败: %s", err.Error())
  340. return
  341. }
  342. for _, v := range dateChange {
  343. if v.ChangeType == 1 {
  344. dateTime = dateTime.AddDate(v.Year, v.Month, v.Day)
  345. newDate = dateTime.Format(utils.FormatDate)
  346. } else if v.ChangeType == 2 {
  347. newDate, err, _ = handleSystemAppointDateT(dateTime, v.FrequencyDay, v.Frequency)
  348. if err != nil {
  349. return
  350. }
  351. dateTime, err = time.ParseInLocation(utils.FormatDate, newDate, time.Local)
  352. if err != nil {
  353. err = fmt.Errorf("日期解析失败: %s", err.Error())
  354. return
  355. }
  356. }
  357. }
  358. }
  359. }
  360. return
  361. }
  362. // handleSystemAppointDateT
  363. // @Description: 处理系统日期相关的指定频率(所在周/旬/月/季/半年/年的最后/最早一天)
  364. // @author: Roc
  365. // @datetime2023-10-27 09:31:35
  366. // @param Frequency string
  367. // @param Day string
  368. // @return date string
  369. // @return err error
  370. // @return errMsg string
  371. func handleSystemAppointDateT(currDate time.Time, appointDay, frequency string) (date string, err error, errMsg string) {
  372. //currDate := time.Now()
  373. switch frequency {
  374. case "本周":
  375. day := int(currDate.Weekday())
  376. if day == 0 { // 周日
  377. day = 7
  378. }
  379. num := 0
  380. switch appointDay {
  381. case "周一":
  382. num = 1
  383. case "周二":
  384. num = 2
  385. case "周三":
  386. num = 3
  387. case "周四":
  388. num = 4
  389. case "周五":
  390. num = 5
  391. case "周六":
  392. num = 6
  393. case "周日":
  394. num = 7
  395. }
  396. day = num - day
  397. date = currDate.AddDate(0, 0, day).Format(utils.FormatDate)
  398. case "本旬":
  399. day := currDate.Day()
  400. var tmpDate time.Time
  401. switch appointDay {
  402. case "第一天":
  403. if day <= 10 {
  404. tmpDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, currDate.Location())
  405. } else if day <= 20 {
  406. tmpDate = time.Date(currDate.Year(), currDate.Month(), 11, 0, 0, 0, 0, currDate.Location())
  407. } else {
  408. tmpDate = time.Date(currDate.Year(), currDate.Month(), 21, 0, 0, 0, 0, currDate.Location())
  409. }
  410. case "最后一天":
  411. if day <= 10 {
  412. tmpDate = time.Date(currDate.Year(), currDate.Month(), 10, 0, 0, 0, 0, currDate.Location())
  413. } else if day <= 20 {
  414. tmpDate = time.Date(currDate.Year(), currDate.Month(), 20, 0, 0, 0, 0, currDate.Location())
  415. } else {
  416. tmpDate = time.Date(currDate.Year(), currDate.Month()+1, 1, 0, 0, 0, 0, currDate.Location()).AddDate(0, 0, -1)
  417. }
  418. }
  419. date = tmpDate.Format(utils.FormatDate)
  420. case "本月":
  421. var tmpDate time.Time
  422. switch appointDay {
  423. case "第一天":
  424. tmpDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, currDate.Location())
  425. case "最后一天":
  426. tmpDate = time.Date(currDate.Year(), currDate.Month()+1, 1, 0, 0, 0, 0, currDate.Location()).AddDate(0, 0, -1)
  427. }
  428. date = tmpDate.Format(utils.FormatDate)
  429. case "本季":
  430. month := currDate.Month()
  431. var tmpDate time.Time
  432. switch appointDay {
  433. case "第一天":
  434. if month <= 3 {
  435. tmpDate = time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, currDate.Location())
  436. } else if month <= 6 {
  437. tmpDate = time.Date(currDate.Year(), 4, 1, 0, 0, 0, 0, currDate.Location())
  438. } else if month <= 9 {
  439. tmpDate = time.Date(currDate.Year(), 7, 1, 0, 0, 0, 0, currDate.Location())
  440. } else {
  441. tmpDate = time.Date(currDate.Year(), 10, 1, 0, 0, 0, 0, currDate.Location())
  442. }
  443. case "最后一天":
  444. if month <= 3 {
  445. tmpDate = time.Date(currDate.Year(), 3, 31, 0, 0, 0, 0, currDate.Location())
  446. } else if month <= 6 {
  447. tmpDate = time.Date(currDate.Year(), 6, 30, 0, 0, 0, 0, currDate.Location())
  448. } else if month <= 9 {
  449. tmpDate = time.Date(currDate.Year(), 9, 30, 0, 0, 0, 0, currDate.Location())
  450. } else {
  451. tmpDate = time.Date(currDate.Year(), 12, 31, 0, 0, 0, 0, currDate.Location())
  452. }
  453. }
  454. date = tmpDate.Format(utils.FormatDate)
  455. case "本半年":
  456. month := currDate.Month()
  457. var tmpDate time.Time
  458. switch appointDay {
  459. case "第一天":
  460. if month <= 6 {
  461. tmpDate = time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, currDate.Location())
  462. } else {
  463. tmpDate = time.Date(currDate.Year(), 7, 1, 0, 0, 0, 0, currDate.Location())
  464. }
  465. case "最后一天":
  466. if month <= 6 {
  467. tmpDate = time.Date(currDate.Year(), 6, 30, 0, 0, 0, 0, currDate.Location())
  468. } else {
  469. tmpDate = time.Date(currDate.Year(), 12, 31, 0, 0, 0, 0, currDate.Location())
  470. }
  471. }
  472. date = tmpDate.Format(utils.FormatDate)
  473. case "本年":
  474. var tmpDate time.Time
  475. switch appointDay {
  476. case "第一天":
  477. tmpDate = time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, currDate.Location())
  478. case "最后一天":
  479. tmpDate = time.Date(currDate.Year(), 12, 31, 0, 0, 0, 0, currDate.Location())
  480. }
  481. date = tmpDate.Format(utils.FormatDate)
  482. default:
  483. errMsg = "错误的日期频度:" + frequency
  484. err = errors.New(errMsg)
  485. return
  486. }
  487. return
  488. }