瀏覽代碼

Merge branch 'master' into feature/eta1.9.6_chart_series

xyxie 5 月之前
父節點
當前提交
425aac7a91
共有 51 個文件被更改,包括 2532 次插入690 次删除
  1. 1 0
      .gitignore
  2. 2 1
      config/config.go
  3. 42 15
      controller/chart/chart_common.go
  4. 1 1
      controller/fe_calendar/fe_calendar.go
  5. 69 51
      controller/pc/pc.go
  6. 1 0
      controller/report/report.go
  7. 11 6
      controller/user/user.go
  8. 0 1
      latest_mongolog
  9. 1 1
      logic/public.go
  10. 1 1
      logic/user/user.go
  11. 1 1
      logic/yb_community_question/yb_community_question_comment.go
  12. 510 0
      models/mgo/edb_data_ths_hf.go
  13. 17 0
      models/request/chart.go
  14. 1 0
      models/response/chart_info/chart_info.go
  15. 23 0
      models/response/pc/report.go
  16. 63 33
      models/response/report.go
  17. 13 0
      models/tables/chart_edb_mapping/query.go
  18. 48 2
      models/tables/edb_data/query.go
  19. 2 2
      models/tables/future_good_edb_data/future_good_edb_data.go
  20. 21 1
      models/tables/future_good_edb_data/query.go
  21. 4 4
      models/tables/future_good_edb_info/future_good_edb_info.go
  22. 0 0
      models/tables/rddp/chart_permission/chart_permission.go
  23. 9 9
      models/tables/rddp/chart_permission/query.go
  24. 0 0
      models/tables/rddp/chart_permission_chapter_mapping/chart_permission_chapter_mapping.go
  25. 7 7
      models/tables/rddp/chart_permission_chapter_mapping/query.go
  26. 32 29
      models/tables/rddp/classify/classify.go
  27. 28 0
      models/tables/rddp/classify/query.go
  28. 142 1
      models/tables/rddp/report/query.go
  29. 10 0
      models/tables/rddp/report/report.go
  30. 81 1
      models/tables/rddp/report_chapter/query.go
  31. 2 0
      models/tables/rddp/report_chapter/report_chapter.go
  32. 11 0
      models/tables/rddp/session/update.go
  33. 33 0
      models/tables/rddp/smart_report_resource/query.go
  34. 37 0
      models/tables/rddp/smart_report_resource/smart_report_resource.go
  35. 85 0
      models/tables/report_chapter_permission_mapping/query.go
  36. 31 0
      models/tables/report_chapter_permission_mapping/report_chapter_permission_mapping.go
  37. 13 0
      models/tables/user_record/query.go
  38. 40 15
      models/tables/yb_comment/query.go
  39. 432 234
      services/chart/future_good/chart_info.go
  40. 1 1
      services/community/video.go
  41. 90 88
      services/company/permission.go
  42. 35 40
      services/elastic/report.go
  43. 1 1
      services/pc/report.go
  44. 275 43
      services/report/report.go
  45. 236 54
      services/report/report_chapter.go
  46. 1 3
      services/report/report_view_record.go
  47. 2 4
      services/report/user_access_record.go
  48. 28 29
      services/user/user.go
  49. 31 5
      services/user/user_bind.go
  50. 4 4
      services/yb_common.go
  51. 3 2
      utils/constants.go

+ 1 - 0
.gitignore

@@ -8,3 +8,4 @@ latest_log
 latest_binlog
 hongze_yb
 /rdlucklog
+latest_mongolog

+ 2 - 1
config/config.go

@@ -11,7 +11,7 @@ type Config struct {
 	EsClient    EsClient    `mapstructure:"es_client" json:"es_client" yaml:"es_client"`
 	Mongo       Mongo       `mapstructure:"mongo" json:"mongo" yaml:"mongo"`
 	EtaChartLib EtaChartLib `mapstructure:"eta_chart_lib" json:"eta_chart_lib" yaml:"eta_chart_lib"`
-	System   System   `mapstructure:"system" json:"system" yaml:"system"`
+	System      System      `mapstructure:"system" json:"system" yaml:"system"`
 }
 
 // Serve gin服务配置
@@ -21,6 +21,7 @@ type Serve struct {
 	UseRedis  bool   `mapstructure:"use-redis" json:"use-redis" yaml:"use-redis" description:"是否使用redis"`
 	AppName   string `mapstructure:"app-name" json:"app-name" yaml:"app-name" description:"项目名称"`
 	StaticDir string `mapstructure:"static-dir" json:"static-dir" yaml:"static-dir" description:"上传的文件存储目录地址"`
+	UseMongo  bool   `mapstructure:"use-mongo" json:"use-mongo" yaml:"use-mongo" description:"是否使用mongo"`
 }
 
 // Log 日志配置

+ 42 - 15
controller/chart/chart_common.go

@@ -156,7 +156,8 @@ func getFutureGoodChartInfoDetail(chartInfo *chartInfoModel.ChartInfoView, myCha
 		}
 	}
 
