Explorar o código

fix:新增预测指标同比、同差运算

Roc %!s(int64=2) %!d(string=hai) anos
pai
achega
9bb1514310

+ 284 - 771
controllers/base_from_predict_calculate.go

@@ -85,7 +85,7 @@ func addPredictCalculate(br *models.BaseResponse, req models.EdbInfoCalculateSav
 		//设置3分钟缓存
 		utils.Rc.SetNX(redisKey, 1, time.Second*300)
 		defer func() {
-			utils.Rc.Delete(redisKey)
+			_ = utils.Rc.Delete(redisKey)
 		}()
 	}
 
@@ -306,7 +306,7 @@ func editPredictCalculate(br *models.BaseResponse, req models.EdbInfoCalculateSa
 		//设置3分钟缓存
 		utils.Rc.SetNX(redisKey, 1, time.Second*300)
 		defer func() {
-			utils.Rc.Delete(redisKey)
+			_ = utils.Rc.Delete(redisKey)
 		}()
 	}
 
@@ -507,39 +507,6 @@ func (this *PredictCalculateController) CalculateBatchSave() {
 		return
 	}
 
-	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 ||
-		req.Source == utils.DATA_SOURCE_CALCULATE_TIME_SHIFT {
-		if req.Formula == "" {
-			br.Msg = "请填写N值"
-			return
-		}
-		formulaInt, _ = strconv.Atoi(req.Formula)
-		if formulaInt <= 0 {
-			br.Msg = "N值输入错误,请重新输入"
-			return
-		}
-	} else if req.Source == utils.DATA_SOURCE_CALCULATE_ZJPJ {
-		//直接拼接指标
-
-		//校验时间格式
-		_, err = time.ParseInLocation(utils.FormatDate, req.Formula, time.Local)
-		if err != nil {
-			br.Msg = "拼接日期有误,请重新输入"
-			return
-		}
-	}
-
-	// 获取指标详情
-	edbInfo, err := models.GetEdbInfoById(req.EdbInfoId)
-	if err != nil {
-		br.Msg = "指标不存在!"
-		br.ErrMsg = "指标不存在"
-		return
-	}
-
 	//加入缓存机制,避免创建同一个名称的指标 start
 	redisKey := fmt.Sprint("edb_info:calculate:batch:save:", req.Source, ":", req.EdbName)
 	isExist := utils.Rc.IsExist(redisKey)
@@ -550,7 +517,7 @@ func (this *PredictCalculateController) CalculateBatchSave() {
 		//设置3分钟缓存
 		utils.Rc.SetNX(redisKey, 1, time.Second*300)
 		defer func() {
-			utils.Rc.Delete(redisKey)
+			_ = utils.Rc.Delete(redisKey)
 		}()
 	}
 	//加入缓存机制,避免创建同一个名称的指标 end
@@ -573,260 +540,16 @@ func (this *PredictCalculateController) CalculateBatchSave() {
 		return
 	}
 
+	// 来源预测指标信息
 	fromEdbInfo, err := models.GetEdbInfoById(req.FromEdbInfoId)
 	if err != nil {
 		br.Msg = "获取指标信息失败"
 		br.ErrMsg = "获取指标信息失败:Err:" + err.Error()
 		return
 	}
