Browse Source

fix:预测指标刷新

Roc 2 years ago
parent
commit
76b84a806f

+ 8 - 86
controllers/base_from_predict.go

@@ -111,8 +111,8 @@ func editPredict(br *models.BaseResponse, req models.AddPredictEdbInfoReq) {
 }
 
 // Refresh
-// @Title 刷新计算指标接口
-// @Description 刷新计算指标接口
+// @Title 刷新预测指标接口(有些预测指标里面含有动态数据)
+// @Description 刷新预测指标接口(有些预测指标里面含有动态数据)
 // @Success 200 {object} models.RefreshEdbInfoReq
 // @router /refresh [post]
 func (this *PredictController) Refresh() {
@@ -159,92 +159,14 @@ func (this *PredictController) Refresh() {
 		_ = utils.Rc.Delete(cacheKey)
 
 	}()
-	startDate := req.StartDate
 	var errMsg string
-	edbInfoId := edbInfo.EdbInfoId
-	source := edbInfo.Source
-
-	var latestDateStr string // 最近实际数据的日期
-	var latestValue float64  // 最近实际数据的值
-	switch source {
-	case utils.DATA_SOURCE_PREDICT_CALCULATE:
-		//startDate = edbInfo.StartDate
-		//sTime, err := time.Parse(utils.FormatDate, edbInfo.EndDate)
-		//if err != nil {
-		//	return
-		//}
-		//startDate = sTime.Format(utils.FormatDate)
-		startDate = ""
-		var edbInfoIdBytes []string
-		calculateMap, err := models.GetEdbInfoCalculateDetailList(edbInfo.EdbInfoId)
-		if err != nil {
-			errMsg = "GetEdbInfoCalculateDetail Err:" + err.Error()
-			break
-		}
-		var formulaStr string
-		edbInfoList := make([]*models.EdbInfo, 0)
-
-		for _, v := range calculateMap {
-			formulaStr += v.FromTag + ","
-			edbInfoIdBytes = append(edbInfoIdBytes, v.FromTag)
-			edbInfo, _ := models.GetEdbInfoById(v.FromEdbInfoId)
-			edbInfoList = append(edbInfoList, edbInfo)
-		}
-		latestDateStr, latestValue, err = models.RefreshAllPredictCalculate(edbInfoList, edbInfo.EdbInfoId, source, edbInfo.EdbCode, edbInfo.CalculateFormula, startDate, edbInfoIdBytes)
-		if err != nil && err.Error() != utils.ErrNoRow() {
-			errMsg = "RefreshCalculate Err:" + err.Error()
-			break
-		}
-	case utils.DATA_SOURCE_PREDICT_CALCULATE_TBZ: //刷新同比值
-		calculateTbz, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
-		if err != nil {
-			errMsg = "GetEdbInfoCalculateTbzDetail Err:" + err.Error()
-			break
-		}
-		fromEdbInfo, err := models.GetEdbInfoById(calculateTbz.FromEdbInfoId)
-		if err != nil {
-			errMsg = "GetEdbInfoById Err:" + err.Error()
-			break
-		}
-		startDate = edbInfo.StartDate
-		latestDateStr, latestValue, err = models.RefreshAllPredictCalculateTbz(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate)
-		if err != nil && err.Error() != utils.ErrNoRow() {
-			errMsg = "RefreshAllCalculateTbz Err:" + err.Error()
-			break
-		}
-	case utils.DATA_SOURCE_PREDICT_CALCULATE_TCZ: //同差值
-		calculateTcz, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
-		if err != nil {
-			errMsg = "GetEdbInfoCalculateTczDetail Err:" + err.Error()
-			break
-		}
-		fromEdbInfo, err := models.GetEdbInfoById(calculateTcz.FromEdbInfoId)
-		if err != nil {
-			errMsg = "GetEdbInfoById Err:" + err.Error()
-			break
-		}
-		startDate = edbInfo.StartDate
-		latestDateStr, latestValue, err = models.RefreshAllPredictCalculateTcz(edbInfoId, source, fromEdbInfo, calculateTcz.EdbCode, startDate)
-		if err != nil && err.Error() != utils.ErrNoRow() {
-			errMsg = "RefreshCalculateTcz Err:" + err.Error()
-			break
-		}
-	default:
-		br.Msg = "来源异常,请联系相关开发!"
-		br.ErrMsg = "来源异常,请联系相关开发"
-		return
-	}
-	if errMsg != `` {
-		br.Msg = "刷新指标失败!"
-		br.ErrMsg = "刷新指标失败,err:" + errMsg
-		return
-	}
-
-	// 更新指标最大最小值
-	err, errMsg = models.UnifiedModifyPredictEdbInfoMaxAndMinInfo(edbInfo, latestDateStr, latestValue)
+	_, err, errMsg = logic.RefreshPredictEdbInfo(req.EdbInfoId)
 	if err != nil {
-		br.Msg = errMsg
-		br.ErrMsg = err.Error()
+		br.Msg = "刷新指标失败!"
+		if errMsg != `` {
+			br.ErrMsg = errMsg
+		}
+		br.ErrMsg = "刷新指标失败,err:" + err.Error()
 		return
 	}
 

+ 147 - 0
logic/predict_edb.go

@@ -561,3 +561,150 @@ func EditPredictEdbInfo(edbInfoId, classifyId int, edbName string, ruleList []mo
 	}
 	return
 }
