|
@@ -7,6 +7,7 @@ import (
|
|
|
"github.com/nosixtools/solarlunar"
|
|
|
"github.com/shopspring/decimal"
|
|
|
"hongze/hongze_edb_lib/utils"
|
|
|
+ "math"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
"time"
|
|
@@ -251,6 +252,13 @@ func refreshAllCalculateCjjx(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo
|
|
|
dateArr = append(dateArr, v.DataTime)
|
|
|
dataMap[v.DataTime] = v
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ handleDataMap := make(map[string]float64)
|
|
|
+ err = handleDataByLinearRegression(dataList, handleDataMap)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
existDataList := make([]*EdbData, 0)
|
|
|
dataTableName := GetEdbDataTableName(source)
|
|
@@ -270,10 +278,10 @@ func refreshAllCalculateCjjx(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo
|
|
|
addSql := ` INSERT INTO edb_data_calculate_cjjx(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
|
|
|
var isAdd bool
|
|
|
|
|
|
- isCompatibility := false
|
|
|
- if utils.InArrayByStr([]string{"日度", "周度", "季度", "月度"}, fromEdbInfo.Frequency) {
|
|
|
- isCompatibility = true
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
moveDayMap := make(map[int]int, 0)
|
|
@@ -282,90 +290,99 @@ func refreshAllCalculateCjjx(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo
|
|
|
lastDataDay, _ = time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
|
|
|
}
|
|
|
for _, av := range dateArr {
|
|
|
- currentItem := dataMap[av]
|
|
|
- if currentItem != nil {
|
|
|
- pastValueList := make([]float64, 0)
|
|
|
-
|
|
|
- currentDate, tmpErr := time.Parse(utils.FormatDate, av)
|
|
|
- if tmpErr != nil {
|
|
|
- err = tmpErr
|
|
|
- return
|
|
|
- }
|
|
|
- pastValueList = append(pastValueList, currentItem.Value)
|
|
|
-
|
|
|
- for i := 1; i < formulaInt; i++ {
|
|
|
-
|
|
|
- hisoryPreDate := currentDate.AddDate(-i, 0, 0)
|
|
|
- moveDay := 0
|
|
|
- if calendar == "农历" {
|
|
|
- if tmpMoveDay, ok := moveDayMap[hisoryPreDate.Year()]; !ok {
|
|
|
- moveDay, err = getMoveDay(lastDataDay, hisoryPreDate)
|
|
|
- if err != nil {
|
|
|
- return
|
|
|
- }
|
|
|
- } else {
|
|
|
- moveDay = tmpMoveDay
|
|
|
- }
|
|
|
+
|
|
|
+ if strings.Contains(av, "02-29") {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ currentDate, tmpErr := time.Parse(utils.FormatDate, av)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if currentDate.Month() > 5 && currentDate.Month() < 11 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
- hisoryPreDate = hisoryPreDate.AddDate(0, 0, moveDay)
|
|
|
- }
|
|
|
+ currentItem, ok := dataMap[av]
|
|
|
+
|
|
|
+ if !ok {
|
|
|
+ continue
|
|
|
+ }
|
|
|
|
|
|
- hisoryPreDateStr := hisoryPreDate.Format(utils.FormatDate)
|
|
|
- if findItem, ok := dataMap[hisoryPreDateStr]; ok {
|
|
|
- pastValueList = append(pastValueList, findItem.Value)
|
|
|
- } else if isCompatibility {
|
|
|
- nextDateDay := hisoryPreDate
|
|
|
- preDateDay := hisoryPreDate
|
|
|
- for i := 0; i < 35; i++ {
|
|
|
- nextDateDayStr := nextDateDay.Format(utils.FormatDate)
|
|
|
- if findItem, ok := dataMap[nextDateDayStr]; ok {
|
|
|
- pastValueList = append(pastValueList, findItem.Value)
|
|
|
- break
|
|
|
- } else {
|
|
|
- preDateDayStr := preDateDay.Format(utils.FormatDate)
|
|
|
- if findItem, ok := dataMap[preDateDayStr]; ok {
|
|
|
- pastValueList = append(pastValueList, findItem.Value)
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- nextDateDay = nextDateDay.AddDate(0, 0, 1)
|
|
|
- preDateDay = preDateDay.AddDate(0, 0, -1)
|
|
|
+ pastValueList := make([]float64, 0)
|
|
|
+
|
|
|
+ pastValueList = append(pastValueList, currentItem.Value)
|
|
|
+
|
|
|
+ for i := 1; i < formulaInt; i++ {
|
|
|
+
|
|
|
+ historyPreDate := currentDate.AddDate(-i, 0, 0)
|
|
|
+ moveDay := 0
|
|
|
+ if calendar == "农历" {
|
|
|
+ if tmpMoveDay, ok := moveDayMap[historyPreDate.Year()]; !ok {
|
|
|
+ moveDay, err = getMoveDay(lastDataDay, historyPreDate)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
}
|
|
|
+ } else {
|
|
|
+ moveDay = tmpMoveDay
|
|
|
}
|
|
|
- if av == "2022-11-28" {
|
|
|
- fmt.Println(moveDay)
|
|
|
- }
|
|
|
- }
|
|
|
- if av == "2022-11-28" {
|
|
|
- fmt.Println(pastValueList)
|
|
|
- }
|
|
|
|
|
|
- if len(pastValueList) == formulaInt {
|
|
|
- delete(removeDataTimeMap, av)
|
|
|
+
|
|
|
+ historyPreDate = historyPreDate.AddDate(0, 0, moveDay)
|
|
|
+ }
|
|
|
|
|
|
- val := CjjxSub(currentItem.Value, pastValueList)
|
|
|
+ historyPreDateStr := historyPreDate.Format(utils.FormatDate)
|
|
|
+ if tmpValue, ok := handleDataMap[historyPreDateStr]; ok {
|
|
|
+ pastValueList = append(pastValueList, tmpValue)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- if existVal, ok := existDataMap[edbCode+av]; !ok {
|
|
|
- timestamp := currentDate.UnixNano() / 1e6
|
|
|
- timestampStr := fmt.Sprintf("%d", timestamp)
|
|
|
- addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
|
|
|
- isAdd = true
|
|
|
- } else {
|
|
|
- existValDecimal, err := decimal.NewFromString(existVal)
|
|
|
- existStr := existValDecimal.String()
|
|
|
- if existStr != val {
|
|
|
- sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
|
|
|
- sql = fmt.Sprintf(sql, dataTableName)
|
|
|
- _, err = to.Raw(sql, val, edbInfoId, av).Exec()
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
+ if len(pastValueList) == formulaInt {
|
|
|
+ delete(removeDataTimeMap, av)
|
|
|
+
|
|
|
+ val := CjjxSub(currentItem.Value, pastValueList)
|
|
|
+
|
|
|
+ if existVal, ok := existDataMap[edbCode+av]; !ok {
|
|
|
+ timestamp := currentDate.UnixNano() / 1e6
|
|
|
+ timestampStr := fmt.Sprintf("%d", timestamp)
|
|
|
+ addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
|
|
|
+ isAdd = true
|
|
|
+ } else {
|
|
|
+ existValDecimal, err := decimal.NewFromString(existVal)
|
|
|
+ existStr := existValDecimal.String()
|
|
|
+ if existStr != val {
|
|
|
+ sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
|
|
|
+ sql = fmt.Sprintf(sql, dataTableName)
|
|
|
+ _, err = to.Raw(sql, val, edbInfoId, av).Exec()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- existDataMap[edbCode+av] = av
|
|
|
}
|
|
|
+ existDataMap[edbCode+av] = av
|
|
|
}
|
|
|
|
|
|
|
|
@@ -432,7 +449,7 @@ func getMoveDay(lastDataDay, currentDataDay time.Time) (moveDay int, err error)
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
func CjjxSub(currValue float64, pastValue []float64) (value string) {
|
|
|
num := len(pastValue)
|
|
|
if num == 0 {
|
|
@@ -454,3 +471,72 @@ func CjjxSub(currValue float64, pastValue []float64) (value string) {
|
|
|
valStr := decimal.NewFromFloat(val).RoundCeil(4).String()
|
|
|
return valStr
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+func handleDataByLinearRegression(edbInfoDataList []*EdbInfoSearchData, handleDataMap map[string]float64) (err error) {
|
|
|
+ if len(edbInfoDataList) < 2 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ var startEdbInfoData *EdbInfoSearchData
|
|
|
+ for _, v := range edbInfoDataList {
|
|
|
+ handleDataMap[v.DataTime] = v.Value
|
|
|
+
|
|
|
+
|
|
|
+ if startEdbInfoData == nil {
|
|
|
+ startEdbInfoData = v
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
|
|
|
+ currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
|
|
|
+ betweenHour := int(currDataTime.Sub(startDataTime).Hours())
|
|
|
+ betweenDay := betweenHour / 24
|
|
|
+
|
|
|
+
|
|
|
+ if betweenDay <= 1 {
|
|
|
+ startEdbInfoData = v
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ var a, b float64
|
|
|
+ {
|
|
|
+ coordinateData := make([]utils.Coordinate, 0)
|
|
|
+ tmpCoordinate1 := utils.Coordinate{
|
|
|
+ X: 1,
|
|
|
+ Y: startEdbInfoData.Value,
|
|
|
+ }
|
|
|
+ coordinateData = append(coordinateData, tmpCoordinate1)
|
|
|
+ tmpCoordinate2 := utils.Coordinate{
|
|
|
+ X: float64(betweenDay) + 1,
|
|
|
+ Y: v.Value,
|
|
|
+ }
|
|
|
+ coordinateData = append(coordinateData, tmpCoordinate2)
|
|
|
+
|
|
|
+ a, b = utils.GetLinearResult(coordinateData)
|
|
|
+ if math.IsNaN(a) || math.IsNaN(b) {
|
|
|
+ err = errors.New("线性方程公式生成失败")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ {
|
|
|
+ for i := 1; i < betweenDay; i++ {
|
|
|
+ tmpDataTime := startDataTime.AddDate(0, 0, i)
|
|
|
+ aDecimal := decimal.NewFromFloat(a)
|
|
|
+ xDecimal := decimal.NewFromInt(int64(i) + 1)
|
|
|
+ bDecimal := decimal.NewFromFloat(b)
|
|
|
+
|
|
|
+ val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).RoundCeil(4).Float64()
|
|
|
+ handleDataMap[tmpDataTime.Format(utils.FormatDate)] = val
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ startEdbInfoData = v
|
|
|
+ }
|
|
|
+
|
|
|
+ return
|
|
|
+}
|