|
@@ -22,6 +22,8 @@ type EdbInfoCalculateSaveReq struct {
|
|
|
Unit string `description:"单位"`
|
|
|
ClassifyId int `description:"分类id"`
|
|
|
CalculateFormula string `description:"计算公式"`
|
|
|
+ EmptyType int `description:"空值处理类型(0查找前后35天,1不计算,2前值填充,3后值填充,4等于0)"`
|
|
|
+ MaxEmptyType int `description:"MAX、MIN公式空值处理类型(1、等于0;2、跳过空值)"`
|
|
|
EdbInfoIdArr []EdbInfoFromTag
|
|
|
}
|
|
|
|
|
@@ -37,92 +39,6 @@ type CalculateItems struct {
|
|
|
DataMap map[string]float64
|
|
|
}
|
|
|
|
|
|
-// AddCalculate 新增计算(运算)指标
|
|
|
-func AddCalculate(edbInfoIdArr []*EdbInfo, edbInfoId int, edbCode, formulaStr string, edbInfoIdBytes []string) (err error) {
|
|
|
- o := orm.NewOrm()
|
|
|
- defer func() {
|
|
|
- if err != nil {
|
|
|
- utils.FileLog.Info(fmt.Sprintf("Calculate Err:%s" + err.Error()))
|
|
|
- }
|
|
|
- }()
|
|
|
- saveDataMap := make(map[string]map[int]float64)
|
|
|
- for _, v := range edbInfoIdArr {
|
|
|
- var condition string
|
|
|
- var pars []interface{}
|
|
|
- condition += " AND edb_info_id=? "
|
|
|
- pars = append(pars, v.EdbInfoId)
|
|
|
- dataList, err := GetEdbDataListAll(condition, pars, v.Source, v.SubSource, 1)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- dataMap := make(map[string]float64)
|
|
|
- for _, dv := range dataList {
|
|
|
- if val, ok := saveDataMap[dv.DataTime]; ok {
|
|
|
- if _, ok := val[v.EdbInfoId]; !ok {
|
|
|
- val[v.EdbInfoId] = dv.Value
|
|
|
- }
|
|
|
- } else {
|
|
|
- temp := make(map[int]float64)
|
|
|
- temp[v.EdbInfoId] = dv.Value
|
|
|
- saveDataMap[dv.DataTime] = temp
|
|
|
- }
|
|
|
- }
|
|
|
- item := new(CalculateItems)
|
|
|
- item.EdbInfoId = v.EdbInfoId
|
|
|
- item.DataMap = dataMap
|
|
|
- }
|
|
|
- formulaMap := utils.CheckFormula(formulaStr)
|
|
|
- addSql := ` INSERT INTO edb_data_calculate(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
|
|
|
- nowStr := time.Now().Format(utils.FormatDateTime)
|
|
|
- var isAdd bool
|
|
|
- for sk, sv := range saveDataMap {
|
|
|
- formulaStr = strings.ToUpper(formulaStr)
|
|
|
- formulaFormStr := ReplaceFormula(edbInfoIdArr, sv, formulaMap, formulaStr, edbInfoIdBytes)
|
|
|
- if formulaStr == "" {
|
|
|
- return
|
|
|
- }
|
|
|
- if formulaFormStr != "" {
|
|
|
- expression := formula.NewExpression(formulaFormStr)
|
|
|
- calResult, err := expression.Evaluate()
|
|
|
- if err != nil {
|
|
|
- err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
|
|
|
- fmt.Println(err)
|
|
|
- return err
|
|
|
- }
|
|
|
- calVal, err := calResult.Float64()
|
|
|
- if err != nil {
|
|
|
- err = errors.New("计算失败:获取计算值失败 Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
|
|
|
- fmt.Println(err)
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- //需要存入的数据
|
|
|
- {
|
|
|
- dataTime, _ := time.ParseInLocation(utils.FormatDate, sk, time.Local)
|
|
|
- timestamp := dataTime.UnixNano() / 1e6
|
|
|
- timeStr := fmt.Sprintf("%d", timestamp)
|
|
|
- addSql += "("
|
|
|
- addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + sk + "'" + "," + utils.SubFloatToString(calVal, 4) + "," + "'" + nowStr + "'" +
|
|
|
- "," + "'" + nowStr + "'" + "," + "'" + timeStr + "'"
|
|
|
- addSql += "),"
|
|
|
- isAdd = true
|
|
|
- }
|
|
|
- } else {
|
|
|
- fmt.Println("formulaFormStr is empty")
|
|
|
- }
|
|
|
- }
|
|
|
- if isAdd {
|
|
|
- addSql = strings.TrimRight(addSql, ",")
|
|
|
- _, err = o.Raw(addSql).Exec()
|
|
|
- if err != nil {
|
|
|
- fmt.Println("AddEdbDataCalculate Err:" + err.Error())
|
|
|
- //errMsg = " tx.Exec Err :" + err.Error()
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
- return
|
|
|
-}
|
|
|
-
|
|
|
// AddCalculateInfo 新增计算(运算)指标
|
|
|
func AddCalculateInfo(req EdbInfoCalculateSaveReq, calculateMappingList []*EdbInfoCalculateMapping, edbInfoList []*EdbInfo, edbCode, uniqueCode string, edbInfoIdBytes []string) (edbInfo *EdbInfo, err error) {
|
|
|
|
|
@@ -172,6 +88,8 @@ func AddCalculateInfo(req EdbInfoCalculateSaveReq, calculateMappingList []*EdbIn
|
|
|
LatestDate: "",
|
|
|
LatestValue: 0,
|
|
|
ChartImage: "",
|
|
|
+ EmptyType: req.EmptyType,
|
|
|
+ MaxEmptyType: req.MaxEmptyType,
|
|
|
}
|
|
|
lastId, err := to.Insert(edbInfo)
|
|
|
if err != nil {
|
|
@@ -194,13 +112,12 @@ func AddCalculateInfo(req EdbInfoCalculateSaveReq, calculateMappingList []*EdbIn
|
|
|
}
|
|
|
|
|
|
//计算数据
|
|
|
- err = refreshAllCalculate(to, edbInfoList, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, edbInfo.CalculateFormula, "", "", edbInfoIdBytes)
|
|
|
-
|
|
|
+ err = refreshAllCalculate(to, edbInfoList, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, edbInfo.CalculateFormula, "", "", edbInfoIdBytes, edbInfo.EmptyType, edbInfo.MaxEmptyType)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// EditCalculateInfo 编辑计算(运算)指标
|
|
|
-func EditCalculateInfo(edbInfo *EdbInfo, req EdbInfoCalculateSaveReq, formulaMap map[string]string, edbInfoIdBytes []string, needCalculate bool) (err error, errMsg string) {
|
|
|
+func EditCalculateInfo(edbInfo *EdbInfo, req EdbInfoCalculateSaveReq, formulaSlice []string, edbInfoIdBytes []string, needCalculate bool) (err error, errMsg string) {
|
|
|
o := orm.NewOrm()
|
|
|
to, err := o.Begin()
|
|
|
if err != nil {
|
|
@@ -223,7 +140,9 @@ func EditCalculateInfo(edbInfo *EdbInfo, req EdbInfoCalculateSaveReq, formulaMap
|
|
|
edbInfo.ClassifyId = req.ClassifyId
|
|
|
edbInfo.CalculateFormula = req.CalculateFormula
|
|
|
edbInfo.ModifyTime = time.Now()
|
|
|
- _, err = to.Update(edbInfo, "EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId", "CalculateFormula", "ModifyTime")
|
|
|
+ edbInfo.EmptyType = req.EmptyType
|
|
|
+ edbInfo.MaxEmptyType = req.MaxEmptyType
|
|
|
+ _, err = to.Update(edbInfo, "EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId", "CalculateFormula", "ModifyTime", "EmptyType", "MaxEmptyType")
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
@@ -274,12 +193,15 @@ func EditCalculateInfo(edbInfo *EdbInfo, req EdbInfoCalculateSaveReq, formulaMap
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //预先计算,判断公式是否正常
|
|
|
- ok, _ := CheckFormula2(edbInfoList, formulaMap, req.CalculateFormula, edbInfoIdBytes)
|
|
|
- if !ok {
|
|
|
- errMsg = "生成计算指标失败,请使用正确的计算公式"
|
|
|
- err = errors.New(errMsg)
|
|
|
- return
|
|
|
+ for _, v := range formulaSlice {
|
|
|
+ formulaMap := utils.CheckFormula(v)
|
|
|
+ //预先计算,判断公式是否正常
|
|
|
+ ok, _ := CheckFormula2(edbInfoList, formulaMap, v, edbInfoIdBytes)
|
|
|
+ if !ok {
|
|
|
+ errMsg = "生成计算指标失败,请使用正确的计算公式"
|
|
|
+ err = errors.New(errMsg)
|
|
|
+ return
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//关联关系表
|
|
@@ -293,8 +215,7 @@ func EditCalculateInfo(edbInfo *EdbInfo, req EdbInfoCalculateSaveReq, formulaMap
|
|
|
}
|
|
|
|
|
|
//计算数据
|
|
|
- err = refreshAllCalculate(to, edbInfoList, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, edbInfo.CalculateFormula, "", "", edbInfoIdBytes)
|
|
|
-
|
|
|
+ err = refreshAllCalculate(to, edbInfoList, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, edbInfo.CalculateFormula, "", "", edbInfoIdBytes, edbInfo.EmptyType, edbInfo.MaxEmptyType)
|
|
|
}
|
|
|
|
|
|
return
|
|
@@ -337,7 +258,7 @@ func DeleteCalculateEdbInfo(edbInfoId int) (err error) {
|
|
|
}
|
|
|
|
|
|
// RefreshAllCalculate 刷新全部数据
|
|
|
-func RefreshAllCalculate(edbInfoIdArr []*EdbInfo, edbInfoId, source, subSource int, edbCode, formulaStr, startDate, endDate string, edbInfoIdBytes []string) (err error) {
|
|
|
+func RefreshAllCalculate(edbInfoIdArr []*EdbInfo, edbInfoId, source, subSource int, edbCode, formulaStr, startDate, endDate string, edbInfoIdBytes []string, emptyType, maxEmptyType int) (err error) {
|
|
|
o := orm.NewOrm()
|
|
|
to, err := o.Begin()
|
|
|
if err != nil {
|
|
@@ -354,13 +275,12 @@ func RefreshAllCalculate(edbInfoIdArr []*EdbInfo, edbInfoId, source, subSource i
|
|
|
fmt.Println(startDate, endDate)
|
|
|
|
|
|
//计算数据
|
|
|
- err = refreshAllCalculate(to, edbInfoIdArr, edbInfoId, source, subSource, edbCode, formulaStr, startDate, endDate, edbInfoIdBytes)
|
|
|
-
|
|
|
+ err = refreshAllCalculate(to, edbInfoIdArr, edbInfoId, source, subSource, edbCode, formulaStr, startDate, endDate, edbInfoIdBytes, emptyType, maxEmptyType)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// refreshAllCalculate 刷新全部数据
|
|
|
-func refreshAllCalculate(to orm.TxOrmer, edbInfoIdArr []*EdbInfo, edbInfoId, source, subSource int, edbCode, formulaStr, startDate, endDate string, edbInfoIdBytes []string) (err error) {
|
|
|
+func refreshAllCalculate(to orm.TxOrmer, edbInfoIdArr []*EdbInfo, edbInfoId, source, subSource int, edbCode, formulaStr, startDate, endDate string, edbInfoIdBytes []string, emptyType, maxEmptyType int) (err error) {
|
|
|
realSaveDataMap := make(map[string]map[int]float64)
|
|
|
saveDataMap := make(map[string]map[int]float64)
|
|
|
|
|
@@ -387,8 +307,6 @@ func refreshAllCalculate(to orm.TxOrmer, edbInfoIdArr []*EdbInfo, edbInfoId, sou
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- lenData := len(dataList)
|
|
|
-
|
|
|
for _, dv := range dataList {
|
|
|
if val, ok := realSaveDataMap[dv.DataTime]; ok {
|
|
|
if _, ok := val[v.EdbInfoId]; !ok {
|
|
@@ -414,26 +332,24 @@ func refreshAllCalculate(to orm.TxOrmer, edbInfoIdArr []*EdbInfo, edbInfoId, sou
|
|
|
// 以第一个指标的日期作为基准日期
|
|
|
if edbInfoIndex == 0 {
|
|
|
dateList = append(dateList, dv.DataTime)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if lenData > 0 {
|
|
|
- tmpLatestDate, _ := time.ParseInLocation(utils.FormatDate, dataList[lenData-1].DataTime, time.Local)
|
|
|
- if minLatestDate.IsZero() || minLatestDate.After(tmpLatestDate) {
|
|
|
- minLatestDate = tmpLatestDate
|
|
|
- }
|
|
|
-
|
|
|
- tmpStartDate, _ := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
|
|
|
- if maxStartDate.IsZero() || maxStartDate.Before(tmpStartDate) {
|
|
|
- maxStartDate = tmpStartDate
|
|
|
+ tmpDate, _ := time.ParseInLocation(utils.FormatDate, dv.DataTime, time.Local)
|
|
|
+ if minLatestDate.IsZero() || tmpDate.After(minLatestDate) {
|
|
|
+ minLatestDate = tmpDate
|
|
|
+ }
|
|
|
+ if maxStartDate.IsZero() || tmpDate.Before(maxStartDate) {
|
|
|
+ maxStartDate = tmpDate
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//数据处理,将日期内不全的数据做补全
|
|
|
- handleDateSaveDataMap(dateList, maxStartDate, minLatestDate, realSaveDataMap, saveDataMap, edbInfoIdArr)
|
|
|
+ HandleDateSaveDataMap(dateList, maxStartDate, minLatestDate, realSaveDataMap, saveDataMap, edbInfoIdArr, emptyType)
|
|
|
|
|
|
- formulaMap := utils.CheckFormula(formulaStr)
|
|
|
+ formulaDateSlice, formulaDateMap, err := utils.HandleFormulaJson(formulaStr, minLatestDate)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
addSql := ` INSERT INTO edb_data_calculate(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
|
|
|
var isAdd bool
|
|
|
|
|
@@ -455,10 +371,44 @@ func refreshAllCalculate(to orm.TxOrmer, edbInfoIdArr []*EdbInfo, edbInfoId, sou
|
|
|
}
|
|
|
edbInfoIdStr := strconv.Itoa(edbInfoId)
|
|
|
existDataMap := make(map[string]string)
|
|
|
+
|
|
|
+ // 判断是否特殊处理max和min函数
|
|
|
+ maxDealFlag := false
|
|
|
+ if emptyType == 4 && maxEmptyType == 2 {
|
|
|
+ maxDealFlag = true
|
|
|
+ }
|
|
|
for sk, sv := range saveDataMap {
|
|
|
+ // 当空值处理类型选择了不计算时,只要有一个指标在某个日期没有值(即空值),则计算指标在该日期没有值
|
|
|
+ if emptyType == 1 {
|
|
|
+ if len(sv) != len(edbInfoIdArr) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
//fmt.Println(sk, sv)
|
|
|
+ // 根据时间范围,选择对应的公式
|
|
|
+ formulaMap := make(map[string]string)
|
|
|
+ formulaStr = ""
|
|
|
+ for _, fv := range formulaDateSlice {
|
|
|
+ if sk < fv {
|
|
|
+ if f, ok := formulaDateMap[fv]; ok {
|
|
|
+ formulaStr = f
|
|
|
+ formulaMap = utils.CheckFormula(formulaStr)
|
|
|
+ }
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if formulaStr == "" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ svMax := make(map[int]float64)
|
|
|
+ if maxDealFlag {
|
|
|
+ // 特殊处理max和min函数,如果原本的值为空,则选择空值参与运算
|
|
|
+ if svMaxData, ok := realSaveDataMap[sk]; ok {
|
|
|
+ svMax = svMaxData
|
|
|
+ }
|
|
|
+ }
|
|
|
formulaStr = strings.ToUpper(formulaStr)
|
|
|
- formulaFormStr := ReplaceFormula(edbInfoIdArr, sv, formulaMap, formulaStr, edbInfoIdBytes)
|
|
|
+ formulaFormStr := ReplaceFormula(edbInfoIdArr, sv, svMax, formulaMap, formulaStr, edbInfoIdBytes, maxDealFlag)
|
|
|
//计算公式异常,那么就移除该指标
|
|
|
if formulaFormStr == `` {
|
|
|
//removeDateList = append(removeDateList, sk)
|
|
@@ -551,15 +501,20 @@ func refreshAllCalculate(to orm.TxOrmer, edbInfoIdArr []*EdbInfo, edbInfoId, sou
|
|
|
}
|
|
|
|
|
|
// ReplaceFormula 替换计算方式
|
|
|
-func ReplaceFormula(edbInfoIdArr []*EdbInfo, valArr map[int]float64, formulaMap map[string]string, formulaStr string, edbInfoIdBytes []string) string {
|
|
|
+func ReplaceFormula(edbInfoIdArr []*EdbInfo, valArr, valArrMax map[int]float64, formulaMap map[string]string, formulaStr string, edbInfoIdBytes []string, maxDealFlag bool) string {
|
|
|
+ // todo 先处理max和min函数的特殊情况
|
|
|
+ //if strings.Contains(formulaStr, "MAX") || strings.Contains(formulaStr, "MIN") {
|
|
|
funMap := GetFormulaMap()
|
|
|
for k, v := range funMap {
|
|
|
formulaStr = strings.Replace(formulaStr, k, v, -1)
|
|
|
}
|
|
|
+ if maxDealFlag {
|
|
|
+ formulaStr = GetMaxMinEdbInfo(formulaStr)
|
|
|
+ }
|
|
|
replaceCount := 0
|
|
|
for dk, dv := range edbInfoIdArr {
|
|
|
var isReplace bool
|
|
|
- formulaStr, isReplace = GetFormulaReplace(dk, dv.EdbInfoId, formulaStr, edbInfoIdBytes, formulaMap, valArr)
|
|
|
+ formulaStr, isReplace = GetFormulaReplace(dk, dv.EdbInfoId, formulaStr, edbInfoIdBytes, formulaMap, valArr, valArrMax, maxDealFlag)
|
|
|
if isReplace {
|
|
|
replaceCount++
|
|
|
}
|
|
@@ -567,6 +522,9 @@ func ReplaceFormula(edbInfoIdArr []*EdbInfo, valArr map[int]float64, formulaMap
|
|
|
for k, v := range funMap {
|
|
|
formulaStr = strings.Replace(formulaStr, v, k, -1)
|
|
|
}
|
|
|
+ if strings.Contains(formulaStr, "MAX()") || strings.Contains(formulaStr, "MIN()") {
|
|
|
+ return ""
|
|
|
+ }
|
|
|
if replaceCount == len(formulaMap) {
|
|
|
return formulaStr
|
|
|
} else {
|
|
@@ -574,14 +532,23 @@ func ReplaceFormula(edbInfoIdArr []*EdbInfo, valArr map[int]float64, formulaMap
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func GetFormulaReplace(index, edbInfoId int, formulaStr string, edbInfoIdBytes []string, formulaMap map[string]string, valArr map[int]float64) (formulaResult string, isReplace bool) {
|
|
|
+func GetFormulaReplace(index, edbInfoId int, formulaStr string, edbInfoIdBytes []string, formulaMap map[string]string, valArr, valArrMax map[int]float64, maxDealFlag bool) (formulaResult string, isReplace bool) {
|
|
|
formulaResult = formulaStr
|
|
|
dKey := edbInfoIdBytes[index]
|
|
|
if _, ok := formulaMap[dKey]; ok { //公式中存在
|
|
|
if val, valOk := valArr[edbInfoId]; valOk { //值存在
|
|
|
dvStr := fmt.Sprintf("%v", val)
|
|
|
- formulaResult = strings.Replace(formulaStr, dKey, dvStr, -1)
|
|
|
+ formulaResult = strings.Replace(formulaResult, dKey, dvStr, -1)
|
|
|
isReplace = true
|
|
|
+ if maxDealFlag {
|
|
|
+ if valM, valMOk := valArrMax[edbInfoId]; valMOk { //值存在
|
|
|
+ dvMStr := fmt.Sprintf("%v", valM)
|
|
|
+ formulaResult = strings.Replace(formulaResult, strings.ToLower(dKey), dvMStr, -1)
|
|
|
+ } else {
|
|
|
+ formulaResult = strings.Replace(formulaResult, strings.ToLower(dKey)+",", "", -1)
|
|
|
+ formulaResult = strings.Replace(formulaResult, ","+strings.ToLower(dKey), "", -1)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
return
|
|
@@ -598,7 +565,9 @@ func GetFormulaMap() map[string]string {
|
|
|
funMap["FLOOR"] = "[@^]"
|
|
|
funMap["MOD"] = "[@&]"
|
|
|
funMap["POW"] = "[@*]"
|
|
|
- funMap["ROUND"] = "[@(]"
|
|
|
+ funMap["ROUND"] = "[@`]"
|
|
|
+ funMap["LN"] = "[@-]"
|
|
|
+ funMap["EXP"] = "[@+]"
|
|
|
return funMap
|
|
|
}
|
|
|
|
|
@@ -656,8 +625,11 @@ func CheckFormula2(edbInfoArr []*EdbInfo, formulaMap map[string]string, formulaS
|
|
|
for _, v := range edbInfoArr {
|
|
|
valArr[v.EdbInfoId] = 100
|
|
|
}
|
|
|
+
|
|
|
formulaStr = strings.ToUpper(formulaStr)
|
|
|
- formulaFormStr := ReplaceFormula(edbInfoArr, valArr, formulaMap, formulaStr, edbInfoIdBytes)
|
|
|
+ // 预设里的max和min无需特殊处理
|
|
|
+ valArrMax := make(map[int]float64)
|
|
|
+ formulaFormStr := ReplaceFormula(edbInfoArr, valArr, valArrMax, formulaMap, formulaStr, edbInfoIdBytes, false)
|
|
|
if formulaFormStr == "" {
|
|
|
return
|
|
|
}
|
|
@@ -671,14 +643,14 @@ func CheckFormula2(edbInfoArr []*EdbInfo, formulaMap map[string]string, formulaS
|
|
|
}
|
|
|
|
|
|
// 处理整个数据
|
|
|
-func handleDateSaveDataMap(dateList []string, maxStartDate, minLatestDate time.Time, realSaveDataMap, saveDataMap map[string]map[int]float64, edbInfoIdArr []*EdbInfo) {
|
|
|
+func HandleDateSaveDataMap(dateList []string, maxStartDate, minLatestDate time.Time, realSaveDataMap, saveDataMap map[string]map[int]float64, edbInfoIdArr []*EdbInfo, emptyType int) {
|
|
|
for _, date := range dateList {
|
|
|
dateTime, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
|
|
|
// 如果当前日期早于数据的最大开始日期,那么不处理,进入下一个循环
|
|
|
if dateTime.Before(maxStartDate) {
|
|
|
continue
|
|
|
}
|
|
|
- // 如果当前日期晚于数据的最小结束日期,那么不处理,直接返回了
|
|
|
+ // todo 规则是否生效如果当前日期晚于数据的最小结束日期,那么不处理,直接返回了
|
|
|
if dateTime.After(minLatestDate) {
|
|
|
return
|
|
|
}
|
|
@@ -688,6 +660,7 @@ func handleDateSaveDataMap(dateList []string, maxStartDate, minLatestDate time.T
|
|
|
tmpEdbInfoId := edbInfo.EdbInfoId // 当前指标id
|
|
|
// 如果该日期不存在该指标数据,那么需要找寻前后日期的数据,进行填补
|
|
|
if _, ok := tmpDataMap[tmpEdbInfoId]; !ok {
|
|
|
+
|
|
|
//day := 0
|
|
|
//switch edbInfo.Frequency {
|
|
|
//case "周度":
|
|
@@ -702,14 +675,24 @@ func handleDateSaveDataMap(dateList []string, maxStartDate, minLatestDate time.T
|
|
|
// day = 365
|
|
|
//}
|
|
|
// 需求池 255 指标运算文案修改,补数据遍历区间修改(2023-3-7 09:37:23修改)
|
|
|
- day := 35
|
|
|
- handleDateDataMap(realSaveDataMap, saveDataMap, date, tmpEdbInfoId, day)
|
|
|
+
|
|
|
+ switch emptyType {
|
|
|
+ case 0:
|
|
|
+ handleDateDataMap(realSaveDataMap, saveDataMap, date, tmpEdbInfoId, 35)
|
|
|
+ case 2:
|
|
|
+ handleDateDataMapBefore(realSaveDataMap, saveDataMap, date, tmpEdbInfoId, edbInfo.StartDate, edbInfo.EndDate)
|
|
|
+ case 3:
|
|
|
+ handleDateDataMapAfter(realSaveDataMap, saveDataMap, date, tmpEdbInfoId, edbInfo.StartDate, edbInfo.EndDate)
|
|
|
+ case 4:
|
|
|
+ handleDateDataMapZero(saveDataMap, date, tmpEdbInfoId)
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// handleDateDataMap 处理单个日期的数据
|
|
|
+// handleDateDataMap 前后35天 处理单个日期的数据
|
|
|
func handleDateDataMap(realSaveDataMap, saveDataMap map[string]map[int]float64, date string, edbInfoId, day int) {
|
|
|
currDate, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
|
|
|
|
|
@@ -728,6 +711,7 @@ func handleDateDataMap(realSaveDataMap, saveDataMap map[string]map[int]float64,
|
|
|
}
|
|
|
if findDataMap, hasFindDataMap := realSaveDataMap[nextDateDayStr]; hasFindDataMap { // 下一个日期有数据
|
|
|
if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
|
|
|
+ fmt.Println(fmt.Sprintf("date:%s, 无值,取%s的值%.4f", date, nextDateDayStr, val))
|
|
|
saveDataMap[date][edbInfoId] = val
|
|
|
return
|
|
|
}
|
|
@@ -741,10 +725,139 @@ func handleDateDataMap(realSaveDataMap, saveDataMap map[string]map[int]float64,
|
|
|
}
|
|
|
if findDataMap, hasFindDataMap := realSaveDataMap[preDateDayStr]; hasFindDataMap { // 下一个日期有数据
|
|
|
if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
|
|
|
+ fmt.Println(fmt.Sprintf("date:%s, 无值,取%s的值%.4f", date, preDateDayStr, val))
|
|
|
+ saveDataMap[date][edbInfoId] = val
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// handleDateDataMapBefore 前值填充:空值优先以最近的前值填充,没有前值时,用后值填充
|
|
|
+func handleDateDataMapBefore(realSaveDataMap, saveDataMap map[string]map[int]float64, date string, edbInfoId int, startDate, endDate string) {
|
|
|
+ currDate, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
|
|
|
+
|
|
|
+ // 前一天
|
|
|
+ preDateDay := currDate
|
|
|
+
|
|
|
+ startDateT, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
|
|
|
+ endDateT, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
|
|
|
+
|
|
|
+ if currDate.Before(startDateT) {
|
|
|
+ if findDataMap, hasFindDataMap := realSaveDataMap[startDate]; hasFindDataMap { // 下一个日期有数据
|
|
|
+ if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
|
|
|
+ //utils.FileLog.Info(fmt.Sprintf("date:%s, 无值,取%s的值%.4f", date, startDate, val))
|
|
|
+ saveDataMap[date][edbInfoId] = val
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if currDate.After(endDateT) {
|
|
|
+ if findDataMap, hasFindDataMap := realSaveDataMap[endDate]; hasFindDataMap { // 下一个日期有数据
|
|
|
+ if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
|
|
|
+ //utils.FileLog.Info(fmt.Sprintf("date:%s, 无值,取%s的值%.4f", date, endDate, val))
|
|
|
+ saveDataMap[date][edbInfoId] = val
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for i := 1; preDateDay.After(startDateT) || preDateDay == startDateT; i++ {
|
|
|
+ // 上个日期的数据
|
|
|
+ {
|
|
|
+ preDateDay = currDate.AddDate(0, 0, -i)
|
|
|
+ preDateDayStr := preDateDay.Format(utils.FormatDate)
|
|
|
+ if findDataMap, hasFindDataMap := realSaveDataMap[preDateDayStr]; hasFindDataMap { // 下一个日期有数据
|
|
|
+ if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
|
|
|
+ //utils.FileLog.Info(fmt.Sprintf("date:%s, 无值,取%s的值%.4f", date, preDateDayStr, val))
|
|
|
+ saveDataMap[date][edbInfoId] = val
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// handleDateDataMapAfter 后值填充:空值优先以最近的后值填充,没有后值时,用前值填充
|
|
|
+func handleDateDataMapAfter(realSaveDataMap, saveDataMap map[string]map[int]float64, date string, edbInfoId int, startDate, endDate string) {
|
|
|
+ currDate, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
|
|
|
+
|
|
|
+ // 后一天
|
|
|
+ nextDateDay := currDate
|
|
|
+
|
|
|
+ startDateT, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
|
|
|
+ endDateT, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
|
|
|
+
|
|
|
+ if currDate.Before(startDateT) {
|
|
|
+ if findDataMap, hasFindDataMap := realSaveDataMap[startDate]; hasFindDataMap { // 下一个日期有数据
|
|
|
+ if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
|
|
|
+ //utils.FileLog.Info(fmt.Sprintf("date:%s, 无值,取%s的值%.4f", date, startDate, val))
|
|
|
+ saveDataMap[date][edbInfoId] = val
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if currDate.After(endDateT) {
|
|
|
+ if findDataMap, hasFindDataMap := realSaveDataMap[endDate]; hasFindDataMap { // 下一个日期有数据
|
|
|
+ if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
|
|
|
+ //utils.FileLog.Info(fmt.Sprintf("date:%s, 无值,取%s的值%.4f", date, endDate, val))
|
|
|
+ saveDataMap[date][edbInfoId] = val
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for i := 1; nextDateDay.Before(endDateT) || nextDateDay == endDateT; i++ {
|
|
|
+ // 下个日期的数据
|
|
|
+ {
|
|
|
+ nextDateDay = currDate.AddDate(0, 0, i)
|
|
|
+ nextDateDayStr := nextDateDay.Format(utils.FormatDate)
|
|
|
+ if findDataMap, hasFindDataMap := realSaveDataMap[nextDateDayStr]; hasFindDataMap { // 下一个日期有数据
|
|
|
+ if val, hasFindItem := findDataMap[edbInfoId]; hasFindItem {
|
|
|
+ //utils.FileLog.Info(fmt.Sprintf("date:%s, 无值,取%s的值%.4f", date, nextDateDayStr, val))
|
|
|
saveDataMap[date][edbInfoId] = val
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// handleDateDataMapZero 等于0
|
|
|
+func handleDateDataMapZero(saveDataMap map[string]map[int]float64, date string, edbInfoId int) {
|
|
|
+ saveDataMap[date][edbInfoId] = 0
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+func GetMaxMinEdbInfo(formula string) string {
|
|
|
+ flag := 0
|
|
|
+ for k, v := range formula {
|
|
|
+ if v >= 65 && v <= 122 {
|
|
|
+ // 从左边找到第一个左括号的位置,往前截取三个字符,判断是不是max或者min,如果是的话,把该入参改成小写
|
|
|
+ for i := k; i >= 4; i-- {
|
|
|
+ if formula[i:i+1] == "(" && flag >= 1 {
|
|
|
+ t := formula[i-4 : i]
|
|
|
+ if t == "[@@]" || t == "[@!]" {
|
|
|
+ formula = formula[:k] + strings.ToLower(formula[k:k+1]) + formula[k+1:]
|
|
|
+ }
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if formula[k:k+1] == "(" {
|
|
|
+ flag += 1
|
|
|
+ } else if formula[k:k+1] == ")" {
|
|
|
+ flag -= 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return formula
|
|
|
+}
|
|
|
+
|
|
|
+// PredictRuleCalculateByNineResp 获取预测指标规则9的绘图数据返回
|
|
|
+type PredictRuleCalculateByNineResp struct {
|
|
|
+ LatestDate string
|
|
|
+ DataList interface{}
|
|
|
}
|