-	edbInfoMapping, err := chartEdbMappingModel.GetEtaEdbChartEdbMapping(chartInfoId)
+	//edbInfoMapping, err := chartEdbMappingModel.GetEtaEdbChartEdbMapping(chartInfoId)
+	edbInfoMappingList, err := chartEdbMappingModel.GetEtaEdbChartEdbMappingList(chartInfoId)
 	if err != nil {
 		msg = "获取失败"
 		errMsg = "获取图表,现货指标信息失败,Err:" + err.Error()
@@ -170,8 +171,7 @@ func getFutureGoodChartInfoDetail(chartInfo *chartInfoModel.ChartInfoView, myCha
 	}
 
 	// 商品价格曲线图的一些配置
-	var barConfig request.BarChartInfoReq
-	barChartInfoDateList := make([]request.BarChartInfoDateReq, 0)
+	var barConfig request.FutureGoodBarChartInfoReq
 	//barChartInfoSort := request.BarChartInfoSortReq{}
 
 	if chartInfo.BarConfig == `` {
@@ -185,12 +185,24 @@ func getFutureGoodChartInfoDetail(chartInfo *chartInfoModel.ChartInfoView, myCha
 		errMsg = "商品价格曲线图配置异常"
 		return
 	}
-
-	barChartInfoDateList = barConfig.DateList
-	//barChartInfoSort = barConfig.Sort
-
+	baseEdbInfoId := barConfig.BaseEdbInfoId
+	var baseEdbInfoMapping *chartEdbMappingModel.ChartEdbInfoMapping
+	// todo 兼容历史数据,
+	if baseEdbInfoId == 0 {
+		// 默认取第一个现货指标
+		baseEdbInfoId = edbInfoMappingList[0].EdbInfoId
+		baseEdbInfoMapping = &edbInfoMappingList[0].ChartEdbInfoMapping
+		barConfig.BaseEdbInfoId = baseEdbInfoId
+	} else {
+		baseEdbInfoMapping, err = chartEdbMappingModel.GetChartEdbMappingByEdbInfoId(baseEdbInfoId)
+		if err != nil {
+			msg = "获取失败"
+			errMsg = "获取图表,指标信息失败,Err:" + err.Error()
+			return
+		}
+	}
 	// 获取图表中的指标数据
-	barConfigEdbInfoIdList, edbList, xEdbIdValue, xDataList, yDataList, sourceArr, err := future_goodServ.GetChartEdbData(chartInfoId, startDate, endDate, edbInfoMapping, futureGoodEdbInfoMapping, barChartInfoDateList)
+	barConfigEdbInfoIdList, edbList, xEdbIdValue, xDataList, yDataList, sourceArr, err := future_goodServ.GetChartEdbData(chartInfoId, startDate, endDate, baseEdbInfoMapping, edbInfoMappingList, futureGoodEdbInfoMapping, barConfig, true)
 	if err != nil {
 		msg = "获取失败"
 		errMsg = "获取图表,指标信息失败,Err:" + err.Error()
@@ -216,7 +228,7 @@ func getFutureGoodChartInfoDetail(chartInfo *chartInfoModel.ChartInfoView, myCha
 			}
 		}
 	}
-	baseEdbInfo := edbList[0] //现货指标
+	baseEdbInfo := baseEdbInfoMapping //现货指标
 	chartInfo.UnitEn = baseEdbInfo.UnitEn
 
 	// 访问记录-仅普通用户记录
@@ -253,11 +265,19 @@ func getFutureGoodChartInfoDetail(chartInfo *chartInfoModel.ChartInfoView, myCha
 
 		resp.MyChartInfo = myChartInfo
 	}
-
+	xDataListFinal := make([]chart_info.XData, 0)
+	for _, v := range xDataList {
+		tmp := chart_info.XData{
+			Name:   v.Name,
+			NameEn: v.NameEn,
+			IsHide: v.IsHide,
+		}
+		xDataListFinal = append(xDataListFinal, tmp)
+	}
 	resp.ChartInfo = chartInfo
 	resp.EdbInfoList = edbList
 	resp.XEdbIdValue = xEdbIdValue
-	resp.XDataList = xDataList
+	resp.XDataList = xDataListFinal
 	resp.YDataList = yDataList
 
 	isOk = true
@@ -280,15 +300,23 @@ func getFutureGoodProfitChartInfoDetail(chartInfo *chartInfoModel.ChartInfoView,
 		errMsg = "商品利润曲线图配置异常,Err:" + err.Error()
 		return
 	}
-
+	if len(extraConf.EdbInfoIdList) == 0 {
+		extraConf.EdbInfoIdList = append(extraConf.EdbInfoIdList, extraConf.BaseEdbInfoId)
+	}
 	edbList := make([]*chartEdbMappingModel.ChartEdbInfoMappingList, 0)
-	edbInfoMapping, err := chartEdbMappingModel.GetEtaEdbChartEdbMapping(chartInfoId)
+	edbInfoMappingList, err := chartEdbMappingModel.GetEtaEdbChartEdbMappingList(chartInfoId)
 	if err != nil {
 		msg = "获取失败"
 		errMsg = "获取图表,现货指标信息失败,Err:" + err.Error()
 		return
 	}
-	edbList = append(edbList, edbInfoMapping)
+	edbList = edbInfoMappingList
+	baseEdbInfo := new(chartEdbMappingModel.ChartEdbInfoMapping)
+	for _, v := range edbInfoMappingList {
+		if v.EdbInfoId == extraConf.BaseEdbInfoId {
+			baseEdbInfo = &v.ChartEdbInfoMapping
+		}
+	}
 	futureGoodEdbInfoMappingList, err := chartEdbMappingModel.GetFutureGoodEdbChartEdbMappingList(chartInfoId)
 	if err != nil {
 		msg = "获取失败"
@@ -326,7 +354,6 @@ func getFutureGoodProfitChartInfoDetail(chartInfo *chartInfoModel.ChartInfoView,
 		return
 	}
 
-	baseEdbInfo := edbList[0] //现货指标
 	chartInfo.UnitEn = baseEdbInfo.UnitEn
 
 	sourceArr := []string{"同花顺"}

+ 1 - 1
controller/fe_calendar/fe_calendar.go

@@ -5,8 +5,8 @@ import (
 	"github.com/gin-gonic/gin"
 	"hongze/hongze_yb/controller/response"
 	"hongze/hongze_yb/models/request"
-	"hongze/hongze_yb/models/tables/chart_permission"
 	"hongze/hongze_yb/models/tables/fe_calendar_matter"
+	"hongze/hongze_yb/models/tables/rddp/chart_permission"
 	"hongze/hongze_yb/services/company"
 	userService "hongze/hongze_yb/services/user"
 	"hongze/hongze_yb/utils"

+ 69 - 51
controller/pc/pc.go

@@ -19,6 +19,7 @@ import (
 	"hongze/hongze_yb/models/tables/yb_pc_suncode"
 	"hongze/hongze_yb/services"
 	"hongze/hongze_yb/services/pc"
+	report2 "hongze/hongze_yb/services/report"
 	userService "hongze/hongze_yb/services/user"
 	"hongze/hongze_yb/services/wechat"
 	"hongze/hongze_yb/utils"
@@ -151,28 +152,39 @@ func ClassifyDetail(c *gin.Context) {
 // ClassifyDetailBanner 专栏详情banner图
 func ClassifyDetailBanner(c *gin.Context) {
 	reqReportId := c.DefaultQuery("reportId", "")
-	classifyName := c.DefaultQuery("classify_name_first", "")
-	if reqReportId == "" {
-		response.Fail("请输入二级分类标识", c)
-		return
-	}
+	//classifyName := c.DefaultQuery("classify_name_first", "")
+	//if reqReportId == "" {
+	//	response.Fail("请输入二级分类标识", c)
+	//	return
+	//}
 	reportId, err := strconv.Atoi(reqReportId)
 	if err != nil {
 		response.Fail("报告ID格式有误", c)
 		return
 	}
+	reportInfo, err := report.GetByReportId(reportId)
+	if err != nil {
+		response.Fail("报告查询出错", c)
+		return
+	}
 
 	//查询分类类别,根据分类配置显示专栏还是报告合集
-	parentClassify, err := classify.GetByClassifyNameFirst(classifyName)
+	parentClassify, err := classify.GetByClassifyIdFirst(reportInfo.ClassifyIdFirst)
 	if err != nil {
 		response.Fail("获取分类信息失败"+err.Error(), c)
 		return
 	}
+	minClassifyId, _, err := report2.GetMinClassify(reportInfo)
+	if err != nil {
+		response.FailMsg("查询最新一期报告合集失败", "查询最新一期报告合集失败1:"+err.Error(), c)
+		return
+	}
+
 	var bannerResp *pcModels.DetailBannerResp
-	if classifyName == "周报" || classifyName == "晨报" {
-		chapterItem, err := report_chapter.GetLatestChapterByClassifyName(classifyName)
+	if reportInfo.HasChapter == 1 {
+		chapterItem, err := report_chapter.GetLatestChapterByMinClassifyId(minClassifyId)
 		if err != nil {
-			response.Fail("查询最新一期晨周报失败"+err.Error(), c)
+			response.FailMsg("查询最新一期报告合集失败2", "查询最新一期报告合集失败2:"+err.Error(), c)
 			return
 		}
 		resp := &pcModels.DetailBannerResp{
@@ -186,11 +198,6 @@ func ClassifyDetailBanner(c *gin.Context) {
 		}
 		bannerResp = resp
 	} else {
-		reportInfo, err := report.GetByReportId(reportId)
-		if err != nil {
-			response.Fail("报告查询出错", c)
-			return
-		}
 		if reportInfo.Id == 0 {
 			response.Fail("报告不存在", c)
 			return
@@ -201,23 +208,30 @@ func ClassifyDetailBanner(c *gin.Context) {
 			return
 		}
 
-		reportItem, err := report.GetLatestReportByClassifyName(classifyName, reportInfo.ClassifyIdSecond)
+		reportItem, err := report.GetLatestReportByClassifyId(reportInfo.ClassifyIdFirst, reportInfo.ClassifyIdSecond, reportInfo.ClassifyIdThird)
 		if err != nil {
 			response.Fail("获取报告详情失败"+err.Error(), c)
 			return
 		}
+		//查询分类类别,根据分类配置显示专栏还是报告合集
+		minClassify, err := classify.GetByClassifyId(minClassifyId)
+		if err != nil {
+			response.FailMsg("获取分类信息失败", "获取分类信息失败"+err.Error(), c)
+			return
+		}
+
 		resp := &pcModels.DetailBannerResp{
 			ReportId:           reportItem.ReportId,
 			Stage:              reportItem.Stage,
-			VipTitle:           reportItem.VipTitle,
+			VipTitle:           minClassify.VipTitle,
 			Author:             reportItem.Author,
-			ReportAuthor:       reportItem.ReportAuthor,
+			ReportAuthor:       minClassify.ReportAuthor,
 			ImgUrl:             "",
 			ClassifyNameFirst:  reportItem.ClassifyNameFirst,
 			ClassifyIdFirst:    reportItem.ClassifyIdFirst,
 			ClassifyNameSecond: reportItem.ClassifyNameSecond,
 			ClassifyIdSecond:   reportItem.ClassifyIdSecond,
-			ShowType:           parentClassify.ShowType,
+			ShowType:           minClassify.ShowType,
 		}
 
 		if parentClassify.ShowType == 1 || parentClassify.ShowType == 3 {
@@ -350,7 +364,6 @@ func ClassifyDetailBanner(c *gin.Context) {
 // Recommend 报告详情页更多推荐
 func Recommend(c *gin.Context) {
 	reqReportId := c.DefaultQuery("reportId", "")
-	classifyName := c.DefaultQuery("classify_name_first", "")
 	if reqReportId == "" {
 		response.Fail("请输入二级分类标识", c)
 		return
@@ -360,12 +373,26 @@ func Recommend(c *gin.Context) {
 		response.Fail("报告ID格式有误", c)
 		return
 	}
+	reportInfo, err := report.GetByReportId(reportId)
+	if err != nil {
+		response.Fail("报告查询出错", c)
+		return
+	}
+	if reportInfo.Id == 0 {
+		response.Fail("报告不存在", c)
+		return
+	}
+	minClassifyId, _, err := report2.GetMinClassify(reportInfo)
+	if err != nil {
+		response.FailMsg("查询最新一期报告合集失败", "查询最新一期报告合集失败1:"+err.Error(), c)
+		return
+	}
 
 	var recommendResp []*pcModels.RecommendResp
-	if classifyName == "周报" || classifyName == "晨报" {
-		recommendList, err := report_chapter.GetWeekRecommendList(reportId, classifyName)
+	if reportInfo.HasChapter == 1 {
+		recommendList, err := report_chapter.GetWeekRecommendListV2(reportId, minClassifyId)
 		if err != nil {
-			response.Fail("获取报告详情失败"+err.Error(), c)
+			response.FailMsg("获取推荐报告列表失败", "获取推荐报告列表失败:"+err.Error(), c)
 			return
 		}
 		for _, chapter := range recommendList {
@@ -380,15 +407,6 @@ func Recommend(c *gin.Context) {
 			recommendResp = append(recommendResp, resp)
 		}
 	} else {
-		reportInfo, err := report.GetByReportId(reportId)
-		if err != nil {
-			response.Fail("报告查询出错", c)
-			return
-		}
-		if reportInfo.Id == 0 {
-			response.Fail("报告不存在", c)
-			return
-		}
 
 		if reportInfo.State != 2 && reportInfo.State != 6 {
 			response.Fail("报告未发布", c)
@@ -402,7 +420,7 @@ func Recommend(c *gin.Context) {
 			reportType = 2
 		}
 
-		recommendList, err := pcModels.GetRecommendList(reportId, reportType, reportInfo.ClassifyIdSecond)
+		recommendList, err := pcModels.GetRecommendListV2(reportId, reportType, reportInfo.ClassifyIdFirst, reportInfo.ClassifyIdSecond, reportInfo.ClassifyIdThird)
 		if err != nil {
 			response.Fail("获取报告详情失败"+err.Error(), c)
 			return
@@ -549,25 +567,25 @@ QUERY_WX_USER:
 		goto QUERY_WX_USER
 	} else if wxUserErr == userService.ERR_USER_NOT_BIND {
 		// 未绑定则去查询unionId是否已经绑定了用户(其他平台,不区分平台),有相应的手机号邮箱信息则自动绑定
-		platformUser, platformErr := userService.GetFirstWxUserItemByUnionId(unionId)
-		if platformErr == nil {
-			// 当公众号用户存在时
-			if platformUser.Mobile != "" || platformUser.Email != "" {
-				// 有手机号或邮箱则绑定信息则自动绑定并新增wx_user
-				countryCode := 0
-				if platformUser.CountryCode != "" {
-					countryCode, _ = strconv.Atoi(platformUser.CountryCode)
-				}
-				tempToken, tempUser, tempErr, errMsg := userService.BindWxUser(openId, platformUser.Mobile, platformUser.Email, "", 3, countryCode, 1)
-				if tempErr != nil {
-					err = errors.New("自动绑定公众号用户失败,Err:" + tempErr.Error() + ", errMsg:" + errMsg)
-					return
-				}
-				token = tempToken
-				userId = int(tempUser.UserID)
-				isBind = true
-			}
-		}
+		//platformUser, platformErr := userService.GetFirstWxUserItemByUnionId(unionId)
+		//if platformErr == nil {
+		//	// 当公众号用户存在时
+		//	if platformUser.Mobile != "" || platformUser.Email != "" {
+		//		// 有手机号或邮箱则绑定信息则自动绑定并新增wx_user
+		//		countryCode := 0
+		//		if platformUser.CountryCode != "" {
+		//			countryCode, _ = strconv.Atoi(platformUser.CountryCode)
+		//		}
+		//		tempToken, tempUser, tempErr, errMsg := userService.BindWxUser(openId, platformUser.Mobile, platformUser.Email, "", 3, countryCode, 1)
+		//		if tempErr != nil {
+		//			err = errors.New("自动绑定公众号用户失败,Err:" + tempErr.Error() + ", errMsg:" + errMsg)
+		//			return
+		//		}
+		//		token = tempToken
+		//		userId = int(tempUser.UserID)
+		//		isBind = true
+		//	}
+		//}
 	} else if wxUserErr != nil {
 		err = wxUserErr
 		return

+ 1 - 0
controller/report/report.go

@@ -60,6 +60,7 @@ func ChapterDetail(c *gin.Context) {
 		response.FailMsg("查看章节详情出错", err.Error(), c)
 		return
 	}
+
 	response.OkData("查询成功", chapterDetail, c)
 	return
 }

+ 11 - 6
controller/user/user.go

@@ -35,15 +35,22 @@ func Login(c *gin.Context) {
 		response.Fail("参数异常", c)
 		return
 	}
+	if req.LoginType != 1 && req.LoginType != 2 {
+		response.Fail("无效的登录方式", c)
+		return
+	}
+
 	if req.LoginType == 1 {
 		//手机登录
+		req.Mobile = strings.Trim(req.Mobile, " ")
 		if req.Mobile == "" {
 			response.Fail("手机号不能为空,请输入手机号", c)
 			return
 		}
-		req.Mobile = strings.Trim(req.Mobile, " ")
-	} else if req.LoginType == 2 {
+	}
+	if req.LoginType == 2 {
 		//邮箱登录
+		req.Email = strings.Trim(req.Email, " ")
 		if req.Email == "" {
 			response.Fail("邮箱不能为空,请输入邮箱", c)
 			return
@@ -52,10 +59,8 @@ func Login(c *gin.Context) {
 			response.Fail("邮箱格式错误,请重新输入", c)
 			return
 		}
-	} else {
-		response.Fail("无效的登录方式", c)
-		return
 	}
+
 	token, newUserInfo, err, errMsg := userService.BindWxUser(openId, req.Mobile, req.Email, req.VerifyCode, req.LoginType, req.AreaNum, 1)
 	if err != nil {
 		if errMsg == "" {
@@ -317,4 +322,4 @@ func GetTopTab(c *gin.Context) {
 	}
 
 	response.OkData("获取成功", tabBarList, c)
-}
+}

+ 0 - 1
latest_mongolog

@@ -1 +0,0 @@
-log/mongolog/2024-05-08-00-00.log

+ 1 - 1
logic/public.go

@@ -2,7 +2,7 @@ package logic
 
 import (
 	"fmt"
-	"hongze/hongze_yb/models/tables/chart_permission"
+	"hongze/hongze_yb/models/tables/rddp/chart_permission"
 	"hongze/hongze_yb/utils"
 )
 

+ 1 - 1
logic/user/user.go

@@ -4,9 +4,9 @@ import (
 	"errors"
 	userReq "hongze/hongze_yb/models/request/user"
 	admin2 "hongze/hongze_yb/models/tables/admin"
-	"hongze/hongze_yb/models/tables/chart_permission"
 	"hongze/hongze_yb/models/tables/company"
 	"hongze/hongze_yb/models/tables/company_product"
+	"hongze/hongze_yb/models/tables/rddp/chart_permission"
 	"hongze/hongze_yb/models/tables/rddp/msg_code"
 	"hongze/hongze_yb/models/tables/research_variety_tag_relation"
 	"hongze/hongze_yb/models/tables/sys_role_admin"

+ 1 - 1
logic/yb_community_question/yb_community_question_comment.go

@@ -6,9 +6,9 @@ import (
 	"hongze/hongze_yb/global"
 	"hongze/hongze_yb/models/response"
 	"hongze/hongze_yb/models/tables/admin"
-	"hongze/hongze_yb/models/tables/chart_permission"
 	"hongze/hongze_yb/models/tables/company"
 	"hongze/hongze_yb/models/tables/company_product"
+	"hongze/hongze_yb/models/tables/rddp/chart_permission"
 	"hongze/hongze_yb/models/tables/wx_user"
 	"hongze/hongze_yb/models/tables/yb_comment_anonymous_user"
 	"hongze/hongze_yb/models/tables/yb_community_question"

+ 510 - 0
models/mgo/edb_data_ths_hf.go

@@ -0,0 +1,510 @@
+package mgo
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"github.com/qiniu/qmgo"
+	"go.mongodb.org/mongo-driver/bson"
+	"go.mongodb.org/mongo-driver/bson/primitive"
+	"hongze/hongze_yb/global"
+	"time"
+)
+
+// EdbDataThsHf
+// @Description: 同花顺高频集合(指标库)
+type EdbDataThsHf struct {
+	ID            primitive.ObjectID `json:"_id" bson:"_id,omitempty" `            // 文档id
+	EdbInfoId     int                `json:"edb_info_id" bson:"edb_info_id"`       // 指标ID
+	EdbCode       string             `json:"edb_code" bson:"edb_code"`             // 指标编码
+	DataTime      time.Time          `json:"data_time" bson:"data_time"`           // 数据日期
+	Value         float64            `json:"value" bson:"value"`                   // 数据值
+	CreateTime    time.Time          `json:"create_time" bson:"create_time"`       // 创建时间
+	ModifyTime    time.Time          `json:"modify_time" bson:"modify_time"`       // 修改时间
+	DataTimestamp int64              `json:"data_timestamp" bson:"data_timestamp"` // 数据日期时间戳
+}
+
+// CollectionName
+// @Description:  获取集合名称
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-26 13:41:36
+// @return string
+func (m *EdbDataThsHf) CollectionName() string {
+	return "edb_data_ths_hf"
+}
+
+// DataBaseName
+// @Description: 获取数据库名称
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-26 13:41:33
+// @return string
+func (m *EdbDataThsHf) DataBaseName() string {
+	return global.CONFIG.Mongo.Database
+}
+
+// GetCollection
+// @Description: 获取mongodb集合的句柄
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-26 13:41:33
+// @return string
+func (m *EdbDataThsHf) GetCollection() *qmgo.Collection {
+	db := global.MgoDataCli.Database(m.DataBaseName())
+	return db.Collection(m.CollectionName())
+}
+
+// GetItem
+// @Description: 根据条件获取单条数据
+// @author: Roc
+// @receiver m
+// @datetime 2024-05-09 10:00:49
+// @param whereParams interface{}
+// @return item *EdbDataThsHf
+// @return err error
+func (m *EdbDataThsHf) GetItem(whereParams interface{}) (item *EdbDataThsHf, err error) {
+	if global.MgoDataCli == nil {
+		err = errors.New("mongodb连接失败")
+		return
+	}
+	db := global.MgoDataCli.Database(m.DataBaseName())
+	coll := db.Collection(m.CollectionName())
+
+	return m.GetItemByColl(coll, whereParams)
+}
+
+// GetItemByColl
+// @Description: 根据条件获取单条数据
+// @author: Roc
+// @receiver m
+// @datetime 2024-05-09 13:22:06
+// @param coll *qmgo.Collection
+// @param whereParams interface{}
+// @return item *EdbDataThsHf
+// @return err error
+func (m *EdbDataThsHf) GetItemByColl(coll *qmgo.Collection, whereParams interface{}) (item *EdbDataThsHf, err error) {
+	ctx := context.TODO()
+	if err != nil {
+		fmt.Println("MgoGetColl Err:", err.Error())
+		return
+	}
+	err = coll.Find(ctx, whereParams).One(&item)
+	if err != nil {
+		return
+	}
+
+	item.DataTime = item.DataTime.In(time.Local)
+	item.CreateTime = item.CreateTime.In(time.Local)
+	item.ModifyTime = item.ModifyTime.In(time.Local)
+
+	return
+}
+
+// GetAllDataList
+// @Description: 根据条件获取所有数据
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-26 13:42:19
+// @param whereParams interface{}
+// @param sort []string
+// @return result []EdbDataThsHf
+// @return err error
+func (m *EdbDataThsHf) GetAllDataList(whereParams interface{}, sort []string) (result []*EdbDataThsHf, err error) {
+	if global.MgoDataCli == nil {
+		err = errors.New("mongodb连接失败")
+		return
+	}
+	db := global.MgoDataCli.Database(m.DataBaseName())
+	coll := db.Collection(m.CollectionName())
+	ctx := context.TODO()
+	if err != nil {
+		fmt.Println("MgoGetColl Err:", err.Error())
+		return
+	}
+	err = coll.Find(ctx, whereParams).Sort(sort...).All(&result)
+	if err != nil {
+		return
+	}
+
+	for _, v := range result {
+		v.DataTime = v.DataTime.In(time.Local)
+		v.CreateTime = v.CreateTime.In(time.Local)
+		v.ModifyTime = v.ModifyTime.In(time.Local)
+	}
+
+	return
+}
+
+// GetLimitDataList
+// @Description: 根据条件获取指定数量数据列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-05-06 17:08:32
+// @param whereParams interface{}
+// @param size int64
+// @param sort []string
+// @return result []*BaseFromBusinessData
+// @return err error
+func (m *EdbDataThsHf) GetLimitDataList(whereParams interface{}, size int64, sort []string) (result []*EdbDataThsHf, err error) {
+	if global.MgoDataCli == nil {
+		err = errors.New("mongodb连接失败")
+		return
+	}
+	db := global.MgoDataCli.Database(m.DataBaseName())
+	coll := db.Collection(m.CollectionName())
+	ctx := context.TODO()
+	if err != nil {
+		fmt.Println("MgoGetColl Err:", err.Error())
+		return
+	}
+	err = coll.Find(ctx, whereParams).Sort(sort...).Limit(size).All(&result)
+	if err != nil {
+		return
+	}
+
+	for _, v := range result {
+		v.DataTime = v.DataTime.In(time.Local)
+		v.CreateTime = v.CreateTime.In(time.Local)
+		v.ModifyTime = v.ModifyTime.In(time.Local)
+	}
+
+	return
+}
+
+// GetPageDataList
+// @Description: 根据条件获取分页数据列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-05-07 10:21:07
+// @param whereParams interface{}
+// @param startSize int64
+// @param size int64
+// @param sort []string
+// @return result []*EdbDataThsHf
+// @return err error
+func (m *EdbDataThsHf) GetPageDataList(whereParams interface{}, startSize, size int64, sort []string) (result []*EdbDataThsHf, err error) {
+	if global.MgoDataCli == nil {
+		err = errors.New("mongodb连接失败")
+		return
+	}
+	db := global.MgoDataCli.Database(m.DataBaseName())
+	coll := db.Collection(m.CollectionName())
+	ctx := context.TODO()
+	if err != nil {
+		fmt.Println("MgoGetColl Err:", err.Error())
+		return
+	}
+	err = coll.Find(ctx, whereParams).Sort(sort...).Skip(startSize).Limit(size).All(&result)
+	if err != nil {
+		return
+	}
+
+	for _, v := range result {
+		v.DataTime = v.DataTime.In(time.Local)
+		v.CreateTime = v.CreateTime.In(time.Local)
+		v.ModifyTime = v.ModifyTime.In(time.Local)
+	}
+
+	return
+}
+
+// GetCountDataList
+// @Description:  根据条件获取数据列表总数
+// @author: Roc
+// @receiver m
+// @datetime 2024-05-07 10:29:00
+// @param whereParams interface{}
+// @return count int64
+// @return err error
+func (m *EdbDataThsHf) GetCountDataList(whereParams interface{}) (count int64, err error) {
+	if global.MgoDataCli == nil {
+		err = errors.New("mongodb连接失败")
+		return
+	}
+	db := global.MgoDataCli.Database(m.DataBaseName())
+	coll := db.Collection(m.CollectionName())
+	ctx := context.TODO()
+	if err != nil {
+		fmt.Println("MgoGetColl Err:", err.Error())
+		return
+	}
+	count, err = coll.Find(ctx, whereParams).Count()
+
+	return
+}
+
+// InsertDataByColl
+// @Description: 写入单条数据(外部传入集合)
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-26 14:22:18
+// @param addData interface{}
+// @return err error
+func (m *EdbDataThsHf) InsertDataByColl(coll *qmgo.Collection, addData interface{}) (err error) {
+	ctx := context.TODO()
+	_, err = coll.InsertOne(ctx, addData)
+	if err != nil {
+		fmt.Println("InsertDataByColl:Err:" + err.Error())
+		return
+	}
+
+	return
+}
+
+// BatchInsertData
+// @Description: 批量写入数据
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-26 14:22:18
+// @param bulk int 每次请求保存的数据量
+// @param dataList []interface{}
+// @return err error
+func (m *EdbDataThsHf) BatchInsertData(bulk int, dataList []interface{}) (err error) {
+	db := global.MgoDataCli.Database(m.DataBaseName())
+	coll := db.Collection(m.CollectionName())
+
+	return m.BatchInsertDataByColl(coll, bulk, dataList)
+}
+
+// BatchInsertDataByColl
+// @Description: 批量写入数据(外部传入集合)
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-26 14:22:18
+// @param coll *qmgo.Collection
+// @param bulk int 每次请求保存的数据量
+// @param dataList []interface{}
+// @return err error
+func (m *EdbDataThsHf) BatchInsertDataByColl(coll *qmgo.Collection, bulk int, dataList []interface{}) (err error) {
+	ctx := context.TODO()
+	dataNum := len(dataList)
+	if dataNum <= 0 {
+		return
+	}
+
+	// 不设置每次保存切片数量大小,或者实际数据量小于设置的切片数量大小,那么就直接保存吧
+	if bulk <= 0 || dataNum <= bulk {
+		_, err = coll.InsertMany(ctx, dataList)
+		if err != nil {
+			fmt.Println("BatchInsertData:Err:" + err.Error())
+			return
+		}
+		return
+	}
+
+	// 分批保存
+	i := 0
+	tmpAddDataList := make([]interface{}, 0)
+	for _, v := range dataList {
+		tmpAddDataList = append(tmpAddDataList, v)
+		i++
+		if i >= bulk {
+			_, err = coll.InsertMany(ctx, tmpAddDataList)
+			if err != nil {
+				fmt.Println("BatchInsertData:Err:" + err.Error())
+				return
+			}
+			i = 0
+			tmpAddDataList = make([]interface{}, 0)
+		}
+	}
+
+	if len(tmpAddDataList) > 0 {
+		_, err = coll.InsertMany(ctx, tmpAddDataList)
+		if err != nil {
+			fmt.Println("BatchInsertData:Err:" + err.Error())
+			return
+		}
+	}
+
+	return
+}
+
+// UpdateData
+// @Description: 单条数据修改
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-26 15:01:51
+// @param whereParams interface{}
+// @param updateParams interface{}
+// @return err error
+func (m *EdbDataThsHf) UpdateData(whereParams, updateParams interface{}) (err error) {
+	db := global.MgoDataCli.Database(m.DataBaseName())
+	coll := db.Collection(m.CollectionName())
+
+	return m.UpdateDataByColl(coll, whereParams, updateParams)
+}
+
+// UpdateDataByColl
+// @Description: 单条数据修改(外部传入集合)
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-26 15:01:51
+// @param whereParams interface{}
+// @param updateParams interface{}
+// @return err error
+func (m *EdbDataThsHf) UpdateDataByColl(coll *qmgo.Collection, whereParams, updateParams interface{}) (err error) {
+	ctx := context.TODO()
+	err = coll.UpdateOne(ctx, whereParams, updateParams)
+	if err != nil {
+		fmt.Println("UpdateDataByColl:Err:" + err.Error())
+		return
+	}
+
+	return
+}
+
+// RemoveMany
+// @Description: 根据条件删除多条数据
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-30 13:17:02
+// @param whereParams interface{}
+// @return err error
+func (m *EdbDataThsHf) RemoveMany(whereParams interface{}) (err error) {
+	db := global.MgoDataCli.Database(m.DataBaseName())
+	coll := db.Collection(m.CollectionName())
+
+	return m.RemoveManyByColl(coll, whereParams)
+}
+
+// RemoveManyByColl
+// @Description: 根据条件删除多条数据(外部传入集合)
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-30 13:18:42
+// @param coll *qmgo.Collection
+// @param whereParams interface{}
+// @return err error
+func (m *EdbDataThsHf) RemoveManyByColl(coll *qmgo.Collection, whereParams interface{}) (err error) {
+	ctx := context.TODO()
+	_, err = coll.RemoveAll(ctx, whereParams)
+	if err != nil {
+		fmt.Println("RemoveManyByColl:Err:" + err.Error())
+		return
+	}
+
+	return
+}
+
+// HandleData
+// @Description: 事务处理数据
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-30 10:39:01
+// @param addDataList []AddEdbDataThsHf
+// @param updateDataList []EdbDataThsHf
+// @return result interface{}
+// @return err error
+func (m *EdbDataThsHf) HandleData(addDataList, updateDataList []EdbDataThsHf) (result interface{}, err error) {
+
+	ctx := context.TODO()
+
+	callback := func(sessCtx context.Context) (interface{}, error) {
+		// 重要:确保事务中的每一个操作,都使用传入的sessCtx参数
+
+		db := global.MgoDataCli.Database(m.DataBaseName())
+		coll := db.Collection(m.CollectionName())
+
+		// 插入数据
+		if len(addDataList) > 0 {
+			_, err = coll.InsertMany(sessCtx, addDataList)
+			if err != nil {
+				return nil, err
+			}
+		}
+
+		// 修改
+
+		if len(updateDataList) > 0 {
+			for _, v := range updateDataList {
+				err = coll.UpdateOne(ctx, bson.M{"_id": v.ID}, bson.M{"$set": bson.M{"value": v.Value, "modify_time": v.ModifyTime}})
+				if err != nil {
+					fmt.Println("BatchInsertData:Err:" + err.Error())
+					return nil, err
+				}
+			}
+		}
+
+		return nil, nil
+	}
+	result, err = global.MgoDataCli.DoTransaction(ctx, callback)
+
+	return
+}
+
+// EdbInfoMaxAndMinInfo 指标最新数据记录结构体
+//type EdbInfoMaxAndMinInfo struct {
+//	MinDate     time.Time `description:"最小日期" bson:"min_date"`
+//	MaxDate     time.Time `description:"最大日期" bson:"max_date"`
+//	MinValue    float64   `description:"最小值" bson:"min_value"`
+//	MaxValue    float64   `description:"最大值" bson:"max_value"`
+//	LatestValue float64   `description:"最新值" bson:"latest_value"`
+//	LatestDate  time.Time `description:"实际数据最新日期" bson:"latest_date"`
+//	EndValue    float64   `description:"最新值" bson:"end_value"`
+//}
+
+// GetEdbInfoMaxAndMinInfo
+// @Description: 获取当前指标的最大最小值
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-30 17:15:39
+// @param whereParams interface{}
+// @return result EdbInfoMaxAndMinInfo
+// @return err error
+func (m *EdbDataThsHf) GetEdbInfoMaxAndMinInfo(whereParams interface{}) (result EdbInfoMaxAndMinInfo, err error) {
+	if global.MgoDataCli == nil {
+		err = errors.New("mongodb连接失败")
+		return
+	}
+	db := global.MgoDataCli.Database(m.DataBaseName())
+	coll := db.Collection(m.CollectionName())
+	ctx := context.TODO()
+	if err != nil {
+		fmt.Println("MgoGetColl Err:", err.Error())
+		return
+	}
+	err = coll.Aggregate(ctx, whereParams).One(&result)
+	if err != nil {
+		return
+	}
+	result.MinDate = result.MinDate.In(time.Local)
+	result.MaxDate = result.MaxDate.In(time.Local)
+	result.LatestDate = result.LatestDate.In(time.Local)
+
+	return
+}
+
+// LatestValue 指标最新数据记录结构体
+//type LatestValue struct {
+//	Value float64 `description:"值" bson:"value"`
+//}
+
+// GetLatestValue
+// @Description: 获取当前指标的最新数据记录
+// @author: Roc
+// @receiver m
+// @datetime 2024-04-30 17:16:15
+// @param whereParams interface{}
+// @param selectParam interface{}
+// @return latestValue LatestValue
+// @return err error
+func (m *EdbDataThsHf) GetLatestValue(whereParams, selectParam interface{}) (latestValue LatestValue, err error) {
+	if global.MgoDataCli == nil {
+		err = errors.New("mongodb连接失败")
+		return
+	}
+	db := global.MgoDataCli.Database(m.DataBaseName())
+	coll := db.Collection(m.CollectionName())
+	ctx := context.TODO()
+	if err != nil {
+		fmt.Println("MgoGetColl Err:", err.Error())
+		return
+	}
+
+	//var result interface{}
+	//err = coll.Find(ctx, whereParams).Select(selectParam).One(&result)
+	err = coll.Find(ctx, whereParams).Select(selectParam).One(&latestValue)
+	return
+}

+ 17 - 0
models/request/chart.go

@@ -7,12 +7,27 @@ type BarChartInfoReq struct {
 	Sort          BarChartInfoSortReq      `description:"排序"`
 }
 
+type FutureGoodBarChartInfoReq struct {
+	EdbInfoIdList []BarChartInfoEdbItemReq `description:"指标信息"`
+	DateList      []BarChartInfoDateReq    `description:"日期配置"`
+	XDataList     []XData                  `description:"横轴配置"`
+	BaseEdbInfoId int                      `description:"日期基准指标id"`
+}
+
+// XData 商品价格曲线的的x轴数据
+type XData struct {
+	Name   string `description:"别名"`
+	NameEn string `description:"英文别名"`
+	IsHide int    `description:"是否隐藏,0不隐藏,1隐藏"`
+}
+
 // BarChartInfoEdbItemReq 柱方图预览请求数据(指标相关)
 type BarChartInfoEdbItemReq struct {
 	EdbInfoId int    `description:"指标ID"`
 	Name      string `description:"别名"`
 	NameEn    string `description:"英文别名"`
 	Source    int    `description:"1:ETA图库;2:商品价格"`
+	IsHide    int    `description:"是否隐藏该项,0不隐藏,1隐藏"`
 }
 
 // BarChartInfoDateReq 柱方图预览请求数据(日期相关)
@@ -135,6 +150,8 @@ type ChartInfoReq struct {
 	BaseEdbInfoId           int                `description:"基础的指标id"`
 	DateList                []ChartInfoDateReq `description:"日期配置"`
 	ProfitNameEn            string             `description:"利润英文名称"`
+	EdbInfoIdList           []int              `description:"现货指标ID列表"`
+	XDataList               []XData            `description:"横轴配置"`
 }
 
 // EdbInfoFromTag 计算指标的关联指标

+ 1 - 0
models/response/chart_info/chart_info.go

@@ -34,6 +34,7 @@ type ChartLibChartInfoDetailResp struct {
 type XData struct {
 	Name   string `description:"别名"`
 	NameEn string `description:"英文别名"`
+	IsHide int    `description:"是否隐藏,0不隐藏,1隐藏"`
 }
 
 // YData 柱方图的y轴数据

+ 23 - 0
models/response/pc/report.go

@@ -122,3 +122,26 @@ type LatestReportBanner struct {
 	Author             string
 	ReportAuthor       string
 }
+
+// GetRecommendListV2
+// @Description: 获取报告的推荐列表
+// @author: Roc
+// @datetime 2024-06-24 14:25:01
+// @param reportId int
+// @param reportType int
+// @param firstId int
+// @param secondId int
+// @param thirdId int
+// @return items []*Report
+// @return err error
+func GetRecommendListV2(reportId, reportType, firstId, secondId, thirdId int) (items []*Report, err error) {
+	sql := `SELECT * FROM report WHERE state=2 AND id<> ? AND classify_id_first=? AND classify_id_second=? AND classify_id_third=? `
+	if reportType == 1 {
+		sql += ` AND classify_name_first = ? `
+	} else {
+		sql += ` AND classify_name_first<>? `
+	}
+	sql += ` ORDER BY publish_time DESC LIMIT 3`
+	err = global.MYSQL["rddp"].Raw(sql, reportId, firstId, secondId, thirdId, "权益研报").Scan(&items).Error
+	return
+}

+ 63 - 33
models/response/report.go

@@ -5,15 +5,16 @@ import (
 )
 
 type ReportDetail struct {
-	ReportInfo        *ReportItem              `json:"report_info"`
-	ReportChapterList []*ReportChapterListItem `json:"report_chapter_list"`
-	PermissionCheck   *PermissionCheckInfo     `json:"permission_check"`
-	AuthOk            bool                     `json:"auth_ok"`
-	LikeNum           int64                    `description:"点赞总数" json:"like_num"`
-	LikeEnabled       int8                     `description:"是否已点赞: 0-未点赞 1-已点赞" json:"like_enabled"`
-	ReportShowType    int                      `descritpion:"展示形式:1-列表 2-专栏" json:"report_show_type"`
-	CollectionId      int                      `description:"收藏ID: 大于0则表示已收藏" json:"collection_id"`
-	RoadVideoId       int                      `json:"road_video_id" description:"绑定的路演视频ID"`
+	ReportInfo           *ReportItem              `json:"report_info"`
+	ReportChapterList    []*ReportChapterListItem `json:"report_chapter_list"`
+	PermissionCheck      *PermissionCheckInfo     `json:"permission_check"`
+	AuthOk               bool                     `json:"auth_ok"`
+	LikeNum              int64                    `description:"点赞总数" json:"like_num"`
+	LikeEnabled          int8                     `description:"是否已点赞: 0-未点赞 1-已点赞" json:"like_enabled"`
+	ReportShowType       int                      `description:"展示形式:1-列表 2-专栏" json:"report_show_type"`
+	CollectionId         int                      `description:"收藏ID: 大于0则表示已收藏" json:"collection_id"`
+	RoadVideoId          int                      `json:"road_video_id" description:"绑定的路演视频ID"`
+	ReportDetailShowType int                      `description:"报告详情的展示类型:1-拼接;2:目录" json:"report_detail_show_type"`
 }
 
 type ReportChapterListItem struct {
@@ -29,6 +30,7 @@ type ReportChapterListItem struct {
 	Sort                   int       `json:"sort"`
 	PublishTime            time.Time `json:"publish_time"`
 	IsClose                int       `gorm:"column:is_close;type:tinyint(1);default:0" json:"is_close"` //音频品种是否关闭
+	Content                string    `description:"内容" json:"content"`
 	VideoUrl               string    `json:"video_url" description:"音频文件URL"`
 	VideoName              string    `json:"video_name" description:"音频文件名称"`
 	VideoPlaySeconds       string    `json:"video_play_seconds" description:"音频播放时长"`
@@ -54,6 +56,13 @@ type ReportItem struct {
 	ContentSub         string    `description:"内容前两个章节" json:"content_sub"`
 	BannerUrl          string    `description:"详情页banner" json:"banner_url"`
 	ShareBgImg         string    `description:"分享背景图" json:"share_bg_img"`
+	HasChapter         int       `description:"是否有章节" json:"has_chapter"`
+	ReportLayout       int8      `description:"报告布局,1:常规布局,2:智能布局。默认:1" json:"report_layout"`
+	HeadImg            string    `description:"报告头图地址" json:"head_img"`
+	EndImg             string    `description:"报告尾图地址" json:"end_img"`
+	CanvasColor        string    `description:"画布颜色" json:"canvas_color"`
+	HeadStyle          string    `description:"版头样式" json:"head_style"`
+	EndStyle           string    `description:"版尾样式" json:"end_style"`
 }
 
 type ReportChapterItem struct {
@@ -78,6 +87,13 @@ type ReportChapterItem struct {
 	ClassifyIdFirst       int       `description:"一级分类id" json:"classify_id_first"`
 	ClassifyNameFirst     string    `description:"一级分类名称" json:"classify_name_first"`
 	ShareBgImg            string    `description:"分享背景图" json:"share_bg_img"`
+	ReportLayout          int8      `description:"报告布局,1:常规布局,2:智能布局。默认:1" json:"report_layout"`
+	HeadImg               string    `description:"报告头图地址" json:"head_img"`
+	EndImg                string    `description:"报告尾图地址" json:"end_img"`
+	CanvasColor           string    `description:"画布颜色" json:"canvas_color"`
+	HeadStyle             string    `description:"版头样式" json:"head_style"`
+	EndStyle              string    `description:"版尾样式" json:"end_style"`
+	ReportVideoUrl        string    `description:"报告音频" json:"report_video_url"`
 }
 
 type ReportChapterDetail struct {
@@ -101,20 +117,29 @@ type ReportChapterMenu struct {
 }
 
 type ReportListItem struct {
-	ReportId           int              `description:"报告Id" json:"report_id"`
-	ClassifyIdFirst    int              `description:"一级分类id" json:"classify_id_first"`
-	ClassifyNameFirst  string           `description:"一级分类名称" json:"classify_name_first"`
-	ClassifyIdSecond   int              `description:"二级分类id" json:"classify_id_second"`
-	ClassifyNameSecond string           `description:"二级分类名称" json:"classify_name_second"`
-	Title              string           `description:"标题" json:"title"`
-	Abstract           string           `description:"摘要" json:"abstract"`
-	Author             string           `description:"作者" json:"author"`
-	ReportImgUrl       string           `description:"作者头像" json:"report_img_url"`
-	PublishTime        time.Time        `description:"发布时间" json:"publish_time"`
-	Stage              int              `description:"期数" json:"stage"`
-	VideoList          []*VideoListItem `json:"video_list"`
-	AuthOk             bool             `json:"auth_ok"`
-	TitleInfo          string           `json:"title_info"`
+	ReportId             int              `description:"报告Id" json:"report_id"`
+	ClassifyIdFirst      int              `description:"一级分类id" json:"classify_id_first"`
+	ClassifyNameFirst    string           `description:"一级分类名称" json:"classify_name_first"`
+	ClassifyIdSecond     int              `description:"二级分类id" json:"classify_id_second"`
+	ClassifyNameSecond   string           `description:"二级分类名称" json:"classify_name_second"`
+	ClassifyIdThird      int              `description:"三级分类id" json:"classify_id_third"`
+	ClassifyNameThird    string           `description:"三级分类名称" json:"classify_name_third"`
+	Title                string           `description:"标题" json:"title"`
+	Abstract             string           `description:"摘要" json:"abstract"`
+	Author               string           `description:"作者" json:"author"`
+	ReportImgUrl         string           `description:"作者头像" json:"report_img_url"`
+	PublishTime          time.Time        `description:"发布时间" json:"publish_time"`
+	Stage                int              `description:"期数" json:"stage"`
+	VideoList            []*VideoListItem `json:"video_list"`
+	AuthOk               bool             `json:"auth_ok"`
+	TitleInfo            string           `json:"title_info"`
+	HasChapter           int              `description:"是否有章节" json:"has_chapter"`
+	VideoUrl             string           `description:"报告音频" json:"video_url"`
+	VideoName            string           `description:"音频文件名称" json:"video_name"`
+	VideoSize            string           `description:"音频文件大小,单位M" json:"video_size"`
+	VideoPlaySeconds     string           `description:"音频播放时长" json:"video_play_seconds"`
+	VideoImg             string           `json:"video_img"` // 音频播放条前面展示的图片
+	ReportDetailShowType int              `description:"报告详情的展示类型:1-拼接;2:目录" json:"report_detail_show_type"`
 }
 
 type VideoListItem struct {
@@ -131,16 +156,19 @@ type ReportList struct {
 }
 
 type ReportCollectListItem struct {
-	ReportId            int       `description:"报告Id" json:"report_id"`
-	ReportChapterId     int       `json:"report_chapter_id"`
-	ClassifyIdFirst     int       `description:"一级分类id" json:"classify_id_first"`
-	ClassifyNameFirst   string    `description:"一级分类名称" json:"classify_name_first"`
-	ClassifyIdSecond    int       `description:"二级分类id" json:"classify_id_second"`
-	ClassifyNameSecond  string    `description:"二级分类名称" json:"classify_name_second"`
-	ReportChapterTypeId int       `json:"report_chapter_type_id"`
-	PublishTime         time.Time `description:"发布时间" json:"publish_time"`
-	Title               string    `description:"标题" json:"title"`
-	ContentSub          string    `description:"内容前两个章节" json:"content_sub"`
+	ReportId             int       `description:"报告Id" json:"report_id"`
+	ReportChapterId      int       `json:"report_chapter_id"`
+	ClassifyIdFirst      int       `description:"一级分类id" json:"classify_id_first"`
+	ClassifyNameFirst    string    `description:"一级分类名称" json:"classify_name_first"`
+	ClassifyIdSecond     int       `description:"二级分类id" json:"classify_id_second"`
+	ClassifyNameSecond   string    `description:"二级分类名称" json:"classify_name_second"`
+	ReportChapterTypeId  int       `json:"report_chapter_type_id"`
+	PublishTime          time.Time `description:"发布时间" json:"publish_time"`
+	Title                string    `description:"标题" json:"title"`
+	ContentSub           string    `description:"内容前两个章节" json:"content_sub"`
+	ClassifyId           int       `description:"最小分类id" json:"classify_id"`
+	ClassifyName         string    `description:"最小分类名称" json:"classify_name"`
+	ReportDetailShowType int       `description:"报告详情的展示类型:1-拼接;2:目录" json:"report_detail_show_type"`
 }
 
 type ReportCollectList struct {
@@ -173,6 +201,8 @@ type EsReportItem struct {
 	Title              string `description:"标题"`
 	Abstract           string `description:"摘要"`
 	StageStr           string `description:"期数"`
+	ClassifyId         int    `description:"最小分类id"`
+	ClassifyName       string `description:"最小分类名称"`
 }
 
 type TickerDataItem struct {

+ 13 - 0
models/tables/chart_edb_mapping/query.go

@@ -123,6 +123,19 @@ func GetEtaEdbChartEdbMapping(chartInfoId int) (item *ChartEdbInfoMappingList, e
 	return
 }
 
+// GetEtaEdbChartEdbMappingList       商品曲线图查询对应的普通指标
+func GetEtaEdbChartEdbMappingList(chartInfoId int) (items []*ChartEdbInfoMappingList, err error) {
+	aField := `a.chart_edb_mapping_id,a.chart_info_id,a.edb_info_id,a.create_time,a.modify_time,a.unique_code,a.max_data,a.min_data,a.is_order,a.is_axis,a.edb_info_type,a.lead_value,a.lead_unit,a.chart_style,a.chart_color,a.predict_chart_color,a.chart_width,a.source as mapping_source`
+
+	sql := ` SELECT ` + aField + `,b.source_name,b.source,b.sub_source,b.edb_code,b.edb_name,b.edb_name_en,b.frequency,b.unit,b.unit_en,b.start_date,b.end_date,b.modify_time,b.latest_date,b.latest_value,b.unique_code,b.edb_info_type AS edb_info_category_type,b.classify_id,b.is_join_permission
+             FROM chart_edb_mapping AS a
+			 INNER JOIN edb_info AS b ON a.edb_info_id=b.edb_info_id
+			 WHERE a.chart_info_id=? AND a.source = ?
+             ORDER BY chart_edb_mapping_id ASC `
+	err = global.MYSQL["data"].Raw(sql, chartInfoId, utils.CHART_SOURCE_DEFAULT).Scan(&items).Error
+	return
+}
+
 // GetFutureGoodEdbChartEdbMapping       商品曲线图查询对应的商品指标
 func GetFutureGoodEdbChartEdbMapping(chartInfoId int) (item *ChartEdbInfoMappingList, err error) {
 	aField := `a.chart_edb_mapping_id,a.chart_info_id,a.edb_info_id,a.create_time,a.modify_time,a.unique_code,a.max_data,a.min_data,a.is_order,a.is_axis,a.edb_info_type,a.lead_value,a.lead_unit,a.chart_style,a.chart_color,a.predict_chart_color,a.chart_width,a.source as mapping_source`

+ 48 - 2
models/tables/edb_data/query.go

@@ -16,7 +16,14 @@ import (
 func GetEdbDataTableName(source, subSource int) (tableName string) {
 	switch source {
 	case utils.DATA_SOURCE_THS:
-		tableName = "edb_data_ths"
+		switch subSource {
+		case utils.DATA_SUB_SOURCE_DATE:
+			tableName = "edb_data_ths_ds"
+		case utils.DATA_SUB_SOURCE_HIGH_FREQUENCY:
+			tableName = "edb_data_ths_hf"
+		default:
+			tableName = "edb_data_ths"
+		}
 	case utils.DATA_SOURCE_WIND:
 		if subSource == utils.DATA_SUB_SOURCE_DATE {
 			tableName = "edb_data_wind_wsd"
@@ -238,9 +245,12 @@ func (m QuarterDataList) Swap(i, j int) {
 // GetEdbDataList 获取指标数据
 func GetEdbDataList(source, subSource, edbInfoId int, startDate, endDate string) (list []*EdbDataList, err error) {
 	// 自有数据需要额外处理(从mongo获取)
-	if source == utils.DATA_SOURCE_BUSINESS {
+	if source == utils.DATA_SOURCE_BUSINESS && global.CONFIG.Serve.UseMongo {
 		return getEdbDataListByMongo(source, subSource, edbInfoId, startDate, endDate)
 	}
+	if source == utils.DATA_SOURCE_THS && subSource == utils.DATA_SUB_SOURCE_HIGH_FREQUENCY && global.CONFIG.Serve.UseMongo {
+		return getThsHfEdbDataListByMongo(source, subSource, edbInfoId, startDate, endDate)
+	}
 
 	return getEdbDataListByMysql(source, subSource, edbInfoId, startDate, endDate)
 }
@@ -337,3 +347,39 @@ func getEdbDataListByMongo(source, subSource, edbInfoId int, startDate, endDate
 
 	return
 }
+
+func getThsHfEdbDataListByMongo(source, subSource, edbInfoId int, startDate, endDate string) (list []*EdbDataList, err error) {
+	list = make([]*EdbDataList, 0)
+
+	mogDataObj := mgo.EdbDataThsHf{}
+	// 构建查询条件
+	queryConditions := bson.M{
+		"edb_info_id": edbInfoId,
+	}
+	// 日期
+	dateCondition, err := mgo.BuildDateCondition(startDate, endDate)
+	if err != nil {
+		return
+	}
+	if len(dateCondition) > 0 {
+		queryConditions["data_time"] = dateCondition
+	}
+
+	// 获取列表数据
+	tmpDataList, tmpErr := mogDataObj.GetAllDataList(queryConditions, []string{"data_time"})
+	if tmpErr != nil {
+		err = tmpErr
+		return
+	}
+	for k, v := range tmpDataList {
+		list = append(list, &EdbDataList{
+			EdbDataId:     k + 1,
+			EdbInfoId:     v.EdbInfoId,
+			DataTime:      v.DataTime.Format(utils.FormatDate),
+			DataTimestamp: v.DataTimestamp,
+			Value:         v.Value,
+		})
+	}
+
+	return
+}

+ 2 - 2
models/tables/future_good_edb_data/future_good_edb_data.go

@@ -6,8 +6,8 @@ import (
 
 // FutureGoodEdbData 期货指标的数据
 type FutureGoodEdbData struct {
-	FutureGoodEdbDataID uint32    `gorm:"primaryKey;column:future_good_edb_data_id;type:int(9) unsigned;not null" json:"-"`
-	FutureGoodEdbInfoID uint32    `gorm:"index:idx_edbid_date;column:future_good_edb_info_id;type:int(9) unsigned" json:"futureGoodEdbInfoId"` // 期货指标id
+	FutureGoodEdbDataID int       `gorm:"primaryKey;column:future_good_edb_data_id;type:int(9) unsigned;not null" json:"-"`
+	FutureGoodEdbInfoID int       `gorm:"index:idx_edbid_date;column:future_good_edb_info_id;type:int(9) unsigned" json:"futureGoodEdbInfoId"` // 期货指标id
 	FutureGoodEdbCode   string    `gorm:"index:idx_code_date;column:future_good_edb_code;type:varchar(64)" json:"futureGoodEdbCode"`           // 期货指标code
 	DataTime            time.Time `gorm:"index:idx_code_date;index:idx_edbid_date;column:data_time;type:date" json:"dataTime"`                 // 数据日期
 	TradeCode           string    `gorm:"column:trade_code;type:varchar(64);default:''" json:"tradeCode"`                                      // 证券代码

+ 21 - 1
models/tables/future_good_edb_data/query.go

@@ -1,6 +1,8 @@
 package future_good_edb_data
 
-import "hongze/hongze_yb/global"
+import (
+	"hongze/hongze_yb/global"
+)
 
 func GetFutureGoodEdbDataListByDate(futureGoodEdbInfoId int, startDate, endDate string) (list []*FutureGoodEdbData, err error) {
 	var pars []interface{}
@@ -20,3 +22,21 @@ func GetFutureGoodEdbDataListByDate(futureGoodEdbInfoId int, startDate, endDate
 
 	return
 }
+
+func GetFutureGoodEdbDataListByIdsAndDate(futureGoodEdbInfoIds []int, startDate, endDate string) (list []*FutureGoodEdbData, err error) {
+	var pars []interface{}
+	sql := `SELECT * FROM future_good_edb_data WHERE 1=1 AND future_good_edb_info_id in (?)  `
+	pars = append(pars, futureGoodEdbInfoIds)
+	if startDate != "" {
+		sql += ` AND data_time>=? `
+		pars = append(pars, startDate)
+	}
+	if endDate != "" {
+		sql += ` AND data_time<=? `
+		pars = append(pars, endDate)
+	}
+
+	sql += ` ORDER BY data_time ASC `
+	err = global.MYSQL["data"].Raw(sql, pars...).Scan(&list).Error
+	return
+}

+ 4 - 4
models/tables/future_good_edb_info/future_good_edb_info.go

@@ -6,17 +6,17 @@ import (
 
 // FutureGoodEdbInfo 期货指标
 type FutureGoodEdbInfo struct {
-	FutureGoodEdbInfoID uint64    `gorm:"primaryKey;column:future_good_edb_info_id;type:bigint(9) unsigned;not null" json:"-"`                // 期货指标id
+	FutureGoodEdbInfoID int       `gorm:"primaryKey;column:future_good_edb_info_id;type:bigint(9) unsigned;not null" json:"-"`                // 期货指标id
 	FutureGoodEdbCode   string    `gorm:"column:future_good_edb_code;type:varchar(64);default:null;default:''" json:"futureGoodEdbCode"`      // 期货指标code
 	FutureGoodEdbName   string    `gorm:"column:future_good_edb_name;type:varchar(64);default:null;default:''" json:"futureGoodEdbName"`      // 期货指标名称
 	FutureGoodEdbNameEn string    `gorm:"column:future_good_edb_name_en;type:varchar(64);default:null;default:''" json:"futureGoodEdbNameEn"` // 期货指标名称(英文)
 	ParentID            uint64    `gorm:"column:parent_id;type:bigint(9) unsigned;default:null;default:0" json:"parentId"`                    // 上级期货id
 	RegionType          string    `gorm:"column:region_type;type:varchar(32);default:null;default:国内" json:"regionType"`                      // 交易所来源,海外还是国内
 	Exchange            string    `gorm:"column:exchange;type:varchar(32);default:null;default:''" json:"exchange"`                           // 所属交易所
-	FutureGoodEdbType   int8      `gorm:"column:future_good_edb_type;type:tinyint(4);default:null;default:1" json:"futureGoodEdbType"`        // 指标类型,1:年月是固定的合约;2:只有M+N期的合约,未固定年月
-	DateSourceID        int64     `gorm:"column:date_source_id;type:bigint(9);default:null;default:0" json:"dateSourceId"`                    // 画图时,日期来源的指标id
+	FutureGoodEdbType   int       `gorm:"column:future_good_edb_type;type:tinyint(4);default:null;default:1" json:"futureGoodEdbType"`        // 指标类型,1:年月是固定的合约;2:只有M+N期的合约,未固定年月
+	DateSourceID        int       `gorm:"column:date_source_id;type:bigint(9);default:null;default:0" json:"dateSourceId"`                    // 画图时,日期来源的指标id
 	Year                int       `gorm:"column:year;type:int(9);default:null;default:0" json:"year"`                                         // 所属年份
-	Month               uint32    `gorm:"column:month;type:int(9) unsigned;default:null;default:0" json:"month"`                              // 所属月份
+	Month               int       `gorm:"column:month;type:int(9) unsigned;default:null;default:0" json:"month"`                              // 所属月份
 	StartDate           time.Time `gorm:"column:start_date;type:date;default:null" json:"startDate"`                                          // 数据开始日期
 	EndDate             time.Time `gorm:"column:end_date;type:date;default:null" json:"endDate"`                                              // 数据结束日期
 	MinValue            float64   `gorm:"column:min_value;type:double;default:null;default:0" json:"minValue"`                                // 最小值

+ 0 - 0
models/tables/chart_permission/chart_permission.go → models/tables/rddp/chart_permission/chart_permission.go


+ 9 - 9
models/tables/chart_permission/query.go → models/tables/rddp/chart_permission/query.go

@@ -8,19 +8,19 @@ import (
 
 // GetListByProductId 根据产品id获取所有权限列表
 func GetListByProductId(productId int64) (list []*ChartPermission, err error) {
-	err = global.DEFAULT_MYSQL.Where(" product_id = ?", productId).Find(&list).Error
+	err = global.MYSQL["rddp"].Where(" product_id = ?", productId).Find(&list).Error
 	return
 }
 
 // GetFiccListExceptTacticByProductId 获取ficc 除了市场策略的所有权限
 func GetFiccListExceptTacticByProductId() (list []*ChartPermission, err error) {
-	err = global.DEFAULT_MYSQL.Where(" enabled = 1 AND permission_type = 0 AND product_id = 1 and parent_id >0 and classify_name != '市场策略'").Order("sort asc").Find(&list).Error
+	err = global.MYSQL["rddp"].Where(" enabled = 1 AND permission_type = 0 AND product_id = 1 and parent_id >0 and classify_name != '市场策略'").Order("sort asc").Find(&list).Error
 	return
 }
 
 // GetClassNameListByProductId 根据权限id获取权限分类
 func GetClassNameListByProductId(productId int64) (list []*ChartPermission, err error) {
-	err = global.DEFAULT_MYSQL.Where(" product_id = ?", productId).Group("classify_name").Find(&list).Error
+	err = global.MYSQL["rddp"].Where(" product_id = ?", productId).Group("classify_name").Find(&list).Error
 	return
 }
 
@@ -31,25 +31,25 @@ func GetByWhereMap(where map[string]interface{}) (list []*ChartPermission, err e
 		err = errors.New("系统异常,生成查询语句失败")
 		return
 	}
-	err = global.DEFAULT_MYSQL.Where(cond, whereVal...).Find(&list).Error
+	err = global.MYSQL["rddp"].Where(cond, whereVal...).Find(&list).Error
 	return
 }
 
 // GetListByIds 通过IDs获取图表权限集合
 func GetListByIds(permissionIds []int) (list []*ChartPermission, err error) {
-	err = global.DEFAULT_MYSQL.Model(ChartPermission{}).Where("chart_permission_id IN (?)", permissionIds).Scan(&list).Error
+	err = global.MYSQL["rddp"].Model(ChartPermission{}).Where("chart_permission_id IN (?)", permissionIds).Scan(&list).Error
 	return
 }
 
 // GetListByProductIdAndPermissionType 根据product及classify_name获取集合
 func GetListByProductIdAndPermissionType(productId int) (items []*ChartPermission, err error) {
-	err = global.DEFAULT_MYSQL.Model(ChartPermission{}).Where("enabled = 1 AND permission_type = 0 AND product_id = ? ", productId).Order("sort ASC").Scan(&items).Error
+	err = global.MYSQL["rddp"].Model(ChartPermission{}).Where("enabled = 1 AND permission_type = 0 AND product_id = ? ", productId).Order("sort ASC").Scan(&items).Error
 	return
 }
 
 // GetByChartPermissionId 根据chartPermissionId 查找权限基本信息
 func GetByChartPermissionId(chartPermissionId int) (item *ChartPermission, err error) {
-	err = global.DEFAULT_MYSQL.Model(ChartPermission{}).Where("chart_permission_id = ?", chartPermissionId).First(&item).Error
+	err = global.MYSQL["rddp"].Model(ChartPermission{}).Where("chart_permission_id = ?", chartPermissionId).First(&item).Error
 	if err == utils.ErrNoRow {
 		err = nil
 	}
@@ -58,13 +58,13 @@ func GetByChartPermissionId(chartPermissionId int) (item *ChartPermission, err e
 
 // GetFiccFirstListExceptTacticByProductId 获取ficc 除了市场策略的所有父级
 func GetFiccFirstListExceptTacticByProductId() (list []*ChartPermission, err error) {
-	err = global.DEFAULT_MYSQL.Where(" enabled = 1 AND permission_type = 0 AND product_id = 1 and classify_name != '市场策略' AND parent_id = 0").Order("sort asc").Find(&list).Error
+	err = global.MYSQL["rddp"].Where(" enabled = 1 AND permission_type = 0 AND product_id = 1 and classify_name != '市场策略' AND parent_id = 0").Order("sort asc").Find(&list).Error
 	return
 }
 
 // GetChartPermissionsByProductId 获取权限列表
 func GetChartPermissionsByProductId() (list []*ChartPermission, err error) {
-	err = global.DEFAULT_MYSQL.Where(" enabled = 1 AND product_id = 1").Order("parent_id ASC, sort ASC, created_time ASC").Find(&list).Error
+	err = global.MYSQL["rddp"].Where(" enabled = 1 AND product_id = 1").Order("parent_id ASC, sort ASC, created_time ASC").Find(&list).Error
 	return
 }
 

+ 0 - 0
models/tables/chart_permission_chapter_mapping/chart_permission_chapter_mapping.go → models/tables/rddp/chart_permission_chapter_mapping/chart_permission_chapter_mapping.go


+ 7 - 7
models/tables/chart_permission_chapter_mapping/query.go → models/tables/rddp/chart_permission_chapter_mapping/query.go

@@ -5,9 +5,9 @@ import (
 )
 
 // GetReportIdsByPermisssionIds 根据权限ID筛选报告ID, rddp 类型表示新后台新增的报告,区分老后台
-func GetReportIdsByPermisssionIds(permissionIds []int, researchType string) (reportIds []int, err error)  {
+func GetReportIdsByPermisssionIds(permissionIds []int, researchType string) (reportIds []int, err error) {
 	var charPermissionMapping []*ChartPermissionChapterMapping
-	err = global.DEFAULT_MYSQL.Model(ChartPermissionChapterMapping{}).Select("DISTINCT report_chapter_type_id ").Where("chart_permission_id in (?) AND research_type = ? ", permissionIds, researchType).Scan(&charPermissionMapping).Error
+	err = global.MYSQL["rddp"].Model(ChartPermissionChapterMapping{}).Select("DISTINCT report_chapter_type_id ").Where("chart_permission_id in (?) AND research_type = ? ", permissionIds, researchType).Scan(&charPermissionMapping).Error
 	if err != nil {
 		return
 	}
@@ -18,9 +18,9 @@ func GetReportIdsByPermisssionIds(permissionIds []int, researchType string) (rep
 }
 
 // GetPermissionIdsByReportId 根据报告ID筛选出对应的权限
-func GetPermissionIdsByReportId(reportId int, researchType string) (permissionIds []int, err error)  {
+func GetPermissionIdsByReportId(reportId int, researchType string) (permissionIds []int, err error) {
 	var charPermissionMapping []*ChartPermissionChapterMapping
-	err = global.DEFAULT_MYSQL.Model(ChartPermissionChapterMapping{}).
+	err = global.MYSQL["rddp"].Model(ChartPermissionChapterMapping{}).
 		Select("DISTINCT chart_permission_id").
 		Where("report_chapter_type_id = ? and research_type = ? ", reportId, researchType).
 		Scan(&charPermissionMapping).Error
@@ -34,9 +34,9 @@ func GetPermissionIdsByReportId(reportId int, researchType string) (permissionId
 }
 
 // GetPermissionIdsByWeek 根据报告ID筛选出对应的权限
-func GetPermissionIdsByWeek() (permissionIds []int, err error)  {
+func GetPermissionIdsByWeek() (permissionIds []int, err error) {
 	var charPermissionMapping []*ChartPermissionChapterMapping
-	err = global.DEFAULT_MYSQL.Model(ChartPermissionChapterMapping{}).
+	err = global.MYSQL["rddp"].Model(ChartPermissionChapterMapping{}).
 		Select("DISTINCT chart_permission_id").
 		Where("research_type = 'week'").
 		Scan(&charPermissionMapping).Error
@@ -47,4 +47,4 @@ func GetPermissionIdsByWeek() (permissionIds []int, err error)  {
 		permissionIds = append(permissionIds, v.ChartPermissionId)
 	}
 	return
-}
+}

+ 32 - 29
models/tables/rddp/classify/classify.go

@@ -3,35 +3,38 @@ package classify
 import "time"
 
 type Classify struct {
-	Id                int       `gorm:"column:id" db:"id" json:"id" form:"id"`
-	ClassifyName      string    `gorm:"column:classify_name" db:"classify_name" json:"classify_name" form:"classify_name"` //分类名称
-	Sort              int8      `gorm:"column:sort" db:"sort" json:"sort" form:"sort"`                                     //排序
-	ParentId          int       `gorm:"column:parent_id" db:"parent_id" json:"parent_id" form:"parent_id"`                 //父级分类id
-	CreateTime        time.Time `gorm:"column:create_time" db:"create_time" json:"create_time" form:"create_time"`
-	ModifyTime        time.Time `gorm:"column:modify_time" db:"modify_time" json:"modify_time" form:"modify_time"`
-	Abstract          string    `gorm:"column:abstract" db:"abstract" json:"abstract" form:"abstract"`                             //栏目简介
-	Descript          string    `gorm:"column:descript" db:"descript" json:"descript" form:"descript"`                             //分享描述
-	ReportAuthor      string    `gorm:"column:report_author" db:"report_author" json:"report_author" form:"report_author"`         //栏目作者
-	AuthorDescript    string    `gorm:"column:author_descript" db:"author_descript" json:"author_descript" form:"author_descript"` //作者简介
-	ReportImgUrl      string    `gorm:"column:report_img_url" db:"report_img_url" json:"report_img_url" form:"report_img_url"`     //报告配图
-	HeadImgUrl        string    `gorm:"column:head_img_url" db:"head_img_url" json:"head_img_url" form:"head_img_url"`             //头部banner
-	AvatarImgUrl      string    `gorm:"column:avatar_img_url" db:"avatar_img_url" json:"avatar_img_url" form:"avatar_img_url"`     //头像
-	ColumnImgUrl      string    `gorm:"column:column_img_url" db:"column_img_url" json:"column_img_url" form:"column_img_url"`     //栏目配图
-	IsHomeColumn      int8      `gorm:"column:is_home_column" db:"is_home_column" json:"is_home_column" form:"is_home_column"`     //1:首页专栏
-	HomeImgUrl        string    `gorm:"column:home_img_url" db:"home_img_url" json:"home_img_url" form:"home_img_url"`             //首页配图
-	ClassifyLabel     string    `gorm:"column:classify_label" db:"classify_label" json:"classify_label" form:"classify_label"`
-	ShowType          uint8     `gorm:"column:show_type" db:"show_type" json:"show_type" form:"show_type"`                                     //展示类型:1-列表 2-专栏
-	HasTeleconference uint8     `gorm:"column:has_teleconference" db:"has_teleconference" json:"has_teleconference" form:"has_teleconference"` //是否有电话会 0-否 1-是
-	VipTitle          string    `gorm:"column:vip_title" db:"vip_title" json:"vip_title" form:"vip_title"`                                     //研究员头衔
-	YbIconUrl         string    `gorm:"column:yb_icon_url" db:"yb_icon_url" json:"yb_icon_url" form:"yb_icon_url"`                             //研报3.0已购页面icon图片地址
-	YbBgUrl           string    `gorm:"column:yb_bg_url" db:"yb_bg_url" json:"yb_bg_url" form:"yb_bg_url"`                                     //研报3.0已购详情背景图地址
-	IsShow            int8      `gorm:"column:is_show" db:"is_show" json:"is_show" form:"is_show"`                                             //是否展示报告:1,展示该分类下的报告,0隐藏分类下的报告
-	YbFiccIcon        string    `gorm:"column:yb_ficc_icon" db:"yb_ficc_icon" json:"yb_ficc_icon" form:"yb_ficc_icon"`                         //研报小程序端ficc页码图标
-	YbFiccPcIcon      string    `gorm:"column:yb_ficc_pc_icon" db:"yb_ficc_pc_icon" json:"yb_ficc_pc_icon" form:"yb_ficc_pc_icon"`             //研报 pc端ficc页码图标
-	YbFiccSort        int       `gorm:"column:yb_ficc_sort" db:"yb_ficc_sort" json:"yb_ficc_sort" form:"yb_ficc_sort"`                         //研报小程序端ficc页面排序
-	YbListImg         string    `gorm:"column:yb_list_img" db:"yb_list_img" json:"yb_list_img" form:"yb_list_img"`                             //研报小程序端报告列表封面图
-	YbShareBgImg      string    `gorm:"column:yb_share_bg_img;" db:"yb_share_bg_img" json:"yb_share_bg_img" form:"yb_share_bg_img"`
-	YbRightBanner     string    `gorm:"column:yb_right_banner;" db:"yb_right_banner" json:"yb_right_banner" form:"yb_right_banner"` // 研报小程序-报告分享背景图
+	Id                   int       `gorm:"column:id" db:"id" json:"id" form:"id"`
+	ClassifyName         string    `gorm:"column:classify_name" db:"classify_name" json:"classify_name" form:"classify_name"` //分类名称
+	Sort                 int8      `gorm:"column:sort" db:"sort" json:"sort" form:"sort"`                                     //排序
+	ParentId             int       `gorm:"column:parent_id" db:"parent_id" json:"parent_id" form:"parent_id"`                 //父级分类id
+	CreateTime           time.Time `gorm:"column:create_time" db:"create_time" json:"create_time" form:"create_time"`
+	ModifyTime           time.Time `gorm:"column:modify_time" db:"modify_time" json:"modify_time" form:"modify_time"`
+	Abstract             string    `gorm:"column:abstract" db:"abstract" json:"abstract" form:"abstract"`                             //栏目简介
+	Descript             string    `gorm:"column:descript" db:"descript" json:"descript" form:"descript"`                             //分享描述
+	ReportAuthor         string    `gorm:"column:report_author" db:"report_author" json:"report_author" form:"report_author"`         //栏目作者
+	AuthorDescript       string    `gorm:"column:author_descript" db:"author_descript" json:"author_descript" form:"author_descript"` //作者简介
+	ReportImgUrl         string    `gorm:"column:report_img_url" db:"report_img_url" json:"report_img_url" form:"report_img_url"`     //报告配图
+	HeadImgUrl           string    `gorm:"column:head_img_url" db:"head_img_url" json:"head_img_url" form:"head_img_url"`             //头部banner
+	AvatarImgUrl         string    `gorm:"column:avatar_img_url" db:"avatar_img_url" json:"avatar_img_url" form:"avatar_img_url"`     //头像
+	ColumnImgUrl         string    `gorm:"column:column_img_url" db:"column_img_url" json:"column_img_url" form:"column_img_url"`     //栏目配图
+	IsHomeColumn         int8      `gorm:"column:is_home_column" db:"is_home_column" json:"is_home_column" form:"is_home_column"`     //1:首页专栏
+	HomeImgUrl           string    `gorm:"column:home_img_url" db:"home_img_url" json:"home_img_url" form:"home_img_url"`             //首页配图
+	ClassifyLabel        string    `gorm:"column:classify_label" db:"classify_label" json:"classify_label" form:"classify_label"`
+	ShowType             uint8     `gorm:"column:show_type" db:"show_type" json:"show_type" form:"show_type"`                                     //展示类型:1-列表 2-专栏
+	HasTeleconference    uint8     `gorm:"column:has_teleconference" db:"has_teleconference" json:"has_teleconference" form:"has_teleconference"` //是否有电话会 0-否 1-是
+	VipTitle             string    `gorm:"column:vip_title" db:"vip_title" json:"vip_title" form:"vip_title"`                                     //研究员头衔
+	YbIconUrl            string    `gorm:"column:yb_icon_url" db:"yb_icon_url" json:"yb_icon_url" form:"yb_icon_url"`                             //研报3.0已购页面icon图片地址
+	YbBgUrl              string    `gorm:"column:yb_bg_url" db:"yb_bg_url" json:"yb_bg_url" form:"yb_bg_url"`                                     //研报3.0已购详情背景图地址
+	IsShow               int8      `gorm:"column:is_show" db:"is_show" json:"is_show" form:"is_show"`                                             //是否展示报告:1,展示该分类下的报告,0隐藏分类下的报告
+	YbFiccIcon           string    `gorm:"column:yb_ficc_icon" db:"yb_ficc_icon" json:"yb_ficc_icon" form:"yb_ficc_icon"`                         //研报小程序端ficc页码图标
+	YbFiccPcIcon         string    `gorm:"column:yb_ficc_pc_icon" db:"yb_ficc_pc_icon" json:"yb_ficc_pc_icon" form:"yb_ficc_pc_icon"`             //研报 pc端ficc页码图标
+	YbFiccSort           int       `gorm:"column:yb_ficc_sort" db:"yb_ficc_sort" json:"yb_ficc_sort" form:"yb_ficc_sort"`                         //研报小程序端ficc页面排序
+	YbListImg            string    `gorm:"column:yb_list_img" db:"yb_list_img" json:"yb_list_img" form:"yb_list_img"`                             //研报小程序端报告列表封面图
+	YbShareBgImg         string    `gorm:"column:yb_share_bg_img;" db:"yb_share_bg_img" json:"yb_share_bg_img" form:"yb_share_bg_img"`
+	YbRightBanner        string    `gorm:"column:yb_right_banner;" db:"yb_right_banner" json:"yb_right_banner" form:"yb_right_banner"`                                // 研报小程序-报告分享背景图
+	Level                int       `gorm:"column:level" db:"level" json:"level" form:"level"`                                                                         // 层级
+	HasChild             int       `gorm:"column:has_child" db:"has_child" json:"has_child" form:"has_child"`                                                         //是否有子级别,0:下面没有子分类,1:下面有子分类;默认:0
+	ReportDetailShowType uint8     `gorm:"column:report_detail_show_type" db:"report_detail_show_type" json:"report_detail_show_type" form:"report_detail_show_type"` // 报告详情的展示类型:1-拼接;2:目录
 }
 
 func (c *Classify) TableName() string {

+ 28 - 0
models/tables/rddp/classify/query.go

@@ -1,6 +1,7 @@
 package classify
 
 import (
+	"errors"
 	"hongze/hongze_yb/global"
 	"hongze/hongze_yb/utils"
 )
@@ -129,3 +130,30 @@ func GetClassifyList() (list []*Classify, err error) {
 	err = global.MYSQL["rddp"].Model(Classify{}).Scan(&list).Error
 	return
 }
+
+// GetByClassifyIdFirst
+// @Description: 根据一级分类id查找一级分类
+// @author: Roc
+// @datetime 2024-06-24 13:57:59
+// @param classifyId int
+// @return item *Classify
+// @return err error
+func GetByClassifyIdFirst(classifyId int) (item *Classify, err error) {
+	err = global.MYSQL["rddp"].Model(Classify{}).Where("id = ? and parent_id = 0", classifyId).First(&item).Error
+	if errors.Is(err, utils.ErrNoRow) {
+		err = nil
+	}
+
+	return
+}
+
+// GetListByClassifyIdList
+// @Description: 根据ID列表获取所有的分类
+// @param idList
+// @return list
+// @return err
+func GetListByClassifyIdList(idList []int) (list []*Classify, err error) {
+	err = global.MYSQL["rddp"].Model(Classify{}).Where("id in (?) AND is_show = 1 AND enabled = 1", idList).Find(&list).Error
+	return
+
+}

+ 142 - 1
models/tables/rddp/report/query.go

@@ -6,6 +6,7 @@ import (
 	"hongze/hongze_yb/models/response"
 	"hongze/hongze_yb/models/response/pc"
 	"hongze/hongze_yb/utils"
+	"strings"
 )
 
 // GetLatestClassReportsByClassifyIdSeconds 根据用户已购买的分类权限查询个分类最新的报告
@@ -225,7 +226,7 @@ func GetListCountByClassifyIdSecond(classifyIdSecond int) (total int64, err erro
 // GetReportList 获取报告列表
 func GetReportList(condition string, pars []interface{}, offset, limit int) (list []*Report, err error) {
 	err = global.MYSQL["rddp"].Model(Report{}).
-		Select("id, classify_id_first, classify_name_first, classify_id_second, classify_name_second, title, stage, publish_time, author, create_time, video_url, video_name, video_play_seconds, abstract").
+		Select("id, classify_id_first, classify_name_first, classify_id_second, classify_name_second,classify_id_third, classify_name_third, title, stage, publish_time, author, create_time, video_url, video_name, video_play_seconds, abstract,has_chapter,head_img,end_img,head_resource_id,end_resource_id").
 		Where(condition, pars...).
 		Order("publish_time desc, id desc").
 		Offset(offset).
@@ -457,3 +458,143 @@ func GetListByReportIds(reportIds []int) (list []*Report, err error) {
 		Scan(&list).Error
 	return
 }
+
+// GetReportCollectListByPermissionV1
+// @Description: 根据权限相关的分类查询报告和章节
+// @author: Roc
+// @datetime 2024-06-21 10:24:14
+// @param chartPermissionId int
+// @param classifyIdSeconds []int
+// @param offset int
+// @param limit int
+// @return list []*response.ReportCollectListItem
+// @return err error
+func GetReportCollectListByPermissionV1(chartPermissionId int, firstClassifyIdList, secondClassifyIdList, thirdClassifyIdList []int, offset, limit int) (list []*response.ReportCollectListItem, err error) {
+	conditionList := make([]string, 0)
+	pars := make([]interface{}, 0)
+	if len(firstClassifyIdList) > 0 {
+		conditionList = append(conditionList, "classify_id_first in ?")
+		pars = append(pars, firstClassifyIdList)
+	}
+	if len(secondClassifyIdList) > 0 {
+		conditionList = append(conditionList, "classify_id_second in ?")
+		pars = append(pars, secondClassifyIdList)
+	}
+	if len(thirdClassifyIdList) > 0 {
+		conditionList = append(conditionList, "classify_id_third in ?")
+		pars = append(pars, thirdClassifyIdList)
+	}
+
+	condition := " classify_id_first = 0 "
+	if len(conditionList) > 0 {
+		condition = strings.Join(conditionList, " OR ")
+	}
+
+	pars = append(pars, chartPermissionId, limit, offset)
+
+	sql := `( SELECT
+id AS report_id,
+0 AS report_chapter_id,
+classify_id_first,
+classify_id_second,
+classify_name_first,
+classify_name_second,
+0 as report_chapter_type_id,
+title,
+content_sub,
+publish_time 
+FROM
+	report
+WHERE
+	has_chapter != 1 
+	AND ( ` + condition + ` )
+	AND state IN (2, 6)
+	)
+UNION
+	
+( SELECT
+a.report_id,
+a.report_chapter_id,
+a.classify_id_first,
+0 as classify_id_second,
+a.classify_name_first,
+null as classify_name_second,
+a.type_id as report_chapter_type_id,
+a.title,
+a.content_sub,
+a.publish_time 
+FROM
+	report_chapter AS a 
+JOIN report_chapter_permission_mapping AS b on a.report_chapter_id=b.report_chapter_id
+WHERE
+	a.publish_state = 2
+AND b.chart_permission_id = ?
+	)
+	ORDER BY publish_time DESC, report_id desc LIMIT ? OFFSET ?
+	`
+	err = global.MYSQL["rddp"].Raw(sql, pars...).Scan(&list).Error
+	return
+}
+
+// GetReportCollectCountByPermission 查询汇总报告总页数
+func GetReportCollectCountByPermissionV1(chartPermissionId int, classifyIdSeconds []int) (total int64, err error) {
+	sql := `select count(*) from ( (( SELECT
+id AS report_id,
+0 AS report_chapter_id
+FROM
+	report
+WHERE
+	has_chapter != 1 
+	AND classify_id_second in ?
+	AND state IN (2, 6)
+	)
+UNION
+	
+( SELECT 
+a.report_id,
+a.report_chapter_id
+FROM
+	report_chapter AS a 
+JOIN report_chapter_permission_mapping AS b on a.report_chapter_id=b.report_chapter_id
+WHERE
+	a.publish_state = 2
+AND b.chart_permission_id = ?
+	)
+)
+	
+) as ru
+	`
+	err = global.MYSQL["rddp"].Raw(sql, classifyIdSeconds, chartPermissionId).Count(&total).Error
+	return
+}
+
+// GetLatestReportByClassifyId
+// @Description: 根据分类id获取最近一期报告
+// @author: Roc
+// @datetime 2024-06-24 14:10:05
+// @param firstId int
+// @param secondId int
+// @param thirdId int
+// @return items *pc.LatestReportBanner
+// @return err error
+func GetLatestReportByClassifyId(firstId, secondId, thirdId int) (items *pc.LatestReportBanner, err error) {
+	sql := `SELECT
+	a.id AS report_id,
+	classify_name_second,
+	classify_id_second,
+	classify_name_first,
+	classify_id_first,
+	author,
+	stage
+FROM
+	report as a
+WHERE
+	a.state IN (2, 6) 
+	AND a.classify_id_first = ? 
+	AND a.classify_id_second = ? 
+	AND a.classify_id_third = ? 
+ORDER BY
+	publish_time DESC `
+	err = global.MYSQL["rddp"].Raw(sql, firstId, secondId, thirdId).First(&items).Error
+	return
+}

+ 10 - 0
models/tables/rddp/report/report.go

@@ -9,6 +9,8 @@ type Report struct {
 	ClassifyNameFirst  string    `description:"一级分类名称" json:"classify_name_first"`
 	ClassifyIdSecond   int       `description:"二级分类id" json:"classify_id_second"`
 	ClassifyNameSecond string    `description:"二级分类名称" json:"classify_name_second"`
+	ClassifyIdThird    int       `description:"三级分类id" json:"classify_id_third"`
+	ClassifyNameThird  string    `description:"三级分类名称" json:"classify_name_third"`
 	Title              string    `description:"标题" json:"title"`
 	Abstract           string    `description:"摘要" json:"abstract"`
 	Author             string    `description:"作者" json:"author"`
@@ -27,6 +29,14 @@ type Report struct {
 	ContentSub         string    `description:"内容前两个章节" json:"content_sub"`
 	ThsMsgIsSend       int       `description:"客户群消息是否已发送,0:否,1:是" json:"ths_msg_is_send"`
 	StageStr           string    `description:"期数" json:"stage_str"`
+	HasChapter         int       `description:"是否有章节" json:"has_chapter"`
+	ReportLayout       int8      `description:"报告布局,1:常规布局,2:智能布局。默认:1" json:"report_layout"`
+	HeadImg            string    `description:"报告头图地址" json:"head_img"`
+	EndImg             string    `description:"报告尾图地址" json:"end_img"`
+	CanvasColor        string    `description:"画布颜色" json:"canvas_color"`
+	HeadResourceId     int       `description:"版头资源ID" json:"head_resource_id"`
+	EndResourceId      int       `description:"版尾资源ID" json:"end_resource_id"`
+	VoiceGenerateType  int8      `description:"音频生成方式,0:系统生成,1:人工上传" json:"voice_generate_type"`
 }
 
 type UnReadItem struct {

+ 81 - 1
models/tables/rddp/report_chapter/query.go

@@ -59,7 +59,7 @@ func GetListByReportIdTypeIds(reportId int, typeIds []int, classifyNameFirst str
 
 // GetContentById 根据ID获取章节详情
 func GetContentById(id int, typeIds []int) (info *ReportChapter, err error) {
-	err = global.MYSQL["rddp"].Model(ReportChapter{}).Select("report_chapter_id, report_id,  is_edit, classify_name_first, classify_id_first, content, trend, type_id, type_name, abstract, title, author, stage, publish_time, content, content_sub, video_url, video_name, video_play_seconds, video_size, report_type, video_size").
+	err = global.MYSQL["rddp"].Model(ReportChapter{}).Select("report_chapter_id, report_id,  is_edit, classify_name_first, classify_id_first, content, trend, type_id, type_name, abstract, title, author, stage, publish_time, content, content_sub, video_url, video_name, video_play_seconds, video_size, report_type, video_size,report_layout").
 		Where("report_chapter_id = ? and type_id in (?) AND publish_state = 2 ", id, typeIds).
 		First(&info).Error
 	if err == utils.ErrNoRow {
@@ -194,3 +194,83 @@ func GetListByChapterIds(chapterIds []int) (list []*ReportChapter, err error) {
 		Scan(&list).Error
 	return
 }
+
+// GetLatestChapterByMinClassifyId
+// @Description: 根据分类id获取最新的章节信息
+// @author: Roc
+// @datetime 2024-06-24 14:00:46
+// @param minClassifyId int
+// @return items *ReportChapter
+// @return err error
+func GetLatestChapterByMinClassifyId(minClassifyId int) (items *ReportChapter, err error) {
+	sql := `SELECT
+	report_id,
+	classify_name_first,
+	classify_id_first,
+	stage 
+FROM
+	report_chapter 
+WHERE
+	publish_state = 2 
+	AND classify_id_first = ?
+ORDER BY
+	publish_time DESC `
+	err = global.MYSQL["rddp"].Raw(sql, minClassifyId).First(&items).Error
+
+	return
+}
+
+// GetWeekRecommendListV2
+// @Description: 获取推荐列表
+// @author: Roc
+// @datetime 2024-06-24 14:20:09
+// @param reportId int
+// @param firstId int
+// @param secondId int
+// @param thirdId int
+// @return items []*ReportChapter
+// @return err error
+func GetWeekRecommendListV2(reportId, minClassifyId int) (items []*ReportChapter, err error) {
+	sql := `SELECT * FROM (SELECT
+	a.report_id,
+	a.report_chapter_id,
+	a.classify_name_first,
+	a.title,
+	a.stage,
+	a.publish_time 
+FROM
+	report_chapter AS a,
+	report AS b
+WHERE
+	a.publish_state = 2 
+	AND a.report_id <> ?
+	AND a.classify_id_first = ?
+	AND a.report_id=b.id
+	AND b.state IN (2, 6)
+ORDER BY
+	publish_time DESC) t
+	GROUP BY report_id 
+	ORDER BY publish_time desc LIMIT 3 `
+	err = global.MYSQL["rddp"].Raw(sql, reportId, minClassifyId).Scan(&items).Error
+	return
+}
+
+// GetByPermissionIdListAndReportList
+// @Description: 根据报告id和品种权限获取所有的章节
+// @param permissionIdList
+// @param reportIds
+// @return list
+// @return err
+func GetByPermissionIdListAndReportList(permissionIdList, reportIds []int) (list []*ReportChapter, err error) {
+	sql := ` SELECT a.report_id, a.type_id, a.report_chapter_id, a.classify_name_first, a.classify_id_first, a.video_url, a.video_name, a.video_play_seconds, a.video_size, a.sort FROM report_chapter a
+            INNER JOIN  report_chapter_permission_mapping b ON a.report_chapter_id = b.report_chapter_id
+            WHERE a.report_id in (?) AND b.chart_permission_id IN (?) AND a.is_edit = 1 AND a.publish_state = 2 `
+
+	sql += ` order by a.sort asc,a.report_chapter_id asc `
+	err = global.MYSQL["rddp"].Raw(sql, reportIds, permissionIdList).Scan(&list).Error
+
+	for _, v := range list {
+		reportIds = append(reportIds, v.ReportId)
+	}
+	return
+}

+ 2 - 0
models/tables/rddp/report_chapter/report_chapter.go

@@ -28,6 +28,8 @@ type ReportChapter struct {
 	VideoSize         string    `gorm:"column:video_size;type:varchar(255);not null;default:''"  json:"video_size"`                 //音频文件大小,单位M
 	CreateTime        time.Time `gorm:"column:create_time;type:datetime"  json:"create_time"`                                       //创建时间
 	ModifyTime        time.Time `gorm:"column:modify_time;type:datetime"  json:"modify_time"`                                       //修改时间
+	ReportLayout      int8      `description:"报告布局,1:常规布局,2:智能布局。默认:1" json:"report_layout"`
+	VoiceGenerateType int8      `description:"音频生成方式,0:系统生成,1:人工上传" json:"voice_generate_type"`
 }
 
 func (r *ReportChapter) TableName() string {

+ 11 - 0
models/tables/rddp/session/update.go

@@ -1,6 +1,7 @@
 package session
 
 import (
+	"fmt"
 	"time"
 )
 
@@ -18,3 +19,13 @@ func (session *Session) UpdateSession(userId int64, expireTime time.Time) (err e
 	err = session.Update(updateCols)
 	return
 }
+
+// ClearRepeatBindAccountToken 清除重复绑定账号的token
+func ClearRepeatBindAccountToken(openIds []string) (err error) {
+	if len(openIds) == 0 {
+		return
+	}
+	sql := fmt.Sprintf(` DELETE FROM session WHERE open_id IN ? AND expire_time >= NOW() `)
+	err = getDb().Exec(sql, openIds).Error
+	return
+}

+ 33 - 0
models/tables/rddp/smart_report_resource/query.go

@@ -0,0 +1,33 @@
+package smart_report_resource
+
+import (
+	"hongze/hongze_yb/global"
+)
+
+// GetResourceItemById
+// @Description: 根据资源id获取信息
+// @author: Roc
+// @datetime 2024-06-21 16:59:23
+// @param resourceId int
+// @return item *SmartReportResource
+// @return err error
+func GetResourceItemById(resourceId int) (item *SmartReportResource, err error) {
+	err = global.MYSQL["rddp"].Model(SmartReportResource{}).
+		Select("*").
+		Where("resource_id = ? ", resourceId).First(&item).Error
+	return
+}
+
+// GetResourceItemListByIdList
+// @Description: 根据资源id列表获取信息列表
+// @author: Roc
+// @datetime 2024-06-21 17:00:31
+// @param resourceIdList []int
+// @return items []*SmartReportResource
+// @return err error
+func GetResourceItemListByIdList(resourceIdList []int) (items []*SmartReportResource, err error) {
+	err = global.MYSQL["rddp"].Model(SmartReportResource{}).
+		Select("*").
+		Where("resource_id in (?) ", resourceIdList).Find(&items).Error
+	return
+}

+ 37 - 0
models/tables/rddp/smart_report_resource/smart_report_resource.go

@@ -0,0 +1,37 @@
+package smart_report_resource
+
+import (
+	"time"
+)
+
+// SmartReportResource 智能研报-资源表
+type SmartReportResource struct {
+	ResourceID int       `gorm:"primaryKey;column:resource_id" json:"-"`
+	ImgURL     string    `gorm:"column:img_url" json:"imgUrl"`         // 图片链接
+	ImgName    string    `gorm:"column:img_name" json:"imgName"`       // 图片名称
+	Type       int       `gorm:"column:type" json:"type"`              // 类型 1-版头 2-版尾
+	CreateTime time.Time `gorm:"column:create_time" json:"createTime"` // 创建时间
+	Style      string    `gorm:"column:style" json:"style"`            // 版图样式
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *SmartReportResource) TableName() string {
+	return "smart_report_resource"
+}
+
+// SmartReportResourceColumns get sql column name.获取数据库列名
+var SmartReportResourceColumns = struct {
+	ResourceID string
+	ImgURL     string
+	ImgName    string
+	Type       string
+	CreateTime string
+	Style      string
+}{
+	ResourceID: "resource_id",
+	ImgURL:     "img_url",
+	ImgName:    "img_name",
+	Type:       "type",
+	CreateTime: "create_time",
+	Style:      "style",
+}

+ 85 - 0
models/tables/report_chapter_permission_mapping/query.go

@@ -0,0 +1,85 @@
+package report_chapter_permission_mapping
+
+import (
+	"hongze/hongze_yb/global"
+	"time"
+)
+
+// GetReportChapterListByPermissionIdsAndReportId
+// @Description: 根据报告ID和品种ID列表获取章节
+// @author: Roc
+// @datetime 2024-06-24 11:00:16
+// @param permissionIds []int
+// @param reportId int
+// @return reportChapterIdList []int
+// @return err error
+func GetReportChapterListByPermissionIdsAndReportId(permissionIds []int, reportId int) (reportChapterIdList []int, err error) {
+	var items []*ReportChapterPermissionMapping
+	obj := ReportChapterPermissionMapping{}
+	err = global.MYSQL["rddp"].Table(obj.TableName()+" AS a ").
+		Joins("INNER JOIN report_chapter AS b ON a.report_chapter_id = b.report_chapter_id").
+		Select("DISTINCT a.report_chapter_id ").
+		Where("a.chart_permission_id in (?) AND b.report_id = ? ", permissionIds, reportId).
+		Scan(&items).Error
+	if err != nil {
+		return
+	}
+	for _, v := range items {
+		reportChapterIdList = append(reportChapterIdList, v.ReportChapterID)
+	}
+
+	return
+}
+
+// ReportChapterPermissionMappingItem 报告章节的权限关系表
+type ReportChapterPermissionMappingItem struct {
+	ReportChapterPermissionMappingID int       `gorm:"primaryKey;column:report_chapter_permission_mapping_id" json:"report_chapter_permission_mapping_id"`
+	ReportChapterID                  int       `gorm:"column:report_chapter_id" json:"report_chapter_id"`     // 报告章节的id
+	ChartPermissionID                int       `gorm:"column:chart_permission_id" json:"chart_permission_id"` // 权限id
+	TypeId                           int       `gorm:"column:type_id" json:"type_id"`                         // 报告章节类型id
+	CreateTime                       time.Time `gorm:"column:create_time" json:"create_time"`
+}
+
+// GetReportChapterPermissionMappingItemListByReportId
+// @Description: 根据报告ID列表获取章节
+// @author: Roc
+// @datetime 2024-06-24 11:00:16
+// @param permissionIds []int
+// @param reportId int
+// @return reportChapterIdList []int
+// @return err error
+func GetReportChapterPermissionMappingItemListByReportId(reportId int) (items []*ReportChapterPermissionMappingItem, err error) {
+	obj := ReportChapterPermissionMapping{}
+	err = global.MYSQL["rddp"].Table(obj.TableName()+" AS a ").
+		Joins("INNER JOIN report_chapter AS b ON a.report_chapter_id = b.report_chapter_id").
+		Select("a.*,b.type_id").
+		Where(" b.report_id = ? ", reportId).
+		Scan(&items).Error
+
+	return
+}
+
+// GetReportChapterListByReportId
+// @Description: 根据报告ID获取所有章节id
+// @author: Roc
+// @datetime 2024-06-24 11:02:23
+// @param reportId int
+// @return reportChapterIdList []int
+// @return err error
+func GetReportChapterListByReportId(reportId int) (reportChapterIdList []int, err error) {
+	var items []*ReportChapterPermissionMapping
+	obj := ReportChapterPermissionMapping{}
+	err = global.MYSQL["rddp"].Table(obj.TableName()+" AS a ").
+		Joins("INNER JOIN report_chapter AS b ON a.report_chapter_id = b.report_chapter_id").
+		Select("DISTINCT report_chapter_id ").
+		Where(" b.report_id = ? ", reportId).
+		Scan(&items).Error
+	if err != nil {
+		return
+	}
+	for _, v := range items {
+		reportChapterIdList = append(reportChapterIdList, v.ReportChapterID)
+	}
+
+	return
+}

+ 31 - 0
models/tables/report_chapter_permission_mapping/report_chapter_permission_mapping.go

@@ -0,0 +1,31 @@
+package report_chapter_permission_mapping
+
+import (
+	"time"
+)
+
+// ReportChapterPermissionMapping 报告章节的权限关系表
+type ReportChapterPermissionMapping struct {
+	ReportChapterPermissionMappingID int       `gorm:"primaryKey;column:report_chapter_permission_mapping_id" json:"report_chapter_permission_mapping_id"`
+	ReportChapterID                  int       `gorm:"column:report_chapter_id" json:"report_chapter_id"`     // 报告章节的id
+	ChartPermissionID                int       `gorm:"column:chart_permission_id" json:"chart_permission_id"` // 权限id
+	CreateTime                       time.Time `gorm:"column:create_time" json:"create_time"`
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *ReportChapterPermissionMapping) TableName() string {
+	return "report_chapter_permission_mapping"
+}
+
+// ReportChapterPermissionMappingColumns get sql column name.获取数据库列名
+var ReportChapterPermissionMappingColumns = struct {
+	ReportChapterPermissionMappingID string
+	ReportChapterID                  string
+	ChartPermissionID                string
+	CreateTime                       string
+}{
+	ReportChapterPermissionMappingID: "report_chapter_permission_mapping_id",
+	ReportChapterID:                  "report_chapter_id",
+	ChartPermissionID:                "chart_permission_id",
+	CreateTime:                       "create_time",
+}

+ 13 - 0
models/tables/user_record/query.go

@@ -31,3 +31,16 @@ func GetFirstByUnionID(unionID string) (item *UserRecord, err error) {
 	err = global.DEFAULT_MYSQL.Where("union_id = ? and user_id>0", unionID).Order("create_platform asc").First(&item).Error
 	return
 }
+
+// GetRepeatBindAccount 获取重复的绑定账号
+func GetRepeatBindAccount(account, unionId string) (items []*UserRecord, err error) {
+	err = global.DEFAULT_MYSQL.Model(UserRecord{}).Where("bind_account = ? AND union_id <> ? AND create_platform IN (3,6)", account, unionId).Find(&items).Error
+	return
+}
+
+// ClearRepeatBindAccount 清除重复的绑定账号
+func ClearRepeatBindAccount(account, unionId string) (err error) {
+	sql := ` UPDATE user_record SET bind_account = '', user_id = 0 WHERE bind_account = ? AND union_id <> ? AND create_platform IN (3,6)`
+	err = global.DEFAULT_MYSQL.Exec(sql, account, unionId).Error
+	return
+}

+ 40 - 15
models/tables/yb_comment/query.go

@@ -5,12 +5,18 @@ import (
 	"hongze/hongze_yb/utils"
 )
 
-
 // GetListByUserIdReportId 获取用户的留言列表
 func GetListByUserIdReportId(userId uint64, reportId, reportChapterId int) (list []*YbComment, err error) {
-	err = global.DEFAULT_MYSQL.Model(YbComment{}).
-		Where("user_id = ? and report_id = ? and report_chapter_id = ? and enabled = 1 ", userId, reportId, reportChapterId).
-		Order("create_time desc, comment_id desc").
+	//err = global.DEFAULT_MYSQL.Model(YbComment{}).
+	//	Where("user_id = ? and report_id = ? and report_chapter_id = ? and enabled = 1 ", userId, reportId, reportChapterId).
+	//	Order("create_time desc, comment_id desc").
+	//	Scan(&list).Error
+	tmp := global.DEFAULT_MYSQL.Model(YbComment{}).
+		Where("user_id = ? and report_id = ? and enabled = 1 ", userId, reportId)
+	if reportChapterId > 0 {
+		tmp = tmp.Where("report_chapter_id = ?", reportChapterId)
+	}
+	err = tmp.Order("create_time desc, comment_id desc").
 		Scan(&list).Error
 	if err == utils.ErrNoRow {
 		err = nil
@@ -32,20 +38,39 @@ func GetListByUserIdOldReportId(userId uint64, oldReportId, oldReportChapterId i
 
 // GetHotListByReportId 获取报告的精选留言列表
 func GetHotListByReportId(reportId, reportChapterId int, offset, limit int) (list []*YbComment, err error) {
-	err = global.DEFAULT_MYSQL.Model(YbComment{}).
-		Where("report_id = ? and report_chapter_id = ? and enabled = 1 and is_hot = 1 and type = 1", reportId, reportChapterId).
-		Order("is_top desc, hot_top_time desc, comment_id desc").
+	//err = global.DEFAULT_MYSQL.Model(YbComment{}).
+	//	Where("report_id = ? and report_chapter_id = ? and enabled = 1 and is_hot = 1 and type = 1", reportId, reportChapterId).
+	//	Order("is_top desc, hot_top_time desc, comment_id desc").
+	//	Offset(offset).
+	//	Limit(limit).
+	//	Scan(&list).Error
+
+	tmp := global.DEFAULT_MYSQL.Model(YbComment{}).
+		Where("report_id = ? and enabled = 1 and is_hot = 1 and type = 1", reportId)
+
+	// 如果有填写章节id,那么就查询章节id
+	if reportChapterId > 0 {
+		tmp = tmp.Where("report_chapter_id = ? ", reportChapterId)
+	}
+
+	err = tmp.Order("is_top desc, hot_top_time desc, comment_id desc").
 		Offset(offset).
 		Limit(limit).
 		Scan(&list).Error
+
 	return
 }
 
 // GetHotListTotalByReportId 获取精选留言总条数
-func GetHotListTotalByReportId(reportId, reportChapterId int)(total int64, err error)  {
-	err = global.DEFAULT_MYSQL.Model(YbComment{}).
-		Where("report_id = ? and report_chapter_id = ? and enabled = 1 and is_hot = 1 and type = 1", reportId, reportChapterId).
-		Count(&total).Error
+func GetHotListTotalByReportId(reportId, reportChapterId int) (total int64, err error) {
+	tmp := global.DEFAULT_MYSQL.Model(YbComment{}).
+		Where("report_id = ? and enabled = 1 and is_hot = 1 and type = 1", reportId)
+	// 如果有填写章节id,那么就查询章节id
+	if reportChapterId > 0 {
+		tmp = tmp.Where(" report_chapter_id = ? ", reportChapterId)
+	}
+	err = tmp.Count(&total).Error
+
 	return
 }
 
@@ -61,7 +86,7 @@ func GetHotListByOldReportId(oldReportId, oldReportChapterId int, offset, limit
 }
 
 // GetHotListTotalByOldReportId 获取老报告的精选留言总条数
-func GetHotListTotalByOldReportId(oldReportId, oldReportChapterId int)(total int64, err error)  {
+func GetHotListTotalByOldReportId(oldReportId, oldReportChapterId int) (total int64, err error) {
 	err = global.DEFAULT_MYSQL.Model(YbComment{}).
 		Where("old_report_id = ? and old_report_chapter_id = ? and enabled = 1 and is_hot = 1 and type = 1", oldReportId, oldReportChapterId).
 		Count(&total).Error
@@ -78,7 +103,7 @@ func GetReplyListByReplyCommentId(replyCommentIds []uint64) (list []*YbComment,
 }
 
 // GetSimpleByCommentId 根据留言ID,查询留言
-func GetSimpleByCommentId(commentId uint64)(item *YbComment, err error)  {
+func GetSimpleByCommentId(commentId uint64) (item *YbComment, err error) {
 	err = global.DEFAULT_MYSQL.Model(YbComment{}).
 		Select("comment_id, user_id, type, enabled").
 		Where("comment_id = ?", commentId).First(&item).Error
@@ -89,9 +114,9 @@ func GetSimpleByCommentId(commentId uint64)(item *YbComment, err error)  {
 }
 
 // GetMyLatestComment 获取用户最新的留言
-func GetMyLatestComment(userId uint64) (item *YbComment, err error){
+func GetMyLatestComment(userId uint64) (item *YbComment, err error) {
 	err = global.DEFAULT_MYSQL.Model(YbComment{}).
 		Select("comment_id, user_id, type, enabled, is_show_name").
 		Where("user_id = ? and type=1", userId).Order("comment_id desc").First(&item).Error
 	return
-}
+}

+ 432 - 234
services/chart/future_good/chart_info.go

@@ -15,47 +15,51 @@ import (
 	"hongze/hongze_yb/utils"
 	"sort"
 	"strconv"
+	"strings"
 	"time"
 )
 
 // GetChartEdbData 获取图表的指标数据
-func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping, futureGoodEdbInfoMapping *chartEdbMappingModel.ChartEdbInfoMappingList, barChartInfoDateList []request.BarChartInfoDateReq) (barConfigEdbInfoIdList []request.BarChartInfoEdbItemReq, edbList []*chartEdbMappingModel.ChartEdbInfoMappingList, xEdbIdValue []int, xDataList []chart_info.XData, yDataList []chart_info.YData, sourceArr []string, err error) {
+func GetChartEdbData(chartInfoId int, startDate, endDate string, baseEdbInfoMapping *chartEdbMappingModel.ChartEdbInfoMapping, edbInfoMappingList []*chartEdbMappingModel.ChartEdbInfoMappingList, futureGoodEdbInfoMapping *chartEdbMappingModel.ChartEdbInfoMappingList, barChartInfoConf request.FutureGoodBarChartInfoReq, needData bool) (barConfigEdbInfoIdList []request.BarChartInfoEdbItemReq, edbList []*chartEdbMappingModel.ChartEdbInfoMappingList, xEdbIdValue []int, xDataList []request.XData, yDataList []chart_info.YData, sourceArr []string, err error) {
 	edbList = make([]*chartEdbMappingModel.ChartEdbInfoMappingList, 0)
-
-	sourceArr = make([]string, 0)
+	barChartInfoDateList := barChartInfoConf.DateList
 	if futureGoodEdbInfoMapping == nil {
 		err = errors.New("商品指标未选取")
 		return
 	}
-	if edbInfoMapping == nil {
+	if len(edbInfoMappingList) == 0 {
 		err = errors.New("ETA指标未选取")
 		return
 	}
+
 	// 指标对应的所有数据
 	edbDataListMap := make(map[int][]*edbDataModel.EdbDataList)
 
-	item := new(chartEdbMappingModel.ChartEdbInfoMappingList)
-	edbInfoMapping.FrequencyEn = chart.GetFrequencyEn(edbInfoMapping.Frequency)
+	// todo item
+	//item := new(chartEdbMappingModel.ChartEdbInfoMappingList)
 
-	if edbInfoMapping.Unit == `无` {
-		edbInfoMapping.Unit = ``
-	}
 	if futureGoodEdbInfoMapping.Unit == `无` {
 		futureGoodEdbInfoMapping.Unit = ``
 	}
 
 	if chartInfoId <= 0 {
-		edbInfoMapping.IsAxis = 1
-		edbInfoMapping.LeadValue = 0
-		edbInfoMapping.LeadUnit = ""
-		edbInfoMapping.ChartEdbMappingId = 0
-		edbInfoMapping.ChartInfoId = 0
-		edbInfoMapping.IsOrder = false
-		edbInfoMapping.EdbInfoType = 1
-		edbInfoMapping.ChartStyle = ""
-		edbInfoMapping.ChartColor = ""
-		edbInfoMapping.ChartWidth = 0
-
+		for k, edbInfoMapping := range edbInfoMappingList {
+			edbInfoMapping.FrequencyEn = chart.GetFrequencyEn(edbInfoMapping.Frequency)
+			if edbInfoMapping.Unit == `无` {
+				edbInfoMapping.Unit = ``
+			}
+			edbInfoMapping.IsAxis = 1
+			edbInfoMapping.LeadValue = 0
+			edbInfoMapping.LeadUnit = ""
+			edbInfoMapping.ChartEdbMappingId = 0
+			edbInfoMapping.ChartInfoId = 0
+			edbInfoMapping.IsOrder = false
+			edbInfoMapping.EdbInfoType = 1
+			edbInfoMapping.ChartStyle = ""
+			edbInfoMapping.ChartColor = ""
+			edbInfoMapping.ChartWidth = 0
+			edbInfoMappingList[k] = edbInfoMapping
+		}
 		futureGoodEdbInfoMapping.IsAxis = 1
 		futureGoodEdbInfoMapping.LeadValue = 0
 		futureGoodEdbInfoMapping.LeadUnit = ""
@@ -67,37 +71,48 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 		futureGoodEdbInfoMapping.ChartColor = ""
 		futureGoodEdbInfoMapping.ChartWidth = 0
 	} else {
-		edbInfoMapping.LeadUnitEn = chart.GetLeadUnitEn(edbInfoMapping.LeadUnit)
+		for k, edbInfoMapping := range edbInfoMappingList {
+			edbInfoMapping.FrequencyEn = chart.GetFrequencyEn(edbInfoMapping.Frequency)
+			if edbInfoMapping.Unit == `无` {
+				edbInfoMapping.Unit = ``
+			}
+			edbInfoMapping.LeadUnitEn = chart.GetLeadUnitEn(edbInfoMapping.LeadUnit)
+			edbInfoMappingList[k] = edbInfoMapping
+		}
 		futureGoodEdbInfoMapping.LeadUnitEn = chart.GetLeadUnitEn(futureGoodEdbInfoMapping.LeadUnit)
 	}
 
+	//查询横轴配置项
+	xDataItemMap := make(map[int]request.XData)
+	for k, v := range barChartInfoConf.XDataList {
+		xDataItemMap[k] = v
+	}
+
 	// 普通的指标数据
 	{
-		dataList := make([]*edbDataModel.EdbDataList, 0)
-
-		dataList, err = edbDataModel.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.SubSource, edbInfoMapping.EdbInfoId, startDate, endDate)
-		edbDataListMap[edbInfoMapping.EdbInfoId] = dataList
-		item.DataList = dataList
-
-		edbList = append(edbList, edbInfoMapping)
-
-		barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, request.BarChartInfoEdbItemReq{
-			EdbInfoId: edbInfoMapping.EdbInfoId,
-			//Name:      edbInfoMapping.EdbName,
-			Name:   "现货价",
-			NameEn: "Spot Price",
-			Source: edbInfoMapping.Source,
-		})
-
-		if !utils.InArray(edbInfoMapping.Source, utils.SystemSourceList) { //来源于系统的指标,都展示为弘则研究
-			if !utils.InArray(edbInfoMapping.SourceName, sourceArr) {
-				sourceArr = append(sourceArr, edbInfoMapping.SourceName)
+		edbList = edbInfoMappingList
+
+		for k, edbInfoMapping := range edbInfoMappingList {
+			tmp := request.BarChartInfoEdbItemReq{
+				EdbInfoId: edbInfoMapping.EdbInfoId,
+				Name:      edbInfoMapping.EdbName,
+				NameEn:    edbInfoMapping.EdbNameEn,
+				Source:    edbInfoMapping.Source,
+			}
+			// 如果有配置,则用配置中的指标名称替换
+			xItem, ok := xDataItemMap[k]
+			if ok && xItem.Name != "" {
+				tmp.Name = xItem.Name
+				tmp.NameEn = xItem.NameEn
+				tmp.IsHide = xItem.IsHide
 			}
+			barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, tmp)
 		}
 	}
 
 	// 获取主力合约和最新日期
 	var zlFutureGoodEdbInfo *future_good_edb_info.FutureGoodEdbInfo
+
 	var latestDate string // 最新日期是这个
 	var regionType string // 交易所来源:“国内”,“海外”
 	var futureGoodEdbType int
@@ -108,11 +123,11 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 			return
 		}
 		regionType = zlFutureGoodEdbInfo.RegionType
-		futureGoodEdbType = int(zlFutureGoodEdbInfo.FutureGoodEdbType)
+		futureGoodEdbType = zlFutureGoodEdbInfo.FutureGoodEdbType
 
 		// 如果当前合约配置的 "画图时,日期来源的指标id" 并不是自己的话,那么就去查找对应配置的合约
-		if uint64(zlFutureGoodEdbInfo.DateSourceID) != zlFutureGoodEdbInfo.FutureGoodEdbInfoID {
-			sourceDateFutureGoodEdbInfo, tmpErr := future_good_edb_info.GetFutureGoodEdbInfo(int(zlFutureGoodEdbInfo.DateSourceID))
+		if zlFutureGoodEdbInfo.DateSourceID != zlFutureGoodEdbInfo.FutureGoodEdbInfoID {
+			sourceDateFutureGoodEdbInfo, tmpErr := future_good_edb_info.GetFutureGoodEdbInfo(zlFutureGoodEdbInfo.DateSourceID)
 			if tmpErr != nil {
 				err = tmpErr
 				return
@@ -141,70 +156,168 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 
 	futureGoodMappingList := make([]*chartEdbMappingModel.ChartEdbInfoMappingList, 0)
 	for k, v := range futureGoodEdbInfoList {
+		tmp1 := chartEdbMappingModel.ChartEdbInfoMapping{
+			EdbInfoId:           v.FutureGoodEdbInfoID,
+			SourceName:          v.Exchange,
+			Source:              0,
+			EdbCode:             v.FutureGoodEdbCode,
+			EdbName:             v.FutureGoodEdbName,
+			EdbAliasName:        v.FutureGoodEdbName,
+			EdbNameEn:           v.FutureGoodEdbNameEn,
+			EdbType:             baseEdbInfoMapping.EdbType, //todo baseEdbInfoMapping
+			Frequency:           baseEdbInfoMapping.Frequency,
+			FrequencyEn:         baseEdbInfoMapping.FrequencyEn,
+			Unit:                baseEdbInfoMapping.Unit,
+			UnitEn:              baseEdbInfoMapping.UnitEn,
+			StartDate:           v.StartDate.Format(utils.FormatDate),
+			EndDate:             v.EndDate.Format(utils.FormatDate),
+			ModifyTime:          v.ModifyTime.Format(utils.FormatDateTime),
+			ChartEdbMappingId:   v.FutureGoodEdbInfoID,
+			ChartInfoId:         baseEdbInfoMapping.ChartInfoId,
+			MaxData:             v.MaxValue,
+			MinData:             v.MinValue,
+			IsOrder:             baseEdbInfoMapping.IsOrder,
+			IsAxis:              baseEdbInfoMapping.IsAxis,
+			EdbInfoType:         baseEdbInfoMapping.EdbInfoType,
+			EdbInfoCategoryType: baseEdbInfoMapping.EdbInfoCategoryType,
+			LeadValue:           baseEdbInfoMapping.LeadValue,
+			LeadUnit:            baseEdbInfoMapping.LeadUnit,
+			LeadUnitEn:          baseEdbInfoMapping.LeadUnitEn,
+			ChartStyle:          baseEdbInfoMapping.ChartStyle,
+			ChartColor:          baseEdbInfoMapping.ChartColor,
+			PredictChartColor:   baseEdbInfoMapping.PredictChartColor,
+			ChartWidth:          baseEdbInfoMapping.ChartWidth,
+			ChartType:           baseEdbInfoMapping.ChartType,
+			LatestDate:          v.LatestDate,
+			LatestValue:         v.LatestValue,
+			UniqueCode:          futureGoodEdbInfoMapping.UniqueCode + strconv.Itoa(k),
+			MinValue:            v.MinValue,
+			MaxValue:            v.MaxValue,
+		}
 		newMappingInfo := &chartEdbMappingModel.ChartEdbInfoMappingList{
-			ChartEdbInfoMapping: chartEdbMappingModel.ChartEdbInfoMapping{
-				EdbInfoId:           int(v.FutureGoodEdbInfoID),
-				SourceName:          v.Exchange,
-				Source:              utils.CHART_SOURCE_FUTURE_GOOD,
-				EdbCode:             v.FutureGoodEdbCode,
-				EdbName:             v.FutureGoodEdbName,
-				EdbAliasName:        v.FutureGoodEdbName,
-				EdbNameEn:           v.FutureGoodEdbNameEn,
-				EdbType:             edbInfoMapping.EdbType,
-				Frequency:           edbInfoMapping.Frequency,
-				FrequencyEn:         edbInfoMapping.FrequencyEn,
-				Unit:                edbInfoMapping.Unit,
-				UnitEn:              edbInfoMapping.UnitEn,
-				StartDate:           v.StartDate.Format(utils.FormatDateTime),
-				EndDate:             v.EndDate.Format(utils.FormatDateTime),
-				ModifyTime:          v.ModifyTime.Format(utils.FormatDateTime),
-				ChartEdbMappingId:   int(v.FutureGoodEdbInfoID),
-				ChartInfoId:         edbInfoMapping.ChartInfoId,
-				MaxData:             v.MaxValue,
-				MinData:             v.MinValue,
-				IsOrder:             edbInfoMapping.IsOrder,
-				IsAxis:              edbInfoMapping.IsAxis,
-				EdbInfoType:         edbInfoMapping.EdbInfoType,
-				EdbInfoCategoryType: edbInfoMapping.EdbInfoCategoryType,
-				LeadValue:           edbInfoMapping.LeadValue,
-				LeadUnit:            edbInfoMapping.LeadUnit,
-				LeadUnitEn:          edbInfoMapping.LeadUnitEn,
-				ChartStyle:          edbInfoMapping.ChartStyle,
-				ChartColor:          edbInfoMapping.ChartColor,
-				PredictChartColor:   edbInfoMapping.PredictChartColor,
-				ChartWidth:          edbInfoMapping.ChartWidth,
-				ChartType:           edbInfoMapping.ChartType,
-				LatestDate:          v.LatestDate,
-				LatestValue:         v.LatestValue,
-				UniqueCode:          futureGoodEdbInfoMapping.UniqueCode + "1" + strconv.Itoa(k),
-				MinValue:            v.MinValue,
-				MaxValue:            v.MaxValue,
-			},
-			DataList:   nil,
-			IsNullData: false,
+			ChartEdbInfoMapping: tmp1,
+			DataList:            nil,
+			IsNullData:          false,
 		}
 		futureGoodMappingList = append(futureGoodMappingList, newMappingInfo)
 
-		barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, request.BarChartInfoEdbItemReq{
+		tmp := request.BarChartInfoEdbItemReq{
 			EdbInfoId: newMappingInfo.EdbInfoId,
 			Name:      fmt.Sprint("M+", v.Month),
 			NameEn:    fmt.Sprint("M+", v.Month),
 			Source:    newMappingInfo.Source,
-		})
+		}
+		// 判断如果有配置,需要替换为配置内容
+		xItem, ok := xDataItemMap[k]
+		if ok && xItem.Name != "" {
+			tmp.Name = xItem.Name
+			tmp.NameEn = xItem.NameEn
+			tmp.IsHide = xItem.IsHide
+		}
+		barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, tmp)
+
+	}
+
+	if regionType == `海外` {
+		zlTmp := chartEdbMappingModel.ChartEdbInfoMapping{
+			EdbInfoId:           zlFutureGoodEdbInfo.FutureGoodEdbInfoID,
+			SourceName:          zlFutureGoodEdbInfo.Exchange,
+			Source:              0,
+			EdbCode:             zlFutureGoodEdbInfo.FutureGoodEdbCode,
+			EdbName:             zlFutureGoodEdbInfo.FutureGoodEdbName,
+			EdbAliasName:        zlFutureGoodEdbInfo.FutureGoodEdbName,
+			EdbNameEn:           zlFutureGoodEdbInfo.FutureGoodEdbNameEn,
+			EdbType:             baseEdbInfoMapping.EdbType,
+			Frequency:           baseEdbInfoMapping.Frequency,
+			FrequencyEn:         baseEdbInfoMapping.FrequencyEn,
+			Unit:                baseEdbInfoMapping.Unit,
+			UnitEn:              baseEdbInfoMapping.UnitEn,
+			StartDate:           zlFutureGoodEdbInfo.StartDate.Format(utils.FormatDate),
+			EndDate:             zlFutureGoodEdbInfo.EndDate.Format(utils.FormatDate),
+			ModifyTime:          zlFutureGoodEdbInfo.ModifyTime.Format(utils.FormatDateTime),
+			ChartEdbMappingId:   zlFutureGoodEdbInfo.FutureGoodEdbInfoID,
+			ChartInfoId:         baseEdbInfoMapping.ChartInfoId,
+			MaxData:             zlFutureGoodEdbInfo.MaxValue,
+			MinData:             zlFutureGoodEdbInfo.MinValue,
+			IsOrder:             baseEdbInfoMapping.IsOrder,
+			IsAxis:              baseEdbInfoMapping.IsAxis,
+			EdbInfoType:         baseEdbInfoMapping.EdbInfoType,
+			EdbInfoCategoryType: baseEdbInfoMapping.EdbInfoCategoryType,
+			LeadValue:           baseEdbInfoMapping.LeadValue,
+			LeadUnit:            baseEdbInfoMapping.LeadUnit,
+			LeadUnitEn:          baseEdbInfoMapping.LeadUnitEn,
+			ChartStyle:          baseEdbInfoMapping.ChartStyle,
+			ChartColor:          baseEdbInfoMapping.ChartColor,
+			PredictChartColor:   baseEdbInfoMapping.PredictChartColor,
+			ChartWidth:          baseEdbInfoMapping.ChartWidth,
+			ChartType:           baseEdbInfoMapping.ChartType,
+			LatestDate:          zlFutureGoodEdbInfo.LatestDate,
+			LatestValue:         zlFutureGoodEdbInfo.LatestValue,
+			UniqueCode:          futureGoodEdbInfoMapping.UniqueCode + strconv.Itoa(0),
+			MinValue:            zlFutureGoodEdbInfo.MinValue,
+			MaxValue:            zlFutureGoodEdbInfo.MaxValue,
+		}
+		zlFutureGoodEdbMapping := &chartEdbMappingModel.ChartEdbInfoMappingList{
+			ChartEdbInfoMapping: zlTmp,
+			DataList:            nil,
+			IsNullData:          false,
+		}
+		edbList = append(edbList, zlFutureGoodEdbMapping)
+		edbList = append(edbList, futureGoodMappingList...)
+	} else {
+		edbList = append(edbList, futureGoodMappingList...)
+	}
+
+	if !needData {
+		return
 	}
 
 	// 获取数据
-	for _, v := range futureGoodMappingList {
+
+	// 现货数据
+	for _, edbInfoMapping := range edbInfoMappingList {
 		dataList := make([]*edbDataModel.EdbDataList, 0)
+		dataList, err = edbDataModel.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.SubSource, edbInfoMapping.EdbInfoId, startDate, endDate)
+		if err != nil {
+			return
+		}
+		edbDataListMap[edbInfoMapping.EdbInfoId] = dataList
+		// todo item
+		//item.DataList = dataList
+	}
 
-		tmpDataList, tmpErr := future_good_edb_data.GetFutureGoodEdbDataListByDate(v.EdbInfoId, startDate, endDate)
+	futureEdbInfoIds := make([]int, 0)
+	for _, v := range futureGoodMappingList {
+		futureEdbInfoIds = append(futureEdbInfoIds, v.EdbInfoId)
+	}
+	tmpDataListMap := make(map[int][]*future_good_edb_data.FutureGoodEdbData)
+	if len(futureEdbInfoIds) > 0 {
+		// 期货数据
+		tmpDataList, tmpErr := future_good_edb_data.GetFutureGoodEdbDataListByIdsAndDate(futureEdbInfoIds, startDate, endDate)
 		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		for _, v := range tmpDataList {
+			if _, ok := tmpDataListMap[v.FutureGoodEdbInfoID]; !ok {
+				tmpDataListMap[v.FutureGoodEdbInfoID] = make([]*future_good_edb_data.FutureGoodEdbData, 0)
+			}
+			tmpDataListMap[v.FutureGoodEdbInfoID] = append(tmpDataListMap[v.FutureGoodEdbInfoID], v)
+		}
+	}
+	// 期货数据
+	for _, v := range futureGoodMappingList {
+		dataList := make([]*edbDataModel.EdbDataList, 0)
+		tmpDataList, ok := tmpDataListMap[v.EdbInfoId]
+		if !ok {
+			err = fmt.Errorf("期货数据不存在 FutureGoodEdbInfoId: %d", v.EdbInfoId)
 			return
 		}
 		for _, tmpData := range tmpDataList {
 			dataList = append(dataList, &edbDataModel.EdbDataList{
-				EdbDataId:     int(tmpData.FutureGoodEdbDataID),
-				EdbInfoId:     int(tmpData.FutureGoodEdbInfoID),
+				EdbDataId:     tmpData.FutureGoodEdbDataID,
+				EdbInfoId:     tmpData.FutureGoodEdbInfoID,
 				DataTime:      tmpData.DataTime.Format(utils.FormatDate),
 				DataTimestamp: tmpData.DataTimestamp,
 				Value:         tmpData.Close,
@@ -214,16 +327,25 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 		v.DataList = dataList
 	}
 
-	edbList = append(edbList, futureGoodMappingList...)
+	// 特殊处理日期
+	// 因为时间格式是:2023-07-19T00:00:00+08:00;所以需要分开
+	baseEndDateTime := strings.Split(baseEdbInfoMapping.EndDate, "T")
+	baseEndDate := baseEndDateTime[0]
 
-	xEdbIdValue, yDataList, err = BarChartData(edbList[0], futureGoodEdbInfoList, edbDataListMap, barChartInfoDateList, regionType, edbInfoMapping.EndDate)
+	xEdbIdValue, yDataList, err = BarChartData(baseEdbInfoMapping, edbInfoMappingList, futureGoodEdbInfoList, edbDataListMap, barChartInfoDateList, regionType, baseEndDate)
 
-	xDataList = []chart_info.XData{
-		{
-			Name:   "现货价",
-			NameEn: "Spot Price",
-		},
+	if len(barChartInfoConf.XDataList) > 0 {
+		xDataList = barChartInfoConf.XDataList
+	} else {
+		for _, v := range edbInfoMappingList {
+			xDataList = append(xDataList, request.XData{
+				Name:   v.EdbName,
+				NameEn: v.EdbNameEn,
+				IsHide: 0,
+			})
+		}
 	}
+
 	//yDataList =make([]chart_info.YData,0)
 	//chart_info.YData{
 	//	Date:           "",
@@ -236,7 +358,7 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 	//}
 	futureGoodEdbInfoIndexMap := make(map[int]int)
 	for index, v := range futureGoodEdbInfoList {
-		futureGoodEdbInfoIndexMap[int(v.FutureGoodEdbInfoID)] = index
+		futureGoodEdbInfoIndexMap[v.FutureGoodEdbInfoID] = index
 	}
 	nMap := make(map[int]int)
 	maxIndex := 0 // 最大x轴的下标
@@ -253,19 +375,20 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 		}
 
 		// 基础指标
-		{
-			baseEdbInfId := edbList[0].EdbInfoId
-			edbInfoIdList = append(edbInfoIdList, baseEdbInfId)
-			tmpVal, ok := yDataMap[baseEdbInfId]
+		baseEdbIds := make([]int, 0)
+		for _, tmp := range edbInfoMappingList {
+			edbInfoIdList = append(edbInfoIdList, tmp.EdbInfoId)
+			baseEdbIds = append(baseEdbIds, tmp.EdbInfoId)
+			tmpVal, ok := yDataMap[tmp.EdbInfoId]
 			valueList = append(valueList, tmpVal)
 			if !ok || tmpVal == 0 {
-				noDataEdbInfoIdList = append(noDataEdbInfoIdList, baseEdbInfId)
-				noDataEdbIdMap[baseEdbInfId] = baseEdbInfId
+				noDataEdbInfoIdList = append(noDataEdbInfoIdList, tmp.EdbInfoId)
+				noDataEdbIdMap[tmp.EdbInfoId] = tmp.EdbInfoId
 			}
 		}
 
 		for _, futureGoodEdbInfo := range futureGoodEdbInfoList {
-			tmpEdbInfId := int(futureGoodEdbInfo.FutureGoodEdbInfoID)
+			tmpEdbInfId := futureGoodEdbInfo.FutureGoodEdbInfoID
 			edbInfoIdList = append(edbInfoIdList, tmpEdbInfId)
 			tmpVal, ok := yDataMap[tmpEdbInfId]
 			valueList = append(valueList, tmpVal)
@@ -283,7 +406,7 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 
 		for i := lenEdbId - 1; i >= 0; i-- {
 			// 如果没有在无数据的指标列表中找到,那么就找到了最大x轴的下标
-			if _, ok := noDataEdbIdMap[edbInfoIdList[i]]; !ok {
+			if _, ok := noDataEdbIdMap[edbInfoIdList[i]]; !ok || utils.InArrayByInt(baseEdbIds, edbInfoIdList[i]) {
 				// 如果最大x轴的下标 小于 当前下标,那么就重新赋值
 				if maxIndex < i-1 {
 					maxIndex = i - 1
@@ -319,34 +442,60 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 			yDataList[k].Value = v.Value[0 : maxIndex+1]
 		}
 	}
-
-	tmpXDataList, newYDataList, err := handleResultData(regionType, futureGoodEdbType, yDataList, futureGoodEdbInfoList, maxIndex)
+	baseEdbLen := len(edbInfoMappingList)
+	tmpXDataList, newYDataList, err := handleResultData(regionType, futureGoodEdbType, baseEdbLen, yDataList, futureGoodEdbInfoList, maxIndex)
 	if err != nil {
 		return
 	}
-	xDataList = append(xDataList, tmpXDataList...)
+	if len(barChartInfoConf.XDataList) == 0 {
+		xDataList = append(xDataList, tmpXDataList...)
+	}
+
 	yDataList = newYDataList
 
 	return
 }
 
 // BarChartData 获取数据
-func BarChartData(edbInfoMapping *chartEdbMappingModel.ChartEdbInfoMappingList, futureGoodMappingList []*future_good_edb_info.FutureGoodEdbInfo, edbDataListMap map[int][]*edbDataModel.EdbDataList, barChartInfoDateList []request.BarChartInfoDateReq, regionType, latestDate string) (edbIdList []int, yDataList []chart_info.YData, err error) {
+func BarChartData(baseEdbInfoMapping *chartEdbMappingModel.ChartEdbInfoMapping, edbInfoMappingList []*chartEdbMappingModel.ChartEdbInfoMappingList, futureGoodMappingList []*future_good_edb_info.FutureGoodEdbInfo, edbDataListMap map[int][]*edbDataModel.EdbDataList, barChartInfoDateList []request.BarChartInfoDateReq, regionType, latestDate string) (edbIdList []int, yDataList []chart_info.YData, err error) {
 	// 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
-	edbDataMap := make(map[int]map[string]float64)
+	// 现货指标数据map
+	baseEdbDataMap := make(map[int]map[string]float64)
+	edbInfoMappingMap := make(map[int]struct{})
+	for _, v := range edbInfoMappingList {
+		edbInfoMappingMap[v.EdbInfoId] = struct{}{}
+	}
 	for edbInfoId, edbDataList := range edbDataListMap {
+		if _, ok1 := edbInfoMappingMap[edbInfoId]; ok1 {
+			edbDateData := make(map[string]float64)
+			for _, edbData := range edbDataList {
+				edbDateData[edbData.DataTime] = edbData.Value
+			}
+			baseEdbDataMap[edbInfoId] = edbDateData
+		}
+	}
+
+	// 期货指标数据map
+	futureGoodEdbDataMap := make(map[int]map[string]float64)
+	for edbInfoId, edbDataList := range edbDataListMap {
+		if _, ok := edbInfoMappingMap[edbInfoId]; ok {
+			continue
+		}
 		edbDateData := make(map[string]float64)
 		for _, edbData := range edbDataList {
 			edbDateData[edbData.DataTime] = edbData.Value
 		}
-		edbDataMap[edbInfoId] = edbDateData
+		futureGoodEdbDataMap[edbInfoId] = edbDateData
 	}
 
 	// edbIdList 指标展示顺序;x轴的指标顺序
 	edbIdList = make([]int, 0)
-	edbIdList = append(edbIdList, edbInfoMapping.EdbInfoId)
+	for _, v := range edbInfoMappingList {
+		edbIdList = append(edbIdList, v.EdbInfoId)
+	}
+
 	for _, v := range futureGoodMappingList {
-		edbIdList = append(edbIdList, int(v.FutureGoodEdbInfoID))
+		edbIdList = append(edbIdList, v.FutureGoodEdbInfoID)
 	}
 
 	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
@@ -385,23 +534,43 @@ func BarChartData(edbInfoMapping *chartEdbMappingModel.ChartEdbInfoMappingList,
 		noDataIdMap := make(map[int]int, 0) // 没有数据的指标map
 		xEdbInfoIdList := make([]int, 0)    // 当前数据的指标id列表
 
-		// 现货指标
-		realDateTime, findDataValue, isFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[edbInfoMapping.EdbInfoId], edbDataMap[edbInfoMapping.EdbInfoId])
+		// 先找到基准日期
+		var realDateTime time.Time
+		realDateTime, findDataValue, isFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[baseEdbInfoMapping.EdbInfoId], baseEdbDataMap[baseEdbInfoMapping.EdbInfoId], futureGoodEdbDataMap)
 		if tmpErr != nil {
 			err = tmpErr
 			return
 		}
-		findDataList = append(findDataList, findDataValue)
-		yDataMap[edbInfoMapping.EdbInfoId] = findDataValue
-		if isFind {
-			maxDate = realDateTime
-		} else {
-			noDataIdList = append(noDataIdList, edbInfoMapping.EdbInfoId)
-			noDataIdMap[edbInfoMapping.EdbInfoId] = edbInfoMapping.EdbInfoId
+		// 处理其余现货指标
+		for _, v := range edbInfoMappingList {
+			if v.EdbInfoId == baseEdbInfoMapping.EdbInfoId {
+				findDataList = append(findDataList, findDataValue)
+				yDataMap[baseEdbInfoMapping.EdbInfoId] = findDataValue
+				if isFind {
+					maxDate = realDateTime
+				} else {
+					noDataIdList = append(noDataIdList, baseEdbInfoMapping.EdbInfoId)
+					noDataIdMap[baseEdbInfoMapping.EdbInfoId] = baseEdbInfoMapping.EdbInfoId
+				}
+				xEdbInfoIdList = append(xEdbInfoIdList, v.EdbInfoId)
+				continue
+			}
+			findDataValueTmp, isFindTmp := baseEdbDataMap[v.EdbInfoId][realDateTime.Format(utils.FormatDate)]
+			findDataList = append(findDataList, findDataValueTmp)
+			yDataMap[v.EdbInfoId] = findDataValueTmp
+			if !isFindTmp {
+				noDataIdList = append(noDataIdList, v.EdbInfoId)
+				noDataIdMap[v.EdbInfoId] = v.EdbInfoId
+			}
+			xEdbInfoIdList = append(xEdbInfoIdList, v.EdbInfoId)
 		}
-		currMonth := findDateTime.Month() // 当前月份
-		currYear := findDateTime.Year()   // 当前年份
-		xEdbInfoIdList = append(xEdbInfoIdList, edbInfoMapping.EdbInfoId)
+		//currMonth := findDateTime.Month() // 当前月份
+		//currYear := findDateTime.Year()   // 当前年份
+
+		// 用实际日期的月份作为基准,往前推12个月(2024-5-13 16:26:43修改)
+		currMonth := realDateTime.Month() // 当前月份
+		currYear := realDateTime.Year()   // 当前年份
+
 		mList := make([]int, 0) // 间隔月份
 		indexList := make([]int, 0)
 		if regionType == `国内` {
@@ -420,11 +589,11 @@ func BarChartData(edbInfoMapping *chartEdbMappingModel.ChartEdbInfoMappingList,
 						continue
 					}
 					indexList = append(indexList, i)
-					mList = append(mList, int(v.Month))
+					mList = append(mList, v.Month)
 				} else {
-					if v.Year > currYear || (v.Year == currYear && int(v.Month) > int(currMonth)) {
+					if v.Year > currYear || (v.Year == currYear && v.Month > int(currMonth)) {
 						indexList = append(indexList, i)
-						mList = append(mList, (v.Year-currYear)*12+int(v.Month)-int(currMonth))
+						mList = append(mList, (v.Year-currYear)*12+v.Month-int(currMonth))
 					}
 				}
 			}
@@ -432,15 +601,15 @@ func BarChartData(edbInfoMapping *chartEdbMappingModel.ChartEdbInfoMappingList,
 
 		for _, i := range indexList {
 			futureGoodMapping := futureGoodMappingList[i] // 当前的期货指标
-			//tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.FutureGoodEdbInfoId], edbDataMap[futureGoodMapping.FutureGoodEdbInfoId])
+			//tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.FutureGoodEdbInfoID], edbDataMap[futureGoodMapping.FutureGoodEdbInfoID])
 			//if tmpErr != nil {
 			//	err = tmpErr
 			//	return
 			//}
 			//tmpRealDateTime := findDateTime	// 按照配置找到的日期
 			tmpRealDateTime := realDateTime // 实际现货的日期
-			tmpFindDataValue, tmpIsFind := edbDataMap[int(futureGoodMapping.FutureGoodEdbInfoID)][tmpRealDateTime.Format(utils.FormatDate)]
-			yDataMap[int(futureGoodMapping.FutureGoodEdbInfoID)] = tmpFindDataValue
+			tmpFindDataValue, tmpIsFind := futureGoodEdbDataMap[futureGoodMapping.FutureGoodEdbInfoID][tmpRealDateTime.Format(utils.FormatDate)]
+			yDataMap[futureGoodMapping.FutureGoodEdbInfoID] = tmpFindDataValue
 
 			findDataList = append(findDataList, tmpFindDataValue)
 			if tmpIsFind {
@@ -448,11 +617,11 @@ func BarChartData(edbInfoMapping *chartEdbMappingModel.ChartEdbInfoMappingList,
 					maxDate = tmpRealDateTime
 				}
 			} else {
-				noDataIdList = append(noDataIdList, int(futureGoodMapping.FutureGoodEdbInfoID))
-				noDataIdMap[int(futureGoodMapping.FutureGoodEdbInfoID)] = int(futureGoodMapping.FutureGoodEdbInfoID)
+				noDataIdList = append(noDataIdList, futureGoodMapping.FutureGoodEdbInfoID)
+				noDataIdMap[futureGoodMapping.FutureGoodEdbInfoID] = futureGoodMapping.FutureGoodEdbInfoID
 			}
 			// 当前期货合约的指标
-			xEdbInfoIdList = append(xEdbInfoIdList, int(futureGoodMapping.FutureGoodEdbInfoID))
+			xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.FutureGoodEdbInfoID)
 		}
 
 		yName := barChartInfoDate.Name
@@ -520,86 +689,9 @@ func BarChartData(edbInfoMapping *chartEdbMappingModel.ChartEdbInfoMappingList,
 	return
 }
 
-// GetNeedDateData 获取合约内需要的日期数据
-func GetNeedDateData(needDateTime time.Time, dataList []*edbDataModel.EdbDataList, edbDataMap map[string]float64) (findDateTime time.Time, findDataValue float64, isFind bool, err error) {
-	//dataList := edbDataListMap[edbInfoId] //指标的所有数据值
-	if len(dataList) <= 0 {
-		// 没有数据的指标id
-		return
-	}
-
-	//最早的日期
-	minDateTime, err := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
-	if err != nil {
-		return
-	}
-
-	for tmpDateTime := needDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
-		tmpDate := tmpDateTime.Format(utils.FormatDate)
-		if tmpValue, ok := edbDataMap[tmpDate]; ok { //如果能找到数据,那么就返回
-			// 数据为0,也直接返回,做无值处理
-			if tmpValue == 0 {
-				return
-			}
-			findDateTime, _ = time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
-			findDataValue = tmpValue
-			isFind = true
-			return
-		}
-	}
-
-	return
-}
-
-// FutureGoodChartInfoRefresh
-// @author Roc
-// @datetime 2023-2-2 18:44:46
-// @description 商品价格曲线图表刷新
-func FutureGoodChartInfoRefresh(chartInfoId int) (err error) {
-	var errMsg string
-	defer func() {
-		if err != nil {
-			go alarm_msg.SendAlarmMsg("ChartInfoRefresh:"+errMsg, 3)
-			fmt.Println("ChartInfoRefresh Err:" + errMsg)
-		}
-	}()
-
-	edbInfoMapping, err := chartEdbMappingModel.GetEtaEdbChartEdbMapping(chartInfoId)
-	if err != nil {
-		errMsg = "获取需要刷新的ETA指标失败:Err:" + err.Error()
-		return
-	}
-	// 获取期货指标
-	futureGoodEdbInfoMapping, err := chartEdbMappingModel.GetFutureGoodEdbChartEdbMapping(chartInfoId)
-	if err != nil {
-		errMsg = "获取需要刷新的商品期货指标失败:Err:" + err.Error()
-		return
-	}
-
-	// 获取期货指标以及期货数据
-	futureGoodEdbInfoList, err := future_good_edb_info.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
-	if err != nil {
-		return
-	}
-
-	// 批量刷新ETA指标
-	err, _ = chart.EdbInfoRefreshAllFromBase([]int{edbInfoMapping.EdbInfoId}, false)
-	if err != nil {
-		return
-	}
-
-	// 批量刷新期货指标
-	err = FutureGoodEdbInfoRefreshAllFromBase(futureGoodEdbInfoList, false)
-	if err != nil {
-		return
-	}
-
-	return
-}
-
 // handleResultData 处理成最终的结果数据
-func handleResultData(regionType string, futureGoodEdbType int, yDataList []chart_info.YData, futureGoodEdbInfoList []*future_good_edb_info.FutureGoodEdbInfo, maxIndex int) (xDataList []chart_info.XData, newYDataList []chart_info.YData, err error) {
-	xDataList = make([]chart_info.XData, 0)
+func handleResultData(regionType string, futureGoodEdbType, baseEdbLen int, yDataList []chart_info.YData, futureGoodEdbInfoList []*future_good_edb_info.FutureGoodEdbInfo, maxIndex int) (xDataList []request.XData, newYDataList []chart_info.YData, err error) {
+	xDataList = make([]request.XData, 0)
 	newYDataList = yDataList
 
 	if regionType == `国内` {
@@ -607,7 +699,8 @@ func handleResultData(regionType string, futureGoodEdbType int, yDataList []char
 			if i > maxIndex {
 				break
 			}
-			xDataList = append(xDataList, chart_info.XData{
+			// todo x轴 内容调整
+			xDataList = append(xDataList, request.XData{
 				Name:   fmt.Sprint("M+", i),
 				NameEn: fmt.Sprint("M+", i),
 			})
@@ -617,13 +710,13 @@ func handleResultData(regionType string, futureGoodEdbType int, yDataList []char
 
 	futureGoodEdbInfoMap := make(map[int]*future_good_edb_info.FutureGoodEdbInfo)
 	for _, v := range futureGoodEdbInfoList {
-		futureGoodEdbInfoMap[int(v.FutureGoodEdbInfoID)] = v
+		futureGoodEdbInfoMap[v.FutureGoodEdbInfoID] = v
 	}
 
 	if futureGoodEdbType == 2 { // 	FutureGoodEdbType   int       `description:"指标类型,1:年月是固定的合约;2:只有M+N期的合约,未固定年月"`
 		nList := []int{3, 15, 27}
 		for _, i := range nList {
-			xDataList = append(xDataList, chart_info.XData{
+			xDataList = append(xDataList, request.XData{
 				Name:   fmt.Sprint("M+", i),
 				NameEn: fmt.Sprint("M+", i),
 			})
@@ -635,11 +728,11 @@ func handleResultData(regionType string, futureGoodEdbType int, yDataList []char
 			tmpNList := nList
 
 			//当前的主力合约
-			newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, yData.XEdbInfoIdList[0])
-			newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[0])
+			newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, yData.XEdbInfoIdList[0:baseEdbLen]...)
+			newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[0:baseEdbLen]...)
 
-			xEdbInfoIdList := yData.XEdbInfoIdList[1:]
-			valIndex := 1
+			xEdbInfoIdList := yData.XEdbInfoIdList[baseEdbLen:]
+			valIndex := baseEdbLen
 			needNum := 0
 			for _, n := range tmpNList {
 				if len(xEdbInfoIdList) > 0 {
@@ -650,7 +743,7 @@ func handleResultData(regionType string, futureGoodEdbType int, yDataList []char
 						return
 					}
 					// 当前距离最早的日期相差的N数
-					if int(futureGoodEdbInfo.Month) == n {
+					if futureGoodEdbInfo.Month == n {
 						if needNum > 0 {
 							currVal := yData.Value[valIndex]
 							preVal := yData.Value[valIndex-1]
@@ -712,7 +805,7 @@ func handleResultData(regionType string, futureGoodEdbType int, yDataList []char
 		//v.XEdbInfoIdList
 		for edbInfoIndex, edbInfoId := range v.XEdbInfoIdList {
 			// 第一个不处理
-			if edbInfoIndex == 0 {
+			if edbInfoIndex <= baseEdbLen-1 {
 				continue
 			}
 
@@ -721,7 +814,7 @@ func handleResultData(regionType string, futureGoodEdbType int, yDataList []char
 				err = errors.New("找不到指标")
 				return
 			}
-			n := (futureGoodEdbInfo.Year-currYear)*12 + int(futureGoodEdbInfo.Month) - int(currMonth)
+			n := (futureGoodEdbInfo.Year-currYear)*12 + futureGoodEdbInfo.Month - int(currMonth)
 			nMap[n] = n
 		}
 
@@ -739,7 +832,7 @@ func handleResultData(regionType string, futureGoodEdbType int, yDataList []char
 	//prevMonth := 1
 
 	for _, n := range nList {
-		xDataList = append(xDataList, chart_info.XData{
+		xDataList = append(xDataList, request.XData{
 			Name:   fmt.Sprint("M+", n),
 			NameEn: fmt.Sprint("M+", n),
 		})
@@ -751,12 +844,12 @@ func handleResultData(regionType string, futureGoodEdbType int, yDataList []char
 		tmpNList := nList
 
 		//当前的主力合约
-		newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, yData.XEdbInfoIdList[0])
-		newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[0])
+		newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, yData.XEdbInfoIdList[0:baseEdbLen]...)
+		newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[0:baseEdbLen]...)
 
-		xEdbInfoIdList := yData.XEdbInfoIdList[1:]
+		xEdbInfoIdList := yData.XEdbInfoIdList[baseEdbLen:]
 		currDataTime := yData.ConfigDate
-		valIndex := 1
+		valIndex := baseEdbLen
 		needNum := 0
 		for _, n := range tmpNList {
 			if len(xEdbInfoIdList) > 0 {
@@ -767,7 +860,7 @@ func handleResultData(regionType string, futureGoodEdbType int, yDataList []char
 					return
 				}
 				// 当前距离最早的日期相差的N数
-				divMonth := (futureGoodEdbInfo.Year-currDataTime.Year())*12 + (int(futureGoodEdbInfo.Month) - int(currDataTime.Month()))
+				divMonth := (futureGoodEdbInfo.Year-currDataTime.Year())*12 + (futureGoodEdbInfo.Month - int(currDataTime.Month()))
 				if divMonth == n {
 					if needNum > 0 {
 						currVal := yData.Value[valIndex]
@@ -818,7 +911,6 @@ func handleResultData(regionType string, futureGoodEdbType int, yDataList []char
 			newYDataList[yIndex].Value = yData.Value[0 : maxI+1]
 		}
 	}
-
 	return
 }
 
@@ -862,14 +954,14 @@ func getFutureGoodEdbInfoList(latestDateTime time.Time, tmpFutureGoodEdbInfoList
 		}
 		//海外的连续日期,目前
 		if v.FutureGoodEdbType == 2 {
-			if int(v.Month) <= maxM {
-				//addMonth := int(earliestDateTime.Month()) + int(v.Month)
+			if v.Month <= maxM {
+				//addMonth := int(earliestDateTime.Month()) + v.Month
 				//v.Year = earliestDateTime.Year() + addMonth/12
 				//realMonth := addMonth % 12
 				//if realMonth == 0 {
 				//	realMonth = 12
 				//}
-				//v.Month = uint32(realMonth)
+				//v.Month = realMonth
 				futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
 			}
 			continue
@@ -884,7 +976,7 @@ func getFutureGoodEdbInfoList(latestDateTime time.Time, tmpFutureGoodEdbInfoList
 			continue
 		}
 		// 如果(当前年-最新日期的年份) * 12个月 + (当前月-最新日期的月份) 小于总月份
-		if (v.Year-earliestDateTime.Year())*12+(int(v.Month)-int(earliestDateTime.Month())) <= maxM {
+		if (v.Year-earliestDateTime.Year())*12+(v.Month-int(earliestDateTime.Month())) <= maxM {
 			futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
 			continue
 		}
@@ -893,3 +985,109 @@ func getFutureGoodEdbInfoList(latestDateTime time.Time, tmpFutureGoodEdbInfoList
 
 	return
 }
+
+// GetNeedDateData 获取合约内需要的日期数据
+func GetNeedDateData(needDateTime time.Time, dataList []*edbDataModel.EdbDataList, edbDataMap map[string]float64, allEdbDataMap map[int]map[string]float64) (findDateTime time.Time, findDataValue float64, isFind bool, err error) {
+	//dataList := edbDataListMap[edbInfoId] //指标的所有数据值
+	if len(dataList) <= 0 {
+		// 没有数据的指标id
+		return
+	}
+
+	//最早的日期
+	minDateTime, err := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
+	if err != nil {
+		return
+	}
+
+	// 该日期存在数据的期货指标的最小数量,目前是现货和期货各1个,总共2个
+	maxCount := 1
+
+	for tmpDateTime := needDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
+		tmpDate := tmpDateTime.Format(utils.FormatDate)
+		tmpValue, ok := edbDataMap[tmpDate]
+		if !ok {
+			continue
+		}
+
+		// 该日期存在数据的指标数量
+		count := 0
+
+		for _, currEdbDataMap := range allEdbDataMap {
+			_, tmpIsFind := currEdbDataMap[tmpDate]
+			if tmpIsFind {
+				count++
+				if count >= maxCount {
+					continue
+				}
+			}
+		}
+
+		// 该日期存在数据的期货指标数量小于2个,那么要继续往前找
+		if count < maxCount {
+			continue
+		}
+
+		//如果能找到数据,那么就返回
+		// 数据为0,也直接返回,做无值处理
+		if tmpValue == 0 {
+			return
+		}
+		findDateTime, _ = time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
+		findDataValue = tmpValue
+		isFind = true
+		return
+	}
+
+	return
+}
+
+// FutureGoodChartInfoRefresh
+// @author Roc
+// @datetime 2023-2-2 18:44:46
+// @description 商品价格曲线图表刷新
+func FutureGoodChartInfoRefresh(chartInfoId int) (err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			go alarm_msg.SendAlarmMsg("ChartInfoRefresh:"+errMsg, 3)
+			fmt.Println("ChartInfoRefresh Err:" + errMsg)
+		}
+	}()
+
+	edbInfoMappingList, err := chartEdbMappingModel.GetEtaEdbChartEdbMappingList(chartInfoId)
+	if err != nil {
+		errMsg = "获取需要刷新的ETA指标失败:Err:" + err.Error()
+		return
+	}
+	edbInfoIds := make([]int, 0)
+	for _, edbInfoMapping := range edbInfoMappingList {
+		edbInfoIds = append(edbInfoIds, edbInfoMapping.EdbInfoId)
+	}
+	// 获取期货指标
+	futureGoodEdbInfoMapping, err := chartEdbMappingModel.GetFutureGoodEdbChartEdbMapping(chartInfoId)
+	if err != nil {
+		errMsg = "获取需要刷新的商品期货指标失败:Err:" + err.Error()
+		return
+	}
+
+	// 获取期货指标以及期货数据
+	futureGoodEdbInfoList, err := future_good_edb_info.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
+	if err != nil {
+		return
+	}
+
+	// 批量刷新ETA指标
+	err, _ = chart.EdbInfoRefreshAllFromBase(edbInfoIds, false)
+	if err != nil {
+		return
+	}
+
+	// 批量刷新期货指标
+	err = FutureGoodEdbInfoRefreshAllFromBase(futureGoodEdbInfoList, false)
+	if err != nil {
+		return
+	}
+
+	return
+}

+ 1 - 1
services/community/video.go

@@ -4,8 +4,8 @@ import (
 	"errors"
 	response2 "hongze/hongze_yb/controller/response"
 	"hongze/hongze_yb/models/response"
-	"hongze/hongze_yb/models/tables/chart_permission"
 	"hongze/hongze_yb/models/tables/company_product"
+	"hongze/hongze_yb/models/tables/rddp/chart_permission"
 	"hongze/hongze_yb/models/tables/yb_community_question_comment"
 	"hongze/hongze_yb/models/tables/yb_community_question_like_tease"
 	"hongze/hongze_yb/models/tables/yb_community_video"

+ 90 - 88
services/company/permission.go

@@ -7,11 +7,11 @@ import (
 	"hongze/hongze_yb/global"
 	"hongze/hongze_yb/models/response"
 	"hongze/hongze_yb/models/tables/admin"
-	"hongze/hongze_yb/models/tables/chart_permission"
 	"hongze/hongze_yb/models/tables/company"
 	"hongze/hongze_yb/models/tables/company_product"
 	"hongze/hongze_yb/models/tables/company_report_permission"
 	"hongze/hongze_yb/models/tables/company_user_chart_classify_permission"
+	chart_permission2 "hongze/hongze_yb/models/tables/rddp/chart_permission"
 	"hongze/hongze_yb/models/tables/wx_user"
 	"hongze/hongze_yb/models/tables/yb_apply_record"
 	"hongze/hongze_yb/services/user"
@@ -28,14 +28,14 @@ var (
 )
 
 // GetClassNameListByProductId 根据权限id获取权限分类
-func GetClassNameListByProductId(productId int64) (list []*chart_permission.ChartPermission, err error) {
-	list, err = chart_permission.GetClassNameListByProductId(productId)
+func GetClassNameListByProductId(productId int64) (list []*chart_permission2.ChartPermission, err error) {
+	list, err = chart_permission2.GetClassNameListByProductId(productId)
 	return
 }
 
 // GetPermissionListByProductId 根据product_id获取所有的权限列表
-func GetPermissionListByProductId(productId int64) (list []*chart_permission.ChartPermission, err error) {
-	list, err = chart_permission.GetListByProductId(productId)
+func GetPermissionListByProductId(productId int64) (list []*chart_permission2.ChartPermission, err error) {
+	list, err = chart_permission2.GetListByProductId(productId)
 	return
 }
 
@@ -330,98 +330,100 @@ func GetCheckPermission(companyId int64, userId int, permissionIdList []int) (ok
 			permissionMap[permissionId] = true
 		}
 	}
+	// 潜在客户名下的
+	if companyId <= 1 {
+		permissionCheckInfo.Type = CheckTypeApply
+		return
+	}
 
 	var productId int64
 	productId = 1
-	if companyId > 1 {
-		//查询是否 开通ficc的客户
-		companyProductInfo, tmpErr := company_product.GetByCompany2ProductId(companyId, productId)
-		if tmpErr != nil {
-			// 没有开通ficc的客户
-			if tmpErr == utils.ErrNoRow {
-				permissionCheckInfo.Type = CheckTypeApply
-				return
-			}
-			err = tmpErr
-			return
-		}
-
-		wxUser, tmpErr := wx_user.GetByUserId(userId)
-		if tmpErr != nil {
+	//查询是否 开通ficc的客户
+	companyProductInfo, tmpErr := company_product.GetByCompany2ProductId(companyId, productId)
+	if tmpErr != nil {
+		// 没有开通ficc的客户
+		if tmpErr == utils.ErrNoRow {
 			permissionCheckInfo.Type = CheckTypeApply
-			err = tmpErr
 			return
 		}
+		err = tmpErr
+		return
+	}
 
-		//客户信息
-		companyInfo, tmpErr := companyCache.GetByCompanyId(companyId)
-		if tmpErr != nil {
-			// 没有开通ficc的客户
-			if tmpErr == utils.ErrNoRow {
-				permissionCheckInfo.Type = CheckTypeApply
-				return
-			}
-			err = tmpErr
-			return
-		}
-		customerInfo := response.CustomerInfo{
-			CompanyName: companyInfo.CompanyName,
-			Status:      companyProductInfo.Status,
-			Name:        wxUser.RealName,
-			IsSuspend:   companyProductInfo.IsSuspend,
-			Mobile:      wxUser.Mobile,
-		}
-		permissionCheckInfo.CustomerInfo = customerInfo
+	wxUser, tmpErr := wx_user.GetByUserId(userId)
+	if tmpErr != nil {
+		permissionCheckInfo.Type = CheckTypeApply
+		err = tmpErr
+		return
+	}
 
-		// 如果客户ficc产品的状态是流失,那么也是让去申请
-		if companyProductInfo.Status == "流失" || companyProductInfo.Status == "关闭" {
+	//客户信息
+	companyInfo, tmpErr := companyCache.GetByCompanyId(companyId)
+	if tmpErr != nil {
+		// 没有开通ficc的客户
+		if tmpErr == utils.ErrNoRow {
 			permissionCheckInfo.Type = CheckTypeApply
 			return
 		}
+		err = tmpErr
+		return
+	}
+	customerInfo := response.CustomerInfo{
+		CompanyName: companyInfo.CompanyName,
+		Status:      companyProductInfo.Status,
+		Name:        wxUser.RealName,
+		IsSuspend:   companyProductInfo.IsSuspend,
+		Mobile:      wxUser.Mobile,
+	}
+	permissionCheckInfo.CustomerInfo = customerInfo
 
-		//查找对应客户的销售信息
-		adminInfo, tmpErr := admin.GetByAdminId(companyProductInfo.SellerID)
-		if tmpErr != nil {
-			//if tmpErr ==
-			err = tmpErr
-			return
-		}
+	// 如果客户ficc产品的状态是流失,那么也是让去申请
+	if companyProductInfo.Status == "流失" || companyProductInfo.Status == "关闭" {
+		permissionCheckInfo.Type = CheckTypeApply
+		return
+	}
 
-		permissionCheckInfo.Name = adminInfo.RealName
-		permissionCheckInfo.Mobile = adminInfo.Mobile
-		if companyProductInfo.Status == "冻结" {
-			permissionCheckInfo.Type = CheckTypeContact
-			return
-		}
+	//查找对应客户的销售信息
+	adminInfo, tmpErr := admin.GetByAdminId(companyProductInfo.SellerID)
+	if tmpErr != nil {
+		//if tmpErr ==
+		err = tmpErr
+		return
+	}
 
-		//客户状态是:试用暂停状态(联系销售)
-		if companyProductInfo.Status == "试用" && companyProductInfo.IsSuspend == 1 {
-			permissionCheckInfo.Type = CheckTypeContact
-			return
-		}
+	permissionCheckInfo.Name = adminInfo.RealName
+	permissionCheckInfo.Mobile = adminInfo.Mobile
+	if companyProductInfo.Status == "冻结" {
+		permissionCheckInfo.Type = CheckTypeContact
+		return
+	}
 
-		// 获取有效的权限id列表
-		validPermissionIdList, tmpErr := GetValidPermissionIdListByCompany2ProductId(companyId, productId)
-		if tmpErr != nil {
-			err = tmpErr
-			return
-		}
-		// 校验在有效的权限id列表中是否存在该权限
-		if len(permissionIdList) > 0 {
-			for _, validPermissionId := range validPermissionIdList {
-				//如果有该权限id,那么直接返回校验通过
-				if _, validOk := permissionMap[validPermissionId]; validOk {
-					finalValidPermissionIds = append(finalValidPermissionIds, validPermissionId)
-					ok = true
-				}
+	//客户状态是:试用暂停状态(联系销售)
+	if companyProductInfo.Status == "试用" && companyProductInfo.IsSuspend == 1 {
+		permissionCheckInfo.Type = CheckTypeContact
+		return
+	}
+
+	// 获取有效的权限id列表
+	validPermissionIdList, tmpErr := GetValidPermissionIdListByCompany2ProductId(companyId, productId)
+	if tmpErr != nil {
+		err = tmpErr
+		return
+	}
+	// 校验在有效的权限id列表中是否存在该权限
+	if len(permissionIdList) > 0 {
+		for _, validPermissionId := range validPermissionIdList {
+			//如果有该权限id,那么直接返回校验通过
+			if _, validOk := permissionMap[validPermissionId]; validOk {
+				finalValidPermissionIds = append(finalValidPermissionIds, validPermissionId)
+				ok = true
 			}
-			return
 		}
-
-		permissionCheckInfo.Type = CheckTypeContact
-	} else {
-		permissionCheckInfo.Type = CheckTypeApply
+		return
 	}
+
+	permissionCheckInfo.Type = CheckTypeContact
+
 	return
 }
 
@@ -627,12 +629,12 @@ type PermissionItem struct {
 func GetFiccPermissionList() (list []*FiccPermissionList, err error) {
 	productId := 1
 	list = make([]*FiccPermissionList, 0)
-	allFiccPermissions, e := chart_permission.GetListByProductIdAndPermissionType(productId)
+	allFiccPermissions, e := chart_permission2.GetListByProductIdAndPermissionType(productId)
 	if e != nil {
 		err = errors.New("获取品种权限失败 Err:" + e.Error())
 		return
 	}
-	permissionMap := make(map[int][]*chart_permission.ChartPermission, 0)
+	permissionMap := make(map[int][]*chart_permission2.ChartPermission, 0)
 	for _, v := range allFiccPermissions {
 		if v.ParentId > 0 {
 			permissionMap[v.ParentId] = append(permissionMap[v.ParentId], v)
@@ -673,7 +675,7 @@ func GetHomeFiccPermissions(user user.UserInfo) (ret response.PermissionFiccResp
 	for _, item := range validPermissionList {
 		validPermissionIds = append(validPermissionIds, item.ChartPermissionID)
 	}
-	permissionList, err := chart_permission.GetFiccListExceptTacticByProductId()
+	permissionList, err := chart_permission2.GetFiccListExceptTacticByProductId()
 	if err != nil {
 		return
 	}
@@ -681,7 +683,7 @@ func GetHomeFiccPermissions(user user.UserInfo) (ret response.PermissionFiccResp
 	permissionFirstMap := make(map[int]*response.PermissionFirstItem)
 
 	//查询首页展示的图标
-	permissionFirstList, err := chart_permission.GetFiccFirstListExceptTacticByProductId()
+	permissionFirstList, err := chart_permission2.GetFiccFirstListExceptTacticByProductId()
 	if err != nil {
 		return
 	}
@@ -744,8 +746,8 @@ func GetHomeFiccPermissions(user user.UserInfo) (ret response.PermissionFiccResp
 		if len(v.List) > 0 {
 			temp.List = v.List
 			sort.Sort(temp.List)
+			list = append(list, temp)
 		}
-		list = append(list, temp)
 	}
 
 	if len(list) > 0 {
@@ -961,7 +963,7 @@ func GetBindFiccPermissions(user user.UserInfo) (ret response.BindPermissionFicc
 	for _, item := range validPermissionList {
 		validPermissionIds = append(validPermissionIds, item.ChartPermissionID)
 	}
-	permissionList, err := chart_permission.GetFiccListExceptTacticByProductId()
+	permissionList, err := chart_permission2.GetFiccListExceptTacticByProductId()
 	if err != nil {
 		return
 	}
@@ -969,7 +971,7 @@ func GetBindFiccPermissions(user user.UserInfo) (ret response.BindPermissionFicc
 	permissionFirstMap := make(map[int]*response.BindPermissionFiccItem)
 
 	//查询首页展示的图标
-	permissionFirstList, err := chart_permission.GetFiccFirstListExceptTacticByProductId()
+	permissionFirstList, err := chart_permission2.GetFiccFirstListExceptTacticByProductId()
 	if err != nil {
 		return
 	}
@@ -1054,7 +1056,7 @@ func GetCommoditiesBindFiccPermissions(user user.UserInfo) (ret response.BindPer
 	for _, item := range validPermissionList {
 		validPermissionIds = append(validPermissionIds, item.ChartPermissionID)
 	}
-	permissionList, err := chart_permission.GetFiccListExceptTacticByProductId()
+	permissionList, err := chart_permission2.GetFiccListExceptTacticByProductId()
 	if err != nil {
 		return
 	}
@@ -1062,7 +1064,7 @@ func GetCommoditiesBindFiccPermissions(user user.UserInfo) (ret response.BindPer
 	permissionFirstMap := make(map[int]*response.BindPermissionFiccItem)
 
 	//查询首页展示的图标
-	permissionFirstList, err := chart_permission.GetFiccFirstListExceptTacticByProductId()
+	permissionFirstList, err := chart_permission2.GetFiccFirstListExceptTacticByProductId()
 	if err != nil {
 		return
 	}

+ 35 - 40
services/elastic/report.go

@@ -11,9 +11,9 @@ import (
 )
 
 // 首页搜索
-func SearchReport(keyWord string, classifyIdFirsts []int, classifyIdSeconds []int, pageIndex, pageSize int) (searchResp *elastic.SearchResult, total int64, err error) {
-	indexName := global.CONFIG.EsClient.Prefix+utils.ES_INDEX_RDDP_REPORT
-	var must  []map[string]interface{}
+func SearchReport(keyWord string, classifyIdList []int, pageIndex, pageSize int) (searchResp *elastic.SearchResult, total int64, err error) {
+	indexName := global.CONFIG.EsClient.Prefix + utils.ES_INDEX_RDDP_REPORT
+	var must []map[string]interface{}
 
 	shouldSub := []map[string]interface{}{
 		/*map[string]interface{}{
@@ -78,17 +78,12 @@ func SearchReport(keyWord string, classifyIdFirsts []int, classifyIdSeconds []in
 	filterMust := []map[string]interface{}{
 		map[string]interface{}{
 			"term": map[string]interface{}{
-				"PublishState": 2,                     //必须是已发布的报告
+				"PublishState": 2, //必须是已发布的报告
 			},
 		},
 		map[string]interface{}{
 			"terms": map[string]interface{}{
-				"ClassifyIdFirst":classifyIdFirsts,     //分类必须是正常显示状态
-			},
-		},
-		map[string]interface{}{
-			"terms": map[string]interface{}{
-				"ClassifyIdSecond":classifyIdSeconds,     //分类必须是正常显示状态
+				"ClassifyId": classifyIdList, //分类必须是正常显示状态
 			},
 		},
 	}
@@ -96,21 +91,21 @@ func SearchReport(keyWord string, classifyIdFirsts []int, classifyIdSeconds []in
 		map[string]interface{}{
 			"term": map[string]interface{}{
 				"BodyContent.keyword": map[string]interface{}{
-					"value": "",                     //过滤没有内容的报告(晨报和周报)bodyContent 不能为空
+					"value": "", //过滤没有内容的报告(晨报和周报)bodyContent 不能为空
 				},
 			},
 		},
 	}
 	filterMap := map[string]interface{}{
 		"bool": map[string]interface{}{
-			"must": filterMust,
+			"must":     filterMust,
 			"must_not": filterMustNot,
 		},
 	}
 	source := map[string]interface{}{
 		"query": map[string]interface{}{
 			"bool": map[string]interface{}{
-				"must": must,
+				"must":   must,
 				"filter": filterMap,
 			},
 		},
@@ -119,31 +114,31 @@ func SearchReport(keyWord string, classifyIdFirsts []int, classifyIdSeconds []in
 	source["size"] = pageSize
 	source["highlight"] = map[string]interface{}{
 		"fields": map[string]interface{}{
-			"Title":map[string]interface{}{},
-			"Categories":map[string]interface{}{},
-			"BodyContent":map[string]interface{}{
-			//	"pre_tags" : "{{highlight}}",
-			//	"post_tags": "{{/highlight}}",
+			"Title":       map[string]interface{}{},
+			"Categories":  map[string]interface{}{},
+			"BodyContent": map[string]interface{}{
+				//	"pre_tags" : "{{highlight}}",
+				//	"post_tags": "{{/highlight}}",
 			},
 		},
-		"pre_tags" : "<span style=\"color:#E3B377\">",
+		"pre_tags":  "<span style=\"color:#E3B377\">",
 		"post_tags": "</span>",
 	}
 
 	source["sort"] = []map[string]interface{}{
 		map[string]interface{}{
-			"PublishTime.keyword":map[string]interface{}{
-				"order":"desc",
+			"PublishTime.keyword": map[string]interface{}{
+				"order": "desc",
 			},
 		},
 		map[string]interface{}{
-			"_score":map[string]interface{}{
-				"order":"desc",
+			"_score": map[string]interface{}{
+				"order": "desc",
 			},
 		},
 	}
 	jsonstr, err := json.Marshal(source)
-	fmt.Printf("%s",jsonstr)
+	fmt.Printf("%s", jsonstr)
 	request := global.EsClient.Search(indexName).Source(source) // sets the JSON request
 
 	searchResp, err = request.Do(context.Background())
@@ -164,8 +159,8 @@ func SearchReport(keyWord string, classifyIdFirsts []int, classifyIdSeconds []in
 
 // ReportListSearch 报告列表页的搜索
 func ReportListSearch(keyWord string, classifyIdFirst int, classifyIdSeconds []int, pageIndex, pageSize int) (searchResp *elastic.SearchResult, total int64, err error) {
-	indexName := global.CONFIG.EsClient.Prefix+utils.ES_INDEX_RDDP_REPORT
-	var must  []map[string]interface{}
+	indexName := global.CONFIG.EsClient.Prefix + utils.ES_INDEX_RDDP_REPORT
+	var must []map[string]interface{}
 	shouldSub := []map[string]interface{}{
 		map[string]interface{}{
 			"match": map[string]interface{}{
@@ -233,12 +228,12 @@ func ReportListSearch(keyWord string, classifyIdFirst int, classifyIdSeconds []i
 		},
 		map[string]interface{}{
 			"term": map[string]interface{}{
-				"ReportChapterId":0,     //排除章节内容
+				"ReportChapterId": 0, //排除章节内容
 			},
 		},
 		map[string]interface{}{
 			"term": map[string]interface{}{
-				"ClassifyIdFirst":classifyIdFirst,
+				"ClassifyIdFirst": classifyIdFirst,
 			},
 		},
 		map[string]interface{}{
@@ -250,7 +245,7 @@ func ReportListSearch(keyWord string, classifyIdFirst int, classifyIdSeconds []i
 	source := map[string]interface{}{
 		"query": map[string]interface{}{
 			"bool": map[string]interface{}{
-				"must": must,
+				"must":   must,
 				"filter": filter,
 			},
 		},
@@ -260,29 +255,29 @@ func ReportListSearch(keyWord string, classifyIdFirst int, classifyIdSeconds []i
 	source["size"] = pageSize
 	source["highlight"] = map[string]interface{}{
 		"fields": map[string]interface{}{
-			"Title":map[string]interface{}{},
-			"Abstract":map[string]interface{}{},
-			"StageStr":map[string]interface{}{},
-			"ClassifyNameSecond":map[string]interface{}{},
+			"Title":              map[string]interface{}{},
+			"Abstract":           map[string]interface{}{},
+			"StageStr":           map[string]interface{}{},
+			"ClassifyNameSecond": map[string]interface{}{},
 		},
-		"pre_tags" : "<span style=\"color:#E3B377\">",
+		"pre_tags":  "<span style=\"color:#E3B377\">",
 		"post_tags": "</span>",
 	}
 
 	source["sort"] = []map[string]interface{}{
 		map[string]interface{}{
-			"PublishTime.keyword":map[string]interface{}{
-				"order":"desc",
+			"PublishTime.keyword": map[string]interface{}{
+				"order": "desc",
 			},
 		},
 		map[string]interface{}{
-			"_score":map[string]interface{}{
-				"order":"desc",
+			"_score": map[string]interface{}{
+				"order": "desc",
 			},
 		},
 	}
 	jsonstr, err := json.Marshal(source)
-	fmt.Printf("%s",jsonstr)
+	fmt.Printf("%s", jsonstr)
 	request := global.EsClient.Search(indexName).Source(source) // sets the JSON request
 	searchResp, err = request.Do(context.Background())
 	if err != nil {
@@ -298,4 +293,4 @@ func ReportListSearch(keyWord string, classifyIdFirst int, classifyIdSeconds []i
 	}
 	total = searchResp.TotalHits()
 	return
-}
+}

+ 1 - 1
services/pc/report.go

@@ -5,8 +5,8 @@ import (
 	"fmt"
 	"hongze/hongze_yb/global"
 	"hongze/hongze_yb/models/response/pc"
-	"hongze/hongze_yb/models/tables/chart_permission"
 	"hongze/hongze_yb/models/tables/chart_permission_search_key_word_mapping"
+	"hongze/hongze_yb/models/tables/rddp/chart_permission"
 	"hongze/hongze_yb/models/tables/rddp/classify"
 	"hongze/hongze_yb/models/tables/rddp/customer_comment"
 	"hongze/hongze_yb/models/tables/rddp/report"

+ 275 - 43
services/report/report.go

@@ -8,17 +8,18 @@ import (
 	"hongze/hongze_yb/global"
 	"hongze/hongze_yb/models/response"
 	"hongze/hongze_yb/models/response/purchase"
-	"hongze/hongze_yb/models/tables/chart_permission"
-	"hongze/hongze_yb/models/tables/chart_permission_chapter_mapping"
 	"hongze/hongze_yb/models/tables/chart_permission_search_key_word_mapping"
 	"hongze/hongze_yb/models/tables/company_product"
 	"hongze/hongze_yb/models/tables/daily_base_column"
+	"hongze/hongze_yb/models/tables/rddp/chart_permission"
+	"hongze/hongze_yb/models/tables/rddp/chart_permission_chapter_mapping"
 	"hongze/hongze_yb/models/tables/rddp/classify"
 	"hongze/hongze_yb/models/tables/rddp/classify_menu"
 	"hongze/hongze_yb/models/tables/rddp/report"
 	"hongze/hongze_yb/models/tables/rddp/report_chapter"
 	"hongze/hongze_yb/models/tables/rddp/report_chapter_ticker"
 	"hongze/hongze_yb/models/tables/rddp/report_ppt_img"
+	"hongze/hongze_yb/models/tables/rddp/smart_report_resource"
 	"hongze/hongze_yb/models/tables/report_chapter_type"
 	"hongze/hongze_yb/models/tables/report_chapter_type_permission"
 	"hongze/hongze_yb/models/tables/user_report_chapter_set"
@@ -397,6 +398,9 @@ func GetReportDetail(userinfo user.UserInfo, reportId int) (reportDetail respons
 		err = errors.New("报告未发布")
 		return
 	}
+	// 获取最小分类
+	minClassifyId, _, err := GetMinClassify(reportInfo)
+
 	// 判断报告是否属于专栏报告
 	firstClassify, e := classify.GetByClassifyId(reportInfo.ClassifyIdFirst)
 	if e != nil {
@@ -404,18 +408,34 @@ func GetReportDetail(userinfo user.UserInfo, reportId int) (reportDetail respons
 		return
 	}
 
+	// 最小分类
+	var minClassify *classify.Classify
+	if reportInfo.ClassifyIdFirst == minClassifyId {
+		minClassify = firstClassify
+	} else {
+		minClassify, e = classify.GetByClassifyId(minClassifyId)
+		if e != nil {
+			err = errors.New("报告最小层级分类有误")
+			return
+		}
+	}
+
 	//判断权限
 
 	var authOk bool
 	var permissionCheckInfo response.PermissionCheckInfo
-	var vaildWeekTypeIds []int
-	if reportInfo.ClassifyNameFirst == "晨报" {
-		authOk, permissionCheckInfo, err = CheckDayReportPermission(userinfo, productAuthOk)
-	} else if reportInfo.ClassifyNameFirst == "周报" {
-		authOk, permissionCheckInfo, vaildWeekTypeIds, err = CheckWeekReportPermission(userinfo, productAuthOk)
+	//var vaildWeekTypeIds []int
+	var reportChapterIdList []int
+	if reportInfo.HasChapter == 1 {
+		if reportInfo.ClassifyNameFirst == "晨报" {
+			authOk, permissionCheckInfo, err = CheckDayReportPermission(userinfo, productAuthOk)
+		} else {
+			authOk, permissionCheckInfo, _, reportChapterIdList, err = CheckWeekReportPermission(userinfo, reportId, productAuthOk)
+		}
 	} else {
 		authOk, permissionCheckInfo, err = CheckReportPermission(userinfo, reportId, productAuthOk)
 	}
+
 	if err != nil {
 		return
 	}
@@ -431,6 +451,35 @@ func GetReportDetail(userinfo user.UserInfo, reportId int) (reportDetail respons
 	reportItem.ContentSub = html.UnescapeString(reportInfo.ContentSub)
 	reportItem.Frequency = reportInfo.Frequency
 	reportItem.VideoName = reportInfo.VideoName
+	reportItem.HasChapter = reportInfo.HasChapter
+	reportItem.ReportLayout = reportInfo.ReportLayout
+	reportItem.HeadImg = reportInfo.HeadImg
+	reportItem.EndImg = reportInfo.EndImg
+	reportItem.CanvasColor = reportInfo.CanvasColor
+
+	// 版头版尾样式
+	{
+		if reportInfo.HeadResourceId > 0 {
+			headResource, tmpErr := smart_report_resource.GetResourceItemById(reportInfo.HeadResourceId)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			reportItem.HeadImg = headResource.ImgURL
+			reportItem.HeadStyle = headResource.Style
+		}
+
+		if reportInfo.EndResourceId > 0 {
+			endResource, tmpErr := smart_report_resource.GetResourceItemById(reportInfo.EndResourceId)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			reportItem.EndImg = endResource.ImgURL
+			reportItem.EndStyle = endResource.Style
+		}
+	}
+
 	if reportInfo.VideoName == "" && reportInfo.VideoUrl != "" {
 		reportItem.VideoName = reportInfo.Title
 	}
@@ -453,15 +502,21 @@ func GetReportDetail(userinfo user.UserInfo, reportId int) (reportDetail respons
 	}
 	var reportTypeList []*response.ReportChapterListItem
 
-	if reportInfo.ClassifyNameFirst == "晨报" || reportInfo.ClassifyNameFirst == "周报" {
+	if reportInfo.HasChapter == 1 {
 		//(晨报和周报的banner图)
 		if reportInfo.ClassifyNameFirst == "晨报" {
 			reportItem.BannerUrl = utils.ALIYUN_YBIMG_HOST + "report_banner_day.jpg"
 		} else {
 			reportItem.BannerUrl = utils.ALIYUN_YBIMG_HOST + "report_banner_week.jpg"
 		}
+
+		// 如果还没有配置banner图,则取晨报的
+		if reportItem.BannerUrl == `` {
+			reportItem.BannerUrl = utils.ALIYUN_YBIMG_HOST + "report_banner_day.jpg"
+		}
+
 		if authOk {
-			reportTypeList, err = GetChapterListByReport(reportInfo.ClassifyNameFirst, reportInfo.Id, vaildWeekTypeIds, reportInfo.CreateTime)
+			reportTypeList, err = GetChapterListByReportChapterIdList(reportInfo.ClassifyNameFirst, reportInfo.Id, reportChapterIdList)
 			if err != nil {
 				return
 			}
@@ -560,6 +615,18 @@ func GetReportDetail(userinfo user.UserInfo, reportId int) (reportDetail respons
 	reportDetail.LikeNum = likeNum
 	reportDetail.LikeEnabled = likeEnabled
 	reportDetail.ReportShowType = int(firstClassify.ShowType)
+	reportDetail.ReportDetailShowType = int(minClassify.ReportDetailShowType)
+
+	// 如果分类配置是列表展示,那么就移除content内容
+	if minClassify.ReportDetailShowType == 2 {
+		for _, v := range reportTypeList {
+			v.Content = ``
+		}
+	} else {
+		for _, v := range reportTypeList {
+			v.Content = html.UnescapeString(v.Content)
+		}
+	}
 
 	// 收藏
 	collectionId, e := collection.GetUserCollectByItem(int(userinfo.UserID), collection.CollectionTypeReport, reportId, 0)
@@ -705,7 +772,7 @@ func GetReportList(user user.UserInfo, keyWord string, classifyIdFirst, classify
 		//}
 
 	} else {
-		if classifyParent.ClassifyName == "晨报" || classifyParent.ClassifyName == "周报" {
+		if classifyParent.HasChild == 0 {
 			//reportImgUrl = chartPermissionImageMap[1]
 			classifyIdSeconds = append(classifyIdSeconds, 0)
 		}
@@ -833,6 +900,10 @@ func GetReportList(user user.UserInfo, keyWord string, classifyIdFirst, classify
 				temp.ClassifyNameFirst = reportItem.ClassifyNameFirst
 				temp.ClassifyIdSecond = reportItem.ClassifyIdSecond
 				temp.ClassifyNameSecond = reportItem.ClassifyNameSecond
+				if reportItem.ClassifyIdSecond > 0 && reportItem.ClassifyIdSecond != reportItem.ClassifyId {
+					temp.ClassifyIdThird = reportItem.ClassifyId
+					temp.ClassifyNameThird = reportItem.ClassifyName
+				}
 				if len(v.Highlight["ClassifyNameSecond"]) > 0 {
 					temp.ClassifyNameSecond = v.Highlight["ClassifyNameSecond"][0]
 				}
@@ -879,33 +950,36 @@ func GetReportList(user user.UserInfo, keyWord string, classifyIdFirst, classify
 			err = errors.New("获取报告分类列表失败" + e.Error())
 			return
 		}
-		listImgMap := make(map[int]string, 0)
-		classifyNameMap := make(map[int]string, 0)
+		listImgMap := make(map[int]string)
+		classifyNameMap := make(map[int]string)
+		classifyMap := make(map[int]*classify.Classify)
 		classifyLen := len(classifyList)
 		for i := 0; i < classifyLen; i++ {
 			listImgMap[classifyList[i].Id] = classifyList[i].YbListImg
 			classifyNameMap[classifyList[i].Id] = classifyList[i].ClassifyName
+			classifyMap[classifyList[i].Id] = classifyList[i]
 		}
 
 		var videoReportIds []int
 		videoMap := make(map[int][]*response.VideoListItem)
 		weekAuthMap := make(map[int]bool)
+
+		// 判断周报权限\查询章节报告的音频列表
+		videoMap, weekAuthMap, errMsg, err = GetReportChapterVideoList(validPermissionIdList, classifyParent.ClassifyName, list, user.UserID)
+		if err != nil {
+			return
+		}
+
+		// 如果是晨报,那么就要过滤掉weekAuthMap的授权
 		if classifyParent.ClassifyName == "晨报" && productAuthOk {
-			//获取晨报的音频列表
-			videoMap, _, errMsg, err = GetReportChapterVideoList(validPermissionIdList, classifyParent.ClassifyName, list, user.UserID)
-			if err != nil {
-				return
-			}
-		} else if classifyParent.ClassifyName == "周报" {
+			weekAuthMap = map[int]bool{}
+		} else {
 			//查询所有权限typeID
 			//如果存在可以查看的章节ID
 			for _, reportInfo := range list {
-				videoReportIds = append(videoReportIds, reportInfo.Id)
-			}
-			// 判断周报权限\查询周报的音频列表
-			videoMap, weekAuthMap, errMsg, err = GetReportChapterVideoList(validPermissionIdList, classifyParent.ClassifyName, list, user.UserID)
-			if err != nil {
-				return
+				if reportInfo.HasChapter == 1 {
+					videoReportIds = append(videoReportIds, reportInfo.Id)
+				}
 			}
 		}
 		// 以下分类图标特殊处理 =_=!
@@ -920,6 +994,10 @@ func GetReportList(user user.UserInfo, keyWord string, classifyIdFirst, classify
 		for _, reportInfo := range list {
 			reportItem := new(response.ReportListItem)
 			reportItem.ReportId = reportInfo.Id
+			reportItem.HasChapter = reportInfo.HasChapter
+			reportItem.VideoUrl = reportInfo.VideoUrl
+			reportItem.VideoName = reportInfo.VideoName
+			reportItem.VideoPlaySeconds = reportInfo.VideoPlaySeconds
 			// 样式限制行数
 			reportItem.Title = "<div style=\"-webkit-line-clamp: 2;-webkit-box-orient: vertical;display: -webkit-box;overflow: hidden;text-overflow: ellipsis;\">" + reportInfo.Title + "</div>"
 			reportItem.PublishTime = reportInfo.PublishTime
@@ -929,6 +1007,8 @@ func GetReportList(user user.UserInfo, keyWord string, classifyIdFirst, classify
 			reportItem.ClassifyNameSecond = classifyNameMap[reportInfo.ClassifyIdSecond]
 			reportItem.ClassifyIdFirst = reportInfo.ClassifyIdFirst
 			reportItem.ClassifyIdSecond = reportInfo.ClassifyIdSecond
+			reportItem.ClassifyIdThird = reportInfo.ClassifyIdThird
+			reportItem.ClassifyNameThird = reportInfo.ClassifyNameThird
 			reportItem.Stage = reportInfo.Stage
 			reportItem.Abstract = reportInfo.Abstract
 			if reportInfo.Abstract != "" {
@@ -940,6 +1020,9 @@ func GetReportList(user user.UserInfo, keyWord string, classifyIdFirst, classify
 				stageStr = strconv.Itoa(reportInfo.Stage)
 			}
 			reportItem.TitleInfo = fmt.Sprintf("【第%s期|FICC|%s】", stageStr, reportItem.ClassifyNameSecond)
+			if reportItem.ClassifyNameThird != `` {
+				reportItem.TitleInfo = fmt.Sprintf("%s|%s】", reportItem.TitleInfo, reportItem.ClassifyNameThird)
+			}
 			//trimClassifyNameSecond := utils.TrimHtml(reportInfo.ClassifyNameSecond)
 			if reportItem.ClassifyNameFirst == "晨报" || reportItem.ClassifyNameFirst == "周报" || classifyIdSecond > 0 {
 				//reportItem.ReportImgUrl = utils.ALIYUN_YBIMG_HOST + reportImgUrl
@@ -957,26 +1040,29 @@ func GetReportList(user user.UserInfo, keyWord string, classifyIdFirst, classify
 				coverImg = listImgMap[reportInfo.ClassifyIdFirst]
 			}
 			reportItem.ReportImgUrl = coverImg
-
-			if classifyParent.ClassifyName == "晨报" && productAuthOk {
-				// 查询当前晨报的所有音频
-				if vList, ok := videoMap[reportInfo.Id]; ok {
-					for _, vd := range vList {
-						vd.VideoImg = reportItem.ReportImgUrl
+			reportItem.VideoImg = reportItem.ReportImgUrl
+
+			if reportItem.HasChapter == 1 {
+				if classifyParent.ClassifyName == "晨报" && productAuthOk {
+					// 查询当前晨报的所有音频
+					if vList, ok := videoMap[reportInfo.Id]; ok {
+						for _, vd := range vList {
+							vd.VideoImg = reportItem.ReportImgUrl
+						}
+						reportItem.VideoList = vList
 					}
-					reportItem.VideoList = vList
-				}
-				reportItem.AuthOk = productAuthOk
-			} else if classifyParent.ClassifyName == "周报" {
-				if wAuth, ok := weekAuthMap[reportInfo.Id]; ok {
-					reportItem.AuthOk = wAuth
-					if wAuth {
-						// 查询当前晨报的所有音频
-						if vList, ok2 := videoMap[reportInfo.Id]; ok2 {
-							for _, vd := range vList {
-								vd.VideoImg = reportItem.ReportImgUrl
+					reportItem.AuthOk = productAuthOk
+				} else {
+					if wAuth, ok := weekAuthMap[reportInfo.Id]; ok {
+						reportItem.AuthOk = wAuth
+						if wAuth {
+							// 查询当前晨报的所有音频
+							if vList, ok2 := videoMap[reportInfo.Id]; ok2 {
+								for _, vd := range vList {
+									vd.VideoImg = reportItem.ReportImgUrl
+								}
+								reportItem.VideoList = vList
 							}
-							reportItem.VideoList = vList
 						}
 					}
 				}
@@ -995,6 +1081,20 @@ func GetReportList(user user.UserInfo, keyWord string, classifyIdFirst, classify
 				reportItem.AuthOk = authOk
 			}
 
+			// 报告详情展示形式
+			{
+				minClassifyId := reportItem.ClassifyIdThird
+				if minClassifyId <= 0 {
+					minClassifyId = reportItem.ClassifyIdSecond
+				}
+				if minClassifyId <= 0 {
+					minClassifyId = reportItem.ClassifyIdFirst
+				}
+				if tmpClassify, ok := classifyMap[minClassifyId]; ok {
+					reportItem.ReportDetailShowType = int(tmpClassify.ReportDetailShowType)
+				}
+			}
+
 			reportList = append(reportList, reportItem)
 		}
 
@@ -1022,6 +1122,97 @@ func GetCollectReportList(user user.UserInfo, chartPermissionId, pageIndex, page
 		return
 	}
 
+	if permissionInfo.ChartPermissionID == 0 {
+		err = errors.New("权限不存在")
+		return
+	}
+	// 除了晨报和周报以外的其他报告
+	classifyIdList, err := chart_permission_search_key_word_mapping.GetClassifyIdsByChartPermissionId(chartPermissionId, "rddp")
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("查询权限对应的分类出错")
+		return
+	}
+
+	var firstClassifyIdList, secondClassifyIdList, thirdClassifyIdList []int
+	{
+		classifyList, tmpErr := classify.GetListByClassifyIdList(classifyIdList)
+		if tmpErr != nil {
+			errMsg = tmpErr.Error()
+			err = errors.New("查询分类信息失败")
+			return
+		}
+
+		for _, v := range classifyList {
+			switch v.Level {
+			case 1:
+				firstClassifyIdList = append(firstClassifyIdList, v.Id)
+			case 2:
+				secondClassifyIdList = append(secondClassifyIdList, v.Id)
+			case 3:
+				thirdClassifyIdList = append(thirdClassifyIdList, v.Id)
+			}
+		}
+	}
+
+	var reportList []*response.ReportCollectListItem
+	list := response.ReportCollectListResp{}
+	var total int64
+
+	{
+		offset := (pageIndex - 1) * pageSize
+		reportList, err = report.GetReportCollectListByPermissionV1(chartPermissionId, firstClassifyIdList, secondClassifyIdList, thirdClassifyIdList, offset, pageSize)
+		if err != nil {
+			errMsg = err.Error()
+			err = errors.New("查询报告信息出错")
+			return
+		}
+		listMap := make(map[string]*response.ReportCollectList)
+		for _, v := range reportList {
+			v.ContentSub = GetReportContentSub(v.ContentSub, true)
+			if _, ok := listMap[v.PublishTime.Format("2006-01-02")]; !ok {
+				temp := new(response.ReportCollectList)
+				temp.Date = v.PublishTime.Format("2006-01-02")
+				listMap[v.PublishTime.Format("2006-01-02")] = temp
+			}
+			listMap[v.PublishTime.Format("2006-01-02")].SubList = append(listMap[v.PublishTime.Format("2006-01-02")].SubList, v)
+		}
+		for _, v := range listMap {
+			list = append(list, v)
+		}
+		total, err = report.GetReportCollectCountByPermissionV1(chartPermissionId, classifyIdList)
+		if err != nil {
+			errMsg = err.Error()
+			err = errors.New("查询报告总数出错")
+			return
+		}
+		if len(list) > 0 {
+			sort.Sort(list)
+		}
+	}
+
+	ret = new(response.ReportCollectResp)
+	ret.List = list
+	ret.Paging = response.GetPaging(pageIndex, pageSize, int(total))
+	return
+}
+
+func GetCollectReportListBak(user user.UserInfo, chartPermissionId, pageIndex, pageSize int) (ret *response.ReportCollectResp, err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			global.LOG.Critical(fmt.Sprintf("GetCollectReportList: userId=%d, err:%s, errMsg:%s", user.UserID, err.Error(), errMsg))
+		}
+	}()
+
+	// 查询权限的基本信息
+	permissionInfo, err := chart_permission.GetByChartPermissionId(chartPermissionId)
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("查询权限出错")
+		return
+	}
+
 	if permissionInfo.ChartPermissionID == 0 {
 		err = errors.New("权限不存在")
 		return
@@ -1107,17 +1298,21 @@ func SearchReport(user user.UserInfo, keyWord string, pageIndex, pageSize int) (
 		err = errors.New("分类查询出错")
 		return
 	}
+	classifyIdList := make([]int, 0)
 	var classifyIdFirsts []int
 	classifyIdSeconds := []int{0}
+	classifyMap := make(map[int]*classify.Classify)
 	for _, v := range classifys {
 		if v.ParentId == 0 {
 			classifyIdFirsts = append(classifyIdFirsts, v.Id)
 		} else {
 			classifyIdSeconds = append(classifyIdSeconds, v.Id)
 		}
+		classifyIdList = append(classifyIdList, v.Id)
+		classifyMap[v.Id] = v
 	}
 	keyWord = addAliasToKeyword(keyWord)
-	searchResp, total, err := elasticService.SearchReport(keyWord, classifyIdFirsts, classifyIdSeconds, pageIndex, pageSize)
+	searchResp, total, err := elasticService.SearchReport(keyWord, classifyIdList, pageIndex, pageSize)
 	if err != nil {
 		errMsg = err.Error()
 		err = errors.New("查询失败")
@@ -1146,6 +1341,8 @@ func SearchReport(user user.UserInfo, keyWord string, pageIndex, pageSize int) (
 			temp.ClassifyNameFirst = reportItem.ClassifyNameFirst
 			temp.ClassifyIdSecond = reportItem.ClassifyIdSecond
 			temp.ClassifyNameSecond = reportItem.ClassifyNameSecond
+			temp.ClassifyId = reportItem.ClassifyId
+			temp.ClassifyName = reportItem.ClassifyName
 			temp.Title = reportItem.Title
 			temp.ContentSub = reportItem.BodyContent
 			temp.PublishTime, err = time.ParseInLocation(utils.FormatDateTime, reportItem.PublishTime, time.Local)
@@ -1165,6 +1362,10 @@ func SearchReport(user user.UserInfo, keyWord string, pageIndex, pageSize int) (
 			//	}
 			//}
 			temp.ContentSub = GetReportContentSub(temp.ContentSub, false)
+
+			if tmpClassify, ok := classifyMap[temp.ClassifyId]; ok {
+				temp.ReportDetailShowType = int(tmpClassify.ReportDetailShowType)
+			}
 			reportList = append(reportList, temp)
 		}
 	}
@@ -1490,6 +1691,37 @@ func GetVarietyReportList(user user.UserInfo, classifyId, chartPermissionId, pag
 	return
 }
 
+// GetMinClassify
+// @Description: 获取最小分类ID
+// @author: Roc
+// @datetime 2024-06-20 09:23:19
+// @param reportInfo *models.Report
+// @return minClassifyId int
+// @return minClassifyName string
+// @return err error
+func GetMinClassify(reportInfo *report.Report) (minClassifyId int, minClassifyName string, err error) {
+	defer func() {
+		if err != nil {
+			global.FILE_LOG.Error("获取最小分类ID失败,报告ID:%d,Err:%s", reportInfo.Id, err.Error())
+		}
+	}()
+	minClassifyId = reportInfo.ClassifyIdThird
+	minClassifyName = reportInfo.ClassifyNameThird
+	if minClassifyId <= 0 {
+		minClassifyId = reportInfo.ClassifyIdSecond
+		minClassifyName = reportInfo.ClassifyNameSecond
+	}
+	if minClassifyId <= 0 {
+		minClassifyId = reportInfo.ClassifyIdFirst
+		minClassifyName = reportInfo.ClassifyNameFirst
+	}
+	if minClassifyId <= 0 {
+		err = errors.New("分类异常")
+	}
+
+	return
+}
+
 // GetCommoditiesReportList 获取大宗商品报告列表
 //func GetCommoditiesReportList(user user.UserInfo, chartPermissionId, pageIndex, pageSize int) (ret *response.ReportList, err error) {
 //	var errMsg string

+ 236 - 54
services/report/report_chapter.go

@@ -6,11 +6,13 @@ import (
 	report_chapter_type_cache "hongze/hongze_yb/cache/report_chapter_type"
 	"hongze/hongze_yb/global"
 	"hongze/hongze_yb/models/response"
-	"hongze/hongze_yb/models/tables/chart_permission_chapter_mapping"
 	"hongze/hongze_yb/models/tables/company_product"
+	"hongze/hongze_yb/models/tables/rddp/chart_permission_chapter_mapping"
 	"hongze/hongze_yb/models/tables/rddp/classify"
 	"hongze/hongze_yb/models/tables/rddp/report"
 	"hongze/hongze_yb/models/tables/rddp/report_chapter"
+	"hongze/hongze_yb/models/tables/rddp/smart_report_resource"
+	"hongze/hongze_yb/models/tables/report_chapter_permission_mapping"
 	"hongze/hongze_yb/models/tables/report_chapter_type"
 	"hongze/hongze_yb/models/tables/user_report_chapter_set"
 	"hongze/hongze_yb/services"
@@ -95,7 +97,7 @@ func GetChapterListByReport(classifyNameFirst string, reportId int, validWeekTyp
 		typeIds = append(typeIds, int(v.ReportChapterTypeId))
 	}
 
-	if classifyNameFirst == "周报" {
+	if classifyNameFirst != "晨报" {
 		for _, v := range validWeekTypeIds {
 			newTypeMap[v] = true
 		}
@@ -190,7 +192,7 @@ func GetChapterDetail(user user.UserInfo, reportChapterId int) (reportChapterDet
 		err = errors.New("无有效的章节类型")
 		return
 	}
-	reportChapter, err := report_chapter.GetContentById(reportChapterId, typeIds)
+	reportChapter, err := report_chapter.GetItemById(reportChapterId)
 	if err != nil {
 		errMsg = err.Error()
 		err = errors.New("章节查询出错")
@@ -212,12 +214,16 @@ func GetChapterDetail(user user.UserInfo, reportChapterId int) (reportChapterDet
 		err = errors.New("报告不存在")
 		return
 	}
-	if reportInfo.ClassifyNameFirst == "周报" && reportChapter.IsEdit != 1 {
-		err = errors.New("章节未编辑")
-		return
+	if reportChapter.Author == `` {
+		reportChapter.Author = reportInfo.Author
 	}
+	//if reportInfo.ClassifyNameFirst == "周报" && reportChapter.IsEdit != 1 {
+	//	err = errors.New("章节未编辑")
+	//	return
+	//}
 	//判断权限
 	var newTypeIds []int
+	var reportChapterIdList []int
 	if reportInfo.ClassifyNameFirst == "晨报" {
 		authOk, permissionCheckInfo, err = CheckDayReportPermission(user, productAuthOk)
 		if err != nil && err != utils.ErrNoRow {
@@ -225,15 +231,15 @@ func GetChapterDetail(user user.UserInfo, reportChapterId int) (reportChapterDet
 			err = errors.New("权限查询出错")
 			return
 		}
-	} else if reportInfo.ClassifyNameFirst == "周报" {
-		authOk, permissionCheckInfo, newTypeIds, err = CheckWeekReportPermission(user, productAuthOk)
+	} else {
+		authOk, permissionCheckInfo, newTypeIds, reportChapterIdList, err = CheckWeekReportPermission(user, reportInfo.Id, productAuthOk)
 		if err != nil && err != utils.ErrNoRow {
 			errMsg = err.Error()
 			err = errors.New("权限查询出错")
 			return
 		}
-		for _, v := range newTypeIds {
-			if v == reportChapter.TypeId {
+		for _, v := range reportChapterIdList {
+			if v == reportChapter.ReportChapterId {
 				chapterAuthOk = true
 			}
 		}
@@ -251,6 +257,39 @@ func GetChapterDetail(user user.UserInfo, reportChapterId int) (reportChapterDet
 	reportChapterItem.PublishTime = reportChapter.PublishTime
 	reportChapterItem.VideoPlaySeconds = reportChapter.VideoPlaySeconds
 	reportChapterItem.VideoName = reportChapter.VideoName
+	reportChapterItem.ReportLayout = reportChapter.ReportLayout
+	reportChapterItem.HeadImg = reportInfo.HeadImg
+	reportChapterItem.EndImg = reportInfo.EndImg
+	reportChapterItem.CanvasColor = reportInfo.CanvasColor
+
+	// 手工上传的才返回
+	if reportInfo.VoiceGenerateType == 1 {
+		reportChapterItem.ReportVideoUrl = reportInfo.VideoUrl
+	}
+
+	// 版头版尾样式
+	{
+		if reportInfo.HeadResourceId > 0 {
+			headResource, tmpErr := smart_report_resource.GetResourceItemById(reportInfo.HeadResourceId)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			reportChapterItem.HeadImg = headResource.ImgURL
+			reportChapterItem.HeadStyle = headResource.Style
+		}
+
+		if reportInfo.EndResourceId > 0 {
+			endResource, tmpErr := smart_report_resource.GetResourceItemById(reportInfo.EndResourceId)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			reportChapterItem.EndImg = endResource.ImgURL
+			reportChapterItem.EndStyle = endResource.Style
+		}
+	}
+
 	if reportChapter.VideoUrl != "" && reportChapter.VideoName == "" {
 		reportChapterItem.VideoName = reportChapter.Title
 	}
@@ -356,24 +395,72 @@ func GetMenuChapter(reportId int, typeIds []int, classifyNameFirst string, repor
 	return
 }
 
-// CheckWeekReportPermission 验证周报的权限
-func CheckWeekReportPermission(userInfo user.UserInfo, productAuthOk bool) (authOk bool, permissionCheckInfo response.PermissionCheckInfo, validTypeIds []int, err error) {
+// CheckWeekReportPermission
+// @Description: 验证周报的权限(并获取拥有权限的章节id列表)
+// @author: Roc
+// @datetime 2024-06-24 11:06:52
+// @param userInfo user.UserInfo
+// @param reportId int
+// @param productAuthOk bool
+// @return authOk bool
+// @return permissionCheckInfo response.PermissionCheckInfo
+// @return validTypeIds []int 分类关联的章节类型ID列表
+// @return reportChapterIdList []int 并获取拥有权限的章节id列表
+// @return err error
+func CheckWeekReportPermission(userInfo user.UserInfo, reportId int, productAuthOk bool) (authOk bool, permissionCheckInfo response.PermissionCheckInfo, validTypeIds, reportChapterIdList []int, err error) {
 	var permissionIds []int
 	var validPermissionIds []int //最后允许显示的章节
+
+	// 当前报告的品种与章节列表的map
+	permissionChapterList := make(map[int][]int)
+	permissionIdMap := make(map[int]bool)
+	typeIdMap := make(map[int]bool)
 	if productAuthOk {
-		permissionIds, err = chart_permission_chapter_mapping.GetPermissionIdsByWeek()
-		if err != nil && err != utils.ErrNoRow {
+		reportChapterMappingList, tmpErr := report_chapter_permission_mapping.GetReportChapterPermissionMappingItemListByReportId(reportId)
+		if tmpErr != nil && errors.Is(tmpErr, utils.ErrNoRow) {
 			return
 		}
+		for _, v := range reportChapterMappingList {
+			if _, ok := permissionIdMap[v.ChartPermissionID]; !ok {
+				permissionIdMap[v.ChartPermissionID] = true
+				permissionIds = append(permissionIds, v.ChartPermissionID)
+			}
+			if _, ok := typeIdMap[v.TypeId]; !ok {
+				typeIdMap[v.TypeId] = true
+				validTypeIds = append(validTypeIds, v.TypeId)
+			}
+
+			tmpList, ok := permissionChapterList[v.ChartPermissionID]
+			if !ok {
+				tmpList = make([]int, 0)
+			}
+			permissionChapterList[v.ChartPermissionID] = append(tmpList, v.ReportChapterID)
+		}
+
 	}
+
 	authOk, permissionCheckInfo, validPermissionIds, err = company.GetCheckPermission(userInfo.CompanyID, int(userInfo.UserID), permissionIds)
 	if err != nil {
 		return
 	}
 	//返回可用的章节列表
 	if len(validPermissionIds) > 0 {
-		validTypeIds, err = chart_permission_chapter_mapping.GetReportIdsByPermisssionIds(validPermissionIds, "week")
+		reportChapterIdMap := make(map[int]bool)
+		for _, v := range validPermissionIds {
+
+			chapterIdList, ok := permissionChapterList[v]
+			if !ok {
+				continue
+			}
+			for _, chapterId := range chapterIdList {
+				if _, ok := reportChapterIdMap[chapterId]; !ok {
+					reportChapterIdMap[chapterId] = true
+					reportChapterIdList = append(reportChapterIdList, chapterId)
+				}
+			}
+		}
 	}
+
 	return
 }
 
@@ -384,6 +471,7 @@ func CheckDayReportPermission(userInfo user.UserInfo, productAuthOk bool) (authO
 		return
 	}
 	authOk, permissionCheckInfo, _, err = company.GetCheckPermission(userInfo.CompanyID, int(userInfo.UserID), []int{})
+
 	return
 }
 
@@ -412,6 +500,7 @@ func GetReportChapterVideoList(permissionIds []int, classifyName string, list []
 
 	typeMap := make(map[int]*report_chapter_type.ReportChapterType)
 	var typeIds []int
+	typeIds = append(typeIds, 0)
 	for _, v := range typeList {
 		typeMap[int(v.ReportChapterTypeId)] = v
 		typeIds = append(typeIds, int(v.ReportChapterTypeId))
@@ -419,19 +508,11 @@ func GetReportChapterVideoList(permissionIds []int, classifyName string, list []
 
 	var chapters []*report_chapter.ReportChapter
 	setMap := make(map[int]int)
-	if classifyName == "周报" {
-		// 查询用户有权限的章节ID
-		newTypeIds, tErr := GetWeekTypeIdsByPermissionIds(permissionIds, typeIds)
-		if tErr != nil {
-			errMsg = tErr.Error()
-			err = errors.New("查询章节类型权限出错")
-			return
-		}
-		// 查询章节列表
-		chapters, err = report_chapter.GetByTypeIdsAndReportIds(newTypeIds, reportIds, classifyName)
+	if classifyName != "晨报" {
+		// 查询用户有权限的章节列表
+		chapters, err = report_chapter.GetByPermissionIdListAndReportList(permissionIds, reportIds)
 		//获取音频设置章节
 		setList, _ := user_report_chapter_set.GetUserReportChapterSet(userId)
-
 		for _, v := range setList {
 			if v.IsClose == 0 {
 				setMap[v.TypeId] = v.TypeId
@@ -447,41 +528,142 @@ func GetReportChapterVideoList(permissionIds []int, classifyName string, list []
 		return
 	}
 	for _, v := range chapters {
-		if classifyName == "周报" {
+		if classifyName != "晨报" {
 			weekAuthMap[v.ReportId] = true
 		}
-		if temp, ok := typeMap[v.TypeId]; ok && v.VideoUrl != "" {
-			if reportDetail, ok1 := reportMap[v.ReportId]; ok1 {
-				reportDate := reportDetail.CreateTime
-				if reportDate.Before(temp.PauseStartTime) || reportDate.After(temp.PauseEndTime) {
-					if classifyName == "周报" {
-						if _, sok := setMap[v.TypeId]; sok {
-							videoItem := new(response.VideoListItem)
-							videoItem.VideoPlaySeconds = v.VideoPlaySeconds
-							videoItem.VideoName = v.VideoName
-							if v.VideoName == "" {
-								videoItem.VideoName = v.Title
-							}
-							videoItem.VideoUrl = v.VideoUrl
-							videoItem.Sort = v.Sort
-							videoMap[v.ReportId] = append(videoMap[v.ReportId], videoItem)
-						}
-					} else {
-						videoItem := new(response.VideoListItem)
-						videoItem.VideoPlaySeconds = v.VideoPlaySeconds
-						videoItem.VideoName = v.VideoName
-						if v.VideoName == "" {
-							videoItem.VideoName = v.Title
-						}
-						videoItem.VideoUrl = v.VideoUrl
-						videoItem.Sort = v.Sort
-						videoMap[v.ReportId] = append(videoMap[v.ReportId], videoItem)
-					}
+
+		// 各种过滤条件
+		{
+			if v.VideoUrl == `` {
+				continue
+			}
+			// 报告校验
+			reportDetail, ok := reportMap[v.ReportId]
+			if !ok { // 不是当前报告,那么过滤不处理
+				continue
+			}
+			reportDate := reportDetail.CreateTime
+
+			// 如果是系统配置的章节类型,那么需要额外校验时间
+			if v.TypeId > 0 {
+				// 如果不存在该类型的章节类型,那么就过滤,直接下一个循环
+				temp, ok := typeMap[v.TypeId]
+				if !ok {
+					continue
+				}
+
+				// 如果晚于开始日期同时早于结束日期;或者等于开始日期;或者等于结束日期,那么就过滤,直接下一个循环
+				if (reportDate.After(temp.PauseStartTime) && reportDate.Before(temp.PauseEndTime)) || reportDate.Equal(temp.PauseStartTime) || reportDate.Equal(temp.PauseEndTime) {
+					continue
 				}
 			}
 
+			if classifyName != "晨报" {
+				if _, sok := setMap[v.TypeId]; !sok {
+					continue
+				}
+			}
+		}
+
+		videoItem := new(response.VideoListItem)
+		videoItem.VideoPlaySeconds = v.VideoPlaySeconds
+		videoItem.VideoName = v.VideoName
+		if v.VideoName == "" {
+			videoItem.VideoName = v.Title
 		}
+		videoItem.VideoUrl = v.VideoUrl
+		videoItem.Sort = v.Sort
+		videoMap[v.ReportId] = append(videoMap[v.ReportId], videoItem)
 	}
 
 	return
 }
+
+// GetChapterListByReportChapterIdList
+// @Description: 根据报告获取章节列表
+// @author: Roc
+// @datetime 2024-06-24 11:23:36
+// @param classifyNameFirst string
+// @param reportId int
+// @param reportChapterIdList []int
+// @param reportCreateTime time.Time
+// @return reportTypeList response.ReportChapterList
+// @return err error
+func GetChapterListByReportChapterIdList(classifyNameFirst string, reportId int, reportChapterIdList []int) (reportTypeList response.ReportChapterList, err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			global.LOG.Critical(fmt.Sprintf("GetChapterListByReport: err:%s, errMsg:%s", err.Error(), errMsg))
+		}
+	}()
+	//查询有效的章节
+	typeList, tErr := report_chapter_type.GetEffectTypes()
+	if tErr != nil {
+		errMsg = tErr.Error()
+		err = errors.New("章节类型查询出错")
+		return
+	}
+	if len(typeList) == 0 {
+		err = errors.New("无有效的章节")
+		return
+	}
+
+	typeMap := make(map[uint64]*report_chapter_type.ReportChapterType)
+	for _, v := range typeList {
+		typeMap[v.ReportChapterTypeId] = v
+	}
+
+	var chapterList []*report_chapter.ReportChapter
+	if len(reportChapterIdList) > 0 {
+		//获取所有当前研报有权限的章节
+		chapterList, tErr = report_chapter.GetListByChapterIds(reportChapterIdList)
+	} else {
+		// 获取所有报告章节
+		chapterList, tErr = report_chapter.GetListByReportId(reportId, classifyNameFirst)
+	}
+	if tErr != nil && tErr != utils.ErrNoRow {
+		errMsg = err.Error()
+		err = errors.New("章节查询出错")
+		return
+	}
+	if len(chapterList) == 0 {
+		err = errors.New("无有效章节")
+		return
+	}
+
+	for _, item := range chapterList {
+		typeItem, ok1 := typeMap[uint64(item.TypeId)]
+		// 如果是配置的章节,那么就需要判断是否禁用,如果禁用,则不展示
+		if item.TypeId > 0 && !ok1 {
+			continue
+		}
+
+		temp := new(response.ReportChapterListItem)
+		temp.ReportChapterId = item.ReportChapterId
+		temp.TypeId = item.TypeId
+		temp.TypeName = item.TypeName
+		temp.Title = item.Title
+		temp.Trend = item.Trend
+		temp.ReportId = item.ReportId
+		temp.Sort = item.Sort
+		temp.PublishTime = item.PublishTime
+		temp.VideoUrl = item.VideoUrl
+		temp.VideoName = item.VideoName
+		temp.VideoPlaySeconds = item.VideoPlaySeconds
+		temp.VideoSize = item.VideoSize
+		temp.Content = item.Content
+
+		// 系统配置的参数,只有配置的章节类型,才能赋值
+		if typeItem != nil {
+			temp.ReportChapterTypeKey = typeItem.ReportChapterTypeKey
+			temp.ReportChapterTypeName = typeItem.ReportChapterTypeName
+			temp.ReportChapterTypeThumb = typeItem.YbIconUrl
+		}
+
+		reportTypeList = append(reportTypeList, temp)
+	}
+	if len(reportTypeList) > 0 {
+		sort.Sort(reportTypeList)
+	}
+	return
+}

+ 1 - 3
services/report/report_view_record.go

@@ -31,9 +31,7 @@ func AddViewRecord(userInfo user.UserInfo, reportId int, classifyName string, re
 	record.RealName = userInfo.RealName
 	record.CompanyName = companyInfo.CompanyName
 	record.CreateTime = time.Now()
-	if classifyName == "晨报" || classifyName == "周报" {
-		record.ReportChapterId = reportChapterId
-	}
+	record.ReportChapterId = reportChapterId
 	err = report_view_record.Create(record)
 	if err != nil {
 		return

+ 2 - 4
services/report/user_access_record.go

@@ -9,7 +9,7 @@ import (
 )
 
 // AddUserAccessRecord 新增报告浏览记录
-func AddUserAccessRecord(userInfo user.UserInfo, reportId int, classifyName string, reportChapterId int, authOk bool){
+func AddUserAccessRecord(userInfo user.UserInfo, reportId int, classifyName string, reportChapterId int, authOk bool) {
 	var err error
 	defer func() {
 		if err != nil {
@@ -26,9 +26,7 @@ func AddUserAccessRecord(userInfo user.UserInfo, reportId int, classifyName stri
 			record.Remark = "0"
 		}
 		record.ReportId = reportId
-		if classifyName == "晨报" || classifyName == "周报" {
-			record.ReportChapterId = reportChapterId
-		}
+		record.ReportChapterId = reportChapterId
 		err = record.Create()
 	}
 	return

+ 28 - 29
services/user/user.go

@@ -28,15 +28,14 @@ type UserInfo struct {
 // GetWxUserItemByOpenId 通过openid获取用户信息
 func GetWxUserItemByOpenId(openid string) (userInfo UserInfo, err error) {
 	//通过openid获取用户关联信息
-	userRecord, userRecordErr := user_record.GetByOpenID(openid)
-	if userRecordErr != nil {
-		if userRecordErr == utils.ErrNoRow {
+	userRecord, e := user_record.GetByOpenID(openid)
+	if e != nil {
+		if e == utils.ErrNoRow {
 			err = ERR_NO_USER_RECORD
 			return
-		} else {
-			err = userRecordErr
-			return
 		}
+		err = e
+		return
 	}
 
 	//该openid在系统中没有关联关系
@@ -288,26 +287,26 @@ QUERY_WX_USER:
 		goto QUERY_WX_USER
 	} else if wxUserErr == ERR_USER_NOT_BIND {
 		// 未绑定则去查询unionId是否已经绑定了用户(其他平台,不区分平台),有相应的手机号邮箱信息则自动绑定
-		platformUser, platformErr := GetFirstWxUserItemByUnionId(unionId)
-		if platformErr == nil {
-			// 当公众号用户存在时
-			if platformUser.Mobile != "" || platformUser.Email != "" {
-				// 有手机号或邮箱则绑定信息则自动绑定并新增wx_user
-				countryCode := 0
-				if platformUser.CountryCode != "" {
-					countryCode, _ = strconv.Atoi(platformUser.CountryCode)
-				}
-				tempToken, tempUser, tempErr, errMsg := BindWxUser(openId, platformUser.Mobile, platformUser.Email, "", 3, countryCode, 1)
-				if tempErr != nil {
-					err = errors.New("自动绑定公众号用户失败,Err:" + tempErr.Error() + ", errMsg:" + errMsg)
-					return
-				}
-				token = tempToken
-				userId = int(tempUser.UserID)
-				isBind = true
-				return
-			}
-		}
+		//platformUser, platformErr := GetFirstWxUserItemByUnionId(unionId)
+		//if platformErr == nil {
+		//	// 当公众号用户存在时
+		//	if platformUser.Mobile != "" || platformUser.Email != "" {
+		//		// 有手机号或邮箱则绑定信息则自动绑定并新增wx_user
+		//		countryCode := 0
+		//		if platformUser.CountryCode != "" {
+		//			countryCode, _ = strconv.Atoi(platformUser.CountryCode)
+		//		}
+		//		tempToken, tempUser, tempErr, errMsg := BindWxUser(openId, platformUser.Mobile, platformUser.Email, "", 3, countryCode, 1)
+		//		if tempErr != nil {
+		//			err = errors.New("自动绑定公众号用户失败,Err:" + tempErr.Error() + ", errMsg:" + errMsg)
+		//			return
+		//		}
+		//		token = tempToken
+		//		userId = int(tempUser.UserID)
+		//		isBind = true
+		//		return
+		//	}
+		//}
 	} else if wxUserErr != nil {
 		err = wxUserErr
 		return
@@ -420,14 +419,14 @@ func GetInfoByClaims(c *gin.Context) (userInfo UserInfo) {
 	return
 }
 
-// GetAdminByUserId 判断当前用户是否为内部人员
+// GetAdminByUserInfo 判断当前用户是否为内部人员
 func GetAdminByUserInfo(userInfo UserInfo) (ok bool, adminInfo *admin2.Admin, err error) {
 	mobile := userInfo.Mobile
 	if mobile == "" {
 		// 用户有可能是通过邮箱登录
 		return
 	}
-	if userInfo.CompanyID != 16 {
+	if userInfo.CompanyID != utils.HzCompanyId {
 		return
 	}
 	adminInfo, err = admin2.GetAdminByMobile(mobile)
@@ -453,7 +452,7 @@ func GetResearcherByUserInfo(userInfo UserInfo) (ok bool, adminInfo *admin2.Admi
 		// 用户有可能是通过邮箱登录
 		return
 	}
-	if userInfo.CompanyID != 16 {
+	if userInfo.CompanyID != utils.HzCompanyId {
 		return
 	}
 	adminInfo, err = admin2.GetAdminByMobile(mobile)

+ 31 - 5
services/user/user_bind.go

@@ -122,8 +122,7 @@ func BindWxUser(openid, mobile, email, code string, bindType, areaNum, registerP
 
 // bindWxUser 用户注册/绑定
 func bindWxUser(openid, mobile, email string, areaNum, registerPlatform int) (userInfo UserInfo, errMsg string, err error) {
-	var source int8
-	source = 6 //绑定来源,1:微信端,2:pc网页端,3:查研观向小程序,4:每日咨询
+	source := int8(utils.USER_RECORD_PLATFORM_YB) //绑定来源,1:微信端,2:pc网页端,3:查研观向小程序,4:每日咨询
 	if mobile == "" && email == "" {
 		err = errors.New("手机号或邮箱必填一个")
 		return
@@ -219,13 +218,40 @@ func bindWxUser(openid, mobile, email string, areaNum, registerPlatform int) (us
 		}
 		return
 	}
+
+	// 未绑定
 	if userRecord.UserID == 0 {
+		// 校验该手机号/邮箱是否已绑定过微信, 若已绑定过则所有微信均进行解绑, 仅绑定当前微信
+		repeats, e := user_record.GetRepeatBindAccount(bindAccount, userRecord.UnionID)
+		if e != nil {
+			err = fmt.Errorf("获取重复的绑定账号数失败, err: %s", e.Error())
+			errMsg = "绑定异常"
+			return
+		}
+		if len(repeats) > 0 {
+			// 清除绑定关系
+			if e = user_record.ClearRepeatBindAccount(bindAccount, userRecord.UnionID); e != nil {
+				err = fmt.Errorf("重置重复的绑定账号失败, err: %s", e.Error())
+				errMsg = "绑定异常"
+				return
+			}
+			// 清除重复账号的session
+			repeatOpenIds := make([]string, 0)
+			for _, v := range repeats {
+				repeatOpenIds = append(repeatOpenIds, v.OpenID)
+			}
+			if e = session.ClearRepeatBindAccountToken(repeatOpenIds); e != nil {
+				err = fmt.Errorf("清除重复绑定账号Token失败, err: %v", e)
+				errMsg = "绑定异常"
+				return
+			}
+		}
+
 		userRecord.BindAccount = bindAccount
 		userRecord.UserID = userId
 		var updateCols = []string{"UserID", "BindAccount"}
-		tmpErr := userRecord.Update(updateCols)
-		if tmpErr != nil {
-			err = tmpErr
+		if e = userRecord.Update(updateCols); e != nil {
+			err = e
 			return
 		}
 	}

+ 4 - 4
services/yb_common.go

@@ -99,10 +99,10 @@ func CheckReportExistByReportIdReportChapterId(reportId, reportChapterId int) (e
 		return
 	}
 
-	if (reportInfo.ClassifyNameFirst == "晨报" || reportInfo.ClassifyNameFirst == "周报") && reportChapterId <= 0 {
-		err = errors.New("请输入报告章节ID")
-		return
-	}
+	//if reportInfo.HasChapter == 1 && reportChapterId <= 0 {
+	//	err = errors.New("请输入报告章节ID")
+	//	return
+	//}
 
 	if reportChapterId > 0 {
 		reportChapterInfo, tErr := report_chapter.GetTypeIdById(reportChapterId)

+ 3 - 2
utils/constants.go

@@ -351,8 +351,9 @@ var DataSourceEnMap = map[int]string{
 
 // 子数据来源渠道
 const (
-	DATA_SUB_SOURCE_EDB  = iota //经济数据库
-	DATA_SUB_SOURCE_DATE        //日期序列
+	DATA_SUB_SOURCE_EDB            = iota //经济数据库
+	DATA_SUB_SOURCE_DATE                  //日期序列
+	DATA_SUB_SOURCE_HIGH_FREQUENCY        //高频数据
 )
 
 // 默认的品种图片