Browse Source

Merge branch 'master' into feature/eta1.9.5_future_good

xyxie 8 months ago
parent
commit
9b7a657c9a
51 changed files with 2042 additions and 373 deletions
  1. 1 0
      .gitignore
  2. 2 1
      config/config.go
  3. 32 19
      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. 5 0
      models/response/chart_info/chart_info.go
  14. 23 0
      models/response/pc/report.go
  15. 27 0
      models/response/report.go
  16. 1 0
      models/tables/chart_info_correlation/entity.go
  17. 19 0
      models/tables/chart_info_correlation/model.go
  18. 48 2
      models/tables/edb_data/query.go
  19. 34 0
      models/tables/factor_edb_series/model.go
  20. 28 0
      models/tables/factor_edb_series_chart_mapping/model.go
  21. 0 0
      models/tables/rddp/chart_permission/chart_permission.go
  22. 9 9
      models/tables/rddp/chart_permission/query.go
  23. 0 0
      models/tables/rddp/chart_permission_chapter_mapping/chart_permission_chapter_mapping.go
  24. 7 7
      models/tables/rddp/chart_permission_chapter_mapping/query.go
  25. 2 0
      models/tables/rddp/classify/classify.go
  26. 28 0
      models/tables/rddp/classify/query.go
  27. 142 1
      models/tables/rddp/report/query.go
  28. 9 0
      models/tables/rddp/report/report.go
  29. 81 1
      models/tables/rddp/report_chapter/query.go
  30. 1 0
      models/tables/rddp/report_chapter/report_chapter.go
  31. 11 0
      models/tables/rddp/session/update.go
  32. 33 0
      models/tables/rddp/smart_report_resource/query.go
  33. 37 0
      models/tables/rddp/smart_report_resource/smart_report_resource.go
  34. 85 0
      models/tables/report_chapter_permission_mapping/query.go
  35. 31 0
      models/tables/report_chapter_permission_mapping/report_chapter_permission_mapping.go
  36. 13 0
      models/tables/user_record/query.go
  37. 15 3
      services/chart/chart_info.go
  38. 67 0
      services/chart/correlation/chart_info.go
  39. 9 0
      services/chart/edb_info.go
  40. 1 1
      services/community/video.go
  41. 89 87
      services/company/permission.go
  42. 35 40
      services/elastic/report.go
  43. 1 1
      services/pc/report.go
  44. 224 41
      services/report/report.go
  45. 231 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. 1 1
      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 日志配置

+ 32 - 19
controller/chart/chart_common.go

@@ -928,36 +928,48 @@ func getCorrelationChartInfoDetail(chartInfo *chartInfoModel.ChartInfoView, myCh
 		errMsg = "获取相关性图表, A指标mapping信息失败, Err:" + e.Error()
 		return
 	}
-	edbInfoMappingB, e := chartEdbMappingModel.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdSecond)
-	if e != nil {
-		msg = "获取失败"
-		errMsg = "获取相关性图表, B指标mapping信息失败, Err:" + e.Error()
-		return
+	edbInfoMappingB := new(chartEdbMappingModel.ChartEdbInfoMapping)
+	if correlationChart.AnalysisMode != 1 {
+		edbInfoMappingB, e = chartEdbMappingModel.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdSecond)
+		if e != nil {
+			msg = "获取失败"
+			errMsg = "获取相关性图表, B指标mapping信息失败, Err:" + e.Error()
+			return
+		}
 	}
 
 	var dataResp interface{} // 绘图数据返回(目前是滚动相关性的图)
 	var xEdbIdValue []int
 	var yDataList []chart_info.YData
