mixed_table.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. package excel
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_api/models/data_manage"
  6. "eta/eta_api/models/data_manage/excel/request"
  7. "eta/eta_api/services/data"
  8. "eta/eta_api/utils"
  9. "fmt"
  10. "strings"
  11. "time"
  12. )
  13. // GetMixedTableCellData 获取混合表格数据
  14. func GetMixedTableCellData(cellRelationConf string, config [][]request.MixedTableCellDataReq) (newMixedTableCellDataList [][]request.MixedTableCellDataReq, err error, errMsg string) {
  15. // 单元格关系配置x信息
  16. cellRelationConfMap := make(map[string]request.CellRelationConf)
  17. cellRelationConfList := make([]request.CellRelationConf, 0)
  18. if cellRelationConf != `` {
  19. err = json.Unmarshal([]byte(cellRelationConf), &cellRelationConfList)
  20. if err != nil {
  21. return
  22. }
  23. for _, v := range cellRelationConfList {
  24. cellRelationConfMap[v.Key] = v
  25. }
  26. }
  27. // 找出所有的关联指标id
  28. config, edbInfoIdList, _, err, errMsg := handleConfig(config)
  29. if err != nil {
  30. return
  31. }
  32. // 查询所有关联的指标信息
  33. edbInfoList, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
  34. if err != nil {
  35. return
  36. }
  37. // 指标信息map
  38. edbInfoMap := make(map[int]*data_manage.EdbInfo)
  39. // 日度指标数据map
  40. edbDayDataListMap := make(map[int]map[string]float64)
  41. // 月度指标数据map
  42. edbMonthDataListMap := make(map[int]map[string]float64)
  43. // 日度指标数据map
  44. edbDataListMap := make(map[int][]*data_manage.EdbDataList)
  45. for _, edbInfo := range edbInfoList {
  46. edbInfoMap[edbInfo.EdbInfoId] = edbInfo
  47. dataList := make([]*data_manage.EdbDataList, 0)
  48. switch edbInfo.EdbInfoType {
  49. case 0:
  50. dataList, _ = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.EdbInfoId, ``, ``)
  51. case 1:
  52. _, dataList, _, _, _, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
  53. default:
  54. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  55. }
  56. dateValMap := make(map[string]float64)
  57. monthValMap := make(map[string]float64)
  58. for _, tmpData := range dataList {
  59. // 日度数据
  60. dateValMap[tmpData.DataTime] = tmpData.Value
  61. // 月度数据(取该月份的第一个数据)
  62. yearMonth := strings.Join(strings.Split(tmpData.DataTime, "-")[0:2], "-")
  63. if _, ok := monthValMap[yearMonth]; !ok {
  64. monthValMap[yearMonth] = tmpData.Value
  65. }
  66. }
  67. edbDayDataListMap[edbInfo.EdbInfoId] = dateValMap
  68. edbMonthDataListMap[edbInfo.EdbInfoId] = monthValMap
  69. edbDataListMap[edbInfo.EdbInfoId] = dataList
  70. }
  71. // 单元格实际绑定的信息map
  72. cellDataRelationMap := make(map[string]request.MixedTableCellDataReq, 0)
  73. // 处理指定指标的日期
  74. for k, row := range config {
  75. for i, cell := range row {
  76. // 单元格是日期类型,且是日导入指标日期(指标库的最新日期)
  77. if cell.DataType == request.DateDT && cell.DataTimeType == request.EdbDateDT {
  78. if edbInfo, ok := edbInfoMap[cell.EdbInfoId]; ok {
  79. cell.ShowValue = edbInfo.EndDate
  80. cell.DataTime = edbInfo.EndDate
  81. config[k][i] = cell
  82. }
  83. }
  84. row[i] = cell
  85. cellDataRelationMap[cell.Uid] = cell
  86. }
  87. config[k] = row
  88. }
  89. type BaseCalculate struct {
  90. DataList []*data_manage.EdbDataList
  91. Frequency string `description:"需要转换的频度"`
  92. Formula interface{}
  93. Calendar string `description:"公历/农历"`
  94. MoveType int `description:"移动方式:1:领先(默认),2:滞后"`
  95. MoveFrequency string `description:"移动频度"`
  96. FromFrequency string `description:"来源的频度"`
  97. Source int `description:"1:累计值转月;2:累计值转季;3:同比值;4:同差值;5:N数值移动平均数计算;6:环比值;7:环差值;8:升频;9:降频;10:时间移位;11:超季节性;12:年化;13:累计值;14:累计值年初至今;15:指数修匀;16:日均值"`
  98. }
  99. // 指标计算的结果map
  100. edbSourceDataMap := make(map[string]map[string]float64)
  101. for k, row := range config {
  102. for i, cell := range row {
  103. switch cell.DataType {
  104. case request.EdbDT: // 指标类型
  105. if edbInfo, ok := edbInfoMap[cell.EdbInfoId]; ok {
  106. cell.ShowValue = edbInfo.EdbName
  107. }
  108. case request.InsertDataDT, request.PopInsertDataDT: // 数据类型
  109. tmpDateList := strings.Split(cell.DataTime, "-")
  110. tmpDateValMap := make(map[string]float64)
  111. if len(tmpDateList) == 2 {
  112. //月度数据
  113. if dateValMap, ok := edbMonthDataListMap[cell.EdbInfoId]; ok {
  114. tmpDateValMap = dateValMap
  115. }
  116. } else {
  117. // 日度数据
  118. if dateValMap, ok := edbDayDataListMap[cell.EdbInfoId]; ok {
  119. tmpDateValMap = dateValMap
  120. }
  121. }
  122. if val, ok2 := tmpDateValMap[cell.DataTime]; ok2 {
  123. //cell.ShowValue = fmt.Sprint(val)
  124. cell.ShowValue = utils.FormatTableDataShowValue(val)
  125. }
  126. case request.InsertEdbCalculateDataDT: // 指标类型
  127. // 日期
  128. relationConf, ok := cellRelationConfMap[cell.Uid]
  129. if !ok {
  130. // 日期关系配置不存在
  131. continue
  132. }
  133. if relationConf.RelationDate.Key == `` {
  134. // 日期关系配置未绑定
  135. continue
  136. }
  137. relationCell, ok := cellDataRelationMap[relationConf.RelationDate.Key]
  138. if relationConf.RelationDate.Key == `` {
  139. // 找不到对应日期的单元格
  140. continue
  141. }
  142. var tmpDataMap map[string]float64
  143. key := utils.MD5(cell.Value)
  144. tmpDataMap, ok = edbSourceDataMap[key]
  145. if !ok {
  146. // 对应的配置值
  147. var tmpConfig request.CalculateConf
  148. err = json.Unmarshal([]byte(cell.Value), &tmpConfig)
  149. if err != nil {
  150. return
  151. }
  152. tmpDataList, ok := edbDataListMap[tmpConfig.EdbInfoId]
  153. if !ok {
  154. continue
  155. }
  156. edbInfo, ok := edbInfoMap[tmpConfig.EdbInfoId]
  157. if !ok {
  158. continue
  159. }
  160. req2 := &BaseCalculate{
  161. DataList: tmpDataList,
  162. Frequency: tmpConfig.Frequency,
  163. Formula: tmpConfig.Formula,
  164. Calendar: tmpConfig.Calendar,
  165. MoveType: tmpConfig.MoveType,
  166. MoveFrequency: tmpConfig.MoveFrequency,
  167. FromFrequency: edbInfo.Frequency,
  168. Source: tmpConfig.Source,
  169. }
  170. // 调用指标库去更新
  171. reqJson, tmpErr := json.Marshal(req2)
  172. if tmpErr != nil {
  173. utils.FileLog.Error(fmt.Sprintf("计算失败1,配置信息;%s;错误原因:%s", cell.Value, tmpErr.Error()))
  174. err = tmpErr
  175. return
  176. }
  177. respItem, tmpErr := data.BaseCalculate(string(reqJson))
  178. if tmpErr != nil {
  179. utils.FileLog.Error(fmt.Sprintf("计算失败2,配置信息;%s;错误原因:%s", cell.Value, tmpErr.Error()))
  180. err = tmpErr
  181. return
  182. }
  183. if respItem.Ret != 200 {
  184. utils.FileLog.Error(fmt.Sprintf("计算失败3,配置信息;%s;原因:%s;错误原因:%s", cell.Value, respItem.Msg, respItem.ErrMsg))
  185. continue
  186. }
  187. tmpDataMap = respItem.Data.DataMap
  188. // 计算结果存一份,万一存在重复的计算方式,那么省的重新计算一下
  189. edbSourceDataMap[key] = tmpDataMap
  190. }
  191. val := tmpDataMap[relationCell.DataTime]
  192. cell.ShowValue = utils.FormatTableDataShowValue(val)
  193. //
  194. }
  195. row[i] = cell
  196. }
  197. config[k] = row
  198. }
  199. newMixedTableCellDataList = config
  200. return
  201. }
  202. // handleConfig
  203. // @Description: 处理混合表格配置
  204. // @author: Roc
  205. // @datetime2023-10-27 13:24:53
  206. // @param configList [][]request.MixedTableCellDataReq
  207. // @return newConfig [][]request.MixedTableCellDataReq
  208. // @return edbInfoIdList []int
  209. // @return dataEdbInfoIdList []int
  210. // @return err error
  211. // @return errMsg string
  212. func handleConfig(configList [][]request.MixedTableCellDataReq) (newConfig [][]request.MixedTableCellDataReq, edbInfoIdList []int, dataEdbInfoIdList []int, err error, errMsg string) {
  213. edbInfoIdList = make([]int, 0)
  214. dataEdbInfoIdList = make([]int, 0)
  215. for ck, rowList := range configList {
  216. for rk, cell := range rowList {
  217. switch cell.DataType {
  218. case request.EdbDT: // 指标信息
  219. edbInfoIdList = append(edbInfoIdList, cell.EdbInfoId)
  220. case request.InsertDataDT, request.PopInsertDataDT: // 插值、弹框插值
  221. dataEdbInfoIdList = append(dataEdbInfoIdList, cell.EdbInfoId)
  222. case request.InsertEdbCalculateDataDT: // 插入指标计算公式生成的值
  223. var config request.CalculateConf
  224. err = json.Unmarshal([]byte(cell.Value), &config)
  225. if err != nil {
  226. return
  227. }
  228. edbInfoIdList = append(edbInfoIdList, config.EdbInfoId)
  229. dataEdbInfoIdList = append(dataEdbInfoIdList, cell.EdbInfoId)
  230. case request.DateDT: // 日期类型
  231. if cell.DataTimeType == request.EdbDateDT {
  232. var config request.EdbDateConf
  233. err = json.Unmarshal([]byte(cell.Value), &config)
  234. if err != nil {
  235. return
  236. }
  237. edbInfoIdList = append(edbInfoIdList, config.EdbInfoId)
  238. } else {
  239. date, tmpErr, tmpErrMsg := handleDate(cell.DataTimeType, cell.Value)
  240. if tmpErr != nil {
  241. err = tmpErr
  242. errMsg = tmpErrMsg
  243. return
  244. }
  245. rowList[rk].DataTime = date
  246. rowList[rk].ShowValue = date
  247. }
  248. }
  249. }
  250. configList[ck] = rowList
  251. }
  252. newConfig = configList
  253. return
  254. }
  255. // HandleDate
  256. // @Description: 日期处理
  257. // @author: Roc
  258. // @datetime2023-10-27 09:37:02
  259. // @param dataTimeType int
  260. // @param val string
  261. // @return date string
  262. // @return err error
  263. // @return errMsg string
  264. func HandleDate(dataTimeType int, val string) (date string, err error, errMsg string) {
  265. return handleDate(dataTimeType, val)
  266. }
  267. // handleDate
  268. // @Description: 日期处理
  269. // @author: Roc
  270. // @datetime2023-10-27 09:36:49
  271. // @param dataTimeType int
  272. // @param val string
  273. // @return date string
  274. // @return err error
  275. // @return errMsg string
  276. func handleDate(dataTimeType int, val string) (date string, err error, errMsg string) {
  277. if val == `` {
  278. errMsg = "错误的日期数据"
  279. err = errors.New(errMsg)
  280. return
  281. }
  282. switch dataTimeType {
  283. case request.CustomDateT: //手动输入日期
  284. date = val
  285. case request.SystemDateT: // 系统日期
  286. date, err, errMsg = handleSystemDateT(val)
  287. case request.EdbDateDT: // 导入指标日期(指标库的最新日期)
  288. default:
  289. errMsg = "错误的日期类型"
  290. err = errors.New(errMsg)
  291. return
  292. }
  293. return
  294. }
  295. // handleSystemDateT
  296. // @Description: 处理导入系统日期
  297. // @author: Roc
  298. // @datetime2023-10-27 09:36:21
  299. // @param confStr string
  300. // @return date string
  301. // @return err error
  302. // @return errMsg string
  303. func handleSystemDateT(confStr string) (date string, err error, errMsg string) {
  304. var config request.SystemDateConf
  305. err = json.Unmarshal([]byte(confStr), &config)
  306. if err != nil {
  307. return
  308. }
  309. switch config.Source {
  310. case request.SystemCurrDateT:
  311. date = time.Now().Format(utils.FormatDate)
  312. case request.SystemCalculateDateT:
  313. date, err, errMsg = handleSystemCalculateDateT(config.CalculateNum, config.CalculateFrequency)
  314. case request.SystemFrequencyDateT: // 处理系统日期相关的指定频率(所在周/旬/月/季/半年/年的最后/最早一天)
  315. date, err, errMsg = handleSystemAppointDateT(config.Day, config.Frequency)
  316. default:
  317. errMsg = "错误的日期日期导入方式"
  318. err = errors.New(fmt.Sprint("错误的日期日期导入方式:", config.Source))
  319. return
  320. }
  321. return
  322. }
  323. // handleSystemCalculateDateT
  324. // @Description: 处理系统日期计算后的日期
  325. // @author: Roc
  326. // @datetime2023-10-27 09:31:22
  327. // @param num int
  328. // @param frequency string
  329. // @return date string
  330. // @return err error
  331. // @return errMsg string
  332. func handleSystemCalculateDateT(num int, frequency string) (date string, err error, errMsg string) {
  333. if err != nil {
  334. return
  335. }
  336. currDate := time.Now()
  337. switch frequency {
  338. case "", "日":
  339. date = currDate.AddDate(0, 0, num).Format(utils.FormatDate)
  340. default:
  341. errMsg = "错误的日期频度:" + frequency
  342. err = errors.New(errMsg)
  343. return
  344. }
  345. return
  346. }
  347. // handleSystemAppointDateT
  348. // @Description: 处理系统日期相关的指定频率(所在周/旬/月/季/半年/年的最后/最早一天)
  349. // @author: Roc
  350. // @datetime2023-10-27 09:31:35
  351. // @param Frequency string
  352. // @param Day string
  353. // @return date string
  354. // @return err error
  355. // @return errMsg string
  356. func handleSystemAppointDateT(appointDay, frequency string) (date string, err error, errMsg string) {
  357. currDate := time.Now()
  358. switch frequency {
  359. case "本周":
  360. day := int(currDate.Weekday())
  361. if day == 0 { // 周日
  362. day = 7
  363. }
  364. num := 0
  365. switch appointDay {
  366. case "周一":
  367. num = 1
  368. case "周二":
  369. num = 2
  370. case "周三":
  371. num = 3
  372. case "周四":
  373. num = 4
  374. case "周五":
  375. num = 5
  376. case "周六":
  377. num = 6
  378. case "周日":
  379. num = 7
  380. }
  381. day = num - day
  382. date = currDate.AddDate(0, 0, day).Format(utils.FormatDate)
  383. case "本旬":
  384. day := currDate.Day()
  385. var tmpDate time.Time
  386. switch appointDay {
  387. case "第一天":
  388. if day <= 10 {
  389. tmpDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, currDate.Location())
  390. } else if day <= 20 {
  391. tmpDate = time.Date(currDate.Year(), currDate.Month(), 11, 0, 0, 0, 0, currDate.Location())
  392. } else {
  393. tmpDate = time.Date(currDate.Year(), currDate.Month(), 21, 0, 0, 0, 0, currDate.Location())
  394. }
  395. case "最后一天":
  396. if day <= 10 {
  397. tmpDate = time.Date(currDate.Year(), currDate.Month(), 10, 0, 0, 0, 0, currDate.Location())
  398. } else if day <= 20 {
  399. tmpDate = time.Date(currDate.Year(), currDate.Month(), 20, 0, 0, 0, 0, currDate.Location())
  400. } else {
  401. tmpDate = time.Date(currDate.Year(), currDate.Month()+1, 1, 0, 0, 0, 0, currDate.Location()).AddDate(0, 0, -1)
  402. }
  403. }
  404. date = tmpDate.Format(utils.FormatDate)
  405. case "本月":
  406. var tmpDate time.Time
  407. switch appointDay {
  408. case "第一天":
  409. tmpDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, currDate.Location())
  410. case "最后一天":
  411. tmpDate = time.Date(currDate.Year(), currDate.Month()+1, 1, 0, 0, 0, 0, currDate.Location()).AddDate(0, 0, -1)
  412. }
  413. date = tmpDate.Format(utils.FormatDate)
  414. case "本季":
  415. month := currDate.Month()
  416. var tmpDate time.Time
  417. switch appointDay {
  418. case "第一天":
  419. if month <= 3 {
  420. tmpDate = time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, currDate.Location())
  421. } else if month <= 6 {
  422. tmpDate = time.Date(currDate.Year(), 4, 1, 0, 0, 0, 0, currDate.Location())
  423. } else if month <= 9 {
  424. tmpDate = time.Date(currDate.Year(), 7, 1, 0, 0, 0, 0, currDate.Location())
  425. } else {
  426. tmpDate = time.Date(currDate.Year(), 10, 1, 0, 0, 0, 0, currDate.Location())
  427. }
  428. case "最后一天":
  429. if month <= 3 {
  430. tmpDate = time.Date(currDate.Year(), 3, 31, 0, 0, 0, 0, currDate.Location())
  431. } else if month <= 6 {
  432. tmpDate = time.Date(currDate.Year(), 6, 30, 0, 0, 0, 0, currDate.Location())
  433. } else if month <= 9 {
  434. tmpDate = time.Date(currDate.Year(), 9, 30, 0, 0, 0, 0, currDate.Location())
  435. } else {
  436. tmpDate = time.Date(currDate.Year(), 12, 31, 0, 0, 0, 0, currDate.Location())
  437. }
  438. }
  439. date = tmpDate.Format(utils.FormatDate)
  440. default:
  441. errMsg = "错误的日期频度:" + frequency
  442. err = errors.New(errMsg)
  443. return
  444. }
  445. return
  446. }