package data_manage import ( "encoding/json" "eta/eta_api/controllers" "eta/eta_api/models" "eta/eta_api/models/data_manage" "eta/eta_api/models/data_manage/request" "eta/eta_api/services/data" correlationServ "eta/eta_api/services/data/correlation" "eta/eta_api/utils" "fmt" "sort" "strconv" "strings" "sync" "time" ) // FactorEdbSeriesController 因子指标系列 type FactorEdbSeriesController struct { controllers.BaseAuthController } // CalculateFuncList // @Title 计算方式列表 // @Description 计算方式列表 // @Param EdbInfoType query int false "指标计算类型: 0-普通指标; 1-预测指标" // @Success Ret=200 操作成功 // @router /factor_edb_series/calculate_func/list [get] func (this *FactorEdbSeriesController) CalculateFuncList() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } edbInfoType, _ := this.GetInt("EdbInfoType", 0) funcOb := new(data_manage.FactorEdbSeriesCalculateFunc) cond := fmt.Sprintf(` AND %s = ?`, funcOb.Cols().EdbInfoType) pars := make([]interface{}, 0) pars = append(pars, edbInfoType) list, e := funcOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", funcOb.Cols().PrimaryId)) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取计算方式列表失败, Err: %v", e) return } resp := make([]*data_manage.FactorEdbSeriesCalculateFuncItem, 0) for _, v := range list { resp = append(resp, v.Format2Item()) } br.Data = resp br.Ret = 200 br.Success = true br.Msg = "获取成功" } // Add // @Title 新增 // @Description 新增 // @Param request body request.AddFactorEdbSeriesReq true "type json string" // @Success Ret=200 操作成功 // @router /factor_edb_series/add [post] func (this *FactorEdbSeriesController) Add() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } 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 request.AddFactorEdbSeriesReq if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil { br.Msg = "参数解析异常" br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e) return } req.SeriesName = strings.TrimSpace(req.SeriesName) if req.SeriesName == "" { br.Msg = "请输入指标系列名称" return } if len(req.EdbInfoIds) <= 0 { br.Msg = "请选择因子指标系列" return } if len(req.EdbInfoIds) > 100 { br.Msg = "添加指标总数量不得超过100" return } calculateLen := len(req.Calculates) if calculateLen > 5 { br.Msg = "计算公式不可超过5个" return } var calculatesJson string if calculateLen > 0 { b, e := json.Marshal(req.Calculates) if e != nil { br.Msg = "计算方式格式有误" br.ErrMsg = "解析计算方式参数失败, Err: " + e.Error() return } calculatesJson = string(b) for _, v := range req.Calculates { switch v.Source { case utils.EdbBaseCalculateNszydpjjs, utils.EdbBaseCalculateHbz, utils.EdbBaseCalculateHcz, utils.EdbBaseCalculateCjjx: if v.Formula == nil { br.Msg = "请输入N值" return } formula, ok := v.Formula.(string) if !ok { br.Msg = "N值格式有误" return } formulaInt, _ := strconv.Atoi(formula) if formulaInt <= 0 { br.Msg = "N值不可小于0, 重新输入" return } case utils.EdbBaseCalculateExponentialSmoothing: if v.Formula == nil { br.Msg = "请填写alpha值" return } formula, ok := v.Formula.(string) if !ok { br.Msg = "alpha值格式有误" return } alpha, _ := strconv.ParseFloat(formula, 64) if alpha <= 0 || alpha >= 1 { br.Msg = "alpha值应在0-1之间, 请重新输入" return } } } } edbArr, e := data_manage.GetEdbInfoByIdList(req.EdbInfoIds) if e != nil { br.Msg = "操作失败" br.ErrMsg = "获取指标列表失败, Err: " + e.Error() return } if len(edbArr) == 0 { br.Msg = "因子指标系列有误" br.ErrMsg = "因子指标系列长度为0" return } // 新增指标系列 seriesItem := new(data_manage.FactorEdbSeries) seriesItem.SeriesName = req.SeriesName seriesItem.EdbInfoType = req.EdbInfoType seriesItem.CreateTime = time.Now().Local() seriesItem.ModifyTime = time.Now().Local() if calculateLen > 0 { seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculating seriesItem.CalculateStep = calculatesJson } mappings := make([]*data_manage.FactorEdbSeriesMapping, 0) for _, v := range edbArr { mappings = append(mappings, &data_manage.FactorEdbSeriesMapping{ EdbInfoId: v.EdbInfoId, EdbCode: v.EdbCode, CreateTime: time.Now().Local(), ModifyTime: time.Now().Local(), }) } seriesId, e := seriesItem.CreateSeriesAndMapping(seriesItem, mappings) if e != nil { br.Msg = "操作失败" br.ErrMsg = "新增因子指标系列失败, Err: " + e.Error() return } // 计算指标数据 var calculateResp data_manage.FactorEdbSeriesStepCalculateResp if calculateLen > 0 { calculateResp, e = data.FactorEdbStepCalculate(seriesId, edbArr, req.Calculates, this.Lang, false) if e != nil { br.Msg = "操作失败" br.ErrMsg = "计算因子指标失败, Err: " + e.Error() return } // 更新系列计算状态 cols := []string{seriesItem.Cols().CalculateState, seriesItem.Cols().ModifyTime} seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculated seriesItem.ModifyTime = time.Now().Local() if e = seriesItem.Update(cols); e != nil { br.Msg = "操作失败" br.ErrMsg = "更新因子指标系列计算状态失败, Err: " + e.Error() return } } else { for _, v := range edbArr { calculateResp.Success = append(calculateResp.Success, data_manage.FactorEdbSeriesStepCalculateResult{ EdbInfoId: v.EdbInfoId, EdbCode: v.EdbCode, Msg: "保存成功", }) } } calculateResp.SeriesId = seriesId br.Data = calculateResp br.Ret = 200 br.Success = true br.Msg = "操作成功" br.IsAddLog = true } // Edit // @Title 编辑 // @Description 编辑 // @Param request body request.EditFactorEdbSeriesReq true "type json string" // @Success Ret=200 操作成功 // @router /factor_edb_series/edit [post] func (this *FactorEdbSeriesController) Edit() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } 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 request.EditFactorEdbSeriesReq if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil { br.Msg = "参数解析异常" br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e) return } if req.SeriesId <= 0 { br.Msg = "参数有误" br.ErrMsg = fmt.Sprintf("参数有误, SeriesId: %d", req.SeriesId) return } req.SeriesName = strings.TrimSpace(req.SeriesName) if req.SeriesName == "" { br.Msg = "请输入指标系列名称" return } if len(req.EdbInfoIds) <= 0 { br.Msg = "请选择因子指标系列" return } if len(req.EdbInfoIds) > 100 { br.Msg = "添加指标总数量不得超过100" return } calculateLen := len(req.Calculates) if calculateLen > 5 { br.Msg = "计算公式不可超过5个" return } var calculatesJson string if calculateLen > 0 { b, e := json.Marshal(req.Calculates) if e != nil { br.Msg = "计算方式格式有误" br.ErrMsg = "解析计算方式参数失败, Err: " + e.Error() return } calculatesJson = string(b) for _, v := range req.Calculates { switch v.Source { case utils.EdbBaseCalculateNszydpjjs, utils.EdbBaseCalculateHbz, utils.EdbBaseCalculateHcz, utils.EdbBaseCalculateCjjx: if v.Formula == nil { br.Msg = "请输入N值" return } formula, ok := v.Formula.(string) if !ok { br.Msg = "N值格式有误" return } formulaInt, _ := strconv.Atoi(formula) if formulaInt <= 0 { br.Msg = "N值不可小于0, 重新输入" return } case utils.EdbBaseCalculateExponentialSmoothing: if v.Formula == nil { br.Msg = "请填写alpha值" return } formula, ok := v.Formula.(string) if !ok { br.Msg = "alpha值格式有误" return } alpha, _ := strconv.ParseFloat(formula, 64) if alpha <= 0 || alpha >= 1 { br.Msg = "alpha值应在0-1之间, 请重新输入" return } } } } seriesOb := new(data_manage.FactorEdbSeries) seriesItem, e := seriesOb.GetItemById(req.SeriesId) if e != nil { if e.Error() == utils.ErrNoRow() { br.Msg = "该因子指标系列不存在" return } br.Msg = "获取失败" br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error() return } edbArr, e := data_manage.GetEdbInfoByIdList(req.EdbInfoIds) if e != nil { br.Msg = "操作失败" br.ErrMsg = "获取指标列表失败, Err: " + e.Error() return } if len(edbArr) == 0 { br.Msg = "因子指标系列有误" br.ErrMsg = "因子指标系列长度为0" return } var calculateResp data_manage.FactorEdbSeriesStepCalculateResp calculateResp.SeriesId = seriesItem.FactorEdbSeriesId // 如果不需要进行重新计算(比如只改了系列名称)那么只更新指标系列 seriesItem.SeriesName = req.SeriesName seriesItem.EdbInfoType = req.EdbInfoType seriesItem.ModifyTime = time.Now().Local() updateCols := []string{seriesOb.Cols().SeriesName, seriesOb.Cols().EdbInfoType, seriesOb.Cols().ModifyTime} if !req.Recalculate { if e = seriesItem.Update(updateCols); e != nil { br.Msg = "操作成功" br.ErrMsg = "更新因子指标系列信息失败, Err: " + e.Error() return } for _, v := range edbArr { calculateResp.Success = append(calculateResp.Success, data_manage.FactorEdbSeriesStepCalculateResult{ EdbInfoId: v.EdbInfoId, EdbCode: v.EdbCode, Msg: "保存成功", }) } br.Data = calculateResp br.Ret = 200 br.Success = true br.Msg = "操作成功" return } // 更新系列信息和指标关联 if calculateLen > 0 { seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculating seriesItem.CalculateStep = calculatesJson updateCols = append(updateCols, seriesOb.Cols().CalculateState, seriesOb.Cols().CalculateStep) } mappings := make([]*data_manage.FactorEdbSeriesMapping, 0) for _, v := range edbArr { mappings = append(mappings, &data_manage.FactorEdbSeriesMapping{ EdbInfoId: v.EdbInfoId, EdbCode: v.EdbCode, CreateTime: time.Now().Local(), ModifyTime: time.Now().Local(), }) } if e = seriesItem.EditSeriesAndMapping(seriesItem, mappings, updateCols); e != nil { br.Msg = "操作失败" br.ErrMsg = "编辑因子指标系列失败, Err: " + e.Error() return } // 重新计算 calculateResp, e = data.FactorEdbStepCalculate(seriesItem.FactorEdbSeriesId, edbArr, req.Calculates, this.Lang, req.Recalculate) if e != nil { br.Msg = "操作失败" br.ErrMsg = "计算因子指标失败, Err: " + e.Error() return } // 更新系列计算状态 cols := []string{seriesItem.Cols().CalculateState, seriesItem.Cols().ModifyTime} seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculated seriesItem.ModifyTime = time.Now().Local() if e = seriesItem.Update(cols); e != nil { br.Msg = "操作失败" br.ErrMsg = "更新因子指标系列计算状态失败, Err: " + e.Error() return } br.Data = calculateResp br.Ret = 200 br.Success = true br.Msg = "操作成功" br.IsAddLog = true } // Detail // @Title 详情 // @Description 详情 // @Param SeriesId query int false "多因子指标系列ID" // @Success 200 {object} data_manage.FactorEdbSeriesDetail // @router /factor_edb_series/detail [get] func (this *FactorEdbSeriesController) Detail() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } seriesId, _ := this.GetInt("SeriesId", 0) if seriesId <= 0 { br.Msg = "参数有误" br.ErrMsg = fmt.Sprintf("参数有误, SeriesId: %d", seriesId) return } seriesOb := new(data_manage.FactorEdbSeries) series, e := seriesOb.GetItemById(seriesId) if e != nil { if e.Error() == utils.ErrNoRow() { br.Msg = "该因子指标系列不存在" return } br.Msg = "获取失败" br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error() return } mappingOb := new(data_manage.FactorEdbSeriesMapping) cond := fmt.Sprintf(" AND %s = ?", mappingOb.Cols().FactorEdbSeriesId) pars := make([]interface{}, 0) pars = append(pars, seriesId) mappings, e := mappingOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", mappingOb.Cols().CreateTime)) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取因子指标系列关联失败, Err: " + e.Error() return } resp := new(data_manage.FactorEdbSeriesDetail) resp.FactorEdbSeriesItem = series.Format2Item() for _, m := range mappings { resp.EdbMappings = append(resp.EdbMappings, m.Format2Item()) } br.Data = resp br.Ret = 200 br.Success = true br.Msg = "获取成功" } // CorrelationMatrix // @Title 因子指标系列-相关性矩阵 // @Description 因子指标系列-相关性矩阵 // @Param request body request.FactorEdbSeriesCorrelationMatrixReq true "type json string" // @Success 200 {object} data_manage.FactorEdbSeriesCorrelationMatrixItem // @router /factor_edb_series/correlation/matrix [post] func (this *FactorEdbSeriesController) CorrelationMatrix() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } 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 request.FactorEdbSeriesCorrelationMatrixReq if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil { br.Msg = "参数解析异常" br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e) return } if req.BaseEdbInfoId <= 0 { br.Msg = "请选择标的指标" return } if len(req.SeriesIds) == 0 { br.Msg = "请选择因子指标系列" return } if req.Correlation.LeadValue <= 0 { br.Msg = "分析周期不允许设置为负数或0" return } if req.Correlation.LeadUnit == "" { br.Msg = "请选择分析周期频度" return } leadUnitDays, ok := utils.FrequencyDaysMap[req.Correlation.LeadUnit] if !ok { br.Msg = "错误的分析周期频度" br.ErrMsg = fmt.Sprintf("分析周期频度有误: %s", req.Correlation.LeadUnit) return } if req.Correlation.CalculateUnit == "" { br.Msg = "请选择计算窗口频度" return } calculateUnitDays, ok := utils.FrequencyDaysMap[req.Correlation.CalculateUnit] if !ok { br.Msg = "错误的计算窗口频度" br.ErrMsg = fmt.Sprintf("计算窗口频度有误: %s", req.Correlation.CalculateUnit) return } leadDays := 2 * req.Correlation.LeadValue * leadUnitDays calculateDays := req.Correlation.CalculateValue * calculateUnitDays if calculateDays < leadDays { br.Msg = "计算窗口必须≥2*分析周期" return } // 获取标的指标信息及数据 baseEdb, e := data_manage.GetEdbInfoById(req.BaseEdbInfoId) if e != nil { if e.Error() == utils.ErrNoRow() { br.Msg = "标的指标不存在" return } br.Msg = "获取失败" br.ErrMsg = "获取标的指标信息失败, Err: " + e.Error() return } dataListA := make([]*data_manage.EdbDataList, 0) { // 标的指标数据日期区间 startDate := time.Now().AddDate(0, 0, -calculateDays).Format(utils.FormatDate) endDate := time.Now().Format(utils.FormatDate) startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local) startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate) // 不包含第一天 switch baseEdb.EdbInfoType { case 0: dataListA, e = data_manage.GetEdbDataList(baseEdb.Source, baseEdb.SubSource, baseEdb.EdbInfoId, startDate, endDate) case 1: _, dataListA, _, _, e, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdb.EdbInfoId, startDate, endDate, false) default: br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("标的指标类型异常: %d", baseEdb.EdbInfoType) return } if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取标的指标数据失败, Err:" + e.Error() return } } // 获取因子系列 seriesIdItem := make(map[int]*data_manage.FactorEdbSeries) { ob := new(data_manage.FactorEdbSeries) cond := fmt.Sprintf(" AND %s IN (%s)", ob.Cols().PrimaryId, utils.GetOrmInReplace(len(req.SeriesIds))) pars := make([]interface{}, 0) pars = append(pars, req.SeriesIds) items, e := ob.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", ob.Cols().PrimaryId)) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error() return } if len(items) != len(req.SeriesIds) { br.Msg = "获取失败" br.ErrMsg = "因子指标系列数量有误" return } for _, v := range items { seriesIdItem[v.FactorEdbSeriesId] = v } } // 获取因子指标 edbMappings := make([]*data_manage.FactorEdbSeriesMapping, 0) edbInfoIds := make([]int, 0) { ob := new(data_manage.FactorEdbSeriesMapping) cond := fmt.Sprintf(" AND %s IN (%s)", ob.Cols().FactorEdbSeriesId, utils.GetOrmInReplace(len(req.SeriesIds))) pars := make([]interface{}, 0) pars = append(pars, req.SeriesIds) order := fmt.Sprintf("%s ASC, %s ASC", ob.Cols().FactorEdbSeriesId, ob.Cols().EdbInfoId) items, e := ob.GetItemsByCondition(cond, pars, []string{}, order) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取因子指标关联失败, Err: " + e.Error() return } for _, v := range items { edbInfoIds = append(edbInfoIds, v.EdbInfoId) } edbMappings = items } edbIdItem := make(map[int]*data_manage.EdbInfo) edbItems, e := data_manage.GetEdbInfoByIdList(edbInfoIds) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取因子指标失败, Err: " + e.Error() return } for _, v := range edbItems { edbIdItem[v.EdbInfoId] = v } // 获取因子指标数据, 计算相关性 resp := new(data_manage.FactorEdbSeriesCorrelationMatrixResp) calculateDataOb := new(data_manage.FactorEdbSeriesCalculateData) calculateWorkers := make(chan struct{}, 10) wg := sync.WaitGroup{} edbExists := make(map[string]bool) chartKeyMap := make(map[string]*data_manage.FactorEdbSeriesChartMapping) for _, v := range edbMappings { existsKey := fmt.Sprintf("%d-%d", v.FactorEdbSeriesId, v.EdbInfoId) if edbExists[existsKey] { continue } edbExists[existsKey] = true edbItem := edbIdItem[v.EdbInfoId] if edbItem == nil { continue } seriesItem := seriesIdItem[v.FactorEdbSeriesId] if seriesItem == nil { continue } wg.Add(1) go func(mapping *data_manage.FactorEdbSeriesMapping, edb *data_manage.EdbInfo, series *data_manage.FactorEdbSeries) { defer func() { wg.Done() <-calculateWorkers }() calculateWorkers <- struct{}{} var item data_manage.FactorEdbSeriesCorrelationMatrixItem item.SeriesId = series.FactorEdbSeriesId item.EdbInfoId = edb.EdbInfoId item.EdbCode = edb.EdbCode item.EdbName = edb.EdbName // 指标来源 edbList := make([]*data_manage.ChartEdbInfoMapping, 0) edbList = append(edbList, &data_manage.ChartEdbInfoMapping{ EdbInfoId: edb.EdbInfoId, EdbInfoCategoryType: edb.EdbInfoType, EdbType: edb.EdbType, Source: edb.Source, SourceName: edb.SourceName, }) sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList) item.SourceName = strings.Join(sourceNameList, ",") item.SourceNameEn = strings.Join(sourceNameEnList, ",") // 获取指标数据 dataListB := make([]*data_manage.EdbDataList, 0) if series.CalculateState == data_manage.FactorEdbSeriesCalculated { cond := fmt.Sprintf(" AND %s = ? AND %s = ?", calculateDataOb.Cols().FactorEdbSeriesId, calculateDataOb.Cols().EdbInfoId) pars := make([]interface{}, 0) pars = append(pars, mapping.FactorEdbSeriesId, mapping.EdbInfoId) dataItems, e := calculateDataOb.GetItemsByCondition(cond, pars, []string{calculateDataOb.Cols().DataTime, calculateDataOb.Cols().Value}, fmt.Sprintf("%s ASC", calculateDataOb.Cols().DataTime)) if e != nil { item.Msg = fmt.Sprintf("计算失败") item.ErrMsg = fmt.Sprintf("获取计算数据失败, err: %v", e) resp.Fail = append(resp.Fail, item) return } dataListB = data_manage.TransEdbSeriesCalculateData2EdbDataList(dataItems) } else { switch edb.EdbInfoType { case 0: dataListB, e = data_manage.GetEdbDataList(edb.Source, edb.SubSource, edb.EdbInfoId, "", "") case 1: _, dataListB, _, _, e, _ = data.GetPredictDataListByPredictEdbInfoId(edb.EdbInfoId, "", "", false) default: item.Msg = fmt.Sprintf("计算失败") item.ErrMsg = fmt.Sprintf("指标类型异常, edbType: %d", edb.EdbInfoType) resp.Fail = append(resp.Fail, item) return } } // 计算相关性 xEdbIdValue, yDataList, e := correlationServ.CalculateCorrelation(req.Correlation.LeadValue, req.Correlation.LeadUnit, baseEdb.Frequency, edb.Frequency, dataListA, dataListB) if e != nil { item.Msg = fmt.Sprintf("计算失败") item.ErrMsg = fmt.Sprintf("相关性计算失败, err: %v", e) resp.Fail = append(resp.Fail, item) return } // X及Y轴数据 yData := yDataList[0].Value yLen := len(yData) values := make([]data_manage.FactorEdbSeriesCorrelationMatrixValues, len(xEdbIdValue)) for k, x := range xEdbIdValue { var y float64 if k >= 0 && k < yLen { y = yData[k] } y = utils.SubFloatToFloat(y, 2) values[k] = data_manage.FactorEdbSeriesCorrelationMatrixValues{ XData: x, YData: y, } } // 图表关联-此处添加的chart_info_id=0 newMapping := new(data_manage.FactorEdbSeriesChartMapping) newMapping.CalculateType = data_manage.FactorEdbSeriesChartCalculateTypeCorrelation // 计算参数 var calculatePars data_manage.FactorEdbSeriesChartCalculateCorrelationReq calculatePars.BaseEdbInfoId = req.BaseEdbInfoId calculatePars.LeadValue = req.Correlation.LeadValue calculatePars.LeadUnit = req.Correlation.LeadUnit calculatePars.CalculateValue = req.Correlation.CalculateValue calculatePars.CalculateUnit = req.Correlation.CalculateUnit bc, e := json.Marshal(calculatePars) if e != nil { item.Msg = fmt.Sprintf("计算失败") item.ErrMsg = fmt.Sprintf("计算参数JSON格式化失败, err: %v", e) resp.Fail = append(resp.Fail, item) return } newMapping.CalculatePars = string(bc) // 计算结果, 注此处保存的是排序前的顺序 bv, e := json.Marshal(values) if e != nil { item.Msg = fmt.Sprintf("计算失败") item.ErrMsg = fmt.Sprintf("计算结果JSON格式化失败, err: %v", e) resp.Fail = append(resp.Fail, item) return } newMapping.CalculateData = string(bv) newMapping.FactorEdbSeriesId = mapping.FactorEdbSeriesId newMapping.EdbInfoId = mapping.EdbInfoId newMapping.CreateTime = time.Now().Local() newMapping.ModifyTime = time.Now().Local() chartKeyMap[existsKey] = newMapping // 按照固定规则排期数[0 1 2 3 -1 -2 -3], 仅矩阵展示为此顺序 sort.Sort(data_manage.FactorEdbSeriesCorrelationMatrixOrder(values)) item.Msg = "计算成功" item.Values = values resp.Success = append(resp.Success, item) }(v, edbItem, seriesItem) } wg.Wait() // 新增图表关联, 此处按照顺序添加 chartMappings := make([]*data_manage.FactorEdbSeriesChartMapping, 0) for _, v := range edbMappings { k := fmt.Sprintf("%d-%d", v.FactorEdbSeriesId, v.EdbInfoId) item := chartKeyMap[k] if item == nil { continue } chartMappings = append(chartMappings, item) } chartMappingOb := new(data_manage.FactorEdbSeriesChartMapping) if e = chartMappingOb.ClearAndCreateMapping(req.SeriesIds, chartMappings); e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("新增图表关联失败, Err: %v", e) return } br.Data = resp br.Ret = 200 br.Success = true br.Msg = "获取成功" }