Browse Source

拟合残差

gmy 5 months ago
parent
commit
84b7af7c9e

+ 139 - 1
controllers/residual_analysis/residual_analysis.go

@@ -85,7 +85,145 @@ func (this *ResidualAnalysisController) ContrastPreview() {
 		return
 	}
 
-	residual_analysis_service.ContrastPreview(IndexCode)
+	resp, err := residual_analysis_service.ContrastPreview(IndexCode)
+	if err != nil {
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// SaveResidualAnalysis
+// @Title 保存残差分析指标
+// @Description 保存残差分析指标
+// @Param
+// @Success
+// @router /save/residual/analysis [post]
+func (this *ResidualAnalysisController) SaveResidualAnalysis() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req residual_analysis_model.ResidualAnalysisIndexSaveReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ClassifyId == 0 {
+		br.Msg = "分类id不能为空"
+		br.ErrMsg = "分类id不能为空"
+		return
+	}
+
+	err = residual_analysis_service.SaveResidualAnalysis(req, sysUser)
+	if err != nil {
+		br.Ret = 408
+		br.Msg = "获取失败"
+		br.ErrMsg = err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "添加成功"
+}
+
+// SaveResidualAnalysisConfig
+// @Title 保存残差指标配置
+// @Description 保存残差指标配置
+// @Param
+// @Success
+// @router /save/residual/analysis/config [post]
+func (this *ResidualAnalysisController) SaveResidualAnalysisConfig() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req residual_analysis_model.ResidualAnalysisIndexSaveReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ClassifyId == 0 {
+		br.Msg = "分类id不能为空"
+		br.ErrMsg = "分类id不能为空"
+		return
+	}
+
+	err = residual_analysis_service.SaveResidualAnalysis(req, sysUser)
+	if err != nil {
+		br.Ret = 408
+		br.Msg = "获取失败"
+		br.ErrMsg = err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "添加成功"
+}
+
+// ResidualAnalysisDetail
+// @Title 残差分析指标详情
+// @Description 残差分析指标详情
+// @Param
+// @Success
+// @router /residual/analysis/detail [get]
+func (this *ResidualAnalysisController) ResidualAnalysisDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	EdbInfoId, err := this.GetInt("EdbInfoId")
+	if err != nil {
+		br.Msg = "EdbInfoId参数异常!"
+		br.ErrMsg = "EdbInfoId参数解析失败,Err:" + err.Error()
+	}
+	if EdbInfoId <= 0 {
+		br.Msg = "EdbInfoId参数异常!"
+		br.ErrMsg = "EdbInfoId参数异常!"
+	}
+
+	residual_analysis_service.ResidualAnalysisDetail(EdbInfoId)
 
 	br.Ret = 200
 	br.Success = true

+ 15 - 0
models/residual_analysis_model/calculate_residual_analysis_config.go

@@ -104,3 +104,18 @@ type ResidualAnalysisChartEdbInfoMapping struct {
 	MaxValue            float64 `json:"-" description:"最大值"`
 	DataList            interface{}
 }
+
+type ResidualAnalysisIndexSaveReq struct {
+	EdbCode      string                 `description:"指标编码"`
+	EdbName      string                 `description:"指标名称"`
+	EdbNameEn    string                 `description:"英文指标名称"`
+	EdbType      int                    `description:"指标类型:1:基础指标,2:计算指标"`
+	Frequency    string                 `description:"频率"`
+	FrequencyEn  string                 `description:"英文频率"`
+	Unit         string                 `description:"单位"`
+	UnitEn       string                 `description:"英文单位"`
+	ClassifyId   int                    `description:"分类id"`
+	ConfigId     int                    `description:"残差配置id"`
+	ResidualType int                    `orm:"column(residual_type)" description:"残差类型: 1-映射残差 2-拟合残差"`
+	DataList     []ResidualAnalysisData `description:"指标数据"`
+}

+ 31 - 1
models/residual_analysis_model/calculate_residual_analysis_config_mapping.go

@@ -5,7 +5,7 @@ import "github.com/beego/beego/v2/client/orm"
 type CalculateResidualAnalysisConfigMapping struct {
 	CalculateResidualAnalysisConfigMappingId int    `orm:"column(calculate_residual_analysis_config_mapping_id);pk;auto" description:"自增id"`
 	CalculateResidualAnalysisConfigId        int    `orm:"column(calculate_residual_analysis_config_id)" description:"残差分析配置id"`
-	EdbInfoId                                int    `orm:"column(edb_info_id)" description:"指标id"`
+	EdbInfoId                                int64  `orm:"column(edb_info_id)" description:"指标id"`
 	ResidualType                             int    `orm:"column(residual_type)" description:"残差类型: 1-映射残差 2-拟合残差"`
 	CreateTime                               string `orm:"column(create_time)" description:"创建时间"`
 	ModifyTime                               string `orm:"column(modify_time)" description:"修改时间"`
@@ -14,3 +14,33 @@ type CalculateResidualAnalysisConfigMapping struct {
 func init() {
 	orm.RegisterModel(new(CalculateResidualAnalysisConfigMapping))
 }
+
+// GetConfigMappingListByConfigId 根据配置配置id查询配置信息
+func GetConfigMappingListByConfigId(configId int) (items []CalculateResidualAnalysisConfigMapping, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `select * from calculate_residual_analysis_config_mapping where calculate_residual_analysis_config_id = ?`
+
+	_, err = o.Raw(sql, configId).QueryRows(&items)
+	return items, nil
+}
+
+// GetConfigMappingListByCondition 通过条件查询指标配置映射
+func GetConfigMappingListByCondition(condition string, pars []interface{}) (items []CalculateResidualAnalysisConfigMapping, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `select * from calculate_residual_analysis_config_mapping where 1=1 `
+
+	sql += condition
+
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return items, nil
+}
+
+// SaveConfigMapping 保存指标和配置的映射关系
+func SaveConfigMapping(mapping CalculateResidualAnalysisConfigMapping) (id int64, err error) {
+	o := orm.NewOrm()
+	id, err = o.Insert(mapping)
+	if err != nil {
+		return 0, err
+	}
+	return id, nil
+}

+ 19 - 0
models/residual_analysis_model/edb_data_residual_analysis.go

@@ -14,3 +14,22 @@ type ResidualAnalysisData struct {
 func init() {
 	orm.RegisterModel(new(ResidualAnalysisData))
 }
+
+// DeleteResidualAnalysisDataByEdbCode 根据指标编码删除数据
+func DeleteResidualAnalysisDataByEdbCode(edbCode string) error {
+	o := orm.NewOrmUsingDB("data")
+	sql := `delete from edb_data_residual_analysis where edb_code = ?`
+	_, err := o.Raw(sql, edbCode).Exec()
+	return err
+}
+
+// AddResidualAnalysisData 新增指标数据
+func AddResidualAnalysisData(dataList []ResidualAnalysisData) (num int64, err error) {
+	o := orm.NewOrmUsingDB("data")
+	num, err = o.InsertMulti(len(dataList), dataList)
+	if err != nil {
+		return 0, err
+	}
+
+	return num, nil
+}

+ 132 - 0
services/residual_analysis_service/residual_analysis_service.go

@@ -3,6 +3,7 @@ package residual_analysis_service
 import (
 	"eta/eta_api/models/data_manage"
 	"eta/eta_api/models/residual_analysis_model"
+	"eta/eta_api/models/system"
 	"eta/eta_api/utils"
 	"fmt"
 	"time"
@@ -300,3 +301,134 @@ func ContrastPreview(indexCode string) (residual_analysis_model.ResidualAnalysis
 	resp.DataList = dataList
 	return resp, nil
 }
+
+func SaveResidualAnalysis(req residual_analysis_model.ResidualAnalysisIndexSaveReq, sysUser *system.Admin) error {
+
+	// 验证分类是否存在
+	classifyCount, err := data_manage.GetEdbClassifyCountById(req.ClassifyId)
+	if err != nil {
+		return err
+	}
+	if classifyCount <= 0 {
+		return fmt.Errorf("分类不存在", nil)
+	}
+
+	// 更新or新增
+	if req.EdbCode != "" {
+		// 查询指标库指标
+		edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_RESIDUAL_ANALYSIS, req.EdbCode)
+		if err != nil {
+			return err
+		}
+		if edbInfo == nil {
+			return fmt.Errorf("指标不存在", nil)
+		}
+		// todo 须补充更新指标最大值,最小值,数据最新时间,
+		err = edbInfo.Update([]string{"min_value", "max_value", "latest_date", "latest_value"})
+		if err != nil {
+			return err
+		}
+
+		// 删除对应得指标数据
+		err = residual_analysis_model.DeleteResidualAnalysisDataByEdbCode(req.EdbCode)
+		if err != nil {
+			return fmt.Errorf("删除指标数据失败", nil)
+		}
+	}
+	// 新增指标
+	edbCode, err := utils.GenerateEdbCode(1, "")
+	if err != nil {
+		return err
+	}
+
+	_, err = data_manage.AddEdbInfo(&data_manage.EdbInfo{
+		EdbCode:    edbCode,
+		EdbName:    req.EdbName,
+		EdbNameEn:  req.EdbNameEn,
+		EdbType:    req.EdbType,
+		Unit:       req.Unit,
+		UnitEn:     req.UnitEn,
+		Frequency:  req.Frequency,
+		Source:     utils.DATA_SOURCE_RESIDUAL_ANALYSIS,
+		SourceName: "残差分析",
+	})
+	if err != nil {
+		return err
+	}
+
+	// 新增数据
+	edbInfoId, err := residual_analysis_model.AddResidualAnalysisData(req.DataList)
+	if err != nil {
+		return err
+	}
+
+	// 更新保存指标和配置的映射关系
+	mappingList, err := residual_analysis_model.GetConfigMappingListByConfigId(req.ConfigId)
+	if err != nil {
+		return err
+	}
+	flag := true
+	for _, mapping := range mappingList {
+		if mapping.CalculateResidualAnalysisConfigId == req.ConfigId {
+			flag = false
+		}
+	}
+
+	if flag {
+		_, err = residual_analysis_model.SaveConfigMapping(residual_analysis_model.CalculateResidualAnalysisConfigMapping{
+			CalculateResidualAnalysisConfigId: req.ConfigId,
+			EdbInfoId:                         edbInfoId,
+			ResidualType:                      req.ResidualType,
+		})
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func ResidualAnalysisDetail(edbInfoId int) ([]*data_manage.EdbInfoList, error) {
+	// 通过指标配置映射表 拿到配置id,再获取关联的所有指标信息
+	var condition string
+	var pars []interface{}
+
+	condition += " and edb_info_id=?"
+	pars = append(pars, edbInfoId)
+
+	mappingList, err := residual_analysis_model.GetConfigMappingListByCondition(condition, pars)
+	if err != nil {
+		return []*data_manage.EdbInfoList{}, err
+	}
+
+	if len(mappingList) <= 0 {
+		return []*data_manage.EdbInfoList{}, fmt.Errorf("指标不存在", nil)
+	}
+
+	mapping := mappingList[0]
+
+	configMappingList, err := residual_analysis_model.GetConfigMappingListByConfigId(mapping.CalculateResidualAnalysisConfigId)
+	if err != nil {
+		return []*data_manage.EdbInfoList{}, err
+	}
+
+	var edbInfoIdList []int64
+	for _, v := range configMappingList {
+		edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
+	}
+
+	condition = ""
+	pars = []interface{}{}
+
+	condition += ` and edb_info_id in(` + utils.GetOrmInReplace(len(edbInfoIdList)) + `)`
+	for _, id := range edbInfoIdList {
+		pars = append(pars, id)
+	}
+
+	edbInfoList, err := data_manage.GetEdbInfoListByCond(condition, pars)
+	if err != nil {
+		return []*data_manage.EdbInfoList{}, err
+	}
+
+	return edbInfoList, nil
+}

+ 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_RESIDUAL_ANALYSIS                    = 99       // 残差分析
 )
 
 // 数据刷新频率