predict_edb.go 41 KB

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