Browse Source

fix:计算指标调整

Roc 2 years ago
parent
commit
15f1d2397f

+ 72 - 4
controllers/base_from_calculate.go

@@ -290,6 +290,7 @@ func (this *CalculateController) CalculateBatchSave() {
 	}
 
 	var formulaInt int
+
 	if req.Source == utils.DATA_SOURCE_CALCULATE_NSZYDPJJS ||
 		req.Source == utils.DATA_SOURCE_CALCULATE_HBZ ||
 		req.Source == utils.DATA_SOURCE_CALCULATE_HCZ ||
@@ -347,6 +348,14 @@ func (this *CalculateController) CalculateBatchSave() {
 		return
 	}
 
+	//当前计算指标
+	edbInfo, err := models.GetEdbInfoById(req.EdbInfoId) //计算指标
+	if err != nil {
+		br.Msg = "获取指标信息失败"
+		br.ErrMsg = "获取指标信息失败:Err:" + err.Error()
+		return
+	}
+
 	fromEdbInfo, err := models.GetEdbInfoById(req.FromEdbInfoId)
 	if err != nil {
 		br.Msg = "获取指标信息失败"
@@ -364,7 +373,65 @@ func (this *CalculateController) CalculateBatchSave() {
 	adminName := req.AdminName
 	var sourName string
 	var edbInfoId int
-	if req.Source == utils.DATA_SOURCE_CALCULATE_LJZZY {
+	if req.Source == utils.DATA_SOURCE_CALCULATE {
+		fromEdbInfoList, tmpErr := models.GetEdbInfoCalculateDetailList(req.EdbInfoId)
+		err = tmpErr
+		if err != nil {
+			br.Msg = "获取计算指标失败:err:" + err.Error()
+			return
+		}
+		if len(fromEdbInfoList) <= 0 {
+			br.Msg = "计算指标所依赖指标不存在"
+			return
+		}
+		fromEdbInfoItem := fromEdbInfoList[0]
+		if fromEdbInfoItem == nil {
+			return
+		}
+
+		//检验公式
+		var formulaStr string
+		var edbInfoIdBytes []string
+		for _, v := range fromEdbInfoList {
+			formulaStr += v.FromTag + ","
+			edbInfoIdBytes = append(edbInfoIdBytes, v.FromTag)
+		}
+		formulaStr = strings.Trim(formulaStr, ",")
+		formulaMap := services.CheckFormula(edbInfo.CalculateFormula)
+		for _, v := range formulaMap {
+			if !strings.Contains(formulaStr, v) {
+				br.Msg = "公式错误,请重新填写"
+				return
+			}
+		}
+
+		edbInfoList := make([]*models.EdbInfo, 0)
+
+		for _, v := range fromEdbInfoList {
+			edbInfo, tmpErr := models.GetEdbInfoById(v.FromEdbInfoId)
+			err = tmpErr
+			if err != nil {
+				if err.Error() == utils.ErrNoRow() {
+					br.Msg = "指标 " + strconv.Itoa(v.FromEdbInfoId) + " 不存在"
+				} else {
+					br.Msg = "获取指标失败:Err:" + err.Error()
+				}
+				return
+			}
+			edbInfoList = append(edbInfoList, edbInfo)
+		}
+		//清除历史数据
+		err = models.DeleteCalculateData(edbInfoId)
+		if err != nil {
+			br.Msg = "清空运算指标失败:Err:" + err.Error() + " edb_info_id:" + strconv.Itoa(edbInfoId)
+			return
+		}
+		err = models.Calculate(edbInfoList, edbInfoId, edbCode, edbInfo.CalculateFormula, edbInfoIdBytes)
+		if err != nil {
+			br.Msg = "生成计算指标失败,Calculate Err:" + err.Error()
+			return
+		}
+	} else if req.Source == utils.DATA_SOURCE_CALCULATE_LJZZY {
 		sourName = "累计值转月值"
 		if fromEdbInfo.Frequency != "月度" {
 			br.Msg = "请选择月度指标"
@@ -412,7 +479,7 @@ func (this *CalculateController) CalculateBatchSave() {
 		edbInfoId, err = models.AddCalculateBp(&req, fromEdbInfo, edbCode, uniqueCode, adminId, adminName)
 	} else if req.Source == utils.DATA_SOURCE_CALCULATE_TIME_SHIFT { //时间移位
 		sourName = "时间移位"
-		edbInfoId, err = models.AddCalculateTimeShift(&req, fromEdbInfo, edbCode, uniqueCode, adminId, adminName)
+		edbInfoId, err = models.EditCalculateTimeShift(&req, fromEdbInfo, edbCode, edbInfo)
 	} else if req.Source == utils.DATA_SOURCE_CALCULATE_ZJPJ { //直接拼接
 		sourName = "直接拼接"
 
@@ -435,7 +502,8 @@ func (this *CalculateController) CalculateBatchSave() {
 			br.ErrMsg = "两个指标不允许为同一个"
 			return
 		}
-		edbInfoId, err = models.AddCalculateZjpj(&req, fromEdbInfo, secondEdbInfo, edbCode, uniqueCode, adminId, adminName)
+
+		edbInfoId, err = models.EditCalculateZjpj(&req, edbInfo, fromEdbInfo, secondEdbInfo)
 	} else if req.Source == utils.DATA_SOURCE_CALCULATE_LJZTBPJ { //累计值同比拼接
 		sourName = "累计值同比拼接"
 
@@ -473,7 +541,7 @@ func (this *CalculateController) CalculateBatchSave() {
 			br.ErrMsg = "两个指标不允许为同一个"
 			return
 		}
-		edbInfoId, err = models.AddCalculateLjztbpj(&req, fromEdbInfo, tbzEdbInfo, edbCode, uniqueCode, adminId, adminName)
+		edbInfoId, err = models.EditCalculateLjztbpj(&req, edbInfo, fromEdbInfo, tbzEdbInfo)
 	} else {
 		br.Msg = "无效计算方式"
 		br.ErrMsg = "无效计算方式,source:" + strconv.Itoa(req.Source)

+ 109 - 11
models/base_from_calculate.go

@@ -348,18 +348,116 @@ type EdbInfoCalculateBatchSaveReq struct {
 
 // EdbInfoCalculateBatchEditReq 编辑计算指标的请求参数
 type EdbInfoCalculateBatchEditReq struct {
-	EdbName       string `description:"指标名称"`
-	Frequency     string `description:"频度"`
-	Unit          string `description:"单位"`
-	ClassifyId    int    `description:"分类id"`
-	Formula       string `description:"N值"`
-	EdbInfoId     int    `description:"编辑指标id"`
-	FromEdbInfoId int    `description:"计算来源指标id"`
-	Source        int    `description:"来源:1:同花顺,2:wind,3:彭博,4:指标运算,5:累计值转月,6:同比值,7:同差值,8:N数值移动平均计算,12:环比值,13:环差值,14:变频"`
-	MoveType      int    `description:"移动方式:1:领先(默认),2:滞后"`
-	MoveFrequency string `description:"移动频度:天/周/月/季/年"`
-	EdbInfoIdArr  []struct {
+	AdminId          int    `description:"添加人id"`
+	AdminName        string `description:"添加人名称"`
+	EdbInfoId        int    `description:"编辑指标id"`
+	EdbName          string `description:"指标名称"`
+	Frequency        string `description:"频度"`
+	Unit             string `description:"单位"`
+	ClassifyId       int    `description:"分类id"`
+	Formula          string `description:"N值/移动天数"`
+	FromEdbInfoId    int    `description:"计算来源指标id"`
+	Source           int    `description:"来源:1:同花顺,2:wind,3:彭博,4:指标运算,5:累计值转月,6:同比值,7:同差值,8:N数值移动平均计算,12:环比值,13:环差值,14:变频"`
+	CalculateFormula string `description:"计算公式"`
+	EdbInfoIdArr     []struct {
 		EdbInfoId int    `description:"指标id"`
 		FromTag   string `description:"指标对应标签"`
 	}
+	MoveType      int    `description:"移动方式:1:领先(默认),2:滞后"`
+	MoveFrequency string `description:"移动频度:天/周/月/季/年"`
+}
+
+// DeleteCalculateData 删除计算数据
+func DeleteCalculateData(edbInfoId int) (err error) {
+	o := orm.NewOrm()
+	sql := `DELETE FROM edb_data_calculate WHERE edb_info_id=?`
+	_, err = o.Raw(sql, edbInfoId).Exec()
+	return
+}
+
+// Calculate 重新计算
+func Calculate(edbInfoIdArr []*EdbInfo, edbInfoId int, edbCode, formulaStr string, edbInfoIdBytes []string) (err error) {
+	defer func() {
+		if err != nil {
+			utils.FileLog.Info("Calculate Err:%s" + err.Error())
+		}
+	}()
+	saveDataMap := make(map[string]map[int]float64)
+	for _, v := range edbInfoIdArr {
+		var condition string
+		var pars []interface{}
+		condition += " AND edb_info_id=? "
+		pars = append(pars, v.EdbInfoId)
+		dataList, err := GetEdbDataListAll(condition, pars, v.Source, 1)
+		if err != nil {
+			return err
+		}
+		dataMap := make(map[string]float64)
+		for _, dv := range dataList {
+			if val, ok := saveDataMap[dv.DataTime]; ok {
+				if _, ok := val[v.EdbInfoId]; !ok {
+					val[v.EdbInfoId] = dv.Value
+				}
+			} else {
+				temp := make(map[int]float64)
+				temp[v.EdbInfoId] = dv.Value
+				saveDataMap[dv.DataTime] = temp
+			}
+		}
+		item := new(CalculateItems)
+		item.EdbInfoId = v.EdbInfoId
+		item.DataMap = dataMap
+	}
+	formulaMap := services.CheckFormula(formulaStr)
+	addSql := ` INSERT INTO edb_data_calculate(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
+	nowStr := time.Now().Format(utils.FormatDateTime)
+	var isAdd bool
+	for sk, sv := range saveDataMap {
+		formulaStr = strings.ToUpper(formulaStr)
+		formulaFormStr := ReplaceFormula(edbInfoIdArr, sv, formulaMap, formulaStr, edbInfoIdBytes)
+		if formulaStr == "" {
+			return
+		}
+		if formulaFormStr != "" {
+			expression := formula.NewExpression(formulaFormStr)
+			calResult, err := expression.Evaluate()
+			if err != nil {
+				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
+			}
+
+			//需要存入的数据
+			{
+				dataTime, _ := time.Parse(utils.FormatDate, sk)
+				timestamp := dataTime.UnixNano() / 1e6
+				timeStr := fmt.Sprintf("%d", timestamp)
+				addSql += "("
+				addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + sk + "'" + "," + utils.SubFloatToString(calVal, 4) + "," + "'" + nowStr + "'" +
+					"," + "'" + nowStr + "'" + "," + "1"
+				addSql += "," + "'" + timeStr + "'"
+				addSql += "),"
+				isAdd = true
+			}
+		} else {
+			fmt.Println("formulaFormStr is empty")
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		o := orm.NewOrm()
+		_, err = o.Raw(addSql).Exec()
+
+		if err != nil {
+			fmt.Println("AddEdbDataCalculate Err:" + err.Error())
+			return err
+		}
+	}
+	return
 }

+ 1 - 1
models/edb_data_calculate_ljztbpj.go

@@ -287,7 +287,7 @@ func AddCalculateLjztbpj(req *EdbInfoCalculateBatchSaveReq, firstEdbInfo, second
 }
 
 // EditCalculateLjztbpj 编辑累计值同比拼接数据
-func EditCalculateLjztbpj(req *EdbInfoCalculateBatchEditReq, nowEdbInfo, firstEdbInfo, secondEdbInfo *EdbInfo) (edbInfoId int, err error) {
+func EditCalculateLjztbpj(req *EdbInfoCalculateBatchSaveReq, nowEdbInfo, firstEdbInfo, secondEdbInfo *EdbInfo) (edbInfoId int, err error) {
 	edbInfoId = req.EdbInfoId
 	o := orm.NewOrm()
 	to, err := o.Begin()

+ 1 - 1
models/edb_data_calculate_time_shift.go

@@ -150,7 +150,7 @@ func AddCalculateTimeShift(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbIn
 }
 
 // EditCalculateTimeShift 修改时间移位
-func EditCalculateTimeShift(req *EdbInfoCalculateBatchEditReq, fromEdbInfo *EdbInfo, edbCode string, oldEdbInfo *EdbInfo) (edbInfoId int, err error) {
+func EditCalculateTimeShift(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbInfo, edbCode string, oldEdbInfo *EdbInfo) (edbInfoId int, err error) {
 	edbInfoId = req.EdbInfoId
 	o := orm.NewOrm()
 	to, err := o.Begin()

+ 1 - 1
models/edb_data_calculate_zjpj.go

@@ -239,7 +239,7 @@ func AddCalculateZjpj(req *EdbInfoCalculateBatchSaveReq, firstEdbInfo, secondEdb
 }
 
 // EditCalculateZjpj 编辑直接拼接数据
-func EditCalculateZjpj(req *EdbInfoCalculateBatchEditReq, nowEdbInfo, firstEdbInfo, secondEdbInfo *EdbInfo) (edbInfoId int, err error) {
+func EditCalculateZjpj(req *EdbInfoCalculateBatchSaveReq, nowEdbInfo, firstEdbInfo, secondEdbInfo *EdbInfo) (edbInfoId int, err error) {
 	edbInfoId = req.EdbInfoId
 	o := orm.NewOrm()
 	to, err := o.Begin()