package trade_analysis import ( "encoding/json" "eta/eta_api/controllers" "eta/eta_api/models" "eta/eta_api/models/data_manage" tradeAnalysisModel "eta/eta_api/models/data_manage/trade_analysis" tradeAnalysisRequest "eta/eta_api/models/data_manage/trade_analysis/request" tradeAnalysisResponse "eta/eta_api/models/data_manage/trade_analysis/response" "eta/eta_api/services/alarm_msg" "eta/eta_api/services/data" tradeAnalysisService "eta/eta_api/services/data/trade_analysis" "eta/eta_api/utils" "fmt" "github.com/rdlucklib/rdluck_tools/paging" "sort" "strconv" "strings" "time" ) // WarehouseController 建仓过程 type WarehouseController struct { controllers.BaseAuthController } // Preview // @Title 图表预览/编辑页预览 // @Description 图表预览/编辑页预览 // @Param request body tradeAnalysisRequest.WarehousePreviewReq true "type json string" // @Success 200 {object} request.WarehousePreviewReq // @router /warehouse/chart/preview [post] func (this *WarehouseController) Preview() { 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 tradeAnalysisRequest.WarehousePreviewReq if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } // 非编辑页预览时需要校验参数 if req.ChartInfoId <= 0 { if req.ExtraConfig == nil { br.Msg = "图表参数有误" return } pass, tips := tradeAnalysisService.CheckWarehouseChartExtraConfig(*req.ExtraConfig) if !pass { br.Msg = tips return } } resp := new(tradeAnalysisResponse.WarehouseChartDetailResp) resp.WarehouseCharts = make([]*data_manage.ChartInfoDetailResp, 0) var ( multiConfigId int extraConfig tradeAnalysisModel.WarehouseExtraConfig configBuy, configSold, configPure tradeAnalysisModel.WarehouseChartPars chartBuy, chartSold, chartPure *data_manage.ChartInfoView ) configBuy.WarehouseChartType = tradeAnalysisModel.WarehouseBuyChartType configSold.WarehouseChartType = tradeAnalysisModel.WarehouseSoldChartType configPure.WarehouseChartType = tradeAnalysisModel.WarehousePureBuyChartType // 编辑页预览, 图表默认取自己的配置, 入参有值时则均取入参 if req.ChartInfoId > 0 { chartInfoView, e := data_manage.GetChartInfoViewById(req.ChartInfoId) if e != nil { if e.Error() == utils.ErrNoRow() { br.Msg = "图表已被删除, 请刷新页面" return } br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取图表信息失败, %v", e) return } if chartInfoView.ExtraConfig == `` { br.Msg = "图表配置信息错误" return } if e = json.Unmarshal([]byte(chartInfoView.ExtraConfig), &extraConfig); e != nil { br.Msg = "配置信息错误" br.ErrMsg = fmt.Sprintf("图表配置信息错误, %v", e) return } multiConfigId = extraConfig.MultipleGraphConfigId // 图表的图例设置 seriesList, e := data_manage.GetChartSeriesByChartInfoId(req.ChartInfoId) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取图例失败, %v", e) return } saveItems := make([]*data_manage.ChartSaveItem, 0) for _, v := range seriesList { saveItems = append(saveItems, &data_manage.ChartSaveItem{ UniqueFlag: v.UniqueFlag, EdbAliasName: v.SeriesName, IsAxis: v.IsAxis, }) } // 图表取自己的日期配置 switch extraConfig.WarehouseChartType { case tradeAnalysisModel.WarehouseBuyChartType: chartBuy = chartInfoView configBuy.WarehouseChartType = extraConfig.WarehouseChartType configBuy.DateType = chartInfoView.DateType configBuy.DateTypeNum = chartInfoView.DateTypeNum configBuy.StartDate = chartInfoView.StartDate configBuy.EndDate = chartInfoView.EndDate configBuy.ChartEdbInfoList = saveItems case tradeAnalysisModel.WarehouseSoldChartType: chartSold = chartInfoView configSold.WarehouseChartType = extraConfig.WarehouseChartType configSold.DateType = chartInfoView.DateType configSold.DateTypeNum = chartInfoView.DateTypeNum configSold.StartDate = chartInfoView.StartDate configSold.EndDate = chartInfoView.EndDate configSold.ChartEdbInfoList = saveItems case tradeAnalysisModel.WarehousePureBuyChartType: chartPure = chartInfoView configPure.WarehouseChartType = extraConfig.WarehouseChartType configPure.DateType = chartInfoView.DateType configPure.DateTypeNum = chartInfoView.DateTypeNum configPure.StartDate = chartInfoView.StartDate configPure.EndDate = chartInfoView.EndDate configPure.ChartEdbInfoList = saveItems } } // 入参有图表配置那么均取入参的 if req.ExtraConfig != nil { extraConfig = *req.ExtraConfig } if len(req.ChartsConfig) > 0 { for _, v := range req.ChartsConfig { if v.WarehouseChartType == tradeAnalysisModel.WarehouseBuyChartType { configBuy = v continue } if v.WarehouseChartType == tradeAnalysisModel.WarehouseSoldChartType { configSold = v continue } if v.WarehouseChartType == tradeAnalysisModel.WarehousePureBuyChartType { configPure = v } } } // 查询配置关联的指标 multiEdbBuy, multiEdbSold, multiEdbPure := make([]*tradeAnalysisModel.WarehouseEdbSaveItem, 0), make([]*tradeAnalysisModel.WarehouseEdbSaveItem, 0), make([]*tradeAnalysisModel.WarehouseEdbSaveItem, 0) if multiConfigId > 0 { multiEdbList, e := data_manage.GetMultipleGraphConfigEdbMappingListByIdAndSource(multiConfigId, utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取配置与图表指标关系失败, %v", e) return } var edbIds []int for _, v := range multiEdbList { edbIds = append(edbIds, v.EdbInfoId) } if len(edbIds) > 0 { edbList, e := data_manage.GetEdbInfoByIdList(edbIds) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取配置关联指标信息失败, %v", e) return } for _, v := range edbList { if v.CalculateFormula == "" { utils.FileLog.Info(fmt.Sprintf("持仓分析图表详情-指标计算公式为空, EdbInfoId: %d", v.EdbInfoId)) continue } var conf tradeAnalysisModel.WarehouseExtraConfig if e = json.Unmarshal([]byte(v.CalculateFormula), &conf); e != nil { utils.FileLog.Info(fmt.Sprintf("持仓分析图表详情-指标计算公式解析失败, EdbInfoId: %d, err: %v", v.EdbInfoId, e)) continue } if len(conf.Companies) != 1 { utils.FileLog.Info(fmt.Sprintf("持仓分析图表详情-指标计算公式信息有误, EdbInfoId: %d", v.EdbInfoId)) continue } item := new(tradeAnalysisModel.WarehouseEdbSaveItem) item.EdbInfoId = v.EdbInfoId item.EdbName = v.EdbName item.Unit = v.Unit item.Frequency = v.Frequency item.ClassifyId = v.ClassifyId item.UniqueFlag = conf.Companies[0] switch conf.WarehouseChartType { case tradeAnalysisModel.WarehouseBuyChartType: multiEdbBuy = append(multiEdbBuy, item) case tradeAnalysisModel.WarehouseSoldChartType: multiEdbSold = append(multiEdbSold, item) case tradeAnalysisModel.WarehousePureBuyChartType: multiEdbPure = append(multiEdbPure, item) } } } } // 获取指标数据, 该图表未用实际指标, 为了统一数据格式用ChartEdbInfoMapping companyTradeData, e := tradeAnalysisService.GetWarehouseTradeData(extraConfig.Exchange, extraConfig.ClassifyName, extraConfig.Contracts, extraConfig.Companies, extraConfig.PredictRatio) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取期货公司持仓加总数据失败, %v", e) return } // 获取三种图表 buyChartResp, e := tradeAnalysisService.GetWarehouseChartResp(chartBuy, companyTradeData, multiEdbBuy, extraConfig, configBuy) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取建仓过程多单图表数据失败, %v", e) return } soldChartResp, e := tradeAnalysisService.GetWarehouseChartResp(chartSold, companyTradeData, multiEdbSold, extraConfig, configSold) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取建仓过程空单图表数据失败, %v", e) return } pureChartResp, e := tradeAnalysisService.GetWarehouseChartResp(chartPure, companyTradeData, multiEdbPure, extraConfig, configPure) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取建仓过程净多单图表数据失败, %v", e) return } resp.MultipleGraphConfigId = multiConfigId resp.WarehouseCharts = append(resp.WarehouseCharts, buyChartResp, soldChartResp, pureChartResp) // 多图配置 if multiConfigId == 0 { multipleGraphConfig := &data_manage.MultipleGraphConfig{ SysUserId: sysUser.AdminId, SysUserRealName: sysUser.RealName, ModifyTime: time.Now(), CreateTime: time.Now(), } if e = data_manage.AddMultipleGraphConfig(multipleGraphConfig); e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("新增建仓过程多图配置失败, %v", e) return } resp.MultipleGraphConfigId = multipleGraphConfig.MultipleGraphConfigId } br.Data = resp br.Ret = 200 br.Success = true br.Msg = "操作成功" } // Add // @Title 新增图表接口 // @Description 新增图表接口 // @Param request body data_manage.AddChartInfoReq true "type json string" // @Success 200 {object} data_manage.AddChartInfoResp // @router /warehouse/chart/add [post] func (this *WarehouseController) 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 } deleteCache := true cacheKey := "CACHE_CHART_INFO_ADD_" + strconv.Itoa(sysUser.AdminId) defer func() { if deleteCache { _ = utils.Rc.Delete(cacheKey) } }() if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) { deleteCache = false br.Msg = "系统处理中,请稍后重试!" br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody) return } var req data_manage.AddChartInfoReq if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } // 图表校验 req.ChartName = strings.Trim(req.ChartName, " ") if req.ChartName == "" { br.Msg = "请填写图表名称" return } if req.ChartClassifyId <= 0 { br.Msg = "请选择分类" return } var extraConfig tradeAnalysisModel.WarehouseExtraConfig if req.ExtraConfig == `` { br.Msg = "配置有误" br.ErrMsg = fmt.Sprintf("建仓图表配置有误, conf: %s", req.ExtraConfig) return } if e := json.Unmarshal([]byte(req.ExtraConfig), &extraConfig); e != nil { br.Msg = "配置有误" br.ErrMsg = fmt.Sprintf("建仓图表配置解析失败, err: %v; conf: %s", e, req.ExtraConfig) return } pass, tips := tradeAnalysisService.CheckWarehouseChartExtraConfig(extraConfig) if !pass { br.Msg = tips return } // 校验图例 if len(req.ChartEdbInfoList) == 0 { br.Msg = "请填写图例" return } if len(req.ChartEdbInfoList) != len(extraConfig.Companies) { br.Msg = "图例不一致" br.ErrMsg = fmt.Sprintf("图例不一致, len: %d, companies: %d", len(req.ChartEdbInfoList), len(extraConfig.Companies)) return } flagExist := make(map[string]bool) for _, v := range req.ChartEdbInfoList { if v.UniqueFlag == "" { br.Msg = "" } if flagExist[v.UniqueFlag] { br.Msg = "图例异常" br.ErrMsg = fmt.Sprintf("建仓图表图例异常, %s", v.UniqueFlag) return } } // 校验分类 _, e := data_manage.GetChartClassifyById(req.ChartClassifyId) if e != nil { if e.Error() == utils.ErrNoRow() { br.Msg = "分类不存在, 请刷新页面" return } br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e) return } // 校验图表是否存在 { var cond string var pars []interface{} switch this.Lang { case utils.EnLangVersion: cond += " AND chart_name_en = ? AND source = ? " default: cond += " AND chart_name = ? AND source = ? " } pars = append(pars, req.ChartName, utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS) count, e := data_manage.GetChartInfoCountByCondition(cond, pars) if e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("获取同名图表计数失败, %v", e) return } if count > 0 { br.Msg = "图表名称已存在, 请重新填写" return } } // 新增图表 chartInfo, e := tradeAnalysisService.AddWarehouseChart(req, extraConfig, sysUser.AdminId, sysUser.RealName) if e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("新增持仓分析图表失败, %v", e) return } // 新增操作日志 { chartLog := new(data_manage.ChartInfoLog) chartLog.ChartInfoId = chartInfo.ChartInfoId chartLog.ChartName = req.ChartName chartLog.ChartClassifyId = req.ChartClassifyId chartLog.SysUserId = sysUser.AdminId chartLog.SysUserRealName = sysUser.RealName chartLog.UniqueCode = chartInfo.UniqueCode chartLog.CreateTime = time.Now() chartLog.Content = string(this.Ctx.Input.RequestBody) chartLog.Status = "新增持仓分析图表" chartLog.Method = this.Ctx.Input.URI() go data_manage.AddChartInfoLog(chartLog) } resp := new(data_manage.AddChartInfoResp) resp.ChartInfoId = chartInfo.ChartInfoId resp.UniqueCode = chartInfo.UniqueCode resp.ChartType = chartInfo.ChartType br.Ret = 200 br.Success = true br.Msg = "保存成功" br.Data = resp br.IsAddLog = true } // Edit // @Title 编辑图表接口 // @Description 编辑图表接口 // @Param request body data_manage.EditChartInfoReq true "type json string" // @Success Ret=200 保存成功 // @router /warehouse/chart/edit [post] func (this *WarehouseController) 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 data_manage.EditChartInfoReq if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil { br.Msg = "参数解析失败" br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e) return } // 图表校验 req.ChartName = strings.Trim(req.ChartName, " ") if req.ChartName == "" { br.Msg = "请填写图表名称" return } if req.ChartClassifyId <= 0 { br.Msg = "请选择分类" return } var extraConfig tradeAnalysisModel.WarehouseExtraConfig if req.ExtraConfig == `` { br.Msg = "配置有误" br.ErrMsg = fmt.Sprintf("建仓图表配置有误, conf: %s", req.ExtraConfig) return } if e := json.Unmarshal([]byte(req.ExtraConfig), &extraConfig); e != nil { br.Msg = "配置有误" br.ErrMsg = fmt.Sprintf("建仓图表配置解析失败, err: %v; conf: %s", e, req.ExtraConfig) return } pass, tips := tradeAnalysisService.CheckWarehouseChartExtraConfig(extraConfig) if !pass { br.Msg = tips return } // 图表校验 chartItem, e := data_manage.GetChartInfoById(req.ChartInfoId) if e != nil { if e.Error() == utils.ErrNoRow() { br.Msg = "图表不存在, 请刷新页面" return } br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("获取图表信息失败, %v", e) return } if chartItem.Source != utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS { br.Msg = "图表类型异常" br.ErrMsg = fmt.Sprintf("图表类型异常: %d", chartItem.Source) return } // 图表操作权限 ok := data.CheckOpChartPermission(sysUser, chartItem.SysUserId, true) if !ok { br.Msg = "没有该图表的操作权限" return } // 校验图例 if len(req.ChartEdbInfoList) == 0 { br.Msg = "请填写图例" return } if len(req.ChartEdbInfoList) != len(extraConfig.Companies) { br.Msg = "图例不一致" br.ErrMsg = fmt.Sprintf("图例不一致, len: %d, companies: %d", len(req.ChartEdbInfoList), len(extraConfig.Companies)) return } flagExist := make(map[string]bool) for _, v := range req.ChartEdbInfoList { if v.UniqueFlag == "" { br.Msg = "" } if flagExist[v.UniqueFlag] { br.Msg = "图例异常" br.ErrMsg = fmt.Sprintf("建仓图表图例异常, %s", v.UniqueFlag) return } } // 校验分类 _, e = data_manage.GetChartClassifyById(req.ChartClassifyId) if e != nil { if e.Error() == utils.ErrNoRow() { br.Msg = "分类不存在, 请刷新页面" return } br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e) return } // 校验图表是否存在 { var cond string var pars []interface{} cond += " AND chart_info_id <> ? " pars = append(pars, req.ChartInfoId) switch this.Lang { case utils.EnLangVersion: cond += " AND chart_name_en = ? AND source = ? " default: cond += " AND chart_name = ? AND source = ? " } pars = append(pars, req.ChartName, utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS) count, e := data_manage.GetChartInfoCountByCondition(cond, pars) if e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("获取同名图表计数失败, %v", e) return } if count > 0 { br.Msg = "图表名称已存在, 请重新填写" return } } // 更新图表 chartItem, e = tradeAnalysisService.EditWarehouseChart(req) if e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("新增持仓分析图表失败, %v", e) return } resp := new(data_manage.AddChartInfoResp) resp.ChartInfoId = chartItem.ChartInfoId resp.UniqueCode = chartItem.UniqueCode resp.ChartType = req.ChartType // 新增操作日志 { chartLog := new(data_manage.ChartInfoLog) chartLog.ChartName = chartItem.ChartName chartLog.ChartInfoId = req.ChartInfoId chartLog.ChartClassifyId = chartItem.ChartClassifyId chartLog.SysUserId = sysUser.AdminId chartLog.SysUserRealName = sysUser.RealName chartLog.UniqueCode = chartItem.UniqueCode chartLog.CreateTime = time.Now() chartLog.Content = string(this.Ctx.Input.RequestBody) chartLog.Status = "编辑持仓分析图表" chartLog.Method = this.Ctx.Input.URL() go data_manage.AddChartInfoLog(chartLog) } br.Ret = 200 br.Success = true br.Msg = "保存成功" br.Data = resp br.IsAddLog = true } // Detail // @Title 获取图表详情 // @Description 获取图表详情接口 // @Param ChartInfoId query int true "图表id" // @Param DateType query int true "日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间" // @Param StartDate query string true "自定义开始日期" // @Param EndDate query string true "自定义结束日期" // @Param Calendar query string true "公历/农历" // @Param SeasonStartDate query string true "季节性图开始日期" // @Param SeasonEndDate query string true "季节性图结束日期" // @Param EdbInfoId query string true "指标ID,多个用英文逗号隔开" // @Param ChartType query int true "生成样式:1:曲线图,2:季节性图" // @Success 200 {object} data_manage.ChartInfoDetailResp // @router /warehouse/chart/detail [get] func (this *WarehouseController) 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 } chartInfoId, _ := this.GetInt("ChartInfoId") if chartInfoId <= 0 { br.Msg = "参数有误" return } dateType, _ := this.GetInt("DateType") startDate := this.GetString("StartDate") endDate := this.GetString("EndDate") dateTypeNum, _ := this.GetInt("DateTypeNum") var err error chartInfo := new(data_manage.ChartInfoView) chartInfo, err = data_manage.GetChartInfoViewById(chartInfoId) if err != nil { if err.Error() == utils.ErrNoRow() { br.Msg = "图被删除,请刷新页面" br.ErrMsg = "图被删除,请刷新页面,Err:" + err.Error() return } br.Msg = "获取失败" br.ErrMsg = "获取图表信息失败,Err:" + err.Error() return } if dateType <= 0 { dateType = chartInfo.DateType } if startDate == "" { startDate = chartInfo.StartDate } if endDate == "" { endDate = chartInfo.EndDate } if dateTypeNum <= 0 { dateTypeNum = chartInfo.DateTypeNum } // 持仓分析图表配置校验 var extraConfig tradeAnalysisModel.WarehouseExtraConfig if chartInfo.ExtraConfig == `` { br.Msg = "配置信息错误" return } if e := json.Unmarshal([]byte(chartInfo.ExtraConfig), &extraConfig); e != nil { br.Msg = "配置信息错误" br.ErrMsg = fmt.Sprintf("图表配置信息错误, %v", e) return } // 获取图表数据 companyTradeData, e := tradeAnalysisService.GetWarehouseTradeData(extraConfig.Exchange, extraConfig.ClassifyName, extraConfig.Contracts, extraConfig.Companies, extraConfig.PredictRatio) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取期货公司持仓加总数据失败, %v", e) return } var chartConfig tradeAnalysisModel.WarehouseChartPars chartConfig.WarehouseChartType = extraConfig.WarehouseChartType chartConfig.DateType = dateType chartConfig.StartDate = startDate chartConfig.EndDate = endDate chartConfig.DateTypeNum = dateTypeNum // 获取图表的图例设置 seriesList, e := data_manage.GetChartSeriesByChartInfoId(chartInfoId) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取图例失败, %v", e) return } saveItems := make([]*data_manage.ChartSaveItem, 0) for _, v := range seriesList { saveItems = append(saveItems, &data_manage.ChartSaveItem{ UniqueFlag: v.UniqueFlag, EdbAliasName: v.SeriesName, IsAxis: v.IsAxis, }) } chartConfig.ChartEdbInfoList = saveItems // 查询配置关联的指标 multiEdb := make([]*tradeAnalysisModel.WarehouseEdbSaveItem, 0) if extraConfig.MultipleGraphConfigId > 0 { multiEdbList, e := data_manage.GetMultipleGraphConfigEdbMappingListByIdAndSource(extraConfig.MultipleGraphConfigId, utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取配置与图表指标关系失败, %v", e) return } var edbIds []int for _, v := range multiEdbList { edbIds = append(edbIds, v.EdbInfoId) } if len(edbIds) > 0 { edbList, e := data_manage.GetEdbInfoByIdList(edbIds) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取配置关联指标信息失败, %v", e) return } for _, v := range edbList { if v.CalculateFormula == "" { utils.FileLog.Info(fmt.Sprintf("持仓分析图表详情-指标计算公式为空, EdbInfoId: %d", v.EdbInfoId)) continue } var conf tradeAnalysisModel.WarehouseExtraConfig if e = json.Unmarshal([]byte(v.CalculateFormula), &conf); e != nil { utils.FileLog.Info(fmt.Sprintf("持仓分析图表详情-指标计算公式解析失败, EdbInfoId: %d, err: %v", v.EdbInfoId, e)) continue } if len(conf.Companies) != 1 { utils.FileLog.Info(fmt.Sprintf("持仓分析图表详情-指标计算公式信息有误, EdbInfoId: %d", v.EdbInfoId)) continue } item := new(tradeAnalysisModel.WarehouseEdbSaveItem) item.EdbInfoId = v.EdbInfoId item.EdbName = v.EdbName item.Unit = v.Unit item.Frequency = v.Frequency item.ClassifyId = v.ClassifyId item.UniqueFlag = conf.Companies[0] if conf.WarehouseChartType == extraConfig.WarehouseChartType { multiEdb = append(multiEdb, item) } } } } chartResp, e := tradeAnalysisService.GetWarehouseChartResp(chartInfo, companyTradeData, multiEdb, extraConfig, chartConfig) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取图表详情失败, %v", e) return } resp := chartResp // 判断是否加入我的图库 if chartInfoId > 0 && chartInfo != nil { { var myChartCondition string var myChartPars []interface{} myChartCondition += ` AND a.admin_id=? ` myChartPars = append(myChartPars, sysUser.AdminId) myChartCondition += ` AND a.chart_info_id=? ` myChartPars = append(myChartPars, chartInfo.ChartInfoId) myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取失败" br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error() return } if myChartList != nil && len(myChartList) > 0 { chartInfo.IsAdd = true chartInfo.MyChartId = myChartList[0].MyChartId chartInfo.MyChartClassifyId = myChartList[0].MyChartClassifyId } } } // 图表操作权限 edbList := make([]*data_manage.ChartEdbInfoMapping, 0) chartInfo.IsEdit = data.CheckOpChartPermission(sysUser, chartInfo.SysUserId, true) // 判断是否需要展示英文标识 //chartInfo.IsEnChart = data.CheckIsEnChart(chartInfo.ChartNameEn, edbList, chartInfo.Source, chartInfo.ChartType) // 数据来源 sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList) sourceNameList = append(sourceNameList, utils.SourceNameTradeAnalysis) sourceNameEnList = append(sourceNameEnList, utils.SourceNameTradeAnalysis) chartInfo.ChartSource = strings.Join(sourceNameList, ",") chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",") // 另存为 chartInfo.Button = data_manage.ChartViewButton{ IsEdit: chartInfo.IsEdit, IsEnChart: chartInfo.IsEnChart, IsAdd: chartInfo.IsAdd, IsCopy: chartInfo.IsEdit, IsSetName: chartInfo.IsSetName, } // 图表当前分类的分类树 classifyLevels := make([]string, 0) { list, e := data_manage.GetChartClassifyAllBySource(utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取图表分类失败, Err: %v", e) return } parents := data.GetChartClassifyParentRecursive(list, chartInfo.ChartClassifyId) sort.Slice(parents, func(i, j int) bool { return parents[i].Level < parents[i].Level }) for _, v := range parents { classifyLevels = append(classifyLevels, v.UniqueCode) } } resp.ClassifyLevels = classifyLevels br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // List // @Title 持仓分析图表列表接口 // @Description 持仓分析图表列表接口 // @Param PageSize query int true "每页数据条数" // @Param CurrentIndex query int true "当前页页码,从1开始" // @Param ChartClassifyId query int true "分类id" // @Param Keyword query string true "搜索关键词" // @Param IsShowMe query bool true "是否只看我的,true、false" // @Success 200 {object} data_manage.ChartListResp // @router /warehouse/chart/list [get] func (this *WarehouseController) List() { 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 } chartClassifyId, _ := this.GetInt("ChartClassifyId") pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") keyword := this.GetString("KeyWord") var total int page := paging.GetPaging(currentIndex, pageSize, total) var startSize int if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize = paging.StartIndex(currentIndex, pageSize) source := utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS var condition string var pars []interface{} // 普通图表 condition += ` AND source = ? ` pars = append(pars, source) if chartClassifyId > 0 { classifyIds, err := data_manage.GetChartClassify(chartClassifyId) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取图表信息失败" br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error() return } if classifyIds == "" { resp := new(data_manage.ChartListResp) page = paging.GetPaging(currentIndex, pageSize, 0) resp.Paging = page resp.List = make([]*data_manage.ChartInfoView, 0) br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp return } condition += " AND chart_classify_id IN(" + classifyIds + ") " } if keyword != "" { //将关键词按照空格分割 keywords := strings.Split(keyword, " ") condition += ` AND ( chart_name LIKE '%` + keywords[0] + `%' ` for k, key := range keywords { if k == 0 { continue } condition += ` OR chart_name LIKE '%` + key + `%' ` } condition += ` )` } //只看我的 isShowMe, _ := this.GetBool("IsShowMe") if isShowMe { condition += ` AND sys_user_id = ? ` pars = append(pars, sysUser.AdminId) } // 获取当前账号的不可见指标 noPermissionChartIdList := make([]int, 0) { obj := data_manage.EdbInfoNoPermissionAdmin{} confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取失败" br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error() return } for _, v := range confList { noPermissionChartIdList = append(noPermissionChartIdList, v.ChartInfoId) } } lenNoPermissionChartIdList := len(noPermissionChartIdList) if lenNoPermissionChartIdList > 0 { condition += ` AND chart_info_id not in (` + utils.GetOrmInReplace(lenNoPermissionChartIdList) + `) ` pars = append(pars, noPermissionChartIdList) } //获取图表信息 list, err := data_manage.GetChartListByCondition(condition, pars, startSize, pageSize) if err != nil && err.Error() != utils.ErrNoRow() { br.Success = true br.Msg = "获取图表信息失败" br.ErrMsg = "获取图表信息失败,Err:" + err.Error() return } myChartList, err := data_manage.GetMyChartListByAdminId(sysUser.AdminId) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取图表信息失败" br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error() return } myChartMap := make(map[int]*data_manage.MyChartView) for _, v := range myChartList { myChartMap[v.ChartInfoId] = v } listLen := len(list) chartEdbMap := make(map[int][]*data_manage.ChartEdbInfoMapping) if listLen > 0 { chartInfoIds := "" for _, v := range list { chartInfoIds += strconv.Itoa(v.ChartInfoId) + "," } if chartInfoIds != "" { chartInfoIds = strings.Trim(chartInfoIds, ",") //判断是否需要展示英文标识 edbList, e := data_manage.GetChartEdbMappingListByChartInfoIds(chartInfoIds) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取图表,指标信息失败,Err:" + e.Error() return } for _, v := range edbList { chartEdbMap[v.ChartInfoId] = append(chartEdbMap[v.ChartInfoId], v) } } } for i := 0; i < listLen; i++ { //判断是否需要展示英文标识 if edbTmpList, ok := chartEdbMap[list[i].ChartInfoId]; ok { list[i].IsEnChart = data.CheckIsEnChart(list[i].ChartNameEn, edbTmpList, list[i].Source, list[i].ChartType) } if existItem, ok := myChartMap[list[i].ChartInfoId]; ok { list[i].IsAdd = true list[i].MyChartId = existItem.MyChartId list[i].MyChartClassifyId = existItem.MyChartClassifyId } } resp := new(data_manage.ChartListResp) if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) { items := make([]*data_manage.ChartInfoView, 0) resp.Paging = page resp.List = items br.Ret = 200 br.Success = true br.Msg = "获取成功" return } dataCount, err := data_manage.GetChartListCountByCondition(condition, pars) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取指标信息失败" br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error() return } page = paging.GetPaging(currentIndex, pageSize, dataCount) resp.Paging = page resp.List = list br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // Copy // @Title 复制并新增图表接口 // @Description 新增图表接口 // @Params request body data_manage.CopyAddChartInfoReq true "type json string" // @Success 200 {object} data_manage.AddChartInfoResp // @router /warehouse/chart/copy [post] func (this *WarehouseController) Copy() { 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 data_manage.CopyAddChartInfoReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.ChartInfoId <= 0 { br.Msg = "参数有误" br.ErrMsg = fmt.Sprintf("参数有误, ChartInfoId: %d", req.ChartInfoId) return } req.ChartName = strings.TrimSpace(req.ChartName) if req.ChartName == "" { br.Msg = "请输入图表名称" return } if req.ChartClassifyId <= 0 { br.Msg = "请选择图表分类" return } deleteCache := true cacheKey := "CACHE_CHART_INFO_ADD_" + strconv.Itoa(sysUser.AdminId) defer func() { if deleteCache { utils.Rc.Delete(cacheKey) } }() if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) { deleteCache = false br.Msg = "系统处理中,请稍后重试!" br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody) return } chartSource := utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS // 校验分类、图表名称 { var cond string var pars []interface{} switch this.Lang { case utils.EnLangVersion: cond += " AND chart_name_en = ? AND source = ? " default: cond += " AND chart_name = ? AND source = ? " } pars = append(pars, req.ChartName, chartSource) count, e := data_manage.GetChartInfoCountByCondition(cond, pars) if e != nil { br.Msg = "保存失败" br.ErrMsg = fmt.Sprintf("获取同名图表失败, Err: %v", e) return } if count > 0 { br.Msg = "图表名称已存在, 请重新填写" return } _, e = data_manage.GetChartClassifyById(req.ChartClassifyId) if e != nil { if e.Error() == utils.ErrNoRow() { br.Msg = "分类不存在" return } br.Msg = "保存失败" br.ErrMsg = fmt.Sprintf("获取图表分类失败, Err: %v", e) return } } // 原图表 originChart, e := data_manage.GetChartInfoById(req.ChartInfoId) if e != nil { if e.Error() == utils.ErrNoRow() { br.Msg = "原图表不存在" return } br.Msg = "保存失败" br.ErrMsg = fmt.Sprintf("获取原图表信息失败, Err: %v", e) return } chartInfo := new(data_manage.ChartInfo) newChart, e := tradeAnalysisService.CopyWarehouseChart(req.ChartClassifyId, req.ChartName, originChart, sysUser.AdminId, sysUser.RealName) if e != nil { br.Msg = "保存失败" br.ErrMsg = fmt.Sprintf("复制图表失败, %v", e) return } chartInfo = newChart // 新增操作日志 { chartLog := new(data_manage.ChartInfoLog) chartLog.ChartInfoId = chartInfo.ChartInfoId chartLog.ChartName = req.ChartName chartLog.ChartClassifyId = req.ChartClassifyId chartLog.SysUserId = sysUser.AdminId chartLog.SysUserRealName = sysUser.RealName chartLog.UniqueCode = chartInfo.UniqueCode chartLog.CreateTime = time.Now() chartLog.Content = string(this.Ctx.Input.RequestBody) chartLog.Status = "复制区间计算图表" chartLog.Method = this.Ctx.Input.URI() go data_manage.AddChartInfoLog(chartLog) } br.Ret = 200 br.Success = true br.Msg = "保存成功" br.Data = data_manage.AddChartInfoResp{ ChartInfoId: chartInfo.ChartInfoId, UniqueCode: chartInfo.UniqueCode, ChartType: chartInfo.ChartType, } br.IsAddLog = true } // Refresh // @Title 图表刷新接口 // @Description 图表刷新接口 // @Param ChartInfoId query int true "图表id" // @Param UniqueCode query string true "唯一code" // @Success Ret=200 刷新成功 // @router /warehouse/chart/refresh [get] func (this *WarehouseController) Refresh() { 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 } chartInfoId, _ := this.GetInt("ChartInfoId") uniqueCode := this.GetString("UniqueCode") if chartInfoId <= 0 && uniqueCode == `` { br.Msg = "参数错误" br.ErrMsg = "参数错误:chartInfoId:" + strconv.Itoa(chartInfoId) + ",UniqueCode:" + uniqueCode return } var chartInfo *data_manage.ChartInfo var err error if chartInfoId > 0 { chartInfo, err = data_manage.GetChartInfoById(chartInfoId) } else { chartInfo, err = data_manage.GetChartInfoByUniqueCode(uniqueCode) } if err != nil { if err.Error() == utils.ErrNoRow() { br.Msg = "图表已被删除,无需刷新" br.ErrMsg = "获取指标信息失败,Err:" + err.Error() return } br.Msg = "刷新失败" br.ErrMsg = "获取图表信息失败,Err:" + err.Error() return } // 清除图表缓存 { key := utils.HZ_CHART_LIB_DETAIL + chartInfo.UniqueCode _ = utils.Rc.Delete(key) } br.Ret = 200 br.Success = true br.Msg = "刷新成功" } // SearchByEs // @Title 图表模糊搜索(从es获取) // @Description 图表模糊搜索(从es获取) // @Param Keyword query string true "图表名称" // @Param IsShowMe query bool true "是否只看我的,true、false" // @Param Source query int true "来源,3:相关性,4:滚动相关性,默认0:全部" // @Success 200 {object} data_manage.ChartInfo // @router /warehouse/chart/search_by_es [get] func (this *WarehouseController) SearchByEs() { 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 } pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") var startSize int if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize = paging.StartIndex(currentIndex, pageSize) keyword := this.GetString("Keyword") //只看我的 isShowMe, _ := this.GetBool("IsShowMe") showSysId := 0 if isShowMe { showSysId = sysUser.AdminId } sourceList := make([]int, 0) sourceList = append(sourceList, utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS) var searchList []*data_manage.ChartInfo var total int64 var err error // 获取当前账号的不可见指标 noPermissionChartIdList := make([]int, 0) { obj := data_manage.EdbInfoNoPermissionAdmin{} confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取失败" br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error() return } for _, v := range confList { noPermissionChartIdList = append(noPermissionChartIdList, v.ChartInfoId) } } if keyword != "" { searchList, total, err = data.EsSearchChartInfo(keyword, showSysId, sourceList, noPermissionChartIdList, startSize, pageSize) } else { total, searchList, err = data_manage.ChartInfoSearchByEmptyKeyWord(showSysId, sourceList, noPermissionChartIdList, startSize, pageSize) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取失败" br.ErrMsg = "获取图表信息失败,Err:" + err.Error() return } } finalList := make([]*data_manage.ChartInfoMore, 0) if len(searchList) > 0 { chartInfoIds := "" chartEdbMap := make(map[int][]*data_manage.ChartEdbInfoMapping) for _, v := range searchList { chartInfoIds += strconv.Itoa(v.ChartInfoId) + "," } if chartInfoIds != "" { chartInfoIds = strings.Trim(chartInfoIds, ",") //判断是否需要展示英文标识 edbList, e := data_manage.GetChartEdbMappingListByChartInfoIds(chartInfoIds) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取图表,指标信息失败,Err:" + e.Error() return } for _, v := range edbList { chartEdbMap[v.ChartInfoId] = append(chartEdbMap[v.ChartInfoId], v) } } for _, v := range searchList { tmp := new(data_manage.ChartInfoMore) tmp.ChartInfo = *v // 图表数据权限 tmp.HaveOperaAuth = true //判断是否需要展示英文标识 if edbTmpList, ok := chartEdbMap[v.ChartInfoId]; ok { tmp.IsEnChart = data.CheckIsEnChart(v.ChartNameEn, edbTmpList, v.Source, v.ChartType) } finalList = append(finalList, tmp) } } //新增搜索词记录 { searchKeyword := new(data_manage.SearchKeyword) searchKeyword.KeyWord = keyword searchKeyword.CreateTime = time.Now() go data_manage.AddSearchKeyword(searchKeyword) } page := paging.GetPaging(currentIndex, pageSize, int(total)) resp := data_manage.ChartInfoListByEsResp{ Paging: page, List: finalList, } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // ChartInfoSave // @Title 保存图表接口 // @Description 保存图表接口 // @Param request body data_manage.SaveChartInfoReq true "type json string" // @Success Ret=200 返回图表id // @router /warehouse/chart/save [post] func (this *WarehouseController) ChartInfoSave() { 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 data_manage.SaveChartInfoReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.ChartInfoId <= 0 { br.Msg = "参数错误!" return } chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId) if err != nil { if err.Error() == utils.ErrNoRow() { br.Msg = "图表已被删除,请刷新页面!" br.ErrMsg = "图表已被删除,请刷新页面,ChartInfoId:" + strconv.Itoa(req.ChartInfoId) return } br.Msg = "获取图表信息失败!" br.ErrMsg = "获取图表信息失败,Err:" + err.Error() return } chartItem.StartDate = req.StartDate chartItem.EndDate = req.EndDate chartItem.DateType = req.DateType chartItem.DateTypeNum = req.DateTypeNum chartItem.LeftMin = req.LeftMin chartItem.LeftMax = req.LeftMax chartItem.RightMin = req.RightMin chartItem.RightMax = req.RightMax chartItem.Right2Min = req.Right2Min chartItem.Right2Max = req.Right2Max chartItem.MinMaxSave = req.MinMaxSave updateCols := []string{"StartDate", "EndDate", "DateType", "DateTypeNum", "LeftMin", "LeftMax", "RightMin", "RightMax", "Right2Min", "Right2Max", "MinMaxSave"} if e := chartItem.Update(updateCols); e != nil { br.Msg = "保存失败" br.ErrMsg = fmt.Sprintf("更新图表基础信息失败, %v", e) return } key := utils.HZ_CHART_LIB_DETAIL + chartItem.UniqueCode if utils.Re == nil && utils.Rc != nil { _ = utils.Rc.Delete(key) } // 更新ES go func() { data.EsAddOrEditChartInfo(chartItem.ChartInfoId) data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId) }() //新增操作日志 { chartLog := new(data_manage.ChartInfoLog) chartLog.ChartName = chartItem.ChartName chartLog.ChartInfoId = req.ChartInfoId chartLog.ChartClassifyId = chartItem.ChartClassifyId chartLog.SysUserId = sysUser.AdminId chartLog.SysUserRealName = sysUser.RealName chartLog.UniqueCode = chartItem.UniqueCode chartLog.CreateTime = time.Now() chartLog.Content = string(this.Ctx.Input.RequestBody) chartLog.Status = "修改配置项" chartLog.Method = this.Ctx.Input.URI() go data_manage.AddChartInfoLog(chartLog) } br.Ret = 200 br.Success = true br.Msg = "保存成功" br.IsAddLog = true } // EdbSaveCheck // @Title 保存指标校验 // @Description 保存指标校验 // @Param request body request.WarehouseEdbSaveReq true "type json string" // @Success Ret=200 返回指标id // @router /warehouse/edb/save_check [post] func (this *WarehouseController) EdbSaveCheck() { 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 tradeAnalysisRequest.WarehouseEdbSaveReq if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil { br.Msg = "参数解析异常" br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e) return } // 参数校验 if !req.IsSaveAs && req.MultipleGraphConfigId <= 0 { br.Msg = "多图配置有误" br.ErrMsg = fmt.Sprintf("配置ID有误, %d", req.MultipleGraphConfigId) return } //var extraConfig tradeAnalysisModel.WarehouseExtraConfig extraConfig := *req.ExtraConfig //if req.ExtraConfig == `` { // br.Msg = "配置有误" // br.ErrMsg = fmt.Sprintf("建仓图表配置有误, conf: %s", req.ExtraConfig) // return //} //if e := json.Unmarshal([]byte(req.ExtraConfig), &extraConfig); e != nil { // br.Msg = "配置有误" // br.ErrMsg = fmt.Sprintf("建仓图表配置解析失败, err: %v; conf: %s", e, req.ExtraConfig) // return //} pass, tips := tradeAnalysisService.CheckWarehouseChartExtraConfig(extraConfig) if !pass { br.Msg = tips return } if extraConfig.WarehouseChartType <= 0 { br.Msg = "配置类型有误" br.ErrMsg = fmt.Sprintf("配置类型有误, %d", extraConfig.WarehouseChartType) return } // 根据extraConfig与已绑定关系的指标进行比对, 看是否需要新增指标 multiEdbList, e := data_manage.GetMultipleGraphConfigEdbMappingListByIdAndSource(req.MultipleGraphConfigId, utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS) if e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("获取配置与图表指标关系失败, %v", e) return } resp := make([]*tradeAnalysisModel.WarehouseEdbSaveItem, 0) // 校验是否需要新增指标 newEdbList, _, e := tradeAnalysisService.CheckEdbSave(extraConfig, multiEdbList, req.IsSaveAs) if e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("校验指标是否需要新增失败, %v", e) return } if len(newEdbList) > 0 { resp = append(resp, newEdbList...) } br.Data = resp br.Ret = 200 br.Success = true br.Msg = "操作成功" } // EdbSave // @Title 保存指标接口 // @Description 保存指标接口 // @Param request body request.WarehouseEdbSaveReq true "type json string" // @Success Ret=200 返回指标id // @router /warehouse/edb/save [post] func (this *WarehouseController) EdbSave() { 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 tradeAnalysisRequest.WarehouseEdbSaveReq if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil { br.Msg = "参数解析异常" br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e) return } cacheKey := "CACHE_CHART_EDB_INFO_ADD_" + strconv.Itoa(sysUser.AdminId) if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) { br.Msg = "系统处理中,请稍后重试!" return } defer func() { _ = utils.Rc.Delete(cacheKey) }() // 参数校验 if !req.IsSaveAs && req.MultipleGraphConfigId <= 0 { br.Msg = "多图配置有误" br.ErrMsg = fmt.Sprintf("配置ID有误, %d", req.MultipleGraphConfigId) return } extraConfig := *req.ExtraConfig pass, tips := tradeAnalysisService.CheckWarehouseChartExtraConfig(extraConfig) if !pass { br.Msg = tips return } if len(req.EdbInfoList) == 0 { br.Msg = "请选择指标" return } edbNameExist := make(map[string]bool) for _, v := range req.EdbInfoList { if v.UniqueFlag == "" { br.Msg = "指标标识有误" br.ErrMsg = fmt.Sprintf("指标标识有误, %s", v.UniqueFlag) return } // 仅新增的时候校验下面的参数 if v.EdbInfoId > 0 { continue } edbName := strings.TrimSpace(v.EdbName) if edbName == "" { br.Msg = "请输入指标名称" return } if edbNameExist[edbName] { br.Msg = "指标名称重复, 请重新输入" return } edbNameExist[edbName] = true if v.Unit == "" { br.Msg = "请输入单位" return } if v.Frequency == "" { br.Msg = "请选择频度" return } if v.ClassifyId <= 0 { br.Msg = "请选择分类" return } } resp := tradeAnalysisResponse.WarehouseEdbSaveResp{ Fail: make([]*tradeAnalysisModel.WarehouseEdbSaveRespItem, 0), Success: make([]*tradeAnalysisModel.WarehouseEdbSaveRespItem, 0), } // 获取需要移除关联的指标 multiEdbList, e := data_manage.GetMultipleGraphConfigEdbMappingListByIdAndSource(req.MultipleGraphConfigId, utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS) if e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("获取配置与图表指标关系失败, %v", e) return } _, removeIds, e := tradeAnalysisService.CheckEdbSave(extraConfig, multiEdbList, req.IsSaveAs) if e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("校验指标是否需要新增失败, %v", e) return } // 根据EdbInfoId判断是否需要更新指标 var newEdbIds []int edbUpdateCols := []string{"CalculateFormula", "ModifyTime"} newEdbRefresh := make([]*data_manage.EdbInfo, 0) for _, v := range req.EdbInfoList { // 图表配置-即指标计算公式 conf := extraConfig conf.Companies = []string{v.UniqueFlag} b, e := json.Marshal(conf) if e != nil { resp.Fail = append(resp.Fail, &tradeAnalysisModel.WarehouseEdbSaveRespItem{ WarehouseEdbSaveItem: *v, Tips: "获取失败", ErrMsg: fmt.Sprintf("指标配置JSON格式化异常, %v", e), }) continue } formula := string(b) //edb.CalculateFormula = string(b) // 更新指标 edbInfo := new(data_manage.EdbInfo) if v.EdbInfoId > 0 { edb, e := data_manage.GetEdbInfoById(v.EdbInfoId) if e != nil { resp.Fail = append(resp.Fail, &tradeAnalysisModel.WarehouseEdbSaveRespItem{ WarehouseEdbSaveItem: *v, Tips: "获取失败", ErrMsg: fmt.Sprintf("获取失败, %v", e), }) continue } edb.CalculateFormula = formula edb.ModifyTime = time.Now().Local() if e = edb.Update(edbUpdateCols); e != nil { resp.Fail = append(resp.Fail, &tradeAnalysisModel.WarehouseEdbSaveRespItem{ WarehouseEdbSaveItem: *v, Tips: "更新失败", ErrMsg: fmt.Sprintf("更新指标计算公式失败, %v", e), }) continue } edbInfo = edb // 刷新指标数据 res, e := data.RefreshEdbData(edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, utils.BASE_START_DATE) if e != nil { resp.Fail = append(resp.Fail, &tradeAnalysisModel.WarehouseEdbSaveRespItem{ WarehouseEdbSaveItem: *v, Tips: "刷新失败", ErrMsg: fmt.Sprintf("刷新失败, %v", e), }) continue } if res.Ret != 200 { resp.Fail = append(resp.Fail, &tradeAnalysisModel.WarehouseEdbSaveRespItem{ WarehouseEdbSaveItem: *v, Tips: "刷新失败", ErrMsg: fmt.Sprintf("刷新失败, Ret: %d, err: %v", res.Ret, e), }) continue } } // 新增指标 if v.EdbInfoId == 0 { edbCode, e := utils.GenerateEdbCode(1, "") if e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("生成指标编码失败, %v", e) return } // PS:新增的开始结束日期为均为初始化日期 edb, e, errMsg, _ := data.EdbInfoAdd(utils.DATA_SOURCE_TRADE_ANALYSIS, utils.DATA_SUB_SOURCE_EDB, v.ClassifyId, edbCode, v.EdbName, v.Frequency, v.Unit, utils.BASE_START_DATE, utils.BASE_START_DATE, sysUser.AdminId, sysUser.RealName, this.Lang) if e != nil { resp.Fail = append(resp.Fail, &tradeAnalysisModel.WarehouseEdbSaveRespItem{ WarehouseEdbSaveItem: *v, Tips: errMsg, ErrMsg: fmt.Sprintf("新增失败, %v", e), }) continue } edb.CalculateFormula = formula edb.ModifyTime = time.Now().Local() if e = edb.Update(edbUpdateCols); e != nil { resp.Fail = append(resp.Fail, &tradeAnalysisModel.WarehouseEdbSaveRespItem{ WarehouseEdbSaveItem: *v, Tips: "更新失败", ErrMsg: fmt.Sprintf("更新指标计算公式失败, %v", e), }) continue } newEdbIds = append(newEdbIds, edb.EdbInfoId) edbInfo = edb // 新增指标的刷新走异步吧, 指标如果没数据, 用户自己删了就行 newEdbRefresh = append(newEdbRefresh, edbInfo) } v.EdbInfoId = edbInfo.EdbInfoId resp.Success = append(resp.Success, &tradeAnalysisModel.WarehouseEdbSaveRespItem{ WarehouseEdbSaveItem: *v, Tips: "操作成功", }) } // 移除关联的指标 if len(removeIds) > 0 { if e = data_manage.DeleteMultipleGraphConfigEdbMappingByEdbIds(req.MultipleGraphConfigId, utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS, removeIds); e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("移除配置与指标关联失败, %v", e) return } } // 新增指标关联 if !req.IsSaveAs && len(newEdbIds) > 0 { newMultiEdb := make([]*data_manage.MultipleGraphConfigEdbMapping, 0) for _, v := range newEdbIds { newMultiEdb = append(newMultiEdb, &data_manage.MultipleGraphConfigEdbMapping{ MultipleGraphConfigId: req.MultipleGraphConfigId, EdbInfoId: v, Source: utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS, ModifyTime: time.Now(), CreateTime: time.Now(), }) } if len(newMultiEdb) > 0 { if e = data_manage.AddMultipleGraphConfigEdbMappingList(newMultiEdb); e != nil { br.Msg = "操作失败" br.ErrMsg = fmt.Sprintf("新增指标关联失败, %v", e) return } } } // 异步刷新新增指标 if len(newEdbRefresh) > 0 { go func() { var refreshTips string for _, edb := range newEdbRefresh { _, e = data.RefreshEdbData(edb.EdbInfoId, edb.Source, edb.SubSource, edb.EdbCode, utils.BASE_START_DATE) if e != nil { refreshTips += fmt.Sprintf("刷新指标失败: %s, err: %v\n", edb.EdbCode, e) } } if refreshTips != "" { utils.FileLog.Info(refreshTips) alarm_msg.SendAlarmMsg(refreshTips, 2) } }() } br.Data = resp br.Ret = 200 br.Success = true br.Msg = "保存成功" br.IsAddLog = true }