瀏覽代碼

累计值的最新值修改

xyxie 1 年之前
父節點
當前提交
48ce2993c7
共有 4 個文件被更改,包括 157 次插入12 次删除
  1. 1 1
      controllers/base_from_calculate.go
  2. 2 0
      models/base_from_calculate.go
  3. 149 11
      models/edb_data_calculate_ljz.go
  4. 5 0
      models/edb_info.go

+ 1 - 1
controllers/base_from_calculate.go

@@ -385,7 +385,7 @@ func (this *CalculateController) Edit() {
 	}
 	var needCalculate bool
 
-	if edbInfoDetail.CalculateFormula != req.CalculateFormula || edbInfoDetail.EmptyType != req.EmptyType || edbInfoDetail.MaxEmptyType != req.MaxEmptyType {
+	if edbInfoDetail.CalculateFormula != req.CalculateFormula || edbInfoDetail.EmptyType != req.EmptyType || edbInfoDetail.MaxEmptyType != req.MaxEmptyType || edbInfoDetail.Extra != req.Extra {
 		needCalculate = true
 	}
 

+ 2 - 0
models/base_from_calculate.go

@@ -630,6 +630,7 @@ type EdbInfoCalculateBatchSaveReq struct {
 	MoveFrequency    string                         `description:"移动频度:天/周/月/季/年"`
 	Calendar         string                         `description:"公历/农历"`
 	Data             interface{}                    `description:"数据"`
+	Extra            string                         `description:"指标的额外配置"`
 }
 
 // EdbInfoCalculateEdbInfoIdReq 新增/编辑请求 关联的指标列表
@@ -657,6 +658,7 @@ type EdbInfoCalculateBatchEditReq struct {
 		MoveValue int    `description:"移动的值"`
 	}
 	Calendar string      `description:"公历/农历" orm:"default(公历)"`
+	Extra    string      `description:"指标的额外配置"`
 	Data     interface{} `description:"数据"`
 }
 

+ 149 - 11
models/edb_data_calculate_ljz.go

@@ -1,6 +1,7 @@
 package models
 
 import (
+	"encoding/json"
 	"errors"
 	"eta/eta_index_lib/utils"
 	"fmt"
@@ -80,6 +81,7 @@ func (obj Ljz) Add(params AddCalculateBatchParams) (edbInfo *EdbInfo, err error,
 		LatestValue:      0,
 		ChartImage:       "",
 		Calendar:         "",
+		Extra:            req.Extra,
 	}
 
 	newEdbInfoId, tmpErr := to.Insert(edbInfo)
@@ -113,7 +115,7 @@ func (obj Ljz) Add(params AddCalculateBatchParams) (edbInfo *EdbInfo, err error,
 	}
 
 	//计算数据
-	err = obj.refresh(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo, fromEdbInfo, edbInfo.EdbCode, "")
+	err = obj.refresh(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo, fromEdbInfo, edbInfo.EdbCode, "", edbInfo.Extra)
 
 	return
 }
@@ -152,7 +154,7 @@ func (obj Ljz) Edit(params EditCalculateBatchParams) (err error, errMsg string)
 	tableName := GetEdbDataTableName(edbInfo.Source, edbInfo.SubSource)
 
 	var isRecalculate bool
-	if edbInfo.Frequency != req.Frequency {
+	if edbInfo.Frequency != req.Frequency || edbInfo.Extra != req.Extra {
 		isRecalculate = true
 	}
 	//修改指标信息
@@ -161,6 +163,7 @@ func (obj Ljz) Edit(params EditCalculateBatchParams) (err error, errMsg string)
 	edbInfo.Frequency = req.Frequency
 	edbInfo.Unit = req.Unit
 	edbInfo.ClassifyId = req.ClassifyId
+	edbInfo.Extra = req.Extra
 	edbInfo.ModifyTime = time.Now()
 	_, err = to.Update(edbInfo, "EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId", "ModifyTime")
 	if err != nil {
@@ -180,9 +183,9 @@ func (obj Ljz) Edit(params EditCalculateBatchParams) (err error, errMsg string)
 	}
 	if count > 0 { // 指标未被替换,无需删除关联数据
 
-		// 频度被换了,需要重新计算
+		// todo 频度被换了,需要重新计算
 		if isRecalculate {
-			err = obj.refresh(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo, fromEdbInfo, edbInfo.EdbCode, "")
+			err = obj.refresh(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo, fromEdbInfo, edbInfo.EdbCode, "", req.Extra)
 		}
 
 		return
@@ -228,7 +231,7 @@ func (obj Ljz) Edit(params EditCalculateBatchParams) (err error, errMsg string)
 	}
 
 	//计算数据
-	err = obj.refresh(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo, fromEdbInfo, edbInfo.EdbCode, "")
+	err = obj.refresh(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo, fromEdbInfo, edbInfo.EdbCode, "", edbInfo.Extra)
 
 	return
 }