-
-	//生成指标编码
-	randStr := utils.GetRandDigit(4)
-	edbCode := `C` + time.Now().Format("060102") + randStr
-	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
-	uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
-
-	adminId := req.AdminId
-	adminName := req.AdminName
-	var sourName string
-	var edbInfoId int
-	if req.Source == utils.DATA_SOURCE_CALCULATE_LJZZY {
-		sourName = "累计值转月值"
-		if fromEdbInfo.Frequency != "月度" {
-			br.Msg = "请选择月度指标"
-			return
-		}
-		edbInfoId, err = models.AddCalculateLjzzy(&req, fromEdbInfo, edbCode, uniqueCode, adminId, adminName)
-	} else if req.Source == utils.DATA_SOURCE_CALCULATE_TBZ {
-		sourName = "同比值"
-		edbInfoId, err = models.AddCalculateTbz(&req, fromEdbInfo, edbCode, uniqueCode, adminId, adminName)
-	} else if req.Source == utils.DATA_SOURCE_CALCULATE_TCZ {
-		sourName = "同差值"
-		edbInfoId, err = models.AddCalculateTcz(&req, fromEdbInfo, edbCode, uniqueCode, adminId, adminName)
-	} else if req.Source == utils.DATA_SOURCE_CALCULATE_NSZYDPJJS {
-		sourName = "N数值移动平均计算"
-		edbInfoId, err = models.AddCalculateNszydpjjs(&req, fromEdbInfo, edbCode, uniqueCode, adminId, adminName, formulaInt)
-	} else if req.Source == utils.DATA_SOURCE_CALCULATE_HBZ { //环比值
-		var condition string
-		var pars []interface{}
-		condition += " AND edb_info_id =? "
-		pars = append(pars, req.FromEdbInfoId)
-		condition += " AND value <=0 "
-		checkCount, err := models.GetEdbDataCount(condition, pars, fromEdbInfo.Source)
-		if err != nil && err.Error() != utils.ErrNoRow() {
-			br.Msg = "判断环比值是否可计算失败"
-			br.ErrMsg = "判断环比值是否可计算失败,Err:" + err.Error()
-			return
-		}
-		if checkCount > 0 {
-			br.Msg = "原始数据中存在0或负数,该指标不能进行环比运算"
-			br.ErrMsg = "原始数据中出现0和负值时,提示该指标不能进行环比运算"
-			return
-		}
-		sourName = "环比值"
-		edbInfoId, err = models.AddCalculateHbz(&req, fromEdbInfo, edbCode, uniqueCode, adminId, adminName, formulaInt)
-	} else if req.Source == utils.DATA_SOURCE_CALCULATE_HCZ {
-		sourName = "环差值"
-		edbInfoId, err = models.AddCalculateHcz(&req, fromEdbInfo, edbCode, uniqueCode, adminId, adminName, formulaInt)
-	} else if req.Source == utils.DATA_SOURCE_CALCULATE_BP {
-		if fromEdbInfo.Frequency == "日度" {
-			br.Msg = "日度指标,无法进行变频操作"
-			br.ErrMsg = "日度指标,无法进行变频操作:edbcode:" + fromEdbInfo.EdbCode
-			return
-		}
-		sourName = "变频"
-		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)
-	} else if req.Source == utils.DATA_SOURCE_CALCULATE_ZJPJ { //直接拼接
-		sourName = "直接拼接"
-
-		if len(req.EdbInfoIdArr) != 1 {
-			br.Msg = "请传入拼接日期之后的指标"
-			br.ErrMsg = "请传入拼接日期之后的指标"
-			return
-		}
-
-		secondEdbInfoReq := req.EdbInfoIdArr[0]
-		secondEdbInfo, err := models.GetEdbInfoById(secondEdbInfoReq.EdbInfoId)
-		if err != nil {
-			br.Msg = "获取拼接日期之后的指标信息失败"
-			br.ErrMsg = "获取拼接日期之后的指标信息失败:Err:" + err.Error()
-			return
-		}
-
-		if fromEdbInfo.EdbInfoId == secondEdbInfo.EdbInfoId {
-			br.Msg = "两个指标不允许为同一个"
-			br.ErrMsg = "两个指标不允许为同一个"
-			return
-		}
-		edbInfoId, err = models.AddCalculateZjpj(&req, fromEdbInfo, secondEdbInfo, edbCode, uniqueCode, adminId, adminName)
-	} else if req.Source == utils.DATA_SOURCE_CALCULATE_LJZTBPJ { //累计值同比拼接
-		sourName = "累计值同比拼接"
-
-		if fromEdbInfo.Frequency != "月度" {
-			br.Msg = "待拼接指标只能筛选月度指标"
-			br.ErrMsg = "待拼接指标只能筛选月度指标"
-			return
-		}
-		if len(req.EdbInfoIdArr) != 1 {
-			br.Msg = "请传入同比值指标"
-			br.ErrMsg = "请传入同比值指标"
-			return
-		}
-
-		secondEdbInfoReq := req.EdbInfoIdArr[0]
-		tbzEdbInfo, err := models.GetEdbInfoById(secondEdbInfoReq.EdbInfoId)
-		if err != nil {
-			br.Msg = "获取同比值指标信息失败"
-			br.ErrMsg = "获取同比值指标信息失败:Err:" + err.Error()
-			return
-		}
-		if tbzEdbInfo.Source != utils.DATA_SOURCE_CALCULATE_TBZ {
-			br.Msg = "指标必须是传入同比值指标类型"
-			br.ErrMsg = "指标必须是传入同比值指标类型"
-			return
-		}
-		if tbzEdbInfo.Frequency != "月度" {
-			br.Msg = "同比值指标只能筛选月度指标"
-			br.ErrMsg = "同比值指标只能筛选月度指标"
-			return
-		}
-
-		if fromEdbInfo.EdbInfoId == tbzEdbInfo.EdbInfoId {
-			br.Msg = "两个指标不允许为同一个"
-			br.ErrMsg = "两个指标不允许为同一个"
-			return
-		}
-		edbInfoId, err = models.AddCalculateLjztbpj(&req, fromEdbInfo, tbzEdbInfo, edbCode, uniqueCode, adminId, adminName)
-	} else {
-		br.Msg = "无效计算方式"
-		br.ErrMsg = "无效计算方式,source:" + strconv.Itoa(req.Source)
-		return
-	}
-
-	if err != nil {
-		br.Msg = "生成" + sourName + "失败"
-		br.Msg = "生成" + sourName + "失败 Err:" + err.Error()
-		return
-	}
-	if edbInfoId <= 0 {
-		br.Msg = "生成" + sourName + "失败"
-		br.ErrMsg = "生成" + sourName + "失败,指标ID错误:" + strconv.Itoa(edbInfoId)
-		return
-	}
-	//处理同名指标
-	{
-		edbNameList, err := models.GetEdbInfoByName(req.EdbName)
-		if err != nil {
-			br.Msg = "保存失败"
-			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
-			return
-		}
-		if len(edbNameList) >= 2 {
-			for _, v := range edbNameList {
-				edbName := v.EdbName + "(" + v.SourceName + ")"
-				err = models.ModifyEdbInfoNameSource(edbName, v.EdbInfoId)
-				if err != nil {
-					br.Msg = "保存失败"
-					br.ErrMsg = "修改指标名称失败,Err:" + err.Error()
-					return
-				}
-			}
-		}
-	}
-
-	// 更新指标最大最小值
-	err, errMsg := models.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo)
-	if err != nil {
-		br.Msg = errMsg
-		br.ErrMsg = err.Error()
-		return
-	}
-	resp := models.AddEdbInfoResp{
-		EdbInfoId:  edbInfoId,
-		UniqueCode: uniqueCode,
-	}
-	br.Ret = 200
-	br.Success = true
-	br.Msg = "保存成功"
-	br.Data = resp
-	br.IsAddLog = true
-}
-
-func AddCalculateBatchSave(br *models.BaseResponse, req models.EdbInfoCalculateBatchSaveReq) {
-	req.EdbName = strings.Trim(req.EdbName, " ")
-	if req.EdbName == "" {
-		br.Msg = "指标名称不能为空"
-		return
-	}
-
-	if req.Frequency == "" {
-		br.Msg = "频率不能为空"
-		return
-	}
-
-	if req.Unit == "" {
-		br.Msg = "单位不能为空"
-		return
-	}
-
-	if req.ClassifyId <= 0 {
-		br.Msg = "请选择分类"
-		return
-	}
-
-	if req.FromEdbInfoId <= 0 {
-		br.Msg = "请选择指标"
-		return
-	}
-
-	// 获取指标详情
-	edbInfo, err := models.GetEdbInfoById(req.EdbInfoId)
-	if err != nil {
-		br.Msg = "指标不存在!"
-		br.ErrMsg = "指标不存在"
-		return
-	}
-
-	//加入缓存机制,避免创建同一个名称的指标 start
-	redisKey := fmt.Sprint("edb_info:calculate:batch:save:", req.Source, ":", req.EdbName)
-	isExist := utils.Rc.IsExist(redisKey)
-	if isExist {
-		br.Msg = "指标正在处理,请勿重复提交"
-		return
-	} else {
-		//设置3分钟缓存
-		utils.Rc.SetNX(redisKey, 1, time.Second*300)
-		defer func() {
-			utils.Rc.Delete(redisKey)
-		}()
-	}
-	//加入缓存机制,避免创建同一个名称的指标 end
-
-	var condition string
-	var pars []interface{}
-	condition += " AND edb_name=? "
-	pars = append(pars, req.EdbName)
-
-	count, err := models.GetEdbInfoCountByCondition(condition, pars)
-	if err != nil {
-		br.Msg = "判断指标名称是否存在失败"
-		br.ErrMsg = "判断指标名称是否存在失败,Err:" + err.Error()
-		return
-	}
-
-	if count > 0 {
-		br.Msg = "指标名称已存在,请重新填写"
-		br.ErrMsg = "指标名称已存在,请重新填写"
-		return
-	}
-
-	fromEdbInfo, err := models.GetEdbInfoById(req.FromEdbInfoId)
-	if err != nil {
-		br.Msg = "获取指标信息失败"
-		br.ErrMsg = "获取指标信息失败:Err:" + err.Error()
+	if fromEdbInfo.EdbInfoType != 1 {
+		br.Msg = "来源指标不是预测指标"
+		br.ErrMsg = "来源指标不是预测指标"
 		return
 	}
 
@@ -839,13 +562,18 @@ func AddCalculateBatchSave(br *models.BaseResponse, req models.EdbInfoCalculateB
 	adminId := req.AdminId
 	adminName := req.AdminName
 	var sourName string
-	var edbInfoId int
+	var errMsg string
+	var edbInfo *models.EdbInfo
+
+	var latestDateStr string // 最近实际数据的日期
+	var latestValue float64  // 最近实际数据的值
+
 	if req.Source == utils.DATA_SOURCE_PREDICT_CALCULATE_TBZ {
 		sourName = "预测同比"
-		edbInfoId, err = models.AddPredictCalculateTbz(&req, fromEdbInfo, edbCode, uniqueCode, adminId, adminName)
+		edbInfo, latestDateStr, latestValue, err, errMsg = models.SavePredictCalculateTbz(req.EdbInfoId, req.ClassifyId, req.EdbName, req.Frequency, req.Unit, req.Formula, fromEdbInfo, edbCode, uniqueCode, adminId, adminName)
 	} else if req.Source == utils.DATA_SOURCE_PREDICT_CALCULATE_TCZ {
 		sourName = "预测同差"
-		edbInfoId, err = models.AddPredictCalculateTcz(&req, fromEdbInfo, edbCode, uniqueCode, adminId, adminName)
+		edbInfo, latestDateStr, latestValue, err, errMsg = models.SavePredictCalculateTcz(req.EdbInfoId, req.ClassifyId, req.EdbName, req.Frequency, req.Unit, req.Formula, fromEdbInfo, edbCode, uniqueCode, adminId, adminName)
 	} else {
 		br.Msg = "无效计算方式"
 		br.ErrMsg = "无效计算方式,source:" + strconv.Itoa(req.Source)
@@ -854,12 +582,15 @@ func AddCalculateBatchSave(br *models.BaseResponse, req models.EdbInfoCalculateB
 
 	if err != nil {
 		br.Msg = "生成" + sourName + "失败"
+		if errMsg != `` {
+			br.Msg = errMsg
+		}
 		br.Msg = "生成" + sourName + "失败 Err:" + err.Error()
 		return
 	}
-	if edbInfoId <= 0 {
+	if edbInfo == nil {
 		br.Msg = "生成" + sourName + "失败"
-		br.ErrMsg = "生成" + sourName + "失败,指标ID错误:" + strconv.Itoa(edbInfoId)
+		br.ErrMsg = "生成" + sourName + "失败,edbInfo is nil"
 		return
 	}
 	//处理同名指标
@@ -884,14 +615,15 @@ func AddCalculateBatchSave(br *models.BaseResponse, req models.EdbInfoCalculateB
 	}
 
 	// 更新指标最大最小值
-	err, errMsg := models.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo)
+	err, errMsg = models.UnifiedModifyPredictEdbInfoMaxAndMinInfo(edbInfo, latestDateStr, latestValue)
 	if err != nil {
 		br.Msg = errMsg
 		br.ErrMsg = err.Error()
 		return
 	}
+
 	resp := models.AddEdbInfoResp{
-		EdbInfoId:  edbInfoId,
+		EdbInfoId:  edbInfo.EdbInfoId,
 		UniqueCode: uniqueCode,
 	}
 	br.Ret = 200
@@ -901,507 +633,288 @@ func AddCalculateBatchSave(br *models.BaseResponse, req models.EdbInfoCalculateB
 	br.IsAddLog = true
 }
 
-// AddPredictCalculate 添加预测指标运算
-//func addPredictCalculate(br *models.BaseResponse, req models.EdbInfoCalculateSaveReq) {
-//
-//	req.EdbName = strings.Trim(req.EdbName, " ")
-//	if req.EdbName == "" {
-//		br.Msg = "指标名称不能为空"
-//		return
-//	}
-//
-//	if req.Frequency == "" {
-//		br.Msg = "频率不能为空"
-//		return
-//	}
-//
-//	if req.Unit == "" {
-//		br.Msg = "单位不能为空"
+// Refresh
+// @Title 刷新计算指标接口
+// @Description 刷新计算指标接口
+// @Success 200 {object} models.RefreshEdbInfoReq
+// @router /refresh [post]
+
+//func (this *PredictCalculateController) Refresh() {
+//	br := new(models.BaseResponse).Init()
+//	var cacheKey string
+//	defer func() {
+//		this.Data["json"] = br
+//		this.ServeJSON()
+//	}()
+//	var req models.RefreshEdbInfoReq
+//	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+//	if err != nil {
+//		br.Msg = "参数解析异常!"
+//		br.ErrMsg = "参数解析失败,Err:" + err.Error()
 //		return
 //	}
-//
-//	if req.ClassifyId <= 0 {
-//		br.Msg = "请选择分类"
+//	if req.EdbCode == "" {
+//		br.Msg = "请输入指标编码!"
+//		br.ErrMsg = "请输入指标编码,指标编码为空"
 //		return
 //	}
-//
-//	if len(req.EdbInfoIdArr) <= 0 {
-//		br.Msg = "请选择指标"
+//	if req.EdbInfoId <= 0 {
+//		br.Msg = "请输入指标ID!"
+//		br.ErrMsg = "请输入指标ID"
 //		return
 //	}
-//
-//	if req.CalculateFormula == "" {
-//		br.Msg = "请填写指标"
+//	edbInfo, err := models.GetEdbInfoById(req.EdbInfoId)
+//	if err != nil {
+//		br.Msg = "指标不存在!"
+//		br.ErrMsg = "指标不存在"
 //		return
 //	}
 //
-//	//加入缓存机制,避免创建同一个名称的指标 start
-//	redisKey := fmt.Sprint("predict_edb_info:calculate:batch:save:", utils.DATA_SOURCE_PREDICT_CALCULATE, ":", req.EdbName)
-//	isExist := utils.Rc.IsExist(redisKey)
-//	if isExist {
-//		br.Msg = "指标正在处理,请勿重复提交"
-//		return
-//	} else {
-//		//设置3分钟缓存
-//		utils.Rc.SetNX(redisKey, 1, time.Second*300)
+//	cacheKey = utils.CACHE_EDB_DATA_REFRESH + strconv.Itoa(edbInfo.Source) + "_" + req.EdbCode
+//	if !utils.Rc.IsExist(cacheKey) {
+//		utils.Rc.SetNX(cacheKey, 1, 1*time.Minute)
 //		defer func() {
-//			utils.Rc.Delete(redisKey)
-//		}()
-//	}
-//
-//	calculateFormula := req.CalculateFormula
-//	calculateFormula = strings.Replace(calculateFormula, "(", "(", -1)
-//	calculateFormula = strings.Replace(calculateFormula, ")", ")", -1)
-//	calculateFormula = strings.Replace(calculateFormula, ",", ",", -1)
-//	calculateFormula = strings.Replace(calculateFormula, "。", ".", -1)
-//	if strings.Contains(req.CalculateFormula, "%") {
-//		calculateFormula = strings.Replace(calculateFormula, "%", "*0.01", -1)
-//	}
-//	req.CalculateFormula = calculateFormula
-//
-//	//检验公式
-//	var formulaStr string
-//	var edbInfoIdBytes []string
-//	for _, v := range req.EdbInfoIdArr {
-//		formulaStr += v.FromTag + ","
-//		edbInfoIdBytes = append(edbInfoIdBytes, v.FromTag)
-//	}
-//	formulaMap := services.CheckFormula(req.CalculateFormula)
-//	for _, v := range formulaMap {
-//		if !strings.Contains(formulaStr, v) {
-//			br.Msg = "公式错误,请重新填写"
-//			return
-//		}
-//	}
+//			_ = utils.Rc.Delete(cacheKey)
 //
-//	// 判断指标名称是否存在
-//	{
-//		var condition string
-//		var pars []interface{}
-//		// 指标类型,0:普通指标,1:预测指标
-//		condition += " AND edb_info_type=?  AND edb_name=? "
-//		pars = append(pars, 1, req.EdbName)
+//		}()
+//		startDate := req.StartDate
+//		var errMsg string
+//		endDate := time.Now().Format(utils.FormatDate)
+//		edbInfoId := edbInfo.EdbInfoId
+//		source := edbInfo.Source
 //
-//		count, err := models.GetEdbInfoCountByCondition(condition, pars)
-//		if err != nil {
-//			br.Msg = "判断指标名称是否存在失败"
-//			br.ErrMsg = "判断指标名称是否存在失败,Err:" + err.Error()
-//			return
-//		}
-//		if count > 0 {
-//			br.Msg = "指标名称已存在,请重新填写"
-//			br.ErrMsg = "指标名称已存在,请重新填写"
-//			return
-//		}
-//	}
+//		switch source {
+//		case utils.DATA_SOURCE_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)
 //
-//	// 关联指标信息
-//	edbInfoList := make([]*models.EdbInfo, 0)
-//	calculateMappingList := make([]*models.EdbInfoCalculateMapping, 0)
-//	for k, v := range req.EdbInfoIdArr {
-//		fromEdbInfo, err := models.GetEdbInfoById(v.EdbInfoId)
-//		if err != nil {
-//			if err.Error() == utils.ErrNoRow() {
-//				br.Msg = "生成计算指标失败"
-//				br.Msg = "指标 " + strconv.Itoa(v.EdbInfoId) + " 不存在"
+//			for _, v := range calculateMap {
+//				formulaStr += v.FromTag + ","
+//				edbInfoIdBytes = append(edbInfoIdBytes, v.FromTag)
+//				edbInfo, _ := models.GetEdbInfoById(v.FromEdbInfoId)
+//				edbInfoList = append(edbInfoList, edbInfo)
+//			}
+//			err = models.RefreshAllCalculate(edbInfoList, edbInfo.EdbInfoId, source, edbInfo.EdbCode, edbInfo.CalculateFormula, startDate, endDate, edbInfoIdBytes)
+//			if err != nil && err.Error() != utils.ErrNoRow() {
+//				errMsg = "RefreshCalculate Err:" + err.Error()
+//				break
+//			}
+//		case utils.DATA_SOURCE_CALCULATE_LJZZY: //刷新累计值转月值
+//			calculateLjzzy, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
+//			if err != nil {
+//				errMsg = "GetEdbInfoCalculateLjzzyDetail Err:" + err.Error()
+//				break
+//			}
+//			fromEdbInfo, err := models.GetEdbInfoById(calculateLjzzy.FromEdbInfoId)
+//			if err != nil {
+//				errMsg = "GetEdbInfoById Err:" + err.Error()
+//				break
+//			}
+//			startDate = edbInfo.StartDate
+//			endDate = time.Now().Format(utils.FormatDate)
+//			err = models.RefreshAllCalculateLjzzy(edbInfoId, source, fromEdbInfo, calculateLjzzy.EdbCode, startDate, endDate)
+//			if err != nil && err.Error() != utils.ErrNoRow() {
+//				errMsg = "RefreshAllCalculateLjzzy Err:" + err.Error()
+//				break
+//			}
+//		case utils.DATA_SOURCE_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
+//			endDate = time.Now().Format(utils.FormatDate)
+//			err = models.RefreshAllCalculateTbz(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate, endDate)
+//			if err != nil && err.Error() != utils.ErrNoRow() {
+//				errMsg = "RefreshAllCalculateTbz Err:" + err.Error()
+//				break
+//			}
+//		case utils.DATA_SOURCE_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
+//			endDate = time.Now().Format(utils.FormatDate)
+//			err = models.RefreshAllCalculateTcz(edbInfoId, source, fromEdbInfo, calculateTcz.EdbCode, startDate, endDate)
+//			if err != nil && err.Error() != utils.ErrNoRow() {
+//				errMsg = "RefreshCalculateTcz Err:" + err.Error()
+//				break
+//			}
+//		case utils.DATA_SOURCE_CALCULATE_NSZYDPJJS: //N数值移动平均计算
+//			calculateNszydpjjs, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
+//			if err != nil {
+//				errMsg = "GetEdbInfoCalculateNszydpjjsDetail Err:" + err.Error()
+//				break
+//			}
+//			fromEdbInfo, err := models.GetEdbInfoById(calculateNszydpjjs.FromEdbInfoId)
+//			if err != nil {
+//				errMsg = "GetEdbInfoById Err:" + err.Error()
+//				break
+//			}
+//			formulaInt, _ := strconv.Atoi(edbInfo.CalculateFormula)
+//			startDate = edbInfo.StartDate
+//			err = models.RefreshAllCalculateNszydpjjs(edbInfoId, edbInfo.Source, formulaInt, fromEdbInfo, calculateNszydpjjs.EdbCode, startDate)
+//			if err != nil && err.Error() != utils.ErrNoRow() {
+//				errMsg = "RefreshCalculateNszydpjjs Err:" + err.Error()
+//				break
+//			}
+//		case utils.DATA_SOURCE_CALCULATE_HBZ: //刷新环比值
+//			calculateTbz, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
+//			if err != nil {
+//				errMsg = "GetEdbInfoCalculateHbzDetail Err:" + err.Error()
+//				break
+//			}
+//			fromEdbInfo, err := models.GetEdbInfoById(calculateTbz.FromEdbInfoId)
+//			if err != nil {
+//				errMsg = "GetEdbInfoById Err:" + err.Error()
+//				break
+//			}
+//			startDate = edbInfo.StartDate
+//			endDate = time.Now().Format(utils.FormatDate)
+//			formulaInt, _ := strconv.Atoi(edbInfo.CalculateFormula)
+//			err = models.RefreshAllCalculateHbz(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate, endDate, formulaInt)
+//			if err != nil && err.Error() != utils.ErrNoRow() {
+//				errMsg = "RefreshAllCalculateHbz Err:" + err.Error()
+//				break
+//			}
+//		case utils.DATA_SOURCE_CALCULATE_HCZ: //刷新环差值
+//			calculateTbz, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
+//			if err != nil {
+//				errMsg = "GetEdbInfoCalculateHczDetail Err:" + err.Error()
+//				break
+//			}
+//			fromEdbInfo, err := models.GetEdbInfoById(calculateTbz.FromEdbInfoId)
+//			if err != nil {
+//				errMsg = "GetEdbInfoById Err:" + err.Error()
+//				break
+//			}
+//			startDate = edbInfo.StartDate
+//			endDate = time.Now().Format(utils.FormatDate)
+//			formulaInt, _ := strconv.Atoi(edbInfo.CalculateFormula)
+//			err = models.RefreshAllCalculateHcz(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate, endDate, formulaInt)
+//			if err != nil && err.Error() != utils.ErrNoRow() {
+//				errMsg = "RefreshAllCalculateHcz Err:" + err.Error()
+//				break
+//			}
+//		case utils.DATA_SOURCE_CALCULATE_BP: //刷新变频
+//			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
+//			endDate = time.Now().Format(utils.FormatDate)
+//			err = models.RefreshAllCalculateBp(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate, endDate)
+//			if err != nil && err.Error() != utils.ErrNoRow() {
+//				errMsg = "RefreshAllCalculateBp Err:" + err.Error()
+//				break
+//			}
+//		case utils.DATA_SOURCE_CALCULATE_TIME_SHIFT:
+//			calculate, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
+//			if err != nil {
+//				errMsg = "GetEdbInfoCalculateTbzDetail Err:" + err.Error()
+//				break
+//			}
+//			fromEdbInfo, err := models.GetEdbInfoById(calculate.FromEdbInfoId)
+//			if err != nil {
+//				errMsg = "GetEdbInfoById Err:" + err.Error()
+//				break
+//			}
+//			startDate = edbInfo.StartDate
+//			endDate = time.Now().Format(utils.FormatDate)
+//			formulaInt, _ := strconv.Atoi(calculate.CalculateFormula)
+//			err = models.RefreshAllCalculateTimeShift(edbInfoId, source, formulaInt, calculate.MoveType, fromEdbInfo, calculate.EdbCode, startDate, endDate, calculate.MoveFrequency)
+//			if err != nil && err.Error() != utils.ErrNoRow() {
+//				errMsg = "RefreshAllCalculateTimeShift Err:" + err.Error()
+//			}
+//		case utils.DATA_SOURCE_CALCULATE_ZJPJ: //刷新直接拼接
+//			err = models.RefreshAllCalculateZjpj(edbInfo)
+//			if err != nil && err.Error() != utils.ErrNoRow() {
+//				errMsg = "RefreshAllCalculateZjpj Err:" + err.Error()
+//				break
+//			}
+//		case utils.DATA_SOURCE_CALCULATE_LJZTBPJ: //刷新累计值同比拼接
+//			err = models.RefreshAllCalculateLjztbpj(edbInfo)
+//			if err != nil && err.Error() != utils.ErrNoRow() {
+//				errMsg = "RefreshAllCalculateLjztbpj Err:" + err.Error()
+//				break
+//			}
+//		case utils.DATA_SOURCE_PYTHON: //python代码运算
+//			edbPythonCode, err := models.GetEdbPythonCodeById(edbInfo.EdbInfoId)
+//			if err != nil {
+//				errMsg = "获取python代码失败 Err:" + err.Error()
+//				break
+//			}
+//			edbData, err, errMsg := services.ExecPythonCode(edbInfo.EdbCode, edbPythonCode.PythonCode)
+//			if err != nil {
+//				br.Msg = "获取数据失败"
+//				br.ErrMsg = "python代码获取数据失败,err:" + err.Error()
+//				if errMsg != "" {
+//					br.ErrMsg = errMsg
+//				}
 //				return
 //			}
-//			br.Msg = "生成计算指标失败"
-//			br.Msg = "获取指标失败:Err:" + err.Error()
-//			return
-//		}
-//		edbInfoList = append(edbInfoList, fromEdbInfo)
-//
-//		//关联关系表
-//		{
-//			calculateMappingItem := &models.EdbInfoCalculateMapping{
-//				CreateTime: time.Now(),
-//				ModifyTime: time.Now(),
-//				Sort:       k + 1,
-//				//EdbCode:        edbCode,
-//				//EdbInfoId:      int(edbInfoId),
-//				FromEdbInfoId:  fromEdbInfo.EdbInfoId,
-//				FromEdbCode:    fromEdbInfo.EdbCode,
-//				FromEdbName:    fromEdbInfo.EdbName,
-//				FromSource:     fromEdbInfo.Source,
-//				FromSourceName: fromEdbInfo.SourceName,
-//				FromTag:        v.FromTag,
-//				Source:         utils.DATA_SOURCE_PREDICT_CALCULATE,
-//				SourceName:     "预测指标运算",
+//			err = models.RefreshAllPythonEdb(edbInfo, edbData)
+//			if err != nil && err.Error() != utils.ErrNoRow() {
+//				errMsg = "RefreshAllPythonEdb Err:" + err.Error()
+//				break
 //			}
-//			calculateMappingList = append(calculateMappingList, calculateMappingItem)
-//		}
-//	}
 //
-//	// 指标入库
-//	randStr := utils.GetRandDigit(4)
-//	edbCode := `C2` + time.Now().Format("060102") + randStr
-//	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
-//	uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
-//	edbInfo := &models.EdbInfo{
-//		EdbInfoType:      1,
-//		Source:           utils.DATA_SOURCE_PREDICT_CALCULATE,
-//		SourceName:       "预测指标运算",
-//		EdbCode:          edbCode,
-//		EdbName:          req.EdbName,
-//		EdbNameSource:    req.EdbName,
-//		Frequency:        req.Frequency,
-//		Unit:             req.Unit,
-//		ClassifyId:       req.ClassifyId,
-//		SysUserId:        req.AdminId,
-//		SysUserRealName:  req.AdminName,
-//		CreateTime:       time.Now(),
-//		ModifyTime:       time.Now(),
-//		UniqueCode:       uniqueCode,
-//		CalculateFormula: req.CalculateFormula,
-//		EdbType:          2,
-//	}
-//	edbInfoId, err := models.AddEdbInfo(edbInfo)
-//	if err != nil {
-//		br.Msg = "生成计算指标失败"
-//		br.Msg = "生成计算指标失败,AddEdbInfo Err:" + err.Error()
-//		return
-//	}
-//	edbInfo.EdbInfoId = int(edbInfoId)
-//
-//	//处理同名指标
-//	{
-//		edbNameList, err := models.GetEdbInfoByName(req.EdbName)
-//		if err != nil {
-//			br.Msg = "保存失败"
-//			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+//		default:
+//			br.Msg = "来源异常,请联系相关开发!"
+//			br.ErrMsg = "来源异常,请联系相关开发"
 //			return
 //		}
-//		if len(edbNameList) >= 2 {
-//			for _, v := range edbNameList {
-//				edbName := v.EdbName + "(" + v.SourceName + ")"
-//				err = models.ModifyEdbInfoNameSource(edbName, v.EdbInfoId)
-//				if err != nil {
-//					br.Msg = "保存失败"
-//					br.ErrMsg = "修改指标名称失败,Err:" + err.Error()
-//					return
-//				}
-//			}
+//		if errMsg != `` {
+//			br.Msg = "刷新指标失败!"
+//			br.ErrMsg = "刷新指标失败,err:" + errMsg
+//			return
 //		}
-//	}
 //
-//	//关联关系表入库
-//	{
-//		if len(calculateMappingList) > 0 {
-//			for k, v := range calculateMappingList {
-//				v.EdbCode = edbInfo.EdbCode
-//				v.EdbInfoId = edbInfo.EdbInfoId
-//				calculateMappingList[k] = v
-//			}
-//			go models.AddEdbInfoCalculateMappingMulti(calculateMappingList)
+//		// 更新指标最大最小值
+//		err, errMsg := models.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo)
+//		if err != nil {
+//			br.Msg = errMsg
+//			br.ErrMsg = err.Error()
+//			return
 //		}
+//		br.Ret = 200
+//		br.Success = true
+//		br.Msg = "获取成功"
+//	} else {
+//		br.Ret = 501
+//		br.Success = true
+//		br.Msg = "系统处理中,请稍后重试"
 //	}
-//
-//	// 开始添加预测指标
-//	latestDateStr, latestValue, err := models.AddPredictCalculateData(edbInfoList, int(edbInfoId), edbCode, req.CalculateFormula, edbInfoIdBytes)
-//	if err != nil {
-//		br.Msg = "生成计算指标失败"
-//		br.Msg = "生成计算指标失败,Calculate Err:" + err.Error()
-//		return
-//	}
-//
-//	// 更新指标最大最小值
-//	err, errMsg := models.UnifiedModifyPredictEdbInfoMaxAndMinInfo(edbInfo, latestDateStr, latestValue)
-//	if err != nil {
-//		br.Msg = errMsg
-//		br.ErrMsg = err.Error()
-//		return
-//	}
-//	resp := models.AddEdbInfoResp{
-//		EdbInfoId:  int(edbInfoId),
-//		UniqueCode: uniqueCode,
-//	}
-//	br.Ret = 200
-//	br.Success = true
-//	br.Msg = "保存成功"
-//	br.Data = resp
-//	br.IsAddLog = true
 //}
-
-// Refresh
-// @Title 刷新计算指标接口
-// @Description 刷新计算指标接口
-// @Success 200 {object} models.RefreshEdbInfoReq
-// @router /refresh [post]
-func (this *PredictCalculateController) Refresh() {
-	br := new(models.BaseResponse).Init()
-	var cacheKey string
-	defer func() {
-		utils.Rc.Delete(cacheKey)
-		this.Data["json"] = br
-		this.ServeJSON()
-	}()
-	var req models.RefreshEdbInfoReq
-	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
-	if err != nil {
-		br.Msg = "参数解析异常!"
-		br.ErrMsg = "参数解析失败,Err:" + err.Error()
-		return
-	}
-	if req.EdbCode == "" {
-		br.Msg = "请输入指标编码!"
-		br.ErrMsg = "请输入指标编码,指标编码为空"
-		return
-	}
-	if req.EdbInfoId <= 0 {
-		br.Msg = "请输入指标ID!"
-		br.ErrMsg = "请输入指标ID"
-		return
-	}
-	edbInfo, err := models.GetEdbInfoById(req.EdbInfoId)
-	if err != nil {
-		br.Msg = "指标不存在!"
-		br.ErrMsg = "指标不存在"
-		return
-	}
-
-	cacheKey = utils.CACHE_EDB_DATA_REFRESH + strconv.Itoa(edbInfo.Source) + "_" + req.EdbCode
-	if !utils.Rc.IsExist(cacheKey) {
-		utils.Rc.SetNX(cacheKey, 1, 1*time.Minute)
-
-		startDate := req.StartDate
-		var errMsg string
-		endDate := time.Now().Format(utils.FormatDate)
-		edbInfoId := edbInfo.EdbInfoId
-		source := edbInfo.Source
-
-		switch source {
-		case utils.DATA_SOURCE_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)
-			}
-			err = models.RefreshAllCalculate(edbInfoList, edbInfo.EdbInfoId, source, edbInfo.EdbCode, edbInfo.CalculateFormula, startDate, endDate, edbInfoIdBytes)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				errMsg = "RefreshCalculate Err:" + err.Error()
-				break
-			}
-		case utils.DATA_SOURCE_CALCULATE_LJZZY: //刷新累计值转月值
-			calculateLjzzy, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
-			if err != nil {
-				errMsg = "GetEdbInfoCalculateLjzzyDetail Err:" + err.Error()
-				break
-			}
-			fromEdbInfo, err := models.GetEdbInfoById(calculateLjzzy.FromEdbInfoId)
-			if err != nil {
-				errMsg = "GetEdbInfoById Err:" + err.Error()
-				break
-			}
-			startDate = edbInfo.StartDate
-			endDate = time.Now().Format(utils.FormatDate)
-			err = models.RefreshAllCalculateLjzzy(edbInfoId, source, fromEdbInfo, calculateLjzzy.EdbCode, startDate, endDate)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				errMsg = "RefreshAllCalculateLjzzy Err:" + err.Error()
-				break
-			}
-		case utils.DATA_SOURCE_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
-			endDate = time.Now().Format(utils.FormatDate)
-			err = models.RefreshAllCalculateTbz(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate, endDate)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				errMsg = "RefreshAllCalculateTbz Err:" + err.Error()
-				break
-			}
-		case utils.DATA_SOURCE_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
-			endDate = time.Now().Format(utils.FormatDate)
-			err = models.RefreshAllCalculateTcz(edbInfoId, source, fromEdbInfo, calculateTcz.EdbCode, startDate, endDate)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				errMsg = "RefreshCalculateTcz Err:" + err.Error()
-				break
-			}
-		case utils.DATA_SOURCE_CALCULATE_NSZYDPJJS: //N数值移动平均计算
-			calculateNszydpjjs, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
-			if err != nil {
-				errMsg = "GetEdbInfoCalculateNszydpjjsDetail Err:" + err.Error()
-				break
-			}
-			fromEdbInfo, err := models.GetEdbInfoById(calculateNszydpjjs.FromEdbInfoId)
-			if err != nil {
-				errMsg = "GetEdbInfoById Err:" + err.Error()
-				break
-			}
-			formulaInt, _ := strconv.Atoi(edbInfo.CalculateFormula)
-			startDate = edbInfo.StartDate
-			err = models.RefreshAllCalculateNszydpjjs(edbInfoId, edbInfo.Source, formulaInt, fromEdbInfo, calculateNszydpjjs.EdbCode, startDate)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				errMsg = "RefreshCalculateNszydpjjs Err:" + err.Error()
-				break
-			}
-		case utils.DATA_SOURCE_CALCULATE_HBZ: //刷新环比值
-			calculateTbz, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
-			if err != nil {
-				errMsg = "GetEdbInfoCalculateHbzDetail Err:" + err.Error()
-				break
-			}
-			fromEdbInfo, err := models.GetEdbInfoById(calculateTbz.FromEdbInfoId)
-			if err != nil {
-				errMsg = "GetEdbInfoById Err:" + err.Error()
-				break
-			}
-			startDate = edbInfo.StartDate
-			endDate = time.Now().Format(utils.FormatDate)
-			formulaInt, _ := strconv.Atoi(edbInfo.CalculateFormula)
-			err = models.RefreshAllCalculateHbz(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate, endDate, formulaInt)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				errMsg = "RefreshAllCalculateHbz Err:" + err.Error()
-				break
-			}
-		case utils.DATA_SOURCE_CALCULATE_HCZ: //刷新环差值
-			calculateTbz, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
-			if err != nil {
-				errMsg = "GetEdbInfoCalculateHczDetail Err:" + err.Error()
-				break
-			}
-			fromEdbInfo, err := models.GetEdbInfoById(calculateTbz.FromEdbInfoId)
-			if err != nil {
-				errMsg = "GetEdbInfoById Err:" + err.Error()
-				break
-			}
-			startDate = edbInfo.StartDate
-			endDate = time.Now().Format(utils.FormatDate)
-			formulaInt, _ := strconv.Atoi(edbInfo.CalculateFormula)
-			err = models.RefreshAllCalculateHcz(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate, endDate, formulaInt)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				errMsg = "RefreshAllCalculateHcz Err:" + err.Error()
-				break
-			}
-		case utils.DATA_SOURCE_CALCULATE_BP: //刷新变频
-			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
-			endDate = time.Now().Format(utils.FormatDate)
-			err = models.RefreshAllCalculateBp(edbInfoId, source, fromEdbInfo, calculateTbz.EdbCode, startDate, endDate)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				errMsg = "RefreshAllCalculateBp Err:" + err.Error()
-				break
-			}
-		case utils.DATA_SOURCE_CALCULATE_TIME_SHIFT:
-			calculate, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
-			if err != nil {
-				errMsg = "GetEdbInfoCalculateTbzDetail Err:" + err.Error()
-				break
-			}
-			fromEdbInfo, err := models.GetEdbInfoById(calculate.FromEdbInfoId)
-			if err != nil {
-				errMsg = "GetEdbInfoById Err:" + err.Error()
-				break
-			}
-			startDate = edbInfo.StartDate
-			endDate = time.Now().Format(utils.FormatDate)
-			formulaInt, _ := strconv.Atoi(calculate.CalculateFormula)
-			err = models.RefreshAllCalculateTimeShift(edbInfoId, source, formulaInt, calculate.MoveType, fromEdbInfo, calculate.EdbCode, startDate, endDate, calculate.MoveFrequency)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				errMsg = "RefreshAllCalculateTimeShift Err:" + err.Error()
-			}
-		case utils.DATA_SOURCE_CALCULATE_ZJPJ: //刷新直接拼接
-			err = models.RefreshAllCalculateZjpj(edbInfo)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				errMsg = "RefreshAllCalculateZjpj Err:" + err.Error()
-				break
-			}
-		case utils.DATA_SOURCE_CALCULATE_LJZTBPJ: //刷新累计值同比拼接
-			err = models.RefreshAllCalculateLjztbpj(edbInfo)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				errMsg = "RefreshAllCalculateLjztbpj Err:" + err.Error()
-				break
-			}
-		case utils.DATA_SOURCE_PYTHON: //python代码运算
-			edbPythonCode, err := models.GetEdbPythonCodeById(edbInfo.EdbInfoId)
-			if err != nil {
-				errMsg = "获取python代码失败 Err:" + err.Error()
-				break
-			}
-			edbData, err, errMsg := services.ExecPythonCode(edbInfo.EdbCode, edbPythonCode.PythonCode)
-			if err != nil {
-				br.Msg = "获取数据失败"
-				br.ErrMsg = "python代码获取数据失败,err:" + err.Error()
-				if errMsg != "" {
-					br.ErrMsg = errMsg
-				}
-				return
-			}
-			err = models.RefreshAllPythonEdb(edbInfo, edbData)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				errMsg = "RefreshAllPythonEdb Err:" + err.Error()
-				break
-			}
-
-		default:
-			br.Msg = "来源异常,请联系相关开发!"
-			br.ErrMsg = "来源异常,请联系相关开发"
-			return
-		}
-		if errMsg != `` {
-			br.Msg = "刷新指标失败!"
-			br.ErrMsg = "刷新指标失败,err:" + errMsg
-			return
-		}
-
-		// 更新指标最大最小值
-		err, errMsg := models.UnifiedModifyEdbInfoMaxAndMinInfo(edbInfo)
-		if err != nil {
-			br.Msg = errMsg
-			br.ErrMsg = err.Error()
-			return
-		}
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "获取成功"
-	} else {
-		br.Ret = 501
-		br.Success = true
-		br.Msg = "系统处理中,请稍后重试"
-	}
-}

