Browse Source

Merge remote-tracking branch 'origin/debug'

Roc 2 years ago
parent
commit
0d0f48d70f

+ 95 - 0
models/data_manage/predict_edb_conf_calculate_mapping.go

@@ -0,0 +1,95 @@
+package data_manage
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"hongze/hongze_chart_lib/utils"
+	"time"
+)
+
+// PredictEdbConfCalculateMapping 预测基础指标规则 与 计算预测指标关联关系表
+type PredictEdbConfCalculateMapping struct {
+	PredictEdbConfCalculateMappingId int       `orm:"column(predict_edb_conf_calculate_mapping_id);pk"`
+	EdbInfoId                        int       `description:"指标id"`
+	ConfigId                         int       `description:"配置id"`
+	FromEdbInfoId                    int       `description:"基础指标id"`
+	FromEdbCode                      string    `description:"基础指标编码"`
+	FromEdbName                      string    `description:"基础指标名称"`
+	FromSource                       int       `description:"基础指标来源"`
+	FromSourceName                   string    `description:"基础指标来源名称"`
+	FromTag                          string    `description:"来源指标标签"`
+	Sort                             int       `description:"计算指标名称排序"`
+	CreateTime                       time.Time `description:"创建时间"`
+	ModifyTime                       time.Time `description:"修改时间"`
+}
+
+// GetPredictEdbConfCalculateMappingListById 根据预测指标id获取预测指标配置的关联指标信息列表
+func GetPredictEdbConfCalculateMappingListById(edbInfoId int) (items []*PredictEdbConf, err error) {
+	o := orm.NewOrmUsingDB("data")
+	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(&items)
+	return
+}
+
+// GetPredictEdbConfCalculateMappingListByConfigId 根据预测指标配置id获取预测指标配置的关联指标信息列表
+func GetPredictEdbConfCalculateMappingListByConfigId(edbInfoId, configId int) (items []*PredictEdbConf, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM predict_edb_conf_calculate_mapping WHERE edb_info_id=? AND config_id=? ORDER BY predict_edb_conf_calculate_mapping_id ASC`
+	_, err = o.Raw(sql, edbInfoId, configId).QueryRows(&items)
+	return
+}
+
+type PredictEdbConfCalculateMappingDetail struct {
+	PredictEdbConfCalculateMappingId int       `orm:"column(predict_edb_conf_calculate_mapping_id);pk"`
+	EdbInfoId                        int       `description:"指标id"`
+	ConfigId                         int       `description:"配置id"`
+	FromEdbInfoId                    int       `description:"基础指标id"`
+	FromEdbCode                      string    `description:"基础指标编码"`
+	FromEdbName                      string    `description:"基础指标名称"`
+	FromSource                       int       `description:"基础指标来源"`
+	FromSourceName                   string    `description:"基础指标来源名称"`
+	FromTag                          string    `description:"来源指标标签"`
+	Sort                             int       `description:"计算指标名称排序"`
+	CreateTime                       time.Time `description:"创建时间"`
+	ModifyTime                       time.Time `description:"修改时间"`
+	StartDate                        string    `description:"开始日期"`
+	EndDate                          string    `description:"结束日期"`
+	EdbType                          int       `description:"指标类型:1:基础指标,2:计算指标"`
+	EdbCode                          string    `description:"指标code"`
+}
+
+// GetPredictEdbConfCalculateMappingDetailListById 根据配置id获取 配置关联指标信息
+func GetPredictEdbConfCalculateMappingDetailListById(edbInfoId int) (list []*PredictEdbConfCalculateMappingDetail, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT a.predict_edb_conf_calculate_mapping_id,a.edb_info_id,a.from_edb_info_id,a.from_edb_code,a.from_source,a.from_source_name,a.sort,a.create_time,a.modify_time,a.from_tag,b.edb_name_source as from_edb_name,b.start_date,b.end_date,b.edb_type FROM predict_edb_conf_calculate_mapping AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id=? ORDER BY sort ASC `
+
+	_, err = o.Raw(sql, edbInfoId).QueryRows(&list)
+	return
+}
+
+// GetPredictEdbConfCalculateMappingDetailListByConfigId 根据配置id和指标id获取 配置关联指标信息
+func GetPredictEdbConfCalculateMappingDetailListByConfigId(edbInfoId, configId int) (list []*PredictEdbConfCalculateMappingDetail, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT a.predict_edb_conf_calculate_mapping_id,a.edb_info_id,a.from_edb_info_id,a.from_edb_code,a.from_source,a.from_source_name,a.sort,a.create_time,a.modify_time,a.from_tag,b.edb_name_source as from_edb_name,b.start_date,b.end_date,b.edb_type FROM predict_edb_conf_calculate_mapping AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id=? AND a.config_id=?  ORDER BY sort ASC `
+
+	_, err = o.Raw(sql, edbInfoId, configId).QueryRows(&list)
+	return
+}
+
+// GetPredictEdbConfCalculateMappingDetailListByEdbInfoId 根据 关联指标id列表 来 获取 相关联的配置关联指标信息
+func GetPredictEdbConfCalculateMappingDetailListByEdbInfoId(fromEdbInfoIdList []int) (list []*PredictEdbConfCalculateMappingDetail, err error) {
+	num := len(fromEdbInfoIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT a.predict_edb_conf_calculate_mapping_id,a.edb_info_id,a.from_edb_info_id,a.from_edb_code,a.from_source,a.from_source_name,a.sort,a.create_time,a.modify_time,a.from_tag,b.edb_name_source as from_edb_name,b.start_date,b.end_date,b.edb_type,b.edb_code FROM predict_edb_conf_calculate_mapping AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id in (` + utils.GetOrmInReplace(num) + `) GROUP BY a.edb_info_id ORDER BY sort ASC `
+
+	_, err = o.Raw(sql, fromEdbInfoIdList).QueryRows(&list)
+	return
+}