@@ -261,7 +264,7 @@ func (obj Ljz) Refresh(params RefreshParams) (err error, errMsg string) {
 	}()
 
 	// 计算数据
-	err = obj.refresh(to, params.EdbInfo.EdbInfoId, params.EdbInfo.Source, params.EdbInfo.SubSource, params.EdbInfo, fromEdbInfo, params.EdbInfo.EdbCode, params.StartDate)
+	err = obj.refresh(to, params.EdbInfo.EdbInfoId, params.EdbInfo.Source, params.EdbInfo.SubSource, params.EdbInfo, fromEdbInfo, params.EdbInfo.EdbCode, params.StartDate, params.EdbInfo.Extra)
 
 	return
 }
@@ -281,7 +284,7 @@ func (obj Ljz) GetEdbType() int {
 	return utils.CALCULATE_EDB_TYPE
 }
 
-func (obj Ljz) refresh(to orm.TxOrmer, edbInfoId, source, subSource int, edbInfo, fromEdbInfo *EdbInfo, edbCode, startDate string) (err error) {
+func (obj Ljz) refresh(to orm.TxOrmer, edbInfoId, source, subSource int, edbInfo, fromEdbInfo *EdbInfo, edbCode, startDate string, extra string) (err error) {
 	dataTableName := GetEdbDataTableName(source, subSource)
 	edbInfoIdStr := strconv.Itoa(edbInfoId)
 	//计算数据
@@ -313,8 +316,19 @@ func (obj Ljz) refresh(to orm.TxOrmer, edbInfoId, source, subSource int, edbInfo
 			return
 		}
 	}
+	var lastValType int
+	if extra != "" {
+		var lastValConfig CalculateLjzEdbExtra
+		err = json.Unmarshal([]byte(extra), &lastValConfig)
+		if err != nil {
+			err = fmt.Errorf("refreshAllCalculate,extra解析失败,Err:%s", err.Error())
+			return
+		}
+		lastValType = lastValConfig.LastValType
+	}
 
 	//日度转周度:日期选周五,计算上周六到本周五的日度值的加总,最新日期为最新值对应的周五。
+	//日度转旬度:日期选每个旬的最后一天,计算当旬所有日度值的加总,最新日期为最新值对应当旬的最后一天。
 	//日度转月度:日期选每个月最后一天,计算当月所有日度值的加总,最新日期为最新值对应当月最后一天。
 	//日度转季度、年度:方法类似转月度。
 	//周度转月度/季度/年度:将周度值转成日度,空值用插值法插值,计算当月/当季/当年所有值的加总,然后除以7。
@@ -326,6 +340,7 @@ func (obj Ljz) refresh(to orm.TxOrmer, edbInfoId, source, subSource int, edbInfo
 	case "年度":
 		yearMap := make(map[int]float64)
 		yearList := make([]int, 0)
+		var lastNewDate time.Time
 		for _, item := range dataList {
 			itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, item.DataTime, time.Local)
 			if tmpErr != nil {
@@ -345,10 +360,41 @@ func (obj Ljz) refresh(to orm.TxOrmer, edbInfoId, source, subSource int, edbInfo
 			currTime := time.Date(v, 12, 31, 0, 0, 0, 0, time.Local)
 			dateList = append(dateList, currTime)
 			valueMap[currTime] = yearMap[v]
+			lastNewDate = currTime
+		}
+
+		// 根据配置处理最新值, 1 表示均值填充
+		if lastValType == 1 {
+			lastItem := dataList[len(dataList)-1]
+			// 最后一天的累计值
+			initVal := valueMap[lastNewDate]
+			itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, lastItem.DataTime, time.Local)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+
+			//获取当季的总天数, 当季最后一天减去当季第一天
+			// 获取当年的总天数
+			startDateT := time.Date(itemDate.Year(), 1, 1, 0, 0, 0, 0, time.Local)
+			allDays := int(lastNewDate.Sub(startDateT).Hours() / 24)
+			//获取距离当年第一天的天数
+			days := int(itemDate.Sub(startDateT).Hours() / 24)
+
+			daysT := decimal.NewFromInt(int64(days))
+			initValAndMonthT := decimal.NewFromFloat(initVal * float64(allDays))
+			val, ok := initValAndMonthT.Div(daysT).RoundCeil(4).Float64()
+			fmt.Printf("最新值 计算公式:%d*%f/(%d) = %f\n", allDays, initVal, days, val)
+			if !ok {
+				err = fmt.Errorf("最新值,均值计算失败")
+				return
+			}
+			valueMap[lastNewDate] = val
 		}
 	case "半年度":
 		yearMonthMap := make(map[string]float64)
 		yearMonthList := make([]string, 0)
+		var lastNewDate time.Time
 		for _, item := range dataList {
 			itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, item.DataTime, time.Local)
 			if tmpErr != nil {
@@ -380,10 +426,41 @@ func (obj Ljz) refresh(to orm.TxOrmer, edbInfoId, source, subSource int, edbInfo
 			currTime = currTime.AddDate(0, 1, -1)
 			dateList = append(dateList, currTime)
 			valueMap[currTime] = yearMonthMap[v]
+			lastNewDate = currTime
+		}
+
+		// 根据配置处理最新值, 1 表示均值填充
+		if lastValType == 1 {
+			lastItem := dataList[len(dataList)-1]
+			// 最后一天的累计值
+			initVal := valueMap[lastNewDate]
+			itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, lastItem.DataTime, time.Local)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+
+			//获取上半年或者下半年的总天数, 半年度最后一天减去半年度第一天
+			startDateT := lastNewDate.AddDate(0, -6, 0)
+			allDays := int(lastNewDate.Sub(startDateT).Hours() / 24)
+
+			//获取距离半年度第一天的天数
+			days := int(itemDate.Sub(startDateT).Hours() / 24)
+
+			daysT := decimal.NewFromInt(int64(days))
+			initValAndMonthT := decimal.NewFromFloat(initVal * float64(allDays))
+			val, ok := initValAndMonthT.Div(daysT).RoundCeil(4).Float64()
+			fmt.Printf("最新值 计算公式:%d*%f/(%d) = %f\n", allDays, initVal, days, val)
+			if !ok {
+				err = fmt.Errorf("最新值,均值计算失败")
+				return
+			}
+			valueMap[lastNewDate] = val
 		}
 	case "季度":
 		yearMonthMap := make(map[string]float64)
 		yearMonthList := make([]string, 0)
+		var lastNewDate time.Time
 		for _, item := range dataList {
 			itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, item.DataTime, time.Local)
 			if tmpErr != nil {
@@ -419,10 +496,40 @@ func (obj Ljz) refresh(to orm.TxOrmer, edbInfoId, source, subSource int, edbInfo
 			currTime = currTime.AddDate(0, 1, -1)
 			dateList = append(dateList, currTime)
 			valueMap[currTime] = yearMonthMap[v]
+			lastNewDate = currTime
+		}
+
+		// 根据配置处理最新值, 1 表示均值填充
+		if lastValType == 1 {
+			lastItem := dataList[len(dataList)-1]
+			// 最后一天的累计值
+			initVal := valueMap[lastNewDate]
+			itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, lastItem.DataTime, time.Local)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+
+			//获取当季的总天数, 当季最后一天减去当季第一天
+			startDateT := lastNewDate.AddDate(0, -3, 0)
+			allDays := int(lastNewDate.Sub(startDateT).Hours() / 24)
+			//获取距离当季第一天的天数
+			days := int(itemDate.Sub(startDateT).Hours() / 24)
+
+			daysT := decimal.NewFromInt(int64(days))
+			initValAndMonthT := decimal.NewFromFloat(initVal * float64(allDays))
+			val, ok := initValAndMonthT.Div(daysT).RoundCeil(4).Float64()
+			fmt.Printf("最新值 计算公式:%d*%f/(%d) = %f\n", allDays, initVal, days, val)
+			if !ok {
+				err = fmt.Errorf("最新值,均值计算失败")
+				return
+			}
+			valueMap[lastNewDate] = val
 		}
 	case "月度":
 		yearMonthMap := make(map[string]float64)
 		yearMonthList := make([]string, 0)
+		var lastNewDate time.Time
 		for _, item := range dataList {
 			itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, item.DataTime, time.Local)
 			if tmpErr != nil {
@@ -450,6 +557,34 @@ func (obj Ljz) refresh(to orm.TxOrmer, edbInfoId, source, subSource int, edbInfo
 			currTime = currTime.AddDate(0, 1, -1)
 			dateList = append(dateList, currTime)
 			valueMap[currTime] = yearMonthMap[v]
+			lastNewDate = currTime
+		}
+
+		// 根据配置处理最新值, 1 表示均值填充
+		if lastValType == 1 {
+			lastItem := dataList[len(dataList)-1]
+			// 最后一天的累计值
+			initVal := valueMap[lastNewDate]
+			itemDate, tmpErr := time.ParseInLocation(utils.FormatDate, lastItem.DataTime, time.Local)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+
+			//获取当月的天数
+			monthDays := lastNewDate.Day()
+			//获取自然日的天数
+			days := itemDate.Day()
+
+			daysT := decimal.NewFromInt(int64(days))
+			initValAndMonthT := decimal.NewFromFloat(initVal * float64(monthDays))
+			val, ok := initValAndMonthT.Div(daysT).RoundCeil(4).Float64()
+			fmt.Printf("最新值 计算公式:%d*%f/(%d) = %f\n", monthDays, initVal, days, val)
+			if !ok {
+				err = fmt.Errorf("最新值,均值计算失败")
+				return
+			}
+			valueMap[lastNewDate] = val
 		}
 	case "旬度":
 		tmpDateDataMap := make(map[time.Time]float64)
@@ -462,20 +597,23 @@ func (obj Ljz) refresh(to orm.TxOrmer, edbInfoId, source, subSource int, edbInfo
 			}
 			dayInt := itemDate.Year()*100 + int(itemDate.Month())
 			var currTime time.Time
-			if itemDate.Month() <= 10 {
-				tmpK := fmt.Sprint(dayInt*100, "10")
+			if itemDate.Day() <= 10 {
+				//本月上旬
+				tmpK := fmt.Sprint(dayInt, "10")
 				currTime, err = time.ParseInLocation(utils.FormatDateUnSpace, tmpK, time.Local)
 				if err != nil {
 					return
 				}
 
-			} else if itemDate.Month() <= 20 {
-				tmpK := fmt.Sprint(dayInt*100, "20")
+			} else if itemDate.Day() <= 20 {
+				// 本月中旬
+				tmpK := fmt.Sprint(dayInt, "20")
 				currTime, err = time.ParseInLocation(utils.FormatDateUnSpace, tmpK, time.Local)
 				if err != nil {
 					return
 				}
 			} else {
+				// 本月下旬
 				currTime, err = time.ParseInLocation(utils.FormatYearMonthUnSpace, fmt.Sprint(dayInt), time.Local)
 				if err != nil {
 					return

+ 5 - 0
models/edb_info.go

@@ -1261,3 +1261,8 @@ func GetEdbAndClassifyMaxSort(parentId int, classifyType uint8) (maxSort int, er
 type CalculateEdbExtra struct {
 	DateTag string `description:"时间序列的生成方式,all 表示所选指标的时间序列并集"`
 }
+
+// CalculateLjzEdbExtra 累计值额外配置
+type CalculateLjzEdbExtra struct {
+	LastValType int `description:"最新值处理:0默认、均值填充"`
+}