kobe6258 2 dní pred
rodič
commit
7b5d8dc7de
2 zmenil súbory, kde vykonal 132 pridanie a 0 odobranie
  1. 5 0
      models/edb_info.go
  2. 127 0
      models/predict_edb_info_rule.go

+ 5 - 0
models/edb_info.go

@@ -1166,6 +1166,11 @@ func GetChartPredictEdbInfoDataListByConfList(predictEdbConfList []*PredictEdbCo
 			if err != nil {
 				return
 			}
+		case 17, 18:
+			predictEdbInfoData, tmpMinValue, tmpMaxValue, err = GetChartPredictEdbInfoDataListByRuleDynamicYOYComparisonOrDifference(predictEdbConf.RuleType, predictEdbConf.PredictEdbInfoId, predictEdbConf.Value, dayList, realPredictEdbInfoData, existMap)
+			if err != nil {
+				return
+			}
 		}
 
 		// 下一个规则的开始日期

+ 127 - 0
models/predict_edb_info_rule.go

@@ -8,6 +8,7 @@ import (
 	"github.com/nosixtools/solarlunar"
 	"github.com/shopspring/decimal"
 	"math"
+	"strconv"
 	"strings"
 	"time"
 )
@@ -1849,3 +1850,129 @@ func getYearListBySeasonConf(configValue string) (yearList []int, seasonConf Sea
 
 	return
 }
+
+// GetChartPredictEdbInfoDataListByRuleDynamicYOYComparisonOrDifference 动态同比
+// 2、指标选择范围为预测指标。
+// 3、动态同比计算方法:预测值=去年同期值*(1+同比指标预测值)
+// 4、上述“去年同期”如果没有严格对应的日期,则前后查找最近35天的值。
+// 5、选择的同比指标日期需要与预测指标未来日期对应上,对应不上的不生成预测值。
+func GetChartPredictEdbInfoDataListByRuleDynamicYOYComparisonOrDifference(ruleType, edbInfoId int, configValue string, dayList []time.Time, realPredictEdbInfoData []*EdbInfoSearchData, existMap map[string]float64) (newPredictEdbInfoData []*EdbInfoSearchData, minValue, maxValue float64, err error) {
+	//预测指标的去年同期数据
+	baseDynamicDataList := make(map[string]decimal.Decimal, len(dayList))
+	//动态同比同差指标
+	DynamicCalculateDataList := make(map[string]decimal.Decimal, len(dayList))
+	index := len(realPredictEdbInfoData)
+	if index <= 0 {
+		return
+	}
+	dynamicYOYComparisonIndexId, err := strconv.Atoi(configValue)
+	if err != nil {
+		return
+	}
+	newPredictEdbInfoData = make([]*EdbInfoSearchData, 0, len(dayList))
+	// 获取同比预测指标的预测数据
+	dynamicYOYComparisonIndex, err := GetEdbInfoById(dynamicYOYComparisonIndexId)
+	if err != nil {
+		return
+	}
+	if dynamicYOYComparisonIndex.EdbInfoType != 1 {
+		err = errors.New("选择的指标不是预测指标")
+		return
+	}
+	startDate, endDate := dayList[0].Format(utils.FormatDate), dayList[len(dayList)-1].Format(utils.FormatDate)
+	//获取动态同比指标对应预测日期的预测数据
+	dynamicYOYComparisonIndexDataList, err := GetEdbDataList(dynamicYOYComparisonIndex.Source, dynamicYOYComparisonIndex.SubSource, dynamicYOYComparisonIndex.EdbInfoId, startDate, endDate)
+	if err != nil {
+		return
+	}
+	if len(dynamicYOYComparisonIndexDataList) <= 0 {
+		return
+	} else {
+		for _, v := range dynamicYOYComparisonIndexDataList {
+			DynamicCalculateDataList[v.DataTime] = decimal.NewFromFloat(v.Value)
+		}
+	}
+	var predictDayList []time.Time
+	//获取上一期的同期数据
+	for _, date := range dayList {
+		preDate := date.AddDate(-1, 0, 0)
+		preDateStr := preDate.Format(utils.FormatDate)
+		if preValue, ok := existMap[preDateStr]; ok { //上一年同期找到
+			baseDynamicDataList[preDateStr] = decimal.NewFromFloat(preValue)
+			predictDayList = append(predictDayList, date)
+		} else {
+			if replaceValue, replaceOk := getReplaceValue(existMap, 35, 1, -1, preDate); !replaceOk {
+				continue
+			} else {
+				baseDynamicDataList[preDateStr] = replaceValue
+				predictDayList = append(predictDayList, date)
+			}
+		}
+	}
+
+	//获取后面的预测数据
+
+	for k, currentDate := range predictDayList {
+		var calculateValue decimal.Decimal
+		var dateStr = currentDate.Format(utils.FormatDate)
+		preDate := currentDate.AddDate(-1, 0, 0)
+		preDateStr := preDate.Format(utils.FormatDate)
+		_, dynamicVal := DynamicCalculateDataList[dateStr]
+		_, baseVal := baseDynamicDataList[preDateStr]
+		if dynamicVal && baseVal {
+			switch ruleType {
+			case 17:
+				calculateValue = baseDynamicDataList[preDateStr].Mul(DynamicCalculateDataList[dateStr].Add(decimal.NewFromInt(1)))
+			case 18:
+				calculateValue = baseDynamicDataList[preDateStr].Add(DynamicCalculateDataList[dateStr])
+			default:
+				err = errors.New("计算规则不存在")
+				return
+			}
+			tmpData := &EdbInfoSearchData{
+				EdbDataId:     edbInfoId + 100000 + index + k,
+				EdbInfoId:     edbInfoId,
+				DataTime:      currentDate.Format(utils.FormatDate),
+				DataTimestamp: currentDate.UnixNano() / 1e6,
+			}
+			var val = calculateValue.InexactFloat64()
+			tmpData.Value = val
+			newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
+			existMap[tmpData.DataTime] = val
+			if k == 0 {
+				minValue = val
+				maxValue = val
+			} else {
+				// 最大最小值
+				if val < minValue {
+					minValue = val
+				}
+				if val > maxValue {
+					maxValue = val
+				}
+			}
+		}
+	}
+	return
+}
+func getReplaceValue(replaceValueMap map[string]float64, days, dayStepForward int, dayStepBack int, currentDate time.Time) (replaceValue decimal.Decimal, success bool) {
+	nextDateDay := currentDate
+	backDateDay := currentDate
+	for i := 0; i <= days; i++ {
+		nextDateDayStr := nextDateDay.Format(utils.FormatDate)
+		if preValue, ok := replaceValueMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
+			replaceValue = decimal.NewFromFloat(preValue)
+			success = true
+			return
+		}
+		backDateDayStr := backDateDay.Format(utils.FormatDate)
+		if backValue, ok := replaceValueMap[backDateDayStr]; ok { //上一年同期->下一个月找到
+			replaceValue = decimal.NewFromFloat(backValue)
+			success = true
+			return
+		}
+		nextDateDay = nextDateDay.AddDate(0, 0, dayStepForward)
+		backDateDay = nextDateDay.AddDate(0, 0, dayStepBack)
+	}
+	return decimal.NewFromInt(0), false
+}