predict_edb_info.go 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177
  1. package data
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_api/models/data_manage"
  6. "eta/eta_api/models/data_manage/request"
  7. "eta/eta_api/models/system"
  8. "eta/eta_api/utils"
  9. "fmt"
  10. "github.com/shopspring/decimal"
  11. "strconv"
  12. "strings"
  13. "time"
  14. )
  15. // AddPredictEdbInfo 新增预测指标
  16. func AddPredictEdbInfo(sourceEdbInfoId, classifyId int, edbName string, ruleList []request.RuleConfig, sysUserId int, sysUserName, requestBody, requestUrl string) (edbInfo *data_manage.EdbInfo, err error, errMsg string) {
  17. var sourceEdbInfo *data_manage.EdbInfo
  18. // 来源指标信息校验
  19. {
  20. sourceEdbInfo, err = data_manage.GetEdbInfoById(sourceEdbInfoId)
  21. if err != nil && err.Error() != utils.ErrNoRow() {
  22. errMsg = "新增失败"
  23. err = errors.New("获取来源指标失败,Err:" + err.Error())
  24. return
  25. }
  26. if sourceEdbInfo == nil {
  27. errMsg = "找不到该来源指标"
  28. err = nil
  29. return
  30. }
  31. //必须是普通的指标
  32. if sourceEdbInfo.EdbInfoType != 0 {
  33. errMsg = "来源指标异常,不是普通的指标"
  34. return
  35. }
  36. if !utils.InArrayByStr([]string{"日度", "周度", "月度"}, sourceEdbInfo.Frequency) {
  37. errMsg = "预测指标只支持选择日度、周度、月度的指标"
  38. return
  39. }
  40. }
  41. var classifyInfo *data_manage.EdbClassify
  42. // 来源分类信息校验
  43. {
  44. classifyInfo, err = data_manage.GetEdbClassifyById(classifyId)
  45. if err != nil && err.Error() != utils.ErrNoRow() {
  46. errMsg = "新增失败"
  47. err = errors.New("获取预测指标分类失败,Err:" + err.Error())
  48. return
  49. }
  50. if classifyInfo == nil {
  51. errMsg = "找不到该预测指标分类"
  52. err = nil
  53. return
  54. }
  55. //必须是预测指标分类
  56. if classifyInfo.ClassifyType != 1 {
  57. errMsg = "预测指标分类异常,不是预测指标分类"
  58. return
  59. }
  60. }
  61. edbName = strings.Trim(edbName, " ")
  62. edbCode := sourceEdbInfo.EdbCode + "_" + time.Now().Format(utils.FormatShortDateTimeUnSpace)
  63. // 判断该来源指标是否已经被引用了
  64. {
  65. //predictEdbConf, tmpErr := data_manage.GetPredictEdbConfBySourceEdbInfoId(sourceEdbInfoId)
  66. //if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
  67. // errMsg = "新增失败"
  68. // err = tmpErr
  69. // return
  70. //}
  71. // 如果该来源指标已经被引用了,那么不允许再次使用
  72. //if predictEdbConf != nil {
  73. // //获取预测指标详情
  74. // predictEdbInfo, tmpErr := data_manage.GetEdbInfoById(predictEdbConf.PredictEdbInfoId)
  75. // if tmpErr != nil {
  76. // errMsg = "新增失败"
  77. // err = tmpErr
  78. // return
  79. // }
  80. // //获取预测指标的分类
  81. // edbClassifyInfo, tmpErr := data_manage.GetEdbClassifyById(predictEdbInfo.ClassifyId)
  82. // if tmpErr != nil {
  83. // errMsg = "新增失败"
  84. // err = tmpErr
  85. // return
  86. // }
  87. // errMsg = "该指标已存在数据库,目录为:" + edbClassifyInfo.ClassifyName + ",请重新选择指标"
  88. // err = errors.New(errMsg)
  89. // return
  90. //}
  91. }
  92. //判断指标名称是否存在
  93. var condition string
  94. var pars []interface{}
  95. condition += " AND edb_info_type=? "
  96. pars = append(pars, 1)
  97. condition += " AND edb_name=? "
  98. pars = append(pars, edbName)
  99. count, err := data_manage.GetEdbInfoCountByCondition(condition, pars)
  100. if err != nil {
  101. errMsg = "判断指标名称是否存在失败"
  102. err = errors.New("判断指标名称是否存在失败,Err:" + err.Error())
  103. return
  104. }
  105. if count > 0 {
  106. errMsg = "指标名称已存在,请重新填写"
  107. return
  108. }
  109. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  110. edbInfo = &data_manage.EdbInfo{
  111. //EdbInfoId: 0,
  112. EdbInfoType: 1,
  113. SourceName: "预测指标",
  114. Source: utils.DATA_SOURCE_PREDICT,
  115. EdbCode: edbCode,
  116. EdbName: edbName,
  117. EdbNameSource: edbName,
  118. Frequency: sourceEdbInfo.Frequency,
  119. Unit: sourceEdbInfo.Unit,
  120. StartDate: sourceEdbInfo.StartDate,
  121. ClassifyId: classifyId,
  122. SysUserId: sysUserId,
  123. SysUserRealName: sysUserName,
  124. UniqueCode: utils.MD5(utils.DATA_PREFIX + "_" + timestamp),
  125. CreateTime: time.Now(),
  126. ModifyTime: time.Now(),
  127. MinValue: sourceEdbInfo.MinValue,
  128. MaxValue: sourceEdbInfo.MaxValue,
  129. CalculateFormula: sourceEdbInfo.CalculateFormula,
  130. EdbType: 1,
  131. //Sort: sourceEdbInfo.,
  132. LatestDate: sourceEdbInfo.LatestDate,
  133. LatestValue: sourceEdbInfo.LatestValue,
  134. MoveType: sourceEdbInfo.MoveType,
  135. MoveFrequency: sourceEdbInfo.MoveFrequency,
  136. NoUpdate: sourceEdbInfo.NoUpdate,
  137. ServerUrl: "",
  138. }
  139. // 关联关系表
  140. calculateMappingList := make([]*data_manage.EdbInfoCalculateMapping, 0)
  141. fromEdbMap := make(map[int]int)
  142. // 源指标关联关系表
  143. calculateMappingItem := &data_manage.EdbInfoCalculateMapping{
  144. //EdbInfoCalculateMappingId: 0,
  145. //EdbInfoId: 0,
  146. Source: edbInfo.Source,
  147. SourceName: edbInfo.SourceName,
  148. EdbCode: edbInfo.EdbCode,
  149. FromEdbInfoId: sourceEdbInfo.EdbInfoId,
  150. FromEdbCode: sourceEdbInfo.EdbCode,
  151. FromEdbName: sourceEdbInfo.EdbName,
  152. FromSource: sourceEdbInfo.Source,
  153. FromSourceName: sourceEdbInfo.SourceName,
  154. //FromTag: "",
  155. Sort: 1,
  156. CreateTime: time.Now(),
  157. ModifyTime: time.Now(),
  158. }
  159. fromEdbMap[sourceEdbInfoId] = sourceEdbInfoId
  160. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  161. // 预测指标配置
  162. predictEdbConfList := make([]*data_manage.PredictEdbConf, 0)
  163. for _, v := range ruleList {
  164. // 预测指标配置
  165. ruleEndDate, tmpErr := time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
  166. if tmpErr != nil {
  167. errMsg = "规则配置的截止日期异常,请重新填写"
  168. return
  169. }
  170. // 没有数据,自己瞎测试
  171. //switch v.RuleType {
  172. //case 3: //3:同比
  173. // v.Value = "0.1"
  174. //case 4: //4:同差
  175. // v.Value = "10"
  176. //case 5: //5:环比
  177. // v.Value = "0.1"
  178. //case 6: //6:环差
  179. // v.Value = "0.1"
  180. //case 7: //7:N期移动均值
  181. // v.Value = "5"
  182. //case 8: //8:N期段线性外推值
  183. // v.Value = "5"
  184. //}
  185. switch v.RuleType {
  186. case 8: //N期段线性外推值
  187. valInt, tmpErr := strconv.Atoi(v.Value)
  188. if tmpErr != nil {
  189. errMsg = "N期段线性外推值的N值异常"
  190. return
  191. }
  192. if valInt <= 1 {
  193. errMsg = "N期段线性外推值的N值必须大于1"
  194. return
  195. }
  196. case 9: //9:动态环差
  197. for _, v := range v.EdbInfoIdArr {
  198. fromEdbMap[v.EdbInfoId] = v.EdbInfoId
  199. }
  200. }
  201. tmpPredictEdbConf := &data_manage.PredictEdbConf{
  202. PredictEdbInfoId: 0,
  203. SourceEdbInfoId: sourceEdbInfoId,
  204. RuleType: v.RuleType,
  205. //FixedValue: v.Value,
  206. Value: v.Value,
  207. EndDate: ruleEndDate,
  208. ModifyTime: time.Now(),
  209. CreateTime: time.Now(),
  210. }
  211. edbInfo.EndDate = v.EndDate
  212. predictEdbConfList = append(predictEdbConfList, tmpPredictEdbConf)
  213. }
  214. err = data_manage.AddPredictEdb(edbInfo, calculateMappingItem, predictEdbConfList)
  215. if err != nil {
  216. errMsg = "保存失败"
  217. err = errors.New("保存失败,Err:" + err.Error())
  218. return
  219. }
  220. //新增操作日志
  221. {
  222. edbLog := new(data_manage.EdbInfoLog)
  223. edbLog.EdbInfoId = edbInfo.EdbInfoId
  224. edbLog.SourceName = edbInfo.SourceName
  225. edbLog.Source = edbInfo.Source
  226. edbLog.EdbCode = edbInfo.EdbCode
  227. edbLog.EdbName = edbInfo.EdbName
  228. edbLog.ClassifyId = edbInfo.ClassifyId
  229. edbLog.SysUserId = sysUserId
  230. edbLog.SysUserRealName = sysUserName
  231. edbLog.CreateTime = time.Now()
  232. edbLog.Content = requestBody
  233. edbLog.Status = "新增指标"
  234. edbLog.Method = requestUrl
  235. go data_manage.AddEdbInfoLog(edbLog)
  236. }
  237. //添加es
  238. AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
  239. return
  240. }
  241. // EditPredictEdbInfo 编辑预测指标
  242. func EditPredictEdbInfo(edbInfoId, classifyId int, edbName string, ruleList []request.RuleConfig, sysUserId int, sysUserName, requestBody, requestUrl string) (edbInfo *data_manage.EdbInfo, err error, errMsg string) {
  243. // 指标信息校验
  244. {
  245. edbInfo, err = data_manage.GetEdbInfoById(edbInfoId)
  246. if err != nil && err.Error() != utils.ErrNoRow() {
  247. errMsg = "修改失败"
  248. err = errors.New("获取预测指标失败,Err:" + err.Error())
  249. return
  250. }
  251. if edbInfo == nil {
  252. errMsg = "找不到该预测指标"
  253. err = nil
  254. return
  255. }
  256. //必须是普通的指标
  257. if edbInfo.EdbInfoType != 1 {
  258. errMsg = "指标异常,不是预测指标"
  259. return
  260. }
  261. }
  262. var predictEdbConf *data_manage.PredictEdbConf
  263. // 指标配置信息校验
  264. {
  265. // 查找该预测指标配置
  266. predictEdbConfList, tmpErr := data_manage.GetPredictEdbConfListById(edbInfo.EdbInfoId)
  267. if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
  268. errMsg = "修改失败"
  269. err = errors.New("获取预测指标配置信息失败,Err:" + tmpErr.Error())
  270. return
  271. }
  272. if len(predictEdbConfList) == 0 {
  273. errMsg = "找不到该预测指标配置"
  274. err = nil
  275. return
  276. }
  277. predictEdbConf = predictEdbConfList[0]
  278. }
  279. //判断指标名称是否存在
  280. var condition string
  281. var pars []interface{}
  282. condition += " AND edb_info_id<>? "
  283. pars = append(pars, edbInfoId)
  284. condition += " AND edb_info_type=? "
  285. pars = append(pars, 1)
  286. condition += " AND edb_name=? "
  287. pars = append(pars, edbName)
  288. count, err := data_manage.GetEdbInfoCountByCondition(condition, pars)
  289. if err != nil {
  290. errMsg = "判断指标名称是否存在失败"
  291. err = errors.New("判断指标名称是否存在失败,Err:" + err.Error())
  292. return
  293. }
  294. if count > 0 {
  295. errMsg = "指标名称已存在,请重新填写"
  296. return
  297. }
  298. edbInfo.EdbName = edbName
  299. edbInfo.EdbNameSource = edbName
  300. edbInfo.ClassifyId = classifyId
  301. edbInfo.ModifyTime = time.Now()
  302. updateEdbInfoCol := []string{"EdbName", "EdbNameSource", "ClassifyId", "EndDate", "ModifyTime"}
  303. // 预测指标配置
  304. predictEdbConfList := make([]*data_manage.PredictEdbConf, 0)
  305. for _, v := range ruleList {
  306. // 预测指标配置
  307. ruleEndDate, tmpErr := time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
  308. if tmpErr != nil {
  309. errMsg = "规则配置的截止日期异常,请重新填写"
  310. return
  311. }
  312. switch v.RuleType {
  313. case 8: //N期段线性外推值
  314. valInt, tmpErr := strconv.Atoi(v.Value)
  315. if tmpErr != nil {
  316. errMsg = "N期段线性外推值的N值异常"
  317. return
  318. }
  319. if valInt <= 1 {
  320. errMsg = "N期段线性外推值的N值必须大于1"
  321. return
  322. }
  323. case 9: //9:动态环差
  324. }
  325. tmpPredictEdbConf := &data_manage.PredictEdbConf{
  326. PredictEdbInfoId: edbInfoId,
  327. SourceEdbInfoId: predictEdbConf.SourceEdbInfoId,
  328. RuleType: v.RuleType,
  329. //FixedValue: v.Value,
  330. Value: v.Value,
  331. EndDate: ruleEndDate,
  332. ModifyTime: time.Now(),
  333. CreateTime: time.Now(),
  334. }
  335. predictEdbConfList = append(predictEdbConfList, tmpPredictEdbConf)
  336. edbInfo.EndDate = v.EndDate
  337. }
  338. err = data_manage.EditPredictEdb(edbInfo, predictEdbConfList, updateEdbInfoCol)
  339. if err != nil {
  340. errMsg = "保存失败"
  341. err = errors.New("保存失败,Err:" + err.Error())
  342. return
  343. }
  344. //新增操作日志
  345. {
  346. edbLog := new(data_manage.EdbInfoLog)
  347. edbLog.EdbInfoId = edbInfo.EdbInfoId
  348. edbLog.SourceName = edbInfo.SourceName
  349. edbLog.Source = edbInfo.Source
  350. edbLog.EdbCode = edbInfo.EdbCode
  351. edbLog.EdbName = edbInfo.EdbName
  352. edbLog.ClassifyId = edbInfo.ClassifyId
  353. edbLog.SysUserId = sysUserId
  354. edbLog.SysUserRealName = sysUserName
  355. edbLog.CreateTime = time.Now()
  356. edbLog.Content = requestBody
  357. edbLog.Status = "编辑指标"
  358. edbLog.Method = requestUrl
  359. go data_manage.AddEdbInfoLog(edbLog)
  360. }
  361. //添加es
  362. AddOrEditEdbInfoToEs(edbInfoId)
  363. // 刷新关联指标
  364. go EdbInfoRefreshAllFromBaseV2(edbInfo.EdbInfoId, true, false)
  365. return
  366. }
  367. // RefreshPredictEdbInfo 刷新预测指标
  368. func RefreshPredictEdbInfo(edbInfoId int, refreshAll bool) (edbInfo *data_manage.EdbInfo, isAsync bool, err error, errMsg string) {
  369. // 指标信息校验
  370. {
  371. edbInfo, err = data_manage.GetEdbInfoById(edbInfoId)
  372. if err != nil && err.Error() != utils.ErrNoRow() {
  373. errMsg = "刷新失败"
  374. err = errors.New("获取预测指标失败,Err:" + err.Error())
  375. return
  376. }
  377. if edbInfo == nil {
  378. errMsg = "找不到该预测指标"
  379. err = nil
  380. return
  381. }
  382. //必须是预测的指标
  383. if edbInfo.EdbInfoType != 1 {
  384. errMsg = "指标异常,不是预测指标"
  385. return
  386. }
  387. }
  388. err, isAsync = EdbInfoRefreshAllFromBaseV2(edbInfo.EdbInfoId, refreshAll, false)
  389. return
  390. }
  391. // MovePredictEdbInfo 移动预测指标
  392. func MovePredictEdbInfo(edbInfoId, classifyId, prevEdbInfoId, nextEdbInfoId int, sysUser *system.Admin, requestBody, requestUrl string) (err error, errMsg string) {
  393. //判断分类是否存在
  394. count, _ := data_manage.GetEdbClassifyCountById(classifyId)
  395. if count <= 0 {
  396. errMsg = "分类已被删除,不可移动,请刷新页面"
  397. return
  398. }
  399. edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
  400. if err != nil {
  401. if err != nil && err.Error() != utils.ErrNoRow() {
  402. errMsg = "移动失败"
  403. err = errors.New("获取预测指标失败,Err:" + err.Error())
  404. return
  405. }
  406. if edbInfo == nil {
  407. errMsg = "找不到该预测指标"
  408. err = nil
  409. return
  410. }
  411. return
  412. }
  413. // 移动权限校验
  414. button := GetEdbOpButton(sysUser, edbInfo.SysUserId, edbInfo.EdbType, edbInfo.EdbInfoType)
  415. if !button.MoveButton {
  416. errMsg = "无权限操作"
  417. err = nil
  418. return
  419. return
  420. }
  421. //如果改变了分类,那么移动该指标数据
  422. if edbInfo.ClassifyId != classifyId {
  423. err = data_manage.MoveEdbInfo(edbInfoId, classifyId)
  424. if err != nil {
  425. errMsg = "移动失败"
  426. err = errors.New("移动预测指标失败,Err:" + err.Error())
  427. return
  428. }
  429. }
  430. updateCol := make([]string, 0)
  431. //如果有传入 上一个兄弟节点分类id
  432. if prevEdbInfoId > 0 {
  433. prevEdbInfo, tmpErr := data_manage.GetEdbInfoById(prevEdbInfoId)
  434. if tmpErr != nil {
  435. errMsg = "移动失败"
  436. err = errors.New("获取上一个兄弟节点分类信息失败,Err:" + tmpErr.Error())
  437. return
  438. }
  439. //如果是移动在两个兄弟节点之间
  440. if nextEdbInfoId > 0 {
  441. //下一个兄弟节点
  442. nextEdbInfo, tmpErr := data_manage.GetEdbInfoById(nextEdbInfoId)
  443. if tmpErr != nil {
  444. errMsg = "移动失败"
  445. err = errors.New("获取下一个兄弟节点分类信息失败,Err:" + tmpErr.Error())
  446. return
  447. }
  448. //如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
  449. if prevEdbInfo.Sort == nextEdbInfo.Sort || prevEdbInfo.Sort == edbInfo.Sort {
  450. //变更兄弟节点的排序
  451. updateSortStr := `sort + 2`
  452. _ = data_manage.UpdateEdbInfoSortByClassifyId(prevEdbInfo.ClassifyId, prevEdbInfo.Sort, prevEdbInfo.EdbInfoId, updateSortStr)
  453. } else {
  454. //如果下一个兄弟的排序权重正好是上个兄弟节点 的下一层,那么需要再加一层了
  455. if nextEdbInfo.Sort-prevEdbInfo.Sort == 1 {
  456. //变更兄弟节点的排序
  457. updateSortStr := `sort + 1`
  458. _ = data_manage.UpdateEdbInfoSortByClassifyId(prevEdbInfo.ClassifyId, prevEdbInfo.Sort, prevEdbInfo.EdbInfoId, updateSortStr)
  459. }
  460. }
  461. }
  462. edbInfo.Sort = prevEdbInfo.Sort + 1
  463. edbInfo.ModifyTime = time.Now()
  464. updateCol = append(updateCol, "Sort", "ModifyTime")
  465. } else {
  466. firstClassify, tmpErr := data_manage.GetFirstEdbInfoByClassifyId(classifyId)
  467. if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
  468. errMsg = "移动失败"
  469. err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error())
  470. return
  471. }
  472. //如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
  473. if firstClassify != nil && firstClassify.Sort == 0 {
  474. updateSortStr := ` sort + 1 `
  475. _ = data_manage.UpdateEdbInfoSortByClassifyId(firstClassify.ClassifyId, 0, firstClassify.EdbInfoId-1, updateSortStr)
  476. }
  477. edbInfo.Sort = 0 //那就是排在第一位
  478. edbInfo.ModifyTime = time.Now()
  479. updateCol = append(updateCol, "Sort", "ModifyTime")
  480. }
  481. //更新
  482. if len(updateCol) > 0 {
  483. err = edbInfo.Update(updateCol)
  484. }
  485. if err != nil {
  486. errMsg = "移动失败"
  487. err = errors.New("修改失败,Err:" + err.Error())
  488. return
  489. }
  490. //新增操作日志
  491. {
  492. edbLog := new(data_manage.EdbInfoLog)
  493. edbLog.EdbInfoId = edbInfo.EdbInfoId
  494. edbLog.SourceName = edbInfo.SourceName
  495. edbLog.Source = edbInfo.Source
  496. edbLog.EdbCode = edbInfo.EdbCode
  497. edbLog.EdbName = edbInfo.EdbName
  498. edbLog.ClassifyId = edbInfo.ClassifyId
  499. edbLog.SysUserId = sysUser.AdminId
  500. edbLog.SysUserRealName = sysUser.RealName
  501. edbLog.CreateTime = time.Now()
  502. edbLog.Content = requestBody
  503. edbLog.Status = "移动指标"
  504. edbLog.Method = requestUrl
  505. go data_manage.AddEdbInfoLog(edbLog)
  506. }
  507. return
  508. }
  509. // GetChartPredictEdbInfoDataListByConfList 获取图表的预测指标的未来数据
  510. func GetChartPredictEdbInfoDataListByConfList(predictEdbConfList []data_manage.PredictEdbConfAndData, filtrateStartDateStr, latestDateStr, endDateStr, frequency, dataDateType string, realPredictEdbInfoData []*data_manage.EdbDataList) (predictEdbInfoData []*data_manage.EdbDataList, minValue, maxValue float64, err error, errMsg string) {
  511. endDate, err := time.ParseInLocation(utils.FormatDate, endDateStr, time.Local)
  512. if err != nil {
  513. return
  514. }
  515. latestDate, err := time.ParseInLocation(utils.FormatDate, latestDateStr, time.Local)
  516. if err != nil {
  517. return
  518. }
  519. // 开始预测数据的时间
  520. startDate := latestDate
  521. // 如果有筛选时间的话
  522. if filtrateStartDateStr != `` {
  523. filtrateStartDate, tmpErr := time.ParseInLocation(utils.FormatDate, filtrateStartDateStr, time.Local)
  524. if tmpErr != nil {
  525. err = tmpErr
  526. return
  527. }
  528. //如果筛选时间晚于实际数据时间,那么就以筛选时间作为获取预测数据的时间
  529. if filtrateStartDate.After(latestDate) {
  530. startDate = filtrateStartDate.AddDate(0, 0, -1)
  531. }
  532. }
  533. //var dateArr []string
  534. // 对应日期的值
  535. existMap := make(map[string]float64)
  536. for _, v := range realPredictEdbInfoData {
  537. //dateArr = append(dateArr, v.DataTime)
  538. existMap[v.DataTime] = v.Value
  539. }
  540. predictEdbInfoData = make([]*data_manage.EdbDataList, 0)
  541. //dataValue := lastDataValue
  542. //预测规则,1:最新,2:固定值,3:同比,4:同差,5:环比,6:环差,7:N期移动均值,8:N期段线性外推值
  543. for _, predictEdbConf := range predictEdbConfList {
  544. dataEndTime := endDate
  545. if predictEdbConf.EndDate.Before(dataEndTime) {
  546. dataEndTime = predictEdbConf.EndDate
  547. }
  548. var tmpMinValue, tmpMaxValue float64 // 当前预测结果中的最大/最小值
  549. dayList := getPredictEdbDayList(startDate, dataEndTime, frequency, dataDateType)
  550. if len(dayList) <= 0 { // 如果未来没有日期的话,那么就退出当前循环,进入下一个循环
  551. continue
  552. }
  553. switch predictEdbConf.RuleType {
  554. case 1: //1:最新
  555. var lastDataValue float64 //最新值
  556. tmpAllData := make([]*data_manage.EdbDataList, 0)
  557. tmpAllData = append(tmpAllData, realPredictEdbInfoData...)
  558. tmpAllData = append(tmpAllData, predictEdbInfoData...)
  559. lenTmpAllData := len(tmpAllData)
  560. if lenTmpAllData > 0 {
  561. lastDataValue = tmpAllData[lenTmpAllData-1].Value
  562. }
  563. predictEdbInfoData = GetChartPredictEdbInfoDataListByRule1(predictEdbConf.PredictEdbInfoId, lastDataValue, dayList, predictEdbInfoData, existMap)
  564. tmpMaxValue = lastDataValue
  565. tmpMinValue = lastDataValue
  566. case 2: //2:固定值
  567. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  568. if tmpErr != nil {
  569. err = tmpErr
  570. return
  571. }
  572. dataValue, _ := tmpValDecimal.Float64()
  573. predictEdbInfoData = GetChartPredictEdbInfoDataListByRule1(predictEdbConf.PredictEdbInfoId, dataValue, dayList, predictEdbInfoData, existMap)
  574. tmpMaxValue = dataValue
  575. tmpMinValue = dataValue
  576. case 3: //3:同比
  577. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  578. if tmpErr != nil {
  579. err = tmpErr
  580. return
  581. }
  582. tbValue, _ := tmpValDecimal.Float64()
  583. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleTb(predictEdbConf.PredictEdbInfoId, tbValue, dayList, frequency, realPredictEdbInfoData, predictEdbInfoData, existMap)
  584. case 4: //4:同差
  585. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  586. if tmpErr != nil {
  587. err = tmpErr
  588. return
  589. }
  590. tcValue, _ := tmpValDecimal.Float64()
  591. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleTc(predictEdbConf.PredictEdbInfoId, tcValue, dayList, frequency, realPredictEdbInfoData, predictEdbInfoData, existMap)
  592. case 5: //5:环比
  593. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  594. if tmpErr != nil {
  595. err = tmpErr
  596. return
  597. }
  598. hbValue, _ := tmpValDecimal.Float64()
  599. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleHb(predictEdbConf.PredictEdbInfoId, hbValue, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  600. case 6: //6:环差
  601. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  602. if tmpErr != nil {
  603. err = tmpErr
  604. return
  605. }
  606. hcValue, _ := tmpValDecimal.Float64()
  607. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleHc(predictEdbConf.PredictEdbInfoId, hcValue, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  608. case 7: //7:N期移动均值
  609. nValue, tmpErr := strconv.Atoi(predictEdbConf.Value)
  610. if tmpErr != nil {
  611. err = tmpErr
  612. return
  613. }
  614. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleNMoveMeanValue(predictEdbConf.PredictEdbInfoId, nValue, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  615. case 8: //8:N期段线性外推值
  616. nValue, tmpErr := strconv.Atoi(predictEdbConf.Value)
  617. if tmpErr != nil {
  618. err = tmpErr
  619. return
  620. }
  621. if nValue <= 1 {
  622. errMsg = `N期段线性外推值的N值必须大于1`
  623. err = errors.New(errMsg)
  624. return
  625. }
  626. predictEdbInfoData, tmpMinValue, tmpMaxValue, err = GetChartPredictEdbInfoDataListByRuleNLinearRegression(predictEdbConf.PredictEdbInfoId, nValue, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  627. if err != nil {
  628. return
  629. }
  630. case 9: //9:动态环差”预测规则;
  631. //规则计算的环差值map
  632. hcDataMap := make(map[string]float64)
  633. if predictEdbConf.PredictEdbInfoId > 0 { //已经生成的动态数据
  634. tmpPredictEdbRuleDataList, tmpErr := data_manage.GetPredictEdbRuleDataList(predictEdbConf.PredictEdbInfoId, predictEdbConf.ConfigId, startDate.Format(utils.FormatDate), endDate.Format(utils.FormatDate))
  635. if tmpErr != nil {
  636. err = tmpErr
  637. return
  638. }
  639. for _, v := range tmpPredictEdbRuleDataList {
  640. hcDataMap[v.DataTime] = v.Value
  641. }
  642. } else { //未生成的动态数据,需要使用外部传入的数据进行计算
  643. if len(predictEdbConf.DataList) <= 0 {
  644. return
  645. }
  646. for _, v := range predictEdbConf.DataList {
  647. currentDate, tmpErr := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  648. if tmpErr != nil {
  649. continue
  650. }
  651. // 只处理时间段内的数据
  652. if currentDate.Before(startDate) || currentDate.After(endDate) {
  653. continue
  654. }
  655. hcDataMap[v.DataTime] = v.Value
  656. }
  657. }
  658. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleTrendsHC(predictEdbConf.PredictEdbInfoId, dayList, realPredictEdbInfoData, predictEdbInfoData, hcDataMap, existMap)
  659. case 10: //10:根据 给定终值后插值 规则获取预测数据
  660. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  661. if tmpErr != nil {
  662. err = tmpErr
  663. return
  664. }
  665. finalValue, _ := tmpValDecimal.Float64()
  666. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleFinalValueHc(predictEdbConf.PredictEdbInfoId, finalValue, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  667. case 11: //11:根据 季节性 规则获取预测数据
  668. predictEdbInfoData, tmpMinValue, tmpMaxValue, err = GetChartPredictEdbInfoDataListByRuleSeason(predictEdbConf.PredictEdbInfoId, predictEdbConf.Value, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  669. if err != nil {
  670. return
  671. }
  672. case 12: //12:根据 移动平均同比 规则获取预测数据
  673. var moveAverageConf MoveAverageConf
  674. tmpErr := json.Unmarshal([]byte(predictEdbConf.Value), &moveAverageConf)
  675. if tmpErr != nil {
  676. err = errors.New("季节性配置信息异常:" + tmpErr.Error())
  677. return
  678. }
  679. predictEdbInfoData, tmpMinValue, tmpMaxValue, err = GetChartPredictEdbInfoDataListByRuleMoveAverageTb(predictEdbConf.PredictEdbInfoId, moveAverageConf.NValue, moveAverageConf.Year, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  680. if err != nil {
  681. return
  682. }
  683. case 13: //13:根据 同比增速差值 规则获取预测数据
  684. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  685. if tmpErr != nil {
  686. err = tmpErr
  687. return
  688. }
  689. tbEndValue, _ := tmpValDecimal.Float64()
  690. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleTbzscz(predictEdbConf.PredictEdbInfoId, tbEndValue, dayList, frequency, realPredictEdbInfoData, predictEdbInfoData, existMap)
  691. case 14: //14:根据 一元线性拟合 规则获取预测数据
  692. var ruleConf RuleLineNhConf
  693. err = json.Unmarshal([]byte(predictEdbConf.Value), &ruleConf)
  694. if err != nil {
  695. err = errors.New("一元线性拟合配置信息异常:" + err.Error())
  696. return
  697. }
  698. // 规则计算的拟合残差值map
  699. newNhccDataMap := make(map[string]float64)
  700. if predictEdbConf.PredictEdbInfoId > 0 { //已经生成的动态数据
  701. tmpPredictEdbRuleDataList, tmpErr := data_manage.GetPredictEdbRuleDataList(predictEdbConf.PredictEdbInfoId, predictEdbConf.ConfigId, "", "")
  702. if tmpErr != nil {
  703. err = tmpErr
  704. return
  705. }
  706. for _, v := range tmpPredictEdbRuleDataList {
  707. newNhccDataMap[v.DataTime] = v.Value
  708. }
  709. } else { //未生成的动态数据,需要使用外部传入的数据进行计算
  710. newNhccDataMap, err = getCalculateNhccData(append(realPredictEdbInfoData, predictEdbInfoData...), ruleConf)
  711. if err != nil {
  712. return
  713. }
  714. }
  715. predictEdbInfoData, tmpMinValue, tmpMaxValue, err = GetChartPredictEdbInfoDataListByRuleLineNh(predictEdbConf.PredictEdbInfoId, dayList, realPredictEdbInfoData, predictEdbInfoData, newNhccDataMap, existMap)
  716. if err != nil {
  717. return
  718. }
  719. case 15: //15:N年均值:过去N年同期均值。过去N年可以连续或者不连续,指标数据均用线性插值补全为日度数据后计算;
  720. predictEdbInfoData, tmpMinValue, tmpMaxValue, err = GetChartPredictEdbInfoDataListByRuleNAnnualAverage(predictEdbConf.PredictEdbInfoId, predictEdbConf.Value, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  721. if err != nil {
  722. return
  723. }
  724. case 16: //16:年度值倒推
  725. predictEdbInfoData, tmpMinValue, tmpMaxValue, err = GetChartPredictEdbInfoDataListByRuleAnnualValueInversion(predictEdbConf.PredictEdbInfoId, predictEdbConf.Value, dayList, frequency, realPredictEdbInfoData, predictEdbInfoData, existMap)
  726. if err != nil {
  727. return
  728. }
  729. }
  730. // 下一个规则的开始日期
  731. {
  732. lenPredictEdbInfoData := len(predictEdbInfoData)
  733. if lenPredictEdbInfoData > 0 {
  734. tmpDataEndTime, _ := time.ParseInLocation(utils.FormatDate, predictEdbInfoData[lenPredictEdbInfoData-1].DataTime, time.Local)
  735. if startDate.Before(tmpDataEndTime) {
  736. startDate = tmpDataEndTime
  737. }
  738. }
  739. }
  740. if tmpMinValue < minValue {
  741. minValue = tmpMinValue
  742. }
  743. if tmpMaxValue > maxValue {
  744. maxValue = tmpMaxValue
  745. }
  746. }
  747. return
  748. }
  749. // GetPredictEdbDayList 获取预测指标日期列表
  750. func getPredictEdbDayList(startDate, endDate time.Time, frequency, dataDateType string) (dayList []time.Time) {
  751. //if !utils.InArrayByStr([]string{"日度", "周度", "月度"}, frequency)
  752. if dataDateType == `` {
  753. dataDateType = `交易日`
  754. }
  755. switch frequency {
  756. case "日度":
  757. for currDate := startDate.AddDate(0, 0, 1); currDate.Before(endDate) || currDate.Equal(endDate); currDate = currDate.AddDate(0, 0, 1) {
  758. // 如果日期类型是交易日的时候,那么需要将周六、日排除
  759. if dataDateType == `交易日` && (currDate.Weekday() == time.Sunday || currDate.Weekday() == time.Saturday) {
  760. continue
  761. }
  762. dayList = append(dayList, currDate)
  763. }
  764. case "周度":
  765. //nextDate := startDate.AddDate(0, 0, 7)
  766. for currDate := startDate.AddDate(0, 0, 7); currDate.Before(endDate) || currDate.Equal(endDate); currDate = currDate.AddDate(0, 0, 7) {
  767. dayList = append(dayList, currDate)
  768. }
  769. case "旬度":
  770. for currDate := startDate.AddDate(0, 0, 1); currDate.Before(endDate) || currDate.Equal(endDate); {
  771. nextDate := currDate.AddDate(0, 0, 1)
  772. //每个月的10号、20号、最后一天,那么就写入
  773. if nextDate.Day() == 11 || nextDate.Day() == 21 || nextDate.Day() == 1 {
  774. dayList = append(dayList, currDate)
  775. }
  776. currDate = nextDate
  777. }
  778. case "月度":
  779. for currDate := startDate; currDate.Before(endDate) || currDate.Equal(endDate); {
  780. currDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, time.Now().Location()).AddDate(0, 1, -1)
  781. if !currDate.After(endDate) && !currDate.Equal(startDate) {
  782. dayList = append(dayList, currDate)
  783. }
  784. currDate = currDate.AddDate(0, 0, 1)
  785. }
  786. case "季度":
  787. for currDate := startDate; currDate.Before(endDate) || currDate.Equal(endDate); {
  788. // 每月的最后一天
  789. currDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, time.Now().Location()).AddDate(0, 1, -1)
  790. if !currDate.After(endDate) && !currDate.Equal(startDate) {
  791. // 季度日期就写入,否则不写入
  792. if currDate.Month() == 3 || currDate.Month() == 6 || currDate.Month() == 9 || currDate.Month() == 12 {
  793. dayList = append(dayList, currDate)
  794. }
  795. }
  796. currDate = currDate.AddDate(0, 0, 1)
  797. }
  798. case "半年度":
  799. for currDate := startDate; currDate.Before(endDate) || currDate.Equal(endDate); {
  800. // 每月的最后一天
  801. currDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, time.Now().Location()).AddDate(0, 1, -1)
  802. if !currDate.After(endDate) && !currDate.Equal(startDate) {
  803. // 半年度日期就写入,否则不写入
  804. if currDate.Month() == 6 || currDate.Month() == 12 {
  805. dayList = append(dayList, currDate)
  806. }
  807. }
  808. currDate = currDate.AddDate(0, 0, 1)
  809. }
  810. case "年度":
  811. for currDate := startDate; currDate.Before(endDate) || currDate.Equal(endDate); {
  812. currDate = time.Date(currDate.Year()+1, 12, 31, 0, 0, 0, 0, time.Now().Location())
  813. if !currDate.After(endDate) && !currDate.Equal(startDate) {
  814. dayList = append(dayList, currDate)
  815. }
  816. }
  817. }
  818. return
  819. }
  820. // GetPredictDataListByPredictEdbInfoId 根据预测指标id获取预测指标的数据(日期正序返回)
  821. func GetPredictDataListByPredictEdbInfoId(edbInfoId int, startDate, endDate string, isTimeBetween bool) (edbInfo *data_manage.EdbInfo, dataList []*data_manage.EdbDataList, sourceEdbInfoItem *data_manage.EdbInfo, predictEdbConf *data_manage.PredictEdbConf, err error, errMsg string) {
  822. edbInfo, err = data_manage.GetEdbInfoById(edbInfoId)
  823. if err != nil {
  824. errMsg = `获取预测指标信息失败`
  825. return
  826. }
  827. dataList, sourceEdbInfoItem, predictEdbConf, err, errMsg = GetPredictDataListByPredictEdbInfo(edbInfo, startDate, endDate, isTimeBetween)
  828. return
  829. }
  830. // GetPredictDataListByPredictEdbInfo 根据预测指标信息获取预测指标的数据
  831. func GetPredictDataListByPredictEdbInfo(edbInfo *data_manage.EdbInfo, startDate, endDate string, isTimeBetween bool) (dataList []*data_manage.EdbDataList, sourceEdbInfoItem *data_manage.EdbInfo, predictEdbConf *data_manage.PredictEdbConf, err error, errMsg string) {
  832. // 非计算指标,直接从表里获取数据
  833. if edbInfo.EdbType != 1 {
  834. if !isTimeBetween { //如果不是区间数据,那么就结束日期为空
  835. endDate = ``
  836. }
  837. return GetPredictCalculateDataListByPredictEdbInfo(edbInfo, startDate, endDate)
  838. }
  839. // 查找该预测指标配置
  840. predictEdbConfList, err := data_manage.GetPredictEdbConfListById(edbInfo.EdbInfoId)
  841. if err != nil && err.Error() != utils.ErrNoRow() {
  842. errMsg = "获取预测指标配置信息失败"
  843. return
  844. }
  845. if len(predictEdbConfList) == 0 {
  846. errMsg = "获取预测指标配置信息失败"
  847. err = errors.New(errMsg)
  848. return
  849. }
  850. predictEdbConf = predictEdbConfList[0]
  851. // 来源指标
  852. sourceEdbInfoItem, err = data_manage.GetEdbInfoById(predictEdbConf.SourceEdbInfoId)
  853. if err != nil {
  854. if err.Error() == utils.ErrNoRow() {
  855. errMsg = "找不到来源指标信息"
  856. err = errors.New(errMsg)
  857. }
  858. return
  859. }
  860. allDataList := make([]*data_manage.EdbDataList, 0)
  861. //获取指标数据(实际已生成)
  862. dataList, err = data_manage.GetEdbDataList(sourceEdbInfoItem.Source, sourceEdbInfoItem.SubSource, sourceEdbInfoItem.EdbInfoId, startDate, endDate)
  863. if err != nil {
  864. return
  865. }
  866. // 如果选择了日期,那么需要筛选所有的数据,用于未来指标的生成
  867. if startDate != `` {
  868. allDataList, err = data_manage.GetEdbDataList(sourceEdbInfoItem.Source, sourceEdbInfoItem.SubSource, sourceEdbInfoItem.EdbInfoId, "", "")
  869. if err != nil {
  870. return
  871. }
  872. } else {
  873. allDataList = dataList
  874. }
  875. // 获取预测指标未来的数据
  876. predictDataList := make([]*data_manage.EdbDataList, 0)
  877. endDateStr := edbInfo.EndDate //预测指标的结束日期
  878. if isTimeBetween && endDate != `` { //如果是时间区间,同时截止日期不为空的情况,那么
  879. reqEndDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  880. endDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.EndDate, time.Local)
  881. // 如果选择的时间区间结束日期 晚于 当天,那么预测数据截止到当天
  882. if reqEndDateTime.Before(endDateTime) {
  883. endDateStr = endDate
  884. }
  885. }
  886. //predictDataList, err = GetChartPredictEdbInfoDataList(*predictEdbConf, startDate, sourceEdbInfoItem.LatestDate, sourceEdbInfoItem.LatestValue, endDateStr, edbInfo.Frequency)
  887. predictEdbConfDataList := make([]data_manage.PredictEdbConfAndData, 0)
  888. for _, v := range predictEdbConfList {
  889. predictEdbConfDataList = append(predictEdbConfDataList, data_manage.PredictEdbConfAndData{
  890. ConfigId: v.ConfigId,
  891. PredictEdbInfoId: v.PredictEdbInfoId,
  892. SourceEdbInfoId: v.SourceEdbInfoId,
  893. RuleType: v.RuleType,
  894. FixedValue: v.FixedValue,
  895. Value: v.Value,
  896. EndDate: v.EndDate,
  897. ModifyTime: v.ModifyTime,
  898. CreateTime: v.CreateTime,
  899. DataList: make([]*data_manage.EdbDataList, 0),
  900. })
  901. }
  902. //var predictMinValue, predictMaxValue float64
  903. predictDataList, _, _, err, _ = GetChartPredictEdbInfoDataListByConfList(predictEdbConfDataList, startDate, sourceEdbInfoItem.LatestDate, endDateStr, edbInfo.Frequency, edbInfo.DataDateType, allDataList)
  904. if err != nil {
  905. return
  906. }
  907. dataList = append(dataList, predictDataList...)
  908. //if len(predictDataList) > 0 {
  909. // // 如果最小值 大于 预测值,那么将预测值作为最小值数据返回
  910. // if edbInfo.MinValue > predictMinValue {
  911. // edbInfo.MinValue = predictMinValue
  912. // }
  913. //
  914. // // 如果最大值 小于 预测值,那么将预测值作为最大值数据返回
  915. // if edbInfo.MaxValue < predictMaxValue {
  916. // edbInfo.MaxValue = predictMaxValue
  917. // }
  918. //}
  919. return
  920. }
  921. // GetChartDataList 通过完整的预测数据 进行 季节性图、公历、农历处理
  922. func GetChartDataList(dataList []*data_manage.EdbDataList, chartType int, calendar, latestDateStr, startDate string) (resultDataList interface{}, err error) {
  923. startDateReal := startDate
  924. calendarPreYear := 0
  925. if calendar == "农历" {
  926. newStartDateReal, err := time.Parse(utils.FormatDate, startDateReal)
  927. if err != nil {
  928. fmt.Println("time.Parse:" + err.Error())
  929. }
  930. calendarPreYear = newStartDateReal.Year() - 1
  931. newStartDateReal = newStartDateReal.AddDate(-1, 0, 0)
  932. startDateReal = newStartDateReal.Format(utils.FormatDate)
  933. }
  934. //实际数据的截止日期
  935. latestDate, tmpErr := time.Parse(utils.FormatDate, latestDateStr)
  936. if tmpErr != nil {
  937. err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + latestDateStr))
  938. return
  939. }
  940. latestDateYear := latestDate.Year() //实际数据截止年份
  941. // 曲线图
  942. if chartType == 1 {
  943. resultDataList = dataList
  944. return
  945. }
  946. if calendar == "农历" {
  947. if len(dataList) <= 0 {
  948. resultDataList = data_manage.EdbDataResult{}
  949. } else {
  950. result, tmpErr := data_manage.AddCalculateQuarterV4(dataList)
  951. if tmpErr != nil {
  952. err = errors.New("获取农历数据失败,Err:" + tmpErr.Error())
  953. return
  954. }
  955. // 处理季节图的截止日期
  956. for k, edbDataItems := range result.List {
  957. var cuttingDataTimestamp int64
  958. // 切割的日期时间字符串
  959. cuttingDataTimeStr := latestDate.AddDate(0, 0, edbDataItems.BetweenDay).Format(utils.FormatDate)
  960. //如果等于最后的实际日期,那么遍历找到该日期对应的时间戳,并将其赋值为 切割时间戳
  961. if edbDataItems.Year >= latestDateYear {
  962. for _, tmpData := range edbDataItems.Items {
  963. if tmpData.DataTime == cuttingDataTimeStr {
  964. cuttingDataTimestamp = tmpData.DataTimestamp
  965. break
  966. }
  967. }
  968. }
  969. edbDataItems.CuttingDataTimestamp = cuttingDataTimestamp
  970. result.List[k] = edbDataItems
  971. }
  972. if result.List[0].Year != calendarPreYear {
  973. itemList := make([]*data_manage.EdbDataList, 0)
  974. items := new(data_manage.EdbDataItems)
  975. //items.Year = calendarPreYear
  976. items.Items = itemList
  977. newResult := new(data_manage.EdbDataResult)
  978. newResult.List = append(newResult.List, items)
  979. newResult.List = append(newResult.List, result.List...)
  980. resultDataList = newResult
  981. } else {
  982. resultDataList = result
  983. }
  984. }
  985. } else {
  986. currentYear := time.Now().Year()
  987. quarterDataList := make([]*data_manage.QuarterData, 0)
  988. quarterMap := make(map[int][]*data_manage.EdbDataList)
  989. var quarterArr []int
  990. for _, v := range dataList {
  991. itemDate, tmpErr := time.Parse(utils.FormatDate, v.DataTime)
  992. if tmpErr != nil {
  993. err = errors.New("季度指标日期转换,Err:" + tmpErr.Error() + ";DataTime:" + v.DataTime)
  994. return
  995. }
  996. year := itemDate.Year()
  997. newItemDate := itemDate.AddDate(currentYear-year, 0, 0)
  998. timestamp := newItemDate.UnixNano() / 1e6
  999. v.DataTimestamp = timestamp
  1000. if findVal, ok := quarterMap[year]; !ok {
  1001. quarterArr = append(quarterArr, year)
  1002. findVal = append(findVal, v)
  1003. quarterMap[year] = findVal
  1004. } else {
  1005. findVal = append(findVal, v)
  1006. quarterMap[year] = findVal
  1007. }
  1008. }
  1009. for _, v := range quarterArr {
  1010. itemList := quarterMap[v]
  1011. quarterItem := new(data_manage.QuarterData)
  1012. quarterItem.Year = v
  1013. quarterItem.DataList = itemList
  1014. //如果等于最后的实际日期,那么将切割时间戳记录
  1015. if v == latestDateYear {
  1016. var cuttingDataTimestamp int64
  1017. for _, tmpData := range itemList {
  1018. if tmpData.DataTime == latestDateStr {
  1019. cuttingDataTimestamp = tmpData.DataTimestamp
  1020. break
  1021. }
  1022. }
  1023. quarterItem.CuttingDataTimestamp = cuttingDataTimestamp
  1024. } else if v > latestDateYear {
  1025. //如果大于最后的实际日期,那么第一个点就是切割的时间戳
  1026. if len(itemList) > 0 {
  1027. quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
  1028. }
  1029. }
  1030. quarterDataList = append(quarterDataList, quarterItem)
  1031. }
  1032. resultDataList = quarterDataList
  1033. }
  1034. return
  1035. }
  1036. // GetPredictCalculateDataListByPredictEdbInfo 根据预测运算指标信息获取预测指标的数据
  1037. func GetPredictCalculateDataListByPredictEdbInfo(edbInfo *data_manage.EdbInfo, startDate, endDate string) (dataList []*data_manage.EdbDataList, sourceEdbInfoItem *data_manage.EdbInfo, predictEdbConf *data_manage.PredictEdbConf, err error, errMsg string) {
  1038. dataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, startDate, endDate)
  1039. return
  1040. }
  1041. // ModifyPredictEdbBaseInfoBySourceEdb 根据来源ETA指标修改预测指标的基础信息
  1042. func ModifyPredictEdbBaseInfoBySourceEdb(sourceEDdbInfo *data_manage.EdbInfo, frequency, unit string) {
  1043. list, err := data_manage.GetGroupPredictEdbBySourceEdbInfoId(sourceEDdbInfo.EdbInfoId)
  1044. if err != nil {
  1045. return
  1046. }
  1047. for _, v := range list {
  1048. v.Frequency = frequency
  1049. v.Unit = unit
  1050. v.Update([]string{"Frequency", "Unit"})
  1051. AddOrEditEdbInfoToEs(v.EdbInfoId)
  1052. }
  1053. }
  1054. // ModifyPredictEdbEnBaseInfoBySourceEdb 根据来源ETA指标修改预测指标的英文基础信息
  1055. func ModifyPredictEdbEnBaseInfoBySourceEdb(sourceEDdbInfo *data_manage.EdbInfo, unitEn string) {
  1056. list, err := data_manage.GetGroupPredictEdbBySourceEdbInfoId(sourceEDdbInfo.EdbInfoId)
  1057. if err != nil {
  1058. return
  1059. }
  1060. for _, v := range list {
  1061. v.UnitEn = unitEn
  1062. v.Update([]string{"UnitEn"})
  1063. AddOrEditEdbInfoToEs(v.EdbInfoId)
  1064. }
  1065. }
  1066. // ModifyPredictEdbUnitBySourceEdbInfoId
  1067. // @Description: 根据来源ETA指标修改预测指标的频度和单位基础信息
  1068. // @author: Roc
  1069. // @datetime 2024-01-05 11:07:39
  1070. // @param sourceEdbInfoId int
  1071. // @param frequency string
  1072. // @param unit string
  1073. // @return err error
  1074. func ModifyPredictEdbUnitBySourceEdbInfoId(sourceEdbInfoId int, frequency, unit string) (err error) {
  1075. list, err := data_manage.GetGroupPredictEdbBySourceEdbInfoId(sourceEdbInfoId)
  1076. if err != nil {
  1077. return
  1078. }
  1079. for _, v := range list {
  1080. v.Frequency = frequency
  1081. v.Unit = unit
  1082. v.Update([]string{"Frequency", "Unit"})
  1083. AddOrEditEdbInfoToEs(v.EdbInfoId)
  1084. }
  1085. return
  1086. }