Преглед изворни кода

add:增加stl指标添加功能

zqbao пре 4 месеци
родитељ
комит
b2875d4392

+ 16 - 0
controllers/data_manage/stl/stl.go

@@ -114,6 +114,22 @@ func (c *STLController) SaveStlEdbInfo() {
 		br.ErrMsg = err.Error()
 		return
 	}
+	sysUser := c.SysUser
+
+	IsSendEmail, msg, err := stl.SaveStlEdbInfo(req, sysUser.AdminId, sysUser.RealName, c.Lang)
+	if err != nil {
+		if msg == "" {
+			msg = "保存异常"
+		}
+		br.Msg = msg
+		br.ErrMsg = err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.IsSendEmail = IsSendEmail
 }
 
 // EdbInfoFilterByEs

+ 8 - 1
models/data_manage/edb_info_calculate_mapping.go

@@ -2,8 +2,9 @@ package data_manage
 
 import (
 	"eta/eta_api/utils"
-	"github.com/beego/beego/v2/client/orm"
 	"time"
+
+	"github.com/beego/beego/v2/client/orm"
 )
 
 // EdbInfoCalculateMapping 计算指标于基础指标,关系表
@@ -93,6 +94,12 @@ type EdbInfoCalculateMappingInfo struct {
 	NoUpdate                  int8      `description:"是否停止更新,0:继续更新;1:停止更新"`
 }
 
