predict_edb.go 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408
  1. package logic
  2. import (
  3. "errors"
  4. "eta/eta_index_lib/models"
  5. "eta/eta_index_lib/utils"
  6. "fmt"
  7. "strconv"
  8. "strings"
  9. "time"
  10. )
  11. // AddPredictEdbInfo 新增预测指标
  12. func AddPredictEdbInfo(sourceEdbInfoId, classifyId int, edbName, dataDateType string, endDateType int, ruleList []models.RuleConfig, minValue, maxValue float64, sysUserId int, sysUserName, lang 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 && !utils.IsErrNoRow(err) {
  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 && !utils.IsErrNoRow(err) {
  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. // 根据指标名称和指标ID校验库中是否还存在其他同名指标
  63. existEdbName, err := CheckExistByEdbNameAndEdbInfoId(utils.PREDICT_EDB_INFO_TYPE, 0, edbName, lang)
  64. if err != nil {
  65. errMsg = "判断指标名称是否存在失败"
  66. err = errors.New("判断指标名称是否存在失败,Err:" + err.Error())
  67. return
  68. }
  69. if existEdbName {
  70. errMsg = "指标名称已存在,请重新填写"
  71. err = errors.New(errMsg)
  72. return
  73. }
  74. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  75. if dataDateType == `` {
  76. dataDateType = `自然日`
  77. }
  78. edbInfo = &models.EdbInfo{
  79. //EdbInfoId: 0,
  80. EdbInfoType: 1,
  81. SourceName: "预测指标",
  82. Source: utils.DATA_SOURCE_PREDICT,
  83. EdbCode: edbCode,
  84. EdbName: edbName,
  85. EdbNameSource: edbName,
  86. Frequency: sourceEdbInfo.Frequency,
  87. Unit: sourceEdbInfo.Unit,
  88. StartDate: sourceEdbInfo.StartDate,
  89. ClassifyId: classifyId,
  90. SysUserId: sysUserId,
  91. SysUserRealName: sysUserName,
  92. UniqueCode: utils.MD5(utils.DATA_PREFIX + "_" + timestamp),
  93. CreateTime: time.Now(),
  94. ModifyTime: time.Now(),
  95. MinValue: minValue,
  96. MaxValue: maxValue,
  97. CalculateFormula: sourceEdbInfo.CalculateFormula,
  98. EdbType: 1,
  99. //Sort: sourceEdbInfo.,
  100. LatestDate: sourceEdbInfo.LatestDate,
  101. LatestValue: sourceEdbInfo.LatestValue,
  102. MoveType: sourceEdbInfo.MoveType,
  103. MoveFrequency: sourceEdbInfo.MoveFrequency,
  104. NoUpdate: sourceEdbInfo.NoUpdate,
  105. ServerUrl: "",
  106. EdbNameEn: edbName,
  107. UnitEn: sourceEdbInfo.UnitEn,
  108. DataDateType: dataDateType,
  109. Sort: models.GetAddEdbMaxSortByClassifyId(classifyId, utils.PREDICT_EDB_INFO_TYPE),
  110. EndDateType: endDateType,
  111. }
  112. // 关联关系表
  113. calculateMappingList := make([]*models.EdbInfoCalculateMapping, 0)
  114. fromEdbMap := make(map[int]int)
  115. // 源指标关联关系表
  116. calculateMappingItem := &models.EdbInfoCalculateMapping{
  117. //EdbInfoCalculateMappingId: 0,
  118. //EdbInfoId: 0,
  119. Source: edbInfo.Source,
  120. SourceName: edbInfo.SourceName,
  121. EdbCode: edbInfo.EdbCode,
  122. FromEdbInfoId: sourceEdbInfo.EdbInfoId,
  123. FromEdbCode: sourceEdbInfo.EdbCode,
  124. FromEdbName: sourceEdbInfo.EdbName,
  125. FromSource: sourceEdbInfo.Source,
  126. FromSourceName: sourceEdbInfo.SourceName,
  127. //FromTag: "",
  128. Sort: 1,
  129. CreateTime: time.Now(),
  130. ModifyTime: time.Now(),
  131. }
  132. fromEdbMap[sourceEdbInfoId] = sourceEdbInfoId
  133. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  134. // 动态环差 计算列表
  135. calculateRuleMap := make(map[int]models.CalculateRule, 0)
  136. // 预测指标配置
  137. predictEdbConfList := make([]*models.PredictEdbConf, 0)
  138. var ruleEndDate time.Time
  139. for ruleIndex, v := range ruleList {
  140. if endDateType == 0 {
  141. // 预测指标配置
  142. ruleEndDate, err = time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
  143. if err != nil {
  144. errMsg = "规则配置的截止日期异常,请重新填写"
  145. err = errors.New(errMsg)
  146. return
  147. }
  148. } else {
  149. if v.EndNum <= 0 {
  150. errMsg = "截止期数不正确,请输入大于等于1的整数"
  151. err = errors.New(errMsg)
  152. return
  153. }
  154. }
  155. //1:最新,2:固定值,3:同比,4:同差,5:环比,6:环差,7:N期移动均值,8:N期段线性外推值,9:动态环差,10:根据 给定终值后插值 规则获取预测数据,11:根据 季节性 规则获取预测数据,12:根据 移动平均同比 规则获取预测数据
  156. // 环比、环差、动态环差、季节性、移动平均同比不支持年度
  157. if sourceEdbInfo.Frequency == "年度" && utils.InArrayByInt([]int{5, 6, 11, 12}, v.RuleType) {
  158. errMsg = "环比、环差、动态环差、季节性、移动平均同比不支持年度指标"
  159. err = errors.New(errMsg)
  160. return
  161. }
  162. if v.RuleType == 16 && endDateType == 1 {
  163. errMsg = "年度值倒推不支持截止期数"
  164. err = errors.New(errMsg)
  165. return
  166. }
  167. switch v.RuleType {
  168. case 8: //N期段线性外推值
  169. valInt, tmpErr := strconv.Atoi(v.Value)
  170. if tmpErr != nil {
  171. errMsg = "N期段线性外推值的N值异常"
  172. err = errors.New(errMsg)
  173. return
  174. }
  175. if valInt <= 1 {
  176. errMsg = "N期段线性外推值的N值必须大于1"
  177. err = errors.New(errMsg)
  178. return
  179. }
  180. case 9: //9:动态环差
  181. if v.Value == "" {
  182. errMsg = "请填写计算规则"
  183. err = errors.New(errMsg)
  184. return
  185. }
  186. formula := v.Value
  187. formula = strings.Replace(formula, "(", "(", -1)
  188. formula = strings.Replace(formula, ")", ")", -1)
  189. formula = strings.Replace(formula, ",", ",", -1)
  190. formula = strings.Replace(formula, "。", ".", -1)
  191. formula = strings.Replace(formula, "%", "*0.01", -1)
  192. v.Value = formula
  193. //检验公式
  194. var formulaStr string
  195. var edbInfoIdBytes []string
  196. for _, tmpEdbInfoId := range v.EdbInfoIdArr {
  197. formulaStr += tmpEdbInfoId.FromTag + ","
  198. edbInfoIdBytes = append(edbInfoIdBytes, tmpEdbInfoId.FromTag)
  199. }
  200. formulaSlice, tErr := utils.CheckFormulaJson(formula)
  201. if tErr != nil {
  202. errMsg = "公式格式错误,请重新填写"
  203. err = errors.New(errMsg)
  204. return
  205. }
  206. for _, fm := range formulaSlice {
  207. formulaMap, e := utils.CheckFormula(fm)
  208. if e != nil {
  209. err = fmt.Errorf("公式错误,请重新填写")
  210. return
  211. }
  212. for _, f := range formulaMap {
  213. if !strings.Contains(formulaStr, f) {
  214. errMsg = "公式错误,请重新填写"
  215. err = errors.New(errMsg)
  216. return
  217. }
  218. }
  219. }
  220. //关联的指标信息
  221. edbInfoList := make([]*models.EdbInfo, 0)
  222. // 动态环差规则 关系表
  223. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  224. for k, tmpEdbInfoId := range v.EdbInfoIdArr {
  225. fromEdbInfo, tmpErr := models.GetEdbInfoById(tmpEdbInfoId.EdbInfoId)
  226. if tmpErr != nil {
  227. err = tmpErr
  228. if err.Error() == utils.ErrNoRow() {
  229. errMsg = "指标 " + strconv.Itoa(tmpEdbInfoId.EdbInfoId) + " 不存在"
  230. err = errors.New(errMsg)
  231. return
  232. }
  233. errMsg = "获取指标失败:Err:" + err.Error()
  234. err = errors.New(errMsg)
  235. return
  236. }
  237. edbInfoList = append(edbInfoList, fromEdbInfo)
  238. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  239. {
  240. if _, ok := fromEdbMap[tmpEdbInfoId.EdbInfoId]; !ok {
  241. fromEdbMap[tmpEdbInfoId.EdbInfoId] = tmpEdbInfoId.EdbInfoId
  242. calculateMappingItem := &models.EdbInfoCalculateMapping{
  243. EdbInfoCalculateMappingId: 0,
  244. EdbInfoId: 0,
  245. Source: edbInfo.Source,
  246. SourceName: edbInfo.SourceName,
  247. EdbCode: "",
  248. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  249. FromEdbCode: fromEdbInfo.EdbCode,
  250. FromEdbName: fromEdbInfo.EdbName,
  251. FromSource: fromEdbInfo.Source,
  252. FromSourceName: fromEdbInfo.SourceName,
  253. //FromTag: tmpEdbInfoId.FromTag,
  254. Sort: k + 1,
  255. CreateTime: time.Now(),
  256. ModifyTime: time.Now(),
  257. }
  258. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  259. }
  260. }
  261. // 动态环差规则 关系表
  262. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  263. //PredictEdbConfCalculateMappingId: 0,
  264. EdbInfoId: 0,
  265. ConfigId: 0,
  266. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  267. FromEdbCode: fromEdbInfo.EdbCode,
  268. FromEdbName: fromEdbInfo.EdbName,
  269. FromSource: fromEdbInfo.Source,
  270. FromSourceName: fromEdbInfo.SourceName,
  271. FromTag: tmpEdbInfoId.FromTag,
  272. Sort: k + 1,
  273. CreateTime: time.Now(),
  274. ModifyTime: time.Now(),
  275. }
  276. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  277. }
  278. for _, f := range formulaSlice {
  279. formulaMap, e := utils.CheckFormula(f)
  280. if e != nil {
  281. err = fmt.Errorf("公式错误,请重新填写")
  282. return
  283. }
  284. //预先计算,判断公式是否正常
  285. ok, _ := models.CheckFormula2(edbInfoList, formulaMap, f, edbInfoIdBytes)
  286. if !ok {
  287. errMsg = "生成计算指标失败,请使用正确的计算公式"
  288. err = errors.New(errMsg)
  289. return
  290. }
  291. }
  292. calculateRuleMap[ruleIndex] = models.CalculateRule{
  293. TrendsCalculateMappingList: trendsMappingList,
  294. EdbInfoList: edbInfoList,
  295. EdbInfoIdBytes: edbInfoIdBytes,
  296. Formula: formula,
  297. RuleType: v.RuleType,
  298. EndDate: v.EndDate,
  299. EdbInfoIdArr: v.EdbInfoIdArr,
  300. }
  301. case 14: //14:根据 一元线性拟合 规则获取预测数据
  302. if v.Value == "" {
  303. errMsg = "请填写一元线性拟合规则"
  304. err = errors.New(errMsg)
  305. return
  306. }
  307. //关联的指标信息
  308. edbInfoList := make([]*models.EdbInfo, 0)
  309. // 动态环差规则 关系表
  310. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  311. for k, tmpEdbInfoId := range v.EdbInfoIdArr {
  312. fromEdbInfo, tmpErr := models.GetEdbInfoById(tmpEdbInfoId.EdbInfoId)
  313. if tmpErr != nil {
  314. err = tmpErr
  315. if err.Error() == utils.ErrNoRow() {
  316. errMsg = "指标 " + strconv.Itoa(tmpEdbInfoId.EdbInfoId) + " 不存在"
  317. err = errors.New(errMsg)
  318. return
  319. }
  320. errMsg = "获取指标失败:Err:" + err.Error()
  321. err = errors.New(errMsg)
  322. return
  323. }
  324. edbInfoList = append(edbInfoList, fromEdbInfo)
  325. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  326. {
  327. if _, ok := fromEdbMap[tmpEdbInfoId.EdbInfoId]; !ok {
  328. fromEdbMap[tmpEdbInfoId.EdbInfoId] = tmpEdbInfoId.EdbInfoId
  329. tmpCalculateMappingItem := &models.EdbInfoCalculateMapping{
  330. EdbInfoCalculateMappingId: 0,
  331. EdbInfoId: 0,
  332. Source: edbInfo.Source,
  333. SourceName: edbInfo.SourceName,
  334. EdbCode: "",
  335. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  336. FromEdbCode: fromEdbInfo.EdbCode,
  337. FromEdbName: fromEdbInfo.EdbName,
  338. FromSource: fromEdbInfo.Source,
  339. FromSourceName: fromEdbInfo.SourceName,
  340. //FromTag: tmpEdbInfoId.FromTag,
  341. Sort: k + 1,
  342. CreateTime: time.Now(),
  343. ModifyTime: time.Now(),
  344. }
  345. calculateMappingList = append(calculateMappingList, tmpCalculateMappingItem)
  346. }
  347. }
  348. // 动态环差规则 关系表
  349. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  350. //PredictEdbConfCalculateMappingId: 0,
  351. EdbInfoId: 0,
  352. ConfigId: 0,
  353. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  354. FromEdbCode: fromEdbInfo.EdbCode,
  355. FromEdbName: fromEdbInfo.EdbName,
  356. FromSource: fromEdbInfo.Source,
  357. FromSourceName: fromEdbInfo.SourceName,
  358. FromTag: tmpEdbInfoId.FromTag,
  359. Sort: k + 1,
  360. CreateTime: time.Now(),
  361. ModifyTime: time.Now(),
  362. }
  363. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  364. }
  365. calculateRuleMap[ruleIndex] = models.CalculateRule{
  366. TrendsCalculateMappingList: trendsMappingList,
  367. EdbInfoList: edbInfoList,
  368. //EdbInfoIdBytes: edbInfoIdBytes,
  369. //Formula: formula,
  370. RuleType: v.RuleType,
  371. EndDate: v.EndDate,
  372. EdbInfoIdArr: v.EdbInfoIdArr,
  373. }
  374. case 17, 18:
  375. //关联的指标信息
  376. edbInfoList := make([]*models.EdbInfo, 0)
  377. // 动态环差规则 关系表
  378. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  379. edbInfoId, parseErr := strconv.Atoi(v.Value)
  380. if parseErr != nil {
  381. errMsg = "请填写正确的指标id"
  382. err = errors.New(errMsg)
  383. return
  384. }
  385. fromEdbInfo, tmpErr := models.GetEdbInfoById(edbInfoId)
  386. if tmpErr != nil {
  387. err = tmpErr
  388. if err.Error() == utils.ErrNoRow() {
  389. errMsg = "指标 " + strconv.Itoa(edbInfoId) + " 不存在"
  390. err = errors.New(errMsg)
  391. return
  392. }
  393. errMsg = "获取指标失败:Err:" + err.Error()
  394. err = errors.New(errMsg)
  395. return
  396. }
  397. edbInfoList = append(edbInfoList, fromEdbInfo)
  398. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  399. calculateMappingItem = &models.EdbInfoCalculateMapping{
  400. EdbInfoCalculateMappingId: 0,
  401. EdbInfoId: 0,
  402. Source: edbInfo.Source,
  403. SourceName: edbInfo.SourceName,
  404. EdbCode: "",
  405. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  406. FromEdbCode: fromEdbInfo.EdbCode,
  407. FromEdbName: fromEdbInfo.EdbName,
  408. FromSource: fromEdbInfo.Source,
  409. FromSourceName: fromEdbInfo.SourceName,
  410. //FromTag: tmpEdbInfoId.FromTag,
  411. Sort: 1,
  412. CreateTime: time.Now(),
  413. ModifyTime: time.Now(),
  414. }
  415. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  416. // 动态同比同差规则 关系表
  417. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  418. //PredictEdbConfCalculateMappingId: 0,
  419. EdbInfoId: 0,
  420. ConfigId: 0,
  421. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  422. FromEdbCode: fromEdbInfo.EdbCode,
  423. FromEdbName: fromEdbInfo.EdbName,
  424. FromSource: fromEdbInfo.Source,
  425. FromSourceName: fromEdbInfo.SourceName,
  426. Sort: 1,
  427. CreateTime: time.Now(),
  428. ModifyTime: time.Now(),
  429. }
  430. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  431. calculateRuleMap[ruleIndex] = models.CalculateRule{
  432. TrendsCalculateMappingList: trendsMappingList,
  433. EdbInfoList: edbInfoList,
  434. RuleType: v.RuleType,
  435. EndDate: v.EndDate,
  436. EdbInfoIdArr: v.EdbInfoIdArr,
  437. }
  438. }
  439. tmpPredictEdbConf := &models.PredictEdbConf{
  440. PredictEdbInfoId: 0,
  441. SourceEdbInfoId: sourceEdbInfoId,
  442. RuleType: v.RuleType,
  443. //FixedValue: v.Value,
  444. Value: v.Value,
  445. //EndDate: ruleEndDate,
  446. ModifyTime: time.Now(),
  447. CreateTime: time.Now(),
  448. EndNum: v.EndNum,
  449. }
  450. if endDateType == 0 {
  451. tmpPredictEdbConf.EndDate = ruleEndDate
  452. }
  453. //todo 指标最终的截止日期的更新
  454. edbInfo.EndDate = v.EndDate
  455. predictEdbConfList = append(predictEdbConfList, tmpPredictEdbConf)
  456. }
  457. err, errMsg = models.AddPredictEdb(edbInfo, calculateMappingList, predictEdbConfList, calculateRuleMap)
  458. return
  459. }
  460. // EditPredictEdbInfo 编辑预测指标
  461. func EditPredictEdbInfo(edbInfoId, classifyId int, edbName, dataDateType string, endDateType int, ruleList []models.RuleConfig, minValue, maxValue float64, lang string) (edbInfo *models.EdbInfo, err error, errMsg string) {
  462. // 指标信息校验
  463. {
  464. edbInfo, err = models.GetEdbInfoById(edbInfoId)
  465. if err != nil && !utils.IsErrNoRow(err) {
  466. errMsg = "修改失败"
  467. err = errors.New("获取预测指标失败,Err:" + err.Error())
  468. return
  469. }
  470. if edbInfo == nil {
  471. errMsg = "找不到该预测指标"
  472. err = errors.New(errMsg)
  473. return
  474. }
  475. //必须是普通的指标
  476. if edbInfo.EdbInfoType != 1 {
  477. errMsg = "指标异常,不是预测指标"
  478. err = errors.New(errMsg)
  479. return
  480. }
  481. }
  482. var predictEdbConf *models.PredictEdbConf
  483. // 指标配置信息校验
  484. {
  485. // 查找该预测指标配置
  486. predictEdbConfList, tmpErr := models.GetPredictEdbConfListById(edbInfo.EdbInfoId)
  487. if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
  488. errMsg = "修改失败"
  489. err = errors.New("获取预测指标配置信息失败,Err:" + tmpErr.Error())
  490. return
  491. }
  492. if len(predictEdbConfList) == 0 {
  493. errMsg = "找不到该预测指标配置"
  494. err = errors.New(errMsg)
  495. return
  496. }
  497. predictEdbConf = predictEdbConfList[0]
  498. }
  499. // 根据指标名称和指标ID校验库中是否还存在其他同名指标
  500. existEdbName, err := CheckExistByEdbNameAndEdbInfoId(utils.PREDICT_EDB_INFO_TYPE, edbInfoId, edbName, lang)
  501. if err != nil {
  502. errMsg = "判断指标名称是否存在失败"
  503. err = errors.New("判断指标名称是否存在失败,Err:" + err.Error())
  504. return
  505. }
  506. if existEdbName {
  507. errMsg = "指标名称已存在,请重新填写"
  508. err = errors.New(errMsg)
  509. return
  510. }
  511. if dataDateType == `` {
  512. dataDateType = `自然日`
  513. }
  514. switch lang {
  515. case utils.EnLangVersion:
  516. edbInfo.EdbNameEn = edbName
  517. default:
  518. edbInfo.EdbName = edbName
  519. }
  520. edbInfo.EdbNameSource = edbName
  521. edbInfo.ClassifyId = classifyId
  522. edbInfo.MinValue = minValue
  523. edbInfo.MaxValue = maxValue
  524. edbInfo.DataDateType = dataDateType
  525. edbInfo.ModifyTime = time.Now()
  526. edbInfo.EndDateType = endDateType
  527. updateEdbInfoCol := []string{"EdbName", "EdbNameEn", "EdbNameSource", "ClassifyId", "EndDate", "MinValue", "MaxValue", "DataDateType", "ModifyTime", "EndDateType"}
  528. var sourceEdbInfo *models.EdbInfo
  529. // 来源指标信息校验
  530. {
  531. sourceEdbInfo, err = models.GetEdbInfoById(predictEdbConf.SourceEdbInfoId)
  532. if err != nil && !utils.IsErrNoRow(err) {
  533. errMsg = "新增失败"
  534. err = errors.New("获取来源指标失败,Err:" + err.Error())
  535. return
  536. }
  537. if sourceEdbInfo == nil {
  538. errMsg = "找不到该来源指标"
  539. err = errors.New(errMsg)
  540. return
  541. }
  542. //必须是普通的指标
  543. if sourceEdbInfo.EdbInfoType != 0 {
  544. errMsg = "来源指标异常,不是普通的指标"
  545. err = errors.New(errMsg)
  546. return
  547. }
  548. //if !utils.InArrayByStr([]string{"日度", "周度", "月度", "年度"}, sourceEdbInfo.Frequency) {
  549. // errMsg = "预测指标只支持选择日度、周度、月度、年度的指标"
  550. // err = errors.New(errMsg)
  551. // return
  552. //}
  553. }
  554. // 预测指标配置
  555. // 关联关系表
  556. calculateMappingList := make([]*models.EdbInfoCalculateMapping, 0)
  557. fromEdbMap := make(map[int]int)
  558. // 源指标关联关系表
  559. calculateMappingItem := &models.EdbInfoCalculateMapping{
  560. //EdbInfoCalculateMappingId: 0,
  561. EdbInfoId: edbInfoId,
  562. Source: edbInfo.Source,
  563. SourceName: edbInfo.SourceName,
  564. EdbCode: edbInfo.EdbCode,
  565. FromEdbInfoId: sourceEdbInfo.EdbInfoId,
  566. FromEdbCode: sourceEdbInfo.EdbCode,
  567. FromEdbName: sourceEdbInfo.EdbName,
  568. FromSource: sourceEdbInfo.Source,
  569. FromSourceName: sourceEdbInfo.SourceName,
  570. //FromTag: "",
  571. Sort: 1,
  572. CreateTime: time.Now(),
  573. ModifyTime: time.Now(),
  574. }
  575. fromEdbMap[sourceEdbInfo.EdbInfoId] = sourceEdbInfo.EdbInfoId
  576. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  577. // 动态环差 计算列表
  578. calculateRuleMap := make(map[int]models.CalculateRule, 0)
  579. // 预测指标配置
  580. predictEdbConfList := make([]*models.PredictEdbConf, 0)
  581. for ruleIndex, v := range ruleList {
  582. var ruleEndDate time.Time
  583. if endDateType == 0 {
  584. // 预测指标配置
  585. ruleEndDate, err = time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
  586. if err != nil {
  587. errMsg = "规则配置的截止日期异常,请重新填写"
  588. err = errors.New(errMsg)
  589. return
  590. }
  591. } else {
  592. if v.EndNum <= 0 {
  593. errMsg = "截止期数不正确,请输入大于等于1的整数"
  594. err = errors.New(errMsg)
  595. return
  596. }
  597. }
  598. //1:最新,2:固定值,3:同比,4:同差,5:环比,6:环差,7:N期移动均值,8:N期段线性外推值,9:动态环差,10:根据 给定终值后插值 规则获取预测数据,11:根据 季节性 规则获取预测数据,12:根据 移动平均同比 规则获取预测数据
  599. // 环比、环差、动态环差、季节性、移动平均同比不支持年度
  600. if sourceEdbInfo.Frequency == "年度" && utils.InArrayByInt([]int{5, 6, 11, 12}, v.RuleType) {
  601. errMsg = "环比、环差、动态环差、季节性、移动平均同比不支持年度指标"
  602. err = errors.New(errMsg)
  603. return
  604. }
  605. if v.RuleType == 16 && endDateType == 1 {
  606. errMsg = "年度值倒推不支持截止期数"
  607. err = errors.New(errMsg)
  608. return
  609. }
  610. switch v.RuleType {
  611. case 8: //N期段线性外推值
  612. valInt, tmpErr := strconv.Atoi(v.Value)
  613. if tmpErr != nil {
  614. errMsg = "N期段线性外推值的N值异常"
  615. err = errors.New(errMsg)
  616. return
  617. }
  618. if valInt <= 1 {
  619. errMsg = "N期段线性外推值的N值必须大于1"
  620. err = errors.New(errMsg)
  621. return
  622. }
  623. case 9: //9:动态环差
  624. if v.Value == "" {
  625. errMsg = "请填写计算规则"
  626. err = errors.New(errMsg)
  627. return
  628. }
  629. formula := v.Value
  630. formula = strings.Replace(formula, "(", "(", -1)
  631. formula = strings.Replace(formula, ")", ")", -1)
  632. formula = strings.Replace(formula, ",", ",", -1)
  633. formula = strings.Replace(formula, "。", ".", -1)
  634. formula = strings.Replace(formula, "%", "*0.01", -1)
  635. v.Value = formula
  636. //检验公式
  637. var formulaStr string
  638. var edbInfoIdBytes []string
  639. for _, tmpEdbInfoId := range v.EdbInfoIdArr {
  640. formulaStr += tmpEdbInfoId.FromTag + ","
  641. edbInfoIdBytes = append(edbInfoIdBytes, tmpEdbInfoId.FromTag)
  642. }
  643. formulaSlice, tErr := utils.CheckFormulaJson(formula)
  644. if tErr != nil {
  645. errMsg = "公式格式错误,请重新填写"
  646. err = errors.New(errMsg)
  647. return
  648. }
  649. for _, fm := range formulaSlice {
  650. formulaMap, e := utils.CheckFormula(fm)
  651. if e != nil {
  652. err = fmt.Errorf("公式错误,请重新填写")
  653. return
  654. }
  655. for _, f := range formulaMap {
  656. if !strings.Contains(formulaStr, f) {
  657. errMsg = "公式错误,请重新填写"
  658. err = errors.New(errMsg)
  659. return
  660. }
  661. }
  662. }
  663. //关联的指标信息
  664. edbInfoList := make([]*models.EdbInfo, 0)
  665. // 动态环差规则 关系表
  666. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  667. for k, tmpEdbInfoId := range v.EdbInfoIdArr {
  668. fromEdbInfo, tmpErr := models.GetEdbInfoById(tmpEdbInfoId.EdbInfoId)
  669. if tmpErr != nil {
  670. err = tmpErr
  671. if err.Error() == utils.ErrNoRow() {
  672. errMsg = "指标 " + strconv.Itoa(tmpEdbInfoId.EdbInfoId) + " 不存在"
  673. err = errors.New(errMsg)
  674. return
  675. }
  676. errMsg = "获取指标失败:Err:" + err.Error()
  677. err = errors.New(errMsg)
  678. return
  679. }
  680. edbInfoList = append(edbInfoList, fromEdbInfo)
  681. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  682. {
  683. if _, ok := fromEdbMap[tmpEdbInfoId.EdbInfoId]; !ok {
  684. fromEdbMap[tmpEdbInfoId.EdbInfoId] = tmpEdbInfoId.EdbInfoId
  685. calculateMappingItem := &models.EdbInfoCalculateMapping{
  686. EdbInfoCalculateMappingId: 0,
  687. EdbInfoId: edbInfoId,
  688. Source: utils.DATA_SOURCE_CALCULATE,
  689. SourceName: "指标运算",
  690. EdbCode: "",
  691. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  692. FromEdbCode: fromEdbInfo.EdbCode,
  693. FromEdbName: fromEdbInfo.EdbName,
  694. FromSource: fromEdbInfo.Source,
  695. FromSourceName: fromEdbInfo.SourceName,
  696. //FromTag: tmpEdbInfoId.FromTag,
  697. Sort: k + 1,
  698. CreateTime: time.Now(),
  699. ModifyTime: time.Now(),
  700. }
  701. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  702. }
  703. }
  704. // 动态环差规则 关系表
  705. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  706. //PredictEdbConfCalculateMappingId: 0,
  707. EdbInfoId: edbInfoId,
  708. ConfigId: 0,
  709. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  710. FromEdbCode: fromEdbInfo.EdbCode,
  711. FromEdbName: fromEdbInfo.EdbName,
  712. FromSource: fromEdbInfo.Source,
  713. FromSourceName: fromEdbInfo.SourceName,
  714. FromTag: tmpEdbInfoId.FromTag,
  715. Sort: k + 1,
  716. CreateTime: time.Now(),
  717. ModifyTime: time.Now(),
  718. }
  719. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  720. }
  721. for _, f := range formulaSlice {
  722. formulaMap, e := utils.CheckFormula(f)
  723. if e != nil {
  724. err = fmt.Errorf("公式错误,请重新填写")
  725. return
  726. }
  727. //预先计算,判断公式是否正常
  728. ok, _ := models.CheckFormula2(edbInfoList, formulaMap, f, edbInfoIdBytes)
  729. if !ok {
  730. errMsg = "生成计算指标失败,请使用正确的计算公式"
  731. err = errors.New(errMsg)
  732. return
  733. }
  734. }
  735. calculateRuleMap[ruleIndex] = models.CalculateRule{
  736. TrendsCalculateMappingList: trendsMappingList,
  737. EdbInfoList: edbInfoList,
  738. EdbInfoIdBytes: edbInfoIdBytes,
  739. Formula: formula,
  740. RuleType: v.RuleType,
  741. EndDate: v.EndDate,
  742. EdbInfoIdArr: v.EdbInfoIdArr,
  743. }
  744. case 14: //14:根据 一元线性拟合 规则获取预测数据
  745. if v.Value == "" {
  746. errMsg = "请填写一元线性拟合规则"
  747. err = errors.New(errMsg)
  748. return
  749. }
  750. //关联的指标信息
  751. edbInfoList := make([]*models.EdbInfo, 0)
  752. // 动态环差规则 关系表
  753. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  754. for k, tmpEdbInfoId := range v.EdbInfoIdArr {
  755. fromEdbInfo, tmpErr := models.GetEdbInfoById(tmpEdbInfoId.EdbInfoId)
  756. if tmpErr != nil {
  757. err = tmpErr
  758. if err.Error() == utils.ErrNoRow() {
  759. errMsg = "指标 " + strconv.Itoa(tmpEdbInfoId.EdbInfoId) + " 不存在"
  760. err = errors.New(errMsg)
  761. return
  762. }
  763. errMsg = "获取指标失败:Err:" + err.Error()
  764. err = errors.New(errMsg)
  765. return
  766. }
  767. edbInfoList = append(edbInfoList, fromEdbInfo)
  768. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  769. {
  770. if _, ok := fromEdbMap[tmpEdbInfoId.EdbInfoId]; !ok {
  771. fromEdbMap[tmpEdbInfoId.EdbInfoId] = tmpEdbInfoId.EdbInfoId
  772. tmpCalculateMappingItem := &models.EdbInfoCalculateMapping{
  773. EdbInfoCalculateMappingId: 0,
  774. EdbInfoId: 0,
  775. Source: utils.DATA_SOURCE_CALCULATE,
  776. SourceName: "指标运算",
  777. EdbCode: "",
  778. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  779. FromEdbCode: fromEdbInfo.EdbCode,
  780. FromEdbName: fromEdbInfo.EdbName,
  781. FromSource: fromEdbInfo.Source,
  782. FromSourceName: fromEdbInfo.SourceName,
  783. //FromTag: tmpEdbInfoId.FromTag,
  784. Sort: k + 1,
  785. CreateTime: time.Now(),
  786. ModifyTime: time.Now(),
  787. }
  788. calculateMappingList = append(calculateMappingList, tmpCalculateMappingItem)
  789. }
  790. }
  791. // 动态环差规则 关系表
  792. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  793. //PredictEdbConfCalculateMappingId: 0,
  794. EdbInfoId: 0,
  795. ConfigId: 0,
  796. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  797. FromEdbCode: fromEdbInfo.EdbCode,
  798. FromEdbName: fromEdbInfo.EdbName,
  799. FromSource: fromEdbInfo.Source,
  800. FromSourceName: fromEdbInfo.SourceName,
  801. FromTag: tmpEdbInfoId.FromTag,
  802. Sort: k + 1,
  803. CreateTime: time.Now(),
  804. ModifyTime: time.Now(),
  805. }
  806. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  807. }
  808. // todo
  809. calculateRuleMap[ruleIndex] = models.CalculateRule{
  810. TrendsCalculateMappingList: trendsMappingList,
  811. EdbInfoList: edbInfoList,
  812. //EdbInfoIdBytes: edbInfoIdBytes,
  813. //Formula: formula,
  814. RuleType: v.RuleType,
  815. EndDate: v.EndDate,
  816. EdbInfoIdArr: v.EdbInfoIdArr,
  817. }
  818. case 17, 18:
  819. //关联的指标信息
  820. edbInfoList := make([]*models.EdbInfo, 0)
  821. // 动态 关系表
  822. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  823. relateEdbInfoId, parseErr := strconv.Atoi(v.Value)
  824. if parseErr != nil {
  825. errMsg = "请填写正确的指标id"
  826. err = errors.New(errMsg)
  827. return
  828. }
  829. fromEdbInfo, tmpErr := models.GetEdbInfoById(relateEdbInfoId)
  830. if tmpErr != nil {
  831. err = tmpErr
  832. if err.Error() == utils.ErrNoRow() {
  833. errMsg = "指标 " + strconv.Itoa(relateEdbInfoId) + " 不存在"
  834. err = errors.New(errMsg)
  835. return
  836. }
  837. errMsg = "获取指标失败:Err:" + err.Error()
  838. err = errors.New(errMsg)
  839. return
  840. }
  841. edbInfoList = append(edbInfoList, fromEdbInfo)
  842. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  843. fromEdbMap[relateEdbInfoId] = relateEdbInfoId
  844. calculateMappingItem = &models.EdbInfoCalculateMapping{
  845. EdbInfoCalculateMappingId: 0,
  846. EdbInfoId: 0,
  847. Source: edbInfo.Source,
  848. SourceName: edbInfo.SourceName,
  849. EdbCode: "",
  850. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  851. FromEdbCode: fromEdbInfo.EdbCode,
  852. FromEdbName: fromEdbInfo.EdbName,
  853. FromSource: fromEdbInfo.Source,
  854. FromSourceName: fromEdbInfo.SourceName,
  855. //FromTag: tmpEdbInfoId.FromTag,
  856. Sort: 1,
  857. CreateTime: time.Now(),
  858. ModifyTime: time.Now(),
  859. }
  860. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  861. // 动态同比同差规则 关系表
  862. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  863. //PredictEdbConfCalculateMappingId: 0,
  864. EdbInfoId: 0,
  865. ConfigId: 0,
  866. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  867. FromEdbCode: fromEdbInfo.EdbCode,
  868. FromEdbName: fromEdbInfo.EdbName,
  869. FromSource: fromEdbInfo.Source,
  870. FromSourceName: fromEdbInfo.SourceName,
  871. Sort: 1,
  872. CreateTime: time.Now(),
  873. ModifyTime: time.Now(),
  874. }
  875. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  876. calculateRuleMap[ruleIndex] = models.CalculateRule{
  877. TrendsCalculateMappingList: trendsMappingList,
  878. EdbInfoList: edbInfoList,
  879. RuleType: v.RuleType,
  880. EndDate: v.EndDate,
  881. EdbInfoIdArr: v.EdbInfoIdArr,
  882. }
  883. }
  884. tmpPredictEdbConf := &models.PredictEdbConf{
  885. PredictEdbInfoId: edbInfoId,
  886. SourceEdbInfoId: sourceEdbInfo.EdbInfoId,
  887. RuleType: v.RuleType,
  888. //FixedValue: v.Value,
  889. Value: v.Value,
  890. EndDate: ruleEndDate,
  891. EndNum: v.EndNum,
  892. ModifyTime: time.Now(),
  893. CreateTime: time.Now(),
  894. }
  895. if endDateType == 0 {
  896. tmpPredictEdbConf.EndDate = ruleEndDate
  897. }
  898. // todo
  899. edbInfo.EndDate = v.EndDate
  900. predictEdbConfList = append(predictEdbConfList, tmpPredictEdbConf)
  901. }
  902. err, errMsg = models.EditPredictEdb(edbInfo, updateEdbInfoCol, calculateMappingList, predictEdbConfList, calculateRuleMap)
  903. return
  904. }
  905. // RefreshPredictEdbInfo 更新基础预测指标规则中的动态数据
  906. func RefreshPredictEdbInfo(edbInfoId int) (edbInfo *models.EdbInfo, err error, errMsg string) {
  907. // 指标信息校验
  908. {
  909. edbInfo, err = models.GetEdbInfoById(edbInfoId)
  910. if err != nil && !utils.IsErrNoRow(err) {
  911. errMsg = "刷新失败"
  912. err = errors.New("获取预测指标失败,Err:" + err.Error())
  913. return
  914. }
  915. if edbInfo == nil {
  916. errMsg = "找不到该预测指标"
  917. err = nil
  918. return
  919. }
  920. //必须是普通的指标
  921. if edbInfo.EdbInfoType != 1 {
  922. errMsg = "指标异常,不是预测指标"
  923. return
  924. }
  925. }
  926. // 配置 与 指标的 关联关系表
  927. list, err := models.GetPredictEdbConfCalculateMappingListByEdbInfoId(edbInfoId)
  928. if err != nil {
  929. return
  930. }
  931. // 没有关联指标,不需要刷新
  932. if len(list) <= 0 {
  933. return
  934. }
  935. // 配置关联的指标信息
  936. predictEdbConfCalculateMappingListMap := make(map[int][]*models.PredictEdbConfCalculateMapping)
  937. configIdList := make([]int, 0) //关联配置id
  938. edbInfoIdList := make([]int, 0) //关联指标配置id
  939. edbInfoIdMap := make(map[int]int, 0) //关联指标配置map
  940. for _, v := range list {
  941. configList, ok := predictEdbConfCalculateMappingListMap[v.ConfigId]
  942. if !ok {
  943. configList = make([]*models.PredictEdbConfCalculateMapping, 0)
  944. configIdList = append(configIdList, v.ConfigId)
  945. }
  946. if _, ok := edbInfoIdMap[v.FromEdbInfoId]; !ok {
  947. edbInfoIdList = append(edbInfoIdList, v.FromEdbInfoId)
  948. }
  949. configList = append(configList, v)
  950. predictEdbConfCalculateMappingListMap[v.ConfigId] = configList
  951. }
  952. predictEdbConfList, err := models.GetPredictEdbConfListByConfigIdList(configIdList)
  953. if err != nil {
  954. errMsg = "刷新失败"
  955. err = errors.New("获取预测指标配置信息失败,Err:" + err.Error())
  956. return
  957. }
  958. if len(predictEdbConfList) == 0 {
  959. errMsg = "找不到该预测指标配置"
  960. err = nil
  961. return
  962. }
  963. // 指标信息
  964. edbInfoList, err := models.GetEdbInfoByIdList(edbInfoIdList)
  965. if err != nil {
  966. err = errors.New("获取关联指标失败,Err:" + err.Error())
  967. return
  968. }
  969. // 指标信息map
  970. edbInfoListMap := make(map[int]*models.EdbInfo)
  971. for _, v := range edbInfoList {
  972. edbInfoListMap[v.EdbInfoId] = v
  973. }
  974. predictEdbConfAndDataList := make([]*models.PredictEdbConfAndData, 0)
  975. // 刷新所有的规则
  976. for _, v := range predictEdbConfList {
  977. // 每次规则计算的时候,产生的临时数据
  978. resultDataList := make([]*models.EdbInfoSearchData, 0)
  979. switch v.RuleType {
  980. case 9: //动态环差值
  981. if v.Value == "" {
  982. errMsg = "请填写计算规则"
  983. return
  984. }
  985. // todo 动态环差的空值类型处理
  986. formula := v.Value
  987. // 动态环差规则 关系表
  988. trendsMappingList := predictEdbConfCalculateMappingListMap[v.ConfigId]
  989. // 关联标签
  990. edbInfoIdArr := make([]models.EdbInfoFromTag, 0)
  991. //关联的指标信息
  992. edbInfoList := make([]*models.EdbInfo, 0)
  993. for _, trendsMapping := range trendsMappingList {
  994. tmpEdbInfo, ok := edbInfoListMap[trendsMapping.FromEdbInfoId]
  995. if ok {
  996. edbInfoList = append(edbInfoList, tmpEdbInfo)
  997. }
  998. // 关联标签
  999. edbInfoIdArr = append(edbInfoIdArr, models.EdbInfoFromTag{
  1000. EdbInfoId: trendsMapping.FromEdbInfoId,
  1001. FromTag: trendsMapping.FromTag,
  1002. })
  1003. }
  1004. //检验公式
  1005. var formulaStr string
  1006. var edbInfoIdBytes []string
  1007. for _, tmpEdbInfoId := range edbInfoIdArr {
  1008. formulaStr += tmpEdbInfoId.FromTag + ","
  1009. edbInfoIdBytes = append(edbInfoIdBytes, tmpEdbInfoId.FromTag)
  1010. }
  1011. formulaSlice, tErr := utils.CheckFormulaJson(formula)
  1012. if tErr != nil {
  1013. errMsg = "公式格式错误,请重新填写"
  1014. err = errors.New(errMsg)
  1015. return
  1016. }
  1017. for _, fm := range formulaSlice {
  1018. formulaMap, e := utils.CheckFormula(fm)
  1019. if e != nil {
  1020. err = fmt.Errorf("公式错误,请重新填写")
  1021. return
  1022. }
  1023. for _, f := range formulaMap {
  1024. if !strings.Contains(formulaStr, f) {
  1025. errMsg = "公式错误,请重新填写"
  1026. err = errors.New(errMsg)
  1027. return
  1028. }
  1029. }
  1030. //预先计算,判断公式是否正常
  1031. ok, _ := models.CheckFormula2(edbInfoList, formulaMap, fm, edbInfoIdBytes)
  1032. if !ok {
  1033. errMsg = "生成计算指标失败,请使用正确的计算公式"
  1034. return
  1035. }
  1036. }
  1037. rule := models.CalculateRule{
  1038. EdbInfoId: v.PredictEdbInfoId,
  1039. ConfigId: v.ConfigId,
  1040. TrendsCalculateMappingList: trendsMappingList,
  1041. EdbInfoList: edbInfoList,
  1042. EdbInfoIdBytes: edbInfoIdBytes,
  1043. Formula: formula,
  1044. RuleType: v.RuleType,
  1045. EndDate: v.EndDate.Format(utils.FormatDate),
  1046. EdbInfoIdArr: edbInfoIdArr,
  1047. }
  1048. resultDataList, err = models.RefreshCalculateByRuleBy9(rule)
  1049. if err != nil {
  1050. return
  1051. }
  1052. case 14: //14:根据 一元线性拟合 规则获取预测数据
  1053. if v.Value == "" {
  1054. errMsg = "一元线性拟合规则信息未配置"
  1055. return
  1056. }
  1057. err, errMsg = models.RefreshCalculateByRuleByLineNh(*edbInfo, predictEdbConfAndDataList, *v)
  1058. if err != nil {
  1059. return
  1060. }
  1061. }
  1062. // 规则配置(含数据)
  1063. tmpPredictEdbConfAndData := &models.PredictEdbConfAndData{
  1064. ConfigId: 0,
  1065. PredictEdbInfoId: 0,
  1066. SourceEdbInfoId: v.SourceEdbInfoId,
  1067. RuleType: v.RuleType,
  1068. FixedValue: v.FixedValue,
  1069. Value: v.Value,
  1070. EndDate: v.EndDate,
  1071. ModifyTime: v.ModifyTime,
  1072. CreateTime: v.CreateTime,
  1073. DataList: resultDataList,
  1074. }
  1075. predictEdbConfAndDataList = append(predictEdbConfAndDataList, tmpPredictEdbConfAndData)
  1076. }
  1077. return
  1078. }
  1079. // checkExistByEdbName
  1080. // @Description: 根据指标名称校验该指标是否存在库中
  1081. // @author: Roc
  1082. // @datetime 2024-04-18 14:58:52
  1083. // @param edbInfoType int
  1084. // @param edbName string
  1085. // @param lang string
  1086. // @return has bool
  1087. // @return err error
  1088. func checkExistByEdbName(edbInfoType int, edbName, lang string) (has bool, err error) {
  1089. var condition string
  1090. var pars []interface{}
  1091. condition += " AND edb_info_type=? "
  1092. pars = append(pars, edbInfoType)
  1093. switch lang {
  1094. case utils.EnLangVersion:
  1095. condition += " AND edb_name_en = ? "
  1096. default:
  1097. condition += " AND edb_name=? "
  1098. }
  1099. pars = append(pars, edbName)
  1100. count, err := models.GetEdbInfoCountByCondition(condition, pars)
  1101. if err != nil {
  1102. return
  1103. }
  1104. if count > 0 {
  1105. has = true
  1106. return
  1107. }
  1108. return
  1109. }
  1110. // checkExistByEdbNameAndEdbInfoId
  1111. // @Description: 根据指标名称和指标ID校验库中是否还存在其他同名指标
  1112. // @author: Roc
  1113. // @datetime 2024-04-18 15:00:19
  1114. // @param edbInfoType int
  1115. // @param edbInfoId int
  1116. // @param edbName string
  1117. // @param lang string
  1118. // @return has bool
  1119. // @return err error
  1120. func checkExistByEdbNameAndEdbInfoId(edbInfoType, edbInfoId int, edbName, lang string) (has bool, err error) {
  1121. var condition string
  1122. var pars []interface{}
  1123. condition += " AND edb_info_type=? "
  1124. pars = append(pars, edbInfoType)
  1125. condition += " AND edb_info_id<>? "
  1126. pars = append(pars, edbInfoId)
  1127. switch lang {
  1128. case utils.EnLangVersion:
  1129. condition += " AND edb_name_en = ? "
  1130. default:
  1131. condition += " AND edb_name=? "
  1132. }
  1133. pars = append(pars, edbName)
  1134. count, err := models.GetEdbInfoCountByCondition(condition, pars)
  1135. if err != nil {
  1136. return
  1137. }
  1138. if count > 0 {
  1139. has = true
  1140. return
  1141. }
  1142. return
  1143. }
  1144. // CheckExistByEdbNameAndEdbInfoId
  1145. // @Description: 根据指标名称和指标ID校验库中是否还存在其他同名指标
  1146. // @author: Roc
  1147. // @datetime 2024-04-18 15:01:44
  1148. // @param edbInfoType int
  1149. // @param edbInfoId int
  1150. // @param edbName string
  1151. // @param lang string
  1152. // @return has bool
  1153. // @return err error
  1154. func CheckExistByEdbNameAndEdbInfoId(edbInfoType, edbInfoId int, edbName, lang string) (has bool, err error) {
  1155. // 指标没有入库的情况
  1156. if edbInfoId == 0 {
  1157. return checkExistByEdbName(edbInfoType, edbName, lang)
  1158. }
  1159. //指标已经入库的情况
  1160. return checkExistByEdbNameAndEdbInfoId(edbInfoType, edbInfoId, edbName, lang)
  1161. }
  1162. // AddStaticPredictEdbInfo 新增静态指标数据
  1163. func AddStaticPredictEdbInfo(sourceEdbInfoId, classifyId int, edbName, frequency, unit string, sysUserId int, sysUserName, lang string) (edbInfo *models.EdbInfo, err error, errMsg string) {
  1164. var sourceEdbInfo *models.EdbInfo
  1165. // 来源指标信息校验
  1166. {
  1167. sourceEdbInfo, err = models.GetEdbInfoById(sourceEdbInfoId)
  1168. if err != nil && !utils.IsErrNoRow(err) {
  1169. errMsg = "新增失败"
  1170. err = errors.New("获取来源指标失败,Err:" + err.Error())
  1171. return
  1172. }
  1173. if sourceEdbInfo == nil {
  1174. errMsg = "找不到该来源指标"
  1175. err = errors.New(errMsg)
  1176. return
  1177. }
  1178. }
  1179. var classifyInfo *models.EdbClassify
  1180. // 来源分类信息校验
  1181. {
  1182. classifyInfo, err = models.GetEdbClassifyById(classifyId)
  1183. if err != nil && !utils.IsErrNoRow(err) {
  1184. errMsg = "新增失败"
  1185. err = errors.New("获取预测指标分类失败,Err:" + err.Error())
  1186. return
  1187. }
  1188. if classifyInfo == nil {
  1189. errMsg = "找不到该预测指标分类"
  1190. err = errors.New(errMsg)
  1191. return
  1192. }
  1193. //必须是预测指标分类
  1194. if classifyInfo.ClassifyType != 1 {
  1195. errMsg = "预测指标分类异常,不是预测指标分类"
  1196. err = errors.New(errMsg)
  1197. return
  1198. }
  1199. }
  1200. edbName = strings.Trim(edbName, " ")
  1201. edbCode := sourceEdbInfo.EdbCode + "_" + time.Now().Format(utils.FormatShortDateTimeUnSpace)
  1202. // 根据指标名称和指标ID校验库中是否还存在其他同名指标
  1203. existEdbName, err := CheckExistByEdbNameAndEdbInfoId(utils.PREDICT_EDB_INFO_TYPE, 0, edbName, lang)
  1204. if err != nil {
  1205. errMsg = "判断指标名称是否存在失败"
  1206. err = errors.New("判断指标名称是否存在失败,Err:" + err.Error())
  1207. return
  1208. }
  1209. if existEdbName {
  1210. errMsg = "指标名称已存在,请重新填写"
  1211. err = errors.New(errMsg)
  1212. return
  1213. }
  1214. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  1215. edbInfo = &models.EdbInfo{
  1216. //EdbInfoId: 0,
  1217. EdbInfoType: sourceEdbInfo.EdbInfoType,
  1218. SourceName: sourceEdbInfo.SourceName,
  1219. Source: sourceEdbInfo.Source,
  1220. EdbCode: edbCode,
  1221. EdbName: edbName,
  1222. EdbNameSource: edbName,
  1223. Frequency: frequency,
  1224. Unit: unit,
  1225. StartDate: sourceEdbInfo.StartDate,
  1226. EndDate: sourceEdbInfo.EndDate,
  1227. ClassifyId: classifyId,
  1228. SysUserId: sysUserId,
  1229. SysUserRealName: sysUserName,
  1230. UniqueCode: utils.MD5(utils.DATA_PREFIX + "_" + timestamp),
  1231. CreateTime: time.Now(),
  1232. ModifyTime: time.Now(),
  1233. MinValue: sourceEdbInfo.MinValue,
  1234. MaxValue: sourceEdbInfo.MaxValue,
  1235. EndValue: sourceEdbInfo.EndValue,
  1236. CalculateFormula: sourceEdbInfo.CalculateFormula,
  1237. EdbType: sourceEdbInfo.EdbType,
  1238. //Sort: sourceEdbInfo.,
  1239. LatestDate: sourceEdbInfo.LatestDate,
  1240. LatestValue: sourceEdbInfo.LatestValue,
  1241. MoveType: sourceEdbInfo.MoveType,
  1242. MoveFrequency: sourceEdbInfo.MoveFrequency,
  1243. NoUpdate: sourceEdbInfo.NoUpdate,
  1244. IsUpdate: sourceEdbInfo.IsUpdate,
  1245. ServerUrl: "",
  1246. EdbNameEn: edbName,
  1247. UnitEn: sourceEdbInfo.UnitEn,
  1248. DataDateType: sourceEdbInfo.DataDateType,
  1249. Sort: models.GetAddEdbMaxSortByClassifyId(classifyId, utils.PREDICT_EDB_INFO_TYPE),
  1250. IsStaticData: 1,
  1251. }
  1252. // 关联关系表
  1253. calculateMappingList := make([]*models.EdbInfoCalculateMapping, 0)
  1254. fromEdbMap := make(map[int]int)
  1255. // 源指标关联关系表
  1256. calculateMappingItem := &models.EdbInfoCalculateMapping{
  1257. //EdbInfoCalculateMappingId: 0,
  1258. //EdbInfoId: 0,
  1259. Source: edbInfo.Source,
  1260. SourceName: edbInfo.SourceName,
  1261. EdbCode: edbInfo.EdbCode,
  1262. FromEdbInfoId: sourceEdbInfo.EdbInfoId,
  1263. FromEdbCode: sourceEdbInfo.EdbCode,
  1264. FromEdbName: sourceEdbInfo.EdbName,
  1265. FromSource: sourceEdbInfo.Source,
  1266. FromSourceName: sourceEdbInfo.SourceName,
  1267. //FromTag: "",
  1268. Sort: 1,
  1269. CreateTime: time.Now(),
  1270. ModifyTime: time.Now(),
  1271. }
  1272. fromEdbMap[sourceEdbInfoId] = sourceEdbInfoId
  1273. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  1274. newPredictEdbConfList := make([]*models.PredictEdbConf, 0)
  1275. //查询原先的预测指标配置项
  1276. if sourceEdbInfo.EdbType == 1 {
  1277. // 查找该预测指标配置
  1278. predictEdbConfList, tmpErr := models.GetPredictEdbConfListById(sourceEdbInfo.EdbInfoId)
  1279. if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
  1280. errMsg = "获取预测指标配置信息失败"
  1281. err = errors.New("获取预测指标配置信息失败,Err:" + tmpErr.Error())
  1282. return
  1283. }
  1284. if len(predictEdbConfList) > 0 {
  1285. // 遍历
  1286. for _, v := range predictEdbConfList {
  1287. tmpPredictEdbConf := &models.PredictEdbConf{
  1288. PredictEdbInfoId: 0,
  1289. SourceEdbInfoId: sourceEdbInfoId,
  1290. RuleType: v.RuleType,
  1291. FixedValue: v.FixedValue,
  1292. Value: v.Value,
  1293. EmptyType: v.EmptyType,
  1294. MaxEmptyType: v.MaxEmptyType,
  1295. EndDate: v.EndDate,
  1296. ModifyTime: time.Now(),
  1297. CreateTime: time.Now(),
  1298. }
  1299. newPredictEdbConfList = append(newPredictEdbConfList, tmpPredictEdbConf)
  1300. }
  1301. }
  1302. }
  1303. err, errMsg = models.AddPredictStaticEdb(edbInfo, sourceEdbInfo, calculateMappingList, newPredictEdbConfList)
  1304. return
  1305. }