excel_info.go 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426
  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"
  7. "eta/eta_api/models/data_manage/excel/request"
  8. "eta/eta_api/models/data_manage/excel/response"
  9. "eta/eta_api/models/system"
  10. "eta/eta_api/services/data"
  11. "eta/eta_api/services/data/data_manage_permission"
  12. "eta/eta_api/utils"
  13. "fmt"
  14. "github.com/shopspring/decimal"
  15. "github.com/yidane/formula"
  16. "sort"
  17. "strconv"
  18. "strings"
  19. "time"
  20. )
  21. // GetExcelDetailInfoByExcelInfoId 根据表格id获取表格详情
  22. func GetExcelDetailInfoByExcelInfoId(excelInfoId, sysUserId int) (excelDetail response.ExcelInfoDetail, errMsg string, err error) {
  23. errMsg = `获取失败`
  24. //获取eta表格信息
  25. excelInfo, err := excel.GetExcelInfoById(excelInfoId)
  26. if err != nil {
  27. err = errors.New("获取ETA表格信息失败,Err:" + err.Error())
  28. if err.Error() == utils.ErrNoRow() {
  29. errMsg = "ETA表格被删除,请刷新页面"
  30. err = errors.New("ETA表格被删除,请刷新页面,Err:" + err.Error())
  31. }
  32. return
  33. }
  34. return formatExcelInfo2Detail(excelInfo, sysUserId)
  35. }
  36. // GetExcelDetailInfoByUnicode 根据表格编码获取表格详情
  37. func GetExcelDetailInfoByUnicode(unicode string, sysUserId int) (excelDetail response.ExcelInfoDetail, errMsg string, err error) {
  38. errMsg = `获取失败`
  39. // 获取eta表格信息
  40. excelInfo, err := excel.GetExcelInfoByUnicode(unicode)
  41. if err != nil {
  42. err = errors.New("获取ETA表格信息失败,Err:" + err.Error())
  43. if err.Error() == utils.ErrNoRow() {
  44. errMsg = "ETA表格被删除,请刷新页面"
  45. err = errors.New("ETA表格被删除,请刷新页面,Err:" + err.Error())
  46. }
  47. return
  48. }
  49. return formatExcelInfo2Detail(excelInfo, sysUserId)
  50. }
  51. func formatExcelInfo2Detail(excelInfo *excel.ExcelInfo, sysUserId int) (excelDetail response.ExcelInfoDetail, errMsg string, err error) {
  52. // 数据权限
  53. // 判断是否是子表,如果是子表,则从父级分类中查询权限信息
  54. if excelInfo.ParentId > 0 {
  55. parentExcelInfo, e := excel.GetExcelInfoById(excelInfo.ParentId)
  56. if e != nil {
  57. err = errors.New("获取父级ETA表格信息失败,Err:" + err.Error())
  58. if err.Error() == utils.ErrNoRow() {
  59. errMsg = "父级ETA表格被删除,请刷新页面"
  60. err = errors.New("父级ETA表格被删除,请刷新页面,Err:" + err.Error())
  61. }
  62. return
  63. }
  64. excelInfo.ExcelClassifyId = parentExcelInfo.ExcelClassifyId
  65. }
  66. haveOperaAuth, err := data_manage_permission.CheckExcelPermissionByExcelInfoId(excelInfo.ExcelInfoId, excelInfo.ExcelClassifyId, excelInfo.IsJoinPermission, sysUserId)
  67. if err != nil {
  68. err = errors.New("获取表格权限信息失败,Err" + err.Error())
  69. return
  70. }
  71. excelDetail = response.ExcelInfoDetail{
  72. ExcelInfoId: excelInfo.ExcelInfoId,
  73. Source: excelInfo.Source,
  74. ExcelType: excelInfo.ExcelType,
  75. ExcelName: excelInfo.ExcelName,
  76. UniqueCode: excelInfo.UniqueCode,
  77. ExcelClassifyId: excelInfo.ExcelClassifyId,
  78. SysUserId: excelInfo.SysUserId,
  79. SysUserRealName: excelInfo.SysUserRealName,
  80. Content: excelInfo.Content,
  81. ExcelImage: excelInfo.ExcelImage,
  82. FileUrl: excelInfo.FileUrl,
  83. Sort: excelInfo.Sort,
  84. IsDelete: excelInfo.IsDelete,
  85. ModifyTime: excelInfo.ModifyTime,
  86. CreateTime: excelInfo.CreateTime,
  87. TableData: nil,
  88. HaveOperaAuth: haveOperaAuth,
  89. ParentId: excelInfo.ParentId,
  90. BalanceType: excelInfo.BalanceType,
  91. UpdateUserId: excelInfo.UpdateUserId,
  92. UpdateUserRealName: excelInfo.UpdateUserRealName,
  93. }
  94. // 无权限,不需要返回数据
  95. if !haveOperaAuth {
  96. return
  97. }
  98. switch excelInfo.Source {
  99. case utils.TIME_TABLE: // 时间序列表格
  100. var tableDataConfig TableDataConfig
  101. err = json.Unmarshal([]byte(excelDetail.Content), &tableDataConfig)
  102. if err != nil {
  103. err = errors.New("表格json转结构体失败,Err:" + err.Error())
  104. return
  105. }
  106. result, tmpErr := GetDataByTableDataConfig(tableDataConfig)
  107. if tmpErr != nil {
  108. err = errors.New("获取最新的表格数据失败,Err:" + tmpErr.Error())
  109. return
  110. }
  111. if len(result.EdbInfoIdList) > 0 {
  112. classifyIdList := make([]int, 0)
  113. for _, v := range result.Data {
  114. classifyIdList = append(classifyIdList, v.ClassifyId)
  115. }
  116. classifyMap := make(map[int]*data_manage.EdbClassify)
  117. classifyList, tmpErr := data_manage.GetEdbClassifyByIdList(classifyIdList)
  118. if tmpErr != nil {
  119. err = errors.New("获取分类列表失败,Err:" + tmpErr.Error())
  120. return
  121. }
  122. for _, v := range classifyList {
  123. classifyMap[v.ClassifyId] = v
  124. }
  125. // 获取所有有权限的指标和分类
  126. permissionEdbIdList, permissionClassifyIdList, tmpErr := data_manage_permission.GetUserEdbAndClassifyPermissionList(sysUserId, 0, 0)
  127. if err != nil {
  128. err = errors.New("获取所有有权限的指标和分类失败,Err:" + tmpErr.Error())
  129. return
  130. }
  131. for i, v := range result.Data {
  132. if currClassify, ok := classifyMap[v.ClassifyId]; ok {
  133. result.Data[i].HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, currClassify.IsJoinPermission, v.EdbInfoId, v.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
  134. }
  135. }
  136. }
  137. excelDetail.TableData = result
  138. case utils.MIXED_TABLE, utils.BALANCE_TABLE: // 混合表格 平衡表
  139. var result request.MixedTableReq
  140. err = json.Unmarshal([]byte(excelDetail.Content), &result)
  141. if err != nil {
  142. err = errors.New("表格json转结构体失败,Err:" + err.Error())
  143. return
  144. }
  145. newData, tmpErr, tmpErrMsg := GetMixedTableCellData(result)
  146. if tmpErr != nil {
  147. errMsg = "获取失败"
  148. if tmpErrMsg != `` {
  149. errMsg = tmpErrMsg
  150. }
  151. err = errors.New("获取最新的数据失败,Err:" + tmpErr.Error())
  152. return
  153. }
  154. result.Data = newData
  155. excelDetail.TableData = result
  156. }
  157. return
  158. }
  159. // GetExcelInfoOpButton 获取ETA表格的操作权限
  160. func GetExcelInfoOpButton(sysUser *system.Admin, belongUserId, source int, haveOperaAuth bool) (button response.ExcelInfoDetailButton) {
  161. // 如果没有数据权限,那么直接返回
  162. if !haveOperaAuth {
  163. return
  164. }
  165. //非管理员角色查看其他用户创建的表格,可刷新、另存为、下载表格;
  166. button.RefreshButton = true
  167. button.CopyButton = true
  168. button.DownloadButton = true
  169. // 1、本用户创建的表格,可编辑、刷新、另存为、下载、删除,删除需二次确认;
  170. // 2、管理员角色对所有表格有如上权限;
  171. // 3、在线excel所有人都能编辑
  172. if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN || sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN || sysUser.AdminId == belongUserId || source == utils.EXCEL_DEFAULT {
  173. button.OpButton = true
  174. button.DeleteButton = true
  175. }
  176. // 自定义分析
  177. if source == utils.CUSTOM_ANALYSIS_TABLE {
  178. if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN || sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN || sysUser.AdminId == belongUserId {
  179. button.OpEdbButton = true // 生成、查看指标按钮
  180. button.RefreshEdbButton = true // 刷新指标按钮
  181. }
  182. }
  183. //todo 如果是平衡表,判断是否是协作人
  184. return
  185. }
  186. // GetFirstEdbDataList 获取第一列的数据
  187. func GetFirstEdbDataList(edbInfo *data_manage.EdbInfo, num int, manualDateList []string) (resultDataList []request.ManualDataReq, err error) {
  188. var dataList []*data_manage.EdbDataList
  189. switch edbInfo.EdbInfoType {
  190. case 0:
  191. dataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
  192. case 1:
  193. _, dataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
  194. default:
  195. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  196. }
  197. if err != nil {
  198. return
  199. }
  200. // 获取需要的期数
  201. lenData := len(dataList)
  202. if lenData <= 0 {
  203. return
  204. }
  205. tmpManualDateNum := 0 // 手工数据的期数
  206. lenManualDate := len(manualDateList)
  207. if lenManualDate > 0 {
  208. sortDateList := manualDateList
  209. baseDateList := utils.StrArr{}
  210. baseDateList = append(baseDateList, sortDateList...)
  211. sort.Sort(baseDateList)
  212. sortDateList = append([]string{}, baseDateList...)
  213. lastData := dataList[lenData-1]
  214. lastDataDate, tmpErr := time.ParseInLocation(utils.FormatDate, lastData.DataTime, time.Local)
  215. if tmpErr != nil {
  216. err = tmpErr
  217. return
  218. }
  219. // 遍历倒序后的日期,然后匹配在实际数据之后日期的个数
  220. for _, tmpDateStr := range sortDateList {
  221. tmpDate, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDateStr, time.Local)
  222. if tmpErr != nil {
  223. err = tmpErr
  224. return
  225. }
  226. if tmpDate.After(lastDataDate) {
  227. tmpManualDateNum++
  228. continue
  229. }
  230. break
  231. }
  232. }
  233. // 需要的期数减去手工数据的期数,这才是A列指标需要的数据
  234. num = num - tmpManualDateNum
  235. if num > lenData {
  236. num = lenData
  237. }
  238. latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
  239. for i := 1; i <= num; i++ {
  240. dataTime, _ := time.ParseInLocation(utils.FormatDate, dataList[lenData-i].DataTime, time.Local)
  241. dataType := 1
  242. // 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
  243. if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
  244. dataType = 5
  245. }
  246. resultDataList = append(resultDataList, request.ManualDataReq{
  247. DataType: dataType,
  248. DataTime: dataList[lenData-i].DataTime,
  249. ShowValue: fmt.Sprint(dataList[lenData-i].Value),
  250. Value: fmt.Sprint(dataList[lenData-i].Value),
  251. DataTimeType: 1,
  252. })
  253. }
  254. return
  255. }
  256. // GetOtherEdbDataList 获取其他列的数据
  257. func GetOtherEdbDataList(edbInfo *data_manage.EdbInfo, dateList []string) (resultDataList []request.ManualDataReq, err error) {
  258. lenDate := len(dateList)
  259. if lenDate <= 0 {
  260. return
  261. }
  262. sortDateList := dateList
  263. baseDateList := utils.StrArr{}
  264. baseDateList = append(baseDateList, sortDateList...)
  265. sort.Sort(baseDateList)
  266. sortDateList = append([]string{}, baseDateList...)
  267. endDateTime, err := time.ParseInLocation(utils.FormatDate, sortDateList[0], time.Local)
  268. if err != nil {
  269. return
  270. }
  271. firstDateTime, err := time.ParseInLocation(utils.FormatDate, sortDateList[lenDate-1], time.Local)
  272. if err != nil {
  273. return
  274. }
  275. var dataList []*data_manage.EdbDataList
  276. switch edbInfo.EdbInfoType {
  277. case 0:
  278. dataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
  279. case 1:
  280. _, dataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
  281. default:
  282. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  283. }
  284. if err != nil {
  285. return
  286. }
  287. // 获取日期内的数据(包含开始日期前一个日期,以及 结束日期后一个日期,目的为了做空日期时的 插值法兼容)
  288. baseDataList := make([]*data_manage.EdbDataList, 0)
  289. var lastData *data_manage.EdbDataList
  290. var isInsert bool
  291. for _, data := range dataList {
  292. tmpDate := data.DataTime
  293. tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
  294. if tmpErr != nil {
  295. err = tmpErr
  296. return
  297. }
  298. if tmpDateTime.Before(firstDateTime) {
  299. lastData = data
  300. continue
  301. }
  302. // 如果是第一次写入数据
  303. if !isInsert && lastData != nil {
  304. baseDataList = append(baseDataList, lastData)
  305. }
  306. if tmpDateTime.After(endDateTime) {
  307. baseDataList = append(baseDataList, data)
  308. break
  309. }
  310. baseDataList = append(baseDataList, data)
  311. isInsert = true
  312. }
  313. // 实际数据的日期map
  314. realValMap := make(map[string]string)
  315. for _, v := range baseDataList {
  316. realValMap[v.DataTime] = v.DataTime
  317. }
  318. // 插值法处理
  319. handleDataMap := make(map[string]float64)
  320. err = data.HandleDataByLinearRegression(baseDataList, handleDataMap)
  321. if err != nil {
  322. return
  323. }
  324. latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
  325. // 对于不存在的数据做补充
  326. for _, date := range sortDateList {
  327. dataType := 1
  328. if _, ok := realValMap[date]; !ok {
  329. dataType = 2
  330. } else {
  331. dataTime, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
  332. // 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
  333. if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
  334. dataType = 5
  335. }
  336. }
  337. var value, showValue string
  338. if tmpVal, ok := handleDataMap[date]; ok {
  339. value = fmt.Sprint(tmpVal)
  340. showValue = value
  341. } else {
  342. dataType = 3
  343. }
  344. resultDataList = append(resultDataList, request.ManualDataReq{
  345. DataType: dataType,
  346. DataTime: date,
  347. ShowValue: showValue,
  348. Value: value,
  349. })
  350. }
  351. return
  352. }
  353. // GetFirstHistoryEdbDataList 获取指标的历史的数据
  354. func GetFirstHistoryEdbDataList(edbInfo *data_manage.EdbInfo, num int, endDate string) (resultDataList []request.ManualDataReq, err error) {
  355. endDateTime, err := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  356. if err != nil {
  357. return
  358. }
  359. var dataList []*data_manage.EdbDataList
  360. switch edbInfo.EdbInfoType {
  361. case 0:
  362. dataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, endDate)
  363. case 1:
  364. _, dataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, endDate, true)
  365. default:
  366. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  367. }
  368. if err != nil {
  369. return
  370. }
  371. // 获取需要的期数
  372. lenData := len(dataList)
  373. if lenData <= 0 {
  374. return
  375. }
  376. lastData := dataList[lenData-1]
  377. lastDataDateTime, err := time.ParseInLocation(utils.FormatDate, lastData.DataTime, time.Local)
  378. if err != nil {
  379. return
  380. }
  381. if endDateTime.Equal(lastDataDateTime) || lastDataDateTime.After(endDateTime) {
  382. dataList = dataList[:lenData-1]
  383. lenData = len(dataList)
  384. }
  385. if num > lenData {
  386. num = lenData
  387. }
  388. latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
  389. for i := 1; i <= num; i++ {
  390. dataTime, _ := time.ParseInLocation(utils.FormatDate, dataList[lenData-i].DataTime, time.Local)
  391. dataType := 1
  392. // 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
  393. if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
  394. dataType = 5
  395. }
  396. resultDataList = append(resultDataList, request.ManualDataReq{
  397. DataType: dataType,
  398. DataTime: dataList[lenData-i].DataTime,
  399. ShowValue: fmt.Sprint(dataList[lenData-i].Value),
  400. Value: fmt.Sprint(dataList[lenData-i].Value),
  401. })
  402. }
  403. return
  404. }
  405. type TableDataConfig struct {
  406. EdbInfoIdList []int `description:"指标id列表,从左至右,从上到下的顺序"`
  407. Sort int `description:"日期排序,0:倒序,1:正序"`
  408. Data []ManualData `description:"数据列表"`
  409. Num int `description:"实际数据需要列出来的期数"`
  410. RemoveDate []string `description:"不展示的日期"`
  411. ManualDate []string `description:"手动配置的日期(未来的日期)"`
  412. TableEdbInfoList []TableEdbInfo `description:"表格内指标信息"`
  413. TextRowData [][]request.ManualDataReq `description:"文本列表"`
  414. }
  415. type TableEdbInfo struct {
  416. EdbInfoId int `description:"指标ID"`
  417. Tag string `description:"标签"`
  418. EdbName string `description:"指标名称"`
  419. EdbAliasName string `description:"指标别名"`
  420. Frequency string `description:"频度"`
  421. Unit string `description:"单位"`
  422. }
  423. type ManualData struct {
  424. DataType int `description:"数据类型,1:普通的,2:插值法,3:手动输入,4:公式计算"`
  425. DataTime string `description:"所属日期"`
  426. DataTimeType int `description:"日期类型,1:实际日期;2:未来日期"`
  427. ShowValue string `description:"展示值"`
  428. Value string `description:"实际值(计算公式)"`
  429. EdbInfoId int `description:"指标id"`
  430. Tag string `description:"下标"`
  431. RelationEdbInfoList []request.RelationEdbInfo `description:"关联指标(计算公式中关联的指标,用于计算的时候去匹配)"`
  432. }
  433. // GetTableDataConfig 根据TableDataReq配置获取相关数据配置
  434. func GetTableDataConfig(reqData request.TableDataReq) (tableDataConfig TableDataConfig, err error) {
  435. // 指标数据
  436. tableDataConfig.EdbInfoIdList = reqData.EdbInfoIdList
  437. tableDataConfig.Sort = reqData.Sort
  438. if len(reqData.Data) <= 0 {
  439. err = errors.New("数据不能为空")
  440. return
  441. }
  442. // 开始日期
  443. var startDate string
  444. // A列的指标id
  445. var firstEdbInfoId int
  446. // 手工操作的数据列
  447. manualDataList := make([]ManualData, 0)
  448. // 指标配置列表
  449. tableEdbInfoList := make([]TableEdbInfo, 0)
  450. // 第一列的日期map
  451. firstDateMap := make(map[string]string)
  452. manualDateMap := make(map[string]string)
  453. for _, v := range reqData.Data {
  454. // 指标信息
  455. tmpTableEdbInfo := TableEdbInfo{
  456. EdbInfoId: v.EdbInfoId,
  457. Tag: v.Tag,
  458. EdbName: v.EdbName,
  459. EdbAliasName: v.EdbAliasName,
  460. Frequency: v.Frequency,
  461. Unit: v.Unit,
  462. }
  463. tableEdbInfoList = append(tableEdbInfoList, tmpTableEdbInfo)
  464. // 确定数据A列
  465. if v.Tag == "A" {
  466. firstEdbInfoId = v.EdbInfoId
  467. lenData := len(v.Data)
  468. if lenData <= 0 {
  469. err = errors.New("A列不能为空")
  470. return
  471. }
  472. index := 0
  473. if reqData.Sort == 1 {
  474. // 倒序
  475. index = lenData - 1
  476. }
  477. startDate = v.Data[index].DataTime
  478. // 存在的日期列表
  479. for _, data := range v.Data {
  480. firstDateMap[data.DataTime] = data.DataTime
  481. if data.DataTimeType == 2 {
  482. manualDateMap[data.DataTime] = data.DataTime
  483. }
  484. }
  485. }
  486. for _, data := range v.Data {
  487. if data.DataType == 3 || data.DataType == 4 {
  488. tmpManualData := ManualData{
  489. DataType: data.DataType,
  490. DataTime: data.DataTime,
  491. DataTimeType: data.DataTimeType,
  492. ShowValue: data.ShowValue,
  493. Value: data.Value,
  494. EdbInfoId: v.EdbInfoId,
  495. Tag: v.Tag,
  496. RelationEdbInfoList: data.RelationEdbInfoList,
  497. }
  498. if data.DataType == 4 {
  499. tmpManualData.ShowValue = ``
  500. }
  501. manualDataList = append(manualDataList, tmpManualData)
  502. }
  503. }
  504. }
  505. // 总共需要的期数
  506. num := len(reqData.Data[0].Data)
  507. removeDate := make([]string, 0)
  508. // 获取期数
  509. {
  510. firstDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  511. if tmpErr != nil {
  512. err = tmpErr
  513. return
  514. }
  515. edbInfo, tmpErr := data_manage.GetEdbInfoById(firstEdbInfoId)
  516. if tmpErr != nil {
  517. err = tmpErr
  518. return
  519. }
  520. var firstDataList []*data_manage.EdbDataList
  521. switch edbInfo.EdbInfoType {
  522. case 0:
  523. firstDataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
  524. case 1:
  525. _, firstDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
  526. default:
  527. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  528. }
  529. if err != nil {
  530. return
  531. }
  532. // 获取日期内的数据(包含开始日期前一个日期,以及 结束日期后一个日期,目的为了做空日期时的 插值法兼容)
  533. baseDataList := make([]*data_manage.EdbDataList, 0)
  534. for _, data := range firstDataList {
  535. tmpDate := data.DataTime
  536. tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
  537. if tmpErr != nil {
  538. err = tmpErr
  539. return
  540. }
  541. if tmpDateTime.Before(firstDateTime) {
  542. continue
  543. }
  544. baseDataList = append(baseDataList, data)
  545. }
  546. // 筛选出需要删除的日期
  547. for _, tmpData := range baseDataList {
  548. //firstDateMap{}
  549. if _, ok := firstDateMap[tmpData.DataTime]; !ok {
  550. removeDate = append(removeDate, tmpData.DataTime)
  551. }
  552. }
  553. }
  554. tableDataConfig.Num = num
  555. tableDataConfig.RemoveDate = removeDate
  556. tableDataConfig.Data = manualDataList
  557. tableDataConfig.TableEdbInfoList = tableEdbInfoList
  558. tableDataConfig.TextRowData = reqData.TextRowData
  559. return
  560. }
  561. // GetDataByTableDataConfig 根据数据配置获取表格数据
  562. func GetDataByTableDataConfig(tableDataConfig TableDataConfig) (resultResp request.TableDataReq, err error) {
  563. // 没有选择指标的情况下,直接返回吧
  564. if len(tableDataConfig.EdbInfoIdList) <= 0 {
  565. return
  566. }
  567. // 实际期数没有的情况下,直接返回吧
  568. if tableDataConfig.Num <= 0 {
  569. return
  570. }
  571. // 获取所有的指标信息
  572. edbInfoMap := make(map[int]*data_manage.EdbInfo)
  573. edbInfoIdList := make([]int, 0)
  574. // 标签与指标id的map
  575. tagEdbInfoIdMap := make(map[string]int)
  576. {
  577. for _, tableEdbInfo := range tableDataConfig.TableEdbInfoList {
  578. edbInfoIdList = append(edbInfoIdList, tableEdbInfo.EdbInfoId)
  579. tagEdbInfoIdMap[tableEdbInfo.Tag] = tableEdbInfo.EdbInfoId
  580. }
  581. edbInfoList, tmpErr := data_manage.GetEdbInfoByIdList(edbInfoIdList)
  582. if tmpErr != nil {
  583. err = tmpErr
  584. return
  585. }
  586. for _, v := range edbInfoList {
  587. edbInfoMap[v.EdbInfoId] = v
  588. }
  589. }
  590. manualDateMap := make(map[string]string, 0)
  591. manualDateList := make([]string, 0)
  592. for _, v := range tableDataConfig.Data {
  593. if _, ok := manualDateMap[v.DataTime]; !ok {
  594. manualDateMap[v.DataTime] = v.DataTime
  595. manualDateList = append(manualDateList, v.DataTime)
  596. }
  597. }
  598. // 寻找A列的数据列表
  599. firstEdbInfo, ok := edbInfoMap[tableDataConfig.TableEdbInfoList[0].EdbInfoId]
  600. if !ok {
  601. err = errors.New("找不到A列指标")
  602. return
  603. }
  604. baseFirstEdbInfoDataList, err := GetFirstEdbDataList(firstEdbInfo, tableDataConfig.Num, manualDateList)
  605. if err != nil {
  606. return
  607. }
  608. // A列找不到数据,那么就直接返回吧
  609. if len(baseFirstEdbInfoDataList) <= 0 {
  610. return
  611. }
  612. firstEdbInfoDataList := make([]request.ManualDataReq, 0)
  613. if tableDataConfig.RemoveDate != nil && len(tableDataConfig.RemoveDate) > 0 {
  614. for _, v := range baseFirstEdbInfoDataList {
  615. if utils.InArrayByStr(tableDataConfig.RemoveDate, v.DataTime) {
  616. continue
  617. }
  618. firstEdbInfoDataList = append(firstEdbInfoDataList, v)
  619. }
  620. } else {
  621. firstEdbInfoDataList = baseFirstEdbInfoDataList
  622. }
  623. if len(firstEdbInfoDataList) <= 0 {
  624. return
  625. }
  626. // 实际数据的最后一天
  627. lastRealDateTime, err := time.ParseInLocation(utils.FormatDate, firstEdbInfoDataList[0].DataTime, time.Local)
  628. if err != nil {
  629. return
  630. }
  631. dateMap := make(map[string]string)
  632. dateList := make([]string, 0)
  633. edbInfoIdDateDataMap := make(map[int]map[string]request.ManualDataReq)
  634. firstDateDataMap := make(map[string]request.ManualDataReq)
  635. for _, v := range firstEdbInfoDataList {
  636. dateList = append(dateList, v.DataTime)
  637. dateMap[v.DataTime] = v.DataTime
  638. firstDateDataMap[v.DataTime] = v
  639. }
  640. // 将手工数据的日期填补进去(未来的日期,过去的就不管了)
  641. for _, manualData := range tableDataConfig.Data {
  642. if !utils.InArrayByStr(dateList, manualData.DataTime) {
  643. tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, manualData.DataTime, time.Local)
  644. if tmpErr != nil {
  645. err = tmpErr
  646. return
  647. }
  648. if tmpDateTime.After(lastRealDateTime) {
  649. dateList = append(dateList, manualData.DataTime)
  650. }
  651. }
  652. }
  653. edbInfoIdDateDataMap[firstEdbInfo.EdbInfoId] = firstDateDataMap
  654. for k, edbInfoId := range tableDataConfig.EdbInfoIdList {
  655. if k == 0 {
  656. continue
  657. }
  658. tmpEdbInfo, ok := edbInfoMap[edbInfoId]
  659. if !ok {
  660. err = errors.New("找不到A列指标")
  661. return
  662. }
  663. otherDataList, tmpErr := GetOtherEdbDataList(tmpEdbInfo, dateList)
  664. if tmpErr != nil {
  665. err = tmpErr
  666. return
  667. }
  668. tmpDateDataMap := make(map[string]request.ManualDataReq)
  669. for _, v := range otherDataList {
  670. tmpDateDataMap[v.DataTime] = v
  671. }
  672. edbInfoIdDateDataMap[tmpEdbInfo.EdbInfoId] = tmpDateDataMap
  673. }
  674. for _, v := range tableDataConfig.Data {
  675. tmpDate := v.DataTime
  676. if _, ok := dateMap[tmpDate]; !ok {
  677. dateMap[v.DataTime] = tmpDate
  678. }
  679. edbInfoIdDateData, ok := edbInfoIdDateDataMap[v.EdbInfoId]
  680. if !ok {
  681. edbInfoIdDateData = make(map[string]request.ManualDataReq)
  682. }
  683. // 判断是否存在该日期的数据(不存在,那么插入数据吧,存在就不管了)
  684. tmpManualData, ok := edbInfoIdDateData[tmpDate]
  685. if !ok {
  686. edbInfoIdDateData[tmpDate] = request.ManualDataReq{
  687. DataType: v.DataType,
  688. DataTime: v.DataTime,
  689. ShowValue: v.ShowValue,
  690. Value: v.Value,
  691. }
  692. } else {
  693. if (tmpManualData.DataType == 3 || tmpManualData.DataType == 4) && tmpManualData.ShowValue == `` {
  694. tmpManualData.DataType = v.DataType
  695. tmpManualData.ShowValue = v.ShowValue
  696. tmpManualData.Value = v.Value
  697. tmpManualData.RelationEdbInfoList = v.RelationEdbInfoList
  698. edbInfoIdDateData[tmpDate] = tmpManualData
  699. }
  700. }
  701. edbInfoIdDateDataMap[v.EdbInfoId] = edbInfoIdDateData
  702. }
  703. // 获取数据的日期排序
  704. sortDateTimeList := make([]time.Time, 0)
  705. {
  706. sortDateList := dateList
  707. if tableDataConfig.Sort == 1 {
  708. baseDateList := utils.StrArr{}
  709. baseDateList = append(baseDateList, sortDateList...)
  710. sort.Sort(baseDateList)
  711. sortDateList = append([]string{}, baseDateList...)
  712. } else {
  713. sort.Strings(sortDateList)
  714. }
  715. for _, v := range sortDateList {
  716. tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, v, time.Local)
  717. if tmpErr != nil {
  718. err = tmpErr
  719. return
  720. }
  721. sortDateTimeList = append(sortDateTimeList, tmpDateTime)
  722. }
  723. }
  724. // 数据处理,处理成表格的数据格式
  725. tableDataMap, textRowListDataResp := handleTable(tagEdbInfoIdMap, lastRealDateTime, sortDateTimeList, edbInfoIdDateDataMap, tableDataConfig.Data, tableDataConfig.TextRowData)
  726. data := make([]request.EdbInfoData, 0)
  727. for _, tableEdbInfo := range tableDataConfig.TableEdbInfoList {
  728. tagEdbInfoIdMap[tableEdbInfo.Tag] = tableEdbInfo.EdbInfoId
  729. manualDataReqList := make([]request.ManualDataReq, 0)
  730. tmpEdbInfoData := request.EdbInfoData{
  731. EdbInfoId: tableEdbInfo.EdbInfoId,
  732. Tag: tableEdbInfo.Tag,
  733. EdbName: tableEdbInfo.EdbName,
  734. EdbAliasName: tableEdbInfo.EdbAliasName,
  735. Frequency: tableEdbInfo.Frequency,
  736. Unit: tableEdbInfo.Unit,
  737. Data: manualDataReqList,
  738. }
  739. edbInfo, ok := edbInfoMap[tableEdbInfo.EdbInfoId]
  740. if ok {
  741. tmpEdbInfoData.EdbName = edbInfo.EdbName
  742. tmpEdbInfoData.Frequency = edbInfo.Frequency
  743. tmpEdbInfoData.Unit = edbInfo.Unit
  744. tmpEdbInfoData.ClassifyId = edbInfo.ClassifyId
  745. tmpEdbInfoData.IsJoinPermission = edbInfo.IsJoinPermission
  746. }
  747. for index, dateTime := range sortDateTimeList {
  748. dataTimeType := 1
  749. if dateTime.After(lastRealDateTime) {
  750. dataTimeType = 2
  751. }
  752. tmpDateTimeStr := dateTime.Format(utils.FormatDate)
  753. rowData, ok := tableDataMap[index+1]
  754. if !ok {
  755. manualDataReqList = append(manualDataReqList, request.ManualDataReq{
  756. DataType: 3,
  757. DataTime: tmpDateTimeStr,
  758. DataTimeType: dataTimeType,
  759. ShowValue: "",
  760. Value: "",
  761. RelationEdbInfoList: nil,
  762. })
  763. continue
  764. }
  765. tmpData, ok := rowData[tableEdbInfo.Tag]
  766. if !ok {
  767. manualDataReqList = append(manualDataReqList, request.ManualDataReq{
  768. DataType: 3,
  769. DataTime: tmpDateTimeStr,
  770. DataTimeType: dataTimeType,
  771. ShowValue: "",
  772. Value: "",
  773. RelationEdbInfoList: nil,
  774. })
  775. continue
  776. }
  777. tmpData.DataTimeType = dataTimeType
  778. manualDataReqList = append(manualDataReqList, tmpData)
  779. }
  780. tmpEdbInfoData.Data = manualDataReqList
  781. data = append(data, tmpEdbInfoData)
  782. }
  783. // 处理一下数据格式
  784. for _, d := range data {
  785. for k2, d2 := range d.Data {
  786. // 可能有ShowValue非数值, 转换一下报错则continue
  787. vf, e := strconv.ParseFloat(d2.ShowValue, 64)
  788. if e != nil {
  789. continue
  790. }
  791. d.Data[k2].ShowValue = utils.FormatTableDataShowValue(vf)
  792. }
  793. }
  794. for _, d := range textRowListDataResp {
  795. for k2, d2 := range d {
  796. // 可能有ShowValue非数值, 转换一下报错则continue
  797. vf, e := strconv.ParseFloat(d2.ShowValue, 64)
  798. if e != nil {
  799. continue
  800. }
  801. d[k2].ShowValue = utils.FormatTableDataShowValue(vf)
  802. }
  803. }
  804. resultResp = request.TableDataReq{
  805. EdbInfoIdList: edbInfoIdList,
  806. Sort: tableDataConfig.Sort,
  807. TextRowData: textRowListDataResp,
  808. Data: data,
  809. }
  810. return
  811. }
  812. // handleTable 表格数据处理
  813. 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) {
  814. tagList := make([]string, 0)
  815. for tag, _ := range tagEdbInfoIdMap {
  816. tagList = append(tagList, tag)
  817. }
  818. sort.Strings(tagList)
  819. tableDataMap = make(map[int]map[string]request.ManualDataReq) //行、列数据
  820. // 日期与行的关系
  821. dateIndexMap := make(map[string]int)
  822. for k, dateTime := range sortDateTimeList {
  823. rowDataMap := make(map[string]request.ManualDataReq)
  824. dataTimeType := 1
  825. if dateTime.After(lastRealDateTime) {
  826. dataTimeType = 2
  827. }
  828. tmpDateTimeStr := dateTime.Format(utils.FormatDate)
  829. dateIndexMap[tmpDateTimeStr] = k + 1
  830. for _, tag := range tagList {
  831. edbInfoId, ok := tagEdbInfoIdMap[tag]
  832. if !ok { // 没有找到该指标的映射关系,那么就用空串填补
  833. rowDataMap[tag] = request.ManualDataReq{
  834. DataType: 3,
  835. DataTime: tmpDateTimeStr,
  836. DataTimeType: dataTimeType,
  837. ShowValue: "",
  838. Value: "",
  839. RelationEdbInfoList: nil,
  840. }
  841. continue
  842. }
  843. // 获取指标的数据map
  844. dateDataMap, ok := edbInfoIdDateDataMap[edbInfoId]
  845. if !ok { // 没有找到该指标的数据,那么就用空串填补
  846. rowDataMap[tag] = request.ManualDataReq{
  847. DataType: 3,
  848. DataTime: tmpDateTimeStr,
  849. DataTimeType: dataTimeType,
  850. ShowValue: "",
  851. Value: "",
  852. RelationEdbInfoList: nil,
  853. }
  854. continue
  855. }
  856. // 获取指标该日期的数据
  857. tmpData, ok := dateDataMap[tmpDateTimeStr]
  858. if !ok { // 该指标没有找到对应日期的数据,那么就用空串填补
  859. rowDataMap[tag] = request.ManualDataReq{
  860. DataType: 3,
  861. DataTime: tmpDateTimeStr,
  862. DataTimeType: dataTimeType,
  863. ShowValue: "",
  864. Value: "",
  865. RelationEdbInfoList: nil,
  866. }
  867. continue
  868. }
  869. tmpData.DataTimeType = dataTimeType
  870. rowDataMap[tag] = tmpData
  871. }
  872. tableDataMap[k+1] = rowDataMap
  873. }
  874. // 替换手工设置的数据
  875. for _, manualData := range manualDataList {
  876. // 找不到该日期,说明这日期过期了,不处理
  877. index, ok := dateIndexMap[manualData.DataTime]
  878. if !ok {
  879. continue
  880. }
  881. // 获取对应行的数据
  882. rowDataMap, ok := tableDataMap[index]
  883. if !ok {
  884. continue
  885. }
  886. // 找到对应的单元格
  887. tmpData, ok := rowDataMap[manualData.Tag]
  888. if !ok {
  889. continue
  890. }
  891. // 如果该单元格实际有数据(包含预测值),或者插值法补充了数据的话,那么就不用手动填入的数据
  892. if utils.InArrayByInt([]int{1, 2, 5}, tmpData.DataType) {
  893. continue
  894. }
  895. // 手工填写的数字
  896. if tmpData.DataType == 3 {
  897. tmpData.ShowValue = manualData.ShowValue
  898. tmpData.Value = manualData.Value
  899. tableDataMap[index][manualData.Tag] = tmpData
  900. //edbInfoIdDateDataMap[manualData.EdbInfoId][manualData.DataTime] = tmpData
  901. continue
  902. }
  903. // 公式
  904. tmpData.DataType = manualData.DataType
  905. tmpData.ShowValue = ``
  906. tmpData.Value = manualData.Value
  907. tmpData.RelationEdbInfoList = manualData.RelationEdbInfoList
  908. tableDataMap[index][manualData.Tag] = tmpData
  909. }
  910. // 文本行的列表插入
  911. lenTableData := len(tableDataMap)
  912. // 文本行第一列的数据列表(可能多行)
  913. firstColTextRowList := make([]request.ManualDataReq, 0)
  914. // 参与计算的文本行列表数据
  915. tmpTextRowList := make([][]request.ManualDataReq, 0)
  916. for k, textRowList := range textRowData {
  917. // 判断列数是否匹配,不匹配的话那么过滤
  918. if len(tagList)+1 != len(textRowList) {
  919. continue
  920. }
  921. rowDataMap := make(map[string]request.ManualDataReq)
  922. tmpTextRow := make([]request.ManualDataReq, 0)
  923. for index, textRow := range textRowList {
  924. // 移除第一列,因为第一列是日期列
  925. if index == 0 {
  926. firstColTextRowList = append(firstColTextRowList, textRow)
  927. continue
  928. }
  929. rowDataMap[tagList[index-1]] = textRow
  930. tmpTextRow = append(tmpTextRow, textRow)
  931. }
  932. tableDataMap[lenTableData+k+1] = rowDataMap
  933. tmpTextRowList = append(tmpTextRowList, tmpTextRow)
  934. }
  935. // 参与计算的单元格
  936. calculateCellMap := make(map[string]string)
  937. // 计算手工填写的单元格
  938. for _, manualData := range manualDataList {
  939. // 找不到该日期,说明这日期过期了,不处理
  940. index, ok := dateIndexMap[manualData.DataTime]
  941. if !ok {
  942. continue
  943. }
  944. // 获取对应行的数据
  945. rowDataMap, ok := tableDataMap[index]
  946. if !ok {
  947. continue
  948. }
  949. // 找到对应的单元格
  950. colData, ok := rowDataMap[manualData.Tag]
  951. if !ok {
  952. continue
  953. }
  954. // 如果该单元格不是计算公式的单元格,那么直接退出当前循环即可
  955. if colData.DataType != 4 {
  956. continue
  957. }
  958. tagMap := make(map[string]float64)
  959. lenRelation := len(colData.RelationEdbInfoList)
  960. replaceNum := 0
  961. for _, relation := range colData.RelationEdbInfoList {
  962. relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
  963. valStr, tmpErr := getCalculateValue(tableDataMap, relation.Tag, relation.Row, calculateCellMap)
  964. if tmpErr != nil {
  965. continue
  966. }
  967. tmpValDecimal, tmpErr := decimal.NewFromString(valStr)
  968. if tmpErr != nil {
  969. continue
  970. }
  971. tagMap[relationCellTagName], _ = tmpValDecimal.Float64()
  972. replaceNum++
  973. }
  974. // 如果替换的数据与关联的不一致,那么就退出当前循环
  975. if lenRelation != replaceNum {
  976. continue
  977. }
  978. // 计算
  979. val, _, err := calculate(strings.ToUpper(colData.Value), tagMap)
  980. // 计算失败,退出循环
  981. if err != nil {
  982. continue
  983. }
  984. // 重新赋值
  985. colData.ShowValue = val
  986. tableDataMap[index][manualData.Tag] = colData
  987. }
  988. // 计算文本行的单元格
  989. for k, textRow := range tmpTextRowList {
  990. // 获取对应行的数据
  991. index := lenTableData + k + 1
  992. rowDataMap, ok := tableDataMap[index]
  993. if !ok {
  994. continue
  995. }
  996. for colIndex, _ := range textRow {
  997. currTag := tagList[colIndex]
  998. // 找到对应的单元格
  999. colData, ok := rowDataMap[currTag]
  1000. if !ok {
  1001. continue
  1002. }
  1003. // 如果该单元格不是计算公式的单元格,那么直接退出当前循环即可
  1004. if colData.DataType != 4 {
  1005. continue
  1006. }
  1007. tagMap := make(map[string]float64)
  1008. lenRelation := len(colData.RelationEdbInfoList)
  1009. replaceNum := 0
  1010. for _, relation := range colData.RelationEdbInfoList {
  1011. relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
  1012. valStr, tmpErr := getCalculateValue(tableDataMap, relation.Tag, relation.Row, calculateCellMap)
  1013. if tmpErr != nil {
  1014. continue
  1015. }
  1016. tmpValDecimal, tmpErr := decimal.NewFromString(valStr)
  1017. if tmpErr != nil {
  1018. continue
  1019. }
  1020. tagMap[relationCellTagName], _ = tmpValDecimal.Float64()
  1021. replaceNum++
  1022. }
  1023. // 如果替换的数据与关联的不一致,那么就退出当前循环
  1024. if lenRelation != replaceNum {
  1025. continue
  1026. }
  1027. // 计算
  1028. val, _, err := calculate(strings.ToUpper(colData.Value), tagMap)
  1029. // 计算失败,退出循环
  1030. if err != nil {
  1031. continue
  1032. }
  1033. // 重新赋值
  1034. colData.ShowValue = val
  1035. tableDataMap[index][currTag] = colData
  1036. }
  1037. }
  1038. // 计算文本行第一列的数据值(多行)
  1039. for k, colData := range firstColTextRowList {
  1040. // 如果该单元格不是计算公式的单元格,那么直接退出当前循环即可
  1041. if colData.DataType != 4 {
  1042. continue
  1043. }
  1044. tagMap := make(map[string]float64)
  1045. lenRelation := len(colData.RelationEdbInfoList)
  1046. replaceNum := 0
  1047. for _, relation := range colData.RelationEdbInfoList {
  1048. relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
  1049. valStr, tmpErr := getCalculateValue(tableDataMap, relation.Tag, relation.Row, calculateCellMap)
  1050. if tmpErr != nil {
  1051. continue
  1052. }
  1053. tmpValDecimal, tmpErr := decimal.NewFromString(valStr)
  1054. if tmpErr != nil {
  1055. continue
  1056. }
  1057. tagMap[relationCellTagName], _ = tmpValDecimal.Float64()
  1058. replaceNum++
  1059. }
  1060. // 如果替换的数据与关联的不一致,那么就退出当前循环
  1061. if lenRelation != replaceNum {
  1062. continue
  1063. }
  1064. // 计算
  1065. val, _, err := calculate(strings.ToUpper(colData.Value), tagMap)
  1066. // 计算失败,退出循环
  1067. if err != nil {
  1068. continue
  1069. }
  1070. // 重新赋值
  1071. colData.ShowValue = val
  1072. firstColTextRowList[k] = colData
  1073. }
  1074. {
  1075. // 文本行的数据处理返回
  1076. textRowListDataResp = make([][]request.ManualDataReq, 0)
  1077. newLenTableDataMap := len(tableDataMap)
  1078. // 文本行的第一行所在的位置
  1079. firstTextRow := lenTableData + 1
  1080. for i := firstTextRow; i <= newLenTableDataMap; i++ {
  1081. textRowDataResp := make([]request.ManualDataReq, 0)
  1082. textRowDataResp = append(textRowDataResp, firstColTextRowList[i-firstTextRow])
  1083. for _, tmpTag := range tagList {
  1084. textRowDataResp = append(textRowDataResp, tableDataMap[i][tmpTag])
  1085. }
  1086. textRowListDataResp = append(textRowListDataResp, textRowDataResp)
  1087. }
  1088. }
  1089. return
  1090. }
  1091. // getCalculateValue 获取公式计算的结果
  1092. func getCalculateValue(tableDataMap map[int]map[string]request.ManualDataReq, tag, row string, calculateCellMap map[string]string) (val string, err error) {
  1093. rowInt, err := strconv.Atoi(row)
  1094. if err != nil {
  1095. return
  1096. }
  1097. // 单元格的标签名
  1098. cellTagName := strings.ToUpper(tag) + row
  1099. val, ok := calculateCellMap[cellTagName]
  1100. if ok {
  1101. return
  1102. }
  1103. // 查找行数据
  1104. rowData, ok := tableDataMap[rowInt]
  1105. if !ok {
  1106. err = errors.New("查找" + row + "行的数据失败")
  1107. return
  1108. }
  1109. // 查找单元格数据
  1110. colData, ok := rowData[tag]
  1111. if !ok {
  1112. err = errors.New("查找单元格" + tag + row + "的数据失败")
  1113. return
  1114. }
  1115. // 如果不是计算单元格
  1116. if colData.DataType != 4 {
  1117. val = colData.ShowValue
  1118. return
  1119. }
  1120. // 如果是计算单元格
  1121. calculateCellMap[cellTagName] = ``
  1122. tagMap := make(map[string]float64)
  1123. for _, relation := range colData.RelationEdbInfoList {
  1124. relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
  1125. valStr, tmpErr := getCalculateValue(tableDataMap, relation.Tag, relation.Row, calculateCellMap)
  1126. if tmpErr != nil {
  1127. err = tmpErr
  1128. return
  1129. }
  1130. tmpValDecimal, tmpErr := decimal.NewFromString(valStr)
  1131. if tmpErr != nil {
  1132. err = tmpErr
  1133. return
  1134. }
  1135. tagMap[relationCellTagName], _ = tmpValDecimal.Float64()
  1136. }
  1137. // 计算
  1138. val, _, err = calculate(strings.ToUpper(colData.Value), tagMap)
  1139. if err != nil {
  1140. return
  1141. }
  1142. // 重新赋值
  1143. colData.ShowValue = val
  1144. tableDataMap[rowInt][tag] = colData
  1145. calculateCellMap[cellTagName] = val
  1146. return
  1147. }
  1148. // calculate 公式计算
  1149. func calculate(calculateFormula string, TagMap map[string]float64) (calVal, errMsg string, err error) {
  1150. if calculateFormula == "" {
  1151. errMsg = "公式异常"
  1152. err = errors.New(errMsg)
  1153. return
  1154. }
  1155. calculateFormula = strings.TrimPrefix(calculateFormula, "=")
  1156. calculateFormula = strings.Replace(calculateFormula, "(", "(", -1)
  1157. calculateFormula = strings.Replace(calculateFormula, ")", ")", -1)
  1158. calculateFormula = strings.Replace(calculateFormula, ",", ",", -1)
  1159. calculateFormula = strings.Replace(calculateFormula, "。", ".", -1)
  1160. calculateFormula = strings.Replace(calculateFormula, "%", "*0.01", -1)
  1161. formulaFormStr := utils.ReplaceFormula(TagMap, calculateFormula)
  1162. //计算公式异常,那么就移除该指标
  1163. if formulaFormStr == `` {
  1164. errMsg = "公式异常"
  1165. err = errors.New(errMsg)
  1166. return
  1167. }
  1168. expression := formula.NewExpression(formulaFormStr)
  1169. calResult, err := expression.Evaluate()
  1170. if err != nil {
  1171. errMsg = "计算失败"
  1172. err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
  1173. // 分母为0的报错
  1174. if strings.Contains(err.Error(), "divide by zero") {
  1175. errMsg = "分母不能为0"
  1176. err = errors.New("分母不能为空,计算公式:" + formulaFormStr)
  1177. }
  1178. return
  1179. }
  1180. // 如果计算结果是NAN,那么就提示报错
  1181. if calResult.IsNan() {
  1182. errMsg = "计算失败"
  1183. err = errors.New("计算失败:计算结果是:NAN;formulaStr:" + formulaFormStr)
  1184. return
  1185. }
  1186. calVal = calResult.String()
  1187. // 转Decimal然后四舍五入
  1188. valDecimal, err := decimal.NewFromString(calVal)
  1189. if err != nil {
  1190. errMsg = "计算失败"
  1191. err = errors.New("计算失败,结果转 Decimal 失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
  1192. return
  1193. }
  1194. calVal = valDecimal.Round(4).String()
  1195. return
  1196. }
  1197. // GetEdbIdsFromExcelCodes 获取表格中的指标IDs
  1198. func GetEdbIdsFromExcelCodes(excelCodes []string, sysUserId int) (edbIds []int, err error) {
  1199. edbIds = make([]int, 0)
  1200. edbIdExist := make(map[int]bool)
  1201. for _, v := range excelCodes {
  1202. // 表格详情
  1203. detail, msg, e := GetExcelDetailInfoByUnicode(v, sysUserId)
  1204. if e != nil {
  1205. err = fmt.Errorf("GetExcelDetailInfoByExcelInfoId err: %s, errMsg: %s", e.Error(), msg)
  1206. return
  1207. }
  1208. // 自定义表格
  1209. if detail.Source == utils.TIME_TABLE {
  1210. jsonByte, e := json.Marshal(detail.TableData)
  1211. if e != nil {
  1212. err = fmt.Errorf("JSON格式化自定义表格数据失败, Err: %s", e.Error())
  1213. return
  1214. }
  1215. var tableData request.TableDataReq
  1216. if e = json.Unmarshal(jsonByte, &tableData); e != nil {
  1217. err = fmt.Errorf("解析自定义表格数据失败, Err: %s", e.Error())
  1218. return
  1219. }
  1220. for _, tv := range tableData.EdbInfoIdList {
  1221. if edbIdExist[tv] {
  1222. continue
  1223. }
  1224. edbIdExist[tv] = true
  1225. edbIds = append(edbIds, tv)
  1226. }
  1227. }
  1228. // 混合表格
  1229. if detail.Source == utils.MIXED_TABLE {
  1230. jsonByte, e := json.Marshal(detail.TableData)
  1231. if e != nil {
  1232. err = fmt.Errorf("JSON格式化混合表格数据失败, Err: %s", e.Error())
  1233. return
  1234. }
  1235. var tableData request.MixedTableReq
  1236. if e = json.Unmarshal(jsonByte, &tableData); e != nil {
  1237. err = fmt.Errorf("解析混合表格数据失败, Err: %s", e.Error())
  1238. return
  1239. }
  1240. if len(tableData.Data) > 0 {
  1241. for _, td := range tableData.Data {
  1242. for _, tv := range td {
  1243. if tv.EdbInfoId > 0 && !edbIdExist[tv.EdbInfoId] {
  1244. edbIdExist[tv.EdbInfoId] = true
  1245. edbIds = append(edbIds, tv.EdbInfoId)
  1246. }
  1247. }
  1248. }
  1249. }
  1250. }
  1251. }
  1252. return
  1253. }
  1254. // GetExcelEdbBatchRefreshKey 获取批量刷新表格指标缓存key
  1255. func GetExcelEdbBatchRefreshKey(source string, reportId, chapterId int) string {
  1256. if source == `` {
  1257. return ``
  1258. }
  1259. return fmt.Sprint("batch_refresh_excel_edb:", source, ":", reportId, ":", chapterId)
  1260. }