predict_edb.go 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422
  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. //calculateMappingList是映射关系,只需要记录一条,因此对list需要去重复
  458. calculateMappingList = RemoveDuplicateCalculateMappingList(calculateMappingList)
  459. err, errMsg = models.AddPredictEdb(edbInfo, calculateMappingList, predictEdbConfList, calculateRuleMap)
  460. return
  461. }
  462. func RemoveDuplicateCalculateMappingList(list []*models.EdbInfoCalculateMapping) (newList []*models.EdbInfoCalculateMapping) {
  463. newList = make([]*models.EdbInfoCalculateMapping, 0)
  464. tmpMap := make(map[int]bool)
  465. for _, v := range list {
  466. if _, ok := tmpMap[v.FromEdbInfoId]; !ok {
  467. tmpMap[v.FromEdbInfoId] = true
  468. newList = append(newList, v)
  469. }
  470. }
  471. return
  472. }
  473. // EditPredictEdbInfo 编辑预测指标
  474. 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) {
  475. // 指标信息校验
  476. {
  477. edbInfo, err = models.GetEdbInfoById(edbInfoId)
  478. if err != nil && !utils.IsErrNoRow(err) {
  479. errMsg = "修改失败"
  480. err = errors.New("获取预测指标失败,Err:" + err.Error())
  481. return
  482. }
  483. if edbInfo == nil {
  484. errMsg = "找不到该预测指标"
  485. err = errors.New(errMsg)
  486. return
  487. }
  488. //必须是普通的指标
  489. if edbInfo.EdbInfoType != 1 {
  490. errMsg = "指标异常,不是预测指标"
  491. err = errors.New(errMsg)
  492. return
  493. }
  494. }
  495. var predictEdbConf *models.PredictEdbConf
  496. // 指标配置信息校验
  497. {
  498. // 查找该预测指标配置
  499. predictEdbConfList, tmpErr := models.GetPredictEdbConfListById(edbInfo.EdbInfoId)
  500. if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
  501. errMsg = "修改失败"
  502. err = errors.New("获取预测指标配置信息失败,Err:" + tmpErr.Error())
  503. return
  504. }
  505. if len(predictEdbConfList) == 0 {
  506. errMsg = "找不到该预测指标配置"
  507. err = errors.New(errMsg)
  508. return
  509. }
  510. predictEdbConf = predictEdbConfList[0]
  511. }
  512. // 根据指标名称和指标ID校验库中是否还存在其他同名指标
  513. existEdbName, err := CheckExistByEdbNameAndEdbInfoId(utils.PREDICT_EDB_INFO_TYPE, edbInfoId, edbName, lang)
  514. if err != nil {
  515. errMsg = "判断指标名称是否存在失败"
  516. err = errors.New("判断指标名称是否存在失败,Err:" + err.Error())
  517. return
  518. }
  519. if existEdbName {
  520. errMsg = "指标名称已存在,请重新填写"
  521. err = errors.New(errMsg)
  522. return
  523. }
  524. if dataDateType == `` {
  525. dataDateType = `自然日`
  526. }
  527. switch lang {
  528. case utils.EnLangVersion:
  529. edbInfo.EdbNameEn = edbName
  530. default:
  531. edbInfo.EdbName = edbName
  532. }
  533. edbInfo.EdbNameSource = edbName
  534. edbInfo.ClassifyId = classifyId
  535. edbInfo.MinValue = minValue
  536. edbInfo.MaxValue = maxValue
  537. edbInfo.DataDateType = dataDateType
  538. edbInfo.ModifyTime = time.Now()
  539. edbInfo.EndDateType = endDateType
  540. updateEdbInfoCol := []string{"EdbName", "EdbNameEn", "EdbNameSource", "ClassifyId", "EndDate", "MinValue", "MaxValue", "DataDateType", "ModifyTime", "EndDateType"}
  541. var sourceEdbInfo *models.EdbInfo
  542. // 来源指标信息校验
  543. {
  544. sourceEdbInfo, err = models.GetEdbInfoById(predictEdbConf.SourceEdbInfoId)
  545. if err != nil && !utils.IsErrNoRow(err) {
  546. errMsg = "新增失败"
  547. err = errors.New("获取来源指标失败,Err:" + err.Error())
  548. return
  549. }
  550. if sourceEdbInfo == nil {
  551. errMsg = "找不到该来源指标"
  552. err = errors.New(errMsg)
  553. return
  554. }
  555. //必须是普通的指标
  556. if sourceEdbInfo.EdbInfoType != 0 {
  557. errMsg = "来源指标异常,不是普通的指标"
  558. err = errors.New(errMsg)
  559. return
  560. }
  561. //if !utils.InArrayByStr([]string{"日度", "周度", "月度", "年度"}, sourceEdbInfo.Frequency) {
  562. // errMsg = "预测指标只支持选择日度、周度、月度、年度的指标"
  563. // err = errors.New(errMsg)
  564. // return
  565. //}
  566. }
  567. // 预测指标配置
  568. // 关联关系表
  569. calculateMappingList := make([]*models.EdbInfoCalculateMapping, 0)
  570. fromEdbMap := make(map[int]int)
  571. // 源指标关联关系表
  572. calculateMappingItem := &models.EdbInfoCalculateMapping{
  573. //EdbInfoCalculateMappingId: 0,
  574. EdbInfoId: edbInfoId,
  575. Source: edbInfo.Source,
  576. SourceName: edbInfo.SourceName,
  577. EdbCode: edbInfo.EdbCode,
  578. FromEdbInfoId: sourceEdbInfo.EdbInfoId,
  579. FromEdbCode: sourceEdbInfo.EdbCode,
  580. FromEdbName: sourceEdbInfo.EdbName,
  581. FromSource: sourceEdbInfo.Source,
  582. FromSourceName: sourceEdbInfo.SourceName,
  583. //FromTag: "",
  584. Sort: 1,
  585. CreateTime: time.Now(),
  586. ModifyTime: time.Now(),
  587. }
  588. fromEdbMap[sourceEdbInfo.EdbInfoId] = sourceEdbInfo.EdbInfoId
  589. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  590. // 动态环差 计算列表
  591. calculateRuleMap := make(map[int]models.CalculateRule, 0)
  592. // 预测指标配置
  593. predictEdbConfList := make([]*models.PredictEdbConf, 0)
  594. for ruleIndex, v := range ruleList {
  595. var ruleEndDate time.Time
  596. if endDateType == 0 {
  597. // 预测指标配置
  598. ruleEndDate, err = time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
  599. if err != nil {
  600. errMsg = "规则配置的截止日期异常,请重新填写"
  601. err = errors.New(errMsg)
  602. return
  603. }
  604. } else {
  605. if v.EndNum <= 0 {
  606. errMsg = "截止期数不正确,请输入大于等于1的整数"
  607. err = errors.New(errMsg)
  608. return
  609. }
  610. }
  611. //1:最新,2:固定值,3:同比,4:同差,5:环比,6:环差,7:N期移动均值,8:N期段线性外推值,9:动态环差,10:根据 给定终值后插值 规则获取预测数据,11:根据 季节性 规则获取预测数据,12:根据 移动平均同比 规则获取预测数据
  612. // 环比、环差、动态环差、季节性、移动平均同比不支持年度
  613. if sourceEdbInfo.Frequency == "年度" && utils.InArrayByInt([]int{5, 6, 11, 12}, v.RuleType) {
  614. errMsg = "环比、环差、动态环差、季节性、移动平均同比不支持年度指标"
  615. err = errors.New(errMsg)
  616. return
  617. }
  618. if v.RuleType == 16 && endDateType == 1 {
  619. errMsg = "年度值倒推不支持截止期数"
  620. err = errors.New(errMsg)
  621. return
  622. }
  623. switch v.RuleType {
  624. case 8: //N期段线性外推值
  625. valInt, tmpErr := strconv.Atoi(v.Value)
  626. if tmpErr != nil {
  627. errMsg = "N期段线性外推值的N值异常"
  628. err = errors.New(errMsg)
  629. return
  630. }
  631. if valInt <= 1 {
  632. errMsg = "N期段线性外推值的N值必须大于1"
  633. err = errors.New(errMsg)
  634. return
  635. }
  636. case 9: //9:动态环差
  637. if v.Value == "" {
  638. errMsg = "请填写计算规则"
  639. err = errors.New(errMsg)
  640. return
  641. }
  642. formula := v.Value
  643. formula = strings.Replace(formula, "(", "(", -1)
  644. formula = strings.Replace(formula, ")", ")", -1)
  645. formula = strings.Replace(formula, ",", ",", -1)
  646. formula = strings.Replace(formula, "。", ".", -1)
  647. formula = strings.Replace(formula, "%", "*0.01", -1)
  648. v.Value = formula
  649. //检验公式
  650. var formulaStr string
  651. var edbInfoIdBytes []string
  652. for _, tmpEdbInfoId := range v.EdbInfoIdArr {
  653. formulaStr += tmpEdbInfoId.FromTag + ","
  654. edbInfoIdBytes = append(edbInfoIdBytes, tmpEdbInfoId.FromTag)
  655. }
  656. formulaSlice, tErr := utils.CheckFormulaJson(formula)
  657. if tErr != nil {
  658. errMsg = "公式格式错误,请重新填写"
  659. err = errors.New(errMsg)
  660. return
  661. }
  662. for _, fm := range formulaSlice {
  663. formulaMap, e := utils.CheckFormula(fm)
  664. if e != nil {
  665. err = fmt.Errorf("公式错误,请重新填写")
  666. return
  667. }
  668. for _, f := range formulaMap {
  669. if !strings.Contains(formulaStr, f) {
  670. errMsg = "公式错误,请重新填写"
  671. err = errors.New(errMsg)
  672. return
  673. }
  674. }
  675. }
  676. //关联的指标信息
  677. edbInfoList := make([]*models.EdbInfo, 0)
  678. // 动态环差规则 关系表
  679. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  680. for k, tmpEdbInfoId := range v.EdbInfoIdArr {
  681. fromEdbInfo, tmpErr := models.GetEdbInfoById(tmpEdbInfoId.EdbInfoId)
  682. if tmpErr != nil {
  683. err = tmpErr
  684. if err.Error() == utils.ErrNoRow() {
  685. errMsg = "指标 " + strconv.Itoa(tmpEdbInfoId.EdbInfoId) + " 不存在"
  686. err = errors.New(errMsg)
  687. return
  688. }
  689. errMsg = "获取指标失败:Err:" + err.Error()
  690. err = errors.New(errMsg)
  691. return
  692. }
  693. edbInfoList = append(edbInfoList, fromEdbInfo)
  694. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  695. {
  696. if _, ok := fromEdbMap[tmpEdbInfoId.EdbInfoId]; !ok {
  697. fromEdbMap[tmpEdbInfoId.EdbInfoId] = tmpEdbInfoId.EdbInfoId
  698. calculateMappingItem := &models.EdbInfoCalculateMapping{
  699. EdbInfoCalculateMappingId: 0,
  700. EdbInfoId: edbInfoId,
  701. Source: utils.DATA_SOURCE_CALCULATE,
  702. SourceName: "指标运算",
  703. EdbCode: "",
  704. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  705. FromEdbCode: fromEdbInfo.EdbCode,
  706. FromEdbName: fromEdbInfo.EdbName,
  707. FromSource: fromEdbInfo.Source,
  708. FromSourceName: fromEdbInfo.SourceName,
  709. //FromTag: tmpEdbInfoId.FromTag,
  710. Sort: k + 1,
  711. CreateTime: time.Now(),
  712. ModifyTime: time.Now(),
  713. }
  714. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  715. }
  716. }
  717. // 动态环差规则 关系表
  718. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  719. //PredictEdbConfCalculateMappingId: 0,
  720. EdbInfoId: edbInfoId,
  721. ConfigId: 0,
  722. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  723. FromEdbCode: fromEdbInfo.EdbCode,
  724. FromEdbName: fromEdbInfo.EdbName,
  725. FromSource: fromEdbInfo.Source,
  726. FromSourceName: fromEdbInfo.SourceName,
  727. FromTag: tmpEdbInfoId.FromTag,
  728. Sort: k + 1,
  729. CreateTime: time.Now(),
  730. ModifyTime: time.Now(),
  731. }
  732. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  733. }
  734. for _, f := range formulaSlice {
  735. formulaMap, e := utils.CheckFormula(f)
  736. if e != nil {
  737. err = fmt.Errorf("公式错误,请重新填写")
  738. return
  739. }
  740. //预先计算,判断公式是否正常
  741. ok, _ := models.CheckFormula2(edbInfoList, formulaMap, f, edbInfoIdBytes)
  742. if !ok {
  743. errMsg = "生成计算指标失败,请使用正确的计算公式"
  744. err = errors.New(errMsg)
  745. return
  746. }
  747. }
  748. calculateRuleMap[ruleIndex] = models.CalculateRule{
  749. TrendsCalculateMappingList: trendsMappingList,
  750. EdbInfoList: edbInfoList,
  751. EdbInfoIdBytes: edbInfoIdBytes,
  752. Formula: formula,
  753. RuleType: v.RuleType,
  754. EndDate: v.EndDate,
  755. EdbInfoIdArr: v.EdbInfoIdArr,
  756. }
  757. case 14: //14:根据 一元线性拟合 规则获取预测数据
  758. if v.Value == "" {
  759. errMsg = "请填写一元线性拟合规则"
  760. err = errors.New(errMsg)
  761. return
  762. }
  763. //关联的指标信息
  764. edbInfoList := make([]*models.EdbInfo, 0)
  765. // 动态环差规则 关系表
  766. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  767. for k, tmpEdbInfoId := range v.EdbInfoIdArr {
  768. fromEdbInfo, tmpErr := models.GetEdbInfoById(tmpEdbInfoId.EdbInfoId)
  769. if tmpErr != nil {
  770. err = tmpErr
  771. if err.Error() == utils.ErrNoRow() {
  772. errMsg = "指标 " + strconv.Itoa(tmpEdbInfoId.EdbInfoId) + " 不存在"
  773. err = errors.New(errMsg)
  774. return
  775. }
  776. errMsg = "获取指标失败:Err:" + err.Error()
  777. err = errors.New(errMsg)
  778. return
  779. }
  780. edbInfoList = append(edbInfoList, fromEdbInfo)
  781. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  782. {
  783. if _, ok := fromEdbMap[tmpEdbInfoId.EdbInfoId]; !ok {
  784. fromEdbMap[tmpEdbInfoId.EdbInfoId] = tmpEdbInfoId.EdbInfoId
  785. tmpCalculateMappingItem := &models.EdbInfoCalculateMapping{
  786. EdbInfoCalculateMappingId: 0,
  787. EdbInfoId: 0,
  788. Source: utils.DATA_SOURCE_CALCULATE,
  789. SourceName: "指标运算",
  790. EdbCode: "",
  791. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  792. FromEdbCode: fromEdbInfo.EdbCode,
  793. FromEdbName: fromEdbInfo.EdbName,
  794. FromSource: fromEdbInfo.Source,
  795. FromSourceName: fromEdbInfo.SourceName,
  796. //FromTag: tmpEdbInfoId.FromTag,
  797. Sort: k + 1,
  798. CreateTime: time.Now(),
  799. ModifyTime: time.Now(),
  800. }
  801. calculateMappingList = append(calculateMappingList, tmpCalculateMappingItem)
  802. }
  803. }
  804. // 动态环差规则 关系表
  805. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  806. //PredictEdbConfCalculateMappingId: 0,
  807. EdbInfoId: 0,
  808. ConfigId: 0,
  809. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  810. FromEdbCode: fromEdbInfo.EdbCode,
  811. FromEdbName: fromEdbInfo.EdbName,
  812. FromSource: fromEdbInfo.Source,
  813. FromSourceName: fromEdbInfo.SourceName,
  814. FromTag: tmpEdbInfoId.FromTag,
  815. Sort: k + 1,
  816. CreateTime: time.Now(),
  817. ModifyTime: time.Now(),
  818. }
  819. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  820. }
  821. // todo
  822. calculateRuleMap[ruleIndex] = models.CalculateRule{
  823. TrendsCalculateMappingList: trendsMappingList,
  824. EdbInfoList: edbInfoList,
  825. //EdbInfoIdBytes: edbInfoIdBytes,
  826. //Formula: formula,
  827. RuleType: v.RuleType,
  828. EndDate: v.EndDate,
  829. EdbInfoIdArr: v.EdbInfoIdArr,
  830. }
  831. case 17, 18:
  832. //关联的指标信息
  833. edbInfoList := make([]*models.EdbInfo, 0)
  834. // 动态 关系表
  835. trendsMappingList := make([]*models.PredictEdbConfCalculateMapping, 0)
  836. relateEdbInfoId, parseErr := strconv.Atoi(v.Value)
  837. if parseErr != nil {
  838. errMsg = "请填写正确的指标id"
  839. err = errors.New(errMsg)
  840. return
  841. }
  842. fromEdbInfo, tmpErr := models.GetEdbInfoById(relateEdbInfoId)
  843. if tmpErr != nil {
  844. err = tmpErr
  845. if err.Error() == utils.ErrNoRow() {
  846. errMsg = "指标 " + strconv.Itoa(relateEdbInfoId) + " 不存在"
  847. err = errors.New(errMsg)
  848. return
  849. }
  850. errMsg = "获取指标失败:Err:" + err.Error()
  851. err = errors.New(errMsg)
  852. return
  853. }
  854. edbInfoList = append(edbInfoList, fromEdbInfo)
  855. //总的 预测指标与所有相关联指标的关系表(不仅仅该条规则)
  856. fromEdbMap[relateEdbInfoId] = relateEdbInfoId
  857. calculateMappingItem = &models.EdbInfoCalculateMapping{
  858. EdbInfoCalculateMappingId: 0,
  859. EdbInfoId: 0,
  860. Source: edbInfo.Source,
  861. SourceName: edbInfo.SourceName,
  862. EdbCode: "",
  863. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  864. FromEdbCode: fromEdbInfo.EdbCode,
  865. FromEdbName: fromEdbInfo.EdbName,
  866. FromSource: fromEdbInfo.Source,
  867. FromSourceName: fromEdbInfo.SourceName,
  868. //FromTag: tmpEdbInfoId.FromTag,
  869. Sort: 1,
  870. CreateTime: time.Now(),
  871. ModifyTime: time.Now(),
  872. }
  873. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  874. // 动态同比同差规则 关系表
  875. tmpPredictEdbConfCalculateMapping := &models.PredictEdbConfCalculateMapping{
  876. //PredictEdbConfCalculateMappingId: 0,
  877. EdbInfoId: 0,
  878. ConfigId: 0,
  879. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  880. FromEdbCode: fromEdbInfo.EdbCode,
  881. FromEdbName: fromEdbInfo.EdbName,
  882. FromSource: fromEdbInfo.Source,
  883. FromSourceName: fromEdbInfo.SourceName,
  884. Sort: 1,
  885. CreateTime: time.Now(),
  886. ModifyTime: time.Now(),
  887. }
  888. trendsMappingList = append(trendsMappingList, tmpPredictEdbConfCalculateMapping)
  889. calculateRuleMap[ruleIndex] = models.CalculateRule{
  890. TrendsCalculateMappingList: trendsMappingList,
  891. EdbInfoList: edbInfoList,
  892. RuleType: v.RuleType,
  893. EndDate: v.EndDate,
  894. EdbInfoIdArr: v.EdbInfoIdArr,
  895. }
  896. }
  897. tmpPredictEdbConf := &models.PredictEdbConf{
  898. PredictEdbInfoId: edbInfoId,
  899. SourceEdbInfoId: sourceEdbInfo.EdbInfoId,
  900. RuleType: v.RuleType,
  901. //FixedValue: v.Value,
  902. Value: v.Value,
  903. EndDate: ruleEndDate,
  904. EndNum: v.EndNum,
  905. ModifyTime: time.Now(),
  906. CreateTime: time.Now(),
  907. }
  908. if endDateType == 0 {
  909. tmpPredictEdbConf.EndDate = ruleEndDate
  910. }
  911. // todo
  912. edbInfo.EndDate = v.EndDate
  913. predictEdbConfList = append(predictEdbConfList, tmpPredictEdbConf)
  914. }
  915. //编辑的时候也需要去重复calcuateMappingList
  916. calculateMappingList = RemoveDuplicateCalculateMappingList(calculateMappingList)
  917. err, errMsg = models.EditPredictEdb(edbInfo, updateEdbInfoCol, calculateMappingList, predictEdbConfList, calculateRuleMap)
  918. return
  919. }
  920. // RefreshPredictEdbInfo 更新基础预测指标规则中的动态数据
  921. func RefreshPredictEdbInfo(edbInfoId int) (edbInfo *models.EdbInfo, err error, errMsg string) {
  922. // 指标信息校验
  923. {
  924. edbInfo, err = models.GetEdbInfoById(edbInfoId)
  925. if err != nil && !utils.IsErrNoRow(err) {
  926. errMsg = "刷新失败"
  927. err = errors.New("获取预测指标失败,Err:" + err.Error())
  928. return
  929. }
  930. if edbInfo == nil {
  931. errMsg = "找不到该预测指标"
  932. err = nil
  933. return
  934. }
  935. //必须是普通的指标
  936. if edbInfo.EdbInfoType != 1 {
  937. errMsg = "指标异常,不是预测指标"
  938. return
  939. }
  940. }
  941. // 配置 与 指标的 关联关系表
  942. list, err := models.GetPredictEdbConfCalculateMappingListByEdbInfoId(edbInfoId)
  943. if err != nil {
  944. return
  945. }
  946. // 没有关联指标,不需要刷新
  947. if len(list) <= 0 {
  948. return
  949. }
  950. // 配置关联的指标信息
  951. predictEdbConfCalculateMappingListMap := make(map[int][]*models.PredictEdbConfCalculateMapping)
  952. configIdList := make([]int, 0) //关联配置id
  953. edbInfoIdList := make([]int, 0) //关联指标配置id
  954. edbInfoIdMap := make(map[int]int, 0) //关联指标配置map
  955. for _, v := range list {
  956. configList, ok := predictEdbConfCalculateMappingListMap[v.ConfigId]
  957. if !ok {
  958. configList = make([]*models.PredictEdbConfCalculateMapping, 0)
  959. configIdList = append(configIdList, v.ConfigId)
  960. }
  961. if _, ok := edbInfoIdMap[v.FromEdbInfoId]; !ok {
  962. edbInfoIdList = append(edbInfoIdList, v.FromEdbInfoId)
  963. }
  964. configList = append(configList, v)
  965. predictEdbConfCalculateMappingListMap[v.ConfigId] = configList
  966. }
  967. predictEdbConfList, err := models.GetPredictEdbConfListByConfigIdList(configIdList)
  968. if err != nil {
  969. errMsg = "刷新失败"
  970. err = errors.New("获取预测指标配置信息失败,Err:" + err.Error())
  971. return
  972. }
  973. if len(predictEdbConfList) == 0 {
  974. errMsg = "找不到该预测指标配置"
  975. err = nil
  976. return
  977. }
  978. // 指标信息
  979. edbInfoList, err := models.GetEdbInfoByIdList(edbInfoIdList)
  980. if err != nil {
  981. err = errors.New("获取关联指标失败,Err:" + err.Error())
  982. return
  983. }
  984. // 指标信息map
  985. edbInfoListMap := make(map[int]*models.EdbInfo)
  986. for _, v := range edbInfoList {
  987. edbInfoListMap[v.EdbInfoId] = v
  988. }
  989. predictEdbConfAndDataList := make([]*models.PredictEdbConfAndData, 0)
  990. // 刷新所有的规则
  991. for _, v := range predictEdbConfList {
  992. // 每次规则计算的时候,产生的临时数据
  993. resultDataList := make([]*models.EdbInfoSearchData, 0)
  994. switch v.RuleType {
  995. case 9: //动态环差值
  996. if v.Value == "" {
  997. errMsg = "请填写计算规则"
  998. return
  999. }
  1000. // todo 动态环差的空值类型处理
  1001. formula := v.Value
  1002. // 动态环差规则 关系表
  1003. trendsMappingList := predictEdbConfCalculateMappingListMap[v.ConfigId]
  1004. // 关联标签
  1005. edbInfoIdArr := make([]models.EdbInfoFromTag, 0)
  1006. //关联的指标信息
  1007. edbInfoList := make([]*models.EdbInfo, 0)
  1008. for _, trendsMapping := range trendsMappingList {
  1009. tmpEdbInfo, ok := edbInfoListMap[trendsMapping.FromEdbInfoId]
  1010. if ok {
  1011. edbInfoList = append(edbInfoList, tmpEdbInfo)
  1012. }
  1013. // 关联标签
  1014. edbInfoIdArr = append(edbInfoIdArr, models.EdbInfoFromTag{
  1015. EdbInfoId: trendsMapping.FromEdbInfoId,
  1016. FromTag: trendsMapping.FromTag,
  1017. })
  1018. }
  1019. //检验公式
  1020. var formulaStr string
  1021. var edbInfoIdBytes []string
  1022. for _, tmpEdbInfoId := range edbInfoIdArr {
  1023. formulaStr += tmpEdbInfoId.FromTag + ","
  1024. edbInfoIdBytes = append(edbInfoIdBytes, tmpEdbInfoId.FromTag)
  1025. }
  1026. formulaSlice, tErr := utils.CheckFormulaJson(formula)
  1027. if tErr != nil {
  1028. errMsg = "公式格式错误,请重新填写"
  1029. err = errors.New(errMsg)
  1030. return
  1031. }
  1032. for _, fm := range formulaSlice {
  1033. formulaMap, e := utils.CheckFormula(fm)
  1034. if e != nil {
  1035. err = fmt.Errorf("公式错误,请重新填写")
  1036. return
  1037. }
  1038. for _, f := range formulaMap {
  1039. if !strings.Contains(formulaStr, f) {
  1040. errMsg = "公式错误,请重新填写"
  1041. err = errors.New(errMsg)
  1042. return
  1043. }
  1044. }
  1045. //预先计算,判断公式是否正常
  1046. ok, _ := models.CheckFormula2(edbInfoList, formulaMap, fm, edbInfoIdBytes)
  1047. if !ok {
  1048. errMsg = "生成计算指标失败,请使用正确的计算公式"
  1049. return
  1050. }
  1051. }
  1052. rule := models.CalculateRule{
  1053. EdbInfoId: v.PredictEdbInfoId,
  1054. ConfigId: v.ConfigId,
  1055. TrendsCalculateMappingList: trendsMappingList,
  1056. EdbInfoList: edbInfoList,
  1057. EdbInfoIdBytes: edbInfoIdBytes,
  1058. Formula: formula,
  1059. RuleType: v.RuleType,
  1060. EndDate: v.EndDate.Format(utils.FormatDate),
  1061. EdbInfoIdArr: edbInfoIdArr,
  1062. }
  1063. resultDataList, err = models.RefreshCalculateByRuleBy9(rule)
  1064. if err != nil {
  1065. return
  1066. }
  1067. case 14: //14:根据 一元线性拟合 规则获取预测数据
  1068. if v.Value == "" {
  1069. errMsg = "一元线性拟合规则信息未配置"
  1070. return
  1071. }
  1072. err, errMsg = models.RefreshCalculateByRuleByLineNh(*edbInfo, predictEdbConfAndDataList, *v)
  1073. if err != nil {
  1074. return
  1075. }
  1076. }
  1077. // 规则配置(含数据)
  1078. tmpPredictEdbConfAndData := &models.PredictEdbConfAndData{
  1079. ConfigId: 0,
  1080. PredictEdbInfoId: 0,
  1081. SourceEdbInfoId: v.SourceEdbInfoId,
  1082. RuleType: v.RuleType,
  1083. FixedValue: v.FixedValue,
  1084. Value: v.Value,
  1085. EndDate: v.EndDate,
  1086. ModifyTime: v.ModifyTime,
  1087. CreateTime: v.CreateTime,
  1088. DataList: resultDataList,
  1089. }
  1090. predictEdbConfAndDataList = append(predictEdbConfAndDataList, tmpPredictEdbConfAndData)
  1091. }
  1092. return
  1093. }
  1094. // checkExistByEdbName
  1095. // @Description: 根据指标名称校验该指标是否存在库中
  1096. // @author: Roc
  1097. // @datetime 2024-04-18 14:58:52
  1098. // @param edbInfoType int
  1099. // @param edbName string
  1100. // @param lang string
  1101. // @return has bool
  1102. // @return err error
  1103. func checkExistByEdbName(edbInfoType int, edbName, lang string) (has bool, err error) {
  1104. var condition string
  1105. var pars []interface{}
  1106. condition += " AND edb_info_type=? "
  1107. pars = append(pars, edbInfoType)
  1108. switch lang {
  1109. case utils.EnLangVersion:
  1110. condition += " AND edb_name_en = ? "
  1111. default:
  1112. condition += " AND edb_name=? "
  1113. }
  1114. pars = append(pars, edbName)
  1115. count, err := models.GetEdbInfoCountByCondition(condition, pars)
  1116. if err != nil {
  1117. return
  1118. }
  1119. if count > 0 {
  1120. has = true
  1121. return
  1122. }
  1123. return
  1124. }
  1125. // checkExistByEdbNameAndEdbInfoId
  1126. // @Description: 根据指标名称和指标ID校验库中是否还存在其他同名指标
  1127. // @author: Roc
  1128. // @datetime 2024-04-18 15:00:19
  1129. // @param edbInfoType int
  1130. // @param edbInfoId int
  1131. // @param edbName string
  1132. // @param lang string
  1133. // @return has bool
  1134. // @return err error
  1135. func checkExistByEdbNameAndEdbInfoId(edbInfoType, edbInfoId int, edbName, lang string) (has bool, err error) {
  1136. var condition string
  1137. var pars []interface{}
  1138. condition += " AND edb_info_type=? "
  1139. pars = append(pars, edbInfoType)
  1140. condition += " AND edb_info_id<>? "
  1141. pars = append(pars, edbInfoId)
  1142. switch lang {
  1143. case utils.EnLangVersion:
  1144. condition += " AND edb_name_en = ? "
  1145. default:
  1146. condition += " AND edb_name=? "
  1147. }
  1148. pars = append(pars, edbName)
  1149. count, err := models.GetEdbInfoCountByCondition(condition, pars)
  1150. if err != nil {
  1151. return
  1152. }
  1153. if count > 0 {
  1154. has = true
  1155. return
  1156. }
  1157. return
  1158. }
  1159. // CheckExistByEdbNameAndEdbInfoId
  1160. // @Description: 根据指标名称和指标ID校验库中是否还存在其他同名指标
  1161. // @author: Roc
  1162. // @datetime 2024-04-18 15:01:44
  1163. // @param edbInfoType int
  1164. // @param edbInfoId int
  1165. // @param edbName string
  1166. // @param lang string
  1167. // @return has bool
  1168. // @return err error
  1169. func CheckExistByEdbNameAndEdbInfoId(edbInfoType, edbInfoId int, edbName, lang string) (has bool, err error) {
  1170. // 指标没有入库的情况
  1171. if edbInfoId == 0 {
  1172. return checkExistByEdbName(edbInfoType, edbName, lang)
  1173. }
  1174. //指标已经入库的情况
  1175. return checkExistByEdbNameAndEdbInfoId(edbInfoType, edbInfoId, edbName, lang)
  1176. }
  1177. // AddStaticPredictEdbInfo 新增静态指标数据
  1178. func AddStaticPredictEdbInfo(sourceEdbInfoId, classifyId int, edbName, frequency, unit string, sysUserId int, sysUserName, lang string) (edbInfo *models.EdbInfo, err error, errMsg string) {
  1179. var sourceEdbInfo *models.EdbInfo
  1180. // 来源指标信息校验
  1181. {
  1182. sourceEdbInfo, err = models.GetEdbInfoById(sourceEdbInfoId)
  1183. if err != nil && !utils.IsErrNoRow(err) {
  1184. errMsg = "新增失败"
  1185. err = errors.New("获取来源指标失败,Err:" + err.Error())
  1186. return
  1187. }
  1188. if sourceEdbInfo == nil {
  1189. errMsg = "找不到该来源指标"
  1190. err = errors.New(errMsg)
  1191. return
  1192. }
  1193. }
  1194. var classifyInfo *models.EdbClassify
  1195. // 来源分类信息校验
  1196. {
  1197. classifyInfo, err = models.GetEdbClassifyById(classifyId)
  1198. if err != nil && !utils.IsErrNoRow(err) {
  1199. errMsg = "新增失败"
  1200. err = errors.New("获取预测指标分类失败,Err:" + err.Error())
  1201. return
  1202. }
  1203. if classifyInfo == nil {
  1204. errMsg = "找不到该预测指标分类"
  1205. err = errors.New(errMsg)
  1206. return
  1207. }
  1208. //必须是预测指标分类
  1209. if classifyInfo.ClassifyType != 1 {
  1210. errMsg = "预测指标分类异常,不是预测指标分类"
  1211. err = errors.New(errMsg)
  1212. return
  1213. }
  1214. }
  1215. edbName = strings.Trim(edbName, " ")
  1216. edbCode := sourceEdbInfo.EdbCode + "_" + time.Now().Format(utils.FormatShortDateTimeUnSpace)
  1217. // 根据指标名称和指标ID校验库中是否还存在其他同名指标
  1218. existEdbName, err := CheckExistByEdbNameAndEdbInfoId(utils.PREDICT_EDB_INFO_TYPE, 0, edbName, lang)
  1219. if err != nil {
  1220. errMsg = "判断指标名称是否存在失败"
  1221. err = errors.New("判断指标名称是否存在失败,Err:" + err.Error())
  1222. return
  1223. }
  1224. if existEdbName {
  1225. errMsg = "指标名称已存在,请重新填写"
  1226. err = errors.New(errMsg)
  1227. return
  1228. }
  1229. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  1230. edbInfo = &models.EdbInfo{
  1231. //EdbInfoId: 0,
  1232. EdbInfoType: sourceEdbInfo.EdbInfoType,
  1233. SourceName: sourceEdbInfo.SourceName,
  1234. Source: sourceEdbInfo.Source,
  1235. EdbCode: edbCode,
  1236. EdbName: edbName,
  1237. EdbNameSource: edbName,
  1238. Frequency: frequency,
  1239. Unit: unit,
  1240. StartDate: sourceEdbInfo.StartDate,
  1241. EndDate: sourceEdbInfo.EndDate,
  1242. ClassifyId: classifyId,
  1243. SysUserId: sysUserId,
  1244. SysUserRealName: sysUserName,
  1245. UniqueCode: utils.MD5(utils.DATA_PREFIX + "_" + timestamp),
  1246. CreateTime: time.Now(),
  1247. ModifyTime: time.Now(),
  1248. MinValue: sourceEdbInfo.MinValue,
  1249. MaxValue: sourceEdbInfo.MaxValue,
  1250. EndValue: sourceEdbInfo.EndValue,
  1251. CalculateFormula: sourceEdbInfo.CalculateFormula,
  1252. EdbType: sourceEdbInfo.EdbType,
  1253. //Sort: sourceEdbInfo.,
  1254. LatestDate: sourceEdbInfo.LatestDate,
  1255. LatestValue: sourceEdbInfo.LatestValue,
  1256. MoveType: sourceEdbInfo.MoveType,
  1257. MoveFrequency: sourceEdbInfo.MoveFrequency,
  1258. NoUpdate: sourceEdbInfo.NoUpdate,
  1259. IsUpdate: sourceEdbInfo.IsUpdate,
  1260. ServerUrl: "",
  1261. EdbNameEn: edbName,
  1262. UnitEn: sourceEdbInfo.UnitEn,
  1263. DataDateType: sourceEdbInfo.DataDateType,
  1264. Sort: models.GetAddEdbMaxSortByClassifyId(classifyId, utils.PREDICT_EDB_INFO_TYPE),
  1265. IsStaticData: 1,
  1266. }
  1267. // 关联关系表
  1268. calculateMappingList := make([]*models.EdbInfoCalculateMapping, 0)
  1269. fromEdbMap := make(map[int]int)
  1270. // 源指标关联关系表
  1271. calculateMappingItem := &models.EdbInfoCalculateMapping{
  1272. //EdbInfoCalculateMappingId: 0,
  1273. //EdbInfoId: 0,
  1274. Source: edbInfo.Source,
  1275. SourceName: edbInfo.SourceName,
  1276. EdbCode: edbInfo.EdbCode,
  1277. FromEdbInfoId: sourceEdbInfo.EdbInfoId,
  1278. FromEdbCode: sourceEdbInfo.EdbCode,
  1279. FromEdbName: sourceEdbInfo.EdbName,
  1280. FromSource: sourceEdbInfo.Source,
  1281. FromSourceName: sourceEdbInfo.SourceName,
  1282. //FromTag: "",
  1283. Sort: 1,
  1284. CreateTime: time.Now(),
  1285. ModifyTime: time.Now(),
  1286. }
  1287. fromEdbMap[sourceEdbInfoId] = sourceEdbInfoId
  1288. calculateMappingList = append(calculateMappingList, calculateMappingItem)
  1289. newPredictEdbConfList := make([]*models.PredictEdbConf, 0)
  1290. //查询原先的预测指标配置项
  1291. if sourceEdbInfo.EdbType == 1 {
  1292. // 查找该预测指标配置
  1293. predictEdbConfList, tmpErr := models.GetPredictEdbConfListById(sourceEdbInfo.EdbInfoId)
  1294. if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
  1295. errMsg = "获取预测指标配置信息失败"
  1296. err = errors.New("获取预测指标配置信息失败,Err:" + tmpErr.Error())
  1297. return
  1298. }
  1299. if len(predictEdbConfList) > 0 {
  1300. // 遍历
  1301. for _, v := range predictEdbConfList {
  1302. tmpPredictEdbConf := &models.PredictEdbConf{
  1303. PredictEdbInfoId: 0,
  1304. SourceEdbInfoId: sourceEdbInfoId,
  1305. RuleType: v.RuleType,
  1306. FixedValue: v.FixedValue,
  1307. Value: v.Value,
  1308. EmptyType: v.EmptyType,
  1309. MaxEmptyType: v.MaxEmptyType,
  1310. EndDate: v.EndDate,
  1311. ModifyTime: time.Now(),
  1312. CreateTime: time.Now(),
  1313. }
  1314. newPredictEdbConfList = append(newPredictEdbConfList, tmpPredictEdbConf)
  1315. }
  1316. }
  1317. }
  1318. err, errMsg = models.AddPredictStaticEdb(edbInfo, sourceEdbInfo, calculateMappingList, newPredictEdbConfList)
  1319. return
  1320. }