-	switch chartInfo.Source {
-	case utils.CHART_SOURCE_CORRELATION: // 相关性图
-		moveUnitDays, ok := utils.FrequencyDaysMap[correlationChart.CalculateUnit]
-		if !ok {
-			msg = "错误的分析周期"
-			errMsg = "相关性图表数据有误"
-			return
+	if correlationChart.AnalysisMode != 1 {
+		switch chartInfo.Source {
+		case utils.CHART_SOURCE_CORRELATION: // 相关性图
+			moveUnitDays, ok := utils.FrequencyDaysMap[correlationChart.CalculateUnit]
+			if !ok {
+				msg = "错误的分析周期"
+				errMsg = "相关性图表数据有误"
+				return
+			}
+			st := time.Now().AddDate(0, 0, -correlationChart.CalculateValue*moveUnitDays).Format(utils.FormatDate)
+			ed := time.Now().Format(utils.FormatDate)
+
+			xEdbIdValue, yDataList, e = correlation.GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, correlationChart.LeadValue, correlationChart.LeadUnit, st, ed)
+			if e != nil {
+				msg = "获取失败"
+				errMsg = "获取相关性图表, 图表计算值失败, Err:" + e.Error()
+				return
+			}
+		case utils.CHART_SOURCE_ROLLING_CORRELATION: // 滚动相关性图
+			st, ed := utils.GetDateByDateType(correlationChart.DateType, correlationChart.StartDate.Format(utils.FormatDate), correlationChart.EndDate.Format(utils.FormatDate))
+			dataResp, e = correlation.GetRollingCorrelationChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, correlationChart.LeadValue, correlationChart.LeadUnit, correlationChart.CalculateValue, correlationChart.CalculateUnit, st, ed, chartInfo.ChartName, chartInfo.ChartNameEn)
 		}
-		startDate := time.Now().AddDate(0, 0, -correlationChart.CalculateValue*moveUnitDays).Format(utils.FormatDate)
-		endDate := time.Now().Format(utils.FormatDate)
-
-		xEdbIdValue, yDataList, e = correlation.GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, correlationChart.LeadValue, correlationChart.LeadUnit, startDate, endDate)
+	} else {
+		xEdbIdValue, yDataList, e = correlation.GetFactorChartDataByChartId(chartInfoId, chartInfo.ExtraConfig)
 		if e != nil {
 			msg = "获取失败"
 			errMsg = "获取相关性图表, 图表计算值失败, Err:" + e.Error()
 			return
 		}
-	case utils.CHART_SOURCE_ROLLING_CORRELATION: // 滚动相关性图
-		startDate, endDate := utils.GetDateByDateType(correlationChart.DateType, correlationChart.StartDate.Format(utils.FormatDate), correlationChart.EndDate.Format(utils.FormatDate))
-		dataResp, e = correlation.GetRollingCorrelationChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, correlationChart.LeadValue, correlationChart.LeadUnit, correlationChart.CalculateValue, correlationChart.CalculateUnit, startDate, endDate, chartInfo.ChartName, chartInfo.ChartNameEn)
 	}
 
 	// 完善指标信息
@@ -978,6 +990,7 @@ func getCorrelationChartInfoDetail(chartInfo *chartInfoModel.ChartInfoView, myCh
 	correlationInfo.LeadValue = correlationChart.LeadValue
 	correlationInfo.EdbInfoIdFirst = correlationChart.EdbInfoIdFirst
 	correlationInfo.EdbInfoIdSecond = correlationChart.EdbInfoIdSecond
+	correlationInfo.AnalysisMode = correlationChart.AnalysisMode
 
 	// 访问记录-仅普通用户记录
 	ok, _, _ := user.GetAdminByUserInfo(userInfo)

+ 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
+}

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

@@ -51,6 +51,10 @@ type YData struct {
 	M              []int           `description:"对应开始日期的间隔值" json:"-"`
 	NameList       []string        `description:"每个值对应的名称"`
 	EnNameList     []string        `description:"每个值对应的英文名称"`
+	SeriesEdb      struct {
+		SeriesId  int `description:"因子指标系列ID"`
+		EdbInfoId int `description:"指标ID"`
+	} `description:"对应的系列指标"`
 }
 
 type CorrelationInfo struct {
@@ -62,6 +66,7 @@ type CorrelationInfo struct {
 	EdbInfoIdSecond int    `description:"B指标ID"`
 	PeriodData      string `description:"X轴-期数数据"`
 	CorrelationData string `description:"Y轴-相关性系数"`
+	AnalysisMode    int    `description:"分析模式: 0-单因子; 1-多因子"`
 }
 
 // RollingCorrelationChartDataResp 滚动相关性图

+ 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
+}

