time_table.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988
  1. package excel
  2. import (
  3. "errors"
  4. "eta/eta_chart_lib/models"
  5. "eta/eta_chart_lib/models/data_manage"
  6. "eta/eta_chart_lib/models/request"
  7. "eta/eta_chart_lib/services/data"
  8. "eta/eta_chart_lib/utils"
  9. "fmt"
  10. "sort"
  11. "strconv"
  12. "strings"
  13. "time"
  14. "github.com/shopspring/decimal"
  15. "github.com/yidane/formula"
  16. )
  17. // TableDataConfig
  18. // @Description: 表格配置
  19. type TableDataConfig struct {
  20. EdbInfoIdList []int `description:"指标id列表,从左至右,从上到下的顺序"`
  21. Sort int `description:"日期排序,0:倒序,1:正序"`
  22. Data []ManualData `description:"数据列表"`
  23. Num int `description:"实际数据需要列出来的期数"`
  24. RemoveDate []string `description:"不展示的日期"`
  25. ManualDate []string `description:"手动配置的日期(未来的日期)"`
  26. TableEdbInfoList []TableEdbInfo `description:"表格内指标信息"`
  27. TextRowData [][]request.ManualDataReq `description:"文本列表"`
  28. DecimalConfig []DecimalConfig `description:"小数位数配置"`
  29. }
  30. type DecimalConfig struct {
  31. Row string `description:"行上的索引, 目前仅保存指标的日期"`
  32. Col int `description:"列上的索引, 目前仅保存edbInfoId"`
  33. Decimal int `description:"小数位数, 从左至右,从上到下的顺序"`
  34. }
  35. // TableEdbInfo
  36. // @Description: 表格指标信息
  37. type TableEdbInfo struct {
  38. EdbInfoId int `description:"指标ID"`
  39. Tag string `description:"标签"`
  40. EdbName string `description:"指标名称"`
  41. EdbNameEn string `description:"英文指标名称"`
  42. EdbAliasName string `description:"指标别名"`
  43. Frequency string `description:"频度"`
  44. Unit string `description:"单位"`
  45. UnitEn string `description:"英文单位"`
  46. }
  47. // ManualData
  48. // @Description: 手工文本配置
  49. type ManualData struct {
  50. DataType int `description:"数据类型,1:普通的,2:插值法,3:手动输入,4:公式计算"`
  51. DataTime string `description:"所属日期"`
  52. DataTimeType int `description:"日期类型,1:实际日期;2:未来日期"`
  53. ShowValue string `description:"展示值"`
  54. Value string `description:"实际值(计算公式)"`
  55. EdbInfoId int `description:"指标id"`
  56. Tag string `description:"下标"`
  57. RelationEdbInfoList []request.RelationEdbInfo `description:"关联指标(计算公式中关联的指标,用于计算的时候去匹配)"`
  58. }
  59. // GetDataByTableDataConfig 根据数据配置获取表格数据
  60. func GetDataByTableDataConfig(tableDataConfig TableDataConfig) (resultResp request.TableDataReq, err error) {
  61. // 没有选择指标的情况下,直接返回吧
  62. if len(tableDataConfig.EdbInfoIdList) <= 0 {
  63. return
  64. }
  65. // 实际期数没有的情况下,直接返回吧
  66. if tableDataConfig.Num <= 0 {
  67. return
  68. }
  69. // 获取所有的指标信息
  70. edbInfoMap := make(map[int]*data_manage.EdbInfo)
  71. edbInfoIdList := make([]int, 0)
  72. // 标签与指标id的map
  73. tagEdbInfoIdMap := make(map[string]int)
  74. {
  75. for _, tableEdbInfo := range tableDataConfig.TableEdbInfoList {
  76. edbInfoIdList = append(edbInfoIdList, tableEdbInfo.EdbInfoId)
  77. tagEdbInfoIdMap[tableEdbInfo.Tag] = tableEdbInfo.EdbInfoId
  78. }
  79. edbInfoList, tmpErr := data_manage.GetEdbInfoByIdList(edbInfoIdList)
  80. if tmpErr != nil {
  81. err = tmpErr
  82. return
  83. }
  84. for _, v := range edbInfoList {
  85. edbInfoMap[v.EdbInfoId] = v
  86. }
  87. }
  88. manualDateMap := make(map[string]string, 0)
  89. manualDateList := make([]string, 0)
  90. for _, v := range tableDataConfig.Data {
  91. if _, ok := manualDateMap[v.DataTime]; !ok {
  92. manualDateMap[v.DataTime] = v.DataTime
  93. manualDateList = append(manualDateList, v.DataTime)
  94. }
  95. }
  96. // 寻找A列的数据列表
  97. firstEdbInfo, ok := edbInfoMap[tableDataConfig.TableEdbInfoList[0].EdbInfoId]
  98. if !ok {
  99. err = errors.New("找不到A列指标")
  100. return
  101. }
  102. baseFirstEdbInfoDataList, err := GetFirstEdbDataList(firstEdbInfo, tableDataConfig.Num, manualDateList)
  103. if err != nil {
  104. return
  105. }
  106. // A列找不到数据,那么就直接返回吧
  107. if len(baseFirstEdbInfoDataList) <= 0 {
  108. return
  109. }
  110. firstEdbInfoDataList := make([]request.ManualDataReq, 0)
  111. if tableDataConfig.RemoveDate != nil && len(tableDataConfig.RemoveDate) > 0 {
  112. for _, v := range baseFirstEdbInfoDataList {
  113. if utils.InArrayByStr(tableDataConfig.RemoveDate, v.DataTime) {
  114. continue
  115. }
  116. firstEdbInfoDataList = append(firstEdbInfoDataList, v)
  117. }
  118. } else {
  119. firstEdbInfoDataList = baseFirstEdbInfoDataList
  120. }
  121. if len(firstEdbInfoDataList) <= 0 {
  122. return
  123. }
  124. // 实际数据的最后一天
  125. lastRealDateTime, err := time.ParseInLocation(utils.FormatDate, firstEdbInfoDataList[0].DataTime, time.Local)
  126. if err != nil {
  127. return
  128. }
  129. dateMap := make(map[string]string)
  130. dateList := make([]string, 0)
  131. edbInfoIdDateDataMap := make(map[int]map[string]request.ManualDataReq)
  132. firstDateDataMap := make(map[string]request.ManualDataReq)
  133. for _, v := range firstEdbInfoDataList {
  134. dateList = append(dateList, v.DataTime)
  135. dateMap[v.DataTime] = v.DataTime
  136. firstDateDataMap[v.DataTime] = v
  137. }
  138. // 将手工数据的日期填补进去(未来的日期,过去的就不管了)
  139. for _, manualData := range tableDataConfig.Data {
  140. if !utils.InArrayByStr(dateList, manualData.DataTime) {
  141. tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, manualData.DataTime, time.Local)
  142. if tmpErr != nil {
  143. err = tmpErr
  144. return
  145. }
  146. if tmpDateTime.After(lastRealDateTime) {
  147. dateList = append(dateList, manualData.DataTime)
  148. }
  149. }
  150. }
  151. edbInfoIdDateDataMap[firstEdbInfo.EdbInfoId] = firstDateDataMap
  152. for k, edbInfoId := range tableDataConfig.EdbInfoIdList {
  153. if k == 0 {
  154. continue
  155. }
  156. tmpEdbInfo, ok := edbInfoMap[edbInfoId]
  157. if !ok {
  158. err = errors.New("找不到A列指标")
  159. return
  160. }
  161. otherDataList, tmpErr := GetOtherEdbDataList(tmpEdbInfo, dateList)
  162. if tmpErr != nil {
  163. err = tmpErr
  164. return
  165. }
  166. tmpDateDataMap := make(map[string]request.ManualDataReq)
  167. for _, v := range otherDataList {
  168. tmpDateDataMap[v.DataTime] = v
  169. }
  170. edbInfoIdDateDataMap[tmpEdbInfo.EdbInfoId] = tmpDateDataMap
  171. }
  172. for _, v := range tableDataConfig.Data {
  173. tmpDate := v.DataTime
  174. if _, ok := dateMap[tmpDate]; !ok {
  175. dateMap[v.DataTime] = tmpDate
  176. }
  177. edbInfoIdDateData, ok := edbInfoIdDateDataMap[v.EdbInfoId]
  178. if !ok {
  179. edbInfoIdDateData = make(map[string]request.ManualDataReq)
  180. }
  181. // 判断是否存在该日期的数据(不存在,那么插入数据吧,存在就不管了)
  182. tmpManualData, ok := edbInfoIdDateData[tmpDate]
  183. if !ok {
  184. edbInfoIdDateData[tmpDate] = request.ManualDataReq{
  185. DataType: v.DataType,
  186. DataTime: v.DataTime,
  187. ShowValue: v.ShowValue,
  188. Value: v.Value,
  189. }
  190. } else {
  191. if (tmpManualData.DataType == 3 || tmpManualData.DataType == 4) && tmpManualData.ShowValue == `` {
  192. tmpManualData.DataType = v.DataType
  193. tmpManualData.ShowValue = v.ShowValue
  194. tmpManualData.Value = v.Value
  195. tmpManualData.RelationEdbInfoList = v.RelationEdbInfoList
  196. edbInfoIdDateData[tmpDate] = tmpManualData
  197. }
  198. }
  199. edbInfoIdDateDataMap[v.EdbInfoId] = edbInfoIdDateData
  200. }
  201. // 获取数据的日期排序
  202. sortDateTimeList := make([]time.Time, 0)
  203. {
  204. sortDateList := dateList
  205. if tableDataConfig.Sort == 1 {
  206. baseDateList := utils.StrArr{}
  207. baseDateList = append(baseDateList, sortDateList...)
  208. sort.Sort(baseDateList)
  209. sortDateList = append([]string{}, baseDateList...)
  210. } else {
  211. sort.Strings(sortDateList)
  212. }
  213. for _, v := range sortDateList {
  214. tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, v, time.Local)
  215. if tmpErr != nil {
  216. err = tmpErr
  217. return
  218. }
  219. sortDateTimeList = append(sortDateTimeList, tmpDateTime)
  220. }
  221. }
  222. // 数据处理,处理成表格的数据格式
  223. tableDataMap, textRowListDataResp := handleTable(tagEdbInfoIdMap, lastRealDateTime, sortDateTimeList, edbInfoIdDateDataMap, tableDataConfig.Data, tableDataConfig.TextRowData)
  224. data := make([]request.EdbInfoData, 0)
  225. for _, tableEdbInfo := range tableDataConfig.TableEdbInfoList {
  226. tagEdbInfoIdMap[tableEdbInfo.Tag] = tableEdbInfo.EdbInfoId
  227. manualDataReqList := make([]request.ManualDataReq, 0)
  228. tmpEdbInfoData := request.EdbInfoData{
  229. EdbInfoId: tableEdbInfo.EdbInfoId,
  230. Tag: tableEdbInfo.Tag,
  231. EdbName: tableEdbInfo.EdbName,
  232. EdbNameEn: tableEdbInfo.EdbNameEn,
  233. EdbAliasName: tableEdbInfo.EdbAliasName,
  234. Frequency: tableEdbInfo.Frequency,
  235. Unit: tableEdbInfo.Unit,
  236. UnitEn: tableEdbInfo.UnitEn,
  237. Data: manualDataReqList,
  238. }
  239. edbInfo, ok := edbInfoMap[tableEdbInfo.EdbInfoId]
  240. if ok {
  241. tmpEdbInfoData.EdbName = edbInfo.EdbName
  242. tmpEdbInfoData.EdbNameEn = edbInfo.EdbNameEn
  243. tmpEdbInfoData.Frequency = edbInfo.Frequency
  244. tmpEdbInfoData.Unit = edbInfo.Unit
  245. tmpEdbInfoData.UnitEn = edbInfo.UnitEn
  246. //tmpEdbInfoData.ClassifyId = edbInfo.ClassifyId
  247. //tmpEdbInfoData.IsJoinPermission = edbInfo.IsJoinPermission
  248. }
  249. for index, dateTime := range sortDateTimeList {
  250. dataTimeType := 1
  251. if dateTime.After(lastRealDateTime) {
  252. dataTimeType = 2
  253. }
  254. tmpDateTimeStr := dateTime.Format(utils.FormatDate)
  255. rowData, ok := tableDataMap[index+1]
  256. if !ok {
  257. manualDataReqList = append(manualDataReqList, request.ManualDataReq{
  258. DataType: 3,
  259. DataTime: tmpDateTimeStr,
  260. DataTimeType: dataTimeType,
  261. ShowValue: "",
  262. Value: "",
  263. RelationEdbInfoList: nil,
  264. })
  265. continue
  266. }
  267. tmpData, ok := rowData[tableEdbInfo.Tag]
  268. if !ok {
  269. manualDataReqList = append(manualDataReqList, request.ManualDataReq{
  270. DataType: 3,
  271. DataTime: tmpDateTimeStr,
  272. DataTimeType: dataTimeType,
  273. ShowValue: "",
  274. Value: "",
  275. RelationEdbInfoList: nil,
  276. })
  277. continue
  278. }
  279. tmpData.DataTimeType = dataTimeType
  280. manualDataReqList = append(manualDataReqList, tmpData)
  281. }
  282. tmpEdbInfoData.Data = manualDataReqList
  283. data = append(data, tmpEdbInfoData)
  284. }
  285. // 处理一下数据格式
  286. for _, d := range data {
  287. for k2, d2 := range d.Data {
  288. // 可能有ShowValue非数值, 转换一下报错则continue
  289. vf, e := strconv.ParseFloat(d2.ShowValue, 64)
  290. if e != nil {
  291. continue
  292. }
  293. d.Data[k2].ShowValue = utils.FormatTableDataShowValue(vf)
  294. }
  295. }
  296. for _, d := range textRowListDataResp {
  297. for k2, d2 := range d {
  298. // 可能有ShowValue非数值, 转换一下报错则continue
  299. vf, e := strconv.ParseFloat(d2.ShowValue, 64)
  300. if e != nil {
  301. continue
  302. }
  303. d[k2].ShowValue = utils.FormatTableDataShowValue(vf)
  304. }
  305. }
  306. data = SetExcelShowValueByDecimalConfig(data, tableDataConfig.DecimalConfig)
  307. resultResp = request.TableDataReq{
  308. EdbInfoIdList: edbInfoIdList,
  309. Sort: tableDataConfig.Sort,
  310. TextRowData: textRowListDataResp,
  311. Data: data,
  312. }
  313. return
  314. }
  315. func SetExcelShowValueByDecimalConfig(edbData []request.EdbInfoData, decimalConfig []DecimalConfig) []request.EdbInfoData {
  316. if len(decimalConfig) <= 0 || len(edbData) <= 0 {
  317. return edbData
  318. }
  319. edbInfoIndexMap := make(map[int]int)
  320. dateIndexMap := make(map[string]int)
  321. for i, edbInfo := range edbData {
  322. edbInfoIndexMap[edbInfo.EdbInfoId] = i
  323. }
  324. for i, date := range edbData[0].Data {
  325. dateIndexMap[date.DataTime] = i
  326. }
  327. for _, conf := range decimalConfig {
  328. if conf.Col > 0 {
  329. if edbIndex, ok := edbInfoIndexMap[conf.Col]; ok {
  330. for i := 0; i < len(edbData[edbIndex].Data); i++ {
  331. f, err := strconv.ParseFloat(edbData[edbIndex].Data[i].Value, 64)
  332. if err != nil {
  333. continue
  334. }
  335. if conf.Decimal == -1 {
  336. continue
  337. }
  338. formatStr := fmt.Sprintf("%%.%df", conf.Decimal)
  339. edbData[edbIndex].Data[i].ShowValue = fmt.Sprintf(formatStr, f)
  340. }
  341. }
  342. }
  343. if conf.Row != `` {
  344. if dateIndex, ok := dateIndexMap[conf.Row]; ok {
  345. for i := 0; i < len(edbData); i++ {
  346. f, err := strconv.ParseFloat(edbData[i].Data[dateIndex].Value, 64)
  347. if err != nil {
  348. continue
  349. }
  350. if conf.Decimal == -1 {
  351. continue
  352. }
  353. formatStr := fmt.Sprintf("%%.%df", conf.Decimal)
  354. edbData[i].Data[dateIndex].ShowValue = fmt.Sprintf(formatStr, f)
  355. }
  356. }
  357. }
  358. }
  359. return edbData
  360. }
  361. // GetTableDataConfig 根据TableDataReq配置获取相关数据配置
  362. func GetTableDataConfig(reqData request.TableDataReq) (tableDataConfig TableDataConfig, err error) {
  363. // 指标数据
  364. tableDataConfig.EdbInfoIdList = reqData.EdbInfoIdList
  365. tableDataConfig.Sort = reqData.Sort
  366. if len(reqData.Data) <= 0 {
  367. err = errors.New("数据不能为空")
  368. return
  369. }
  370. // 开始日期
  371. var startDate string
  372. // A列的指标id
  373. var firstEdbInfoId int
  374. // 手工操作的数据列
  375. manualDataList := make([]ManualData, 0)
  376. // 指标配置列表
  377. tableEdbInfoList := make([]TableEdbInfo, 0)
  378. // 第一列的日期map
  379. firstDateMap := make(map[string]string)
  380. manualDateMap := make(map[string]string)
  381. for _, v := range reqData.Data {
  382. // 指标信息
  383. tmpTableEdbInfo := TableEdbInfo{
  384. EdbInfoId: v.EdbInfoId,
  385. Tag: v.Tag,
  386. EdbName: v.EdbName,
  387. EdbNameEn: v.EdbNameEn,
  388. EdbAliasName: v.EdbAliasName,
  389. Frequency: v.Frequency,
  390. Unit: v.Unit,
  391. UnitEn: v.UnitEn,
  392. }
  393. tableEdbInfoList = append(tableEdbInfoList, tmpTableEdbInfo)
  394. // 确定数据A列
  395. if v.Tag == "A" {
  396. firstEdbInfoId = v.EdbInfoId
  397. lenData := len(v.Data)
  398. if lenData <= 0 {
  399. err = errors.New("A列不能为空")
  400. return
  401. }
  402. index := 0
  403. if reqData.Sort == 1 {
  404. // 倒序
  405. index = lenData - 1
  406. }
  407. startDate = v.Data[index].DataTime
  408. // 存在的日期列表
  409. for _, data := range v.Data {
  410. firstDateMap[data.DataTime] = data.DataTime
  411. if data.DataTimeType == 2 {
  412. manualDateMap[data.DataTime] = data.DataTime
  413. }
  414. }
  415. }
  416. for _, data := range v.Data {
  417. if data.DataType == 3 || data.DataType == 4 {
  418. tmpManualData := ManualData{
  419. DataType: data.DataType,
  420. DataTime: data.DataTime,
  421. DataTimeType: data.DataTimeType,
  422. ShowValue: data.ShowValue,
  423. Value: data.Value,
  424. EdbInfoId: v.EdbInfoId,
  425. Tag: v.Tag,
  426. RelationEdbInfoList: data.RelationEdbInfoList,
  427. }
  428. if data.DataType == 4 {
  429. tmpManualData.ShowValue = ``
  430. }
  431. manualDataList = append(manualDataList, tmpManualData)
  432. }
  433. }
  434. }
  435. // 总共需要的期数
  436. num := len(reqData.Data[0].Data)
  437. removeDate := make([]string, 0)
  438. // 获取期数
  439. {
  440. firstDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  441. if tmpErr != nil {
  442. err = tmpErr
  443. return
  444. }
  445. edbInfo, tmpErr := data_manage.GetEdbInfoById(firstEdbInfoId)
  446. if tmpErr != nil {
  447. err = tmpErr
  448. return
  449. }
  450. var firstDataList []*models.EdbDataList
  451. switch edbInfo.EdbInfoType {
  452. case 0:
  453. firstDataList, err = models.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
  454. case 1:
  455. _, firstDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
  456. default:
  457. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  458. }
  459. if err != nil {
  460. return
  461. }
  462. // 获取日期内的数据(包含开始日期前一个日期,以及 结束日期后一个日期,目的为了做空日期时的 插值法兼容)
  463. baseDataList := make([]*models.EdbDataList, 0)
  464. for _, data := range firstDataList {
  465. tmpDate := data.DataTime
  466. tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
  467. if tmpErr != nil {
  468. err = tmpErr
  469. return
  470. }
  471. if tmpDateTime.Before(firstDateTime) {
  472. continue
  473. }
  474. baseDataList = append(baseDataList, data)
  475. }
  476. // 筛选出需要删除的日期
  477. for _, tmpData := range baseDataList {
  478. //firstDateMap{}
  479. if _, ok := firstDateMap[tmpData.DataTime]; !ok {
  480. removeDate = append(removeDate, tmpData.DataTime)
  481. }
  482. }
  483. }
  484. tableDataConfig.Num = num
  485. tableDataConfig.RemoveDate = removeDate
  486. tableDataConfig.Data = manualDataList
  487. tableDataConfig.TableEdbInfoList = tableEdbInfoList
  488. tableDataConfig.TextRowData = reqData.TextRowData
  489. return
  490. }
  491. // handleTable 表格数据处理
  492. func handleTable(tagEdbInfoIdMap map[string]int, lastRealDateTime time.Time, sortDateTimeList []time.Time, edbInfoIdDateDataMap map[int]map[string]request.ManualDataReq, manualDataList []ManualData, textRowData [][]request.ManualDataReq) (tableDataMap map[int]map[string]request.ManualDataReq, textRowListDataResp [][]request.ManualDataReq) {
  493. tagList := make([]string, 0)
  494. for tag, _ := range tagEdbInfoIdMap {
  495. tagList = append(tagList, tag)
  496. }
  497. sort.Strings(tagList)
  498. tableDataMap = make(map[int]map[string]request.ManualDataReq) //行、列数据
  499. // 日期与行的关系
  500. dateIndexMap := make(map[string]int)
  501. for k, dateTime := range sortDateTimeList {
  502. rowDataMap := make(map[string]request.ManualDataReq)
  503. dataTimeType := 1
  504. if dateTime.After(lastRealDateTime) {
  505. dataTimeType = 2
  506. }
  507. tmpDateTimeStr := dateTime.Format(utils.FormatDate)
  508. dateIndexMap[tmpDateTimeStr] = k + 1
  509. for _, tag := range tagList {
  510. edbInfoId, ok := tagEdbInfoIdMap[tag]
  511. if !ok { // 没有找到该指标的映射关系,那么就用空串填补
  512. rowDataMap[tag] = request.ManualDataReq{
  513. DataType: 3,
  514. DataTime: tmpDateTimeStr,
  515. DataTimeType: dataTimeType,
  516. ShowValue: "",
  517. Value: "",
  518. RelationEdbInfoList: nil,
  519. }
  520. continue
  521. }
  522. // 获取指标的数据map
  523. dateDataMap, ok := edbInfoIdDateDataMap[edbInfoId]
  524. if !ok { // 没有找到该指标的数据,那么就用空串填补
  525. rowDataMap[tag] = request.ManualDataReq{
  526. DataType: 3,
  527. DataTime: tmpDateTimeStr,
  528. DataTimeType: dataTimeType,
  529. ShowValue: "",
  530. Value: "",
  531. RelationEdbInfoList: nil,
  532. }
  533. continue
  534. }
  535. // 获取指标该日期的数据
  536. tmpData, ok := dateDataMap[tmpDateTimeStr]
  537. if !ok { // 该指标没有找到对应日期的数据,那么就用空串填补
  538. rowDataMap[tag] = request.ManualDataReq{
  539. DataType: 3,
  540. DataTime: tmpDateTimeStr,
  541. DataTimeType: dataTimeType,
  542. ShowValue: "",
  543. Value: "",
  544. RelationEdbInfoList: nil,
  545. }
  546. continue
  547. }
  548. tmpData.DataTimeType = dataTimeType
  549. rowDataMap[tag] = tmpData
  550. }
  551. tableDataMap[k+1] = rowDataMap
  552. }
  553. // 替换手工设置的数据
  554. for _, manualData := range manualDataList {
  555. // 找不到该日期,说明这日期过期了,不处理
  556. index, ok := dateIndexMap[manualData.DataTime]
  557. if !ok {
  558. continue
  559. }
  560. // 获取对应行的数据
  561. rowDataMap, ok := tableDataMap[index]
  562. if !ok {
  563. continue
  564. }
  565. // 找到对应的单元格
  566. tmpData, ok := rowDataMap[manualData.Tag]
  567. if !ok {
  568. continue
  569. }
  570. // 如果该单元格实际有数据(包含预测值),或者插值法补充了数据的话,那么就不用手动填入的数据
  571. if utils.InArrayByInt([]int{1, 2, 5}, tmpData.DataType) {
  572. continue
  573. }
  574. // 手工填写的数字
  575. if tmpData.DataType == 3 {
  576. tmpData.ShowValue = manualData.ShowValue
  577. tmpData.Value = manualData.Value
  578. tableDataMap[index][manualData.Tag] = tmpData
  579. //edbInfoIdDateDataMap[manualData.EdbInfoId][manualData.DataTime] = tmpData
  580. continue
  581. }
  582. // 公式
  583. tmpData.DataType = manualData.DataType
  584. tmpData.ShowValue = ``
  585. tmpData.Value = manualData.Value
  586. tmpData.RelationEdbInfoList = manualData.RelationEdbInfoList
  587. tableDataMap[index][manualData.Tag] = tmpData
  588. }
  589. // 文本行的列表插入
  590. lenTableData := len(tableDataMap)
  591. // 文本行第一列的数据列表(可能多行)
  592. firstColTextRowList := make([]request.ManualDataReq, 0)
  593. // 参与计算的文本行列表数据
  594. tmpTextRowList := make([][]request.ManualDataReq, 0)
  595. for k, textRowList := range textRowData {
  596. // 判断列数是否匹配,不匹配的话那么过滤
  597. if len(tagList)+1 != len(textRowList) {
  598. continue
  599. }
  600. rowDataMap := make(map[string]request.ManualDataReq)
  601. tmpTextRow := make([]request.ManualDataReq, 0)
  602. for index, textRow := range textRowList {
  603. // 移除第一列,因为第一列是日期列
  604. if index == 0 {
  605. firstColTextRowList = append(firstColTextRowList, textRow)
  606. continue
  607. }
  608. rowDataMap[tagList[index-1]] = textRow
  609. tmpTextRow = append(tmpTextRow, textRow)
  610. }
  611. tableDataMap[lenTableData+k+1] = rowDataMap
  612. tmpTextRowList = append(tmpTextRowList, tmpTextRow)
  613. }
  614. // 参与计算的单元格
  615. calculateCellMap := make(map[string]string)
  616. // 计算手工填写的单元格
  617. for _, manualData := range manualDataList {
  618. // 找不到该日期,说明这日期过期了,不处理
  619. index, ok := dateIndexMap[manualData.DataTime]
  620. if !ok {
  621. continue
  622. }
  623. // 获取对应行的数据
  624. rowDataMap, ok := tableDataMap[index]
  625. if !ok {
  626. continue
  627. }
  628. // 找到对应的单元格
  629. colData, ok := rowDataMap[manualData.Tag]
  630. if !ok {
  631. continue
  632. }
  633. // 如果该单元格不是计算公式的单元格,那么直接退出当前循环即可
  634. if colData.DataType != 4 {
  635. continue
  636. }
  637. tagMap := make(map[string]float64)
  638. lenRelation := len(colData.RelationEdbInfoList)
  639. replaceNum := 0
  640. for _, relation := range colData.RelationEdbInfoList {
  641. relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
  642. valStr, tmpErr := getCalculateValue(tableDataMap, relation.Tag, relation.Row, calculateCellMap)
  643. if tmpErr != nil {
  644. continue
  645. }
  646. tmpValDecimal, tmpErr := decimal.NewFromString(valStr)
  647. if tmpErr != nil {
  648. continue
  649. }
  650. tagMap[relationCellTagName], _ = tmpValDecimal.Float64()
  651. replaceNum++
  652. }
  653. // 如果替换的数据与关联的不一致,那么就退出当前循环
  654. if lenRelation != replaceNum {
  655. continue
  656. }
  657. // 计算
  658. val, _, err := calculate(strings.ToUpper(colData.Value), tagMap)
  659. // 计算失败,退出循环
  660. if err != nil {
  661. continue
  662. }
  663. // 重新赋值
  664. colData.ShowValue = val
  665. tableDataMap[index][manualData.Tag] = colData
  666. }
  667. // 计算文本行的单元格
  668. for k, textRow := range tmpTextRowList {
  669. // 获取对应行的数据
  670. index := lenTableData + k + 1
  671. rowDataMap, ok := tableDataMap[index]
  672. if !ok {
  673. continue
  674. }
  675. for colIndex, _ := range textRow {
  676. currTag := tagList[colIndex]
  677. // 找到对应的单元格
  678. colData, ok := rowDataMap[currTag]
  679. if !ok {
  680. continue
  681. }
  682. // 如果该单元格不是计算公式的单元格,那么直接退出当前循环即可
  683. if colData.DataType != 4 {
  684. continue
  685. }
  686. tagMap := make(map[string]float64)
  687. lenRelation := len(colData.RelationEdbInfoList)
  688. replaceNum := 0
  689. for _, relation := range colData.RelationEdbInfoList {
  690. relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
  691. valStr, tmpErr := getCalculateValue(tableDataMap, relation.Tag, relation.Row, calculateCellMap)
  692. if tmpErr != nil {
  693. continue
  694. }
  695. tmpValDecimal, tmpErr := decimal.NewFromString(valStr)
  696. if tmpErr != nil {
  697. continue
  698. }
  699. tagMap[relationCellTagName], _ = tmpValDecimal.Float64()
  700. replaceNum++
  701. }
  702. // 如果替换的数据与关联的不一致,那么就退出当前循环
  703. if lenRelation != replaceNum {
  704. continue
  705. }
  706. // 计算
  707. val, _, err := calculate(strings.ToUpper(colData.Value), tagMap)
  708. // 计算失败,退出循环
  709. if err != nil {
  710. continue
  711. }
  712. // 重新赋值
  713. colData.ShowValue = val
  714. tableDataMap[index][currTag] = colData
  715. }
  716. }
  717. // 计算文本行第一列的数据值(多行)
  718. for k, colData := range firstColTextRowList {
  719. // 如果该单元格不是计算公式的单元格,那么直接退出当前循环即可
  720. if colData.DataType != 4 {
  721. continue
  722. }
  723. tagMap := make(map[string]float64)
  724. lenRelation := len(colData.RelationEdbInfoList)
  725. replaceNum := 0
  726. for _, relation := range colData.RelationEdbInfoList {
  727. relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
  728. valStr, tmpErr := getCalculateValue(tableDataMap, relation.Tag, relation.Row, calculateCellMap)
  729. if tmpErr != nil {
  730. continue
  731. }
  732. tmpValDecimal, tmpErr := decimal.NewFromString(valStr)
  733. if tmpErr != nil {
  734. continue
  735. }
  736. tagMap[relationCellTagName], _ = tmpValDecimal.Float64()
  737. replaceNum++
  738. }
  739. // 如果替换的数据与关联的不一致,那么就退出当前循环
  740. if lenRelation != replaceNum {
  741. continue
  742. }
  743. // 计算
  744. val, _, err := calculate(strings.ToUpper(colData.Value), tagMap)
  745. // 计算失败,退出循环
  746. if err != nil {
  747. continue
  748. }
  749. // 重新赋值
  750. colData.ShowValue = val
  751. firstColTextRowList[k] = colData
  752. }
  753. {
  754. // 文本行的数据处理返回
  755. textRowListDataResp = make([][]request.ManualDataReq, 0)
  756. newLenTableDataMap := len(tableDataMap)
  757. // 文本行的第一行所在的位置
  758. firstTextRow := lenTableData + 1
  759. for i := firstTextRow; i <= newLenTableDataMap; i++ {
  760. textRowDataResp := make([]request.ManualDataReq, 0)
  761. textRowDataResp = append(textRowDataResp, firstColTextRowList[i-firstTextRow])
  762. for _, tmpTag := range tagList {
  763. textRowDataResp = append(textRowDataResp, tableDataMap[i][tmpTag])
  764. }
  765. textRowListDataResp = append(textRowListDataResp, textRowDataResp)
  766. }
  767. }
  768. return
  769. }
  770. // getCalculateValue 获取公式计算的结果
  771. func getCalculateValue(tableDataMap map[int]map[string]request.ManualDataReq, tag, row string, calculateCellMap map[string]string) (val string, err error) {
  772. rowInt, err := strconv.Atoi(row)
  773. if err != nil {
  774. return
  775. }
  776. // 单元格的标签名
  777. cellTagName := strings.ToUpper(tag) + row
  778. val, ok := calculateCellMap[cellTagName]
  779. if ok {
  780. return
  781. }
  782. // 查找行数据
  783. rowData, ok := tableDataMap[rowInt]
  784. if !ok {
  785. err = errors.New("查找" + row + "行的数据失败")
  786. return
  787. }
  788. // 查找单元格数据
  789. colData, ok := rowData[tag]
  790. if !ok {
  791. err = errors.New("查找单元格" + tag + row + "的数据失败")
  792. return
  793. }
  794. // 如果不是计算单元格
  795. if colData.DataType != 4 {
  796. val = colData.ShowValue
  797. return
  798. }
  799. // 如果是计算单元格
  800. calculateCellMap[cellTagName] = ``
  801. tagMap := make(map[string]float64)
  802. for _, relation := range colData.RelationEdbInfoList {
  803. relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
  804. valStr, tmpErr := getCalculateValue(tableDataMap, relation.Tag, relation.Row, calculateCellMap)
  805. if tmpErr != nil {
  806. err = tmpErr
  807. return
  808. }
  809. tmpValDecimal, tmpErr := decimal.NewFromString(valStr)
  810. if tmpErr != nil {
  811. err = tmpErr
  812. return
  813. }
  814. tagMap[relationCellTagName], _ = tmpValDecimal.Float64()
  815. }
  816. // 计算
  817. val, _, err = calculate(strings.ToUpper(colData.Value), tagMap)
  818. if err != nil {
  819. return
  820. }
  821. // 重新赋值
  822. colData.ShowValue = val
  823. tableDataMap[rowInt][tag] = colData
  824. calculateCellMap[cellTagName] = val
  825. return
  826. }
  827. // calculate 公式计算
  828. func calculate(calculateFormula string, TagMap map[string]float64) (calVal, errMsg string, err error) {
  829. if calculateFormula == "" {
  830. errMsg = "公式异常"
  831. err = errors.New(errMsg)
  832. return
  833. }
  834. calculateFormula = strings.TrimPrefix(calculateFormula, "=")
  835. calculateFormula = strings.Replace(calculateFormula, "(", "(", -1)
  836. calculateFormula = strings.Replace(calculateFormula, ")", ")", -1)
  837. calculateFormula = strings.Replace(calculateFormula, ",", ",", -1)
  838. calculateFormula = strings.Replace(calculateFormula, "。", ".", -1)
  839. calculateFormula = strings.Replace(calculateFormula, "%", "*0.01", -1)
  840. formulaFormStr := utils.ReplaceFormula(TagMap, calculateFormula)
  841. //计算公式异常,那么就移除该指标
  842. if formulaFormStr == `` {
  843. errMsg = "公式异常"
  844. err = errors.New(errMsg)
  845. return
  846. }
  847. expression := formula.NewExpression(formulaFormStr)
  848. calResult, err := expression.Evaluate()
  849. if err != nil {
  850. errMsg = "计算失败"
  851. err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
  852. // 分母为0的报错
  853. if strings.Contains(err.Error(), "divide by zero") {
  854. errMsg = "分母不能为0"
  855. err = errors.New("分母不能为空,计算公式:" + formulaFormStr)
  856. }
  857. return
  858. }
  859. // 如果计算结果是NAN,那么就提示报错
  860. if calResult.IsNan() {
  861. errMsg = "计算失败"
  862. err = errors.New("计算失败:计算结果是:NAN;formulaStr:" + formulaFormStr)
  863. return
  864. }
  865. calVal = calResult.String()
  866. // 转Decimal然后四舍五入
  867. valDecimal, err := decimal.NewFromString(calVal)
  868. if err != nil {
  869. errMsg = "计算失败"
  870. err = errors.New("计算失败,结果转 Decimal 失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
  871. return
  872. }
  873. calVal = valDecimal.Round(4).String()
  874. return
  875. }