+func (e *EdbInfoCalculateMappingInfo) Insert() (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Insert(e)
+	return
+}
+
 // GetEdbInfoCalculateMappingListByEdbInfoId 根据生成的指标id获取来源的指标id列表
 func GetEdbInfoCalculateMappingListByEdbInfoId(edbInfoId int) (items []*EdbInfoCalculateMappingInfo, err error) {
 	o := orm.NewOrmUsingDB("data")

+ 7 - 0
models/data_manage/stl/calculate_stl_config.go

@@ -19,3 +19,10 @@ func (c *CalculateStlConfig) Insert() (insertId int64, err error) {
 	insertId, err = o.Insert(c)
 	return
 }
+
+func GetCalculateStlConfigById(id int) (item *CalculateStlConfig, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := "SELECT * FROM calculate_stl_config WHERE calculate_stl_config_id =?"
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}

+ 32 - 0
models/data_manage/stl/edb_data_calculate_stl.go

@@ -0,0 +1,32 @@
+package stl
+
+import (
+	"eta/eta_api/utils"
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type EdbDataCalculateStl struct {
+	EdbDataId     int       `orm:"pk"`
+	EdbInfoId     int       `description:"指标id"`
+	EdbCode       string    `description:"指标编码"`
+	DataTime      time.Time `description:"数据时间"`
+	Value         float64   `description:"数据值"`
+	CreateTime    time.Time `description:"创建时间"`
+	ModifyTime    time.Time `description:"修改时间"`
+	DataTimestamp int64     `description:"数据时间戳"`
+}
+
+func (m *EdbDataCalculateStl) GetMaxId() (maxId int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT max(edb_data_id) id FROM edb_data_calculate_stl limit 1`
+	err = o.Raw(sql).QueryRow(&maxId)
+	return
+}
+
+func (m *EdbDataCalculateStl) BatchInsert(dataList []*EdbDataCalculateStl) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.InsertMulti(utils.MultiAddNum, dataList)
+	return
+}

+ 2 - 1
models/data_manage/stl/request/stl.go

@@ -20,8 +20,9 @@ type StlConfigReq struct {
 type SaveStlEdbInfoReq struct {
 	CalculateStlConfigId int    `description:"计算的STL配置ID"`
 	EdbInfoId            int    `description:"指标ID"`
+	StlEdbType           int    `description:"stl指标类型: 1-Trend, 2-Seasonal, 3-Residual"`
 	Frequency            string `description:"频度"`
-	Uint                 string `description:"单位"`
+	Unit                 string `description:"单位"`
 	EdbName              string `description:"指标名称"`
 	ClassifyId           int    `description:"分类ID"`
 }

+ 18 - 0
routers/commentsRouter.go

@@ -2311,6 +2311,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/stl:STLController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/stl:STLController"],
+        beego.ControllerComments{
+            Method: "SaveConf",
+            Router: `/config/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/stl:STLController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/stl:STLController"],
+        beego.ControllerComments{
+            Method: "SaveStlEdbInfo",
+            Router: `/edb_info/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/stl:STLController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/stl:STLController"],
         beego.ControllerComments{
             Method: "EdbInfoFilterByEs",

+ 1 - 0
services/data/edb_info.go

@@ -1836,6 +1836,7 @@ func EdbInfoAdd(source, subSource, classifyId int, edbCode, edbName, frequency,
 		utils.DATA_SOURCE_SCI_HQ:              "卓创红期",
 		utils.DATA_SOURCE_LY:                  "粮油商务网",
 		utils.DATA_SOURCE_TRADE_ANALYSIS:      "持仓分析",
+		utils.DATA_SOURCE_CALCULATE_STL:       "STL趋势分解",
 	}
 
 	sourceName, ok := sourceNameMap[source]

+ 261 - 8
services/data/stl/stl.go

@@ -2,10 +2,12 @@ package stl
 
 import (
 	"encoding/json"
+	"errors"
 	"eta/eta_api/models/data_manage"
 	"eta/eta_api/models/data_manage/stl"
 	"eta/eta_api/models/data_manage/stl/request"
 	"eta/eta_api/models/data_manage/stl/response"
+	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/data_manage_permission"
 	"eta/eta_api/services/elastic"
 	"eta/eta_api/utils"
@@ -161,9 +163,9 @@ func GenerateStlEdbData(req *request.StlConfigReq, adminId int) (resp *response.
 	resp.EvaluationResult.AdfPValue = strconv.FormatFloat(result.AdfPValue, 'f', -1, 64)
 	resp.EvaluationResult.LjungBoxPValue = strconv.FormatFloat(result.LbTestPValue, 'f', -1, 64)
 
-	utils.Rc.Put(EDB_DATA_CALCULATE_STL_TREND_CACHE+strconv.Itoa(req.CalculateStlConfigId)+":"+resp.TrendChartInfo.Title, trendChart, time.Hour)
-	utils.Rc.Put(EDB_DATA_CALCULATE_STL_TREND_CACHE+strconv.Itoa(req.CalculateStlConfigId)+":"+resp.SeasonalChartInfo.Title, seasonalChart, time.Hour)
-	utils.Rc.Put(EDB_DATA_CALCULATE_STL_TREND_CACHE+strconv.Itoa(req.CalculateStlConfigId)+":"+resp.ResidualChartInfo.Title, residualChart, time.Hour)
+	utils.Rc.Put(EDB_DATA_CALCULATE_STL_TREND_CACHE+strconv.Itoa(req.CalculateStlConfigId), trendChart, time.Hour)
+	utils.Rc.Put(EDB_DATA_CALCULATE_STL_SEASONAL_CACHE+strconv.Itoa(req.CalculateStlConfigId), seasonalChart, time.Hour)
+	utils.Rc.Put(EDB_DATA_CALCULATE_STL_RESIDUAL_CACHE+strconv.Itoa(req.CalculateStlConfigId), residualChart, time.Hour)
 
 	return
 }
@@ -398,11 +400,6 @@ func SearchEdbInfoWithStl(adminId int, keyWord string, currentIndex, pageSize in
 	isEs := false
 	var total int64
 	if keyWord != "" {
-		var keyWordArr []string
-		keyWordArr = append(keyWordArr, keyWord)
-
-		newKeyWord := strings.Split(keyWord, " ")
-		keyWordArr = append(keyWordArr, newKeyWord...)
 		frequencyList := []string{"日度", "周度", "旬度", "月度", "季度"}
 
 		// 普通的搜索
@@ -525,3 +522,259 @@ func SearchEdbInfoWithStl(adminId int, keyWord string, currentIndex, pageSize in
 	}
 	return
 }
+
+func SaveStlEdbInfo(req *request.SaveStlEdbInfoReq, adminId int, adminRealName, lang string) (isSendEmail bool, msg string, err error) {
+	conf, err := stl.GetCalculateStlConfigById(req.CalculateStlConfigId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			msg = "未找到配置,请先进行计算"
+			err = fmt.Errorf("配置不存在")
+			return
+		}
+		msg = "获取失败"
+		return
+	}
+	var edbInfoData []*response.EdbData
+	switch req.StlEdbType {
+	case 1:
+		// 趋势指标
+		if ok := utils.Rc.IsExist(EDB_DATA_CALCULATE_STL_TREND_CACHE + strconv.Itoa(req.CalculateStlConfigId)); ok {
+			msg = "计算已过期,请重新计算"
+			err = fmt.Errorf("not found")
+			return
+		}
+		trendData, er := utils.Rc.RedisBytes(EDB_DATA_CALCULATE_STL_TREND_CACHE + strconv.Itoa(req.CalculateStlConfigId))
+		if er != nil {
+			msg = "获取失败"
+			err = fmt.Errorf("获取redis数据失败,Err:" + er.Error())
+			return
+		}
+		if er := json.Unmarshal(trendData, &edbInfoData); er != nil {
+			msg = "获取失败"
+			err = fmt.Errorf("json解析失败,Err:" + er.Error())
+			return
+		}
+	case 2:
+		// 季节性指标
+		if ok := utils.Rc.IsExist(EDB_DATA_CALCULATE_STL_SEASONAL_CACHE + strconv.Itoa(req.CalculateStlConfigId)); ok {
+			msg = "计算已过期,请重新计算"
+			err = fmt.Errorf("not found")
+			return
+		}
+		seasonalData, er := utils.Rc.RedisBytes(EDB_DATA_CALCULATE_STL_SEASONAL_CACHE + strconv.Itoa(req.CalculateStlConfigId))
+		if er != nil {
+			msg = "获取失败"
+			err = fmt.Errorf("获取redis数据失败,Err:" + er.Error())
+			return
+		}
+		if er := json.Unmarshal(seasonalData, &edbInfoData); er != nil {
+			msg = "获取失败"
+			err = fmt.Errorf("json解析失败,Err:" + er.Error())
+			return
+		}
+	case 3:
+		// 残差性指标
+		if ok := utils.Rc.IsExist(EDB_DATA_CALCULATE_STL_RESIDUAL_CACHE + strconv.Itoa(req.CalculateStlConfigId)); ok {
+			msg = "计算已过期,请重新计算"
+			err = fmt.Errorf("not found")
+			return
+		}
+		residualData, er := utils.Rc.RedisBytes(EDB_DATA_CALCULATE_STL_RESIDUAL_CACHE + strconv.Itoa(req.CalculateStlConfigId))
+		if er != nil {
+			msg = "获取失败"
+			err = fmt.Errorf("获取redis数据失败,Err:" + er.Error())
+			return
+		}
+		if er := json.Unmarshal(residualData, &edbInfoData); er != nil {
+			msg = "获取失败"
+			err = fmt.Errorf("json解析失败,Err:" + er.Error())
+			return
+		}
+	}
+
+	indexObj := new(stl.EdbDataCalculateStl)
+	edbCode, err := utils.GenerateEdbCode(1, "stl")
+	if err != nil {
+		msg = "生成指标代码失败"
+		return
+	}
+	var dataList []*stl.EdbDataCalculateStl
+	var startDate, endDate time.Time
+	for _, v := range edbInfoData {
+		dataTime, _ := time.Parse(utils.FormatDate, v.DataTime)
+		value, _ := strconv.ParseFloat(v.Value, 64)
+		if startDate.IsZero() || dataTime.Before(startDate) {
+			startDate = dataTime
+		}
+		if endDate.IsZero() || dataTime.After(endDate) {
+			endDate = dataTime
+		}
+		dataList = append(dataList, &stl.EdbDataCalculateStl{
+			EdbInfoId:     req.EdbInfoId,
+			EdbCode:       edbCode,
+			DataTime:      dataTime,
+			Value:         value,
+			CreateTime:    time.Now(),
+			ModifyTime:    time.Now(),
+			DataTimestamp: time.Now().UnixMilli(),
+		})
+	}
+	err = indexObj.BatchInsert(dataList)
+	if err != nil {
+		msg = "保存失败"
+		return
+	}
+
+	startDateStr := startDate.Format(utils.FormatDate)
+	endDateStr := endDate.Format(utils.FormatDate)
+
+	//判断指标名称是否存在
+	ok, err := CheckDulplicateEdbInfoName(req.EdbName, lang)
+	if err != nil {
+		msg = "保存失败"
+		return
+	}
+	if ok {
+		msg = "指标名称已存在"
+		err = fmt.Errorf("指标名称已存在")
+		return
+	}
+
+	source := utils.DATA_SOURCE_CALCULATE_STL
+	subSource := utils.DATA_SUB_SOURCE_EDB
+	edbInfo := new(data_manage.EdbInfo)
+	//获取该层级下最大的排序数
+	maxSort, err := data.GetEdbClassifyMaxSort(req.ClassifyId, 0)
+	if err != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("获取最大排序失败,Err:" + err.Error())
+		return
+	}
+
+	edbInfo.EdbCode = edbCode
+	edbInfo.EdbName = req.EdbName
+	edbInfo.EdbNameEn = req.EdbName
+	edbInfo.EdbNameSource = req.EdbName
+	edbInfo.Frequency = req.Frequency
+	edbInfo.Unit = req.Unit
+	edbInfo.UnitEn = req.Unit
+	edbInfo.StartDate = startDateStr
+	edbInfo.EndDate = endDateStr
+	edbInfo.CalculateFormula = conf.Config
+	edbInfo.ClassifyId = req.ClassifyId
+	edbInfo.SysUserId = adminId
+	edbInfo.SysUserRealName = adminRealName
+	edbInfo.CreateTime = time.Now()
+	edbInfo.ModifyTime = time.Now()
+	edbInfo.Sort = maxSort + 1
+	edbInfo.DataDateType = `交易日`
+	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	edbInfo.UniqueCode = utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
+	itemVal, err := data_manage.GetEdbInfoMaxAndMinInfo(source, subSource, edbCode)
+	if itemVal != nil && err == nil {
+		edbInfo.MaxValue = itemVal.MaxValue
+		edbInfo.MinValue = itemVal.MinValue
+	}
+	edbInfo.EdbType = 2
+	extra, _ := json.Marshal(req)
+	edbInfo.Extra = string(extra)
+	edbInfoId, err := data_manage.AddEdbInfo(edbInfo)
+	if err != nil {
+		msg = "保存失败"
+		err = errors.New("保存失败,Err:" + err.Error())
+		return
+	}
+	edbInfo.EdbInfoId = int(edbInfoId)
+	//保存数据
+	data_manage.ModifyEdbInfoDataStatus(edbInfoId, source, subSource, edbCode)
+
+	maxAndMinItem, _ := data_manage.GetEdbInfoMaxAndMinInfo(source, subSource, edbCode)
+	if maxAndMinItem != nil {
+		err = data_manage.ModifyEdbInfoMaxAndMinInfo(int(edbInfoId), maxAndMinItem)
+		if err != nil {
+			msg = "保存失败"
+			err = errors.New("保存失败,Err:" + err.Error())
+			return
+		}
+	}
+	// 保存配置映射
+	{
+		stlMapping := new(stl.CalculateStlConfigMapping)
+		stlMapping.EdbInfoId = int(edbInfoId)
+		stlMapping.CalculateStlConfigId = req.CalculateStlConfigId
+		stlMapping.CreateTime = time.Now()
+		stlMapping.ModifyTime = time.Now()
+		_, err = stlMapping.Insert()
+		if err != nil {
+			msg = "保存失败"
+			err = errors.New("保存配置映射失败,Err:" + err.Error())
+			return
+		}
+	}
+	// 保存溯源信息
+	{
+		fromEdbInfo, er := data_manage.GetEdbInfoById(req.EdbInfoId)
+		if er != nil {
+			if er.Error() == utils.ErrNoRow() {
+				msg = "未找到指标,请刷新后重试"
+				err = fmt.Errorf("指标不存在,err:" + er.Error())
+				return
+			}
+			msg = "获取失败"
+			err = er
+			return
+		}
+
+		edbCalculateMappingInfo := new(data_manage.EdbInfoCalculateMappingInfo)
+		edbCalculateMappingInfo.EdbInfoId = int(edbInfoId)
+		edbCalculateMappingInfo.Source = source
+		edbCalculateMappingInfo.SourceName = "STL趋势分解"
+		edbCalculateMappingInfo.EdbCode = edbCode
+		edbCalculateMappingInfo.FromEdbInfoId = req.EdbInfoId
+		edbCalculateMappingInfo.FromEdbCode = fromEdbInfo.EdbCode
+		edbCalculateMappingInfo.FromEdbName = fromEdbInfo.EdbName
+		edbCalculateMappingInfo.FromSource = fromEdbInfo.Source
+		edbCalculateMappingInfo.FromSourceName = fromEdbInfo.SourceName
+		edbCalculateMappingInfo.FromEdbType = fromEdbInfo.EdbType
+		edbCalculateMappingInfo.FromEdbInfoType = fromEdbInfo.EdbInfoType
+		edbCalculateMappingInfo.FromClassifyId = fromEdbInfo.ClassifyId
+		edbCalculateMappingInfo.FromUniqueCode = fromEdbInfo.UniqueCode
+		edbCalculateMappingInfo.CreateTime = time.Now()
+		edbCalculateMappingInfo.ModifyTime = time.Now()
+		err = edbCalculateMappingInfo.Insert()
+		if err != nil {
+			msg = "保存失败"
+			err = errors.New("保存溯源信息失败,Err:" + err.Error())
+			return
+		}
+	}
+
+	//添加es
+	data.AddOrEditEdbInfoToEs(int(edbInfoId))
+	return
+}
+
+func CheckDulplicateEdbInfoName(edbName, lang string) (ok bool, err error) {
+	var count int
+	var condition string
+	var pars []interface{}
+
+	switch lang {
+	case utils.EnLangVersion:
+		condition += " AND edb_name_en = ? "
+	default:
+		condition += " AND edb_name=? "
+	}
+	pars = append(pars, edbName)
+
+	count, err = data_manage.GetEdbInfoCountByCondition(condition, pars)
+	if err != nil {
+		return
+	}
+
+	if count > 0 {
+		ok = true
+		return
+	}
+	return
+}

+ 1 - 0
utils/constants.go

@@ -184,6 +184,7 @@ const (
 	DATA_SOURCE_LY                                   = 91       // 粮油商务网
 	DATA_SOURCE_TRADE_ANALYSIS                       = 92       // 持仓分析
 	DATA_SOURCE_HISUGAR                              = 93       // 泛糖科技 -> 93
+	DATA_SOURCE_CALCULATE_STL                        = 98       // STL趋势分解 -> 98
 )
 
 // 数据刷新频率