+ 27 - 0
models/response/report.go

@@ -54,6 +54,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 +85,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 {
@@ -106,6 +120,8 @@ type ReportListItem 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"`
@@ -115,6 +131,13 @@ type ReportListItem struct {
 	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"` // 音频播放条前面展示的图片
+
 }
 
 type VideoListItem struct {
@@ -141,6 +164,8 @@ type ReportCollectListItem struct {
 	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"`
 }
 
 type ReportCollectList struct {
@@ -173,6 +198,8 @@ type EsReportItem struct {
 	Title              string `description:"标题"`
 	Abstract           string `description:"摘要"`
 	StageStr           string `description:"期数"`
+	ClassifyId         int    `description:"最小分类id"`
+	ClassifyName       string `description:"最小分类名称"`
 }
 
 type TickerDataItem struct {

+ 1 - 0
models/tables/chart_info_correlation/entity.go

@@ -20,6 +20,7 @@ type ChartInfoCorrelation struct {
 	CorrelationData        string    `gorm:"column:correlation_data;type:text" json:"correlationData"`                                     // Y轴-相关性系数
 	CreateTime             time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`                                           // 创建时间
 	ModifyTime             time.Time `gorm:"column:modify_time;type:datetime" json:"modifyTime"`                                           // 更新时间
+	AnalysisMode           int       `gorm:"column:analysis_mode;type:int(10) unsigned;not null;default:0" json:"analysisMode"`            // 分析模式: 0-单因子; 1-多因子
 }
 
 // TableName get sql table name.获取数据库表名

+ 19 - 0
models/tables/chart_info_correlation/model.go

@@ -14,3 +14,22 @@ func (m *ChartInfoCorrelation) Update(updateCols []string) (err error) {
 	err = global.MYSQL["data"].Model(m).Select(updateCols).Updates(*m).Error
 	return
 }
+
+// CorrelationChartLegend 相关性图表图例
+type CorrelationChartLegend struct {
+	LegendName string `description:"图例名称"`
+	Color      string `description:"图例颜色"`
+	EdbInfoId  int    `description:"指标ID"`
+	SeriesId   int    `description:"因子指标系列ID"`
+}
+
+// CorrelationSeriesEdbReq 指标系列
+type CorrelationSeriesEdbReq struct {
+	EdbInfoId int `description:"指标ID"`
+	SeriesId  int `description:"因子指标系列ID"`
+}
+
+// CorrelationChartInfoExtraConfig 相关性图表额外设置
+type CorrelationChartInfoExtraConfig struct {
+	LegendConfig []*CorrelationChartLegend `description:"图例设置"`
+}

+ 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
+}

+ 34 - 0
models/tables/factor_edb_series/model.go

@@ -0,0 +1,34 @@
+package factor_edb_series
+
+// FactorEdbSeriesCorrelationMatrixValues 因子指标系列-相关性矩阵XY值
+type FactorEdbSeriesCorrelationMatrixValues struct {
+	XData int     `description:"X轴数据"`
+	YData float64 `description:"Y轴数据"`
+}
+
+// FactorEdbSeriesCorrelationMatrixOrder 排序规则[0 1 2 3 -1 -2 -3]
+type FactorEdbSeriesCorrelationMatrixOrder []FactorEdbSeriesCorrelationMatrixValues
+
+func (a FactorEdbSeriesCorrelationMatrixOrder) Len() int {
+	return len(a)
+}
+
+func (a FactorEdbSeriesCorrelationMatrixOrder) Swap(i, j int) {
+	a[i], a[j] = a[j], a[i]
+}
+
+func (a FactorEdbSeriesCorrelationMatrixOrder) Less(i, j int) bool {
+	// 非负数优先
+	if a[i].XData >= 0 && a[j].XData < 0 {
+		return true
+	}
+	if a[i].XData < 0 && a[j].XData >= 0 {
+		return false
+	}
+	// 非负数升序排序
+	if a[i].XData >= 0 {
+		return a[i].XData < a[j].XData
+	}
+	// 负数按绝对值的降序排序(即数值的升序)
+	return a[i].XData > a[j].XData
+}

+ 28 - 0
models/tables/factor_edb_series_chart_mapping/model.go

@@ -0,0 +1,28 @@
+package factor_edb_series_chart_mapping
+
+import (
+	"hongze/hongze_yb/global"
+	"time"
+)
+
+// FactorEdbSeriesChartMapping 因子指标系列-图表关联
+type FactorEdbSeriesChartMapping struct {
+	FactorEdbSeriesChartMappingId int       `orm:"column(factor_edb_series_chart_mapping_id);pk"`
+	ChartInfoId                   int       `description:"图表ID"`
+	Source                        int       `description:"图表来源, 同chart_info表source"`
+	CalculateType                 int       `description:"计算方式: 1-相关性"`
+	CalculatePars                 string    `description:"计算参数-JSON(如计算窗口等)"`
+	CalculateData                 string    `description:"计算数据-JSON(如相关性矩阵等)"`
+	FactorEdbSeriesId             int       `description:"因子指标系列ID"`
+	EdbInfoId                     int       `description:"指标ID"`
+	EdbUsed                       int       `description:"指标是否使用: 0-否; 1-是"`
+	CreateTime                    time.Time `description:"创建时间"`
+	ModifyTime                    time.Time `description:"修改时间"`
+}
+
+// GetChartUsedFactorSeriesEdb 获取图表引用的系列指标
+func GetChartUsedFactorSeriesEdb(chartId int) (items []*FactorEdbSeriesChartMapping, err error) {
+	sql := `SELECT * FROM factor_edb_series_chart_mapping WHERE chart_info_id = ? AND edb_used = 1`
+	err = global.MYSQL["data"].Raw(sql, chartId).Scan(&items).Error
+	return
+}

+ 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
-}
+}

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

@@ -32,6 +32,8 @@ type Classify struct {
 	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
 }
 
 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
+}

+ 9 - 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,13 @@ 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"`
 }
 
 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
+}

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

@@ -28,6 +28,7 @@ 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"`
 }
 
 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
+}

+ 15 - 3
services/chart/chart_info.go

@@ -583,7 +583,7 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 		item.ConvertValue = v.ConvertValue
 		item.ConvertUnit = v.ConvertUnit
 		item.ConvertEnUnit = v.ConvertEnUnit
-		
+
 		var startDateReal string
 		var diffSeconds int64
 		if chartType == 2 { //季节性图
@@ -782,6 +782,7 @@ func GetSeasonEdbInfoDataListByXDate(dataList []*edbDataModel.EdbDataList, lates
 	}
 	endYear := lastDateT.Year()
 	nowYear := time.Now().Year()
+	chartLegendMaxYear := 0
 	dataMap := make(map[string]edbDataModel.QuarterXDateItem, 0)
 
 	quarterDataList := make([]*edbDataModel.QuarterData, 0)
@@ -826,6 +827,7 @@ func GetSeasonEdbInfoDataListByXDate(dataList []*edbDataModel.EdbDataList, lates
 			EndDate:   endT,
 			ShowName:  showName,
 		}
+		chartLegendMaxYear = endT.Year()
 		dataMap[name] = item
 		chartLegendMap[name] = idx
 		idx++
@@ -835,9 +837,13 @@ func GetSeasonEdbInfoDataListByXDate(dataList []*edbDataModel.EdbDataList, lates
 		}
 	}
 	lenYear := len(dataMap)
+	if chartLegendMaxYear > endYear {
+		chartLegendMaxYear = endYear
+	}
 	for k, v := range dataMap {
 		if i, ok := chartLegendMap[k]; ok {
-			v.ChartLegend = strconv.Itoa(endYear - lenYear + i)
+			//v.ChartLegend = strconv.Itoa(endYear - lenYear + i)
+			v.ChartLegend = strconv.Itoa(chartLegendMaxYear - lenYear + i)
 		}
 		dataMap[k] = v
 	}
@@ -971,6 +977,7 @@ func GetSeasonEdbInfoDataListByXDateNong(result *edbDataModel.EdbDataResult, lat
 	}
 	endYear := lastDateT.Year()
 	nowYear := time.Now().Year()
+	chartLegendMaxYear := 0
 	dataMap := make(map[string]edbDataModel.QuarterXDateItem, 0)
 
 	quarterDataList := make([]*edbDataModel.QuarterData, 0)
@@ -1015,6 +1022,7 @@ func GetSeasonEdbInfoDataListByXDateNong(result *edbDataModel.EdbDataResult, lat
 			EndDate:   endT,
 			ShowName:  showName,
 		}
+		chartLegendMaxYear = endT.Year()
 		dataMap[showName] = item
 		fmt.Println("年份" + showName + "日期" + startStr + " " + endStr)
 		startTmpT = startT
@@ -1027,9 +1035,13 @@ func GetSeasonEdbInfoDataListByXDateNong(result *edbDataModel.EdbDataResult, lat
 		}
 	}
 	lenYear := len(dataMap)