+ 140 - 300
models/predict_edb_data_calculate_tbz.go

@@ -11,8 +11,8 @@ import (
 	"time"
 )
 
-// AddPredictCalculateTbz 同比值
-func AddPredictCalculateTbz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbInfo, edbCode, uniqueCode string, sysUserId int, sysUserRealName string) (edbInfoId int, err error) {
+// SavePredictCalculateTbz 新增/编辑 预测同比指标
+func SavePredictCalculateTbz(reqEdbInfoId, classifyId int, edbName, frequency, unit, formula string, fromEdbInfo *EdbInfo, edbCode, uniqueCode string, sysUserId int, sysUserRealName string) (edbInfo *EdbInfo, latestDateStr string, latestValue float64, err error, errMsg string) {
 	o := orm.NewOrm()
 	to, err := o.Begin()
 	if err != nil {
@@ -26,45 +26,66 @@ func AddPredictCalculateTbz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 			_ = to.Commit()
 		}
 	}()
-	if req.EdbInfoId <= 0 {
-		edbInfo := new(EdbInfo)
-		edbInfo.Source = utils.DATA_SOURCE_CALCULATE_TBZ
-		edbInfo.SourceName = "同比值"
-		edbInfo.EdbCode = edbCode
-		edbInfo.EdbName = req.EdbName
-		edbInfo.EdbNameSource = req.EdbName
-		edbInfo.Frequency = req.Frequency
-		edbInfo.Unit = req.Unit
-		edbInfo.ClassifyId = req.ClassifyId
-		edbInfo.SysUserId = sysUserId
-		edbInfo.SysUserRealName = sysUserRealName
-		edbInfo.CreateTime = time.Now()
-		edbInfo.ModifyTime = time.Now()
-		edbInfo.UniqueCode = uniqueCode
-		edbInfo.CalculateFormula = req.Formula
-		edbInfo.EdbType = 2
+
+	if reqEdbInfoId <= 0 {
+		edbInfo = &EdbInfo{
+			//EdbInfoId:        0,
+			EdbInfoType:   1,
+			SourceName:    "预测同比",
+			Source:        utils.DATA_SOURCE_PREDICT_CALCULATE_TBZ,
+			EdbCode:       edbCode,
+			EdbName:       edbName,
+			EdbNameSource: edbName,
+			Frequency:     frequency,
+			Unit:          unit,
+			//StartDate:        "",
+			//EndDate:          "",
+			ClassifyId:       classifyId,
+			SysUserId:        sysUserId,
+			SysUserRealName:  sysUserRealName,
+			UniqueCode:       uniqueCode,
+			CreateTime:       time.Now(),
+			ModifyTime:       time.Now(),
+			MinValue:         0,
+			MaxValue:         0,
+			CalculateFormula: formula,
+			EdbType:          2,
+			Sort:             0,
+			MoveType:         0,
+			MoveFrequency:    "",
+			NoUpdate:         0,
+			ServerUrl:        "",
+			EdbNameEn:        "",
+			UnitEn:           "",
+			LatestDate:       "",
+			LatestValue:      0,
+			ChartImage:       "",
+		}
 		newEdbInfoId, tmpErr := to.Insert(edbInfo)
 		if tmpErr != nil {
-			return edbInfoId, tmpErr
+			err = tmpErr
+			return
 		}
-		edbInfoId = int(newEdbInfoId)
+		edbInfo.EdbInfoId = int(newEdbInfoId)
 
-		//关联关系
+		// 添加关联关系
 		{
-			calculateMappingItem := new(EdbInfoCalculateMapping)
-			calculateMappingItem.CreateTime = time.Now()
-			calculateMappingItem.ModifyTime = time.Now()
-			calculateMappingItem.Sort = 1
-			calculateMappingItem.EdbCode = edbCode
-			calculateMappingItem.EdbInfoId = edbInfoId
-			calculateMappingItem.FromEdbInfoId = fromEdbInfo.EdbInfoId
-			calculateMappingItem.FromEdbCode = fromEdbInfo.EdbCode
-			calculateMappingItem.FromEdbName = fromEdbInfo.EdbName
-			calculateMappingItem.FromSource = fromEdbInfo.Source
-			calculateMappingItem.FromSourceName = fromEdbInfo.SourceName
-			calculateMappingItem.FromTag = ""
-			calculateMappingItem.Source = edbInfo.Source
-			calculateMappingItem.SourceName = edbInfo.SourceName
+			calculateMappingItem := &EdbInfoCalculateMapping{
+				EdbInfoCalculateMappingId: 0,
+				EdbInfoId:                 edbInfo.EdbInfoId,
+				Source:                    edbInfo.Source,
+				SourceName:                edbInfo.SourceName,
+				EdbCode:                   edbCode,
+				FromEdbInfoId:             fromEdbInfo.EdbInfoId,
+				FromEdbCode:               fromEdbInfo.EdbCode,
+				FromEdbName:               fromEdbInfo.EdbName,
+				FromSource:                fromEdbInfo.Source,
+				FromSourceName:            fromEdbInfo.SourceName,
+				FromTag:                   "",
+				Sort:                      1,
+				CreateTime:                time.Now(),
+				ModifyTime:                time.Now(),
+			}
 			_, err = to.Insert(calculateMappingItem)
 			if err != nil {
 				return
@@ -72,31 +93,38 @@ func AddPredictCalculateTbz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 		}
 
 	} else {
-		edbInfoId = req.EdbInfoId
-		dataTableName := GetEdbDataTableName(utils.DATA_SOURCE_CALCULATE_TBZ)
+		edbInfo, err = GetEdbInfoById(reqEdbInfoId)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				errMsg = `获取指标信息失败`
+			}
+			return
+		}
+		if edbInfo.EdbInfoType != 1 {
+			errMsg = `该指标不是预测指标`
+			err = errors.New(errMsg)
+			return
+		}
+
+		// 删除该指标所有的同比数据
+		dataTableName := GetEdbDataTableName(utils.DATA_SOURCE_PREDICT_CALCULATE_TBZ)
 		deleteSql := ` DELETE FROM %s WHERE edb_info_id=? `
 		deleteSql = fmt.Sprintf(deleteSql, dataTableName)
-		_, err = to.Raw(deleteSql, req.EdbInfoId).Exec()
+		_, err = to.Raw(deleteSql, edbInfo.EdbInfoId).Exec()
 		if err != nil {
 			return
 		}
 	}
 
-	edbInfoIdStr := strconv.Itoa(edbInfoId)
-
-	//计算数据
-	var condition string
-	var pars []interface{}
-	condition += " AND edb_info_id=? "
-	if req.EdbInfoId <= 0 {
-		pars = append(pars, req.FromEdbInfoId)
-	} else {
-		pars = append(pars, fromEdbInfo.EdbInfoId)
-	}
-	dataList, err := GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 0)
+	edbInfoIdStr := strconv.Itoa(edbInfo.EdbInfoId)
+	// 获取源指标数据
+	dataList, err := GetPredictEdbDataListAll(fromEdbInfo, 0)
 	if err != nil {
-		return edbInfoId, err
+		return
 	}
