|
@@ -9,7 +9,6 @@ import (
|
|
|
"eta/eta_api/utils"
|
|
|
"fmt"
|
|
|
"github.com/shopspring/decimal"
|
|
|
- "github.com/yidane/formula"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
"time"
|
|
@@ -1127,209 +1126,6 @@ func GetPredictCalculateDataListByPredictEdbInfo(edbInfo *data_manage.EdbInfo, s
|
|
|
return
|
|
|
}
|
|
|
|
|
|
-// GetCalculateByRuleByNineParams 获取预测规则9的计算参数
|
|
|
-func GetCalculateByRuleByNineParams(req request.RuleConfig) (formula string, edbInfoList []*data_manage.EdbInfo, edbInfoIdBytes []string, err error, errMsg string) {
|
|
|
- formula = req.Value
|
|
|
- formula = strings.Replace(formula, "(", "(", -1)
|
|
|
- formula = strings.Replace(formula, ")", ")", -1)
|
|
|
- formula = strings.Replace(formula, ",", ",", -1)
|
|
|
- formula = strings.Replace(formula, "。", ".", -1)
|
|
|
- formula = strings.Replace(formula, "%", "*0.01", -1)
|
|
|
-
|
|
|
- //检验公式
|
|
|
- var checkFormulaStr string
|
|
|
- for _, tmpEdbInfoId := range req.EdbInfoIdArr {
|
|
|
- checkFormulaStr += tmpEdbInfoId.FromTag + ","
|
|
|
- edbInfoIdBytes = append(edbInfoIdBytes, tmpEdbInfoId.FromTag)
|
|
|
- }
|
|
|
- formulaMap := CheckFormula(formula)
|
|
|
- for _, tmpFormula := range formulaMap {
|
|
|
- if !strings.Contains(checkFormulaStr, tmpFormula) {
|
|
|
- errMsg = "公式错误,请重新填写"
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //关联的指标信息
|
|
|
- edbInfoList = make([]*data_manage.EdbInfo, 0)
|
|
|
-
|
|
|
- for _, tmpEdbInfoId := range req.EdbInfoIdArr {
|
|
|
- fromEdbInfo, tmpErr := data_manage.GetEdbInfoById(tmpEdbInfoId.EdbInfoId)
|
|
|
- if tmpErr != nil {
|
|
|
- if tmpErr.Error() == utils.ErrNoRow() {
|
|
|
- err = errors.New("指标 " + strconv.Itoa(tmpEdbInfoId.EdbInfoId) + " 不存在")
|
|
|
- } else {
|
|
|
- err = errors.New("获取指标失败:Err:" + tmpErr.Error())
|
|
|
- }
|
|
|
- errMsg = "数据计算失败"
|
|
|
- return
|
|
|
- }
|
|
|
- edbInfoList = append(edbInfoList, fromEdbInfo)
|
|
|
- }
|
|
|
- ok, _ := CheckFormula2(edbInfoList, formulaMap, formula, edbInfoIdBytes)
|
|
|
- if !ok {
|
|
|
- errMsg = "生成计算指标失败,请使用正确的计算公式"
|
|
|
- err = errors.New(errMsg)
|
|
|
- }
|
|
|
- return
|
|
|
-}
|
|
|
-
|
|
|
-// CalculateByRuleByNine 动态环差规则计算入库
|
|
|
-func CalculateByRuleByNine(formulaStr string, edbInfoList []*data_manage.EdbInfo, edbInfoIdBytes []string, emptyType, maxEmptyType int) (dataList []*data_manage.EdbDataList, err error) {
|
|
|
- realSaveDataMap := make(map[string]map[int]float64)
|
|
|
- saveDataMap := make(map[string]map[int]float64)
|
|
|
- dateList := make([]string, 0) //日期
|
|
|
-
|
|
|
- // 最小的结束日期 , 最晚的数据开始日期
|
|
|
- var minLatestDate, maxStartDate time.Time
|
|
|
- formulaStr = strings.ToUpper(formulaStr)
|
|
|
- // 获取关联指标数据
|
|
|
- for edbInfoIndex, v := range edbInfoList {
|
|
|
- sourceDataList, _, _, tmpErr, _ := GetPredictDataListByPredictEdbInfo(v, "", "", false)
|
|
|
- if tmpErr != nil {
|
|
|
- err = tmpErr
|
|
|
- return
|
|
|
- }
|
|
|
- dataMap := make(map[string]float64)
|
|
|
- lenData := len(sourceDataList)
|
|
|
- for _, dv := range sourceDataList {
|
|
|
- // 实际数据
|
|
|
- if val, ok := realSaveDataMap[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
|
|
|
- realSaveDataMap[dv.DataTime] = temp
|
|
|
- }
|
|
|
-
|
|
|
- // saveDataMap 待计算的数据
|
|
|
- if val, ok := saveDataMap[dv.DataTime]; ok {
|
|
|
- if _, ok := val[v.EdbInfoId]; !ok {
|
|
|
- val[v.EdbInfoId] = dv.Value
|
|
|
- }
|
|
|
- } else {
|
|
|
- temp2 := make(map[int]float64)
|
|
|
- temp2[v.EdbInfoId] = dv.Value
|
|
|
- saveDataMap[dv.DataTime] = temp2
|
|
|
- }
|
|
|
-
|
|
|
- // 以第一个指标的日期作为基准日期
|
|
|
- if edbInfoIndex == 0 {
|
|
|
- dateList = append(dateList, dv.DataTime)
|
|
|
- }
|
|
|
-
|
|
|
- if lenData > 0 {
|
|
|
- tmpLatestDate, _ := time.ParseInLocation(utils.FormatDate, sourceDataList[lenData-1].DataTime, time.Local)
|
|
|
- if minLatestDate.IsZero() || minLatestDate.After(tmpLatestDate) {
|
|
|
- minLatestDate = tmpLatestDate
|
|
|
- }
|
|
|
-
|
|
|
- tmpStartDate, _ := time.ParseInLocation(utils.FormatDate, sourceDataList[0].DataTime, time.Local)
|
|
|
- if maxStartDate.IsZero() || maxStartDate.Before(tmpStartDate) {
|
|
|
- maxStartDate = tmpStartDate
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- item := new(CalculateItems)
|
|
|
- item.EdbInfoId = v.EdbInfoId
|
|
|
- item.DataMap = dataMap
|
|
|
- }
|
|
|
-
|
|
|
- // todo 数据处理,将日期内不全的数据做填补
|
|
|
- handleDateSaveDataMap(dateList, realSaveDataMap, saveDataMap, edbInfoList, emptyType)
|
|
|
- // 添加数据
|
|
|
- dataList = make([]*data_manage.EdbDataList, 0)
|
|
|
-
|
|
|
- // 计算规则
|
|
|
- formulaDateSlice, formulaDateMap, err := HandleFormulaJson(formulaStr, maxStartDate.Format(utils.FormatDate))
|
|
|
- if err != nil {
|
|
|
- return
|
|
|
- }
|
|
|
- existDataMap := make(map[string]string)
|
|
|
- // 判断是否特殊处理max和min函数
|
|
|
- /*maxDealFlag := false
|
|
|
- if emptyType == 4 && maxEmptyType == 2 {
|
|
|
- maxDealFlag = true
|
|
|
- }*/
|
|
|
- for k, date := range dateList {
|
|
|
- sv := saveDataMap[date]
|
|
|
- // 当空值处理类型选择了不计算时,只要有一个指标在某个日期没有值(即空值),则计算指标在该日期没有值
|
|
|
- if emptyType == 1 {
|
|
|
- if len(sv) != len(edbInfoList) {
|
|
|
- continue
|
|
|
- }
|
|
|
- }
|
|
|
- //fmt.Println(sk, sv)
|
|
|
- // 根据时间范围,选择对应的公式
|
|
|
- formulaMap := make(map[string]string)
|
|
|
- formulaStr = ""
|
|
|
- for _, fv := range formulaDateSlice {
|
|
|
- if date >= fv {
|
|
|
- if f, ok := formulaDateMap[fv]; ok {
|
|
|
- formulaStr = f
|
|
|
- formulaMap = CheckFormula(formulaStr)
|
|
|
- }
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- if formulaStr == "" {
|
|
|
- continue
|
|
|
- }
|
|
|
- /*svMax := make(map[int]float64)
|
|
|
- if maxDealFlag {
|
|
|
- // 特殊处理max和min函数,如果原本的值为空,则选择空值参与运算
|
|
|
- if svMaxData, ok := realSaveDataMap[date]; ok {
|
|
|
- svMax = svMaxData
|
|
|
- }
|
|
|
- }
|
|
|
- */
|
|
|
- //fmt.Println(date, sv)
|
|
|
-
|
|
|
- formulaFormStr := ReplaceFormula(edbInfoList, sv, formulaMap, formulaStr, edbInfoIdBytes)
|
|
|
- if formulaFormStr == `` {
|
|
|
- //计算公式异常,那么就移除该指标
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- //fmt.Println(fmt.Sprintf("formulaFormStr:%s", formulaFormStr))
|
|
|
- expression := formula.NewExpression(formulaFormStr)
|
|
|
- calResult, tmpErr := expression.Evaluate()
|
|
|
- if tmpErr != nil {
|
|
|
- // 分母为0的报错
|
|
|
- if strings.Contains(tmpErr.Error(), "divide by zero") {
|
|
|
- continue
|
|
|
- }
|
|
|
- err = errors.New("计算失败:Err:" + tmpErr.Error() + ";formulaStr:" + formulaFormStr)
|
|
|
- return
|
|
|
- }
|
|
|
- calVal, tmpErr := calResult.Float64()
|
|
|
- if tmpErr != nil {
|
|
|
- err = errors.New("计算失败:获取计算值失败 Err:" + tmpErr.Error() + ";formulaStr:" + formulaFormStr)
|
|
|
- fmt.Println(err)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- saveValue, _ := decimal.NewFromFloat(calVal).RoundCeil(4).Float64() //utils.SubFloatToString(calVal, 4)
|
|
|
- dataTime, _ := time.Parse(utils.FormatDate, date)
|
|
|
- timestamp := dataTime.UnixNano() / 1e6
|
|
|
-
|
|
|
- if _, existOk := existDataMap[date]; !existOk {
|
|
|
- tmpPredictEdbRuleData := &data_manage.EdbDataList{
|
|
|
- EdbDataId: k,
|
|
|
- EdbInfoId: 0,
|
|
|
- DataTime: date,
|
|
|
- DataTimestamp: timestamp,
|
|
|
- Value: saveValue,
|
|
|
- }
|
|
|
- dataList = append(dataList, tmpPredictEdbRuleData)
|
|
|
- }
|
|
|
- existDataMap[date] = date
|
|
|
- }
|
|
|
- return
|
|
|
-}
|
|
|
-
|
|
|
// ModifyPredictEdbBaseInfoBySourceEdb 根据来源ETA指标修改预测指标的基础信息
|
|
|
func ModifyPredictEdbBaseInfoBySourceEdb(sourceEDdbInfo *data_manage.EdbInfo) {
|
|
|
list, err := data_manage.GetGroupPredictEdbBySourceEdbInfoId(sourceEDdbInfo.EdbInfoId)
|