+	if chartLegendMaxYear > endYear {
+		chartLegendMaxYear = endYear
+	}
 	for k, v := range dataMap {
 		if i, ok := chartLegendMap[k]; ok {
-			v.ChartLegend = strconv.Itoa(endYear - lenYear + i)
+			//v.ChartLegend = strconv.Itoa(endYear - lenYear + i)
+			v.ChartLegend = strconv.Itoa(chartLegendMaxYear - lenYear + i)
 		}
 		dataMap[k] = v
 	}

+ 67 - 0
services/chart/correlation/chart_info.go

@@ -10,6 +10,8 @@ import (
 	"hongze/hongze_yb/models/tables/chart_info_correlation"
 	"hongze/hongze_yb/models/tables/edb_data"
 	edbDataModel "hongze/hongze_yb/models/tables/edb_data"
+	"hongze/hongze_yb/models/tables/factor_edb_series"
+	"hongze/hongze_yb/models/tables/factor_edb_series_chart_mapping"
 	"hongze/hongze_yb/services/alarm_msg"
 	"hongze/hongze_yb/services/chart"
 	"hongze/hongze_yb/utils"
@@ -626,3 +628,68 @@ func ChartInfoRefresh(chartInfoId int) (err error) {
 	}
 	return
 }
+
+// GetFactorChartDataByChartId 获取多因子相关性图表数据
+func GetFactorChartDataByChartId(chartInfoId int, extraConfig string) (xEdbIdValue []int, yDataList []chart_info.YData, err error) {
+	if chartInfoId <= 0 {
+		return
+	}
+	// 指标对应的图例
+	extra := new(chart_info_correlation.CorrelationChartInfoExtraConfig)
+	if extraConfig != "" {
+		if e := json.Unmarshal([]byte(extraConfig), extra); e != nil {
+			err = fmt.Errorf("解析图表额外配置失败, err: %v", e)
+			return
+		}
+	}
+	legends := make(map[string]*chart_info_correlation.CorrelationChartLegend)
+	if extra != nil {
+		for _, v := range extra.LegendConfig {
+			s := fmt.Sprintf("%d-%d", v.SeriesId, v.EdbInfoId)
+			legends[s] = v
+		}
+	}
+
+	// 获取图表引用到的系列指标
+	chartMappings, e := factor_edb_series_chart_mapping.GetChartUsedFactorSeriesEdb(chartInfoId)
+	if e != nil {
+		err = fmt.Errorf("获取图表引用系列指标失败, err: %v", e)
+		return
+	}
+
+	// 取出计算结果
+	yDataList = make([]chart_info.YData, 0)
+	yDate := "0000-00-00"
+	for k, m := range chartMappings {
+		var values []factor_edb_series.FactorEdbSeriesCorrelationMatrixValues
+		if m.CalculateData != "" {
+			e = json.Unmarshal([]byte(m.CalculateData), &values)
+			if e != nil {
+				err = fmt.Errorf("系列指标计算数据有误, err: %v", e)
+				return
+			}
+		}
+		var y []float64
+		for _, v := range values {
+			if k == 0 {
+				xEdbIdValue = append(xEdbIdValue, v.XData)
+			}
+			y = append(y, v.YData)
+		}
+		var yData chart_info.YData
+		yData.Date = yDate
+		yData.Value = y
+		yData.SeriesEdb.SeriesId = m.FactorEdbSeriesId
+		yData.SeriesEdb.EdbInfoId = m.EdbInfoId
+
+		// 图例
+		s := fmt.Sprintf("%d-%d", m.FactorEdbSeriesId, m.EdbInfoId)
+		legend := legends[s]
+		if legend != nil {
+			yData.Name = legend.LegendName
+			yData.Color = legend.Color
+		}
+		yDataList = append(yDataList, yData)
+	}
+	return
+}