+ 36 - 0
models/data_manage/predict_edb_rule_data.go

@@ -0,0 +1,36 @@
+package data_manage
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// PredictEdbRuleData 预测指标,动态规则的计算数据
+type PredictEdbRuleData struct {
+	PredictEdbRuleDataId int `orm:"column(predict_edb_rule_data_id);pk"`
+	EdbInfoId            int
+	ConfigId             int
+	DataTime             string
+	Value                float64
+	CreateTime           time.Time
+	ModifyTime           time.Time
+	DataTimestamp        int64
+}
+
+// GetPredictEdbRuleDataList 根据基础预测指标id集合 获取 所有的普通指标列表数据
+func GetPredictEdbRuleDataList(edbInfoId, configId int, startDate, endDate string) (list []*PredictEdbRuleData, err error) {
+	o := orm.NewOrmUsingDB("data")
+	var pars []interface{}
+	sql := ` SELECT * FROM predict_edb_rule_data WHERE edb_info_id = ? AND config_id = ? `
+	if startDate != "" {
+		sql += ` AND data_time>=? `
+		pars = append(pars, startDate)
+	}
+	if endDate != "" {
+		sql += ` AND data_time<=? `
+		pars = append(pars, endDate)
+	}
+	sql += ` ORDER BY data_time ASC `
+	_, err = o.Raw(sql, edbInfoId, configId, pars).QueryRows(&list)
+	return
+}

+ 5 - 3
models/db.go

@@ -38,8 +38,10 @@ func init() {
 	//注册对象
 	orm.RegisterModel(
 		new(data_manage.EdbInfo),
-		new(ShareChartRefreshLog),       //分享图表刷新日志表
-		new(ExcelInfo),                  //excel表格
-		new(data_manage.PredictEdbConf), //预测指标配置
+		new(ShareChartRefreshLog),                       //分享图表刷新日志表
+		new(ExcelInfo),                                  //excel表格
+		new(data_manage.PredictEdbConf),                 //预测指标配置
+		new(data_manage.PredictEdbRuleData),             //预测指标配置生成的数据
+		new(data_manage.PredictEdbConfCalculateMapping), //预测指标关系表
 	)
 }

+ 2 - 0
services/data/base_edb_lib.go

