package controllers import ( "encoding/json" "eta_gn/eta_chart_lib/models" "eta_gn/eta_chart_lib/models/data_manage" "eta_gn/eta_chart_lib/models/data_manage/cross_variety/request" "eta_gn/eta_chart_lib/models/data_manage/excel" "eta_gn/eta_chart_lib/services/data" "eta_gn/eta_chart_lib/services/data/cross_variety" "eta_gn/eta_chart_lib/services/data/range_analysis" dwmini "eta_gn/eta_chart_lib/services/dw_mini" "eta_gn/eta_chart_lib/utils" "fmt" "strings" "time" ) // 图表 type ChartController struct { BaseAuthController } // ChartInfoDetail // @Title 获取图表详情 // @Description 获取图表详情接口 // @Param UniqueCode query string true "图表唯一编码,如果是管理后台访问,传固定字符串:7c69b590249049942070ae9dcd5bf6dc" // @Success 200 {object} data_manage.ChartInfoDetailResp // @router /detail [get] func (this *ChartController) ChartInfoDetail() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() uniqueCode := this.GetString("UniqueCode") token := this.GetString("Token") source, _ := this.GetInt("Source") if uniqueCode == "" { br.Msg = "参数错误" br.ErrMsg = "参数错误,uniqueCode is empty" return } key := utils.HZ_CHART_LIB_DETAIL + uniqueCode resp := new(models.ChartInfoDetailResp) // 图表水印 conf, e := models.GetBusinessConf() if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取配置信息失败, Err: " + e.Error() return } var isCollect bool if source == utils.CHART_SOURCE_DW && token != "" { tmpIsCollect, err := dwmini.GetMyChartIsCollect(token, uniqueCode) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取收藏状态失败,Err:" + err.Error() return } isCollect = tmpIsCollect } //判断是否有缓存 if utils.Re == nil { if utils.Re == nil && utils.Rc.IsExist(key) { if data, err1 := utils.Rc.RedisBytes(key); err1 == nil { err := json.Unmarshal(data, &resp) if err == nil && resp != nil { if conf[models.BusinessConfWatermarkChart] == "true" && conf[models.BusinessConfCompanyWatermark] != "" { resp.WaterMark = conf[models.BusinessConfCompanyWatermark] } if isCollect { resp.IsCollect = isCollect } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp fmt.Println("source redis") return } } } } chartInfo, err := models.GetChartInfoByUniqueCode(uniqueCode) if err != nil { if utils.IsErrNoRow(err) { br.Msg = "该图已被删除,请刷新页面" br.ErrMsg = "该图已被删除,请刷新页面,Err:" + err.Error() return } br.Msg = "获取失败" br.ErrMsg = "获取图表信息失败,Err:" + err.Error() return } //var resp interface{} var isOk bool var msg, errMsg string switch chartInfo.Source { case utils.CHART_SOURCE_DEFAULT: resp, isOk, msg, errMsg = GetChartInfoDetailFromUniqueCode(chartInfo, key) case utils.CHART_SOURCE_FUTURE_GOOD: resp, isOk, msg, errMsg = GetFutureGoodChartInfoDetailFromUniqueCode(chartInfo, key) case utils.CHART_SOURCE_FUTURE_GOOD_PROFIT: resp, isOk, msg, errMsg = GetFutureGoodProfitChartInfoDetailFromUniqueCode(chartInfo, key) case utils.CHART_SOURCE_CORRELATION, utils.CHART_SOURCE_ROLLING_CORRELATION: resp, isOk, msg, errMsg = GetCorrelationChartInfoDetailFromUniqueCode(chartInfo, key) case utils.CHART_SOURCE_LINE_EQUATION: resp, isOk, msg, errMsg = GetLineEquationChartInfoDetailFromUniqueCode(chartInfo, key) case utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE, utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY: resp, isOk, msg, errMsg = GetLineFeatureChartInfoDetailFromUniqueCode(chartInfo, key) case utils.CHART_SOURCE_CROSS_HEDGING: resp, isOk, msg, errMsg = GetCrossVarietyChartInfoDetailFromUniqueCode(chartInfo, key) case utils.CHART_SOURCE_BALANCE_EXCEL: resp, isOk, msg, errMsg = GetBalanceChartInfoDetailFromUniqueCode(chartInfo, key, this.Lang) if !isOk { br.Msg = msg br.ErrMsg = errMsg return } case utils.CHART_SOURCE_RANGE_ANALYSIS: resp, isOk, msg, errMsg = GetRangeAnalysisChartInfoDetailFromUniqueCode(chartInfo, key, this.Lang) if !isOk { br.Msg = msg br.ErrMsg = errMsg return } default: br.Msg = "错误的图表" br.ErrMsg = "错误的图表" return } if !isOk { br.Msg = msg br.ErrMsg = errMsg return } if isCollect { resp.IsCollect = isCollect } if conf[models.BusinessConfWatermarkChart] == "true" && conf[models.BusinessConfCompanyWatermark] != "" { resp.WaterMark = conf[models.BusinessConfCompanyWatermark] } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // ChartInfoRefresh // @Title 图表刷新接口 // @Description 图表刷新接口 // @Param UniqueCode query string true "图表唯一编码,如果是管理后台访问,传固定字符串:7c69b590249049942070ae9dcd5bf6dc" // @Success Ret=200 刷新成功 // @router /refresh [get] func (this *ChartController) ChartInfoRefresh() { br := new(models.BaseResponse).Init() chartId := 0 defer func() { // 添加日志 if chartId > 0 { shareChartRefreshLogInfo := &models.ShareChartRefreshLog{ Ip: this.Ctx.Input.IP(), ChartId: chartId, CreateTime: time.Now(), } models.AddShareChartRefreshLog(shareChartRefreshLogInfo) } this.Data["json"] = br this.ServeJSON() }() uniqueCode := this.GetString("UniqueCode") if uniqueCode == "" { br.Msg = "参数错误" br.ErrMsg = "参数错误,uniqueCode is empty" return } chartInfo, err := models.GetChartInfoByUniqueCode(uniqueCode) if err != nil { if utils.IsErrNoRow(err) { br.Msg = "该图已被删除,请刷新页面" br.ErrMsg = "该图已被删除,请刷新页面,Err:" + err.Error() return } br.Msg = "获取失败" br.ErrMsg = "获取图表信息失败,Err:" + err.Error() return } chartId = chartInfo.ChartInfoId switch chartInfo.Source { case utils.CHART_SOURCE_CROSS_HEDGING: var config request.ChartConfigReq err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &config) if err != nil { br.Msg = "解析跨品种分析配置失败" br.ErrMsg = "解析跨品种分析配置失败,Err:" + err.Error() return } // 获取关联的指标信息 _, _, edbInfoIdList, tmpErr := cross_variety.GetXYEdbIdList(config.TagX, config.TagY, config.VarietyList) if tmpErr != nil { br.Msg = "刷新失败,获取指标信息失败" br.ErrMsg = "刷新失败,获取指标信息失败,Err:" + tmpErr.Error() return } err, _ = data.EdbInfoRefreshAllFromBase(edbInfoIdList, false) case utils.CHART_SOURCE_BALANCE_EXCEL: excelDetail, err := excel.GetExcelInfoByChartInfoId(chartInfo.ChartInfoId) if err != nil { br.Msg = "图表数据异常" br.ErrMsg = "未找到对应的表格" + err.Error() br.IsSendEmail = false return } err = refreshBalanceTable(excelDetail, this.Lang) if err != nil { br.Msg = "刷新失败" br.ErrMsg = "刷新失败,Err:" + err.Error() return } case utils.CHART_SOURCE_RANGE_ANALYSIS: //// 刷新相关性图表 if _, e := range_analysis.ChartInfoRefresh(chartInfo.ChartInfoId, ""); e != nil { br.Msg = "刷新失败" br.ErrMsg = "刷新相关性图表失败, Err:" + e.Error() return } default: err = data.ChartInfoRefreshV2(chartInfo.ChartInfoId) } if err != nil { br.Msg = "刷新失败" br.ErrMsg = "刷新图表关联指标信息失败,Err:" + err.Error() return } //清除数据缓存 key := utils.HZ_CHART_LIB_DETAIL + uniqueCode if utils.Re == nil { utils.Rc.Delete(key) } br.Ret = 200 br.Success = true br.Msg = "刷新成功" } // CollectCancel // @Title 东吴小程序图表取消收藏接口 // @Description 东吴小程序图表取消收藏接口 // @Param request body models.ChartDwCollectReq true "type json string" // @Success Ret=200 取消收藏成功 // @router /dw/collectCancel [post] func (this *ChartController) CollectCancel() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() var req models.ChartDwCollectReq if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数错误" br.ErrMsg = "参数错误,Err:" + err.Error() return } if req.UniqueCode == "" { br.Msg = "参数错误" br.ErrMsg = "参数错误,UniqueCode is empty" return } if req.Token == "" { br.Msg = "参数错误" br.ErrMsg = "参数错误,Token is empty" return } result, err := dwmini.MyChartCollectCancel(req.Token, req.UniqueCode) if err != nil { br.Msg = "取消收藏失败" br.ErrMsg = "取消收藏失败,Err:" + err.Error() return } if result.Ret != 200 { br.Msg = result.Msg br.ErrMsg = "取消收藏失败,Err:" + result.ErrMsg return } br.Ret = 200 br.Success = true br.Msg = "取消收藏成功" } // Collect // @Title 东吴小程序图表收藏接口 // @Description 东吴小程序图表收藏接口 // @Param request body models.ChartDwCollectReq true "type json string" // @Success Ret=200 收藏成功 // @router /dw/collect [post] func (this *ChartController) Collect() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() var req models.ChartDwCollectReq if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数错误" br.ErrMsg = "参数错误,Err:" + err.Error() return } if req.UniqueCode == "" { br.Msg = "参数错误" br.ErrMsg = "参数错误,UniqueCode is empty" return } if req.Token == "" { br.Msg = "参数错误" br.ErrMsg = "参数错误,Token is empty" return } chartInfo, err := models.GetChartInfoByUniqueCode(req.UniqueCode) if err != nil { if utils.IsErrNoRow(err) { br.Msg = "该图已被删除,请刷新页面" br.ErrMsg = "该图已被删除,请刷新页面,Err:" + err.Error() return } br.Msg = "获取失败" br.ErrMsg = "获取图表信息失败,Err:" + err.Error() return } result, err := dwmini.MyChartCollect(req.Token, req.UniqueCode, chartInfo.ChartName, chartInfo.ChartImage, chartInfo.ChartInfoId) if err != nil { br.Msg = "收藏失败" br.ErrMsg = "收藏失败,Err:" + err.Error() return } if result.Ret != 200 { br.Msg = result.Msg br.ErrMsg = "收藏失败,Err:" + result.ErrMsg return } br.Ret = 200 br.Success = true br.Msg = "收藏成功" } // 获取频度的英文版 func GetFrequencyEn(frequency string) (frequencyEn string) { switch frequency { case "日度": frequencyEn = "day" return case "周度": frequencyEn = "week" return case "旬度": frequencyEn = "ten days" return case "月度": frequencyEn = "month" return case "季度": frequencyEn = "quarter" return case "年度": frequencyEn = "year" return } return } func GetLeadUnitEn(unit string) (unitEn string) { switch unit { case "天": unitEn = "day" return case "周": unitEn = "week" return case "月": unitEn = "month" return case "季": unitEn = "quarter" return case "年": unitEn = "year" return } return } // GetChartInfoDetailFromUniqueCode 根据编码获取图表详情 func GetChartInfoDetailFromUniqueCode(chartInfo *models.ChartInfo, key string) (resp *models.ChartInfoDetailResp, isOk bool, msg, errMsg string) { resp = new(models.ChartInfoDetailResp) // 获取主题样式 chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, chartInfo.Source, chartInfo.ChartType) if err != nil { msg = "获取失败" errMsg = "获取主题信息失败,Err:" + err.Error() return } chartInfo.ChartThemeStyle = chartTheme.Config chartInfo.ChartThemeId = chartTheme.ChartThemeId chartInfoId := chartInfo.ChartInfoId dateType := chartInfo.DateType if dateType <= 0 { dateType = 3 } startDate := chartInfo.StartDate endDate := chartInfo.EndDate startYear := chartInfo.StartYear calendar := chartInfo.Calendar chartType := chartInfo.ChartType if calendar == "" { calendar = "公历" } mappingList, err := models.GetChartEdbMappingList(chartInfoId) if err != nil { msg = "获取失败" errMsg = "获取图表,指标信息失败,Err:" + err.Error() return } yearMax := 0 if dateType == utils.DateTypeNYears { for _, v := range mappingList { v.ConvertToResp() if v.LatestDate != "" { lastDateT, tErr := time.Parse(utils.FormatDate, v.LatestDate) if tErr != nil { msg = "获取失败" errMsg = "获取图表日期信息失败,Err:" + tErr.Error() return } if lastDateT.Year() > yearMax { yearMax = lastDateT.Year() } } } } startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, yearMax) extraConfigStr := chartInfo.ExtraConfig // 柱方图的一些配置 var barConfig data_manage.BarChartInfoReq if chartInfo != nil && chartInfo.ChartType == 7 { if chartInfo.BarConfig == `` { msg = "柱方图未配置" errMsg = "柱方图未配置" return } err := json.Unmarshal([]byte(chartInfo.BarConfig), &barConfig) if err != nil { msg = "柱方图配置异常" errMsg = "柱方图配置异常" return } extraConfigStr = chartInfo.BarConfig } edbList, xEdbIdValue, yDataList, dataResp, err, tmpErrMsg := data.GetChartEdbData(chartInfoId, chartType, calendar, startDate, endDate, mappingList, extraConfigStr, chartInfo.SeasonExtraConfig) if err != nil { msg = "获取失败" if tmpErrMsg != `` { msg = tmpErrMsg } errMsg = "获取图表,指标信息失败,Err:" + err.Error() return } for _, v := range edbList { // 指标别名 if barConfig.EdbInfoIdList != nil && len(barConfig.EdbInfoIdList) > 0 { for _, reqEdb := range barConfig.EdbInfoIdList { if v.EdbInfoId == reqEdb.EdbInfoId { v.EdbAliasName = reqEdb.Name } } } } // 图表的指标来源 sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList) chartInfo.ChartSource = strings.Join(sourceNameList, ",") chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",") resp.ChartInfo = chartInfo resp.EdbInfoList = edbList resp.XEdbIdValue = xEdbIdValue resp.YDataList = yDataList resp.DataResp = dataResp if utils.Re == nil { jsonData, _ := json.Marshal(resp) utils.Rc.Put(key, jsonData, 10*time.Minute) } isOk = true return }