+ 9 - 0
services/chart/edb_info.go

@@ -419,6 +419,9 @@ func getRefreshEdbInfoListByIds(edbInfoIdList []int) (newBaseEdbInfoArr, newBase
 	// 第一次的计算指标map
 	newCalculateMap = make(map[int]*edbInfoModel.EdbInfo)
 	for _, v := range calculateInfoArr {
+		if v.NoUpdate == 1 {
+			continue
+		}
 		if _, ok := newCalculateMap[v.EdbInfoId]; !ok {
 			calculateArr = append(calculateArr, v.EdbInfoId)
 		}
@@ -499,6 +502,9 @@ func getRefreshEdbInfoListByIds(edbInfoIdList []int) (newBaseEdbInfoArr, newBase
 
 		// 第二次计算指标的map
 		for _, v := range calculateInfoArr {
+			if v.NoUpdate == 1 {
+				continue
+			}
 			if _, ok := newCalculateMap[v.EdbInfoId]; !ok {
 				calculateArr = append(calculateArr, v.EdbInfoId)
 			}
@@ -510,6 +516,9 @@ func getRefreshEdbInfoListByIds(edbInfoIdList []int) (newBaseEdbInfoArr, newBase
 	newBaseEdbInfoArr = make([]*edbInfoModel.EdbInfo, 0)
 	baseMap := make(map[int]int)
 	for _, v := range baseEdbInfoArr {
+		if v.NoUpdate == 1 {
+			continue
+		}
 		if _, ok := baseMap[v.EdbInfoId]; !ok {
 			newBaseEdbInfoArr = append(newBaseEdbInfoArr, v)
 		}

+ 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"

+ 89 - 87
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
 	}
@@ -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"

+ 224 - 41
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"
@@ -408,14 +409,18 @@ func GetReportDetail(userinfo user.UserInfo, reportId int) (reportDetail respons
 
 	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 +436,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 +487,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
 			}
@@ -705,7 +745,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 +873,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]
 				}
@@ -890,22 +934,23 @@ func GetReportList(user user.UserInfo, keyWord string, classifyIdFirst, classify
 		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 +965,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 +978,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 +991,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 +1011,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
 						}
 					}
 				}
@@ -1022,6 +1079,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,6 +1255,7 @@ func SearchReport(user user.UserInfo, keyWord string, pageIndex, pageSize int) (
 		err = errors.New("分类查询出错")
 		return
 	}
+	classifyIdList := make([]int, 0)
 	var classifyIdFirsts []int
 	classifyIdSeconds := []int{0}
 	for _, v := range classifys {
@@ -1115,9 +1264,10 @@ func SearchReport(user user.UserInfo, keyWord string, pageIndex, pageSize int) (
 		} else {
 			classifyIdSeconds = append(classifyIdSeconds, v.Id)
 		}
+		classifyIdList = append(classifyIdList, v.Id)
 	}
 	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 +1296,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)
@@ -1490,6 +1642,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

+ 231 - 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,35 @@ 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
+	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 +391,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 +467,7 @@ func CheckDayReportPermission(userInfo user.UserInfo, productAuthOk bool) (authO
 		return
 	}
 	authOk, permissionCheckInfo, _, err = company.GetCheckPermission(userInfo.CompanyID, int(userInfo.UserID), []int{})
+
 	return
 }
 
@@ -412,6 +496,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 +504,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 +524,141 @@ 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
+
+		// 系统配置的参数,只有配置的章节类型,才能赋值
+		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
 		}
 	}

+ 1 - 1
services/yb_common.go

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

+ 3 - 2
utils/constants.go

@@ -350,8 +350,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        //高频数据
 )
 
 // 默认的品种图片