|
@@ -2,6 +2,8 @@ package chart
|
|
|
|
|
|
import (
|
|
|
"errors"
|
|
|
+ "fmt"
|
|
|
+ "github.com/nosixtools/solarlunar"
|
|
|
"github.com/shopspring/decimal"
|
|
|
edbDataModel "hongze/hongze_yb/models/tables/edb_data"
|
|
|
predictEdbRuleDataModel "hongze/hongze_yb/models/tables/predict_edb_rule_data"
|
|
@@ -726,3 +728,328 @@ func GetChartPredictEdbInfoDataListByRuleFinalValueHc(edbInfoId int, finalValue
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+type SeasonConf struct {
|
|
|
+ Calendar string `description:"公历、农历"`
|
|
|
+ YearType int `description:"选择方式,1:连续N年;2:指定年份"`
|
|
|
+ NValue int `description:"连续N年"`
|
|
|
+ YearList []int `description:"指定年份列表"`
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+func GetChartPredictEdbInfoDataListByRuleSeason(edbInfoId int, yearsList []int, calendar string, startDate, endDate time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*edbDataModel.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*edbDataModel.EdbDataList, minValue, maxValue float64, err error) {
|
|
|
+ allDataList := make([]*edbDataModel.EdbDataList, 0)
|
|
|
+ allDataList = append(allDataList, realPredictEdbInfoData...)
|
|
|
+ allDataList = append(allDataList, predictEdbInfoData...)
|
|
|
+ newPredictEdbInfoData = predictEdbInfoData
|
|
|
+
|
|
|
+
|
|
|
+ moveDayMap := make(map[int]int, 0)
|
|
|
+ {
|
|
|
+ if calendar == "公历" {
|
|
|
+ for _, year := range yearsList {
|
|
|
+ moveDayMap[year] = 0
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ currentDay := time.Now()
|
|
|
+ if currentDay.Month() >= 11 {
|
|
|
+ currentDay = currentDay.AddDate(1, 0, 0)
|
|
|
+ }
|
|
|
+
|
|
|
+ currentYear := currentDay.Year()
|
|
|
+ currentYearCjnl := fmt.Sprintf("%d-01-01", currentYear)
|
|
|
+ currentYearCjgl := solarlunar.LunarToSolar(currentYearCjnl, false)
|
|
|
+ currentYearCjglTime, tmpErr := time.ParseInLocation(utils.FormatDate, currentYearCjgl, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = errors.New("当前春节公历日期转换失败:" + tmpErr.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ for _, year := range yearsList {
|
|
|
+ tmpYearCjnl := fmt.Sprintf("%d-01-01", year)
|
|
|
+ tmpYearCjgl := solarlunar.LunarToSolar(tmpYearCjnl, false)
|
|
|
+
|
|
|
+
|
|
|
+ tmpYearCjglTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpYearCjgl, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = errors.New(fmt.Sprintf("%d公历日期转换失败:%s", year, tmpErr.Error()))
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ tmpCurrentYearCjglTime := currentYearCjglTime.AddDate(year-currentYear, 0, 0)
|
|
|
+ moveDay := utils.GetTimeSubDay(tmpYearCjglTime, tmpCurrentYearCjglTime)
|
|
|
+ moveDayMap[year] = moveDay
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ index := len(allDataList)
|
|
|
+
|
|
|
+ dayList := getPredictEdbDayList(startDate, endDate, frequency)
|
|
|
+
|
|
|
+
|
|
|
+ predictEdbInfoData = make([]*edbDataModel.EdbDataList, 0)
|
|
|
+ for k, currentDate := range dayList {
|
|
|
+ tmpHistoryVal := decimal.NewFromFloat(0)
|
|
|
+ tmpHistoryValNum := 0
|
|
|
+
|
|
|
+ tmpLenAllDataList := len(allDataList)
|
|
|
+ tmpK := tmpLenAllDataList - 1
|
|
|
+ lastDayStr := allDataList[tmpK].DataTime
|
|
|
+ lastDayVal := allDataList[tmpK].Value
|
|
|
+ lastDay, tmpErr := time.ParseInLocation(utils.FormatDate, lastDayStr, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = errors.New("获取上期日期转换失败:" + tmpErr.Error())
|
|
|
+ }
|
|
|
+ for _, year := range yearsList {
|
|
|
+ moveDay := moveDayMap[year]
|
|
|
+ var tmpHistoryCurrentVal, tmpHistoryLastVal float64
|
|
|
+ var isFindHistoryCurrent, isFindHistoryLast bool
|
|
|
+
|
|
|
+
|
|
|
+ tmpHistoryCurrentDate := currentDate.AddDate(year-currentDate.Year(), 0, moveDay)
|
|
|
+ for i := 0; i <= 35; i++ {
|
|
|
+ tmpDate := tmpHistoryCurrentDate.AddDate(0, 0, i)
|
|
|
+ if val, ok := existMap[tmpDate.Format(utils.FormatDate)]; ok {
|
|
|
+ tmpHistoryCurrentVal = val
|
|
|
+ isFindHistoryCurrent = true
|
|
|
+ break
|
|
|
+ } else {
|
|
|
+ tmpDate := tmpHistoryCurrentDate.AddDate(0, 0, -i)
|
|
|
+ if val, ok := existMap[tmpDate.Format(utils.FormatDate)]; ok {
|
|
|
+ tmpHistoryCurrentVal = val
|
|
|
+ isFindHistoryCurrent = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ tmpHistoryLastDate := lastDay.AddDate(year-lastDay.Year(), 0, moveDay)
|
|
|
+ for i := 0; i <= 35; i++ {
|
|
|
+ tmpDate := tmpHistoryLastDate.AddDate(0, 0, i)
|
|
|
+ if val, ok := existMap[tmpDate.Format(utils.FormatDate)]; ok {
|
|
|
+ tmpHistoryLastVal = val
|
|
|
+ isFindHistoryLast = true
|
|
|
+ break
|
|
|
+ } else {
|
|
|
+ tmpDate := tmpHistoryLastDate.AddDate(0, 0, -i)
|
|
|
+ if val, ok := existMap[tmpDate.Format(utils.FormatDate)]; ok {
|
|
|
+ tmpHistoryLastVal = val
|
|
|
+ isFindHistoryLast = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if isFindHistoryCurrent && isFindHistoryLast {
|
|
|
+ af := decimal.NewFromFloat(tmpHistoryCurrentVal)
|
|
|
+ bf := decimal.NewFromFloat(tmpHistoryLastVal)
|
|
|
+ tmpHistoryVal = tmpHistoryVal.Add(af.Sub(bf))
|
|
|
+ tmpHistoryValNum++
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if tmpHistoryValNum != len(yearsList) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ lastDayValDec := decimal.NewFromFloat(lastDayVal)
|
|
|
+ val, _ := tmpHistoryVal.Div(decimal.NewFromInt(int64(tmpHistoryValNum))).Add(lastDayValDec).RoundCeil(4).Float64()
|
|
|
+
|
|
|
+ currentDateStr := currentDate.Format(utils.FormatDate)
|
|
|
+ tmpData := &edbDataModel.EdbDataList{
|
|
|
+ EdbDataId: edbInfoId + 10000000000 + index + k,
|
|
|
+ EdbInfoId: edbInfoId,
|
|
|
+ DataTime: currentDateStr,
|
|
|
+ Value: val,
|
|
|
+ DataTimestamp: (currentDate.UnixNano() / 1e6) + 1000,
|
|
|
+ }
|
|
|
+ newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
|
|
|
+ allDataList = append(allDataList, tmpData)
|
|
|
+ existMap[currentDateStr] = val
|
|
|
+
|
|
|
+
|
|
|
+ if val < minValue {
|
|
|
+ minValue = val
|
|
|
+ }
|
|
|
+ if val > maxValue {
|
|
|
+ maxValue = val
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+type MoveAverageConf struct {
|
|
|
+ Year int `description:"指定年份"`
|
|
|
+ NValue int `description:"N期的数据"`
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+func GetChartPredictEdbInfoDataListByRuleMoveAverageTb(edbInfoId int, nValue, year int, startDate, endDate time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*edbDataModel.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*edbDataModel.EdbDataList, minValue, maxValue float64, err error) {
|
|
|
+ allDataList := make([]*edbDataModel.EdbDataList, 0)
|
|
|
+ allDataList = append(allDataList, realPredictEdbInfoData...)
|
|
|
+ allDataList = append(allDataList, predictEdbInfoData...)
|
|
|
+ newPredictEdbInfoData = predictEdbInfoData
|
|
|
+
|
|
|
+ lenAllData := len(allDataList)
|
|
|
+ if lenAllData < nValue || lenAllData <= 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if nValue <= 0 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ decimalN := decimal.NewFromInt(int64(nValue))
|
|
|
+
|
|
|
+
|
|
|
+ dayList := getPredictEdbDayList(startDate, endDate, frequency)
|
|
|
+ for k, currentDate := range dayList {
|
|
|
+ tmpLenAllDataList := len(allDataList)
|
|
|
+ tmpIndex := tmpLenAllDataList - 1
|
|
|
+
|
|
|
+ averageDateList := make([]string, 0)
|
|
|
+
|
|
|
+
|
|
|
+ tmpDecimalVal := decimal.NewFromFloat(allDataList[tmpIndex].Value)
|
|
|
+ averageDateList = append(averageDateList, allDataList[tmpIndex].DataTime)
|
|
|
+ for tmpK := 2; tmpK <= nValue; tmpK++ {
|
|
|
+ tmpIndex2 := tmpIndex - tmpK
|
|
|
+ tmpDecimalVal2 := decimal.NewFromFloat(allDataList[tmpIndex2].Value)
|
|
|
+ tmpDecimalVal = tmpDecimalVal.Add(tmpDecimalVal2)
|
|
|
+ averageDateList = append(averageDateList, allDataList[tmpIndex2].DataTime)
|
|
|
+ }
|
|
|
+
|
|
|
+ tmpAverageVal := tmpDecimalVal.Div(decimalN)
|
|
|
+
|
|
|
+ var tmpHistoryCurrentVal float64
|
|
|
+ var isFindHistoryCurrent, isFindHistoryLast bool
|
|
|
+ tmpHistoryDecimalVal := decimal.NewFromFloat(0)
|
|
|
+
|
|
|
+ {
|
|
|
+
|
|
|
+ tmpHistoryValNum := 0
|
|
|
+ {
|
|
|
+
|
|
|
+ tmpHistoryCurrentDate := currentDate.AddDate(year-currentDate.Year(), 0, 0)
|
|
|
+ for i := 0; i <= 35; i++ {
|
|
|
+ tmpDate := tmpHistoryCurrentDate.AddDate(0, 0, i)
|
|
|
+ if val, ok := existMap[tmpDate.Format(utils.FormatDate)]; ok {
|
|
|
+ tmpHistoryCurrentVal = val
|
|
|
+ isFindHistoryCurrent = true
|
|
|
+ break
|
|
|
+ } else {
|
|
|
+ tmpDate := tmpHistoryCurrentDate.AddDate(0, 0, -i)
|
|
|
+ if val, ok := existMap[tmpDate.Format(utils.FormatDate)]; ok {
|
|
|
+ tmpHistoryCurrentVal = val
|
|
|
+ isFindHistoryCurrent = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, averageDate := range averageDateList {
|
|
|
+ lastDay, tmpErr := time.ParseInLocation(utils.FormatDate, averageDate, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ tmpHistoryLastDate := lastDay.AddDate(year-lastDay.Year(), 0, 0)
|
|
|
+ for i := 0; i <= 35; i++ {
|
|
|
+ tmpDate := tmpHistoryLastDate.AddDate(0, 0, i)
|
|
|
+ if val, ok := existMap[tmpDate.Format(utils.FormatDate)]; ok {
|
|
|
+ tmpDecimalVal2 := decimal.NewFromFloat(val)
|
|
|
+ tmpHistoryDecimalVal = tmpHistoryDecimalVal.Add(tmpDecimalVal2)
|
|
|
+ tmpHistoryValNum++
|
|
|
+ break
|
|
|
+ } else {
|
|
|
+ tmpDate := tmpHistoryLastDate.AddDate(0, 0, -i)
|
|
|
+ if val, ok := existMap[tmpDate.Format(utils.FormatDate)]; ok {
|
|
|
+ tmpDecimalVal2 := decimal.NewFromFloat(val)
|
|
|
+ tmpHistoryDecimalVal = tmpHistoryDecimalVal.Add(tmpDecimalVal2)
|
|
|
+ tmpHistoryValNum++
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if tmpHistoryValNum == nValue {
|
|
|
+ isFindHistoryLast = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if !isFindHistoryLast || !isFindHistoryCurrent {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ tbVal := tmpAverageVal.Div(tmpHistoryDecimalVal)
|
|
|
+
|
|
|
+
|
|
|
+ val, _ := decimal.NewFromFloat(tmpHistoryCurrentVal).Mul(tbVal).RoundCeil(4).Float64()
|
|
|
+
|
|
|
+ currentDateStr := currentDate.Format(utils.FormatDate)
|
|
|
+ tmpData := &edbDataModel.EdbDataList{
|
|
|
+ EdbDataId: edbInfoId + 10000000000 + lenAllData + k,
|
|
|
+ EdbInfoId: edbInfoId,
|
|
|
+ DataTime: currentDateStr,
|
|
|
+ Value: val,
|
|
|
+ DataTimestamp: (currentDate.UnixNano() / 1e6) + 1000,
|
|
|
+ }
|
|
|
+ newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
|
|
|
+ allDataList = append(allDataList, tmpData)
|
|
|
+ existMap[currentDateStr] = val
|
|
|
+
|
|
|
+
|
|
|
+ if val < minValue {
|
|
|
+ minValue = val
|
|
|
+ }
|
|
|
+ if val > maxValue {
|
|
|
+ maxValue = val
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|