+
+// RefreshPredictEdbInfo 更新基础预测指标规则中的动态数据
+func RefreshPredictEdbInfo(edbInfoId int) (edbInfo *models.EdbInfo, err error, errMsg string) {
+	// 指标信息校验
+	{
+		edbInfo, err = models.GetEdbInfoById(edbInfoId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			errMsg = "刷新失败"
+			err = errors.New("获取预测指标失败,Err:" + err.Error())
+			return
+		}
+		if edbInfo == nil {
+			errMsg = "找不到该预测指标"
+			err = nil
+			return
+		}
+		//必须是普通的指标
+		if edbInfo.EdbInfoType != 1 {
+			errMsg = "指标异常,不是预测指标"
+			return
+		}
+	}
+
+	// 配置 与 指标的 关联关系表
+	list, err := models.GetPredictEdbConfCalculateMappingListByEdbInfoId(edbInfoId)
+	if err != nil {
+		return
+	}
+	// 没有关联指标,不需要刷新
+	if len(list) <= 0 {
+		return
+	}
+
+	// 配置关联的指标信息
+	predictEdbConfCalculateMappingListMap := make(map[int][]*models.PredictEdbConfCalculateMapping)
+	configIdList := make([]int, 0)       //关联配置id
+	edbInfoIdList := make([]int, 0)      //关联指标配置id
+	edbInfoIdMap := make(map[int]int, 0) //关联指标配置map
+	for _, v := range list {
+		configList, ok := predictEdbConfCalculateMappingListMap[v.ConfigId]
+		if !ok {
+			configList = make([]*models.PredictEdbConfCalculateMapping, 0)
+			configIdList = append(configIdList, v.ConfigId)
+		}
+		if _, ok := edbInfoIdMap[v.FromEdbInfoId]; !ok {
+			edbInfoIdList = append(edbInfoIdList, v.FromEdbInfoId)
+		}
+		configList = append(configList, v)
+		predictEdbConfCalculateMappingListMap[v.ConfigId] = configList
+	}
+
+	predictEdbConfList, err := models.GetPredictEdbConfListByConfigIdList(configIdList)
+	if err != nil {
+		errMsg = "刷新失败"
+		err = errors.New("获取预测指标配置信息失败,Err:" + err.Error())
+		return
+	}
+	if len(predictEdbConfList) == 0 {
+		errMsg = "找不到该预测指标配置"
+		err = nil
+		return
+	}
+
+	// 指标信息
+	edbInfoList, err := models.GetEdbInfoByIdList(edbInfoIdList)
+	if err != nil {
+		err = errors.New("获取关联指标失败,Err:" + err.Error())
+		return
+	}
+	// 指标信息map
+	edbInfoListMap := make(map[int]*models.EdbInfo)
+	for _, v := range edbInfoList {
+		edbInfoListMap[v.EdbInfoId] = v
+	}
+
+	// 刷新所有的规则
+	for _, v := range predictEdbConfList {
+		switch v.RuleType {
+		case 9:
+			if v.Value == "" {
+				errMsg = "请填写计算规则"
+				return
+			}
+			formula := v.Value
+
+			// 动态环差规则 关系表
+			trendsMappingList := predictEdbConfCalculateMappingListMap[v.ConfigId]
+
+			// 关联标签
+			edbInfoIdArr := make([]models.EdbInfoFromTag, 0)
+
+			//关联的指标信息
+			edbInfoList := make([]*models.EdbInfo, 0)
+			for _, trendsMapping := range trendsMappingList {
+				tmpEdbInfo, ok := edbInfoListMap[trendsMapping.FromEdbInfoId]
+				if ok {
+					edbInfoList = append(edbInfoList, tmpEdbInfo)
+				}
+
+				// 关联标签
+				edbInfoIdArr = append(edbInfoIdArr, models.EdbInfoFromTag{
+					EdbInfoId: trendsMapping.FromEdbInfoId,
+					FromTag:   trendsMapping.FromTag,
+				})
+			}
+
+			//检验公式
+			var formulaStr string
+			var edbInfoIdBytes []string
+			for _, tmpEdbInfoId := range edbInfoIdArr {
+				formulaStr += tmpEdbInfoId.FromTag + ","
+				edbInfoIdBytes = append(edbInfoIdBytes, tmpEdbInfoId.FromTag)
+			}
+			formulaMap := services.CheckFormula(formula)
+			for _, formula := range formulaMap {
+				if !strings.Contains(formulaStr, formula) {
+					errMsg = "公式错误,请重新填写"
+					return
+				}
+			}
+
+			ok, _ := models.CheckFormula2(edbInfoList, formulaMap, formula, edbInfoIdBytes)
+			if !ok {
+				errMsg = "生成计算指标失败,请使用正确的计算公式"
+				return
+			}
+
+			rule := models.CalculateRule{
+				EdbInfoId:                  v.PredictEdbInfoId,
+				ConfigId:                   v.ConfigId,
+				TrendsCalculateMappingList: trendsMappingList,
+				EdbInfoList:                edbInfoList,
+				EdbInfoIdBytes:             edbInfoIdBytes,
+				Formula:                    formula,
+				RuleType:                   v.RuleType,
+				EndDate:                    v.EndDate.Format(utils.FormatDate),
+				EdbInfoIdArr:               edbInfoIdArr,
+			}
+			err = models.RefreshCalculateByRuleBy9(rule)
+			if err != nil {
+				return
+			}
+		}
+	}
+
+	return
+}

