time_table.go 27 KB

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