predict_edb.go 30 KB

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