Przeglądaj źródła

Merge remote-tracking branch 'origin/chart/15.0' into debug

# Conflicts:
#	utils/constants.go
Roc 1 rok temu
rodzic
commit
d78ba4cb7d

+ 4 - 0
models/common.go

@@ -82,6 +82,10 @@ func GetBasePredictEdbInfoModel(source int) (baseEdbInfoModel BasePredictEdbInfo
 		baseEdbInfoModel = PredictLjz{}
 	case utils.DATA_SOURCE_PREDICT_CALCULATE_LJZNCZJ:
 		baseEdbInfoModel = PredictLjzNczj{}
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_STANDARD_DEVIATION:
+		baseEdbInfoModel = PredictStandardDeviation{}
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_PERCENTILE:
+		baseEdbInfoModel = PredictPercentile{}
 	default:
 
 	}

+ 11 - 0
models/edb_data_base.go

@@ -143,6 +143,17 @@ func GetAllEdbDataListByTo(to orm.TxOrmer, edbInfoId, source int) (existDataList
 	return
 }
 
+// GetFinalLastByTo 获取所有的指标数据列表
+func GetFinalLastByTo(to orm.TxOrmer, edbInfoId, source int, latestDate string) (finalLast EdbInfoSearchData, err error) {
+	dataTableName := GetEdbDataTableName(source)
+	sql := fmt.Sprintf(` SELECT data_time , value FROM %s WHERE edb_info_id=? and data_time<=? ORDER BY data_time DESC `, dataTableName)
+	err = to.Raw(sql, edbInfoId, latestDate).QueryRow(&finalLast)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return
+	}
+	return
+}
+
 // 新版本
 type EdbDataV1 struct {
 	EdbDataId     int `orm:"column(edb_data_id);pk"`

+ 0 - 1
models/edb_data_calculate_percentile.go

@@ -135,7 +135,6 @@ func (obj Percentile) Edit(params EditCalculateBatchParams) (err error, errMsg s
 		return
 	}
 	if count > 0 { // 指标未被替换,无需处理逻辑
-
 		// 如果相关配置更改了,那么重新计算
 		if oldEdbInfo.CalculateFormula != edbInfo.CalculateFormula {
 			err, errMsg = obj.refresh(to, edbInfo, fromEdbInfo, edbInfo.EdbCode)

+ 0 - 1
models/edb_data_calculate_standard_deviation.go

@@ -134,7 +134,6 @@ func (obj StandardDeviation) Edit(params EditCalculateBatchParams) (err error, e
 		return
 	}
 	if count > 0 { // 指标未被替换,无需处理逻辑
-
 		// 如果相关配置更改了,那么重新计算
 		if oldEdbInfo.CalculateFormula != edbInfo.CalculateFormula {
 			err = obj.refresh(to, edbInfo, fromEdbInfo, edbInfo.EdbCode)

+ 4 - 0
models/edb_data_table.go

@@ -139,6 +139,10 @@ func GetEdbDataTableName(source int) (tableName string) {
 		tableName = "edb_data_calculate_standard_deviation"
 	case utils.DATA_SOURCE_CALCULATE_PERCENTILE: //百分位->68
 		tableName = "edb_data_calculate_percentile"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_STANDARD_DEVIATION: //预测标准差->69
+		tableName = "edb_data_predict_ccalculate_standard_deviation"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_PERCENTILE: //预测百分位->70
+		tableName = "edb_data_predict_ccalculate_percentile"
 	default:
 		tableName = ""
 	}

+ 441 - 0
models/predict_edb_data_calculate_percentile.go

@@ -0,0 +1,441 @@
+package models
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/shopspring/decimal"
+	"hongze/hongze_edb_lib/utils"
+	"reflect"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// PredictPercentile 预测累计值年初至今
+type PredictPercentile struct {
+}
+
+// Add 添加
+func (obj PredictPercentile) Add(params BatchSaveCalculateBatchParams) (edbInfo *EdbInfo, latestDateStr string, latestValue float64, err error, errMsg string) {
+	req := params.Req
+	fromEdbInfo := params.FromEdbInfo
+	edbCode := params.EdbCode
+
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = to.Rollback()
+			fmt.Println(reflect.TypeOf(obj).Name(), ";Add,Err:"+err.Error())
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	edbInfo = &EdbInfo{
+		//EdbInfoId:        0,
+		SourceName:       obj.GetSourceName(),
+		Source:           obj.GetSource(),
+		EdbCode:          edbCode,
+		EdbName:          req.EdbName,
+		EdbNameSource:    req.EdbName,
+		Frequency:        req.Frequency,
+		Unit:             req.Unit,
+		StartDate:        "",
+		EndDate:          "",
+		ClassifyId:       req.ClassifyId,
+		SysUserId:        params.SysUserId,
+		SysUserRealName:  params.SysUserRealName,
+		UniqueCode:       params.UniqueCode,
+		CreateTime:       time.Now(),
+		ModifyTime:       time.Now(),
+		MinValue:         0,
+		MaxValue:         0,
+		CalculateFormula: req.Formula,
+		EdbType:          2,
+		Sort:             0,
+		MoveType:         0,
+		MoveFrequency:    "",
+		NoUpdate:         0,
+		ServerUrl:        "",
+		EdbInfoType:      1,
+		EdbNameEn:        "",
+		UnitEn:           "",
+		LatestDate:       "",
+		LatestValue:      0,
+		ChartImage:       "",
+		Calendar:         "",
+	}
+
+	newEdbInfoId, tmpErr := to.Insert(edbInfo)
+	if tmpErr != nil {
+		err = tmpErr
+		return
+	}
+	edbInfo.EdbInfoId = int(newEdbInfoId)
+
+	//关联关系
+	{
+		calculateMappingItem := new(EdbInfoCalculateMapping)
+		calculateMappingItem.CreateTime = time.Now()
+		calculateMappingItem.ModifyTime = time.Now()
+		calculateMappingItem.Sort = 1
+		calculateMappingItem.EdbCode = edbCode
+		calculateMappingItem.EdbInfoId = edbInfo.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
+		_, err = to.Insert(calculateMappingItem)
+		if err != nil {
+			return
+		}
+	}
+
+	//计算数据
+	latestDateStr, latestValue, err, errMsg = obj.refresh(to, edbInfo, fromEdbInfo, edbInfo.EdbCode, "")
+
+	return
+}
+
+// Edit 编辑
+func (obj PredictPercentile) Edit(params BatchSaveCalculateBatchParams) (latestDateStr string, latestValue float64, err error, errMsg string) {
+	req := params.Req
+	edbInfo := params.EdbInfo
+	fromEdbInfo := params.FromEdbInfo
+
+	latestDateStr = edbInfo.LatestDate
+	latestValue = edbInfo.LatestValue
+
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = to.Rollback()
+			fmt.Println(reflect.TypeOf(obj).Name(), ";Edit,Err:"+err.Error())
+		} else {
+			_ = to.Commit()
+		}
+	}()
+	tableName := GetEdbDataTableName(edbInfo.Source)
+
+	var isRecalculate bool
+	if edbInfo.CalculateFormula != req.Formula {
+		isRecalculate = true
+	}
+	//修改指标信息
+	edbInfo.EdbName = req.EdbName
+	edbInfo.EdbNameSource = req.EdbName
+	edbInfo.Frequency = req.Frequency
+	edbInfo.Unit = req.Unit
+	edbInfo.ClassifyId = req.ClassifyId
+	edbInfo.CalculateFormula = req.Formula
+	edbInfo.ModifyTime = time.Now()
+	_, err = to.Update(edbInfo, "EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId", "CalculateFormula", "ModifyTime")
+	if err != nil {
+		return
+	}
+
+	var existCondition string
+	var existPars []interface{}
+	existCondition += " AND edb_info_id=? AND from_edb_info_id=? "
+	existPars = append(existPars, edbInfo.EdbInfoId, req.FromEdbInfoId)
+
+	//判断计算指标是否被更换
+	count, err := GetEdbInfoCalculateCountByCondition(existCondition, existPars)
+	if err != nil {
+		err = errors.New("判断指标是否改变失败,Err:" + err.Error())
+		return
+	}
+	if count > 0 { // 指标未被替换,无需删除关联数据
+
+		// 频度被换了,需要重新计算
+		if isRecalculate {
+			latestDateStr, latestValue, err, errMsg = obj.refresh(to, edbInfo, fromEdbInfo, edbInfo.EdbCode, "")
+		}
+
+		return
+	}
+
+	//删除,计算指标关联的,基础指标的关联关系
+	sql := ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id = ? `
+	_, err = to.Raw(sql, edbInfo.EdbInfoId).Exec()
+	if err != nil {
+		return
+	}
+
+	//清空原有数据
+	sql = ` DELETE FROM ` + tableName + ` WHERE edb_info_id = ? `
+	_, err = to.Raw(sql, edbInfo.EdbInfoId).Exec()
+	if err != nil {
+		return
+	}
+
+	//关联关系
+	{
+		calculateMappingItem := &EdbInfoCalculateMapping{
+			EdbInfoCalculateMappingId: 0,
+			EdbInfoId:                 edbInfo.EdbInfoId,
+			Source:                    obj.GetSource(),
+			SourceName:                obj.GetSourceName(),
+			EdbCode:                   edbInfo.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
+		}
+	}
+
+	//计算数据
+	latestDateStr, latestValue, err, errMsg = obj.refresh(to, edbInfo, fromEdbInfo, edbInfo.EdbCode, "")
+
+	return
+}
+
+// Refresh 刷新
+func (obj PredictPercentile) Refresh(params RefreshParams) (latestDateStr string, latestValue float64, err error, errMsg string) {
+	calculateMapping, err := GetEdbInfoCalculateMappingDetail(params.EdbInfo.EdbInfoId)
+	if err != nil {
+		return
+	}
+	fromEdbInfo, err := GetEdbInfoById(calculateMapping.FromEdbInfoId)
+	if err != nil {
+		errMsg = "GetEdbInfoById Err:" + err.Error()
+		return
+	}
+
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = to.Rollback()
+			fmt.Println(reflect.TypeOf(obj).Name(), ";Refresh,Err:"+err.Error())
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	// 计算数据
+	latestDateStr, latestValue, err, errMsg = obj.refresh(to, params.EdbInfo, fromEdbInfo, params.EdbInfo.EdbCode, params.StartDate)
+
+	return
+}
+
+// GetSource 获取来源编码id
+func (obj PredictPercentile) GetSource() int {
+	return utils.DATA_SOURCE_PREDICT_CALCULATE_PERCENTILE
+}
+
+// GetSourceName 获取来源名称
+func (obj PredictPercentile) GetSourceName() string {
+	return utils.DATA_SOURCE_NAME_PREDICT_CALCULATE_PERCENTILE
+}
+
+func (obj PredictPercentile) refresh(to orm.TxOrmer, edbInfo, fromEdbInfo *EdbInfo, edbCode, startDate string) (latestDateStr string, latestValue float64, err error, errMsg string) {
+	edbInfoId := edbInfo.EdbInfoId
+	dataTableName := GetEdbDataTableName(edbInfo.Source)
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+
+	var percentileConfig PercentileConfig
+	err = json.Unmarshal([]byte(edbInfo.CalculateFormula), &percentileConfig)
+	if err != nil {
+		return
+	}
+
+	// 获取百分位的指标数据
+	fromDataList, err, errMsg := obj.getPercentileData(fromEdbInfo, percentileConfig.CalculateValue, percentileConfig.CalculateUnit)
+	if err != nil {
+		return
+	}
+
+	//获取指标所有数据
+	existDataList := make([]*EdbData, 0)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	_, err = to.Raw(sql, edbInfoId).QueryRows(&existDataList)
+	if err != nil {
+		return
+	}
+	existDataMap := make(map[string]string)
+	removeDataTimeMap := make(map[string]int) //需要移除的日期数据
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v.Value
+		removeDataTimeMap[v.DataTime] = 1
+	}
+	needAddDateMap := make(map[time.Time]int)
+
+	addSql := ` INSERT INTO ` + dataTableName + `(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	for _, tmpData := range fromDataList {
+		currDateStr := tmpData.DataTime
+		currTime, tmpErr := time.ParseInLocation(utils.FormatDate, currDateStr, time.Local)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		// 当前的实际值
+		saveValue := decimal.NewFromFloat(tmpData.Value).Round(4).String()
+
+		existVal, ok := existDataMap[currDateStr]
+		// 如果库中已经存在该数据的话,那么就进行值的变更操作
+		if ok {
+			//校验待删除日期数据里面是否存在该元素,如果存在的话,那么移除该日期
+			delete(removeDataTimeMap, currDateStr)
+
+			if existVal != saveValue {
+				sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				sql = fmt.Sprintf(sql, dataTableName)
+				_, err = to.Raw(sql, saveValue, edbInfoId, currDateStr).Exec()
+				if err != nil {
+					return
+				}
+			}
+
+			continue
+		}
+
+		// 库中不存在该日期的数据
+		timestamp := currTime.UnixNano() / 1e6
+		timeStr := fmt.Sprintf("%d", timestamp)
+		if _, existOk := needAddDateMap[currTime]; !existOk {
+			addSql += GetAddSql(edbInfoIdStr, edbCode, currDateStr, timeStr, saveValue)
+			isAdd = true
+		}
+		needAddDateMap[currTime] = 1
+	}
+
+	//删除已经不存在的指标数据(由于该指标当日的数据删除了)
+	{
+		removeDateList := make([]string, 0)
+		for dateTime := range removeDataTimeMap {
+			removeDateList = append(removeDateList, dateTime)
+		}
+		removeNum := len(removeDateList)
+		if removeNum > 0 {
+			sql := fmt.Sprintf(` DELETE FROM %s WHERE edb_info_id = ? and data_time in (`+utils.GetOrmInReplace(removeNum)+`) `, dataTableName)
+			_, err = to.Raw(sql, edbInfo.EdbInfoId, removeDateList).Exec()
+			if err != nil {
+				fmt.Println(reflect.TypeOf(obj).Name(), " add data ;delete Err", err.Error())
+				err = fmt.Errorf("删除不存在的指标数据失败,Err:" + err.Error())
+				return
+			}
+		}
+	}
+
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		_, err = to.Raw(addSql).Exec()
+		if err != nil {
+			fmt.Println(reflect.TypeOf(obj).Name(), " add data Err", err.Error())
+			return
+		}
+	}
+
+	//确定实际数据的最终值
+	{
+		finalLast, tmpErr := GetFinalLastByTo(to, edbInfoId, edbInfo.Source, fromEdbInfo.LatestDate)
+		if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
+			return
+		}
+		if tmpErr == nil {
+			latestDateStr = finalLast.DataTime
+			latestValue = finalLast.Value
+		}
+	}
+
+	return
+}
+
+// GetPercentileData 获取百分位的指标数据
+func (obj PredictPercentile) getPercentileData(fromEdbInfo *EdbInfo, calculateValue int, calculateUnit string) (newDataList []EdbInfoSearchData, err error, errMsg string) {
+	// 获取时间基准指标在时间区间内的值
+	dataList := make([]*EdbInfoSearchData, 0)
+	switch fromEdbInfo.EdbInfoType {
+	case 0:
+		var condition string
+		var pars []interface{}
+		condition += " AND edb_info_id=? "
+		pars = append(pars, fromEdbInfo.EdbInfoId)
+
+		//获取来源指标的数据
+		dataList, err = GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 1)
+	case 1:
+		dataList, err = GetPredictEdbDataListAllByStartDate(fromEdbInfo, 1, "")
+	default:
+		err = errors.New(fmt.Sprint("获取失败,指标base类型异常", fromEdbInfo.EdbInfoType))
+		return
+	}
+
+	moveUnitDays, ok := utils.FrequencyDaysMap[calculateUnit]
+	if !ok {
+		errMsg = `错误的周期`
+		err = errors.New(errMsg)
+		return
+	}
+	calculateDay := calculateValue * moveUnitDays
+	// 指标对应的所有数据
+
+	newDataList = make([]EdbInfoSearchData, 0)
+
+	dataMap := make(map[time.Time]float64, 0)
+	for _, tmpData := range dataList {
+		currDateTime, _ := time.ParseInLocation(utils.FormatDate, tmpData.DataTime, time.Local)
+		dataMap[currDateTime] = tmpData.Value
+	}
+
+	//百分位:对所选指标滚动地取对应时间长度的数据值,取最大值Max,最小值Min,计算Max-Min,百分位=(现值-Min)/(Max-Min),Max=Min时不予计算。
+	for i, tmpData := range dataList {
+		currDateTime, _ := time.ParseInLocation(utils.FormatDate, tmpData.DataTime, time.Local)
+		maxVal := tmpData.Value
+		minVal := tmpData.Value
+		for i := 0; i < calculateDay; i++ {
+			preVal, ok := dataMap[currDateTime.AddDate(0, 0, -i)]
+			if ok {
+				if preVal > maxVal {
+					maxVal = preVal
+				}
+				if preVal < minVal {
+					minVal = preVal
+				}
+			}
+		}
+
+		if maxVal == minVal {
+			continue
+		}
+		tmpV := (tmpData.Value) / (maxVal - minVal) * 100
+		tmpV, _ = decimal.NewFromFloat(tmpV).Round(4).Float64()
+		//百分位=(现值-Min)/(Max-Min)
+		newDataList = append(newDataList, EdbInfoSearchData{
+			EdbDataId: i,
+			DataTime:  dataList[i-1].DataTime,
+			Value:     tmpV,
+		})
+	}
+
+	return
+}

+ 423 - 0
models/predict_edb_data_calculate_standard_deviation.go

@@ -0,0 +1,423 @@
+package models
+
+import (
+	"errors"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/shopspring/decimal"
+	"hongze/hongze_edb_lib/utils"
+	"reflect"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// PredictStandardDeviation 预测累计值年初至今
+type PredictStandardDeviation struct {
+}
+
+// Add 添加
+func (obj PredictStandardDeviation) Add(params BatchSaveCalculateBatchParams) (edbInfo *EdbInfo, latestDateStr string, latestValue float64, err error, errMsg string) {
+	req := params.Req
+	fromEdbInfo := params.FromEdbInfo
+	edbCode := params.EdbCode
+
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = to.Rollback()
+			fmt.Println(reflect.TypeOf(obj).Name(), ";Add,Err:"+err.Error())
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	edbInfo = &EdbInfo{
+		//EdbInfoId:        0,
+		SourceName:       obj.GetSourceName(),
+		Source:           obj.GetSource(),
+		EdbCode:          edbCode,
+		EdbName:          req.EdbName,
+		EdbNameSource:    req.EdbName,
+		Frequency:        req.Frequency,
+		Unit:             req.Unit,
+		StartDate:        "",
+		EndDate:          "",
+		ClassifyId:       req.ClassifyId,
+		SysUserId:        params.SysUserId,
+		SysUserRealName:  params.SysUserRealName,
+		UniqueCode:       params.UniqueCode,
+		CreateTime:       time.Now(),
+		ModifyTime:       time.Now(),
+		MinValue:         0,
+		MaxValue:         0,
+		CalculateFormula: req.Formula,
+		EdbType:          2,
+		Sort:             0,
+		MoveType:         0,
+		MoveFrequency:    "",
+		NoUpdate:         0,
+		ServerUrl:        "",
+		EdbInfoType:      1,
+		EdbNameEn:        "",
+		UnitEn:           "",
+		LatestDate:       "",
+		LatestValue:      0,
+		ChartImage:       "",
+		Calendar:         "",
+	}
+
+	newEdbInfoId, tmpErr := to.Insert(edbInfo)
+	if tmpErr != nil {
+		err = tmpErr
+		return
+	}
+	edbInfo.EdbInfoId = int(newEdbInfoId)
+
+	//关联关系
+	{
+		calculateMappingItem := new(EdbInfoCalculateMapping)
+		calculateMappingItem.CreateTime = time.Now()
+		calculateMappingItem.ModifyTime = time.Now()
+		calculateMappingItem.Sort = 1
+		calculateMappingItem.EdbCode = edbCode
+		calculateMappingItem.EdbInfoId = edbInfo.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
+		_, err = to.Insert(calculateMappingItem)
+		if err != nil {
+			return
+		}
+	}
+
+	//计算数据
+	latestDateStr, latestValue, err = obj.refresh(to, edbInfo, fromEdbInfo, edbInfo.EdbCode, "")
+
+	return
+}
+
+// Edit 编辑
+func (obj PredictStandardDeviation) Edit(params BatchSaveCalculateBatchParams) (latestDateStr string, latestValue float64, err error, errMsg string) {
+	req := params.Req
+	edbInfo := params.EdbInfo
+	fromEdbInfo := params.FromEdbInfo
+
+	if fromEdbInfo.Frequency == `年度` {
+		errMsg = "年初至今累计值计算中,可选指标范围为非年度指标"
+		err = errors.New(errMsg)
+		return
+	}
+
+	if fromEdbInfo.Frequency != req.Frequency {
+		errMsg = "生成指标频度与原指标频度不同"
+		err = errors.New(errMsg)
+		return
+	}
+
+	latestDateStr = edbInfo.LatestDate
+	latestValue = edbInfo.LatestValue
+
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = to.Rollback()
+			fmt.Println(reflect.TypeOf(obj).Name(), ";Edit,Err:"+err.Error())
+		} else {
+			_ = to.Commit()
+		}
+	}()
+	tableName := GetEdbDataTableName(edbInfo.Source)
+
+	var isRecalculate bool
+	if edbInfo.CalculateFormula != req.Formula {
+		isRecalculate = true
+	}
+	//修改指标信息
+	edbInfo.EdbName = req.EdbName
+	edbInfo.EdbNameSource = req.EdbName
+	edbInfo.Frequency = req.Frequency
+	edbInfo.Unit = req.Unit
+	edbInfo.ClassifyId = req.ClassifyId
+	edbInfo.CalculateFormula = req.Formula
+	edbInfo.ModifyTime = time.Now()
+	_, err = to.Update(edbInfo, "EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId", "CalculateFormula", "ModifyTime")
+	if err != nil {
+		return
+	}
+
+	var existCondition string
+	var existPars []interface{}
+	existCondition += " AND edb_info_id=? AND from_edb_info_id=? "
+	existPars = append(existPars, edbInfo.EdbInfoId, req.FromEdbInfoId)
+
+	//判断计算指标是否被更换
+	count, err := GetEdbInfoCalculateCountByCondition(existCondition, existPars)
+	if err != nil {
+		err = errors.New("判断指标是否改变失败,Err:" + err.Error())
+		return
+	}
+	if count > 0 { // 指标未被替换,无需删除关联数据
+
+		// 频度被换了,需要重新计算
+		if isRecalculate {
+			latestDateStr, latestValue, err = obj.refresh(to, edbInfo, fromEdbInfo, edbInfo.EdbCode, "")
+		}
+
+		return
+	}
+
+	//删除,计算指标关联的,基础指标的关联关系
+	sql := ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id = ? `
+	_, err = to.Raw(sql, edbInfo.EdbInfoId).Exec()
+	if err != nil {
+		return
+	}
+
+	//清空原有数据
+	sql = ` DELETE FROM ` + tableName + ` WHERE edb_info_id = ? `
+	_, err = to.Raw(sql, edbInfo.EdbInfoId).Exec()
+	if err != nil {
+		return
+	}
+
+	//关联关系
+	{
+		calculateMappingItem := &EdbInfoCalculateMapping{
+			EdbInfoCalculateMappingId: 0,
+			EdbInfoId:                 edbInfo.EdbInfoId,
+			Source:                    obj.GetSource(),
+			SourceName:                obj.GetSourceName(),
+			EdbCode:                   edbInfo.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
+		}
+	}
+
+	//计算数据
+	latestDateStr, latestValue, err = obj.refresh(to, edbInfo, fromEdbInfo, edbInfo.EdbCode, "")
+
+	return
+}
+
+// Refresh 刷新
+func (obj PredictStandardDeviation) Refresh(params RefreshParams) (latestDateStr string, latestValue float64, err error, errMsg string) {
+	calculateMapping, err := GetEdbInfoCalculateMappingDetail(params.EdbInfo.EdbInfoId)
+	if err != nil {
+		return
+	}
+	fromEdbInfo, err := GetEdbInfoById(calculateMapping.FromEdbInfoId)
+	if err != nil {
+		errMsg = "GetEdbInfoById Err:" + err.Error()
+		return
+	}
+
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = to.Rollback()
+			fmt.Println(reflect.TypeOf(obj).Name(), ";Refresh,Err:"+err.Error())
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	// 计算数据
+	latestDateStr, latestValue, err = obj.refresh(to, params.EdbInfo, fromEdbInfo, params.EdbInfo.EdbCode, params.StartDate)
+
+	return
+}
+
+// GetSource 获取来源编码id
+func (obj PredictStandardDeviation) GetSource() int {
+	return utils.DATA_SOURCE_PREDICT_CALCULATE_STANDARD_DEVIATION
+}
+
+// GetSourceName 获取来源名称
+func (obj PredictStandardDeviation) GetSourceName() string {
+	return utils.DATA_SOURCE_NAME_PREDICT_CALCULATE_STANDARD_DEVIATION
+}
+
+func (obj PredictStandardDeviation) refresh(to orm.TxOrmer, edbInfo, fromEdbInfo *EdbInfo, edbCode, startDate string) (latestDateStr string, latestValue float64, err error) {
+	edbInfoId := edbInfo.EdbInfoId
+	dataTableName := GetEdbDataTableName(edbInfo.Source)
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	latestDateStr = fromEdbInfo.LatestDate
+
+	calculateValue, err := strconv.Atoi(edbInfo.CalculateFormula)
+	if err != nil {
+		return
+	}
+
+	// 获取标准差图表的指标数据
+	fromDataList, err := obj.getStandardDeviationData(fromEdbInfo, calculateValue)
+	if err != nil {
+		return
+	}
+
+	//获取指标所有数据
+	existDataList := make([]*EdbData, 0)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	_, err = to.Raw(sql, edbInfoId).QueryRows(&existDataList)
+	if err != nil {
+		return
+	}
+	existDataMap := make(map[string]string)
+	removeDataTimeMap := make(map[string]int) //需要移除的日期数据
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v.Value
+		removeDataTimeMap[v.DataTime] = 1
+	}
+	needAddDateMap := make(map[time.Time]int)
+
+	addSql := ` INSERT INTO ` + dataTableName + `(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	for _, tmpData := range fromDataList {
+		currDateStr := tmpData.DataTime
+		currTime, tmpErr := time.ParseInLocation(utils.FormatDate, currDateStr, time.Local)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		// 当前的实际值
+		saveValue := decimal.NewFromFloat(tmpData.Value).Round(4).String()
+
+		existVal, ok := existDataMap[currDateStr]
+		// 如果库中已经存在该数据的话,那么就进行值的变更操作
+		if ok {
+			//校验待删除日期数据里面是否存在该元素,如果存在的话,那么移除该日期
+			delete(removeDataTimeMap, currDateStr)
+
+			if existVal != saveValue {
+				sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				sql = fmt.Sprintf(sql, dataTableName)
+				_, err = to.Raw(sql, saveValue, edbInfoId, currDateStr).Exec()
+				if err != nil {
+					return
+				}
+			}
+
+			continue
+		}
+
+		// 库中不存在该日期的数据
+		timestamp := currTime.UnixNano() / 1e6
+		timeStr := fmt.Sprintf("%d", timestamp)
+		if _, existOk := needAddDateMap[currTime]; !existOk {
+			addSql += GetAddSql(edbInfoIdStr, edbCode, currDateStr, timeStr, saveValue)
+			isAdd = true
+		}
+		needAddDateMap[currTime] = 1
+	}
+
+	//删除已经不存在的指标数据(由于该指标当日的数据删除了)
+	{
+		removeDateList := make([]string, 0)
+		for dateTime := range removeDataTimeMap {
+			removeDateList = append(removeDateList, dateTime)
+		}
+		removeNum := len(removeDateList)
+		if removeNum > 0 {
+			sql := fmt.Sprintf(` DELETE FROM %s WHERE edb_info_id = ? and data_time in (`+utils.GetOrmInReplace(removeNum)+`) `, dataTableName)
+			_, err = to.Raw(sql, edbInfo.EdbInfoId, removeDateList).Exec()
+			if err != nil {
+				fmt.Println(reflect.TypeOf(obj).Name(), " add data ;delete Err", err.Error())
+				err = fmt.Errorf("删除不存在的指标数据失败,Err:" + err.Error())
+				return
+			}
+		}
+	}
+
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		_, err = to.Raw(addSql).Exec()
+		if err != nil {
+			fmt.Println(reflect.TypeOf(obj).Name(), " add data Err", err.Error())
+			return
+		}
+	}
+
+	//确定实际数据的最终值
+	{
+		finalLast, tmpErr := GetFinalLastByTo(to, edbInfoId, edbInfo.Source, fromEdbInfo.LatestDate)
+		if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
+			return
+		}
+		if tmpErr == nil {
+			latestDateStr = finalLast.DataTime
+			latestValue = finalLast.Value
+		}
+	}
+
+	return
+}
+
+// GetStandardDeviationData 获取标准差图表的指标数据
+func (obj PredictStandardDeviation) getStandardDeviationData(fromEdbInfo *EdbInfo, calculateValue int) (newDataList []EdbInfoSearchData, err error) {
+	// 获取时间基准指标在时间区间内的值
+	dataList := make([]*EdbInfoSearchData, 0)
+	switch fromEdbInfo.EdbInfoType {
+	case 0:
+		var condition string
+		var pars []interface{}
+		condition += " AND edb_info_id=? "
+		pars = append(pars, fromEdbInfo.EdbInfoId)
+
+		//获取来源指标的数据
+		dataList, err = GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 1)
+	case 1:
+		dataList, err = GetPredictEdbDataListAllByStartDate(fromEdbInfo, 1, "")
+	default:
+		err = errors.New(fmt.Sprint("获取失败,指标base类型异常", fromEdbInfo.EdbInfoType))
+		return
+	}
+
+	// 指标对应的所有数据
+	newDataList = make([]EdbInfoSearchData, 0)
+	lenData := len(dataList)
+	if lenData >= calculateValue {
+		tmpDataList := make([]float64, 0)
+		for _, tmpData := range dataList {
+			tmpDataList = append(tmpDataList, tmpData.Value)
+		}
+		for i := lenData; i >= calculateValue; i-- {
+			tmpV := utils.CalculateStandardDeviation(tmpDataList[i-calculateValue : i])
+			newDataList = append(newDataList, EdbInfoSearchData{
+				EdbDataId: i,
+				DataTime:  dataList[i-1].DataTime,
+				Value:     tmpV,
+			})
+		}
+	}
+
+	return
+}

