predict_edb.go 40 KB

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