Sfoglia il codice sorgente

Merge branch 'feature/eta1.2.2_day_val' of eta_server/eta_index_lib into master

xyxie 1 anno fa
parent
commit
68139609c6

+ 48 - 0
controllers/base_from_calculate.go

@@ -806,6 +806,21 @@ func (this *CalculateController) BatchSave() {
 		}
 		sourName = utils.DATA_SOURCE_NAME_CALCULATE_CORRELATION
 		edbInfo, err, errMsg = models.AddCalculateCorrelation(&req, edbCode, uniqueCode, sysUserId, sysUserName)
+	case utils.DATA_SOURCE_CALCULATE_RJZ:
+		if req.Frequency == "日度" {
+			br.Msg = "日度指标无需进行日均值计算"
+			return
+		}
+		if req.Frequency != fromEdbInfo.Frequency {
+			br.Msg = "当前频度和原指标频度不一致"
+			return
+		}
+		if req.Unit != fromEdbInfo.Unit {
+			br.Msg = "单位只允许为和原指标频度保持一致,禁止选择其他单位"
+			return
+		}
+		sourName = "日均值"
+		edbInfo, err = models.AddCalculateRjz(&req, fromEdbInfo, edbCode, uniqueCode, sysUserId, sysUserName)
 	default:
 		// 获取通用的数据源处理服务
 		baseEdbInfoModel = models.GetBaseEdbInfoModel(req.Source)
@@ -1223,6 +1238,21 @@ func (this *CalculateController) BatchEdit() {
 		}
 		sourName = utils.DATA_SOURCE_NAME_CALCULATE_CORRELATION
 		err, errMsg = models.EditCalculateCorrelation(edbInfo, &req)
+	case utils.DATA_SOURCE_CALCULATE_RJZ:
+		if req.Frequency == "日度" {
+			br.Msg = "日度指标无需进行日均值计算"
+			return
+		}
+		if req.Frequency != fromEdbInfo.Frequency {
+			br.Msg = "当前频度和原指标频度不一致"
+			return
+		}
+		if req.Unit != fromEdbInfo.Unit {
+			br.Msg = "单位只允许为和原指标频度保持一致,禁止选择其他单位"
+			return
+		}
+		sourName = "日均值"
+		err = models.EditCalculateRjz(edbInfo, &req, fromEdbInfo)
 	default:
 		// 获取通用的数据源处理服务
 		baseEdbInfoModel = models.GetBaseEdbInfoModel(req.Source)
@@ -1664,6 +1694,24 @@ func (this *CalculateController) Refresh() {
 		}
 	case utils.DATA_SOURCE_CALCULATE_CORRELATION:
 		err, errMsg = models.RefreshAllCalculateCorrelation(edbInfo)
+	case utils.DATA_SOURCE_CALCULATE_RJZ: //刷新日均值
+		calculateRjz, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
+		if err != nil {
+			errMsg = "GetEdbInfoCalculateMappingDetail Err:" + err.Error()
+			break
+		}
+		fromEdbInfo, err := models.GetEdbInfoById(calculateRjz.FromEdbInfoId)
+		if err != nil {
+			errMsg = "GetEdbInfoById Err:" + err.Error()
+			break
+		}
+		//startDate = edbInfo.StartDate
+		endDate = time.Now().Format(utils.FormatDate)
+		err = models.RefreshAllCalculateRjz(edbInfoId, source, fromEdbInfo, calculateRjz.EdbCode, startDate, endDate)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			errMsg = "RefreshAllCalculateRjz Err:" + err.Error()
+			break
+		}
 	default:
 		// 获取通用的数据源处理服务
 		baseEdbInfoModel = models.GetBaseEdbInfoModel(source)

+ 362 - 0
models/edb_data_calculate_rjz.go