+ 72 - 68
utils/constants.go

@@ -99,78 +99,82 @@ const (
 	DATA_SOURCE_PREDICT_CALCULATE_LJZNCZJ               //预测指标 - 累计值(年初至今) -> 66
 	DATA_SOURCE_CALCULATE_STANDARD_DEVIATION            //标准差->67
 	DATA_SOURCE_CALCULATE_PERCENTILE                    //百分位->68
+	DATA_SOURCE_PREDICT_CALCULATE_STANDARD_DEVIATION            //预测标准差->69
+	DATA_SOURCE_PREDICT_CALCULATE_PERCENTILE                    //预测百分位->70
 )
 
 // 指标来源的中文展示
 const (
-	DATA_SOURCE_NAME_THS                          = `同花顺`               //同花顺
-	DATA_SOURCE_NAME_WIND                         = `wind`              //wind
-	DATA_SOURCE_NAME_PB                           = `彭博`                //彭博
-	DATA_SOURCE_NAME_CALCULATE                    = `指标运算`              //指标运算
-	DATA_SOURCE_NAME_CALCULATE_LJZZY              = `累计值转月值`            //累计值转月
-	DATA_SOURCE_NAME_CALCULATE_TBZ                = `同比值`               //同比值
-	DATA_SOURCE_NAME_CALCULATE_TCZ                = `同差值`               //同差值
-	DATA_SOURCE_NAME_CALCULATE_NSZYDPJJS          = `N数值移动平均计算`         //N数值移动平均计算
-	DATA_SOURCE_NAME_MANUAL                       = `手工数据`              //手工指标
-	DATA_SOURCE_NAME_LZ                           = `隆众`                //隆众
-	DATA_SOURCE_NAME_YS                           = `SMM`               //有色
-	DATA_SOURCE_NAME_CALCULATE_HBZ                = `环比值`               //环比值->12
-	DATA_SOURCE_NAME_CALCULATE_HCZ                = `环差值`               //环差值->13
-	DATA_SOURCE_NAME_CALCULATE_BP                 = `升频`                //变频,2023-2-10 13:56:01调整为"升频"->14
-	DATA_SOURCE_NAME_GL                           = `钢联`                //钢联->15
-	DATA_SOURCE_NAME_ZZ                           = `郑商所`               //郑商所->16
-	DATA_SOURCE_NAME_DL                           = `大商所`               //大商所->17
-	DATA_SOURCE_NAME_SH                           = `上期所`               //上期所->18
-	DATA_SOURCE_NAME_CFFEX                        = `中金所`               //中金所->19
-	DATA_SOURCE_NAME_SHFE                         = `上期能源`              //上期能源->20
-	DATA_SOURCE_NAME_GIE                          = `欧洲天然气`             //欧洲天然气->21
-	DATA_SOURCE_NAME_CALCULATE_TIME_SHIFT         = `时间移位`              //时间移位->22
-	DATA_SOURCE_NAME_CALCULATE_ZJPJ               = `直接拼接`              //直接拼接->23
-	DATA_SOURCE_NAME_CALCULATE_LJZTBPJ            = `累计值同比拼接`           //累计值同比拼接->24
-	DATA_SOURCE_NAME_LT                           = `路透`                //路透->25
-	DATA_SOURCE_NAME_COAL                         = `中国煤炭网`             //煤炭网->26
-	DATA_SOURCE_NAME_PYTHON                       = `代码运算`              //python代码->27
-	DATA_SOURCE_NAME_PB_FINANCE                   = `彭博财务`              //彭博财务数据->28
-	DATA_SOURCE_NAME_GOOGLE_TRAVEL                = `our world in data` //谷歌出行数据->29
-	DATA_SOURCE_NAME_PREDICT                      = `预测指标`              //普通预测指标->30
-	DATA_SOURCE_NAME_PREDICT_CALCULATE            = `预测指标运算`            //预测指标运算->31
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_TBZ        = `预测同比`              //预测指标 - 同比值->32
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_TCZ        = `预测同差`              //预测指标 - 同差值->33
-	DATA_SOURCE_NAME_MYSTEEL_CHEMICAL             = `钢联化工`              //钢联化工->34
-	DATA_SOURCE_NAME_CALCULATE_CJJX               = `超季节性`              //超季节性->35
-	DATA_SOURCE_NAME_EIA_STEO                     = `EIA STERO报告`       //eia stero报告->36
-	DATA_SOURCE_NAME_CALCULATE_NHCC               = `拟合残差`              //计算指标(拟合残差)->37
-	DATA_SOURCE_NAME_COM_TRADE                    = `UN`                //联合国商品贸易数据->38
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_NSZYDPJJS  = `预测N数值移动平均计算`       //预测指标 - N数值移动平均计算 -> 39
-	DATA_SOURCE_NAME_CALCULATE_ADJUST             = `数据调整`              //数据调整->40
-	DATA_SOURCE_NAME_SCI                          = `SCI`               //卓创数据(红桃三)->41
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_LJZZY      = `预测累计值转月值`          //预测指标 - 累计值转月->42
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_HBZ        = `预测环比值`             //预测指标 - 环比值->43
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_HCZ        = `预测环差值`             //预测指标 - 环差值->44
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_BP         = `预测升频`              //预测指标 - 升频->45
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_TIME_SHIFT = `预测时间移位`            //预测指标 - 时间移位->46
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_ZJPJ       = `预测直接拼接`            //预测指标 - 直接拼接->47
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_LJZTBPJ    = `预测累计值同比拼接`         //预测指标 - 累计值同比拼接->48
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_CJJX       = `预测超季节性`            //预测指标 - 超季节性->49
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_NHCC       = `预测拟合残差`            //预测指标 - 计算指标(拟合残差)->50
-	DATA_SOURCE_NAME_CALCULATE_JP                 = `降频`                //降频->51
-	DATA_SOURCE_NAME_CALCULATE_NH                 = `年化`                //年化->52
-	DATA_SOURCE_NAME_CALCULATE_KSZS               = `扩散指数`              //扩散指数->53
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_JP         = `预测降频`              //预测指标 - 计算指标(降频)->54
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_NH         = `预测年化`              //预测指标 - 计算指标(年化)->55
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_KSZS       = `预测扩散指数`            //预测指标 - 计算指标(扩散指数)->56
-	DATA_SOURCE_NAME_BAIINFO                      = `百川盈孚`              //百川盈孚 ->57
-	DATA_SOURCE_NAME_STOCK_PLANT                  = `存量装置`              //存量装置 ->58
-	DATA_SOURCE_NAME_CALCULATE_CORRELATION        = `相关性计算`             //相关性计算->59
-	DATA_SOURCE_NAME_NATIONAL_STATISTICS          = `国家统计局`             //国家统计局->60
-	DATA_SOURCE_NAME_CALCULATE_LJZZJ              = `累计值转季值`            //累计值转季 -> 61
-	DATA_SOURCE_NAME_CALCULATE_LJZ                = `累计值`               //累计值 -> 62
-	DATA_SOURCE_NAME_CALCULATE_LJZNCZJ            = `年初至今累计值`           //累计值(年初至今) -> 63
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_LJZZJ      = `预测累计值转季值`          //预测指标 - 累计值转季->64
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_LJZ        = `预测累计值`             //预测指标 - 累计值 -> 65
-	DATA_SOURCE_NAME_PREDICT_CALCULATE_LJZNCZJ    = `预测年初至今累计值`         //预测指标 - 累计值(年初至今) -> 66
-	DATA_SOURCE_NAME_CALCULATE_STANDARD_DEVIATION = `标准差`               //标准差->67
-	DATA_SOURCE_NAME_CALCULATE_PERCENTILE         = `百分位`               //百分位->68
+	DATA_SOURCE_NAME_THS                                  = `同花顺`               //同花顺
+	DATA_SOURCE_NAME_WIND                                 = `wind`              //wind
+	DATA_SOURCE_NAME_PB                                   = `彭博`                //彭博
+	DATA_SOURCE_NAME_CALCULATE                            = `指标运算`              //指标运算
+	DATA_SOURCE_NAME_CALCULATE_LJZZY                      = `累计值转月值`            //累计值转月
+	DATA_SOURCE_NAME_CALCULATE_TBZ                        = `同比值`               //同比值
+	DATA_SOURCE_NAME_CALCULATE_TCZ                        = `同差值`               //同差值
+	DATA_SOURCE_NAME_CALCULATE_NSZYDPJJS                  = `N数值移动平均计算`         //N数值移动平均计算
+	DATA_SOURCE_NAME_MANUAL                               = `手工数据`              //手工指标
+	DATA_SOURCE_NAME_LZ                                   = `隆众`                //隆众
+	DATA_SOURCE_NAME_YS                                   = `SMM`               //有色
+	DATA_SOURCE_NAME_CALCULATE_HBZ                        = `环比值`               //环比值->12
+	DATA_SOURCE_NAME_CALCULATE_HCZ                        = `环差值`               //环差值->13
+	DATA_SOURCE_NAME_CALCULATE_BP                         = `升频`                //变频,2023-2-10 13:56:01调整为"升频"->14
+	DATA_SOURCE_NAME_GL                                   = `钢联`                //钢联->15
+	DATA_SOURCE_NAME_ZZ                                   = `郑商所`               //郑商所->16
+	DATA_SOURCE_NAME_DL                                   = `大商所`               //大商所->17
+	DATA_SOURCE_NAME_SH                                   = `上期所`               //上期所->18
+	DATA_SOURCE_NAME_CFFEX                                = `中金所`               //中金所->19
+	DATA_SOURCE_NAME_SHFE                                 = `上期能源`              //上期能源->20
+	DATA_SOURCE_NAME_GIE                                  = `欧洲天然气`             //欧洲天然气->21
+	DATA_SOURCE_NAME_CALCULATE_TIME_SHIFT                 = `时间移位`              //时间移位->22
+	DATA_SOURCE_NAME_CALCULATE_ZJPJ                       = `直接拼接`              //直接拼接->23
+	DATA_SOURCE_NAME_CALCULATE_LJZTBPJ                    = `累计值同比拼接`           //累计值同比拼接->24
+	DATA_SOURCE_NAME_LT                                   = `路透`                //路透->25
+	DATA_SOURCE_NAME_COAL                                 = `中国煤炭网`             //煤炭网->26
+	DATA_SOURCE_NAME_PYTHON                               = `代码运算`              //python代码->27
+	DATA_SOURCE_NAME_PB_FINANCE                           = `彭博财务`              //彭博财务数据->28
+	DATA_SOURCE_NAME_GOOGLE_TRAVEL                        = `our world in data` //谷歌出行数据->29
+	DATA_SOURCE_NAME_PREDICT                              = `预测指标`              //普通预测指标->30
+	DATA_SOURCE_NAME_PREDICT_CALCULATE                    = `预测指标运算`            //预测指标运算->31
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_TBZ                = `预测同比`              //预测指标 - 同比值->32
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_TCZ                = `预测同差`              //预测指标 - 同差值->33
+	DATA_SOURCE_NAME_MYSTEEL_CHEMICAL                     = `钢联化工`              //钢联化工->34
+	DATA_SOURCE_NAME_CALCULATE_CJJX                       = `超季节性`              //超季节性->35
+	DATA_SOURCE_NAME_EIA_STEO                             = `EIA STERO报告`       //eia stero报告->36
+	DATA_SOURCE_NAME_CALCULATE_NHCC                       = `拟合残差`              //计算指标(拟合残差)->37
+	DATA_SOURCE_NAME_COM_TRADE                            = `UN`                //联合国商品贸易数据->38
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_NSZYDPJJS          = `预测N数值移动平均计算`       //预测指标 - N数值移动平均计算 -> 39
+	DATA_SOURCE_NAME_CALCULATE_ADJUST                     = `数据调整`              //数据调整->40
+	DATA_SOURCE_NAME_SCI                                  = `SCI`               //卓创数据(红桃三)->41
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_LJZZY              = `预测累计值转月值`          //预测指标 - 累计值转月->42
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_HBZ                = `预测环比值`             //预测指标 - 环比值->43
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_HCZ                = `预测环差值`             //预测指标 - 环差值->44
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_BP                 = `预测升频`              //预测指标 - 升频->45
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_TIME_SHIFT         = `预测时间移位`            //预测指标 - 时间移位->46
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_ZJPJ               = `预测直接拼接`            //预测指标 - 直接拼接->47
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_LJZTBPJ            = `预测累计值同比拼接`         //预测指标 - 累计值同比拼接->48
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_CJJX               = `预测超季节性`            //预测指标 - 超季节性->49
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_NHCC               = `预测拟合残差`            //预测指标 - 计算指标(拟合残差)->50
+	DATA_SOURCE_NAME_CALCULATE_JP                         = `降频`                //降频->51
+	DATA_SOURCE_NAME_CALCULATE_NH                         = `年化`                //年化->52
+	DATA_SOURCE_NAME_CALCULATE_KSZS                       = `扩散指数`              //扩散指数->53
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_JP                 = `预测降频`              //预测指标 - 计算指标(降频)->54
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_NH                 = `预测年化`              //预测指标 - 计算指标(年化)->55
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_KSZS               = `预测扩散指数`            //预测指标 - 计算指标(扩散指数)->56
+	DATA_SOURCE_NAME_BAIINFO                              = `百川盈孚`              //百川盈孚 ->57
+	DATA_SOURCE_NAME_STOCK_PLANT                          = `存量装置`              //存量装置 ->58
+	DATA_SOURCE_NAME_CALCULATE_CORRELATION                = `相关性计算`             //相关性计算->59
+	DATA_SOURCE_NAME_NATIONAL_STATISTICS                  = `国家统计局`             //国家统计局->60
+	DATA_SOURCE_NAME_CALCULATE_LJZZJ                      = `累计值转季值`            //累计值转季 -> 61
+	DATA_SOURCE_NAME_CALCULATE_LJZ                        = `累计值`               //累计值 -> 62
+	DATA_SOURCE_NAME_CALCULATE_LJZNCZJ                    = `年初至今累计值`           //累计值(年初至今) -> 63
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_LJZZJ              = `预测累计值转季值`          //预测指标 - 累计值转季->64
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_LJZ                = `预测累计值`             //预测指标 - 累计值 -> 65
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_LJZNCZJ            = `预测年初至今累计值`         //预测指标 - 累计值(年初至今) -> 66
+	DATA_SOURCE_NAME_CALCULATE_STANDARD_DEVIATION         = `标准差`               //标准差->67
+	DATA_SOURCE_NAME_CALCULATE_PERCENTILE                 = `百分位`               //百分位->68
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_STANDARD_DEVIATION = `预测标准差`             //预测标准差->69
+	DATA_SOURCE_NAME_PREDICT_CALCULATE_PERCENTILE         = `预测百分位`             //预测百分位->70
 )
 
 // 基础数据初始化日期