@@ -104,6 +104,8 @@ func RefreshEdbData(edbInfoId, source int, edbCode, startDate string) (resp *mod
 		urlStr = "mysteel_chemical/refresh"
 	case utils.DATA_SOURCE_EIA_STEO:
 		urlStr = "eia_steo/refresh"
+	case utils.DATA_SOURCE_PREDICT:
+		urlStr = "predict/refresh"
 	}
 	if urlStr == "" {
 		err = fmt.Errorf(fmt.Sprint("source:", source, ";未实现该指标的刷新接口,请联系管理员"))

+ 102 - 3
services/data/edb_info.go

@@ -10,7 +10,7 @@ import (
 	"time"
 )
 
-// EdbInfoRefreshAllFromBaseV3 全部刷新指标(切换到edb_lib服务)
+// EdbInfoRefreshAllFromBase 全部刷新指标(切换到edb_lib服务)
 // @author Roc
 // @datetime 2022-09-16 11:04:44
 // @description 将原有的单个指标刷新,调整为批量多个指标刷新
@@ -24,7 +24,7 @@ func EdbInfoRefreshAllFromBase(edbInfoIdList []int, refreshAll bool) (err error,
 	}()
 
 	// 获取关联的基础指标
-	newBaseEdbInfoArr, newCalculateMap, newPredictCalculateMap, calculateArr, predictCalculateArr, err, errmsg := getRefreshEdbInfoListByIds(edbInfoIdList)
+	newBaseEdbInfoArr, newBasePredictEdbInfoArr, newCalculateMap, newPredictCalculateMap, calculateArr, predictCalculateArr, err, errmsg := getRefreshEdbInfoListByIds(edbInfoIdList)
 	if err != nil {
 		return
 	}
@@ -217,11 +217,100 @@ func EdbInfoRefreshAllFromBase(edbInfoIdList []int, refreshAll bool) (err error,
 			return
 		}
 	}
+
+	// 4、更新动态环差值
+	{
+		predictEdbInfoIdList := make([]int, 0)
+		for _, v := range newBasePredictEdbInfoArr {
+			predictEdbInfoIdList = append(predictEdbInfoIdList, v.EdbInfoId)
+		}
+		fmt.Println("predictEdbConfCalculateMappingDetailList:", predictEdbInfoIdList)
+		predictEdbConfCalculateMappingDetailList, tmpErr := data_manage.GetPredictEdbConfCalculateMappingDetailListByEdbInfoId(predictEdbInfoIdList)
+		if tmpErr != nil {
+			err = tmpErr
+			errmsg = fmt.Sprint("更新动态环差值时,获取数据失败:" + err.Error())
+			return
+		}
+		for _, bv := range predictEdbConfCalculateMappingDetailList {
+			result, tmpErr := RefreshEdbData(bv.EdbInfoId, utils.DATA_SOURCE_PREDICT, bv.EdbCode, "")
+			if tmpErr != nil {
+				err = tmpErr
+				fmt.Println(bv.EdbInfoId, "RefreshBasePredictEdbData err", time.Now())
+				errmsg = "RefreshBasePredictEdbData Err:" + err.Error()
+				return
+			}
+			if result.Ret != 200 {
+				fmt.Println(bv.EdbInfoId, "RefreshBasePredictEdbData err;msg:", result.Msg, ";errMsg:", result.ErrMsg)
+				errmsg = fmt.Sprint(bv.EdbInfoId, "RefreshBasePredictEdbData err;msg:", result.Msg, ";errMsg:", result.ErrMsg)
+				err = errors.New("刷新失败:" + errmsg)
+				return
+			}
+			fmt.Println("end predictEdbConfCalculateMappingDetailList:", bv, time.Now())
+		}
+	}
+
+	//5、刷新相关预测计算指标
+	for _, v := range predictCalculateArr {
+		edbInfo := newPredictCalculateMap[v]
+		if edbInfo == nil {
+			return
+		}
+		startDate = edbInfo.StartDate
+		source := edbInfo.Source
+		if startDate == "" || startDate == "0000-00-00" { //如果没有开始日期,说明还没有计算出来数据,那么就往前面推40年吧(也意味着重新计算了)
+			startDate = time.Now().AddDate(-40, 0, 0).Format(utils.FormatDate)
+		} else {
+			if source == utils.DATA_SOURCE_PREDICT_CALCULATE {
+				startDate = ``
+				if refreshAll { //刷新所有数据,用开始时间作为起始日期去刷新
+					startDate = edbInfo.StartDate
+				} else {
+					sTime, tmpErr := time.Parse(utils.FormatDate, edbInfo.EndDate)
+					if tmpErr != nil {
+						err = tmpErr
+						errmsg = tmpErr.Error()
+						return
+					}
+					frequency := edbInfo.Frequency
+					var limitDay int
+					switch frequency {
+					case "日度":
+						limitDay = utils.DATA_REFRESH
+					case "周度":
+						limitDay = utils.DATA_REFRESH * 7
+					case "月度":
+						limitDay = utils.DATA_REFRESH * 30
+					case "季度":
+						limitDay = utils.DATA_REFRESH * 90
+					case "年度":
+						limitDay = utils.DATA_REFRESH * 365
+					default:
+						limitDay = utils.DATA_REFRESH
+					}
+					startDate = sTime.AddDate(0, 0, -limitDay).Format(utils.FormatDate)
+				}
+			}
+		}
+
+		result, tmpErr := RefreshPredictEdbCalculateData(edbInfo.EdbInfoId, edbInfo.EdbCode, startDate)
+		if tmpErr != nil {
+			err = tmpErr
+			fmt.Println(v, "RefreshPredictEdbCalculateData err", time.Now())
+			errmsg = "RefreshPredictEdbCalculateData Err:" + tmpErr.Error()
+			return
+		}
+		if result.Ret != 200 {
+			fmt.Println(v, "RefreshPredictEdbCalculateData err;msg:", result.Msg, ";errMsg:", result.ErrMsg)
+			errmsg = fmt.Sprint(v, "RefreshPredictEdbCalculateData err;msg:", result.Msg, ";errMsg:", result.ErrMsg)
+			err = fmt.Errorf("刷新失败")
+			return
+		}
+	}
 	return
 }
 
 // getRefreshEdbInfoList 获取待更新的指标(普通基础指标、普通运算指标,预测运算指标)