+ 2 - 2
models/base_from_manual.go

@@ -120,10 +120,10 @@ func RefreshEdbDataFromManual(edbInfoId int, edbCode, startDate string) (err err
 	addSql := ` INSERT INTO edb_data_manual(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
 	var isAdd bool
 	manualMap := make(map[string]*ManualEdbdata)
-	fmt.Println("manualDataList:", len(manualDataList))
+	//fmt.Println("manualDataList:", len(manualDataList))
 	for _, v := range manualDataList {
 		item := v
-		fmt.Println("Item:", item.Dt, item.Close, item.TradeCode, item.ModifyTime)
+		//fmt.Println("Item:", item.Dt, item.Close, item.TradeCode, item.ModifyTime)
 		if findItem, ok := existMap[v.Dt]; !ok {
 			eDate := item.Dt
 			sValue := item.Close

+ 12 - 0
models/edb_info.go

@@ -97,6 +97,18 @@ func GetEdbInfoById(edbInfoId int) (item *EdbInfo, err error) {
 	return
 }
 
+// GetEdbInfoByIdList 根据指标id列表获取指标信息
+func GetEdbInfoByIdList(edbInfoIdList []int) (items []*EdbInfo, err error) {
+	num := len(edbInfoIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM edb_info WHERE edb_info_id in (` + utils.GetOrmInReplace(num) + `) `
+	_, err = o.Raw(sql, edbInfoIdList).QueryRows(&items)
+	return
+}
+
 // Update 更新EdbInfo信息
 func (edbInfo *EdbInfo) Update(cols []string) (err error) {
 	o := orm.NewOrm()

+ 73 - 52
models/predict_edb.go

@@ -7,6 +7,7 @@ import (
 	"github.com/shopspring/decimal"
 	"github.com/yidane/formula"
 	"hongze/hongze_edb_lib/services"
+	"hongze/hongze_edb_lib/services/alarm_msg"
 	"hongze/hongze_edb_lib/utils"
 	"strings"
 	"time"
@@ -25,6 +26,27 @@ type CalculateRule struct {
 	EdbInfoIdArr               []EdbInfoFromTag `description:"指标信息"`
 }
 
+// RefreshCalculateByRuleBy9 刷新计算
+func RefreshCalculateByRuleBy9(rule CalculateRule) (err error) {
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			tmpErr := to.Rollback()
+			if tmpErr != nil {
+				go alarm_msg.SendAlarmMsg("RefreshCalculateByRuleBy9 事务回滚失败,Err:"+tmpErr.Error(), 3)
+			}
+		} else {
+			err = to.Commit()
+		}
+	}()
+	err = CalculateByRuleBy9(to, rule)
+	return
+}
+
 // CalculateByRuleBy9 动态环差规则计算入库
 func CalculateByRuleBy9(to orm.TxOrmer, rule CalculateRule) (err error) {
 	saveDataMap := make(map[string]map[int]float64)
@@ -76,62 +98,63 @@ func CalculateByRuleBy9(to orm.TxOrmer, rule CalculateRule) (err error) {
 	for sk, sv := range saveDataMap {
 		//fmt.Println(sk, sv)
 		formulaFormStr := ReplaceFormula(rule.EdbInfoList, sv, formulaMap, formulaStr, rule.EdbInfoIdBytes)
-		if formulaFormStr != "" {
-			utils.FileLog.Info(fmt.Sprintf("formulaFormStr:%s", formulaFormStr))
-			expression := formula.NewExpression(formulaFormStr)
-			calResult, err := expression.Evaluate()
-			if err != nil {
-				// 分母为0的报错
-				if strings.Contains(err.Error(), "divide by zero") {
-					removeDateList = append(removeDateList, sk)
-					continue
-				}
-				err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
-				fmt.Println(err)
-				return err
-			}
-			calVal, err := calResult.Float64()
-			if err != nil {
-				err = errors.New("计算失败:获取计算值失败 Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
-				fmt.Println(err)
-				return err
+		//计算公式异常,那么就移除该指标
+		if formulaFormStr == "" {
+			removeDateList = append(removeDateList, sk)
+			continue
+		}
+
+		utils.FileLog.Info(fmt.Sprintf("formulaFormStr:%s", formulaFormStr))
+		expression := formula.NewExpression(formulaFormStr)
+		calResult, err := expression.Evaluate()
+		if err != nil {
+			// 分母为0的报错
+			if strings.Contains(err.Error(), "divide by zero") {
+				removeDateList = append(removeDateList, sk)
+				continue
 			}
+			err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
+			fmt.Println(err)
+			return err
+		}
+		calVal, err := calResult.Float64()
+		if err != nil {
+			err = errors.New("计算失败:获取计算值失败 Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
+			fmt.Println(err)
+			return err
+		}
 
-			saveValue := decimal.NewFromFloat(calVal).RoundCeil(4).String() //utils.SubFloatToString(calVal, 4)
-			if existPredictEdbRuleData, ok := dataMap[sk]; !ok {
-				dataTime, _ := time.Parse(utils.FormatDate, sk)
-				timestamp := dataTime.UnixNano() / 1e6
+		saveValue := decimal.NewFromFloat(calVal).RoundCeil(4).String() //utils.SubFloatToString(calVal, 4)
+		existPredictEdbRuleData, ok := dataMap[sk]
+		if !ok {
+			dataTime, _ := time.Parse(utils.FormatDate, sk)
+			timestamp := dataTime.UnixNano() / 1e6
 
-				if _, existOk := existDataMap[sk]; !existOk {
-					tmpPredictEdbRuleData := &PredictEdbRuleData{
-						//PredictEdbRuleDataId: 0,
-						EdbInfoId:     rule.EdbInfoId,
-						ConfigId:      rule.ConfigId,
-						DataTime:      sk,
-						Value:         saveValue,
-						CreateTime:    time.Now(),
-						ModifyTime:    time.Now(),
-						DataTimestamp: timestamp,
-					}
-					addDataList = append(addDataList, tmpPredictEdbRuleData)
-				}
-				existDataMap[sk] = sk
-			} else {
-				existValDecimal, err := decimal.NewFromString(existPredictEdbRuleData.Value)
-				existStr := existValDecimal.String()
-				if existStr != saveValue {
-					existPredictEdbRuleData.Value = saveValue
-					existPredictEdbRuleData.ModifyTime = time.Now()
-					_, err = to.Update(existPredictEdbRuleData, "Value", "ModifyTime")
-					if err != nil {
-						return err
-					}
+			if _, existOk := existDataMap[sk]; !existOk {
+				tmpPredictEdbRuleData := &PredictEdbRuleData{
+					//PredictEdbRuleDataId: 0,
+					EdbInfoId:     rule.EdbInfoId,
+					ConfigId:      rule.ConfigId,
+					DataTime:      sk,
+					Value:         saveValue,
+					CreateTime:    time.Now(),
+					ModifyTime:    time.Now(),
+					DataTimestamp: timestamp,
 				}
+				addDataList = append(addDataList, tmpPredictEdbRuleData)
 			}
+			existDataMap[sk] = sk
 		} else {
-			//计算公式异常,那么就移除该指标
-			removeDateList = append(removeDateList, sk)
-			continue
+			existValDecimal, err := decimal.NewFromString(existPredictEdbRuleData.Value)
+			existStr := existValDecimal.String()
+			if existStr != saveValue {
+				existPredictEdbRuleData.Value = saveValue
+				existPredictEdbRuleData.ModifyTime = time.Now()
+				_, err = to.Update(existPredictEdbRuleData, "Value", "ModifyTime")
+				if err != nil {
+					return err
+				}
+			}
 		}
 	}
 
@@ -147,8 +170,6 @@ func CalculateByRuleBy9(to orm.TxOrmer, rule CalculateRule) (err error) {
 	//删除多余的值
 	lenRemoveDateList := len(removeDateList)
 	if lenRemoveDateList > 0 {
-		removeDateStr := strings.Join(removeDateList, `","`)
-		removeDateStr = `"` + removeDateStr + `"`
 		//如果拼接指标变更了,那么需要删除所有的指标数据
 		sql := ` DELETE FROM predict_edb_rule_data WHERE config_id = ? and data_time in (` + utils.GetOrmInReplace(lenRemoveDateList) + `) `
 

+ 12 - 0
models/predict_edb_conf.go

@@ -70,6 +70,18 @@ func GetPredictEdbConfListById(edbInfoId int) (items []*PredictEdbConf, err erro
 	return
 }
 
+// GetPredictEdbConfListByConfigIdList 根据预测指标id列表获取预测指标配置信息列表
+func GetPredictEdbConfListByConfigIdList(configIdList []int) (items []*PredictEdbConf, err error) {
+	num := len(configIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM predict_edb_conf WHERE config_id in (` + utils.GetOrmInReplace(num) + `) ORDER BY config_id ASC`
+	_, err = o.Raw(sql, configIdList).QueryRows(&items)
+	return
+}
+
 // ModifyPredictEdbInfoMaxAndMinInfoBySourceEdbInfoId 根据来源指标修改预测指标的最新数据信息
 func ModifyPredictEdbInfoMaxAndMinInfoBySourceEdbInfoId(sourceEdbInfoId int, item *EdbInfoMaxAndMinInfo) (err error) {
 	o := orm.NewOrm()

+ 11 - 0
models/predict_edb_conf_calculate_mapping.go

@@ -1,6 +1,7 @@
 package models
 
 import (
+	"github.com/beego/beego/v2/client/orm"
 	"time"
 )
 
@@ -19,3 +20,13 @@ type PredictEdbConfCalculateMapping struct {
 	CreateTime                       time.Time `description:"创建时间"`
 	ModifyTime                       time.Time `description:"修改时间"`
 }
+
+// GetPredictEdbConfCalculateMappingListByEdbInfoId 根据预测指标id获取所有关联指标
+func GetPredictEdbConfCalculateMappingListByEdbInfoId(edbInfoId int) (list []*PredictEdbConfCalculateMapping, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * from predict_edb_conf_calculate_mapping
+			WHERE edb_info_id=? ORDER BY predict_edb_conf_calculate_mapping_id ASC `
+
+	_, err = o.Raw(sql, edbInfoId).QueryRows(&list)
+	return
+}