+
+	latestDateStr = fromEdbInfo.LatestDate
+	// 计算数据
 	var dateArr []string
 	dataMap := make(map[string]*EdbInfoSearchData)
 	for _, v := range dataList {
@@ -112,9 +140,10 @@ func AddPredictCalculateTbz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 		currentItem := dataMap[av]
 		if currentItem != nil {
 			//当前日期
-			currentDate, err := time.Parse(utils.FormatDate, av)
-			if err != nil {
-				return edbInfoId, err
+			currentDate, tmpErr := time.Parse(utils.FormatDate, av)
+			if tmpErr != nil {
+				err = tmpErr
+				return
 			}
 			//上一年的日期
 			preDate := currentDate.AddDate(-1, 0, 0)
@@ -128,6 +157,15 @@ func AddPredictCalculateTbz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 					addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
 					isAdd = true
 					utils.FileLog.Info("同期找到:" + av + ";" + preDateStr)
+
+					// 实际数据的值
+					if fromEdbInfo.LatestDate == av {
+						latestValueDecimal, tmpErr := decimal.NewFromString(val)
+						if tmpErr != nil {
+							return
+						}
+						latestValue, _ = latestValueDecimal.Truncate(4).Float64() //保留4位小数
+					}
 				}
 				existMap[edbCode+av] = av
 			} else {
@@ -143,6 +181,15 @@ func AddPredictCalculateTbz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 								val := TbzDiv(currentItem.Value, findItem.Value)
 								addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
 								isAdd = true
+
+								// 实际数据的值
+								if fromEdbInfo.LatestDate == av {
+									latestValueDecimal, tmpErr := decimal.NewFromString(val)
+									if tmpErr != nil {
+										return
+									}
+									latestValue, _ = latestValueDecimal.Truncate(4).Float64() //保留4位小数
+								}
 							}
 							existMap[edbCode+av] = av
 							break
@@ -156,6 +203,15 @@ func AddPredictCalculateTbz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 
 									addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
 									isAdd = true
+
+									// 实际数据的值
+									if fromEdbInfo.LatestDate == av {
+										latestValueDecimal, tmpErr := decimal.NewFromString(val)
+										if tmpErr != nil {
+											return
+										}
+										latestValue, _ = latestValueDecimal.Truncate(4).Float64() //保留4位小数
+									}
 								}
 								existMap[edbCode+av] = av
 								break