@@ -0,0 +1,362 @@
+package models
+
+import (
+	"errors"
+	"eta/eta_index_lib/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/shopspring/decimal"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// AddCalculateRjz 日均值
+func AddCalculateRjz(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbInfo, edbCode, uniqueCode string, sysUserId int, sysUserRealName string) (edbInfo *EdbInfo, err error) {
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("AddCalculateRjz,Err:" + err.Error())
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+	if req.EdbInfoId <= 0 {
+		edbInfo = new(EdbInfo)
+		edbInfo.Source = utils.DATA_SOURCE_CALCULATE_RJZ
+		edbInfo.SourceName = "日均值"
+		edbInfo.EdbCode = edbCode
+		edbInfo.EdbName = req.EdbName
+		edbInfo.EdbNameSource = req.EdbName
+		edbInfo.Frequency = req.Frequency
+		edbInfo.Unit = req.Unit
+		edbInfo.ClassifyId = req.ClassifyId
+		edbInfo.SysUserId = sysUserId
+		edbInfo.SysUserRealName = sysUserRealName
+		edbInfo.CreateTime = time.Now()
+		edbInfo.ModifyTime = time.Now()
+		edbInfo.UniqueCode = uniqueCode
+		edbInfo.CalculateFormula = req.Formula
+		edbInfo.EdbType = 2
+		newEdbInfoId, tmpErr := to.Insert(edbInfo)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		edbInfo.EdbInfoId = int(newEdbInfoId)
+
+		//关联关系
+		{
+			calculateMappingItem := new(EdbInfoCalculateMapping)
+			calculateMappingItem.CreateTime = time.Now()
+			calculateMappingItem.ModifyTime = time.Now()
+			calculateMappingItem.Sort = 1
+			calculateMappingItem.EdbCode = edbCode
+			calculateMappingItem.EdbInfoId = edbInfo.EdbInfoId
+			calculateMappingItem.FromEdbInfoId = fromEdbInfo.EdbInfoId
+			calculateMappingItem.FromEdbCode = fromEdbInfo.EdbCode
+			calculateMappingItem.FromEdbName = fromEdbInfo.EdbName
+			calculateMappingItem.FromSource = fromEdbInfo.Source
+			calculateMappingItem.FromSourceName = fromEdbInfo.SourceName
+			calculateMappingItem.FromTag = ""
+			calculateMappingItem.Source = edbInfo.Source
+			calculateMappingItem.SourceName = edbInfo.SourceName
+			_, err = to.Insert(calculateMappingItem)
+			if err != nil {
+				return
+			}
+		}
+
+	} else {
+		edbInfo, err = GetEdbInfoById(req.EdbInfoId)
+		if err != nil {
+			return
+		}
+		dataTableName := GetEdbDataTableName(utils.DATA_SOURCE_CALCULATE_RJZ)
+		deleteSql := ` DELETE FROM %s WHERE edb_info_id=? `
+		deleteSql = fmt.Sprintf(deleteSql, dataTableName)
+		_, err = to.Raw(deleteSql, req.EdbInfoId).Exec()
+		if err != nil {
+			return
+		}
+	}
+
+	//计算数据
+	err = refreshAllCalculateRjz(to, edbInfo.EdbInfoId, edbInfo.Source, fromEdbInfo, edbCode, "", "")
+
+	return
+}
+
+// EditCalculateRjz 日均值
+func EditCalculateRjz(edbInfo *EdbInfo, req *EdbInfoCalculateBatchEditReq, fromEdbInfo *EdbInfo) (err error) {
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("EditCalculateRjz,Err:" + err.Error())
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	//修改指标信息
+	edbInfo.EdbName = req.EdbName
+	edbInfo.EdbNameSource = req.EdbName
+	edbInfo.Frequency = req.Frequency
+	edbInfo.Unit = req.Unit
+	edbInfo.ClassifyId = req.ClassifyId
+	edbInfo.ModifyTime = time.Now()
+	_, err = to.Update(edbInfo, "EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId", "ModifyTime")
+	if err != nil {
+		return
+	}
+
+	//判断计算指标是否被更换
+	var existCondition string
+	var existPars []interface{}
+	existCondition += " AND edb_info_id=? AND from_edb_info_id=? "
+	existPars = append(existPars, edbInfo.EdbInfoId, req.FromEdbInfoId)
+
+	count, err := GetEdbInfoCalculateCountByCondition(existCondition, existPars)
+	if err != nil {
+		err = errors.New("判断指标是否改变失败,Err:" + err.Error())
+		return
+	}
+	if count > 0 { // 指标未被替换,无需重新计算
+		return
+	}
+
+	//删除,计算指标关联的,基础指标的关联关系
+	sql := ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id = ? `
+	_, err = to.Raw(sql, edbInfo.EdbInfoId).Exec()
+	if err != nil {
+		return
+	}
+	//清空原有数据
+	sql = ` DELETE FROM edb_data_calculate_rjz WHERE edb_info_id = ? `
+	_, err = to.Raw(sql, edbInfo.EdbInfoId).Exec()
+	if err != nil {
+		return
+	}
+	//关联关系
+	{
+		calculateMappingItem := &EdbInfoCalculateMapping{
+			EdbInfoCalculateMappingId: 0,
+			EdbInfoId:                 edbInfo.EdbInfoId,
+			Source:                    utils.DATA_SOURCE_CALCULATE_RJZ,
+			SourceName:                "日均值",
+			EdbCode:                   edbInfo.EdbCode,
+			FromEdbInfoId:             fromEdbInfo.EdbInfoId,
+			FromEdbCode:               fromEdbInfo.EdbCode,
+			FromEdbName:               fromEdbInfo.EdbName,
+			FromSource:                fromEdbInfo.Source,
+			FromSourceName:            fromEdbInfo.SourceName,
+			FromTag:                   "",
+			Sort:                      1,
+			CreateTime:                time.Now(),
+			ModifyTime:                time.Now(),
+		}
+		_, err = to.Insert(calculateMappingItem)
+		if err != nil {
+			return
+		}
+	}
+
+	//计算数据
+	err = refreshAllCalculateRjz(to, edbInfo.EdbInfoId, edbInfo.Source, fromEdbInfo, edbInfo.EdbCode, "", "")
+
+	return
+}
+
+// RefreshAllCalculateRjz 刷新所有日均值数据
+func RefreshAllCalculateRjz(edbInfoId, source int, fromEdbInfo *EdbInfo, edbCode, startDate, endDate string) (err error) {
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("RefreshAllCalculateRjz,Err:" + err.Error())
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	//计算数据
+	err = refreshAllCalculateRjz(to, edbInfoId, source, fromEdbInfo, edbCode, startDate, endDate)
+	return
+}
+
+// refreshAllCalculateRjz
+func refreshAllCalculateRjz(to orm.TxOrmer, edbInfoId, source int, fromEdbInfo *EdbInfo, edbCode, startDate, endDate string) (err error) {
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	//计算数据
+
+	//计算数据
+	var condition string
+	var pars []interface{}
+	condition += " AND edb_info_id=? "
+	pars = append(pars, fromEdbInfo.EdbInfoId)
+
+	if startDate != "" {
+		condition += " AND data_time>=? "
+		pars = append(pars, startDate)
+	}
+	//if endDate != "" {
+	//	condition += " AND data_time<=? "
+	//	pars = append(pars, endDate)
+	//}
+
+	dataList, err := GetEdbDataListAll(condition, pars, fromEdbInfo.Source, 0)
+	if err != nil {
+		return err
+	}
+	var dateArr []string
+	dataMap := make(map[string]*EdbInfoSearchData)
+	for _, v := range dataList {
+		dateArr = append(dateArr, v.DataTime)
+		dataMap[v.DataTime] = v
+	}
+	fmt.Println("source:", source)
+	//获取指标所有数据
+	existDataList := make([]*EdbData, 0)
+	dataTableName := GetEdbDataTableName(source)
+	fmt.Println("dataTableName:", dataTableName)
+	sql := `SELECT * FROM %s WHERE edb_info_id=? `
+	sql = fmt.Sprintf(sql, dataTableName)
+	_, err = to.Raw(sql, edbInfoId).QueryRows(&existDataList)
+	if err != nil {
+		return err
+	}
+	existDataMap := make(map[string]string)
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v.Value
+	}
+	fmt.Println("existDataMap:", existDataMap)
+	addSql := ` INSERT INTO edb_data_calculate_rjz(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	existAddDataMap := make(map[string]string)
+	for _, av := range dateArr {
+		currentItem := dataMap[av]
+		if currentItem != nil {
+			//当前日期
+			currentDate, err := time.ParseInLocation(utils.FormatDate, av, time.Local)
+			if err != nil {
+				return err
+			}
+			//根据频度计算需要均分的天数
+			days, err := GetRjzFrequencyDays(currentDate, fromEdbInfo.Frequency)
+			val := rjzDiv(currentItem.Value, days)
+
+			timestamp := currentDate.UnixNano() / 1e6
+			timestampStr := fmt.Sprintf("%d", timestamp)
+			if existVal, ok := existDataMap[av]; !ok {
+				if _, existOk := existAddDataMap[av]; !existOk {
+					addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, val)
+					isAdd = true
+				}
+				existAddDataMap[av] = av
+			} 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 isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		_, err = to.Raw(addSql).Exec()
+		if err != nil {
+			return err
+		}
+	}
+	return
+}
+func GetRjzFrequencyDays(currDate time.Time, frequency string) (days int, err error) {
+	switch frequency {
+	case "周度", "周":
+		days = 7
+	case "旬度":
+		if currDate.Day() <= 20 { // 1旬和2旬都是10天
+			days = 10
+		} else {
+			// 下旬,多种可能,最大天数可能存在8天,9天,10天,11天,
+			currT := time.Date(currDate.Year(), currDate.Month(), 20, 0, 0, 0, 0, time.Local)
+			nextT := time.Date(currDate.Year(), currDate.Month()+1, 1, 0, 0, 0, 0, time.Local).AddDate(0, 0, -1)
+			days = utils.GetTimeSubDay(currT, nextT)
+		}
+	case "月度":
+		//统计当月的天数
+		currMonthFd := time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, time.Local)
+		nextMonthFd := time.Date(currDate.Year(), currDate.Month()+1, 1, 0, 0, 0, 0, time.Local)
+		days = utils.GetTimeSubDay(currMonthFd, nextMonthFd)
+	case "季度":
+		curr0T := time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, time.Local)
+		curr1T := time.Date(currDate.Year(), 3, 31, 0, 0, 0, 0, time.Local)
+		curr2T := time.Date(currDate.Year(), 6, 30, 0, 0, 0, 0, time.Local)
+		curr3T := time.Date(currDate.Year(), 9, 30, 0, 0, 0, 0, time.Local)
+		curr4T := time.Date(currDate.Year(), 12, 31, 0, 0, 0, 0, time.Local)
+
+		if currDate.Month() < 4 { // 1季度
+			days = utils.GetTimeSubDay(curr0T, curr1T)
+		} else if currDate.Month() < 7 { // 2季度
+			days = utils.GetTimeSubDay(curr1T, curr2T)
+		} else if currDate.Month() < 10 { // 3季度
+			days = utils.GetTimeSubDay(curr2T, curr3T)
+		} else {
+			// 4季度
+			days = utils.GetTimeSubDay(curr3T, curr4T)
+		}
+	case "年度":
+		//统计当前年份的天数,明年1月1日-今天年1月1日
+		currentYearFd := time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, time.Local)
+		nextYearFd := currentYearFd.AddDate(1, 0, 0)
+		days = utils.GetTimeSubDay(currentYearFd, nextYearFd)
+	case "半年度":
+		curr0T := time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, time.Local)
+		curr1T := time.Date(currDate.Year(), 6, 30, 0, 0, 0, 0, time.Local)
+		curr2T := time.Date(currDate.Year(), 12, 31, 0, 0, 0, 0, time.Local)
+
+		if currDate.Month() <= 6 { // 上半年
+			days = utils.GetTimeSubDay(curr0T, curr1T)
+		} else {
+			// 下半年
+			days = utils.GetTimeSubDay(curr1T, curr2T)
+		}
+	default:
+		days = 1
+		return
+	}
+	return
+}
+
+func rjzDiv(a float64, b int) string {
+	var valStr string
+	if b != 0 {
+		af := decimal.NewFromFloat(a)
+		bf := decimal.NewFromFloat(float64(b))
+		val, _ := af.Div(bf).Float64()
+		valStr = decimal.NewFromFloat(val).Round(4).String()
+	} else {
+		valStr = "0"
+	}
+	return valStr
+}

