excel_info.go 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  1. package excel
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_api/models"
  6. "eta/eta_api/models/data_manage"
  7. "eta/eta_api/models/data_manage/excel"
  8. "eta/eta_api/models/data_manage/excel/request"
  9. "eta/eta_api/models/data_manage/excel/response"
  10. "eta/eta_api/models/system"
  11. "eta/eta_api/services/data"
  12. "eta/eta_api/services/data/data_manage_permission"
  13. "eta/eta_api/utils"
  14. "fmt"
  15. "sort"
  16. "strings"
  17. "time"
  18. "github.com/xuri/excelize/v2"
  19. )
  20. // GetExcelDetailInfoByExcelInfoId 根据表格id获取表格详情
  21. func GetExcelDetailInfoByExcelInfoId(excelInfoId, sysUserId int, lang string) (excelDetail response.ExcelInfoDetail, errMsg string, err error) {
  22. errMsg = `获取失败`
  23. //获取eta表格信息
  24. excelInfo, err := excel.GetExcelInfoById(excelInfoId)
  25. if err != nil {
  26. err = errors.New("获取ETA表格信息失败,Err:" + err.Error())
  27. if utils.IsErrNoRow(err) {
  28. errMsg = "ETA表格被删除,请刷新页面"
  29. err = errors.New("ETA表格被删除,请刷新页面,Err:" + err.Error())
  30. }
  31. return
  32. }
  33. return formatExcelInfo2Detail(excelInfo, sysUserId, lang)
  34. }
  35. // GetExcelDetailInfoByUnicode 根据表格编码获取表格详情
  36. func GetExcelDetailInfoByUnicode(unicode string, sysUserId int, lang string) (excelDetail response.ExcelInfoDetail, errMsg string, err error) {
  37. errMsg = `获取失败`
  38. // 获取eta表格信息
  39. excelInfo, err := excel.GetExcelInfoByUnicode(unicode)
  40. if err != nil {
  41. err = errors.New("获取ETA表格信息失败,Err:" + err.Error())
  42. if utils.IsErrNoRow(err) {
  43. errMsg = "ETA表格被删除,请刷新页面"
  44. err = errors.New("ETA表格被删除,请刷新页面,Err:" + err.Error())
  45. }
  46. return
  47. }
  48. return formatExcelInfo2Detail(excelInfo, sysUserId, lang)
  49. }
  50. func formatExcelInfo2Detail(excelInfo *excel.ExcelInfo, sysUserId int, lang string) (excelDetail response.ExcelInfoDetail, errMsg string, err error) {
  51. checkExcelInfo := excelInfo
  52. if excelInfo.Source == utils.BALANCE_TABLE {
  53. checkExcelInfoId := excelInfo.ExcelInfoId
  54. if excelInfo.BalanceType == 1 {
  55. checkExcelInfoId = excelInfo.RelExcelInfoId
  56. } else {
  57. if excelInfo.ParentId > 0 {
  58. checkExcelInfoId = excelInfo.ParentId
  59. }
  60. }
  61. if checkExcelInfoId != excelInfo.ExcelInfoId {
  62. checkExcelInfo, err = excel.GetExcelInfoById(checkExcelInfoId)
  63. if err != nil {
  64. errMsg = "获取平衡表格信息失败"
  65. err = errors.New("获取平衡表格信息失败,Err:" + err.Error())
  66. return
  67. }
  68. }
  69. }
  70. // 数据权限
  71. haveOperaAuth, err := data_manage_permission.CheckExcelPermissionByExcelInfoId(checkExcelInfo.ExcelInfoId, checkExcelInfo.ExcelClassifyId, checkExcelInfo.IsJoinPermission, sysUserId)
  72. if err != nil {
  73. err = errors.New("获取表格权限信息失败,Err" + err.Error())
  74. return
  75. }
  76. excelDetail = response.ExcelInfoDetail{
  77. ExcelInfoId: excelInfo.ExcelInfoId,
  78. Source: excelInfo.Source,
  79. ExcelType: excelInfo.ExcelType,
  80. ExcelName: excelInfo.ExcelName,
  81. UniqueCode: excelInfo.UniqueCode,
  82. ExcelClassifyId: excelInfo.ExcelClassifyId,
  83. SysUserId: excelInfo.SysUserId,
  84. SysUserRealName: excelInfo.SysUserRealName,
  85. Content: excelInfo.Content,
  86. ExcelImage: excelInfo.ExcelImage,
  87. FileUrl: excelInfo.FileUrl,
  88. Sort: excelInfo.Sort,
  89. IsDelete: excelInfo.IsDelete,
  90. ModifyTime: excelInfo.ModifyTime,
  91. CreateTime: excelInfo.CreateTime,
  92. TableData: nil,
  93. HaveOperaAuth: haveOperaAuth,
  94. ParentId: excelInfo.ParentId,
  95. BalanceType: excelInfo.BalanceType,
  96. UpdateUserId: excelInfo.UpdateUserId,
  97. UpdateUserRealName: excelInfo.UpdateUserRealName,
  98. RelExcelInfoId: excelInfo.RelExcelInfoId,
  99. SourcesFrom: excelInfo.SourcesFrom,
  100. }
  101. // 额外配置(表格冻结行列等)
  102. if excelInfo.ExtraConfig != "" {
  103. if e := json.Unmarshal([]byte(excelInfo.ExtraConfig), &excelDetail.ExtraConfig); e != nil {
  104. err = fmt.Errorf("额外配置解析失败, %v", e)
  105. return
  106. }
  107. }
  108. // 无权限,不需要返回数据
  109. if !haveOperaAuth {
  110. return
  111. }
  112. switch excelInfo.Source {
  113. case utils.TIME_TABLE: // 时间序列表格
  114. var tableDataConfig TableDataConfig
  115. err = json.Unmarshal([]byte(excelDetail.Content), &tableDataConfig)
  116. if err != nil {
  117. err = errors.New("表格json转结构体失败,Err:" + err.Error())
  118. return
  119. }
  120. result, tmpErr := GetDataByTableDataConfig(tableDataConfig)
  121. if tmpErr != nil {
  122. err = errors.New("获取最新的表格数据失败,Err:" + tmpErr.Error())
  123. return
  124. }
  125. result = SetExcelByDecimalConfig(result, tableDataConfig.DecimalConfig)
  126. if len(result.EdbInfoIdList) > 0 {
  127. classifyIdList := make([]int, 0)
  128. for _, v := range result.Data {
  129. classifyIdList = append(classifyIdList, v.ClassifyId)
  130. }
  131. classifyMap := make(map[int]*data_manage.EdbClassify)
  132. classifyList, tmpErr := data_manage.GetEdbClassifyByIdList(classifyIdList)
  133. if tmpErr != nil {
  134. err = errors.New("获取分类列表失败,Err:" + tmpErr.Error())
  135. return
  136. }
  137. for _, v := range classifyList {
  138. classifyMap[v.ClassifyId] = v
  139. }
  140. // 获取所有有权限的指标和分类
  141. permissionEdbIdList, permissionClassifyIdList, tmpErr := data_manage_permission.GetUserEdbAndClassifyPermissionList(sysUserId, 0, 0)
  142. if tmpErr != nil {
  143. err = errors.New("获取所有有权限的指标和分类失败,Err:" + tmpErr.Error())
  144. return
  145. }
  146. for i, v := range result.Data {
  147. if currClassify, ok := classifyMap[v.ClassifyId]; ok {
  148. result.Data[i].HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, currClassify.IsJoinPermission, v.EdbInfoId, v.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
  149. }
  150. }
  151. }
  152. excelDetail.TableData = result
  153. case utils.MIXED_TABLE, utils.BALANCE_TABLE: // 混合表格 平衡表
  154. var result request.MixedTableReq
  155. err = json.Unmarshal([]byte(excelDetail.Content), &result)
  156. if err != nil {
  157. err = errors.New("表格json转结构体失败,Err:" + err.Error())
  158. return
  159. }
  160. newData, tmpErr, tmpErrMsg := GetMixedTableCellData(result, lang)
  161. if tmpErr != nil {
  162. errMsg = "获取失败"
  163. if tmpErrMsg != `` {
  164. errMsg = tmpErrMsg
  165. }
  166. err = errors.New("获取最新的数据失败,Err:" + tmpErr.Error())
  167. return
  168. }
  169. result.Data = newData
  170. excelDetail.TableData = result
  171. }
  172. if excelDetail.Source == utils.BALANCE_TABLE {
  173. excelDetail.Button = GetBalanceExcelInfoOpButton(sysUserId, checkExcelInfo.SysUserId, excelDetail.HaveOperaAuth, checkExcelInfo.ExcelInfoId)
  174. }
  175. return
  176. }
  177. // SetExcelByDecimalConfig 设置表格的小数位
  178. func SetExcelByDecimalConfig(tableData request.TableDataReq, config []request.DecimalConfig) request.TableDataReq {
  179. excelData := tableData.Data
  180. edbInfoIndex := make(map[int]int)
  181. dateIndex := make(map[string]int)
  182. for i, v := range excelData {
  183. edbInfoIndex[v.EdbInfoId] = i
  184. }
  185. for i, v := range excelData[0].Data {
  186. dateIndex[v.DataTime] = i
  187. }
  188. for _, conf := range config {
  189. if conf.Col > 0 {
  190. if v, ok := edbInfoIndex[conf.Col]; ok {
  191. excelData[v].Decimal = conf.Decimal
  192. for i := 0; i < len(excelData[v].Data); i++ {
  193. excelData[v].Data[i].Decimal = conf.Decimal
  194. }
  195. }
  196. }
  197. if conf.Row != "" {
  198. if v, ok := dateIndex[conf.Row]; ok {
  199. for i := 0; i < len(excelData); i++ {
  200. excelData[i].Data[v].Decimal = conf.Decimal
  201. }
  202. }
  203. }
  204. }
  205. tableData.Data = excelData
  206. tableData.DecimalConfig = config
  207. return tableData
  208. }
  209. // GetExcelInfoOpButton 获取ETA表格的操作权限
  210. func GetExcelInfoOpButton(sysUser *system.Admin, belongUserId, source int, haveOperaAuth bool) (button excel.ExcelInfoDetailButton) {
  211. // 如果没有数据权限,那么直接返回
  212. if !haveOperaAuth {
  213. return
  214. }
  215. //非管理员角色查看其他用户创建的表格,可刷新、另存为、下载表格;
  216. button.RefreshButton = true
  217. button.CopyButton = true
  218. button.DownloadButton = true
  219. // 1、本用户创建的表格,可编辑、刷新、另存为、下载、删除,删除需二次确认;
  220. // 2、管理员角色对所有表格有如上权限;
  221. // 3、在线excel所有人都能编辑
  222. if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN || sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN || sysUser.AdminId == belongUserId || source == utils.EXCEL_DEFAULT {
  223. button.OpButton = true
  224. button.DeleteButton = true
  225. }
  226. // 自定义分析
  227. if source == utils.CUSTOM_ANALYSIS_TABLE {
  228. if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN || sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN || sysUser.AdminId == belongUserId {
  229. button.OpEdbButton = true // 生成、查看指标按钮
  230. button.RefreshEdbButton = true // 刷新指标按钮
  231. }
  232. }
  233. return
  234. }
  235. // GetFirstEdbDataList 获取第一列的数据
  236. func GetFirstEdbDataList(edbInfo *data_manage.EdbInfo, num int, manualDateList []string, decimal int) (resultDataList []request.ManualDataReq, err error) {
  237. var dataList []*data_manage.EdbDataList
  238. resultDataList = make([]request.ManualDataReq, 0)
  239. switch edbInfo.EdbInfoType {
  240. case 0:
  241. dataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
  242. case 1:
  243. _, dataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
  244. default:
  245. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  246. }
  247. if err != nil {
  248. return
  249. }
  250. // 获取需要的期数
  251. lenData := len(dataList)
  252. if lenData <= 0 {
  253. return
  254. }
  255. tmpManualDateNum := 0 // 手工数据的期数
  256. lenManualDate := len(manualDateList)
  257. if lenManualDate > 0 {
  258. sortDateList := manualDateList
  259. baseDateList := utils.StrArr{}
  260. baseDateList = append(baseDateList, sortDateList...)
  261. sort.Sort(baseDateList)
  262. sortDateList = append([]string{}, baseDateList...)
  263. lastData := dataList[lenData-1]
  264. lastDataDate, tmpErr := time.ParseInLocation(utils.FormatDate, lastData.DataTime, time.Local)
  265. if tmpErr != nil {
  266. err = tmpErr
  267. return
  268. }
  269. // 遍历倒序后的日期,然后匹配在实际数据之后日期的个数
  270. for _, tmpDateStr := range sortDateList {
  271. tmpDate, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDateStr, time.Local)
  272. if tmpErr != nil {
  273. err = tmpErr
  274. return
  275. }
  276. if tmpDate.After(lastDataDate) {
  277. tmpManualDateNum++
  278. continue
  279. }
  280. break
  281. }
  282. }
  283. // 需要的期数减去手工数据的期数,这才是A列指标需要的数据
  284. num = num - tmpManualDateNum
  285. if num > lenData {
  286. num = lenData
  287. }
  288. latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
  289. for i := 1; i <= num; i++ {
  290. dataTime, _ := time.ParseInLocation(utils.FormatDate, dataList[lenData-i].DataTime, time.Local)
  291. dataType := 1
  292. // 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
  293. if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
  294. dataType = 5
  295. }
  296. resultDataList = append(resultDataList, request.ManualDataReq{
  297. DataType: dataType,
  298. DataTime: dataList[lenData-i].DataTime,
  299. ShowValue: fmt.Sprint(dataList[lenData-i].Value),
  300. Value: fmt.Sprint(dataList[lenData-i].Value),
  301. Decimal: decimal,
  302. DataTimeType: 1,
  303. })
  304. }
  305. return
  306. }
  307. // PadFirstEdbDataList 补齐第一列的数据
  308. func PadFirstEdbDataList(resultDataList []request.ManualDataReq, dateList []string, sortType string, decimal int) []request.ManualDataReq {
  309. originDataNum := len(resultDataList)
  310. requsetDateNum := len(dateList)
  311. if originDataNum >= requsetDateNum {
  312. return resultDataList
  313. }
  314. padNum := requsetDateNum - originDataNum
  315. if sortType == "asc" {
  316. for i := 0; i < padNum; i++ {
  317. resultDataList = append(resultDataList, request.ManualDataReq{
  318. DataType: 0,
  319. DataTime: dateList[originDataNum+i],
  320. Decimal: decimal,
  321. ShowValue: ``,
  322. Value: ``,
  323. DataTimeType: 1,
  324. })
  325. }
  326. } else {
  327. var tmpDateList []request.ManualDataReq
  328. for i := padNum - 1; i <= 0; i-- {
  329. tmpDateList = append(tmpDateList, request.ManualDataReq{
  330. DataType: 0,
  331. DataTime: dateList[originDataNum+i],
  332. Decimal: decimal,
  333. ShowValue: ``,
  334. Value: ``,
  335. DataTimeType: 1,
  336. })
  337. resultDataList = append(tmpDateList, resultDataList...)
  338. }
  339. }
  340. return resultDataList
  341. }
  342. // GetOtherEdbDataListFollowDate 获取其他列的数据,并设置日期的小数位数
  343. func GetOtherEdbDataListFollowDate(edbInfo *data_manage.EdbInfo, dateList []string, dateDecimal map[string]int) (resultDataList []request.ManualDataReq, err error) {
  344. lenDate := len(dateList)
  345. if lenDate <= 0 {
  346. return
  347. }
  348. sortDateList := dateList
  349. baseDateList := utils.StrArr{}
  350. baseDateList = append(baseDateList, sortDateList...)
  351. sort.Sort(baseDateList)
  352. sortDateList = append([]string{}, baseDateList...)
  353. endDateTime, err := time.ParseInLocation(utils.FormatDate, sortDateList[0], time.Local)
  354. if err != nil {
  355. return
  356. }
  357. firstDateTime, err := time.ParseInLocation(utils.FormatDate, sortDateList[lenDate-1], time.Local)
  358. if err != nil {
  359. return
  360. }
  361. var dataList []*data_manage.EdbDataList
  362. switch edbInfo.EdbInfoType {
  363. case 0:
  364. dataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
  365. case 1:
  366. _, dataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
  367. default:
  368. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  369. }
  370. if err != nil {
  371. return
  372. }
  373. // 获取日期内的数据(包含开始日期前一个日期,以及 结束日期后一个日期,目的为了做空日期时的 插值法兼容)
  374. baseDataList := make([]*data_manage.EdbDataList, 0)
  375. var lastData *data_manage.EdbDataList
  376. var isInsert bool
  377. for _, data := range dataList {
  378. tmpDate := data.DataTime
  379. tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
  380. if tmpErr != nil {
  381. err = tmpErr
  382. return
  383. }
  384. if tmpDateTime.Before(firstDateTime) {
  385. lastData = data
  386. continue
  387. }
  388. // 如果是第一次写入数据
  389. if !isInsert && lastData != nil {
  390. baseDataList = append(baseDataList, lastData)
  391. }
  392. if tmpDateTime.After(endDateTime) {
  393. baseDataList = append(baseDataList, data)
  394. break
  395. }
  396. baseDataList = append(baseDataList, data)
  397. isInsert = true
  398. }
  399. // 实际数据的日期map
  400. realValMap := make(map[string]string)
  401. for _, v := range baseDataList {
  402. realValMap[v.DataTime] = v.DataTime
  403. }
  404. // 插值法处理
  405. handleDataMap := make(map[string]float64)
  406. err = data.HandleDataByLinearRegression(baseDataList, handleDataMap)
  407. if err != nil {
  408. return
  409. }
  410. latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
  411. // 对于不存在的数据做补充
  412. for _, date := range sortDateList {
  413. dataType := 1
  414. if _, ok := realValMap[date]; !ok {
  415. dataType = 2
  416. } else {
  417. dataTime, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
  418. // 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
  419. if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
  420. dataType = 5
  421. }
  422. }
  423. var value, showValue string
  424. if tmpVal, ok := handleDataMap[date]; ok {
  425. value = fmt.Sprint(tmpVal)
  426. showValue = value
  427. } else {
  428. dataType = 3
  429. }
  430. tmpData := request.ManualDataReq{
  431. DataType: dataType,
  432. DataTime: date,
  433. ShowValue: showValue,
  434. Value: value,
  435. }
  436. if v, ok := dateDecimal[date]; ok {
  437. tmpData.Decimal = v
  438. } else {
  439. tmpData.Decimal = -1
  440. }
  441. resultDataList = append(resultDataList, tmpData)
  442. }
  443. return
  444. }
  445. // GetOtherEdbDataList 获取其他列的数据
  446. func GetOtherEdbDataList(edbInfo *data_manage.EdbInfo, dateList []string, decimal int) (resultDataList []request.ManualDataReq, err error) {
  447. lenDate := len(dateList)
  448. if lenDate <= 0 {
  449. return
  450. }
  451. sortDateList := dateList
  452. baseDateList := utils.StrArr{}
  453. baseDateList = append(baseDateList, sortDateList...)
  454. sort.Sort(baseDateList)
  455. sortDateList = append([]string{}, baseDateList...)
  456. endDateTime, err := time.ParseInLocation(utils.FormatDate, sortDateList[0], time.Local)
  457. if err != nil {
  458. return
  459. }
  460. firstDateTime, err := time.ParseInLocation(utils.FormatDate, sortDateList[lenDate-1], time.Local)
  461. if err != nil {
  462. return
  463. }
  464. var dataList []*data_manage.EdbDataList
  465. switch edbInfo.EdbInfoType {
  466. case 0:
  467. dataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
  468. case 1:
  469. _, dataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
  470. default:
  471. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  472. }
  473. if err != nil {
  474. return
  475. }
  476. // 获取日期内的数据(包含开始日期前一个日期,以及 结束日期后一个日期,目的为了做空日期时的 插值法兼容)
  477. baseDataList := make([]*data_manage.EdbDataList, 0)
  478. var lastData *data_manage.EdbDataList
  479. var isInsert bool
  480. for _, data := range dataList {
  481. tmpDate := data.DataTime
  482. tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
  483. if tmpErr != nil {
  484. err = tmpErr
  485. return
  486. }
  487. if tmpDateTime.Before(firstDateTime) {
  488. lastData = data
  489. continue
  490. }
  491. // 如果是第一次写入数据
  492. if !isInsert && lastData != nil {
  493. baseDataList = append(baseDataList, lastData)
  494. }
  495. if tmpDateTime.After(endDateTime) {
  496. baseDataList = append(baseDataList, data)
  497. break
  498. }
  499. baseDataList = append(baseDataList, data)
  500. isInsert = true
  501. }
  502. // 实际数据的日期map
  503. realValMap := make(map[string]string)
  504. for _, v := range baseDataList {
  505. realValMap[v.DataTime] = v.DataTime
  506. }
  507. // 插值法处理
  508. handleDataMap := make(map[string]float64)
  509. err = data.HandleDataByLinearRegression(baseDataList, handleDataMap)
  510. if err != nil {
  511. return
  512. }
  513. latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
  514. // 对于不存在的数据做补充
  515. for _, date := range sortDateList {
  516. dataType := 1
  517. if _, ok := realValMap[date]; !ok {
  518. dataType = 2
  519. } else {
  520. dataTime, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
  521. // 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
  522. if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
  523. dataType = 5
  524. }
  525. }
  526. var value, showValue string
  527. if tmpVal, ok := handleDataMap[date]; ok {
  528. value = fmt.Sprint(tmpVal)
  529. showValue = value
  530. } else {
  531. dataType = 3
  532. }
  533. resultDataList = append(resultDataList, request.ManualDataReq{
  534. DataType: dataType,
  535. DataTime: date,
  536. Decimal: decimal,
  537. ShowValue: showValue,
  538. Value: value,
  539. })
  540. }
  541. return
  542. }
  543. // GetFirstHistoryEdbDataList 获取指标的历史的数据
  544. func GetFirstHistoryEdbDataList(edbInfo *data_manage.EdbInfo, num int, endDate string, decimal int) (resultDataList []request.ManualDataReq, err error) {
  545. endDateTime, err := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  546. if err != nil {
  547. return
  548. }
  549. var dataList []*data_manage.EdbDataList
  550. switch edbInfo.EdbInfoType {
  551. case 0:
  552. dataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, endDate)
  553. case 1:
  554. _, dataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, endDate, true)
  555. default:
  556. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  557. }
  558. if err != nil {
  559. return
  560. }
  561. // 获取需要的期数
  562. lenData := len(dataList)
  563. if lenData <= 0 {
  564. return
  565. }
  566. lastData := dataList[lenData-1]
  567. lastDataDateTime, err := time.ParseInLocation(utils.FormatDate, lastData.DataTime, time.Local)
  568. if err != nil {
  569. return
  570. }
  571. if endDateTime.Equal(lastDataDateTime) || lastDataDateTime.After(endDateTime) {
  572. dataList = dataList[:lenData-1]
  573. lenData = len(dataList)
  574. }
  575. if num > lenData {
  576. num = lenData
  577. }
  578. latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
  579. for i := 1; i <= num; i++ {
  580. dataTime, _ := time.ParseInLocation(utils.FormatDate, dataList[lenData-i].DataTime, time.Local)
  581. dataType := 1
  582. // 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
  583. if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
  584. dataType = 5
  585. }
  586. resultDataList = append(resultDataList, request.ManualDataReq{
  587. DataType: dataType,
  588. DataTime: dataList[lenData-i].DataTime,
  589. Decimal: decimal,
  590. ShowValue: fmt.Sprint(dataList[lenData-i].Value),
  591. Value: fmt.Sprint(dataList[lenData-i].Value),
  592. })
  593. }
  594. return
  595. }
  596. // GetEdbIdsFromExcelCodes 获取表格中的指标IDs
  597. func GetEdbIdsFromExcelCodes(excelCodes []string, sysUserId int, lang string) (edbIds []int, err error) {
  598. edbIds = make([]int, 0)
  599. edbIdExist := make(map[int]bool)
  600. for _, v := range excelCodes {
  601. // 表格详情
  602. detail, msg, e := GetExcelDetailInfoByUnicode(v, sysUserId, lang)
  603. if e != nil {
  604. err = fmt.Errorf("GetExcelDetailInfoByExcelInfoId err: %s, errMsg: %s", e.Error(), msg)
  605. return
  606. }
  607. // 自定义表格
  608. if detail.Source == utils.TIME_TABLE {
  609. jsonByte, e := json.Marshal(detail.TableData)
  610. if e != nil {
  611. err = fmt.Errorf("JSON格式化自定义表格数据失败, Err: %s", e.Error())
  612. return
  613. }
  614. var tableData request.TableDataReq
  615. if e = json.Unmarshal(jsonByte, &tableData); e != nil {
  616. err = fmt.Errorf("解析自定义表格数据失败, Err: %s", e.Error())
  617. return
  618. }
  619. for _, tv := range tableData.EdbInfoIdList {
  620. if edbIdExist[tv] {
  621. continue
  622. }
  623. edbIdExist[tv] = true
  624. edbIds = append(edbIds, tv)
  625. }
  626. }
  627. // 混合表格
  628. if detail.Source == utils.MIXED_TABLE {
  629. jsonByte, e := json.Marshal(detail.TableData)
  630. if e != nil {
  631. err = fmt.Errorf("JSON格式化混合表格数据失败, Err: %s", e.Error())
  632. return
  633. }
  634. var tableData request.MixedTableReq
  635. if e = json.Unmarshal(jsonByte, &tableData); e != nil {
  636. err = fmt.Errorf("解析混合表格数据失败, Err: %s", e.Error())
  637. return
  638. }
  639. if len(tableData.Data) > 0 {
  640. for _, td := range tableData.Data {
  641. for _, tv := range td {
  642. if tv.EdbInfoId > 0 && !edbIdExist[tv.EdbInfoId] {
  643. edbIdExist[tv.EdbInfoId] = true
  644. edbIds = append(edbIds, tv.EdbInfoId)
  645. }
  646. }
  647. }
  648. }
  649. }
  650. }
  651. return
  652. }
  653. // GetExcelEdbBatchRefreshKey 获取批量刷新表格指标缓存key
  654. func GetExcelEdbBatchRefreshKey(source string, primaryId, subId int) string {
  655. if source == `` {
  656. return ``
  657. }
  658. return fmt.Sprint("batch_refresh_excel_edb:", source, ":", primaryId, ":", subId)
  659. }
  660. // GetEdbSourceByEdbInfoIdList 获取关联指标的来源
  661. func GetEdbSourceByEdbInfoIdList(edbInfoIdList []int) (sourceNameList, sourceNameEnList []string, err error) {
  662. sourceNameList = make([]string, 0)
  663. sourceNameEnList = make([]string, 0)
  664. sourceMap := make(map[int]string)
  665. edbInfoList, tmpErr := data_manage.GetEdbInfoByIdList(edbInfoIdList)
  666. if tmpErr != nil {
  667. err = tmpErr
  668. return
  669. }
  670. for _, v := range edbInfoList {
  671. // 指标类型:1:基础指标,2:计算指标
  672. if v.EdbType == 2 {
  673. //sourceMap[0] = "弘则研究"
  674. baseEdbInfoArr, _, _ := data_manage.GetRefreshEdbInfoFromBase(v.EdbInfoId, v.Source)
  675. for _, baseEdbInfo := range baseEdbInfoArr {
  676. if baseEdbInfo.EdbInfoType == 0 { //普通指标才参与,预测指标不参与
  677. sourceMap[baseEdbInfo.Source] = baseEdbInfo.SourceName
  678. }
  679. }
  680. } else {
  681. sourceMap[v.Source] = v.SourceName
  682. }
  683. }
  684. for source, sourceName := range sourceMap {
  685. if utils.InArrayByInt([]int{utils.DATA_SOURCE_MANUAL}, source) {
  686. continue
  687. }
  688. sourceNameList = append(sourceNameList, sourceName)
  689. sourceNameEn, ok := utils.DataSourceEnMap[source]
  690. if !ok {
  691. sourceNameEn = sourceName
  692. }
  693. sourceNameEnList = append(sourceNameEnList, sourceNameEn)
  694. }
  695. //sourceNameList = append(sourceNameList, utils.ChartDefaultNameCn)
  696. //sourceNameEnList = append(sourceNameEnList, utils.ChartDefaultNameEn)
  697. // 图表来源
  698. conf, e := models.GetBusinessConf()
  699. if e != nil {
  700. return
  701. }
  702. if conf[models.BusinessConfCompanyName] != "" {
  703. sourceNameList = append(sourceNameList, conf[models.BusinessConfCompanyName])
  704. sourceNameEnList = append(sourceNameEnList, conf[models.BusinessConfCompanyName])
  705. }
  706. // (弘则)合规上的要求过滤掉SMM,彭博以及彭博财务;前端那边没办法完全处理掉入口的所以这边也过滤一下
  707. if conf[models.BusinessConfHideSourceFormSMM] == "true" {
  708. newNames, newEnNames := make([]string, 0), make([]string, 0)
  709. for _, v := range sourceNameList {
  710. str := strings.ToUpper(v)
  711. if str == "SMM" || str == "彭博" || str == "彭博财务" {
  712. continue
  713. }
  714. newNames = append(newNames, v)
  715. }
  716. for _, v := range sourceNameEnList {
  717. str := strings.ToUpper(v)
  718. if str == "SMM" || str == "彭博" || str == "彭博财务" {
  719. continue
  720. }
  721. newEnNames = append(newEnNames, v)
  722. }
  723. return newNames, newEnNames, nil
  724. }
  725. return
  726. }
  727. // GetCustomAnalysisOpButton 获取自定义分析按钮权限
  728. func GetCustomAnalysisOpButton(sysUser *system.Admin, belongUserId int, permissionType []int) (button excel.ExcelInfoDetailButton) {
  729. // 管理员/所属人所有权限
  730. if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN || sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN || sysUser.AdminId == belongUserId {
  731. button.RefreshButton = true
  732. button.CopyButton = true
  733. button.DownloadButton = true
  734. button.OpEdbButton = true
  735. button.RefreshEdbButton = true
  736. button.OpButton = true
  737. button.DeleteButton = true
  738. return
  739. }
  740. // 非管理员-被分享人
  741. for _, v := range permissionType {
  742. if v == 1 {
  743. button.RefreshButton = true
  744. button.CopyButton = true
  745. button.DownloadButton = true
  746. }
  747. if v == 2 {
  748. button.OpEdbButton = true
  749. button.RefreshEdbButton = true
  750. button.OpButton = true
  751. button.CopyButton = true
  752. button.DownloadButton = true
  753. }
  754. }
  755. return
  756. }
  757. func parseExcelScopeCoord(scopeList []string) (scopeCoord string, err error) {
  758. if len(scopeList) == 2 {
  759. x1, y1, er := excelize.CellNameToCoordinates(scopeList[0])
  760. if er != nil {
  761. return "", er
  762. }
  763. x2, y2, er := excelize.CellNameToCoordinates(scopeList[1])
  764. if er != nil {
  765. return "", er
  766. }
  767. scopeCoord = fmt.Sprintf("%d,%d,%d,%d", x1, y1, x2, y2)
  768. }
  769. if len(scopeList) == 1 {
  770. x1, y1, er := excelize.CellNameToCoordinates(scopeList[0])
  771. if er != nil {
  772. return "", er
  773. }
  774. scopeCoord = fmt.Sprintf("%d,%d", x1, y1)
  775. }
  776. return
  777. }
  778. func ExcelRuleFormat(req *request.ExcelRuleMappingReq, lang string) (res *excel.ExcelInfoRuleMapping, err error) {
  779. res = new(excel.ExcelInfoRuleMapping)
  780. if req.RuleType == 5 {
  781. switch req.LeftValue {
  782. // 今天
  783. case "today":
  784. res.LeftValueBack = req.LeftValue
  785. // 明天
  786. case "tomorrow":
  787. res.LeftValueBack = req.LeftValue
  788. // 最近7天
  789. case "last7days":
  790. res.LeftValueBack = req.LeftValue
  791. // 上周
  792. case "lastweek":
  793. res.LeftValueBack = req.LeftValue
  794. // 本周
  795. case "thisweek":
  796. res.LeftValueBack = req.LeftValue
  797. // 下周
  798. case "nextweek":
  799. res.LeftValueBack = req.LeftValue
  800. // 上月
  801. case "lastmonth":
  802. res.LeftValueBack = req.LeftValue
  803. // 本月
  804. case "thismonth":
  805. res.LeftValueBack = req.LeftValue
  806. // 下月
  807. case "nextmonth":
  808. res.LeftValueBack = req.LeftValue
  809. default:
  810. err = errors.New("发生日期规则错误")
  811. return
  812. }
  813. }
  814. // 格式化条件值
  815. switch req.LeftValueType {
  816. // 坐标
  817. case 2:
  818. x, y, err := excelize.CellNameToCoordinates(req.LeftValue)
  819. if err != nil {
  820. return nil, err
  821. }
  822. res.LeftValue = req.LeftValue
  823. res.LeftValueBack = fmt.Sprintf("%d,%d", x, y)
  824. default:
  825. res.LeftValue = req.LeftValue
  826. res.LeftValueBack = req.LeftValue
  827. }
  828. switch req.RightValueType {
  829. // 坐标
  830. case 2:
  831. x, y, err := excelize.CellNameToCoordinates(req.RightValue)
  832. if err != nil {
  833. return nil, err
  834. }
  835. res.RightValue = req.RightValue
  836. res.RightValueBack = fmt.Sprintf("%d,%d", x, y)
  837. default:
  838. res.RightValue = req.RightValue
  839. res.RightValueBack = req.RightValue
  840. }
  841. if res.LeftValueBack == "" {
  842. res.LeftValueBack = req.LeftValue
  843. }
  844. if res.RightValueBack == "" {
  845. res.RightValueBack = req.RightValue
  846. }
  847. res.RuleType = req.RuleType
  848. res.ExcelInfoId = req.ExcelInfoId
  849. res.ExcelInfoRuleMappingId = req.ExcelRuleMappingId
  850. res.LeftValueType = req.LeftValueType
  851. res.RightValueType = req.RightValueType
  852. res.FontColor = req.FontColor
  853. res.BackgroundColor = req.BackgroundColor
  854. res.Remark = req.Remark
  855. res.RemarkEn = req.Remark
  856. res.ScopeShow = req.Scope
  857. scopeList := strings.Split(req.Scope, ":")
  858. res.ScopeCoord, err = parseExcelScopeCoord(scopeList)
  859. return
  860. }
  861. func AddExcelRule(req *request.ExcelRuleMappingReq, lang string) (err error) {
  862. excelRule, err := ExcelRuleFormat(req, lang)
  863. if err != nil {
  864. return
  865. }
  866. if excelRule.ExcelInfoRuleMappingId != 0 {
  867. return errors.New("规则已存在")
  868. }
  869. excelRule.CreateTime = time.Now()
  870. _, err = excelRule.Insert()
  871. return
  872. }
  873. func ModifyExcelRule(req *request.ExcelRuleMappingReq, lang string) (err error) {
  874. excelInfo, err := excel.GetExcelRuleMappingById(req.ExcelRuleMappingId)
  875. if err != nil {
  876. return
  877. }
  878. editExcelInfo, err := ExcelRuleFormat(req, lang)
  879. if err != nil {
  880. return
  881. }
  882. var updateCols []string
  883. if excelInfo.LeftValue != editExcelInfo.LeftValue {
  884. updateCols = append(updateCols, "LeftValue")
  885. updateCols = append(updateCols, "LeftValueBack")
  886. }
  887. if excelInfo.LeftValueType != editExcelInfo.LeftValueType {
  888. updateCols = append(updateCols, "LeftValueType")
  889. }
  890. if excelInfo.RightValue != editExcelInfo.RightValue {
  891. updateCols = append(updateCols, "RightValue")
  892. updateCols = append(updateCols, "RightValueBack")
  893. }
  894. if excelInfo.RightValueType != editExcelInfo.RightValueType {
  895. updateCols = append(updateCols, "RightValueType")
  896. }
  897. if excelInfo.FontColor != editExcelInfo.FontColor {
  898. updateCols = append(updateCols, "FontColor")
  899. }
  900. if excelInfo.BackgroundColor != editExcelInfo.BackgroundColor {
  901. updateCols = append(updateCols, "BackgroundColor")
  902. }
  903. if excelInfo.Remark != editExcelInfo.Remark {
  904. updateCols = append(updateCols, "Remark")
  905. }
  906. if excelInfo.RemarkEn != editExcelInfo.RemarkEn {
  907. updateCols = append(updateCols, "RemarkEn")
  908. }
  909. if excelInfo.ScopeShow != editExcelInfo.ScopeShow {
  910. updateCols = append(updateCols, "ScopeCoord")
  911. updateCols = append(updateCols, "ScopeShow")
  912. }
  913. if len(updateCols) > 0 {
  914. err = editExcelInfo.Update(updateCols)
  915. }
  916. return
  917. }
  918. // GetExcelRuleList 获取规则列表
  919. func GetExcelRuleList(excelInfoId int) (resp *response.ExcelRuleListResp, err error) {
  920. resp = new(response.ExcelRuleListResp)
  921. excelInfoList, err := excel.GetExcelRuleMappingByExcelInfoId(excelInfoId)
  922. if err != nil {
  923. return
  924. }
  925. resp.List = excelInfoList
  926. return
  927. }
  928. // GetExcelRuleDetail 获取规则列表
  929. func GetExcelRuleDetail(excelInfoMappingId int) (resp *excel.ExcelInfoRuleMappingView, err error) {
  930. resp = new(excel.ExcelInfoRuleMappingView)
  931. excelInfoDetail, err := excel.GetExcelRuleMappingById(excelInfoMappingId)
  932. if err != nil {
  933. return
  934. }
  935. resp = excelInfoDetail
  936. return
  937. }