@@ -173,6 +229,15 @@ func AddPredictCalculateTbz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 
 							addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
 							isAdd = true
+
+							// 实际数据的值
+							if fromEdbInfo.LatestDate == av {
+								latestValueDecimal, tmpErr := decimal.NewFromString(val)
+								if tmpErr != nil {
+									return
+								}
+								latestValue, _ = latestValueDecimal.Truncate(4).Float64() //保留4位小数
+							}
 						}
 						existMap[edbCode+av] = av
 						break
@@ -190,6 +255,15 @@ func AddPredictCalculateTbz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 								val := TbzDiv(currentItem.Value, findItem.Value)
 								addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
 								isAdd = true
+
+								// 实际数据的值
+								if fromEdbInfo.LatestDate == av {
+									latestValueDecimal, tmpErr := decimal.NewFromString(val)
+									if tmpErr != nil {
+										return
+									}
+									latestValue, _ = latestValueDecimal.Truncate(4).Float64() //保留4位小数
+								}
 							}
 							existMap[edbCode+av] = av
 							break
@@ -202,6 +276,15 @@ func AddPredictCalculateTbz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 									val := TbzDiv(currentItem.Value, findItem.Value)
 									addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
 									isAdd = true
+
+									// 实际数据的值
+									if fromEdbInfo.LatestDate == av {
+										latestValueDecimal, tmpErr := decimal.NewFromString(val)
+										if tmpErr != nil {
+											return
+										}
+										latestValue, _ = latestValueDecimal.Truncate(4).Float64() //保留4位小数
+									}
 								}
 								existMap[edbCode+av] = av
 								break
