predict_edb.go 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. package logic
  2. import (
  3. "errors"
  4. "hongze/hongze_edb_lib/models"
  5. "hongze/hongze_edb_lib/services"
  6. "hongze/hongze_edb_lib/utils"
  7. "strconv"
  8. "strings"
  9. "time"
  10. )
  11. // AddPredictEdbInfo 新增预测指标
  12. func AddPredictEdbInfo(sourceEdbInfoId, classifyId int, edbName string, ruleList []models.RuleConfig, sysUserId int, sysUserName string) (edbInfo *models.EdbInfo, err error, errMsg string) {
  13. var sourceEdbInfo *models.EdbInfo
  14. // 来源指标信息校验
  15. {
  16. sourceEdbInfo, err = models.GetEdbInfoById(sourceEdbInfoId)
  17. if err != nil && err.Error() != utils.ErrNoRow() {
  18. errMsg = "新增失败"
  19. err = errors.New("获取来源指标失败,Err:" + err.Error())
  20. return
  21. }
  22. if sourceEdbInfo == nil {
  23. errMsg = "找不到该来源指标"
  24. err = errors.New(errMsg)
  25. return
  26. }
  27. //必须是普通的指标
  28. if sourceEdbInfo.EdbInfoType != 0 {
  29. errMsg = "来源指标异常,不是普通的指标"
  30. err = errors.New(errMsg)
  31. return
  32. }
  33. if !utils.InArrayByStr([]string{"日度", "周度", "月度", "年度"}, sourceEdbInfo.Frequency) {
  34. errMsg = "预测指标只支持选择日度、周度、月度、年度的指标"
  35. err = errors.New(errMsg)
  36. return
  37. }
  38. }
  39. var classifyInfo *models.EdbClassify
  40. // 来源分类信息校验
  41. {
  42. classifyInfo, err = models.GetEdbClassifyById(classifyId)
  43. if err != nil && err.Error() != utils.ErrNoRow() {
  44. errMsg = "新增失败"
  45. err = errors.New("获取预测指标分类失败,Err:" + err.Error())
  46. return
  47. }
  48. if classifyInfo == nil {
  49. errMsg = "找不到该预测指标分类"
  50. err = errors.New(errMsg)
  51. return
  52. }
  53. //必须是预测指标分类
  54. if classifyInfo.ClassifyType != 1 {
  55. errMsg = "预测指标分类异常,不是预测指标分类"
  56. err = errors.New(errMsg)
  57. return
  58. }
  59. }
  60. edbName = strings.Trim(edbName, " ")
  61. edbCode := sourceEdbInfo.EdbCode + "_" + time.Now().Format(utils.FormatShortDateTimeUnSpace)
  62. //判断指标名称是否存在
  63. var condition string
  64. var pars []interface{}
  65. condition += " AND edb_info_type=? "
  66. pars = append(pars, 1)
  67. condition += " AND edb_name=? "
  68. pars = append(pars, edbName)
  69. count, err := models.GetEdbInfoCountByCondition(condition, pars)
  70. if err != nil {
  71. errMsg = "判断指标名称是否存在失败"
  72. err = errors.New("判断指标名称是否存在失败,Err:" + err.Error())
  73. return
  74. }
  75. if count > 0 {
  76. errMsg = "指标名称已存在,请重新填写"
  77. err = errors.New(errMsg)
  78. return
  79. }
  80. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  81. edbInfo = &models.EdbInfo{
  82. //EdbInfoId: 0,
  83. EdbInfoType: 1,
  84. SourceName: "预测指标",
  85. Source: utils.DATA_SOURCE_PREDICT,
  86. EdbCode: edbCode,
  87. EdbName: edbName,
  88. EdbNameSource: edbName,
  89. Frequency: sourceEdbInfo.Frequency,
  90. Unit: sourceEdbInfo.Unit,
  91. StartDate: sourceEdbInfo.StartDate,
  92. ClassifyId: classifyId,
  93. SysUserId: sysUserId,
  94. SysUserRealName: sysUserName,
  95. UniqueCode: utils.MD5(utils.DATA_PREFIX + "_" + timestamp),
  96. CreateTime: time.Now(),
  97. ModifyTime: time.Now(),
  98. MinValue: sourceEdbInfo.MinValue,
  99. MaxValue: sourceEdbInfo.MaxValue,
  100. CalculateFormula: sourceEdbInfo.CalculateFormula,
  101. EdbType: 1,
  102. //Sort: sourceEdbInfo.,
  103. LatestDate: sourceEdbInfo.LatestDate,
  104. LatestValue: sourceEdbInfo.LatestValue,
  105. MoveType: sourceEdbInfo.MoveType,
  106. MoveFrequency: sourceEdbInfo.MoveFrequency,
  107. NoUpdate: sourceEdbInfo.NoUpdate,
  108. ServerUrl: "",
  109. }
  110. // 关联关系表
  111. calculateMappingList := make([]*models.EdbInfoCalculateMapping, 0)
  112. fromEdbMap := make(map[int]int)
  113. // 源指标关联关系表
  114. calculateMappingItem := &models.EdbInfoCalculateMapping{
  115. //EdbInfoCalculateMappingId: 0,
  116. //EdbInfoId: 0,
  117. Source: edbInfo.Source,
  118. SourceName: edbInfo.SourceName,
  119. EdbCode: edbInfo.EdbCode,
  120. FromEdbInfoId: sourceEdbInfo.EdbInfoId,
  121. FromEdbCode: sourceEdbInfo.EdbCode,
  122. FromEdbName: sourceEdbInfo.EdbName,
  123. FromSource: sourceEdbInfo.Source,
  124. FromSourceName: sourceEdbInfo.SourceName,
  125. //FromTag: "",
  126. Sort: 1,
  127. CreateTime: time.Now(),
  128. ModifyTime: time.Now(),
  129. }
  130. fromEdbMap[sourceEdbInfoId] = sourceEdbInfoId
  131. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  132. // 动态环差 计算列表
  133. calculateRuleMap := make(map[int]models.CalculateRule, 0)
  134. // 预测指标配置
  135. predictEdbConfList := make([]*models.PredictEdbConf, 0)
  136. for ruleIndex, v := range ruleList {
  137. // 预测指标配置
  138. ruleEndDate, tmpErr := time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
  139. if tmpErr != nil {
  140. errMsg = "规则配置的截止日期异常,请重新填写"
  141. err = errors.New(errMsg)
  142. return
  143. }
  144. //1:最新,2:固定值,3:同比,4:同差,5:环比,6:环差,7:N期移动均值,8:N期段线性外推值,9:动态环差,10:根据 给定终值后插值 规则获取预测数据,11:根据 季节性 规则获取预测数据,12:根据 移动平均同比 规则获取预测数据
  145. // 环比、环差、动态环差、季节性、移动平均同比不支持年度
  146. if sourceEdbInfo.Frequency == "年度" && utils.InArrayByInt([]int{5, 6, 11, 12}, v.RuleType) {
  147. errMsg = "环比、环差、动态环差、季节性、移动平均同比不支持年度指标"
  148. err = errors.New(errMsg)
  149. return
  150. }
  151. switch v.RuleType {
  152. case 8: //N期段线性外推值
  153. valInt, tmpErr := strconv.Atoi(v.Value)
  154. if tmpErr != nil {
  155. errMsg = "N期段线性外推值的N值异常"
  156. err = errors.New(errMsg)
  157. return
  158. }
  159. if valInt <= 1 {
  160. errMsg = "N期段线性外推值的N值必须大于1"
  161. err = errors.New(errMsg)
  162. return
  163. }
  164. case 9: //9:动态环差
  165. if v.Value == "" {
  166. errMsg = "请填写计算规则"
  167. err = errors.New(errMsg)
  168. return
  169. }
  170. formula := v.Value
  171. formula = strings.Replace(formula, "(", "(", -1)
  172. formula = strings.Replace(formula, ")", ")", -1)
  173. formula = strings.Replace(formula, ",", ",", -1)
  174. formula = strings.Replace(formula, "。", ".", -1)
  175. formula = strings.Replace(formula, "%", "*0.01", -1)
  176. v.Value = formula
  177. //检验公式
  178. var formulaStr string
  179. var edbInfoIdBytes []string
  180. for _, tmpEdbInfoId := range v.EdbInfoIdArr {
  181. formulaStr += tmpEdbInfoId.FromTag + ","
  182. edbInfoIdBytes = append(edbInfoIdBytes, tmpEdbInfoId.FromTag)
  183. }
  184. formulaMap := services.CheckFormula(formula)
  185. for _, formula := range formulaMap {
  186. if !strings.Contains(formulaStr, formula) {
  187. errMsg = "公式错误,请重新填写"
  188. err = errors.New(errMsg)
  189. return
  190. }
  191. }
  192. //关联的指标信息
  193. edbInfoList := make([]*models.EdbInfo, 0)
  194. // 动态环差规则 关系表
  195. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  196. for k, tmpEdbInfoId := range v.EdbInfoIdArr {
  197. fromEdbInfo, tmpErr := models.GetEdbInfoById(tmpEdbInfoId.EdbInfoId)
  198. if tmpErr != nil {
  199. err = tmpErr
  200. if err.Error() == utils.ErrNoRow() {
  201. errMsg = "指标 " + strconv.Itoa(tmpEdbInfoId.EdbInfoId) + " 不存在"
  202. err = errors.New(errMsg)
  203. return
  204. }
  205. errMsg = "获取指标失败:Err:" + err.Error()
  206. err = errors.New(errMsg)
  207. return
  208. }
  209. edbInfoList = append(edbInfoList, fromEdbInfo)
  210. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  211. {
  212. if _, ok := fromEdbMap[tmpEdbInfoId.EdbInfoId]; !ok {
  213. fromEdbMap[tmpEdbInfoId.EdbInfoId] = tmpEdbInfoId.EdbInfoId
  214. calculateMappingItem := &models.EdbInfoCalculateMapping{
  215. EdbInfoCalculateMappingId: 0,
  216. EdbInfoId: 0,
  217. Source: utils.DATA_SOURCE_CALCULATE,
  218. SourceName: "指标运算",
  219. EdbCode: "",
  220. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  221. FromEdbCode: fromEdbInfo.EdbCode,
  222. FromEdbName: fromEdbInfo.EdbName,
  223. FromSource: fromEdbInfo.Source,
  224. FromSourceName: fromEdbInfo.SourceName,
  225. //FromTag: tmpEdbInfoId.FromTag,
  226. Sort: k + 1,
  227. CreateTime: time.Now(),
  228. ModifyTime: time.Now(),
  229. }
  230. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  231. }
  232. }
  233. // 动态环差规则 关系表
  234. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  235. //PredictEdbConfCalculateMappingId: 0,
  236. EdbInfoId: 0,
  237. ConfigId: 0,
  238. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  239. FromEdbCode: fromEdbInfo.EdbCode,
  240. FromEdbName: fromEdbInfo.EdbName,
  241. FromSource: fromEdbInfo.Source,
  242. FromSourceName: fromEdbInfo.SourceName,
  243. FromTag: tmpEdbInfoId.FromTag,
  244. Sort: k + 1,
  245. CreateTime: time.Now(),
  246. ModifyTime: time.Now(),
  247. }
  248. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  249. }
  250. ok, _ := models.CheckFormula2(edbInfoList, formulaMap, formula, edbInfoIdBytes)
  251. if !ok {
  252. errMsg = "生成计算指标失败,请使用正确的计算公式"
  253. err = errors.New(errMsg)
  254. return
  255. }
  256. calculateRuleMap[ruleIndex] = models.CalculateRule{
  257. TrendsCalculateMappingList: trendsMappingList,
  258. EdbInfoList: edbInfoList,
  259. EdbInfoIdBytes: edbInfoIdBytes,
  260. Formula: formula,
  261. RuleType: v.RuleType,
  262. EndDate: v.EndDate,
  263. EdbInfoIdArr: v.EdbInfoIdArr,
  264. }
  265. case 14: //14:根据 一元线性拟合 规则获取预测数据
  266. if v.Value == "" {
  267. errMsg = "请填写一元线性拟合规则"
  268. err = errors.New(errMsg)
  269. return
  270. }
  271. //关联的指标信息
  272. edbInfoList := make([]*models.EdbInfo, 0)
  273. // 动态环差规则 关系表
  274. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  275. for k, tmpEdbInfoId := range v.EdbInfoIdArr {
  276. fromEdbInfo, tmpErr := models.GetEdbInfoById(tmpEdbInfoId.EdbInfoId)
  277. if tmpErr != nil {
  278. err = tmpErr
  279. if err.Error() == utils.ErrNoRow() {
  280. errMsg = "指标 " + strconv.Itoa(tmpEdbInfoId.EdbInfoId) + " 不存在"
  281. err = errors.New(errMsg)
  282. return
  283. }
  284. errMsg = "获取指标失败:Err:" + err.Error()
  285. err = errors.New(errMsg)
  286. return
  287. }
  288. edbInfoList = append(edbInfoList, fromEdbInfo)
  289. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  290. {
  291. if _, ok := fromEdbMap[tmpEdbInfoId.EdbInfoId]; !ok {
  292. fromEdbMap[tmpEdbInfoId.EdbInfoId] = tmpEdbInfoId.EdbInfoId
  293. tmpCalculateMappingItem := &models.EdbInfoCalculateMapping{
  294. EdbInfoCalculateMappingId: 0,
  295. EdbInfoId: 0,
  296. Source: utils.DATA_SOURCE_CALCULATE,
  297. SourceName: "指标运算",
  298. EdbCode: "",
  299. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  300. FromEdbCode: fromEdbInfo.EdbCode,
  301. FromEdbName: fromEdbInfo.EdbName,
  302. FromSource: fromEdbInfo.Source,
  303. FromSourceName: fromEdbInfo.SourceName,
  304. //FromTag: tmpEdbInfoId.FromTag,
  305. Sort: k + 1,
  306. CreateTime: time.Now(),
  307. ModifyTime: time.Now(),
  308. }
  309. calculateMappingList = append(calculateMappingList, tmpCalculateMappingItem)
  310. }
  311. }
  312. // 动态环差规则 关系表
  313. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  314. //PredictEdbConfCalculateMappingId: 0,
  315. EdbInfoId: 0,
  316. ConfigId: 0,
  317. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  318. FromEdbCode: fromEdbInfo.EdbCode,
  319. FromEdbName: fromEdbInfo.EdbName,
  320. FromSource: fromEdbInfo.Source,
  321. FromSourceName: fromEdbInfo.SourceName,
  322. FromTag: tmpEdbInfoId.FromTag,
  323. Sort: k + 1,
  324. CreateTime: time.Now(),
  325. ModifyTime: time.Now(),
  326. }
  327. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  328. }
  329. calculateRuleMap[ruleIndex] = models.CalculateRule{
  330. TrendsCalculateMappingList: trendsMappingList,
  331. EdbInfoList: edbInfoList,
  332. //EdbInfoIdBytes: edbInfoIdBytes,
  333. //Formula: formula,
  334. RuleType: v.RuleType,
  335. EndDate: v.EndDate,
  336. EdbInfoIdArr: v.EdbInfoIdArr,
  337. }
  338. }
  339. tmpPredictEdbConf := &models.PredictEdbConf{
  340. PredictEdbInfoId: 0,
  341. SourceEdbInfoId: sourceEdbInfoId,
  342. RuleType: v.RuleType,
  343. //FixedValue: v.Value,
  344. Value: v.Value,
  345. EndDate: ruleEndDate,
  346. ModifyTime: time.Now(),
  347. CreateTime: time.Now(),
  348. }
  349. edbInfo.EndDate = v.EndDate
  350. predictEdbConfList = append(predictEdbConfList, tmpPredictEdbConf)
  351. }
  352. err, errMsg = models.AddPredictEdb(edbInfo, calculateMappingList, predictEdbConfList, calculateRuleMap)
  353. return
  354. }
  355. // EditPredictEdbInfo 编辑预测指标
  356. func EditPredictEdbInfo(edbInfoId, classifyId int, edbName string, ruleList []models.RuleConfig) (edbInfo *models.EdbInfo, err error, errMsg string) {
  357. // 指标信息校验
  358. {
  359. edbInfo, err = models.GetEdbInfoById(edbInfoId)
  360. if err != nil && err.Error() != utils.ErrNoRow() {
  361. errMsg = "修改失败"
  362. err = errors.New("获取预测指标失败,Err:" + err.Error())
  363. return
  364. }
  365. if edbInfo == nil {
  366. errMsg = "找不到该预测指标"
  367. err = errors.New(errMsg)
  368. return
  369. }
  370. //必须是普通的指标
  371. if edbInfo.EdbInfoType != 1 {
  372. errMsg = "指标异常,不是预测指标"
  373. err = errors.New(errMsg)
  374. return
  375. }
  376. }
  377. var predictEdbConf *models.PredictEdbConf
  378. // 指标配置信息校验
  379. {
  380. // 查找该预测指标配置
  381. predictEdbConfList, tmpErr := models.GetPredictEdbConfListById(edbInfo.EdbInfoId)
  382. if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
  383. errMsg = "修改失败"
  384. err = errors.New("获取预测指标配置信息失败,Err:" + tmpErr.Error())
  385. return
  386. }
  387. if len(predictEdbConfList) == 0 {
  388. errMsg = "找不到该预测指标配置"
  389. err = errors.New(errMsg)
  390. return
  391. }
  392. predictEdbConf = predictEdbConfList[0]
  393. }
  394. //判断指标名称是否存在
  395. var condition string
  396. var pars []interface{}
  397. condition += " AND edb_info_id<>? "
  398. pars = append(pars, edbInfoId)
  399. condition += " AND edb_info_type=? "
  400. pars = append(pars, 1)
  401. condition += " AND edb_name=? "
  402. pars = append(pars, edbName)
  403. count, err := models.GetEdbInfoCountByCondition(condition, pars)
  404. if err != nil {
  405. errMsg = "判断指标名称是否存在失败"
  406. err = errors.New("判断指标名称是否存在失败,Err:" + err.Error())
  407. return
  408. }
  409. if count > 0 {
  410. errMsg = "指标名称已存在,请重新填写"
  411. err = errors.New(errMsg)
  412. return
  413. }
  414. edbInfo.EdbName = edbName
  415. edbInfo.EdbNameSource = edbName
  416. edbInfo.ClassifyId = classifyId
  417. edbInfo.ModifyTime = time.Now()
  418. updateEdbInfoCol := []string{"EdbName", "EdbNameSource", "ClassifyId", "EndDate", "ModifyTime"}
  419. var sourceEdbInfo *models.EdbInfo
  420. // 来源指标信息校验
  421. {
  422. sourceEdbInfo, err = models.GetEdbInfoById(predictEdbConf.SourceEdbInfoId)
  423. if err != nil && err.Error() != utils.ErrNoRow() {
  424. errMsg = "新增失败"
  425. err = errors.New("获取来源指标失败,Err:" + err.Error())
  426. return
  427. }
  428. if sourceEdbInfo == nil {
  429. errMsg = "找不到该来源指标"
  430. err = errors.New(errMsg)
  431. return
  432. }
  433. //必须是普通的指标
  434. if sourceEdbInfo.EdbInfoType != 0 {
  435. errMsg = "来源指标异常,不是普通的指标"
  436. err = errors.New(errMsg)
  437. return
  438. }
  439. if !utils.InArrayByStr([]string{"日度", "周度", "月度", "年度"}, sourceEdbInfo.Frequency) {
  440. errMsg = "预测指标只支持选择日度、周度、月度、年度的指标"
  441. err = errors.New(errMsg)
  442. return
  443. }
  444. }
  445. // 预测指标配置
  446. // 关联关系表
  447. calculateMappingList := make([]*models.EdbInfoCalculateMapping, 0)
  448. fromEdbMap := make(map[int]int)
  449. // 源指标关联关系表
  450. calculateMappingItem := &models.EdbInfoCalculateMapping{
  451. //EdbInfoCalculateMappingId: 0,
  452. EdbInfoId: edbInfoId,
  453. Source: edbInfo.Source,
  454. SourceName: edbInfo.SourceName,
  455. EdbCode: edbInfo.EdbCode,
  456. FromEdbInfoId: sourceEdbInfo.EdbInfoId,
  457. FromEdbCode: sourceEdbInfo.EdbCode,
  458. FromEdbName: sourceEdbInfo.EdbName,
  459. FromSource: sourceEdbInfo.Source,
  460. FromSourceName: sourceEdbInfo.SourceName,
  461. //FromTag: "",
  462. Sort: 1,
  463. CreateTime: time.Now(),
  464. ModifyTime: time.Now(),
  465. }
  466. fromEdbMap[sourceEdbInfo.EdbInfoId] = sourceEdbInfo.EdbInfoId
  467. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  468. // 动态环差 计算列表
  469. calculateRuleMap := make(map[int]models.CalculateRule, 0)
  470. // 预测指标配置
  471. predictEdbConfList := make([]*models.PredictEdbConf, 0)
  472. for ruleIndex, v := range ruleList {
  473. // 预测指标配置
  474. ruleEndDate, tmpErr := time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
  475. if tmpErr != nil {
  476. errMsg = "规则配置的截止日期异常,请重新填写"
  477. err = errors.New(errMsg)
  478. return
  479. }
  480. //1:最新,2:固定值,3:同比,4:同差,5:环比,6:环差,7:N期移动均值,8:N期段线性外推值,9:动态环差,10:根据 给定终值后插值 规则获取预测数据,11:根据 季节性 规则获取预测数据,12:根据 移动平均同比 规则获取预测数据
  481. // 环比、环差、动态环差、季节性、移动平均同比不支持年度
  482. if sourceEdbInfo.Frequency == "年度" && utils.InArrayByInt([]int{5, 6, 11, 12}, v.RuleType) {
  483. errMsg = "环比、环差、动态环差、季节性、移动平均同比不支持年度指标"
  484. err = errors.New(errMsg)
  485. return
  486. }
  487. switch v.RuleType {
  488. case 8: //N期段线性外推值
  489. valInt, tmpErr := strconv.Atoi(v.Value)
  490. if tmpErr != nil {
  491. errMsg = "N期段线性外推值的N值异常"
  492. err = errors.New(errMsg)
  493. return
  494. }
  495. if valInt <= 1 {
  496. errMsg = "N期段线性外推值的N值必须大于1"
  497. err = errors.New(errMsg)
  498. return
  499. }
  500. case 9: //9:动态环差
  501. if v.Value == "" {
  502. errMsg = "请填写计算规则"
  503. err = errors.New(errMsg)
  504. return
  505. }
  506. formula := v.Value
  507. formula = strings.Replace(formula, "(", "(", -1)
  508. formula = strings.Replace(formula, ")", ")", -1)
  509. formula = strings.Replace(formula, ",", ",", -1)
  510. formula = strings.Replace(formula, "。", ".", -1)
  511. formula = strings.Replace(formula, "%", "*0.01", -1)
  512. v.Value = formula
  513. //检验公式
  514. var formulaStr string
  515. var edbInfoIdBytes []string
  516. for _, tmpEdbInfoId := range v.EdbInfoIdArr {
  517. formulaStr += tmpEdbInfoId.FromTag + ","
  518. edbInfoIdBytes = append(edbInfoIdBytes, tmpEdbInfoId.FromTag)
  519. }
  520. formulaMap := services.CheckFormula(formula)
  521. for _, formula := range formulaMap {
  522. if !strings.Contains(formulaStr, formula) {
  523. errMsg = "公式错误,请重新填写"
  524. err = errors.New(errMsg)
  525. return
  526. }
  527. }
  528. //关联的指标信息
  529. edbInfoList := make([]*models.EdbInfo, 0)
  530. // 动态环差规则 关系表
  531. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  532. for k, tmpEdbInfoId := range v.EdbInfoIdArr {
  533. fromEdbInfo, tmpErr := models.GetEdbInfoById(tmpEdbInfoId.EdbInfoId)
  534. if tmpErr != nil {
  535. err = tmpErr
  536. if err.Error() == utils.ErrNoRow() {
  537. errMsg = "指标 " + strconv.Itoa(tmpEdbInfoId.EdbInfoId) + " 不存在"
  538. err = errors.New(errMsg)
  539. return
  540. }
  541. errMsg = "获取指标失败:Err:" + err.Error()
  542. err = errors.New(errMsg)
  543. return
  544. }
  545. edbInfoList = append(edbInfoList, fromEdbInfo)
  546. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  547. {
  548. if _, ok := fromEdbMap[tmpEdbInfoId.EdbInfoId]; !ok {
  549. fromEdbMap[tmpEdbInfoId.EdbInfoId] = tmpEdbInfoId.EdbInfoId
  550. calculateMappingItem := &models.EdbInfoCalculateMapping{
  551. EdbInfoCalculateMappingId: 0,
  552. EdbInfoId: edbInfoId,
  553. Source: utils.DATA_SOURCE_CALCULATE,
  554. SourceName: "指标运算",
  555. EdbCode: "",
  556. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  557. FromEdbCode: fromEdbInfo.EdbCode,
  558. FromEdbName: fromEdbInfo.EdbName,
  559. FromSource: fromEdbInfo.Source,
  560. FromSourceName: fromEdbInfo.SourceName,
  561. //FromTag: tmpEdbInfoId.FromTag,
  562. Sort: k + 1,
  563. CreateTime: time.Now(),
  564. ModifyTime: time.Now(),
  565. }
  566. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  567. }
  568. }
  569. // 动态环差规则 关系表
  570. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  571. //PredictEdbConfCalculateMappingId: 0,
  572. EdbInfoId: edbInfoId,
  573. ConfigId: 0,
  574. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  575. FromEdbCode: fromEdbInfo.EdbCode,
  576. FromEdbName: fromEdbInfo.EdbName,
  577. FromSource: fromEdbInfo.Source,
  578. FromSourceName: fromEdbInfo.SourceName,
  579. FromTag: tmpEdbInfoId.FromTag,
  580. Sort: k + 1,
  581. CreateTime: time.Now(),
  582. ModifyTime: time.Now(),
  583. }
  584. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  585. }
  586. ok, _ := models.CheckFormula2(edbInfoList, formulaMap, formula, edbInfoIdBytes)
  587. if !ok {
  588. errMsg = "生成计算指标失败,请使用正确的计算公式"
  589. err = errors.New(errMsg)
  590. return
  591. }
  592. calculateRuleMap[ruleIndex] = models.CalculateRule{
  593. TrendsCalculateMappingList: trendsMappingList,
  594. EdbInfoList: edbInfoList,
  595. EdbInfoIdBytes: edbInfoIdBytes,
  596. Formula: formula,
  597. RuleType: v.RuleType,
  598. EndDate: v.EndDate,
  599. EdbInfoIdArr: v.EdbInfoIdArr,
  600. }
  601. case 14: //14:根据 一元线性拟合 规则获取预测数据
  602. if v.Value == "" {
  603. errMsg = "请填写一元线性拟合规则"
  604. err = errors.New(errMsg)
  605. return
  606. }
  607. //关联的指标信息
  608. edbInfoList := make([]*models.EdbInfo, 0)
  609. // 动态环差规则 关系表
  610. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  611. for k, tmpEdbInfoId := range v.EdbInfoIdArr {
  612. fromEdbInfo, tmpErr := models.GetEdbInfoById(tmpEdbInfoId.EdbInfoId)
  613. if tmpErr != nil {
  614. err = tmpErr
  615. if err.Error() == utils.ErrNoRow() {
  616. errMsg = "指标 " + strconv.Itoa(tmpEdbInfoId.EdbInfoId) + " 不存在"
  617. err = errors.New(errMsg)
  618. return
  619. }
  620. errMsg = "获取指标失败:Err:" + err.Error()
  621. err = errors.New(errMsg)
  622. return
  623. }
  624. edbInfoList = append(edbInfoList, fromEdbInfo)
  625. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  626. {
  627. if _, ok := fromEdbMap[tmpEdbInfoId.EdbInfoId]; !ok {
  628. fromEdbMap[tmpEdbInfoId.EdbInfoId] = tmpEdbInfoId.EdbInfoId
  629. tmpCalculateMappingItem := &models.EdbInfoCalculateMapping{
  630. EdbInfoCalculateMappingId: 0,
  631. EdbInfoId: 0,
  632. Source: utils.DATA_SOURCE_CALCULATE,
  633. SourceName: "指标运算",
  634. EdbCode: "",
  635. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  636. FromEdbCode: fromEdbInfo.EdbCode,
  637. FromEdbName: fromEdbInfo.EdbName,
  638. FromSource: fromEdbInfo.Source,
  639. FromSourceName: fromEdbInfo.SourceName,
  640. //FromTag: tmpEdbInfoId.FromTag,
  641. Sort: k + 1,
  642. CreateTime: time.Now(),
  643. ModifyTime: time.Now(),
  644. }
  645. calculateMappingList = append(calculateMappingList, tmpCalculateMappingItem)
  646. }
  647. }
  648. // 动态环差规则 关系表
  649. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  650. //PredictEdbConfCalculateMappingId: 0,
  651. EdbInfoId: 0,
  652. ConfigId: 0,
  653. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  654. FromEdbCode: fromEdbInfo.EdbCode,
  655. FromEdbName: fromEdbInfo.EdbName,
  656. FromSource: fromEdbInfo.Source,
  657. FromSourceName: fromEdbInfo.SourceName,
  658. FromTag: tmpEdbInfoId.FromTag,
  659. Sort: k + 1,
  660. CreateTime: time.Now(),
  661. ModifyTime: time.Now(),
  662. }
  663. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  664. }
  665. calculateRuleMap[ruleIndex] = models.CalculateRule{
  666. TrendsCalculateMappingList: trendsMappingList,
  667. EdbInfoList: edbInfoList,
  668. //EdbInfoIdBytes: edbInfoIdBytes,
  669. //Formula: formula,
  670. RuleType: v.RuleType,
  671. EndDate: v.EndDate,
  672. EdbInfoIdArr: v.EdbInfoIdArr,
  673. }
  674. }
  675. tmpPredictEdbConf := &models.PredictEdbConf{
  676. PredictEdbInfoId: edbInfoId,
  677. SourceEdbInfoId: sourceEdbInfo.EdbInfoId,
  678. RuleType: v.RuleType,
  679. //FixedValue: v.Value,
  680. Value: v.Value,
  681. EndDate: ruleEndDate,
  682. ModifyTime: time.Now(),
  683. CreateTime: time.Now(),
  684. }
  685. edbInfo.EndDate = v.EndDate
  686. predictEdbConfList = append(predictEdbConfList, tmpPredictEdbConf)
  687. }
  688. err, errMsg = models.EditPredictEdb(edbInfo, updateEdbInfoCol, calculateMappingList, predictEdbConfList, calculateRuleMap)
  689. return
  690. }
  691. // RefreshPredictEdbInfo 更新基础预测指标规则中的动态数据
  692. func RefreshPredictEdbInfo(edbInfoId int) (edbInfo *models.EdbInfo, err error, errMsg string) {
  693. // 指标信息校验
  694. {
  695. edbInfo, err = models.GetEdbInfoById(edbInfoId)
  696. if err != nil && err.Error() != utils.ErrNoRow() {
  697. errMsg = "刷新失败"
  698. err = errors.New("获取预测指标失败,Err:" + err.Error())
  699. return
  700. }
  701. if edbInfo == nil {
  702. errMsg = "找不到该预测指标"
  703. err = nil
  704. return
  705. }
  706. //必须是普通的指标
  707. if edbInfo.EdbInfoType != 1 {
  708. errMsg = "指标异常,不是预测指标"
  709. return
  710. }
  711. }
  712. // 配置 与 指标的 关联关系表
  713. list, err := models.GetPredictEdbConfCalculateMappingListByEdbInfoId(edbInfoId)
  714. if err != nil {
  715. return
  716. }
  717. // 没有关联指标,不需要刷新
  718. if len(list) <= 0 {
  719. return
  720. }
  721. // 配置关联的指标信息
  722. predictEdbConfCalculateMappingListMap := make(map[int][]*models.PredictEdbConfCalculateMapping)
  723. configIdList := make([]int, 0) //关联配置id
  724. edbInfoIdList := make([]int, 0) //关联指标配置id
  725. edbInfoIdMap := make(map[int]int, 0) //关联指标配置map
  726. for _, v := range list {
  727. configList, ok := predictEdbConfCalculateMappingListMap[v.ConfigId]
  728. if !ok {
  729. configList = make([]*models.PredictEdbConfCalculateMapping, 0)
  730. configIdList = append(configIdList, v.ConfigId)
  731. }
  732. if _, ok := edbInfoIdMap[v.FromEdbInfoId]; !ok {
  733. edbInfoIdList = append(edbInfoIdList, v.FromEdbInfoId)
  734. }
  735. configList = append(configList, v)
  736. predictEdbConfCalculateMappingListMap[v.ConfigId] = configList
  737. }
  738. predictEdbConfList, err := models.GetPredictEdbConfListByConfigIdList(configIdList)
  739. if err != nil {
  740. errMsg = "刷新失败"
  741. err = errors.New("获取预测指标配置信息失败,Err:" + err.Error())
  742. return
  743. }
  744. if len(predictEdbConfList) == 0 {
  745. errMsg = "找不到该预测指标配置"
  746. err = nil
  747. return
  748. }
  749. // 指标信息
  750. edbInfoList, err := models.GetEdbInfoByIdList(edbInfoIdList)
  751. if err != nil {
  752. err = errors.New("获取关联指标失败,Err:" + err.Error())
  753. return
  754. }
  755. // 指标信息map
  756. edbInfoListMap := make(map[int]*models.EdbInfo)
  757. for _, v := range edbInfoList {
  758. edbInfoListMap[v.EdbInfoId] = v
  759. }
  760. predictEdbConfAndDataList := make([]*models.PredictEdbConfAndData, 0)
  761. // 刷新所有的规则
  762. for _, v := range predictEdbConfList {
  763. // 每次规则计算的时候,产生的临时数据
  764. resultDataList := make([]*models.EdbInfoSearchData, 0)
  765. switch v.RuleType {
  766. case 9: //动态环差值
  767. if v.Value == "" {
  768. errMsg = "请填写计算规则"
  769. return
  770. }
  771. formula := v.Value
  772. // 动态环差规则 关系表
  773. trendsMappingList := predictEdbConfCalculateMappingListMap[v.ConfigId]
  774. // 关联标签
  775. edbInfoIdArr := make([]models.EdbInfoFromTag, 0)
  776. //关联的指标信息
  777. edbInfoList := make([]*models.EdbInfo, 0)
  778. for _, trendsMapping := range trendsMappingList {
  779. tmpEdbInfo, ok := edbInfoListMap[trendsMapping.FromEdbInfoId]
  780. if ok {
  781. edbInfoList = append(edbInfoList, tmpEdbInfo)
  782. }
  783. // 关联标签
  784. edbInfoIdArr = append(edbInfoIdArr, models.EdbInfoFromTag{
  785. EdbInfoId: trendsMapping.FromEdbInfoId,
  786. FromTag: trendsMapping.FromTag,
  787. })
  788. }
  789. //检验公式
  790. var formulaStr string
  791. var edbInfoIdBytes []string
  792. for _, tmpEdbInfoId := range edbInfoIdArr {
  793. formulaStr += tmpEdbInfoId.FromTag + ","
  794. edbInfoIdBytes = append(edbInfoIdBytes, tmpEdbInfoId.FromTag)
  795. }
  796. formulaMap := services.CheckFormula(formula)
  797. for _, formula := range formulaMap {
  798. if !strings.Contains(formulaStr, formula) {
  799. errMsg = "公式错误,请重新填写"
  800. return
  801. }
  802. }
  803. ok, _ := models.CheckFormula2(edbInfoList, formulaMap, formula, edbInfoIdBytes)
  804. if !ok {
  805. errMsg = "生成计算指标失败,请使用正确的计算公式"
  806. return
  807. }
  808. rule := models.CalculateRule{
  809. EdbInfoId: v.PredictEdbInfoId,
  810. ConfigId: v.ConfigId,
  811. TrendsCalculateMappingList: trendsMappingList,
  812. EdbInfoList: edbInfoList,
  813. EdbInfoIdBytes: edbInfoIdBytes,
  814. Formula: formula,
  815. RuleType: v.RuleType,
  816. EndDate: v.EndDate.Format(utils.FormatDate),
  817. EdbInfoIdArr: edbInfoIdArr,
  818. }
  819. resultDataList, err = models.RefreshCalculateByRuleBy9(rule)
  820. if err != nil {
  821. return
  822. }
  823. case 14: //14:根据 一元线性拟合 规则获取预测数据
  824. if v.Value == "" {
  825. errMsg = "一元线性拟合规则信息未配置"
  826. return
  827. }
  828. err, errMsg = models.RefreshCalculateByRuleByLineNh(*edbInfo, predictEdbConfAndDataList, *v)
  829. if err != nil {
  830. return
  831. }
  832. }
  833. // 规则配置(含数据)
  834. tmpPredictEdbConfAndData := &models.PredictEdbConfAndData{
  835. ConfigId: 0,
  836. PredictEdbInfoId: 0,
  837. SourceEdbInfoId: v.SourceEdbInfoId,
  838. RuleType: v.RuleType,
  839. FixedValue: v.FixedValue,
  840. Value: v.Value,
  841. EndDate: v.EndDate,
  842. ModifyTime: v.ModifyTime,
  843. CreateTime: v.CreateTime,
  844. DataList: resultDataList,
  845. }
  846. predictEdbConfAndDataList = append(predictEdbConfAndDataList, tmpPredictEdbConfAndData)
  847. }
  848. return
  849. }