|
@@ -4,6 +4,7 @@ import (
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
"github.com/beego/beego/v2/client/orm"
|
|
|
+ "github.com/nosixtools/solarlunar"
|
|
|
"github.com/shopspring/decimal"
|
|
|
"hongze/hongze_edb_lib/utils"
|
|
|
"strconv"
|
|
@@ -88,7 +89,7 @@ func AddCalculateCjjx(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbInfo, e
|
|
|
}
|
|
|
|
|
|
//计算数据
|
|
|
- err = refreshAllCalculateCjjx(to, edbInfo.EdbInfoId, edbInfo.Source, fromEdbInfo, edbInfo.EdbCode, "", "", formulaInt)
|
|
|
+ err = refreshAllCalculateCjjx(to, edbInfo.EdbInfoId, edbInfo.Source, fromEdbInfo, edbInfo.EdbCode, "", "", "公历", formulaInt)
|
|
|
|
|
|
return
|
|
|
}
|
|
@@ -187,7 +188,7 @@ func EditCalculateCjjx(req *EdbInfoCalculateBatchEditReq, edbInfo, fromEdbInfo *
|
|
|
}
|
|
|
|
|
|
//计算数据
|
|
|
- err = refreshAllCalculateCjjx(to, edbInfo.EdbInfoId, edbInfo.Source, fromEdbInfo, edbInfo.EdbCode, "", "", formulaInt)
|
|
|
+ err = refreshAllCalculateCjjx(to, edbInfo.EdbInfoId, edbInfo.Source, fromEdbInfo, edbInfo.EdbCode, "", "", "公历", formulaInt)
|
|
|
|
|
|
return
|
|
|
}
|
|
@@ -209,13 +210,13 @@ func RefreshAllCalculateCjjx(edbInfoId, source int, fromEdbInfo *EdbInfo, edbCod
|
|
|
}()
|
|
|
|
|
|
// 重新计算
|
|
|
- err = refreshAllCalculateCjjx(to, edbInfoId, source, fromEdbInfo, edbCode, startDate, endDate, formulaInt)
|
|
|
+ err = refreshAllCalculateCjjx(to, edbInfoId, source, fromEdbInfo, edbCode, startDate, endDate, "农历", formulaInt)
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// refreshAllCalculateCjjx 刷新全部超季节性数据
|
|
|
-func refreshAllCalculateCjjx(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo *EdbInfo, edbCode, startDate, endDate string, formulaInt int) (err error) {
|
|
|
+func refreshAllCalculateCjjx(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo *EdbInfo, edbCode, startDate, endDate, calendar string, formulaInt int) (err error) {
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
@@ -257,8 +258,10 @@ func refreshAllCalculateCjjx(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo
|
|
|
return err
|
|
|
}
|
|
|
existDataMap := make(map[string]string)
|
|
|
+ removeDataTimeMap := make(map[string]int) //需要移除的日期数据
|
|
|
for _, v := range existDataList {
|
|
|
existDataMap[edbCode+v.DataTime] = v.Value
|
|
|
+ removeDataTimeMap[v.DataTime] = 1
|
|
|
}
|
|
|
|
|
|
addSql := ` INSERT INTO edb_data_calculate_cjjx(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
|
|
@@ -269,6 +272,12 @@ func refreshAllCalculateCjjx(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo
|
|
|
isCompatibility = true
|
|
|
}
|
|
|
|
|
|
+ // 每个年份的日期数据需要平移的天数
|
|
|
+ moveDayMap := make(map[int]int, 0) // 每个年份的春节公历
|
|
|
+ var lastDataDay time.Time
|
|
|
+ if len(dataList) > 0 {
|
|
|
+ lastDataDay, _ = time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
|
|
|
+ }
|
|
|
for _, av := range dateArr {
|
|
|
currentItem := dataMap[av]
|
|
|
if currentItem != nil {
|
|
@@ -280,15 +289,31 @@ func refreshAllCalculateCjjx(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo
|
|
|
return
|
|
|
}
|
|
|
pastValueList = append(pastValueList, currentItem.Value)
|
|
|
+
|
|
|
for i := 1; i < formulaInt; i++ {
|
|
|
- //前几年的日期
|
|
|
- preDate := currentDate.AddDate(-i, 0, 0)
|
|
|
- preDateStr := preDate.Format(utils.FormatDate)
|
|
|
- if findItem, ok := dataMap[preDateStr]; ok { //上一年同期找到
|
|
|
+ //前几年当天公历的日期
|
|
|
+ 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
|
|
|
+ }
|
|
|
+
|
|
|
+ // 移动天数到对应农历 的 公历 日期
|
|
|
+ hisoryPreDate = hisoryPreDate.AddDate(0, 0, moveDay)
|
|
|
+ }
|
|
|
+
|
|
|
+ hisoryPreDateStr := hisoryPreDate.Format(utils.FormatDate)
|
|
|
+ if findItem, ok := dataMap[hisoryPreDateStr]; ok { //上一年同期找到
|
|
|
pastValueList = append(pastValueList, findItem.Value)
|
|
|
} else if isCompatibility { // 如果需要兼容上下35天
|
|
|
- nextDateDay := preDate
|
|
|
- preDateDay := preDate
|
|
|
+ nextDateDay := hisoryPreDate
|
|
|
+ preDateDay := hisoryPreDate
|
|
|
for i := 0; i < 35; i++ {
|
|
|
nextDateDayStr := nextDateDay.Format(utils.FormatDate)
|
|
|
if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
|
|
@@ -305,9 +330,17 @@ func refreshAllCalculateCjjx(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo
|
|
|
preDateDay = preDateDay.AddDate(0, 0, -1)
|
|
|
}
|
|
|
}
|
|
|
+ if av == "2022-11-28" {
|
|
|
+ fmt.Println(moveDay)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if av == "2022-11-28" {
|
|
|
+ fmt.Println(pastValueList)
|
|
|
}
|
|
|
|
|
|
if len(pastValueList) == formulaInt {
|
|
|
+ delete(removeDataTimeMap, av) //将待删除的日期给移除
|
|
|
+
|
|
|
val := CjjxSub(currentItem.Value, pastValueList)
|
|
|
|
|
|
if existVal, ok := existDataMap[edbCode+av]; !ok {
|
|
@@ -331,6 +364,26 @@ func refreshAllCalculateCjjx(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo
|
|
|
existDataMap[edbCode+av] = av
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ //删除已经不存在的超季节性指标数据(由于该指标当日的数据删除了)
|
|
|
+ {
|
|
|
+ removeDateList := make([]string, 0)
|
|
|
+ for dateTime := range removeDataTimeMap {
|
|
|
+ removeDateList = append(removeDateList, dateTime)
|
|
|
+ }
|
|
|
+ removeNum := len(removeDateList)
|
|
|
+ if removeNum > 0 {
|
|
|
+ //如果拼接指标变更了,那么需要删除所有的指标数据
|
|
|
+ tableName := GetEdbDataTableName(source)
|
|
|
+ sql := fmt.Sprintf(` DELETE FROM %s WHERE edb_info_id = ? and data_time in (`+utils.GetOrmInReplace(removeNum)+`) `, tableName)
|
|
|
+ _, err = to.Raw(sql, edbInfoId, removeDateList).Exec()
|
|
|
+ if err != nil {
|
|
|
+ err = fmt.Errorf("删除不存在的超季节性指标数据失败,Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if isAdd {
|
|
|
addSql = strings.TrimRight(addSql, ",")
|
|
|
_, err = to.Raw(addSql).Exec()
|
|
@@ -341,6 +394,39 @@ func refreshAllCalculateCjjx(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+// getMoveDay 获取两个日期的平移天数
|
|
|
+func getMoveDay(lastDataDay, currentDataDay time.Time) (moveDay int, err error) {
|
|
|
+ if lastDataDay.Month() >= 11 { //最新数据的日期如果大于等于11月份,那么用的是下一年的春节
|
|
|
+ lastDataDay = lastDataDay.AddDate(1, 0, 0)
|
|
|
+ }
|
|
|
+
|
|
|
+ currentYear := lastDataDay.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
|
|
|
+ }
|
|
|
+
|
|
|
+ //指定年的春节农历
|
|
|
+ tmpYearCjnl := fmt.Sprintf("%d-01-01", currentDataDay.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", currentDataDay.Year(), tmpErr.Error()))
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将两个日期同步到同一年,然后计算两个日期相差的天数
|
|
|
+ tmpCurrentYearCjglTime := currentYearCjglTime.AddDate(currentDataDay.Year()-currentYear, 0, 0)
|
|
|
+ moveDay = utils.GetTimeSubDay(tmpYearCjglTime, tmpCurrentYearCjglTime)
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
// CjjxSub 计算超季节性值
|
|
|
// 计算公式=现值-过去n年(包括今年)均值,n为取数个数,需大于等于1;
|
|
|
//举例:A指标 2022-10-13值100,2021-10-13值120,2020-10-13值110,设置n=3,则“超季节性”指标计算值为100-(100+120+110)/3=-10。
|
|
@@ -352,7 +438,7 @@ func CjjxSub(currValue float64, pastValue []float64) (value string) {
|
|
|
numDecimal := decimal.NewFromInt(int64(num))
|
|
|
|
|
|
af := decimal.NewFromFloat(currValue)
|
|
|
- fmt.Println(af)
|
|
|
+ //fmt.Println(af)
|
|
|
|
|
|
bf := decimal.NewFromFloat(pastValue[0])
|
|
|
|