@@ -216,255 +299,12 @@ func AddPredictCalculateTbz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 			}
 		}
 	}
+
 	if isAdd {
 		addSql = strings.TrimRight(addSql, ",")
 		_, err = to.Raw(addSql).Exec()
 		if err != nil {
-			return edbInfoId, err
-		}
-	}
-	return
-}
-
-// EditPredictCalculateTbz 同比值
-func EditPredictCalculateTbz(req *EdbInfoCalculateBatchEditReq, fromEdbInfo *EdbInfo, edbCode string) (edbInfoId int, err error) {
-	edbInfoId = req.EdbInfoId
-	o := orm.NewOrm()
-	to, err := o.Begin()
-	if err != nil {
-		return
-	}
-	defer func() {
-		if err != nil {
-			fmt.Println("EditCalculateTbz,Err:" + err.Error())
-			_ = to.Rollback()
-		} else {
-			_ = to.Commit()
-		}
-	}()
-
-	//修改指标信息
-	sql := ` UPDATE  edb_info
-			SET
-			  edb_name =?,
-			  edb_name_source=?,
-			  frequency = ?,
-			  unit = ?,
-			  classify_id = ?,
-			  modify_time = NOW()
-			WHERE edb_info_id = ? `
-	_, err = o.Raw(sql, req.EdbName, req.EdbName, req.Frequency, req.Unit, req.ClassifyId, edbInfoId).Exec()
-	if err != nil {
-		return
-	}
-
-	var existCondition string
-	var existPars []interface{}
-	existCondition += " AND edb_info_id=? "
-	existPars = append(existPars, edbInfoId)
-
-	existCondition += " AND from_edb_info_id=? "
-	existPars = append(existPars, req.FromEdbInfoId)
-
-	//判断计算指标是否被更换
-	count, err := GetEdbInfoCalculateCountByCondition(existCondition, existPars)
-	if err != nil {
-		err = errors.New("判断指标是否改变失败,Err:" + err.Error())
-		return
-	}
-	if count <= 0 {
-		//删除指标关联计算指标
-		//sql := ` DELETE FROM edb_info_calculate_tbz WHERE edb_info_id = ? `
-		//_, err = o.Raw(sql, edbInfoId).Exec()
-		//if err != nil {
-		//	return
-		//}
-		//
-		//calculateItem := new(EdbInfoCalculateTbz)
-		//calculateItem.CreateTime = time.Now()
-		//calculateItem.ModifyTime = time.Now()
-		//calculateItem.Sort = 1
-		//calculateItem.EdbCode = edbCode
-		//calculateItem.EdbInfoId = edbInfoId
-		//calculateItem.FromEdbInfoId = fromEdbInfo.EdbInfoId
-		//calculateItem.FromEdbCode = fromEdbInfo.EdbCode
-		//calculateItem.FromEdbName = fromEdbInfo.EdbName
-		//calculateItem.FromSource = fromEdbInfo.Source
-		//calculateItem.FromSourceName = fromEdbInfo.SourceName
-		//
-		//_, err = o.Insert(calculateItem)
-		//if err != nil {
-		//	return
-		//}
-
-		//删除,计算指标关联的,基础指标的关联关系
-		sql = ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id = ? `
-		_, err = o.Raw(sql, edbInfoId).Exec()
-		if err != nil {
-			return edbInfoId, err
-		}
-		//清空原有数据
-		sql = ` DELETE FROM edb_data_predict_calculate_tbz WHERE edb_info_id = ? `
-		_, err = o.Raw(sql, edbInfoId).Exec()
-		if err != nil {
-			return edbInfoId, err
-		}
-		//关联关系
-		{
-			calculateMappingItem := new(EdbInfoCalculateMapping)
-			calculateMappingItem.CreateTime = time.Now()
-			calculateMappingItem.ModifyTime = time.Now()
-			calculateMappingItem.Sort = 1
-			calculateMappingItem.EdbCode = edbCode
-			calculateMappingItem.EdbInfoId = edbInfoId
-			calculateMappingItem.FromEdbInfoId = fromEdbInfo.EdbInfoId
-			calculateMappingItem.FromEdbCode = fromEdbInfo.EdbCode
-			calculateMappingItem.FromEdbName = fromEdbInfo.EdbName
-			calculateMappingItem.FromSource = fromEdbInfo.Source
-			calculateMappingItem.FromSourceName = fromEdbInfo.SourceName
-			calculateMappingItem.FromTag = ""
-			calculateMappingItem.Source = utils.DATA_SOURCE_CALCULATE_TBZ
-			calculateMappingItem.SourceName = "同比值"
-			_, err = o.Insert(calculateMappingItem)
-			if err != nil {
-				return
-			}
-		}
-
-		edbInfoIdStr := strconv.Itoa(edbInfoId)
-
-		//计算数据
-		var condition string
-		var pars []interface{}
-		condition += " AND edb_info_id=? "
-		pars = append(pars, req.FromEdbInfoId)
-		fmt.Println("EdbInfoId:", req.FromEdbInfoId)
-		dataList, err := GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 0)
-		if err != nil {
-			return edbInfoId, err
-		}
-		var dateArr []string
-		dataMap := make(map[string]*EdbInfoSearchData)
-		for _, v := range dataList {
-			dateArr = append(dateArr, v.DataTime)
-			dataMap[v.DataTime] = v
-		}
-
-		addSql := ` INSERT INTO edb_data_predict_calculate_tbz(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
-		var isAdd bool
-		for _, av := range dateArr {
-			currentItem := dataMap[av]
-			if currentItem != nil {
-				//当前日期
-				currentDate, err := time.Parse(utils.FormatDate, av)
-				if err != nil {
-					return edbInfoId, err
-				}
-				//上一年的日期
-				preDate := currentDate.AddDate(-1, 0, 0)
-				preDateStr := preDate.Format(utils.FormatDate)
-				if findItem, ok := dataMap[preDateStr]; ok { //上一年同期找到
-					//dataTime, _ := time.Parse(utils.FormatDate, date)
-					timestamp := currentDate.UnixNano() / 1e6
-					timestampStr := fmt.Sprintf("%d", timestamp)
-					val := TbzDiv(currentItem.Value, findItem.Value)
-					addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
-					isAdd = true
-					utils.FileLog.Info("同期找到:" + av + ";" + preDateStr)
-					continue
-				} else {
-					if fromEdbInfo.Frequency == "月度" { //向上和向下,各找一个月
-						nextDateDay := preDate.AddDate(0, 1, 0)
-						nextDateDayStr := nextDateDay.Format(utils.FormatDate)
-
-						preDateDay := preDate.AddDate(0, -1, 0)
-						preDateDayStr := preDateDay.Format(utils.FormatDate)
-
-						for i := 0; i <= 6; i++ {
-							if i >= 1 {
-								nextDateDay = nextDateDay.AddDate(0, 0, i)
-								nextDateDayStr = nextDateDay.Format(utils.FormatDate)
-							}
-							if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
-								timestamp := currentDate.UnixNano() / 1e6
-								timestampStr := fmt.Sprintf("%d", timestamp)
-								val := TbzDiv(currentItem.Value, findItem.Value)
-
-								addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
-								isAdd = true
-								break
-							} else {
-								if i >= 1 {
-									preDateDay = preDate.AddDate(0, 0, -i)
-									preDateDayStr = nextDateDay.Format(utils.FormatDate)
-								}
-								if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
-									timestamp := currentDate.UnixNano() / 1e6
-									timestampStr := fmt.Sprintf("%d", timestamp)
-									val := TbzDiv(currentItem.Value, findItem.Value)
-
-									addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
-									isAdd = true
-									break
-								}
-							}
-						}
-					} else if fromEdbInfo.Frequency == "季度" || fromEdbInfo.Frequency == "年度" {
-						if findItem, ok := dataMap[preDateStr]; ok { //上一年同期->下一个月找到
-							timestamp := currentDate.UnixNano() / 1e6
-							timestampStr := fmt.Sprintf("%d", timestamp)
-							val := TbzDiv(currentItem.Value, findItem.Value)
-
-							addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
-							isAdd = true
-							break
-						}
-					} else {
-						nextDateDay := preDate.AddDate(0, 0, 1)
-						nextDateDayStr := nextDateDay.Format(utils.FormatDate)
-
-						preDateDay := preDate.AddDate(0, 0, -1)
-						preDateDayStr := preDateDay.Format(utils.FormatDate)
-
-						for i := 0; i < 35; i++ {
-							if i >= 1 {
-								nextDateDay = nextDateDay.AddDate(0, 0, i)
-								nextDateDayStr = nextDateDay.Format(utils.FormatDate)
-							}
-							if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
-								timestamp := currentDate.UnixNano() / 1e6
-								timestampStr := fmt.Sprintf("%d", timestamp)
-								val := TbzDiv(currentItem.Value, findItem.Value)
-
-								addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
-								isAdd = true
-								break
-							} else {
-								if i >= 1 {
-									preDateDay = preDate.AddDate(0, 0, -i)
-									preDateDayStr = nextDateDay.Format(utils.FormatDate)
-								}
-								if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
-									timestamp := currentDate.UnixNano() / 1e6
-									timestampStr := fmt.Sprintf("%d", timestamp)
-									val := TbzDiv(currentItem.Value, findItem.Value)
-
-									addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
-									isAdd = true
-									break
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-		if isAdd {
-			addSql = strings.TrimRight(addSql, ",")
-			_, err = o.Raw(addSql).Exec()
-			if err != nil {
-				return edbInfoId, err
-			}
+			return
 		}
 	}
 	return

+ 143 - 59
models/predict_edb_data_calculate_tcz.go

@@ -11,8 +11,8 @@ import (
 	"time"
 )
 
-// AddPredictCalculateTcz 同差值
-func AddPredictCalculateTcz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbInfo, edbCode, uniqueCode string, sysUserId int, sysUserRealName string) (edbInfoId int, err error) {
+// SavePredictCalculateTcz 同差值
+func SavePredictCalculateTcz(reqEdbInfoId, classifyId int, edbName, frequency, unit, formula string, fromEdbInfo *EdbInfo, edbCode, uniqueCode string, sysUserId int, sysUserRealName string) (edbInfo *EdbInfo, latestDateStr string, latestValue float64, err error, errMsg string) {
 	o := orm.NewOrm()
 	to, err := o.Begin()
 	if err != nil {
@@ -26,87 +26,116 @@ func AddPredictCalculateTcz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 			_ = to.Commit()
 		}
 	}()
-	fmt.Println("req.EdbInfoId:", req.EdbInfoId)
-	if req.EdbInfoId <= 0 {
-		edbInfo := new(EdbInfo)
-		edbInfo.Source = utils.DATA_SOURCE_CALCULATE_TCZ
-		edbInfo.SourceName = "同差值"
-		edbInfo.EdbCode = edbCode
-		edbInfo.EdbName = req.EdbName
-		edbInfo.EdbNameSource = req.EdbName
-		edbInfo.Frequency = req.Frequency
-		edbInfo.Unit = req.Unit
-		edbInfo.ClassifyId = req.ClassifyId
-		edbInfo.SysUserId = sysUserId
-		edbInfo.SysUserRealName = sysUserRealName
-		edbInfo.CreateTime = time.Now()
-		edbInfo.ModifyTime = time.Now()
-		edbInfo.UniqueCode = uniqueCode
-		edbInfo.CalculateFormula = req.Formula
-		edbInfo.EdbType = 2
+	fmt.Println("reqEdbInfoId:", reqEdbInfoId)
+
+	if reqEdbInfoId <= 0 {
+		edbInfo = &EdbInfo{
+			//EdbInfoId:        0,
+			EdbInfoType:   1,
+			SourceName:    "预测同差",
+			Source:        utils.DATA_SOURCE_PREDICT_CALCULATE_TCZ,
+			EdbCode:       edbCode,
+			EdbName:       edbName,
+			EdbNameSource: edbName,
+			Frequency:     frequency,
+			Unit:          unit,
+			//StartDate:        "",
+			//EndDate:          "",
+			ClassifyId:       classifyId,
+			SysUserId:        sysUserId,
+			SysUserRealName:  sysUserRealName,
+			UniqueCode:       uniqueCode,
+			CreateTime:       time.Now(),
+			ModifyTime:       time.Now(),
+			MinValue:         0,
+			MaxValue:         0,
+			CalculateFormula: formula,
+			EdbType:          2,
+			Sort:             0,
+			MoveType:         0,
+			MoveFrequency:    "",
+			NoUpdate:         0,
+			ServerUrl:        "",
+			EdbNameEn:        "",
+			UnitEn:           "",
+			LatestDate:       "",
+			LatestValue:      0,
+			ChartImage:       "",
+		}
 		newEdbInfoId, tmpErr := to.Insert(edbInfo)
 		if tmpErr != nil {
-			return edbInfoId, tmpErr
+			err = tmpErr
+			return
 		}
-		edbInfoId = int(newEdbInfoId)
+		edbInfo.EdbInfoId = int(newEdbInfoId)
 
-		//关联关系
+		// 添加关联关系
 		{
-			calculateMappingItem := new(EdbInfoCalculateMapping)
-			calculateMappingItem.CreateTime = time.Now()
-			calculateMappingItem.ModifyTime = time.Now()
-			calculateMappingItem.Sort = 1
-			calculateMappingItem.EdbCode = edbCode
-			calculateMappingItem.EdbInfoId = edbInfoId
-			calculateMappingItem.FromEdbInfoId = fromEdbInfo.EdbInfoId
-			calculateMappingItem.FromEdbCode = fromEdbInfo.EdbCode
-			calculateMappingItem.FromEdbName = fromEdbInfo.EdbName
-			calculateMappingItem.FromSource = fromEdbInfo.Source
-			calculateMappingItem.FromSourceName = fromEdbInfo.SourceName
-			calculateMappingItem.FromTag = ""
-			calculateMappingItem.Source = edbInfo.Source
-			calculateMappingItem.SourceName = edbInfo.SourceName
+			calculateMappingItem := &EdbInfoCalculateMapping{
+				EdbInfoCalculateMappingId: 0,
+				EdbInfoId:                 edbInfo.EdbInfoId,
+				Source:                    edbInfo.Source,
+				SourceName:                edbInfo.SourceName,
+				EdbCode:                   edbCode,
+				FromEdbInfoId:             fromEdbInfo.EdbInfoId,
+				FromEdbCode:               fromEdbInfo.EdbCode,
+				FromEdbName:               fromEdbInfo.EdbName,
+				FromSource:                fromEdbInfo.Source,
+				FromSourceName:            fromEdbInfo.SourceName,
+				FromTag:                   "",
+				Sort:                      1,
+				CreateTime:                time.Now(),
+				ModifyTime:                time.Now(),
+			}
 			_, err = to.Insert(calculateMappingItem)
 			if err != nil {
 				return
 			}
 		}
 	} else {
-		edbInfoId = req.EdbInfoId
+		edbInfo, err = GetEdbInfoById(reqEdbInfoId)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				errMsg = `获取指标信息失败`
+			}
+			return
+		}
+		if edbInfo.EdbInfoType != 1 {
+			errMsg = `该指标不是预测指标`
+			err = errors.New(errMsg)
+			return
+		}
+
+		// 删除该指标所有的同差数据
 		dataTableName := GetEdbDataTableName(utils.DATA_SOURCE_CALCULATE_TCZ)
 		fmt.Println("dataTableName:", dataTableName)
 		deleteSql := ` DELETE FROM %s WHERE edb_info_id=? `
 		deleteSql = fmt.Sprintf(deleteSql, dataTableName)
-		_, err = to.Raw(deleteSql, req.EdbInfoId).Exec()
+		_, err = to.Raw(deleteSql, edbInfo.EdbInfoId).Exec()
 		if err != nil {
-			return edbInfoId, err
+			return
 		}
 	}
 
-	edbInfoIdStr := strconv.Itoa(edbInfoId)
-
-	//计算数据
-	var condition string
-	var pars []interface{}
-	condition += " AND edb_info_id=? "
-	if req.EdbInfoId <= 0 {
-		pars = append(pars, req.FromEdbInfoId)
-	} else {
-		pars = append(pars, fromEdbInfo.EdbInfoId)
-	}
+	edbInfoIdStr := strconv.Itoa(edbInfo.EdbInfoId)
 
-	fmt.Println("EdbInfoId:", req.FromEdbInfoId)
-	dataList, err := GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 0)
+	//获取源指标数据
+	fmt.Println("EdbInfoId:", fromEdbInfo.EdbInfoId)
+	dataList, err := GetPredictEdbDataListAll(fromEdbInfo, 0)
 	if err != nil {
-		return edbInfoId, err
+		return
 	}
+
+	latestDateStr = fromEdbInfo.LatestDate
+	// 计算数据
 	var dateArr []string
 	dataMap := make(map[string]*EdbInfoSearchData)
 	for _, v := range dataList {
 		dateArr = append(dateArr, v.DataTime)
 		dataMap[v.DataTime] = v
 	}
-	fmt.Println("Frequency:", fromEdbInfo.Frequency)
+	//fmt.Println("Frequency:", fromEdbInfo.Frequency)
+
 	addSql := ` INSERT INTO edb_data_predict_calculate_tcz(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
 	var isAdd bool
 	existMap := make(map[string]string)
@@ -115,9 +144,10 @@ func AddPredictCalculateTcz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 		currentItem := dataMap[av]
 		if currentItem != nil {
 			//当前日期
-			currentDate, err := time.Parse(utils.FormatDate, av)
-			if err != nil {
-				return edbInfoId, err
+			currentDate, tmpErr := time.Parse(utils.FormatDate, av)
+			if tmpErr != nil {
+				err = tmpErr
+				return
 			}
 			//上一年的日期
 			preDate := currentDate.AddDate(-1, 0, 0)
@@ -131,6 +161,15 @@ func AddPredictCalculateTcz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 					val := TczSub(currentItem.Value, findItem.Value)
 					addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
 					isAdd = true
+
+					// 实际数据的值
+					if fromEdbInfo.LatestDate == av {
+						latestValueDecimal, tmpErr := decimal.NewFromString(val)
+						if tmpErr != nil {
+							return
+						}
+						latestValue, _ = latestValueDecimal.Truncate(4).Float64() //保留4位小数
+					}
 				}
 				existMap[edbCode+av] = av
 			} else {
@@ -147,6 +186,15 @@ func AddPredictCalculateTcz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 
 								addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
 								isAdd = true
+
+								// 实际数据的值
+								if fromEdbInfo.LatestDate == av {
+									latestValueDecimal, tmpErr := decimal.NewFromString(val)
+									if tmpErr != nil {
+										return
+									}
+									latestValue, _ = latestValueDecimal.Truncate(4).Float64() //保留4位小数
+								}
 							}
 							existMap[edbCode+av] = av
 							break
@@ -160,6 +208,15 @@ func AddPredictCalculateTcz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 
 									addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
 									isAdd = true
+
+									// 实际数据的值
+									if fromEdbInfo.LatestDate == av {
+										latestValueDecimal, tmpErr := decimal.NewFromString(val)
+										if tmpErr != nil {
+											return
+										}
+										latestValue, _ = latestValueDecimal.Truncate(4).Float64() //保留4位小数
+									}
 								}
 								existMap[edbCode+av] = av
 								break
@@ -176,6 +233,15 @@ func AddPredictCalculateTcz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 							val := TczSub(currentItem.Value, findItem.Value)
 							addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
 							isAdd = true
+
+							// 实际数据的值
+							if fromEdbInfo.LatestDate == av {
+								latestValueDecimal, tmpErr := decimal.NewFromString(val)
+								if tmpErr != nil {
+									return
+								}
+								latestValue, _ = latestValueDecimal.Truncate(4).Float64() //保留4位小数
+							}
 						}
 						existMap[edbCode+av] = av
 						break
@@ -193,6 +259,15 @@ func AddPredictCalculateTcz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 
 								addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
 								isAdd = true
+
+								// 实际数据的值
+								if fromEdbInfo.LatestDate == av {
+									latestValueDecimal, tmpErr := decimal.NewFromString(val)
+									if tmpErr != nil {
+										return
+									}
+									latestValue, _ = latestValueDecimal.Truncate(4).Float64() //保留4位小数
+								}
 							}
 							existMap[edbCode+av] = av
 							break
@@ -206,6 +281,15 @@ func AddPredictCalculateTcz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 
 									addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
 									isAdd = true
+
+									// 实际数据的值
+									if fromEdbInfo.LatestDate == av {
+										latestValueDecimal, tmpErr := decimal.NewFromString(val)
+										if tmpErr != nil {
+											return
+										}
+										latestValue, _ = latestValueDecimal.Truncate(4).Float64() //保留4位小数
+									}
 								}
 								existMap[edbCode+av] = av
 								break
@@ -224,7 +308,7 @@ func AddPredictCalculateTcz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbI
 		addSql = strings.TrimRight(addSql, ",")
 		_, err = to.Raw(addSql).Exec()
 		if err != nil {
-			return edbInfoId, err
+			return
 		}
 	}
 	return

+ 2 - 2
routers/commentsRouter.go

@@ -234,8 +234,8 @@ func init() {
 
     beego.GlobalControllerRouter["hongze/hongze_edb_lib/controllers:PredictCalculateController"] = append(beego.GlobalControllerRouter["hongze/hongze_edb_lib/controllers:PredictCalculateController"],
         beego.ControllerComments{
-            Method: "Refresh",
-            Router: `/refresh`,
+            Method: "CalculateBatchSave",
+            Router: `/batch/save`,
             AllowHTTPMethods: []string{"post"},
             MethodParams: param.Make(),
             Filters: nil,