+ 4 - 0
models/edb_data_table.go

@@ -149,6 +149,10 @@ func GetEdbDataTableName(source int) (tableName string) {
 		tableName = "edb_data_calculate_zsxy" // 指数修匀->72
 	case utils.DATA_SOURCE_PREDICT_CALCULATE_ZSXY:
 		tableName = "edb_data_predict_calculate_zsxy" // 预测指数修匀->73
+	case utils.DATA_SOURCE_CALCULATE_ZDYFX:
+		tableName = "edb_data_calculate_zdyfx" // 自定义分析->74
+	case utils.DATA_SOURCE_CALCULATE_RJZ: //日均值75
+		tableName = "edb_data_calculate_rjz"
 	default:
 		tableName = ""
 	}

+ 0 - 70
utils/common.go

@@ -7,7 +7,6 @@ import (
 	"encoding/base64"
 	"encoding/hex"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"github.com/shopspring/decimal"
 	"image"
@@ -849,75 +848,6 @@ func GetNowYearLastDay() time.Time {
 }
 
 // CalculationDate 计算两个日期之间相差n年m月y天
-func CalculationDate(startDate, endDate time.Time) (beetweenDay string, err error) {
-	//startDate := time.Date(2021, 3, 28, 0, 0, 0, 0, time.Now().Location())
-	//endDate := time.Date(2022, 3, 31, 0, 0, 0, 0, time.Now().Location())
-	numYear := endDate.Year() - startDate.Year()
-
-	numMonth := int(endDate.Month()) - int(startDate.Month())
-
-	numDay := 0
-	//获取截止月的总天数
-	endDateDays := getMonthDay(endDate.Year(), int(endDate.Month()))
-
-	//获取截止月的前一个月
-	endDatePrevMonthDate := endDate.AddDate(0, -1, 0)
-	//获取截止日期的上一个月的总天数
-	endDatePrevMonthDays := getMonthDay(endDatePrevMonthDate.Year(), int(endDatePrevMonthDate.Month()))
-	//获取开始日期的的月份总天数
-	startDateMonthDays := getMonthDay(startDate.Year(), int(startDate.Month()))
-
-	//判断,截止月是否完全被选中,如果相等,那么代表截止月份全部天数被选择
-	if endDate.Day() == endDateDays {
-		numDay = startDateMonthDays - startDate.Day() + 1
-
-		//如果剩余天数正好与开始日期的天数是一致的,那么月份加1
-		if numDay == startDateMonthDays {
-			numMonth++
-			numDay = 0
-			//超过月份了,那么年份加1
-			if numMonth == 12 {
-				numYear++
-				numMonth = 0
-			}
-		}
-	} else {
-		numDay = endDate.Day() - startDate.Day() + 1
-	}
-
-	//天数小于0,那么向月份借一位
-	if numDay < 0 {
-		//向上一个月借一个月的天数
-		numDay += endDatePrevMonthDays
-
-		//总月份减去一个月
-		numMonth = numMonth - 1
-	}
-
-	//月份小于0,那么向年份借一位
-	if numMonth < 0 {
-		//向上一个年借12个月
-		numMonth += 12
-
-		//总年份减去一年
-		numYear = numYear - 1
-	}
-	if numYear < 0 {
-		err = errors.New("日期异常")
-		return
-	}
-
-	if numYear > 0 {
-		beetweenDay += fmt.Sprint(numYear, "年")
-	}
-	if numMonth > 0 {
-		beetweenDay += fmt.Sprint(numMonth, "个月")
-	}
-	if numDay > 0 {
-		beetweenDay += fmt.Sprint(numDay, "天")
-	}
-	return
-}
 
 // FormatPrice 格式化展示金额数字(财务金额展示,小数点前,每三位用,隔开)    1,234,567,898.55
 func FormatPrice(price float64) (str string) {

+ 2 - 0
utils/constants.go

@@ -95,6 +95,8 @@ const (
 	DATA_SOURCE_FUBAO                                           //富宝数据->71
 	DATA_SOURCE_CALCULATE_ZSXY                                  // 指数修匀->72
 	DATA_SOURCE_PREDICT_CALCULATE_ZSXY                          // 预测指数修匀->73
+	DATA_SOURCE_CALCULATE_ZDYFX                                 // 自定义分析->74
+	DATA_SOURCE_CALCULATE_RJZ                                   // 日均值计算->75
 )
 
 // 指标来源的中文展示