excel_info.go 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  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 err.Error() == utils.ErrNoRow() {
  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 err.Error() == utils.ErrNoRow() {
  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, utils.DATA_SOURCE_MYSTEEL_CHEMICAL}, 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. return
  707. }
  708. // GetCustomAnalysisOpButton 获取自定义分析按钮权限
  709. func GetCustomAnalysisOpButton(sysUser *system.Admin, belongUserId int, permissionType []int) (button excel.ExcelInfoDetailButton) {
  710. // 管理员/所属人所有权限
  711. if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN || sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN || sysUser.AdminId == belongUserId {
  712. button.RefreshButton = true
  713. button.CopyButton = true
  714. button.DownloadButton = true
  715. button.OpEdbButton = true
  716. button.RefreshEdbButton = true
  717. button.OpButton = true
  718. button.DeleteButton = true
  719. return
  720. }
  721. // 非管理员-被分享人
  722. for _, v := range permissionType {
  723. if v == 1 {
  724. button.RefreshButton = true
  725. button.CopyButton = true
  726. button.DownloadButton = true
  727. }
  728. if v == 2 {
  729. button.OpEdbButton = true
  730. button.RefreshEdbButton = true
  731. button.OpButton = true
  732. button.CopyButton = true
  733. button.DownloadButton = true
  734. }
  735. }
  736. return
  737. }
  738. func parseExcelScopeCoord(scopeList []string) (scopeCoord string, err error) {
  739. if len(scopeList) == 2 {
  740. x1, y1, er := excelize.CellNameToCoordinates(scopeList[0])
  741. if er != nil {
  742. return "", er
  743. }
  744. x2, y2, er := excelize.CellNameToCoordinates(scopeList[1])
  745. if er != nil {
  746. return "", er
  747. }
  748. scopeCoord = fmt.Sprintf("%d,%d,%d,%d", x1, y1, x2, y2)
  749. }
  750. if len(scopeList) == 1 {
  751. x1, y1, er := excelize.CellNameToCoordinates(scopeList[0])
  752. if er != nil {
  753. return "", er
  754. }
  755. scopeCoord = fmt.Sprintf("%d,%d", x1, y1)
  756. }
  757. return
  758. }
  759. func ExcelRuleFormat(req *request.ExcelRuleMappingReq, lang string) (res *excel.ExcelInfoRuleMapping, err error) {
  760. res = new(excel.ExcelInfoRuleMapping)
  761. if req.RuleType == 5 {
  762. switch req.LeftValue {
  763. // 今天
  764. case "today":
  765. res.LeftValueBack = req.LeftValue
  766. // 明天
  767. case "tomorrow":
  768. res.LeftValueBack = req.LeftValue
  769. // 最近7天
  770. case "last7days":
  771. res.LeftValueBack = req.LeftValue
  772. // 上周
  773. case "lastweek":
  774. res.LeftValueBack = req.LeftValue
  775. // 本周
  776. case "thisweek":
  777. res.LeftValueBack = req.LeftValue
  778. // 下周
  779. case "nextweek":
  780. res.LeftValueBack = req.LeftValue
  781. // 上月
  782. case "lastmonth":
  783. res.LeftValueBack = req.LeftValue
  784. // 本月
  785. case "thismonth":
  786. res.LeftValueBack = req.LeftValue
  787. // 下月
  788. case "nextmonth":
  789. res.LeftValueBack = req.LeftValue
  790. default:
  791. err = errors.New("发生日期规则错误")
  792. return
  793. }
  794. }
  795. // 格式化条件值
  796. switch req.LeftValueType {
  797. // 坐标
  798. case 2:
  799. x, y, err := excelize.CellNameToCoordinates(req.LeftValue)
  800. if err != nil {
  801. return nil, err
  802. }
  803. res.LeftValue = req.LeftValue
  804. res.LeftValueBack = fmt.Sprintf("%d,%d", x, y)
  805. default:
  806. res.LeftValue = req.LeftValue
  807. res.LeftValueBack = req.LeftValue
  808. }
  809. switch req.RightValueType {
  810. // 坐标
  811. case 2:
  812. x, y, err := excelize.CellNameToCoordinates(req.RightValue)
  813. if err != nil {
  814. return nil, err
  815. }
  816. res.RightValue = req.RightValue
  817. res.RightValueBack = fmt.Sprintf("%d,%d", x, y)
  818. default:
  819. res.RightValue = req.RightValue
  820. res.RightValueBack = req.RightValue
  821. }
  822. if res.LeftValueBack == "" {
  823. res.LeftValueBack = req.LeftValue
  824. }
  825. if res.RightValueBack == "" {
  826. res.RightValueBack = req.RightValue
  827. }
  828. res.RuleType = req.RuleType
  829. res.ExcelInfoId = req.ExcelInfoId
  830. res.ExcelInfoRuleMappingId = req.ExcelRuleMappingId
  831. res.LeftValueType = req.LeftValueType
  832. res.RightValueType = req.RightValueType
  833. res.FontColor = req.FontColor
  834. res.BackgroundColor = req.BackgroundColor
  835. res.Remark = req.Remark
  836. res.RemarkEn = req.Remark
  837. res.ScopeShow = req.Scope
  838. scopeList := strings.Split(req.Scope, ":")
  839. res.ScopeCoord, err = parseExcelScopeCoord(scopeList)
  840. return
  841. }
  842. func AddExcelRule(req *request.ExcelRuleMappingReq, lang string) (err error) {
  843. excelRule, err := ExcelRuleFormat(req, lang)
  844. if err != nil {
  845. return
  846. }
  847. if excelRule.ExcelInfoRuleMappingId != 0 {
  848. return errors.New("规则已存在")
  849. }
  850. excelRule.CreateTime = time.Now()
  851. _, err = excelRule.Insert()
  852. return
  853. }
  854. func ModifyExcelRule(req *request.ExcelRuleMappingReq, lang string) (err error) {
  855. excelInfo, err := excel.GetExcelRuleMappingById(req.ExcelRuleMappingId)
  856. if err != nil {
  857. return
  858. }
  859. editExcelInfo, err := ExcelRuleFormat(req, lang)
  860. if err != nil {
  861. return
  862. }
  863. var updateCols []string
  864. if excelInfo.LeftValue != editExcelInfo.LeftValue {
  865. updateCols = append(updateCols, "LeftValue")
  866. updateCols = append(updateCols, "LeftValueBack")
  867. }
  868. if excelInfo.LeftValueType != editExcelInfo.LeftValueType {
  869. updateCols = append(updateCols, "LeftValueType")
  870. }
  871. if excelInfo.RightValue != editExcelInfo.RightValue {
  872. updateCols = append(updateCols, "RightValue")
  873. updateCols = append(updateCols, "RightValueBack")
  874. }
  875. if excelInfo.RightValueType != editExcelInfo.RightValueType {
  876. updateCols = append(updateCols, "RightValueType")
  877. }
  878. if excelInfo.FontColor != editExcelInfo.FontColor {
  879. updateCols = append(updateCols, "FontColor")
  880. }
  881. if excelInfo.BackgroundColor != editExcelInfo.BackgroundColor {
  882. updateCols = append(updateCols, "BackgroundColor")
  883. }
  884. if excelInfo.Remark != editExcelInfo.Remark {
  885. updateCols = append(updateCols, "Remark")
  886. }
  887. if excelInfo.RemarkEn != editExcelInfo.RemarkEn {
  888. updateCols = append(updateCols, "RemarkEn")
  889. }
  890. if excelInfo.ScopeShow != editExcelInfo.ScopeShow {
  891. updateCols = append(updateCols, "ScopeCoord")
  892. updateCols = append(updateCols, "ScopeShow")
  893. }
  894. if len(updateCols) > 0 {
  895. err = editExcelInfo.Update(updateCols)
  896. }
  897. return
  898. }
  899. // GetExcelRuleList 获取规则列表
  900. func GetExcelRuleList(excelInfoId int) (resp *response.ExcelRuleListResp, err error) {
  901. resp = new(response.ExcelRuleListResp)
  902. excelInfoList, err := excel.GetExcelRuleMappingByExcelInfoId(excelInfoId)
  903. if err != nil {
  904. return
  905. }
  906. resp.List = excelInfoList
  907. return
  908. }
  909. // GetExcelRuleDetail 获取规则列表
  910. func GetExcelRuleDetail(excelInfoMappingId int) (resp *excel.ExcelInfoRuleMappingView, err error) {
  911. resp = new(excel.ExcelInfoRuleMappingView)
  912. excelInfoDetail, err := excel.GetExcelRuleMappingById(excelInfoMappingId)
  913. if err != nil {
  914. return
  915. }
  916. resp = excelInfoDetail
  917. return
  918. }