package chart import ( "context" "encoding/json" "fmt" "github.com/gin-gonic/gin" "hongze/hongze_yb/controller/response" "hongze/hongze_yb/global" "hongze/hongze_yb/models/request" responseModel "hongze/hongze_yb/models/response" "hongze/hongze_yb/models/response/chart_info" chartEdbMappingModel "hongze/hongze_yb/models/tables/chart_edb_mapping" chartInfoModel "hongze/hongze_yb/models/tables/chart_info" "hongze/hongze_yb/models/tables/chart_info_log" edbInfoModel "hongze/hongze_yb/models/tables/edb_info" "hongze/hongze_yb/models/tables/yb_my_chart" "hongze/hongze_yb/services" "hongze/hongze_yb/services/alarm_msg" "hongze/hongze_yb/services/chart" "hongze/hongze_yb/services/chart/cross_variety" "hongze/hongze_yb/services/user" "hongze/hongze_yb/utils" "sort" "strconv" "strings" "time" ) // GetChartInfoDetail 获取图表详情 // @Tags 图库模块 // @Summary 获取图表详情 // @Description 获取图表详情 // @Security ApiKeyAuth // @Param Authorization header string true "Bearer 31a165baebe6dec616b1f8f3207b4273" // @Accept json // @Product json // @Param DateType query string false "时间段:1-00年至今; 2-10年至今; 3-15年至今; 4-21年至今; 5-指定区间; 6-指定年月至今; 7-18年至今; 8-19年至今; 9-20年至今" // @Param ClassifyId query string false "图表分类ID" // @Success 200 {object} chart_info.ChartInfoDetailResp // @failure 400 {string} string "图表详情获取失败" // @Router /my_chart/getChartInfoDetail [get] func GetChartInfoDetail(c *gin.Context) { // 图表ID reqChartInfoId := c.DefaultQuery("ChartInfoId", "") if reqChartInfoId == "" { response.Fail("参数有误:图表ID", c) return } chartInfoId, _ := strconv.Atoi(reqChartInfoId) reqStartDate := c.DefaultQuery("StartDate", "") reqEndDate := c.DefaultQuery("EndDate", "") // 图表样式类型 reqChartType := c.DefaultQuery("ChartType", "") chartType, _ := strconv.Atoi(reqChartType) /*// 季节性图表时间 reqSeasonStartDate := c.DefaultQuery("SeasonStartDate", "") reqSeasonEndDate := c.DefaultQuery("SeasonEndDate", "")*/ // 指标ID edbInfoId := c.DefaultQuery("EdbInfoId", "") // 公历/农历 reqCalendar := c.DefaultQuery("Calendar", "") // 获取图表信息 var err error chartInfo := new(chartInfoModel.ChartInfoView) chartInfo, err = chartInfoModel.GetChartInfoViewById(chartInfoId) if err != nil { if err == utils.ErrNoRow { response.Custom(4003, "图表不存在,请刷新页面", c) return } response.FailMsg("获取失败", "获取图表信息失败, Err:"+err.Error(), c) return } var ( edbList []*chartEdbMappingModel.ChartEdbInfoMappingList xEdbIdValue []int yDataList []chart_info.YData sourceArr []string dataResp interface{} ) // todo 特殊处理平衡表 if chartInfo.Source == utils.CHART_SOURCE_BALANCE_EXCEL { //调用接口 chartData, e := services.GetBalanceChartDetail(chartInfo.UniqueCode) if e != nil { response.FailMsg("获取失败", "获取图表信息失败, Err:"+e.Error(), c) return } chartDataResp := new(chart_info.ChartInfoDetailResp) // 兼容返回值类型 chartDataString, _ := json.Marshal(chartData) err = json.Unmarshal(chartDataString, chartDataResp) if err != nil { response.FailMsg("获取失败", "获取图表信息失败, Err:"+err.Error(), c) return } chartInfo = chartDataResp.ChartInfo chartInfo.ChartInfoId = chartInfoId yDataList = chartDataResp.YDataList edbList = chartDataResp.EdbInfoList xEdbIdValue = chartDataResp.XEdbIdValue sourceArr = append(sourceArr, "平衡表") dataResp = chartDataResp.DataResp } else { // 获取主题样式 chartTheme, err := chart.GetChartThemeConfig(chartInfo.ChartThemeId, chartInfo.Source, chartInfo.ChartType) if err != nil { response.FailMsg("获取失败", "获取主题信息失败, Err:"+err.Error(), c) return } chartInfo.ChartThemeStyle = chartTheme.Config chartInfo.ChartThemeId = chartTheme.ChartThemeID chartType = chartInfo.ChartType startDate := chartInfo.StartDate endDate := chartInfo.EndDate startYear := chartInfo.StartYear calendar := chartInfo.Calendar if reqCalendar != "" { calendar = reqCalendar } // 时段筛选 reqDateType := c.DefaultQuery("DateType", "") dateType := chartInfo.DateType if reqDateType != "" { dateType, _ = strconv.Atoi(reqDateType) } if dateType <= 0 { dateType = 3 // 默认同后台15年至今 } if reqStartDate != "" { startDate = reqStartDate } if reqEndDate != "" { endDate = reqEndDate } // 获取图表指标映射 mappingList := make([]*chartEdbMappingModel.ChartEdbInfoMapping, 0) if chartInfoId > 0 { mappingList, err = chartEdbMappingModel.GetMappingListByChartInfoId(chartInfoId) if err != nil { response.FailMsg("获取失败", "获取图表指标信息失败4001, Err:"+err.Error(), c) return } } else { if edbInfoId != "" { mappingList, err = chartEdbMappingModel.GetMappingListByEdbInfoId(edbInfoId) if err != nil { response.FailMsg("获取失败", "获取图表指标信息失败4002, Err:"+err.Error(), c) return } } } yearMax := 0 if dateType == utils.DateTypeNYears { for _, v := range mappingList { if v.LatestDate.Year() > yearMax { yearMax = v.LatestDate.Year() } } } startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, yearMax) // 图表额外数据参数 extraConfigStr := chartInfo.ExtraConfig // 柱方图的一些配置 var barConfig request.BarChartInfoReq if chartInfo != nil && chartInfo.ChartType == 7 { if chartInfo.BarConfig == `` { response.FailMsg("柱方图未配置", "柱方图未配置", c) return } err = json.Unmarshal([]byte(chartInfo.BarConfig), &barConfig) if err != nil { response.FailMsg("柱方图配置异常", "柱方图配置异常", c) return } extraConfigStr = chartInfo.BarConfig } var errMsg string // 获取图表中的指标数据 edbList, xEdbIdValue, yDataList, sourceArr, dataResp, err, errMsg = chart.GetChartEdbData(chartInfoId, chartType, calendar, startDate, endDate, mappingList, extraConfigStr, chartInfo.SeasonExtraConfig) if err != nil { msg := `获取失败` if errMsg != `` { msg = errMsg } response.FailMsg(msg, "获取图表,指标信息失败, Err:"+err.Error(), c) 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 := chart.GetEdbSourceByEdbInfoIdList(edbList) chartInfo.ChartSource = strings.Join(sourceNameList, ",") chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",") } sourceArr = append(sourceArr, "弘则研究") chartInfo.ChartSource = strings.Join(sourceArr, ",") // 访问记录-仅普通用户记录 userInfo := user.GetInfoByClaims(c) ok, _, _ := user.GetAdminByUserInfo(userInfo) if !ok { reqMyChartClassifyId := c.DefaultQuery("MyChartClassifyId", "") myChartClassifyId, _ := strconv.Atoi(reqMyChartClassifyId) go chart.SaveChartVisitLog(userInfo, chartInfo, myChartClassifyId) } // 用户是否有收藏该图表 ob := new(yb_my_chart.YbMyChart) cond := `user_id = ? AND chart_info_id = ?` pars := make([]interface{}, 0) pars = append(pars, userInfo.UserID, chartInfo.ChartInfoId) exists, e := ob.FetchByCondition(cond, pars) if e != nil && e != utils.ErrNoRow { response.FailMsg("操作失败", "获取用户图表失败, Err: "+e.Error(), c) return } myChartInfo := new(responseModel.MyChartItem) if exists != nil && exists.MyChartID > 0 { myChartInfo.MyChartID = exists.MyChartID myChartInfo.MyChartClassifyID = exists.MyChartClassifyID myChartInfo.ChartInfoID = exists.ChartInfoID myChartInfo.ChartName = exists.ChartName myChartInfo.UniqueCode = exists.UniqueCode myChartInfo.ChartImage = exists.ChartImage myChartInfo.UserID = exists.UserID myChartInfo.ReportID = exists.ReportID myChartInfo.ReportChapterID = exists.ReportChapterID myChartInfo.CreateTime = utils.TimeTransferString(utils.FormatDateTime, exists.CreateTime) } resp := new(chart_info.ChartInfoDetailResp) resp.ChartInfo = chartInfo resp.EdbInfoList = edbList resp.XEdbIdValue = xEdbIdValue resp.YDataList = yDataList resp.MyChartInfo = myChartInfo resp.DataResp = dataResp response.OkData("获取成功", resp, c) } func getChartInfoDetail(chartInfo *chartInfoModel.ChartInfoView, myChartClassifyId int, userInfo user.UserInfo) (resp *chart_info.ChartInfoDetailResp, isOk bool, msg, errMsg string) { // 获取图表信息 var err error chartType := chartInfo.ChartType calendar := chartInfo.Calendar startDate := chartInfo.StartDate endDate := chartInfo.EndDate startYear := chartInfo.StartYear // 时段筛选 dateType := chartInfo.DateType if dateType <= 0 { dateType = 3 // 默认同后台15年至今 } // 获取图表指标映射 mappingList := make([]*chartEdbMappingModel.ChartEdbInfoMapping, 0) mappingList, err = chartEdbMappingModel.GetMappingListByChartInfoId(chartInfo.ChartInfoId) if err != nil { msg = `获取失败` errMsg = "获取图表指标信息失败4001, Err:" + err.Error() return } yearMax := 0 if dateType == utils.DateTypeNYears { for _, v := range mappingList { if v.LatestDate.Year() > yearMax { yearMax = v.LatestDate.Year() } } } startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, yearMax) //fmt.Println("start_date:", startDate) //fmt.Println("end_date:", endDate) // 图表额外数据参数 extraConfigStr := chartInfo.ExtraConfig // 柱方图的一些配置 var barConfig request.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, sourceArr, dataResp, err, tmpErrMsg := chart.GetChartEdbData(chartInfo.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 } } } } sourceArr = append(sourceArr, "弘则研究") chartInfo.ChartSource = strings.Join(sourceArr, ",") // 访问记录-仅普通用户记录 ok, _, _ := user.GetAdminByUserInfo(userInfo) if !ok { go chart.SaveChartVisitLog(userInfo, chartInfo, myChartClassifyId) } // 用户是否有收藏该图表 ob := new(yb_my_chart.YbMyChart) cond := `user_id = ? AND chart_info_id = ?` pars := make([]interface{}, 0) pars = append(pars, userInfo.UserID, chartInfo.ChartInfoId) exists, e := ob.FetchByCondition(cond, pars) if e != nil && e != utils.ErrNoRow { msg = `操作失败` errMsg = "获取用户图表失败, Err: " + e.Error() return } myChartInfo := new(responseModel.MyChartItem) if exists != nil && exists.MyChartID > 0 { myChartInfo.MyChartID = exists.MyChartID myChartInfo.MyChartClassifyID = exists.MyChartClassifyID myChartInfo.ChartInfoID = exists.ChartInfoID myChartInfo.ChartName = exists.ChartName myChartInfo.UniqueCode = exists.UniqueCode myChartInfo.ChartImage = exists.ChartImage myChartInfo.UserID = exists.UserID myChartInfo.ReportID = exists.ReportID myChartInfo.ReportChapterID = exists.ReportChapterID myChartInfo.CreateTime = utils.TimeTransferString(utils.FormatDateTime, exists.CreateTime) } resp = new(chart_info.ChartInfoDetailResp) resp.ChartInfo = chartInfo resp.EdbInfoList = edbList resp.XEdbIdValue = xEdbIdValue resp.YDataList = yDataList resp.MyChartInfo = myChartInfo resp.DataResp = dataResp isOk = true return } // RefreshChartInfo 刷新图表信息 // @Tags 图库模块 // @Summary 刷新图表信息 // @Description 刷新图表信息 // @Security ApiKeyAuth // @Param Authorization header string true "Bearer 31a165baebe6dec616b1f8f3207b4273" // @Accept json // @Product json // @Param data body chartInfoModel.SaveChartInfoReq true "请求参数" // @Success 200 {string} string "操作成功" // @failure 400 {string} string "操作失败" // @Router /my_chart/refreshChartInfo [post] func RefreshChartInfo(c *gin.Context) { // 参数校验 var req chartInfoModel.RefreshChartInfoReq if c.ShouldBind(&req) != nil { response.Fail("参数异常", c) return } chartInfoId := req.ChartInfoId if chartInfoId == 0 { response.Fail("参数有误", c) return } userInfo := user.GetInfoByClaims(c) ok, _, err := user.GetAdminByUserInfo(userInfo) if err != nil { response.FailMsg("刷新失败", "RefreshChartInfo-获取系统用户信息失败"+err.Error(), c) return } if !ok { // 普通用户刷新频率限制-每个用户/图/天/2次 cacheKey := utils.HZ_CHART_LIB_DETAIL + "YB_REFRESH_LIMIT_" + strconv.Itoa(chartInfoId) + "_" + strconv.Itoa(int(userInfo.UserID)) fmt.Println("refreshCacheKey:", cacheKey) countUserRefresh, _ := global.Redis.Get(context.TODO(), cacheKey).Int() if countUserRefresh >= 2 { response.Ok("目前已是最新数据", c) return } countUserRefresh += 1 now := time.Now() today := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, time.Local) sub := today.Sub(now) _ = global.Redis.SetEX(context.TODO(), cacheKey, countUserRefresh, sub) } // 图表信息校验 chartInfo, err := chartInfoModel.GetChartInfoById(chartInfoId) if err != nil { if err == utils.ErrNoRow { response.Fail("图表已被删除,无需刷新", c) return } response.FailMsg("刷新失败", "刷新失败, Err:"+err.Error(), c) return } if chartInfo.Source == utils.CHART_SOURCE_CROSS_HEDGING { var config request.ChartConfigReq err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &config) if err != nil { response.FailMsg("解析跨品种分析配置失败", "解析跨品种分析配置失败, Err:"+err.Error(), c) return } // 获取关联的指标信息 _, _, edbInfoIdList, err := cross_variety.GetXYEdbIdList(config.TagX, config.TagY, config.VarietyList) if err != nil { response.FailMsg("获取指标信息失败", "刷新失败,获取指标信息失败, Err:"+err.Error(), c) return } // 刷新图表 //_ = correlation.ChartInfoRefresh(chartInfo.ChartInfoId) err, errMsg := chart.EdbInfoRefreshAllFromBase(edbInfoIdList, false) if err != nil { errContent := fmt.Sprint("刷新图表关联指标信息失败 errMsg:", errMsg, "err: "+err.Error()) if global.CONFIG.Serve.RunMode == "release" { go alarm_msg.SendAlarmMsg("刷新图表报错"+time.Now().Format("2006-01-02 15:04:05")+";Err:"+errContent, 3) //go services.SendEmail("弘则研报小程序-release-刷新图表报错", errContent, utils.EmailSendToUsers) } else { global.LOG.Info(errContent) } response.FailMsg("刷新失败", "刷新失败,获取指标信息失败, Err:"+err.Error(), c) return } } else { // 刷新图表 if err = chart.ChartInfoRefreshV2(chartInfo.ChartInfoId); err != nil { errContent := fmt.Sprint("ErrMsg: 刷新图表关联指标信息失败, " + err.Error()) if global.CONFIG.Serve.RunMode == "release" { go alarm_msg.SendAlarmMsg("刷新图表报错"+time.Now().Format("2006-01-02 15:04:05")+";Err:"+errContent, 3) //go services.SendEmail("弘则研报小程序-release-刷新图表报错", errContent, utils.EmailSendToUsers) } else { global.LOG.Info(errContent) } } } //清除图表缓存 { key := utils.HZ_CHART_LIB_DETAIL + chartInfo.UniqueCode _ = global.Redis.Del(context.TODO(), key) } response.OkData("刷新成功", "", c) } // EditChartInfo 编辑图表信息 // @Tags 图库模块 // @Summary 编辑图表信息 // @Description 编辑图表信息 // @Security ApiKeyAuth // @Param Authorization header string true "Bearer 31a165baebe6dec616b1f8f3207b4273" // @Accept json // @Product json // @Param data body chartInfoModel.SaveChartInfoReq true "请求参数" // @Success 200 {string} string "操作成功" // @failure 400 {string} string "操作失败" // @Router /my_chart/editChartInfo [post] func EditChartInfo(c *gin.Context) { // 参数校验 var req chartInfoModel.SaveChartInfoReq if c.ShouldBind(&req) != nil { response.Fail("参数异常", c) return } if req.ChartInfoId <= 0 { response.Fail("参数异常", c) return } // 操作权限校验 userInfo := user.GetInfoByClaims(c) ok, adminInfo, err := user.GetAdminByUserInfo(userInfo) if err != nil { response.Fail("操作人信息有误", c) return } if !ok { response.Fail("非内部人员无权进行操作", c) return } // 图表信息校验 chartItem, err := chartInfoModel.GetChartInfoById(req.ChartInfoId) if err != nil { if err == utils.ErrNoRow { response.Fail("图表已被删除,请刷新页面!", c) return } response.FailMsg("操作失败", "获取图表信息失败, Err:"+err.Error(), c) return } // 图表关联指标id chartEdbInfoList := make([]*chartInfoModel.ChartSaveItem, 0) // 关联指标 var edbInfoIdArr []int // 非散点截面图的直接通过前端获取,散点截面图需要额外从配置中获取 if chartItem.ChartType != 10 { //edbList := make([]*data_manage.EdbInfo, 0) for _, v := range req.ChartEdbInfoList { edbInfoId := v.EdbInfoId edbInfo, err := edbInfoModel.GetEdbInfoById(edbInfoId) if err != nil { if err == utils.ErrNoRow { response.FailMsg("操作失败", "图表不存在,ChartInfoId:"+strconv.Itoa(v.EdbInfoId), c) return } response.FailMsg("操作失败", "获取图表的指标信息失败,Err:"+err.Error(), c) return } if edbInfo == nil { response.FailMsg("操作失败", "指标不存在,ChartInfoId:"+strconv.Itoa(v.EdbInfoId), c) return } if edbInfo.EdbInfoId <= 0 { response.FailMsg("指标已被删除,请重新选择!", "指标不存在,ChartInfoId:"+strconv.Itoa(v.EdbInfoId), c) return } edbInfoIdArr = append(edbInfoIdArr, edbInfoId) edbInfo.EdbNameSource = edbInfo.EdbName //edbList = append(edbList, edbInfo) } chartEdbInfoList = req.ChartEdbInfoList } else { if req.ExtraConfig == `` { response.FailMsg("请选择指标!", "请选择指标!, Err:"+err.Error(), c) return } // 校验配置的指标列表 tmpEdbInfoIdArr, err, errMsg := chart.CheckChartExtraConfig(chartItem.ChartType, req.ExtraConfig) if err != nil { response.FailMsg(errMsg, "修改失败!, Err:"+err.Error(), c) return } edbInfoIdArr = tmpEdbInfoIdArr lenEdbInfoIdArr := len(edbInfoIdArr) if lenEdbInfoIdArr > 0 { tmpEdbList, err := edbInfoModel.GetEdbInfoByIdList(edbInfoIdArr) if err != nil { response.FailMsg("指标异常!", "指标异常!, Err:"+err.Error(), c) return } if len(tmpEdbList) != lenEdbInfoIdArr { response.FailMsg("指标异常!", fmt.Sprint("查找出来的指标数量与选择的指标数量不符!查找出来的指标数量:", len(tmpEdbList), ";用户选择的指标数量:", lenEdbInfoIdArr), c) return } for _, v := range tmpEdbList { chartEdbInfoList = append(chartEdbInfoList, &chartInfoModel.ChartSaveItem{ EdbInfoId: v.EdbInfoId, MaxData: 0, MinData: 0, IsOrder: false, IsAxis: 1, EdbInfoType: 1, LeadValue: 0, LeadUnit: "", ChartStyle: "", ChartColor: "", //PredictChartColor: "", ChartWidth: 0, Source: utils.CHART_SOURCE_DEFAULT, }) } } } if len(edbInfoIdArr) <= 0 { response.Fail("请选择指标!", c) return } if chartItem.ChartType == 2 && len(req.ChartEdbInfoList) > 1 { response.Fail("您选择的图表样式为季节性图表,只支持单指标画图!", c) return } if req.Calendar == "" { req.Calendar = "公历" } sort.Ints(edbInfoIdArr) var edbInfoIdArrStr []string for _, v := range edbInfoIdArr { edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v)) } edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",") err = chart.ModifyChartInfoAndMapping(edbInfoIdStr, &req, chartItem.ChartType, chartEdbInfoList) if err != nil { response.Fail("图表保存失败, Err:"+err.Error(), c) return } // 清除图表缓存 cacheKey := utils.HZ_CHART_LIB_DETAIL + chartItem.UniqueCode _ = global.Redis.Del(context.TODO(), cacheKey) // 新增操作日志 { chartLog := new(chart_info_log.ChartInfoLog) chartLog.ChartName = chartItem.ChartName chartLog.ChartInfoId = req.ChartInfoId chartLog.ChartClassifyId = chartItem.ChartClassifyId chartLog.SysUserId = int(adminInfo.AdminID) chartLog.SysUserRealName = adminInfo.RealName chartLog.UniqueCode = chartItem.UniqueCode chartLog.CreateTime = time.Now() bodyBytes, _ := json.Marshal(req) chartLog.Content = string(bodyBytes) chartLog.Status = "修改配置项" chartLog.Method = c.Request.URL.String() go chartLog.Create() } response.OkData("操作成功", "", c) }