-func getRefreshEdbInfoListByIds(edbInfoIdList []int) (newBaseEdbInfoArr []*data_manage.EdbInfo, newCalculateMap, newPredictCalculateMap map[int]*data_manage.EdbInfo, calculateArr, predictCalculateArr []int, err error, errMsg string) {
+func getRefreshEdbInfoListByIds(edbInfoIdList []int) (newBaseEdbInfoArr, newBasePredictEdbInfoArr []*data_manage.EdbInfo, newCalculateMap, newPredictCalculateMap map[int]*data_manage.EdbInfo, calculateArr, predictCalculateArr []int, err error, errMsg string) {
 	calculateList, err := data_manage.GetEdbInfoAllCalculateByEdbInfoIdList(edbInfoIdList)
 	if err != nil && err.Error() != utils.ErrNoRow() {
 		err = errors.New("GetEdbInfoAllCalculate Err:" + err.Error())
@@ -449,6 +538,16 @@ func getRefreshEdbInfoListByIds(edbInfoIdList []int) (newBaseEdbInfoArr []*data_
 	// 普通计算指标的id
 	sort.Ints(calculateArr)
 
+	// 普通预测指标去重
+	newBasePredictEdbInfoArr = make([]*data_manage.EdbInfo, 0)
+	basePredictMap := make(map[int]int)
+	for _, v := range basePredictEdbInfoArr {
+		if _, ok := basePredictMap[v.EdbInfoId]; !ok {
+			newBasePredictEdbInfoArr = append(newBasePredictEdbInfoArr, v)
+		}
+		basePredictMap[v.EdbInfoId] = v.EdbInfoId
+	}
+
 	// 预测计算指标去重
 	newPredictCalculateMap = make(map[int]*data_manage.EdbInfo)
 	for _, v := range predictCalculateInfoArr {

+ 10 - 0
services/data/predict_edb_info.go

@@ -308,6 +308,16 @@ func GetChartPredictEdbInfoDataListByConfList(predictEdbConfList []*data_manage.
 				return
 			}
 			predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleNLinearRegression(predictEdbConf.PredictEdbInfoId, nValue, startDate, dataEndTime, frequency, realPredictEdbInfoData, predictEdbInfoData, existMap)
+		case 9: //9:动态环差”预测规则;
+			predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleTrendsHC(predictEdbConf.PredictEdbInfoId, predictEdbConf.ConfigId, startDate, dataEndTime, frequency, realPredictEdbInfoData, predictEdbInfoData, existMap)
+		case 10: //10:根据 给定终值后插值 规则获取预测数据
+			tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			finalValue, _ := tmpValDecimal.Float64()
+			predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleFinalValueHc(predictEdbConf.PredictEdbInfoId, finalValue, startDate, dataEndTime, frequency, realPredictEdbInfoData, predictEdbInfoData, existMap)
 		}
 		//startDate = dataEndTime.AddDate(0, 0, 1)
 		startDate = dataEndTime

+ 139 - 0
services/data/predict_edb_info_rule.go

@@ -3,6 +3,7 @@ package data
 import (
 	"github.com/shopspring/decimal"
 	"hongze/hongze_chart_lib/models"
+	"hongze/hongze_chart_lib/models/data_manage"
 	"hongze/hongze_chart_lib/utils"
 	"time"
 )
@@ -581,3 +582,141 @@ func getLinearResult(s []Coordinate) (gradient, intercept float64) {
 
 	return
 }
+
+//	GetChartPredictEdbInfoDataListByRuleTrendsHC 根据动态环比增加值的计算规则获取预测数据
+// 研究员有对预测指标进行动态环差计算的需求,即预测指标使用环差规则进行预测时,环比增加值不是固定值,而是由几个预测指标计算得出的动态变化的值;
+//需求说明:
+//1、增加“动态环差”预测规则;
+//2、环比增加值在弹窗设置;
+//3、动态环差预测举例:
+//指标A实际最新数据为2022-10-27(100);
+//预测指标B预测数据为2022-10-28(240)、2022-10-29(300);
+//预测指标C预测数据为2022-10-28(260)、2022-10-29(310);
+//计算公式为B-C;
+//则指标A至2022-10-29的预测值为2022-10-28(100+(240-260)=80)、2022-10-29(80+(300-310)=90);
+//注:动态环比增加值的计算遵从计算指标的计算规则,即用于计算的指标若有部分指标缺少部分日期数据,则这部分日期数据不做计算,为空;若动态环比增加值某一天为空,则往前追溯最近一期有值的环比增加值作为该天的数值参与计算;
+func GetChartPredictEdbInfoDataListByRuleTrendsHC(edbInfoId, configId int, startDate, endDate time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
+	allDataList := make([]*models.EdbDataList, 0)
+	allDataList = append(allDataList, realPredictEdbInfoData...)
+	allDataList = append(allDataList, predictEdbInfoData...)
+	newPredictEdbInfoData = predictEdbInfoData
+
+	lenAllData := len(allDataList)
+	if lenAllData <= 0 {
+		return
+	}
+
+	hcDataMap := make(map[string]float64) //规则计算的环差值map
+
+	//已经生成的动态数据
+	tmpPredictEdbRuleDataList, err := data_manage.GetPredictEdbRuleDataList(edbInfoId, configId, startDate.Format(utils.FormatDate), endDate.Format(utils.FormatDate))
+	if err != nil {
+		return
+	}
+	for _, v := range tmpPredictEdbRuleDataList {
+		hcDataMap[v.DataTime] = v.Value
+	}
+	dayList := getPredictEdbDayList(startDate, endDate, frequency)
+	for k, currentDate := range dayList {
+		// 最近一条数据
+		tmpLenAllDataList := len(allDataList)
+		lastValue := allDataList[tmpLenAllDataList-1].Value
+
+		// 动态环差值数据
+		currentDateStr := currentDate.Format(utils.FormatDate)
+		hcVal, ok := hcDataMap[currentDateStr]
+		if !ok {
+			continue
+		}
+		lastValueDecimal := decimal.NewFromFloat(lastValue)
+		hcValDecimal := decimal.NewFromFloat(hcVal)
+
+		val, _ := lastValueDecimal.Add(hcValDecimal).RoundCeil(4).Float64()
+
+		tmpData := &models.EdbDataList{
+			EdbDataId:     edbInfoId + 10000000000 + lenAllData + k,
+			EdbInfoId:     edbInfoId,
+			DataTime:      currentDateStr,
+			Value:         val,
+			DataTimestamp: (currentDate.UnixNano() / 1e6) + 1000, //前端需要让加1s,说是2022-09-01 00:00:00 这样的整点不合适
+		}
+		newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
+		allDataList = append(allDataList, tmpData)
+		existMap[currentDateStr] = val
+
+		// 最大最小值
+		if val < minValue {
+			minValue = val
+		}
+		if val > maxValue {
+			maxValue = val
+		}
+	}
+	return
+}
+
+//	GetChartPredictEdbInfoDataListByRuleFinalValueHc 根据 给定终值后插值 规则获取预测数据
+// 项目背景:
+//假设螺纹产量在2023年1月1号的预测值是255万吨,从当下到2023年1月1号,螺纹产量将会线性变化,那么每一期的螺纹产量是多少?
+//算法:从当下(2022/10/28)到2023/1/1号,一共65天,从当前值(305.02)到255,差值-50.02,
+//则每日环差为-50.02/65=-0.7695。因为数据点是周度频率,每周环差为,-0.3849*7=-5.3868。
+//从以上计算过程可看出,“给定终值后差值”的算法,是在“环差”算法的基础上,做的一个改动。即这个”环差值”=【(终值-最新值)/终值与最新值得日期差】*数据频率
+//需求说明:
+//1、增加一个预测规则,名为“给定终值后插值”,给定预测截止日期和预测终值,计算最新数据日期至预测截止日期的时间差T,计算最新数据和预测终值的数据差S,数据频率与指标频度有关,日度=1,周度=7,旬度=10,月度=30,季度=90,年度=365,环差值=S/T*频率,预测数值=前一天数值+环差值;
+//2、最新数据值和日期改动后,需重新计算环差值和预测数值;
+func GetChartPredictEdbInfoDataListByRuleFinalValueHc(edbInfoId int, finalValue float64, startDate, endDate time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
+	allDataList := make([]*models.EdbDataList, 0)
+	allDataList = append(allDataList, realPredictEdbInfoData...)
+	allDataList = append(allDataList, predictEdbInfoData...)
+	newPredictEdbInfoData = predictEdbInfoData
+
+	index := len(allDataList)
+	//获取后面的预测日期
+	dayList := getPredictEdbDayList(startDate, endDate, frequency)
+	lenDay := len(dayList)
+	if lenDay <= 0 {
+		return
+	}
+
+	var hcValue float64
+	lastValueDeciamal := decimal.NewFromFloat(allDataList[index-1].Value)            // 实际数据的最后一个值
+	finalValueDeciamal := decimal.NewFromFloat(finalValue)                           // 给定的终止数据
+	dayDecimal := decimal.NewFromInt(int64(lenDay))                                  // 需要作为分母的期数
+	hcValue, _ = finalValueDeciamal.Sub(lastValueDeciamal).Div(dayDecimal).Float64() // 计算出来的环差值
+
+	//获取后面的预测数据
+	predictEdbInfoData = make([]*models.EdbDataList, 0)
+	lastK := lenDay - 1 // 最后的日期
+	for k, currentDate := range dayList {
+		tmpK := index + k - 1 //上1期的值
+
+		var val float64
+		// 环差别值计算
+		if k == lastK { //如果是最后一天,那么就用最终值,否则就计算
+			val = finalValue
+		} else {
+			val = HczDiv(allDataList[tmpK].Value, hcValue)
+		}
+
+		currentDateStr := currentDate.Format(utils.FormatDate)
+		tmpData := &models.EdbDataList{
+			EdbDataId: edbInfoId + 10000000000 + index + k,
+			//EdbInfoId:     edbInfoId,
+			DataTime: currentDateStr,
+			Value:    val,
+			//DataTimestamp: (currentDate.UnixNano() / 1e6) + 1000, //前端需要让加1s,说是2022-09-01 00:00:00 这样的整点不合适
+		}
+		newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
+		allDataList = append(allDataList, tmpData)
+		existMap[currentDateStr] = val
+
+		// 最大最小值
+		if val < minValue {
+			minValue = val
+		}
+		if val > maxValue {
+			maxValue = val
+		}
+	}
+	return
+}