kobe6258 8 ماه پیش
والد
کامیت
ac7098fa4c

+ 55 - 0
common/component/config/file_config.go

@@ -0,0 +1,55 @@
+package config
+
+import (
+	"eta_mini_ht_api/common/contants"
+	"sync"
+)
+
+var (
+	fileOnce   sync.Once
+	fileConfig *FileConfig
+)
+
+type FileOpts struct {
+	Notice     string
+	Disclaimer string
+	PublicKey  string
+}
+type FileConfig struct {
+	BaseConfig
+	opts FileOpts
+}
+
+func (f *FileConfig) GetNotice() string {
+	return f.opts.Notice
+}
+
+func (f *FileConfig) GetPublicKey() string {
+	return f.opts.PublicKey
+}
+func (f *FileConfig) GetDisclaimer() string {
+	return f.opts.Disclaimer
+}
+func (f *FileConfig) InitConfig() {
+	opts := FileOpts{
+		Notice:     f.GetString("url"),
+		Disclaimer: f.GetString("driver"),
+		PublicKey:  f.GetString("publicKey"),
+	}
+	f.opts = opts
+}
+func NewFileConfig() Config {
+	if dbConfig == nil {
+		fileOnce.Do(func() {
+			fileConfig = &FileConfig{
+				BaseConfig: BaseConfig{prefix: contants.FILE},
+				opts:       FileOpts{},
+			}
+		})
+	}
+	return fileConfig
+}
+
+func init() {
+	Register(contants.FILE, NewFileConfig)
+}

+ 65 - 18
common/component/es/es.go

@@ -30,9 +30,11 @@ type ESClient struct {
 type SearchType string
 
 const (
-	MatchAll = "match_all"
-	Match    = "match"
-	Range    = "range"
+	MatchAll            = "match_all"
+	Match               = "match"
+	Range               = "range"
+	MatchAllByCondition = "match_all_by_condition"
+	RangeByCondition    = "range_by_condition"
 )
 
 func GetInstance() *ESClient {
@@ -115,14 +117,14 @@ func (es *ESClient) BulkInsert(indexName string, docs []ESBase) (err error) {
 
 type ESResponse struct {
 	Took     int        `json:"took"`
-	TimedOut bool       `json:"timed_out"`
+	TimedOut bool       `json:"timedOut"`
 	Hits     Hits       `json:"hits"`
 	_Shards  ShardsInfo `json:"_shards"`
 }
 
 type Hits struct {
 	Total    TotalHits `json:"total"`
-	MaxScore float64   `json:"max_score"`
+	MaxScore float64   `json:"maxScore"`
 	Hits     []Hit     `json:"hits"`
 }
 
@@ -147,16 +149,18 @@ type ShardsInfo struct {
 	Failed     int `json:"failed"`
 }
 type ESQueryRequest struct {
-	IndexName   string
-	From        int
-	Size        int
-	Key         string
-	Column      string
-	Sorts       []string
-	Type        SearchType
-	RangeColumn string
-	Max         interface{}
-	Min         interface{}
+	IndexName      string
+	From           int
+	Size           int
+	Key            string
+	Column         string
+	Condition      string
+	ConditionValue string
+	Sorts          []string
+	Type           SearchType
+	RangeColumn    string
+	Max            interface{}
+	Min            interface{}
 }
 
 func (req *ESQueryRequest) CreateESQueryRequest(index string, column string, key string, from int, size int, sorts []string, searchType SearchType) *ESQueryRequest {
@@ -177,6 +181,11 @@ func (req *ESQueryRequest) Range(from int64, to int64, column string) *ESQueryRe
 	req.Min = from
 	return req
 }
+func (req *ESQueryRequest) ByCondition(column string, value string) *ESQueryRequest {
+	req.Condition = column
+	req.ConditionValue = value
+	return req
+}
 
 func (req *ESQueryRequest) parseJsonQuery() (queryMap map[string]interface{}) {
 	switch req.Type {
@@ -187,6 +196,18 @@ func (req *ESQueryRequest) parseJsonQuery() (queryMap map[string]interface{}) {
 			},
 		}
 		return
+	case MatchAllByCondition:
+		queryMap = map[string]interface{}{
+			"query": map[string]interface{}{
+				"match_all": map[string]interface{}{},
+			},
+			"post_filter": map[string]interface{}{
+				"term": map[string]interface{}{
+					req.Condition: req.ConditionValue,
+				},
+			},
+		}
+		return
 	case Match:
 		queryMap = map[string]interface{}{
 			"query": map[string]interface{}{
@@ -198,7 +219,7 @@ func (req *ESQueryRequest) parseJsonQuery() (queryMap map[string]interface{}) {
 				"fields": map[string]interface{}{
 					req.Column: map[string]interface{}{},
 				},
-				"pre_tags":  []string{"<span style='color:red'>"},
+				"pre_tags":  []string{"<span style='color:#0078E8'>"},
 				"post_tags": []string{"</span>"},
 			},
 		}
@@ -227,6 +248,33 @@ func (req *ESQueryRequest) parseJsonQuery() (queryMap map[string]interface{}) {
 			},
 		}
 		return
+	case RangeByCondition:
+		queryMap = map[string]interface{}{
+			"query": map[string]interface{}{
+				"match": map[string]interface{}{
+					req.Column: req.Key,
+				},
+			},
+			"highlight": map[string]interface{}{
+				"fields": map[string]interface{}{
+					req.Column: map[string]interface{}{},
+				},
+				"pre_tags":  []string{"<span style='color:red'>"},
+				"post_tags": []string{"</span>"},
+			},
+			"post_filter": map[string]interface{}{
+				"range": map[string]interface{}{
+					req.RangeColumn: map[string]interface{}{
+						"gte": req.Min,
+						"lte": req.Max,
+					},
+				},
+				"term": map[string]interface{}{
+					req.Condition: req.ConditionValue,
+				},
+			},
+		}
+		return
 	default:
 		queryMap = map[string]interface{}{}
 		return
@@ -266,8 +314,7 @@ func (es *ESClient) Search(params *ESQueryRequest) (response ESResponse, err err
 		if err = json.NewDecoder(res.Body).Decode(&e); err != nil {
 			logger.Error("解析es应答失败: %v", err)
 		} else {
-			// Print the response status and error information.
-			logger.Error("es请求失败: %s: %v\n", res.Status(), err)
+			logger.Error("es请求失败: %s: %v\n", res.Status(), e)
 		}
 	}
 	body, err := io.ReadAll(res.Body)

+ 1 - 0
common/contants/contants.go

@@ -2,6 +2,7 @@ package contants
 
 const (
 	DATABASE = "database"
+	FILE     = "file"
 	SMS      = "sms"
 	REDIS    = "redis"
 

+ 7 - 0
common/exception/exc_enums.go

@@ -32,6 +32,7 @@ const (
 	GetAreaCodesFailed
 	AnalystNotFound
 	IllegalAreaCode
+	MediaTypeError
 )
 
 // UserErrCode 用户
@@ -49,6 +50,8 @@ const (
 	FeedBackError
 	IllegalFollowType
 	UserFollowAnalystFailed
+	GetNoticeFileError
+	GetDisclaimerFileError
 )
 
 // WechatErrCode 微信
@@ -86,6 +89,8 @@ var ErrorMap = map[int]string{
 	AnalystNotFound:       "研究员不存在",
 	GetAreaCodesFailed:    "获取手机区号失败",
 	IllegalAreaCode:       "无效的区号",
+	MediaTypeError:        "媒体类型非法",
+
 	//用户
 	TemplateUserNotFound:     "临时用户记录不存在",
 	TemplateUserCreateFailed: "创建临时用户失败",
@@ -98,6 +103,8 @@ var ErrorMap = map[int]string{
 	FeedBackError:            "提交反馈信息失败",
 	IllegalFollowType:        "无效的关注类型",
 	UserFollowAnalystFailed:  "关注研究员失败",
+	GetNoticeFileError:       "获取注册须知失败",
+	GetDisclaimerFileError:   "获取免责声明失败",
 	//微信
 	WeChatServerError:    "微信服务器发生错误",
 	WechatUserInfoFailed: "获取微信用户信息失败",

+ 11 - 4
common/utils/page/page_utils.go

@@ -1,19 +1,23 @@
 package page
 
+import "math"
+
 type PageInfo struct {
 	LatestId int64
 	Current  int
 	PageSize int
+	Total    int64
 }
 type PageResult struct {
 	Page Page
 	Data interface{}
 }
 type Page struct {
-	LatestId int64
-	Current  int
-	PageSize int
-	Total    int64
+	LatestId  int64 `json:"latestId"`
+	Current   int   `json:"current"`
+	PageSize  int   `json:"pageSize"`
+	Total     int64 `json:"total"`
+	TotalPage int   `json:"totalPage"`
 }
 
 func StartIndex(page, pagesize int) int {
@@ -23,6 +27,9 @@ func StartIndex(page, pagesize int) int {
 	return 0
 }
 
+func TotalPages(total int64, pagesize int) int {
+	return int(math.Ceil(float64(total) / float64(pagesize)))
+}
 func (p *PageInfo) Reset() {
 	p.Current = 0
 	p.PageSize = 0

+ 12 - 0
common/utils/string/string_utils.go

@@ -1,6 +1,7 @@
 package string
 
 import (
+	"strconv"
 	"strings"
 )
 
@@ -14,3 +15,14 @@ func IsBlank(s string) bool {
 func IsNotBlank(s string) bool {
 	return !IsBlank(s)
 }
+func StringToIntSlice(strSlice []string) ([]int, error) {
+	var intSlice []int
+	for _, str := range strSlice {
+		num, err := strconv.Atoi(str)
+		if err != nil {
+			return nil, err
+		}
+		intSlice = append(intSlice, num)
+	}
+	return intSlice, nil
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
conf/海通免责声明.txt


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
conf/海通小程序注册用户须知.txt


+ 2 - 0
controllers/list_contoller.go

@@ -14,6 +14,7 @@ func (l *ListController) Prepare() {
 	pageSize, _ := l.GetInt("pageSize")
 	currentIndex, _ := l.GetInt("currentIndex")
 	LatestId, _ := l.GetInt64("latestId")
+	total, _ := l.GetInt64("total")
 	if pageSize <= 0 {
 		pageSize = contants.PageSizeDefault
 	}
@@ -27,6 +28,7 @@ func (l *ListController) Prepare() {
 		LatestId: LatestId,
 		Current:  currentIndex,
 		PageSize: pageSize,
+		Total:    total,
 	}
 }
 

+ 136 - 0
controllers/media/media_controller.go

@@ -1 +1,137 @@
 package media
+
+import (
+	"encoding/json"
+	"eta_mini_ht_api/common/exception"
+	"eta_mini_ht_api/common/utils/page"
+	"eta_mini_ht_api/controllers"
+	"eta_mini_ht_api/service/media"
+	"eta_mini_ht_api/service/report"
+)
+
+type MediaController struct {
+	controllers.ListController
+}
+
+const (
+	video = "video"
+	audio = "audio"
+)
+
+// Search 搜索报告列表
+// @Description 搜索报告列表
+// @Success 200 {object}
+// @router /search [get]
+func (m *MediaController) Search(mediaType string, key string) {
+	controllers.Wrap(&m.BaseController, func() (result *controllers.WrapData, err error) {
+		result = m.InitWrapData("分页搜索媒体列表失败")
+		if key == "" {
+			err = exception.New(exception.SearchKeyEmptyError)
+			m.FailedResult("分页搜索报告列表失败", result)
+			return
+		}
+		pageRes := page.Page{
+			Current:  m.PageInfo.Current,
+			PageSize: m.PageInfo.PageSize,
+		}
+		if m.PageInfo.LatestId == 0 {
+			pageRes.LatestId = media.SearchMaxMediaId(mediaType)
+			m.PageInfo.LatestId = pageRes.LatestId
+		} else {
+			pageRes.LatestId = m.PageInfo.LatestId
+		}
+		pageRes.Total = pageRes.LatestId
+		pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
+		list, err := media.SearchMediaList(mediaType, key, m.PageInfo)
+		if err != nil {
+			m.FailedResult("分页搜索报告列表失败", result)
+			return
+		}
+		reports := new(page.PageResult)
+		reports.Data = list
+		reports.Page = pageRes
+		m.SuccessResult("分页搜索报告列表成功", reports, result)
+		return
+	})
+}
+
+// List 获取报告列表
+// @Description 获取报告列表
+// @Success 200 {object}
+// @router /list [get]
+func (m *MediaController) List(mediaType string) {
+	controllers.Wrap(&m.BaseController, func() (result *controllers.WrapData, err error) {
+		result = m.InitWrapData("分页查询媒体列表失败")
+		if mediaType == "" || !checkMediaType(mediaType) {
+			err = exception.New(exception.MediaTypeError)
+			m.FailedResult("分页查询媒体列表失败", result)
+			return
+		}
+		pageRes := page.Page{
+			Current:  m.PageInfo.Current,
+			PageSize: m.PageInfo.PageSize,
+		}
+		if m.PageInfo.LatestId == 0 {
+			pageRes.LatestId = media.GetTotalPageCount(mediaType)
+			m.PageInfo.LatestId = pageRes.LatestId
+		} else {
+			pageRes.LatestId = m.PageInfo.LatestId
+		}
+		pageRes.Total = pageRes.LatestId
+		pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
+		list, err := media.GetMediaPage(mediaType, m.PageInfo)
+		if err != nil {
+			m.FailedResult("分页查询媒体列表失败", result)
+			return
+		}
+		reports := new(page.PageResult)
+		reports.Data = list
+		reports.Page = pageRes
+		m.SuccessResult("分页查询媒体列表成功", reports, result)
+		return
+	})
+}
+
+type RecordCountReq struct {
+	ReportId   int         `json:"reportId"`
+	IpAddress  string      `json:"ipAddress"`
+	Location   string      `json:"location"`
+	Referer    string      `json:"referer"`
+	Additional interface{} `json:"additional"`
+}
+
+// // GetReport 获取研报详情
+// // @Description 获取研报详情
+// // @Success 200 {object}
+// // @router /report [get]
+//
+//	func (r *ReportController) GetReport(reportId int) {
+//		controllers.Wrap(&r.BaseController, func() (result *controllers.WrapData, err error) {
+//			result = r.InitWrapData("获取研报详情失败")
+//			fmt.Println(reportId)
+//			reportDetail, err := report.GetReportById(reportId)
+//			if err != nil {
+//				err = exception.New(exception.GetReportFailed)
+//				return
+//			}
+//			r.SuccessResult("获取研报详情成功", reportDetail, result)
+//			return
+//		})
+//	}
+func convertToRecordCount(req *RecordCountReq) report.RecordCount {
+	additionStr, _ := json.Marshal(req.Additional)
+	return report.RecordCount{
+		ReportId:   req.ReportId,
+		IpAddress:  req.IpAddress,
+		Location:   req.Location,
+		Referer:    req.Referer,
+		Additional: string(additionStr),
+	}
+}
+
+func checkMediaType(mediaType string) bool {
+	if mediaType == video || mediaType == audio {
+		return true
+	}
+	return false
+}

+ 109 - 53
controllers/report/report_controller.go

@@ -2,12 +2,16 @@ package report
 
 import (
 	"encoding/json"
+	logger "eta_mini_ht_api/common/component/log"
 	"eta_mini_ht_api/common/exception"
 	"eta_mini_ht_api/common/utils/page"
+	stringUtils "eta_mini_ht_api/common/utils/string"
 	"eta_mini_ht_api/controllers"
+	reportService "eta_mini_ht_api/domian/report"
 	"eta_mini_ht_api/service/report"
 	"eta_mini_ht_api/service/user"
 	"fmt"
+	"strings"
 )
 
 type ReportController struct {
@@ -26,25 +30,31 @@ func (r *ReportController) Search(key string) {
 			r.FailedResult("分页搜索报告列表失败", result)
 			return
 		}
-		pageReq := page.Page{
+		pageRes := page.Page{
 			Current:  r.PageInfo.Current,
 			PageSize: r.PageInfo.PageSize,
 		}
 		if r.PageInfo.LatestId == 0 {
-			pageReq.LatestId = report.SearchMaxReportId()
-			r.PageInfo.LatestId = pageReq.LatestId
+			pageRes.LatestId = report.SearchMaxReportId()
+			pageRes.Total = pageRes.LatestId
+			r.PageInfo.LatestId = pageRes.LatestId
+			r.PageInfo.Total = pageRes.Total
 		} else {
-			pageReq.LatestId = r.PageInfo.LatestId
+			pageRes.LatestId = r.PageInfo.LatestId
+			pageRes.Total = r.PageInfo.Total
 		}
-		pageReq.Total = pageReq.LatestId
-		list, err := report.SearchReportList(key, r.PageInfo)
-		if err != nil {
-			r.FailedResult("分页搜索报告列表失败", result)
-			return
+		pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
+		list := make([]reportService.ReportDTO, 0)
+		if pageRes.LatestId > 0 {
+			list, err = report.SearchReportList(key, r.PageInfo)
+			if err != nil {
+				r.FailedResult("分页搜索报告列表失败", result)
+				return
+			}
 		}
 		reports := new(page.PageResult)
 		reports.Data = list
-		reports.Page = pageReq
+		reports.Page = pageRes
 		r.SuccessResult("分页搜索报告列表成功", reports, result)
 		return
 	})
@@ -54,50 +64,92 @@ func (r *ReportController) Search(key string) {
 // @Description 获取报告列表
 // @Success 200 {object}
 // @router /list [get]
-func (r *ReportController) List() {
+func (r *ReportController) List(permissionIds string) {
 	controllers.Wrap(&r.BaseController, func() (result *controllers.WrapData, err error) {
 		result = r.InitWrapData("分页查询报告列表失败")
-		pageReq := page.Page{
+		pageRes := page.Page{
 			Current:  r.PageInfo.Current,
 			PageSize: r.PageInfo.PageSize,
 		}
+		permissionIdList, err := transPermissionIds(permissionIds)
+		if err != nil {
+			logger.Error("品种列表解析错误:%v", err)
+			r.FailedResult("分页查询报告列表失败", result)
+			err = exception.New(exception.QueryReportPageFailed)
+			return
+		}
+		var reportOrgIds []int
 		if r.PageInfo.LatestId == 0 {
-			pageReq.LatestId = report.GetTotalPageCount()
-			r.PageInfo.LatestId = pageReq.LatestId
+			pageRes.Total, pageRes.LatestId, reportOrgIds = report.GetTotalPageCountByPermissionIds(permissionIdList)
+			r.PageInfo.LatestId = pageRes.LatestId
 		} else {
-			pageReq.LatestId = r.PageInfo.LatestId
+			pageRes.LatestId = r.PageInfo.LatestId
+			pageRes.Total = r.PageInfo.Total
 		}
-		pageReq.Total = pageReq.LatestId
-		list, err := report.GetReportPage(r.PageInfo)
+		pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
+		list, err := report.GetReportPage(r.PageInfo, reportOrgIds)
 		if err != nil {
 			r.FailedResult("分页查询报告列表失败", result)
 			return
 		}
 		reports := new(page.PageResult)
 		reports.Data = list
-		reports.Page = pageReq
+		reports.Page = pageRes
 		r.SuccessResult("查询报告列表成功", reports, result)
 		return
 	})
 }
+func transPermissionIds(permissionIds string) (permissionIdList []int, err error) {
+	if strings.HasPrefix(permissionIds, ",") {
+		permissionIds = permissionIds[1:len(permissionIds)]
+	}
+	if strings.HasSuffix(permissionIds, ",") {
+		permissionIds = permissionIds[0 : len(permissionIds)-1]
+	}
+	if permissionIds == "" {
+		permissionIdList = []int{}
+	} else {
+		permissionIdList, err = stringUtils.StringToIntSlice(strings.Split(permissionIds, ","))
+	}
+	return
+}
 
 // HotRanked @Title 获取本周最热的报告列表
 // @Description 获取本周最热的报告列表
 // @Success 200 {object}
 // @router /hotRankedList [get]
-func (r *ReportController) HotRanked() {
+func (r *ReportController) HotRanked(permissionIds string, limit int) {
 	controllers.Wrap(&r.BaseController, func() (result *controllers.WrapData, err error) {
-		limit, _ := r.GetInt("size")
 		if limit <= 0 {
 			limit = 3
 		}
 		result = r.InitWrapData("获取本周最热报告列表失败")
 		list, err := report.GetRandedReportByWeeklyHot(limit)
+		permissionIdList, err := transPermissionIds(permissionIds)
+		if err != nil {
+			logger.Error("品种列表解析错误:%v", err)
+			r.FailedResult("分页查询报告列表失败", result)
+			err = exception.New(exception.QueryReportPageFailed)
+			return
+		}
+		filterList := make([]report.HotRankedReport, 0)
+		if len(permissionIdList) > 0 {
+			for _, item := range list {
+				for _, permissionId := range permissionIdList {
+					if _, ok := item.Permissions[permissionId]; ok {
+						filterList = append(filterList, item)
+						break
+					}
+				}
+			}
+		} else {
+			filterList = list
+		}
 		if err != nil {
 			r.FailedResult("获取本周最热报告列表成功", result)
 			return
 		}
-		r.SuccessResult("获取本周最热报告列表成功", list, result)
+		r.SuccessResult("获取本周最热报告列表成功", filterList, result)
 		return
 	})
 }
@@ -106,11 +158,14 @@ func (r *ReportController) HotRanked() {
 // @Description 获取最新发布的报告列表
 // @Success 200 {object}
 // @router /publishRankedList [get]
-func (r *ReportController) PublishRanked() {
+func (r *ReportController) PublishRanked(limit int, week bool) {
 	controllers.Wrap(&r.BaseController, func() (result *controllers.WrapData, err error) {
 		result = r.InitWrapData("获取最新发布报告列表失败")
+		if limit <= 0 {
+			limit = 3
+		}
 		//获取最新的报告列表
-		list, err := report.GetRandedReportByPublishTime()
+		list, err := report.GetRandedReportByPublishTimeWeekly(limit, week)
 		if err != nil {
 			r.FailedResult("获取最新发布报告列表失败", result)
 			return
@@ -121,36 +176,37 @@ func (r *ReportController) PublishRanked() {
 	})
 }
 
-// AnalystReportList @Title 获取最新发布的报告列表
-// @Description 获取最新发布的报告列表
+// AnalystReportList @Title 获取研究员报告列表
+// @Description 获取研究员报告列表
 // @Success 200 {object}
 // @router /AnalystReportList [get]
-func (r *ReportController) AnalystReportList(authorId int) {
-	controllers.Wrap(&r.BaseController, func() (result *controllers.WrapData, err error) {
-		result = r.InitWrapData("分页获取研究员报告列表失败")
-		pageReq := page.Page{
-			Current:  r.PageInfo.Current,
-			PageSize: r.PageInfo.PageSize,
-		}
-		if r.PageInfo.LatestId == 0 {
-			pageReq.LatestId = report.GetTotalPageCount()
-			r.PageInfo.LatestId = pageReq.LatestId
-		} else {
-			pageReq.LatestId = r.PageInfo.LatestId
-		}
-		pageReq.Total = pageReq.LatestId
-		list, err := report.GetReportPage(r.PageInfo)
-		if err != nil {
-			r.FailedResult("分页查询报告列表失败", result)
-			return
-		}
-		reports := new(page.PageResult)
-		reports.Data = list
-		reports.Page = pageReq
-		r.SuccessResult("查询报告列表成功", reports, result)
-		return
-	})
-}
+//func (r *ReportController) AnalystReportList(authorId int) {
+//	controllers.Wrap(&r.BaseController, func() (result *controllers.WrapData, err error) {
+//		result = r.InitWrapData("分页获取研究员报告列表失败")
+//		pageRes := page.Page{
+//			Current:  r.PageInfo.Current,
+//			PageSize: r.PageInfo.PageSize,
+//		}
+//		if r.PageInfo.LatestId == 0 {
+//			pageRes.LatestId, _ = report.GetTotalPageCount([]int{})
+//			r.PageInfo.LatestId = pageRes.LatestId
+//		} else {
+//			pageRes.LatestId = r.PageInfo.LatestId
+//		}
+//		pageRes.Total = pageRes.LatestId
+//		pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
+//		list, err := report.GetReportPageByAlayyst(r.PageInfo)
+//		if err != nil {
+//			r.FailedResult("分页查询报告列表失败", result)
+//			return
+//		}
+//		reports := new(page.PageResult)
+//		reports.Data = list
+//		reports.Page = pageRes
+//		r.SuccessResult("查询报告列表成功", reports, result)
+//		return
+//	})
+//}
 
 // GetPermissions  @Title 获取品种列表
 // @Description 获取最新发布的报告列表
@@ -171,8 +227,8 @@ func (r *ReportController) GetPermissions() {
 }
 
 type RecordCountReq struct {
-	ReportId   int         `json:"report_id"`
-	IpAddress  string      `json:"ip_address"`
+	ReportId   int         `json:"reportId"`
+	IpAddress  string      `json:"ipAddress"`
 	Location   string      `json:"location"`
 	Referer    string      `json:"referer"`
 	Additional interface{} `json:"additional"`

+ 79 - 8
controllers/user/auth_controller.go

@@ -1,6 +1,7 @@
 package user
 
 import (
+	"bufio"
 	"eta_mini_ht_api/common/component/config"
 	logger "eta_mini_ht_api/common/component/log"
 	"eta_mini_ht_api/common/contants"
@@ -8,6 +9,9 @@ import (
 	authUtils "eta_mini_ht_api/common/utils/auth"
 	"eta_mini_ht_api/controllers"
 	"eta_mini_ht_api/service/auth"
+	"os"
+	"path/filepath"
+	"strings"
 )
 
 type AuthController struct {
@@ -19,9 +23,9 @@ const ChinaAreaCode = "86"
 // LoginReq  获取验证码请求
 type LoginReq struct {
 	Code       string `json:"code"`
-	VerifyCode string `json:"verify_code"`
+	VerifyCode string `json:"verifyCode"`
 	Mobile     string `json:"mobile"`
-	AreaCode   string `json:"area_code"`
+	AreaCode   string `json:"areaCode"`
 }
 
 // Login 小程序登录接口
@@ -76,7 +80,7 @@ type LoginResp struct {
 // SmsCodeReq 获取验证码请求
 type SmsCodeReq struct {
 	Mobile   string `json:"mobile"`
-	AreaCode string `json:"area_code"`
+	AreaCode string `json:"areaCode"`
 }
 
 // SMSCode 小程序手机验证码接口
@@ -184,12 +188,79 @@ func (a *AuthController) WXAppid() {
 	})
 }
 
-// Test 获取APPID
+type FileResp struct {
+	Name    string
+	Content string
+}
+
+// Notice 获取注册须知
+// @Summary 获取注册须知
 // @Success 200 {object} controllers.BaseResponse
-// @Description 获取APPID
-// @router /test [get]
-func (a *AuthController) Test() {
-	auth.GetValidAreaCodes()
+// @Description 获取注册须知
+// @router /notice [get]
+func (a *AuthController) Notice() {
+	controllers.Wrap(&a.BaseController, func() (result *controllers.WrapData, err error) {
+		result = a.InitWrapData("获取注册须知失败")
+		rootDir, err := filepath.Abs(filepath.Dir(os.Args[0]))
+		if err != nil {
+			logger.Error("获取文件路径失败:%v", err)
+			err = exception.New(exception.GetNoticeFileError)
+			a.FailedResult("获取注册须知失败", result)
+			return
+		}
+		//publicKey := config.GetConfig(contants.FILE).(*config.FileConfig).GetPublicKey()
+		noticeFile := config.GetConfig(contants.FILE).(*config.FileConfig).GetNotice()
+		filePath := filepath.Join(rootDir, "conf", noticeFile)
+		content, err := readTextConfig(filePath)
+		if err != nil {
+			err = exception.New(exception.GetNoticeFileError)
+			a.FailedResult("获取注册须知失败", result)
+		}
+		a.SuccessResult("获取注册须知成功", FileResp{
+			Name:    noticeFile,
+			Content: content,
+		}, result)
+		return
+	})
+}
+
+//// Disclaimer 获取免责声明
+//// @Summary 获取免责声明
+//// @Success 200 {object} controllers.BaseResponse
+//// @Description 获取免责声明
+//// @router /disclaimer [get]
+//func (a *AuthController) Disclaimer() {
+//	controllers.Wrap(&a.BaseController, func() (result *controllers.WrapData, err error) {
+//		result = a.InitWrapData("获取免责声明失败")
+//		publicKey := config.GetConfig(contants.FILE).(*config.FileConfig).GetPublicKey()
+//		disclaimerFile = config.GetConfig(contants.FILE).(*config.FileConfig).GetDisclaimer()
+//		appid := config.GetConfig(contants.WECHAT).(*config.WechatConfig).GetAppid()
+//		if err != nil {
+//			a.FailedResult("获取免责声明失败", result)
+//		}
+//		a.SuccessResult("获取免责声明成功", WXAppidResp{
+//			AppId: appid,
+//		}, result)
+//		return
+//	})
+//}
+
+// 读取纯文本文件
+func readTextConfig(filename string) (content string, err error) {
+	file, err := os.Open(filename)
+	if err != nil {
+		return "", err
+	}
+	defer file.Close()
+	scanner := bufio.NewScanner(file)
+	scanner.Split(bufio.ScanLines)
+	var lines []string
+	for scanner.Scan() {
+		line := scanner.Text()
+		lines = append(lines, line)
+	}
+	err = scanner.Err()
+	return strings.Join(lines, "\n"), nil
 }
 
 func checkValidAreaCode(areaCode string) bool {

+ 0 - 0
domian/financial_analyst/eta_report_author.go → domian/financial_analyst/eta_report_author_service.go


+ 0 - 0
domian/financial_analyst/financial_analyst.go → domian/financial_analyst/financial_analyst_service.go


+ 128 - 0
domian/media/media_service.go

@@ -0,0 +1,128 @@
+package media
+
+import (
+	"encoding/json"
+	"eta_mini_ht_api/common/component/es"
+	logger "eta_mini_ht_api/common/component/log"
+	"eta_mini_ht_api/common/utils/page"
+	reportService "eta_mini_ht_api/domian/report"
+	"eta_mini_ht_api/models"
+	mediaDao "eta_mini_ht_api/models/media"
+)
+
+const (
+	DESC models.Order = "desc"
+	ASC  models.Order = "asc"
+
+	ESIndex         = "media_index"
+	ESColumn        = "media_name"
+	ESRangeColumn   = "media_id"
+	ConditionColumn = "media_type"
+)
+
+var (
+	sortField = []string{"_score:desc"}
+)
+
+func elastic() *es.ESClient {
+	return es.GetInstance()
+}
+
+type MediaDTO struct {
+	MediaId          int      `json:"mediaId"`
+	AuthorName       string   `json:"authorName,omitempty"`
+	MediaType        string   `json:"mediaType"`
+	Src              string   `json:"src"`
+	MediaName        string   `json:"mediaName"`
+	SourceType       string   `json:"sourceType"`
+	MediaPlaySeconds int      `json:"mediaPlaySeconds"`
+	PermissionIDs    string   `json:"permissionIDs"`
+	PermissionNames  []string `json:"permissionNames,omitempty"`
+	Highlight        []string `json:"highlight,omitempty"`
+}
+
+func SearchMediaList(mediaType string, key string, from int, size int, max int64) (reports []MediaDTO, err error) {
+	//同步es
+	sorts := append(sortField, "media_id:desc")
+	request := matchRangeByCondition(key, from, size, max, sorts, ConditionColumn, mediaType)
+	re, err := elastic().Search(request)
+	if err != nil {
+		logger.Error("es:%v", err)
+	}
+	hits := elastic().GetSource(re.Hits)
+	for _, hit := range hits {
+		var content map[string][]string
+		err = json.Unmarshal(hit.Highlight, &content)
+		report := MediaDTO{}
+		report.Highlight = content[ESColumn]
+		err = json.Unmarshal(hit.Source, &report)
+		if err != nil {
+			logger.Error("解析研报数据失败:%v", err)
+			continue
+		}
+		reports = append(reports, report)
+	}
+	return
+}
+func SearchMaxMediaId(mediaType string) (mediaId int64) {
+	sort := []string{"media_id:desc"}
+	request := matchAllByCondition(sort, ConditionColumn, mediaType)
+	//同步es
+	re, err := elastic().Search(request)
+	if err != nil {
+		logger.Error("es:%v", err)
+	}
+	hits := elastic().GetSource(re.Hits)
+	if len(hits) > 0 {
+		data := hits[0].Source
+		media := MediaDTO{}
+		err = json.Unmarshal(data, &media)
+		if err != nil {
+			logger.Error("获取当前最大研报id失败:%v", err)
+			return 0
+		}
+		return int64(media.MediaPlaySeconds)
+	}
+	return 0
+}
+func GetTotalPageCount(mediaType string) (count int64) {
+	return mediaDao.GetCountByMediaType(mediaType)
+}
+func GetMediaPage(mediaType string, pageInfo page.PageInfo) (list []MediaDTO, err error) {
+	offset := page.StartIndex(pageInfo.Current, pageInfo.PageSize)
+	reports, err := mediaDao.GetMediaPage(pageInfo.LatestId, pageInfo.PageSize, offset, mediaType)
+	if err == nil && reports != nil {
+		for _, report := range reports {
+			dto := convertMediaDTO(report)
+			list = append(list, dto)
+		}
+	}
+	return
+}
+
+func convertMediaDTO(media mediaDao.Medias) MediaDTO {
+	return MediaDTO{
+		MediaId:          media.ID,
+		AuthorName:       media.AuthorName,
+		MediaType:        media.MediaType,
+		Src:              media.Src,
+		MediaName:        media.MediaName,
+		SourceType:       media.SourceType,
+		MediaPlaySeconds: media.MediaPlaySeconds,
+		PermissionIDs:    media.PermissionIDs,
+	}
+}
+
+func GetPermissionsByIds(ids []int) (permissionDTOs []reportService.PermissionDTO, err error) {
+	return reportService.GetFirstPermissionsByIds(ids)
+}
+
+func matchAllByCondition(sorts []string, column string, value string) (request *es.ESQueryRequest) {
+	req := new(es.ESQueryRequest)
+	return req.CreateESQueryRequest(ESIndex, "", "", 0, 1, sorts, es.MatchAllByCondition).ByCondition(column, value)
+}
+
+func matchRangeByCondition(key string, from int, to int, max int64, sorts []string, column string, value string) (request *es.ESQueryRequest) {
+	req := new(es.ESQueryRequest)
+	return req.CreateESQueryRequest(ESIndex, ESColumn, key, from, to, sorts, es.Range).Range(0, max, ESRangeColumn).ByCondition(column, value)
+}

+ 11 - 2
domian/report/eta_report_service.go

@@ -4,6 +4,7 @@ import (
 	logger "eta_mini_ht_api/common/component/log"
 	"eta_mini_ht_api/models/eta"
 	"fmt"
+	"html"
 	"sync"
 	"time"
 )
@@ -43,6 +44,14 @@ type SmartResourceDTO struct {
 	Style  string `json:"style"`
 }
 
+func GetETAReportIdsByPermissionIds(permissionIds []int) (ids []int, err error) {
+	classifyIds, err := GetClassifyIdsByPermissionIds(permissionIds)
+	if err != nil {
+		logger.Error("品种获取研报分类列表失败:%v", err)
+		return
+	}
+	return eta.GetETAReportIdsByClassifyIds(classifyIds)
+}
 func GetETAReport(id int) (detail ETAReportDTO, err error) {
 	report, err := eta.GetETAReportById(id)
 	if err != nil {
@@ -105,7 +114,7 @@ func convertToETAReportDTO(report eta.ETAReport) (dto ETAReportDTO) {
 		Abstract:         report.Abstract,
 		Author:           report.Author,
 		PublishTime:      report.PublishTime,
-		Content:          report.Content,
+		Content:          html.UnescapeString(report.Content),
 		ReportLayout:     report.ReportLayout,
 		VideoUrl:         report.VideoUrl,
 		VideoName:        report.VideoName,
@@ -126,7 +135,7 @@ func convertToETAReportDTO(report eta.ETAReport) (dto ETAReportDTO) {
 func convertToReportChapterDTO(chapters []eta.ReportChapter) (dtoList []ReportChapterDTO) {
 	for _, chapter := range chapters {
 		dto := ReportChapterDTO{
-			Content:          chapter.Content,
+			Content:          html.UnescapeString(chapter.Content),
 			VideoURL:         chapter.VideoURL,
 			VideoName:        chapter.VideoName,
 			VideoPlaySeconds: chapter.VideoPlaySeconds,

+ 13 - 0
domian/report/permission_service.go

@@ -5,6 +5,9 @@ import (
 	etaDao "eta_mini_ht_api/models/eta"
 )
 
+func GetClassifyIdsByPermissionIds(permissionIds []int) (classifyIds []int, err error) {
+	return etaDao.GetClassifyIdsByPermissionIds(permissionIds)
+}
 func GetPermissionList() (dtoList []PermissionDTO, err error) {
 	list, err := etaDao.GetChartPermissionList()
 	if err != nil {
@@ -18,6 +21,16 @@ func GetPermissionList() (dtoList []PermissionDTO, err error) {
 	}
 	return
 }
+func GetFirstPermissionsByIds(ids []int) (permissionDTOS []PermissionDTO, err error) {
+	list, err := etaDao.GetFirstPermissionsByIds(ids)
+	if err != nil {
+		logger.Error("查询品种信息失败:%v", err)
+	}
+	for _, node := range list {
+		permissionDTOS = append(permissionDTOS, convertPermissionDTO(node))
+	}
+	return
+}
 
 func GetReportPermissionsById(id int, source string) (permissionIds []PermissionDTO) {
 	switch source {

+ 73 - 26
domian/report/report_service.go

@@ -14,8 +14,6 @@ import (
 )
 
 const (
-	indexName = "report_index"
-
 	SourceETA = "ETA"
 	SourceHT  = "HT"
 
@@ -23,8 +21,8 @@ const (
 	ASC  models.Order = "asc"
 
 	ESIndex       = "report_index"
-	ESColumn      = "abstract"
-	ESRangeColumn = "report_id"
+	ESColumn      = "title"
+	ESRangeColumn = "reportId"
 )
 
 var (
@@ -37,26 +35,30 @@ func elastic() *es.ESClient {
 
 // ESReport Report ES研报mapping
 type ESReport struct {
-	ReportID      int                    `json:"report_id"`
-	OrgId         int                    `json:"org_id"`
+	ReportID      int                    `json:"reportId"`
+	OrgId         int                    `json:"orgId"`
+	Title         string                 `json:"title"`
 	Author        string                 `json:"author"`
 	Source        reportDao.ReportSource `json:"source"`
 	Abstract      string                 `json:"abstract"`
+	CoverSrc      string                 `json:"coverSrc"`
 	Status        reportDao.ReportStatus `json:"status"`
-	PublishedTime string                 `json:"published_time"`
+	PublishedTime string                 `json:"publishedTime"`
 }
 
 type ReportDTO struct {
-	ReportID        int             `json:"report_id"`
-	OrgId           int             `json:"org_id"`
+	ReportID        int             `json:"reportId"`
+	OrgId           int             `json:"orgId"`
 	Title           string          `json:"title"`
 	Author          string          `json:"author"`
 	Source          string          `json:"source"`
 	Abstract        string          `json:"abstract"`
-	PublishedTime   string          `json:"published_time"`
+	PublishedTime   string          `json:"publishedTime"`
+	Permissions     map[int]string  `json:"-"`
 	PermissionNames interface{}     `json:"permissionNames,omitempty"`
 	Highlight       []string        `json:"highlight,omitempty"`
 	Detail          json.RawMessage `json:"detail,omitempty"`
+	CoverSrc        string          `json:"coverSrc"`
 }
 
 type Detail struct {
@@ -89,51 +91,81 @@ func GetTotalPageCount() (total int64) {
 	return reportDao.GetTotalPageCount()
 }
 func SearchMaxReportId() (reportId int64) {
-	sortField = []string{"report_id:desc"}
-	request := matchAll(sortField)
+	sort := []string{"reportId:desc"}
+	request := matchAll(sort)
 	//同步es
 	re, err := elastic().Search(request)
 	if err != nil {
 		logger.Error("es:%v", err)
 	}
 	hits := elastic().GetSource(re.Hits)
-	data := hits[0].Source
-	report := ReportDTO{}
-	err = json.Unmarshal(data, &report)
-	if err != nil {
-		logger.Error("获取当前最大研报id失败:%v", err)
-		return 0
+	if len(hits) > 0 {
+		data := hits[0].Source
+		report := ReportDTO{}
+		err = json.Unmarshal(data, &report)
+		if err != nil {
+			logger.Error("获取当前最大研报id失败:%v", err)
+			return 0
+		}
+		return int64(report.ReportID)
 	}
-	return int64(report.ReportID)
+	return 0
 }
 
 func SearchReportList(key string, from int, size int, max int64) (reports []ReportDTO, err error) {
 	//同步es
-	sorts := append(sortField, "report_id:desc")
+	sorts := append(sortField, "reportId:desc")
 	request := matchRange(key, from, size, max, sorts)
 	re, err := elastic().Search(request)
 	if err != nil {
-		logger.Error("es:%v", err)
+		logger.Error("es搜索异常:%v", err)
 	}
 	hits := elastic().GetSource(re.Hits)
+	if len(hits) == 0 {
+		reports = []ReportDTO{}
+		return
+	}
 	for _, hit := range hits {
 		var content map[string][]string
 		err = json.Unmarshal(hit.Highlight, &content)
 		report := ReportDTO{}
-		report.Highlight = content[ESColumn]
 		err = json.Unmarshal(hit.Source, &report)
 		if err != nil {
 			logger.Error("解析研报数据失败:%v", err)
 			continue
 		}
+		report.Highlight = content[ESColumn]
+		report.Title = report.Highlight[0]
 		reports = append(reports, report)
 	}
 	return
 }
+
+func GetReportPageByOrgIds(pageInfo page.PageInfo, orgIds []int) (list []ReportDTO, err error) {
+	offset := page.StartIndex(pageInfo.Current, pageInfo.PageSize)
+	reports, err := reportDao.GetReportPageByOrgIds(pageInfo.LatestId, pageInfo.PageSize, offset, orgIds)
+	if err != nil {
+		logger.Error("分页查询报告列表失败:%v", err)
+		return
+	}
+	list = make([]ReportDTO, 0)
+	if reports != nil {
+		for _, report := range reports {
+			dto := convertReportDTO(report)
+			list = append(list, dto)
+		}
+	}
+	return
+}
 func GetReportPage(pageInfo page.PageInfo) (list []ReportDTO, err error) {
 	offset := page.StartIndex(pageInfo.Current, pageInfo.PageSize)
 	reports, err := reportDao.GetReportPage(pageInfo.LatestId, pageInfo.PageSize, offset)
-	if err == nil && reports != nil {
+	if err != nil {
+		logger.Error("分页查询报告列表失败:%v", err)
+		return
+	}
+	list = make([]ReportDTO, 0)
+	if reports != nil {
 		for _, report := range reports {
 			dto := convertReportDTO(report)
 			list = append(list, dto)
@@ -182,7 +214,7 @@ func SyncETAReportList(list []eta.ETAReport) (err error) {
 		esReports = append(esReports, esRp)
 	}
 	//同步es
-	err = elastic().BulkInsert(indexName, esReports)
+	err = elastic().BulkInsert(ESIndex, esReports)
 	if err != nil {
 		logger.Error("同步ETA研报到es失败:%v", err)
 		return
@@ -190,8 +222,8 @@ func SyncETAReportList(list []eta.ETAReport) (err error) {
 	return
 }
 
-func GetListOrderByCondition(column string, limit int, order models.Order) (dtoList []ReportDTO, err error) {
-	reports, err := reportDao.GetListOrderByCondition(column, limit, order)
+func GetListOrderByConditionWeekly(week bool, column string, limit int, order models.Order) (dtoList []ReportDTO, err error) {
+	reports, err := reportDao.GetListOrderByCondition(week, column, limit, order)
 	if err != nil {
 		logger.Error("获取研报失败:%v", err)
 		return
@@ -220,6 +252,19 @@ func GetListByCondition[T any](column string, ids []T) (dtoList []ReportDTO, err
 	return
 }
 
+func GetTotalPageCountByPermissionIds(permissionIds []int) (total int64, latestId int64, ids []int) {
+	//TODO 一期品种筛选reportIds
+	htIds := []int{}
+	etaIds, err := GetETAReportIdsByPermissionIds(permissionIds)
+	if err != nil {
+		logger.Error("品种筛选eta报告id失败:%v", err)
+		etaIds = []int{}
+	}
+	total = int64(len(etaIds) + len(htIds))
+	ids = append(etaIds, htIds...)
+	latestId = reportDao.GetMaxIdByPermissionIds(ids)
+	return
+}
 func convertEtaReport(etaRp eta.ETAReport) reportDao.Report {
 	return reportDao.Report{
 		OrgID:         etaRp.ID,
@@ -234,11 +279,13 @@ func convertEtaReport(etaRp eta.ETAReport) reportDao.Report {
 func convertEsReport(report reportDao.Report) ESReport {
 	return ESReport{
 		ReportID:      report.ID,
+		Title:         report.Title,
 		OrgId:         report.OrgID,
 		Author:        report.Author,
 		Source:        report.Source,
 		Abstract:      report.Abstract,
 		Status:        report.Status,
+		CoverSrc:      report.CoverSrc,
 		PublishedTime: report.PublishedTime,
 	}
 }

+ 2 - 2
domian/user/area_code_service.go

@@ -6,8 +6,8 @@ import (
 )
 
 type AreaCodeDTO struct {
-	CodeName  string `json:"code_name"`
-	CodeValue string `json:"code_value"`
+	CodeName  string `json:"codeName"`
+	CodeValue string `json:"codeValue"`
 }
 
 func GetAreaCodes() (areaCodes []AreaCodeDTO, err error) {

+ 1 - 1
domian/user/user_serivce.go

@@ -18,7 +18,7 @@ type UserDTO struct {
 
 type FeedbackDTO struct {
 	Mobile  string `json:"mobile"`
-	UserId  int    `json:"user_id"`
+	UserId  int    `json:"userId"`
 	Message string `json:"message"`
 }
 type FollowDTO struct {

+ 11 - 10
main.go

@@ -8,6 +8,8 @@ import (
 	_ "eta_mini_ht_api/routers"
 	_ "eta_mini_ht_api/task"
 	"github.com/beego/beego/v2/server/web"
+	"github.com/beego/beego/v2/server/web/filter/cors"
+	"time"
 )
 
 func main() {
@@ -15,15 +17,14 @@ func main() {
 		web.BConfig.WebConfig.DirectoryIndex = true
 		web.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
 	}
-
-	//web.InsertFilter("*", web.BeforeRouter, cors.Allow(&cors.Options{
-	//	AllowAllOrigins:  true, // 允许所有来源的请求
-	//	AllowMethods:     []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
-	//	AllowHeaders:     []string{"Origin", "Authorization", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Content-Type"},
-	//	ExposeHeaders:    []string{"Content-Length"},
-	//	AllowCredentials: true,
-	//	MaxAge:           12 * time.Hour,
-	//}))
+	web.InsertFilter("*", web.BeforeRouter, cors.Allow(&cors.Options{
+		AllowAllOrigins:  true, // 允许所有来源的请求
+		AllowMethods:     []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
+		AllowHeaders:     []string{"Origin", "Authorization", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Content-Type"},
+		ExposeHeaders:    []string{"Content-Length"},
+		AllowCredentials: true,
+		MaxAge:           12 * time.Hour,
+	}))
 	//增加授权拦截
 	web.InsertFilter("*", web.BeforeRouter, middleware.AuthMiddleware())
 	//web.ErrorHandler("*", exception.ControllerAdvice())
@@ -31,7 +32,7 @@ func main() {
 	go func() {
 		//内存数据预热预加载
 		logger.Info("开始预加载数据")
-		
+
 	}()
 	logger.Info("初始化成功")
 	web.Run()

+ 18 - 0
models/eta/chart_permission_search_key_word_mapping.go

@@ -0,0 +1,18 @@
+package eta
+
+import "eta_mini_ht_api/models"
+
+// ChartPermissionSearchKeyWordMapping 表示 chart_permission_search_key_word_mapping 表的结构
+type ChartPermissionSearchKeyWordMapping struct {
+	ChartPermissionID int `gorm:"column:chart_permission_id"` // chart_permission_id 字段
+	ClassifyID        int `gorm:"column:classify_id"`         // classify_id 字段
+}
+
+func GetClassifyIdsByPermissionIds(permissionIds []int) (classifyIds []int, err error) {
+	db := models.ETA()
+	err = db.Model(&ChartPermissionSearchKeyWordMapping{}).Select("DISTINCT classify_id").Where("chart_permission_id in ?", permissionIds).Scan(&classifyIds).Error
+	return
+}
+func (c *ChartPermissionSearchKeyWordMapping) TableName() string {
+	return "chart_permission_search_key_word_mapping"
+}

+ 5 - 0
models/eta/eta_permission.go

@@ -36,6 +36,11 @@ func GetFirstPermissionsByClassifyID(classifyID int) (chartPermissionList []Char
 	err = doSql(sql, &chartPermissionList, classifyID)
 	return
 }
+func GetFirstPermissionsByIds(ids []int) (chartPermissionList []ChartPermission, err error) {
+	sql := "select chart_permission_id, permission_name where chart_permission_id in (select parent_id from chart_permission WHERE chart_permission_id in ?)"
+	err = doSql(sql, &chartPermissionList, ids)
+	return
+}
 func doSql(sql string, result interface{}, values ...interface{}) (err error) {
 	db := models.ETA()
 	err = db.Raw(sql, values...).Find(result).Error

+ 6 - 0
models/eta/eta_report.go

@@ -80,6 +80,12 @@ func GetReportClassifyById(id int) (classifyId int, err error) {
 		Where("id =?", id).Scan(&classifyId).Error
 	return
 }
+
+func GetETAReportIdsByClassifyIds(classifyIds []int) (reportIds []int, err error) {
+	db := models.ETA()
+	err = db.Model(&ETAReport{}).Select("DISTINCT id").Where("COALESCE(NULLIF(classify_id_third,0),NULLIF(classify_id_second,0),classify_id_first) in (?)", classifyIds).Scan(&reportIds).Error
+	return
+}
 func setClassifyIdValue(report *ETAReport) {
 	if report.ClassifyIDThird > 0 {
 		report.ClassifyID = report.ClassifyIDThird

+ 51 - 0
models/media/media.go

@@ -0,0 +1,51 @@
+package media
+
+import (
+	"errors"
+	logger "eta_mini_ht_api/common/component/log"
+	"eta_mini_ht_api/models"
+	"time"
+)
+
+const (
+	CommonColumns = "id,media_type,src,media_name,source_type,media_play_seconds,permission_ids"
+)
+
+type Medias struct {
+	ID                   int       `gorm:"primary_key;auto_increment;column:id"`
+	AuthorId             int       `gorm:"column:author_id"`
+	AuthorName           string    `gorm:"column:author_name"`
+	MediaType            string    `gorm:"type:enum('video','audio');column:media_type"`
+	Src                  string    `gorm:"type:varchar(255);column:src"`
+	MediaName            string    `gorm:"type:varchar(100);column:media_name"`
+	SourceType           string    `gorm:"type:varchar(255);column:source_type"`
+	MediaPlaySeconds     int       `gorm:"type:int(20);column:media_play_seconds"`
+	PermissionIDs        string    `gorm:"type:varchar(255);column:permission_ids"`
+	ReversePermissionIDS string    `gorm:"column:reverse_permission_ids"`
+	CreatedTime          time.Time `gorm:"type:timestamp;column:created_time"`
+	UpdatedTime          time.Time `gorm:"type:timestamp;column:updated_time"`
+}
+
+func GetCountByMediaType(mediaType string) (count int64) {
+	db := models.Main()
+	err := db.Model(&Medias{}).Select("Max(id) count").Where("media_type = ?", mediaType).Scan(&count).Error
+	if err != nil {
+		return 0
+	}
+	return
+}
+
+func GetMediaPage(latestId int64, limit int, offset int, mediaType string) (mediaList []Medias, err error) {
+	if latestId < 0 {
+		err = errors.New("非法的id参数")
+		logger.Error("非法的id参数:%d", latestId)
+		return
+	}
+	if limit <= 0 {
+		err = errors.New("非法的limit参数")
+		logger.Error("非法的limit参数:%d", limit)
+	}
+	db := models.Main()
+	err = db.Select(CommonColumns).Where("media_type= ? and id<= ?", mediaType, latestId).Order("created_time desc").Limit(limit).Offset(offset).Find(&mediaList).Error
+	return
+}

+ 37 - 6
models/report/report.go

@@ -3,6 +3,7 @@ package report
 import (
 	"errors"
 	logger "eta_mini_ht_api/common/component/log"
+	"eta_mini_ht_api/common/utils/date"
 	"eta_mini_ht_api/models"
 	"fmt"
 	"gorm.io/gorm"
@@ -20,7 +21,7 @@ const (
 	StatusDone    ReportStatus = "DONE"
 
 	MaxBatchNum   = 1000
-	CommonColumns = "id,org_id,author,abstract,title,source,published_time"
+	CommonColumns = "id,org_id,author,abstract,title,source,cover_src,published_time"
 )
 
 type Report struct {
@@ -30,6 +31,7 @@ type Report struct {
 	Title         string       `gorm:"column:title;comment:'标题'" json:"title"`
 	Abstract      string       `gorm:"column:abstract;comment:'摘要'" json:"abstract"`
 	Author        string       `gorm:"column:author;comment:'作者'" json:"author"`
+	CoverSrc      string       `gorm:"column:cover_src;comment:'封面图片'" json:"cover_src"`
 	Status        ReportStatus `gorm:"column:status;comment:'报告状态 init:初始化 pending:同步中 done:完成同步'" json:"status"`
 	PublishedTime string       `gorm:"column:published_time;comment:'发布时间'" json:"published_time"`
 	CreatedTime   time.Time    `gorm:"column:created_time;comment:'创建时间'" json:"created_time"`
@@ -75,9 +77,15 @@ func DoSql(sql string, result interface{}, values ...interface{}) (err error) {
 	return
 }
 
-func GetListOrderByCondition(column string, limit int, order models.Order) (reports []Report, err error) {
+func GetListOrderByCondition(week bool, column string, limit int, order models.Order) (reports []Report, err error) {
 	db := models.Main()
-	err = db.Select(CommonColumns).Order(fmt.Sprintf("%s %s", column, order)).Limit(limit).Find(&reports).Error
+	if week {
+		end := time.Now()
+		begin := date.GetBeginOfTheWeek(end, time.Monday)
+		err = db.Select(CommonColumns).Where("DATE(published_time) BETWEEN ? AND ?", begin, end).Order(fmt.Sprintf("%s %s", column, order)).Limit(limit).Find(&reports).Error
+	} else {
+		err = db.Select(CommonColumns).Order(fmt.Sprintf("%s %s", column, order)).Limit(limit).Find(&reports).Error
+	}
 	if err != nil {
 		logger.Error("查询报告列表失败:%v", err)
 	}
@@ -102,7 +110,15 @@ func GetListByCondition[T any](column string, values []T) (reports []Report, err
 	}
 	return
 }
-
+func GetMaxIdByPermissionIds(orgIds []int) (maxId int64) {
+	db := models.Main()
+	err := db.Model(&Report{}).Select("MAX(id) id").Where("org_id in ?", orgIds).Scan(&maxId).Error
+	if err != nil {
+		logger.Error("获取报告最大ID失败:%v", err)
+		return 0
+	}
+	return
+}
 func GetTotalPageCount() (total int64) {
 	db := models.Main()
 	err := db.Model(&Report{}).Count(&total).Error
@@ -123,8 +139,23 @@ func GetReportPage(latestId int64, limit int, offset int) (list []Report, err er
 	}
 	db := models.Main()
 	err = db.Select(CommonColumns).Where("id<= ?", latestId).Order("published_time desc").Limit(limit).Offset(offset).Find(&list).Error
-	if err != nil {
-		logger.Error("分页查询报告列表失败:%v", err)
+	return
+}
+
+func GetReportPageByOrgIds(latestId int64, limit int, offset int, orgIds []int) (list []Report, err error) {
+	if len(orgIds) == 0 {
+		return GetReportPage(latestId, limit, offset)
 	}
+	if latestId < 0 {
+		err = errors.New("非法的id参数")
+		logger.Error("非法的id参数:%d", latestId)
+		return
+	}
+	if limit <= 0 {
+		err = errors.New("非法的limit参数")
+		logger.Error("非法的limit参数:%d", limit)
+	}
+	db := models.Main()
+	err = db.Select(CommonColumns).Where("id<= ? and org_id in ?", latestId, orgIds).Order("published_time desc").Limit(limit).Offset(offset).Find(&list).Error
 	return
 }

+ 36 - 16
routers/commentsRouter.go

@@ -7,13 +7,25 @@ import (
 
 func init() {
 
-    beego.GlobalControllerRouter["eta_mini_ht_api/controllers/report:ReportController"] = append(beego.GlobalControllerRouter["eta_mini_ht_api/controllers/report:ReportController"],
+    beego.GlobalControllerRouter["eta_mini_ht_api/controllers/media:MediaController"] = append(beego.GlobalControllerRouter["eta_mini_ht_api/controllers/media:MediaController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(
+				param.New("mediaType"),
+			),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_mini_ht_api/controllers/media:MediaController"] = append(beego.GlobalControllerRouter["eta_mini_ht_api/controllers/media:MediaController"],
         beego.ControllerComments{
-            Method: "AnalystReportList",
-            Router: `/AnalystReportList`,
+            Method: "Search",
+            Router: `/search`,
             AllowHTTPMethods: []string{"get"},
             MethodParams: param.Make(
-				param.New("authorId"),
+				param.New("mediaType"),
+				param.New("key"),
 			),
             Filters: nil,
             Params: nil})
@@ -32,7 +44,10 @@ func init() {
             Method: "HotRanked",
             Router: `/hotRankedList`,
             AllowHTTPMethods: []string{"get"},
-            MethodParams: param.Make(),
+            MethodParams: param.Make(
+				param.New("permissionIds"),
+				param.New("limit"),
+			),
             Filters: nil,
             Params: nil})
 
@@ -41,7 +56,9 @@ func init() {
             Method: "List",
             Router: `/list`,
             AllowHTTPMethods: []string{"get"},
-            MethodParams: param.Make(),
+            MethodParams: param.Make(
+				param.New("permissionIds"),
+			),
             Filters: nil,
             Params: nil})
 
@@ -59,7 +76,10 @@ func init() {
             Method: "PublishRanked",
             Router: `/publishRankedList`,
             AllowHTTPMethods: []string{"get"},
-            MethodParams: param.Make(),
+            MethodParams: param.Make(
+				param.New("limit"),
+				param.New("week"),
+			),
             Filters: nil,
             Params: nil})
 
@@ -103,6 +123,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_mini_ht_api/controllers/user:AuthController"] = append(beego.GlobalControllerRouter["eta_mini_ht_api/controllers/user:AuthController"],
+        beego.ControllerComments{
+            Method: "Notice",
+            Router: `/notice`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_mini_ht_api/controllers/user:AuthController"] = append(beego.GlobalControllerRouter["eta_mini_ht_api/controllers/user:AuthController"],
         beego.ControllerComments{
             Method: "RefreshToken",
@@ -123,15 +152,6 @@ func init() {
             Filters: nil,
             Params: nil})
 
-    beego.GlobalControllerRouter["eta_mini_ht_api/controllers/user:AuthController"] = append(beego.GlobalControllerRouter["eta_mini_ht_api/controllers/user:AuthController"],
-        beego.ControllerComments{
-            Method: "Test",
-            Router: `/test`,
-            AllowHTTPMethods: []string{"get"},
-            MethodParams: param.Make(),
-            Filters: nil,
-            Params: nil})
-
     beego.GlobalControllerRouter["eta_mini_ht_api/controllers/user:AuthController"] = append(beego.GlobalControllerRouter["eta_mini_ht_api/controllers/user:AuthController"],
         beego.ControllerComments{
             Method: "WXAppid",

+ 6 - 0
routers/router.go

@@ -1,6 +1,7 @@
 package routers
 
 import (
+	"eta_mini_ht_api/controllers/media"
 	"eta_mini_ht_api/controllers/report"
 	"eta_mini_ht_api/controllers/user"
 	beego "github.com/beego/beego/v2/server/web"
@@ -23,6 +24,11 @@ func init() {
 				&report.ReportController{},
 			),
 		),
+		beego.NSNamespace("/media",
+			beego.NSInclude(
+				&media.MediaController{},
+			),
+		),
 	)
 	beego.AddNamespace(ns)
 }

+ 83 - 0
service/media/media_service.go

@@ -0,0 +1,83 @@
+package media
+
+import (
+	logger "eta_mini_ht_api/common/component/log"
+	"eta_mini_ht_api/common/exception"
+	"eta_mini_ht_api/common/utils/page"
+	stringUtils "eta_mini_ht_api/common/utils/string"
+	mediaService "eta_mini_ht_api/domian/media"
+	"strings"
+	"sync"
+)
+
+func GetTotalPageCount(mediaType string) (count int64) {
+	if mediaType == "" {
+		return 0
+	}
+	return mediaService.GetTotalPageCount(mediaType)
+}
+func SearchMaxMediaId(mediaType string) (id int64) {
+	return mediaService.SearchMaxMediaId(mediaType)
+}
+func GetMediaPage(mediaType string, pageInfo page.PageInfo) (list []mediaService.MediaDTO, err error) {
+	list, err = mediaService.GetMediaPage(mediaType, pageInfo)
+	//并发获取媒体的标签
+	var wg sync.WaitGroup
+	wg.Add(len(list))
+	for i := 0; i < len(list); i++ {
+		go func(media *mediaService.MediaDTO) {
+			defer wg.Done()
+
+			idStr := strings.Split(media.PermissionIDs, ",")
+			var ids []int
+			ids, err = stringUtils.StringToIntSlice(idStr)
+			if err != nil {
+				logger.Error("品种名称列表转换失败:%v", err)
+			}
+			media.PermissionNames = getMediaPermissionNames(ids)
+		}(&list[i])
+	}
+	wg.Wait()
+	if err != nil {
+		err = exception.New(exception.QueryReportPageFailed)
+	}
+	return
+}
+func getMediaPermissionNames(id []int) (labels []string) {
+	permissions, err := mediaService.GetPermissionsByIds(id)
+	if err != nil {
+		logger.Error("查询品种名称列表失败:%v", err)
+		labels = []string{}
+		return
+	}
+	for _, permission := range permissions {
+		labels = append(labels, permission.Name)
+	}
+	return
+}
+
+// stringToIntSlice 将一个包含数字字符串的切片转换为整数切片
+
+func SearchMediaList(mediaType string, key string, pageInfo page.PageInfo) (medias []mediaService.MediaDTO, err error) {
+	offset := page.StartIndex(pageInfo.Current, pageInfo.PageSize)
+	medias, err = mediaService.SearchMediaList(mediaType, key, offset, pageInfo.PageSize, pageInfo.LatestId)
+	var wg sync.WaitGroup
+	wg.Add(len(medias))
+	for i := 0; i < len(medias); i++ {
+		go func(media *mediaService.MediaDTO) {
+			defer wg.Done()
+			idStr := strings.Split(media.PermissionIDs, ",")
+			var ids []int
+			ids, err = stringUtils.StringToIntSlice(idStr)
+			if err != nil {
+				logger.Error("获取品种列表失败:%v", err)
+			}
+			media.PermissionNames = getMediaPermissionNames(ids)
+		}(&medias[i])
+	}
+	wg.Wait()
+	if err != nil {
+		err = exception.New(exception.SearchReportPageFailed)
+	}
+	return
+}

+ 67 - 25
service/report/report_service.go

@@ -17,21 +17,25 @@ const (
 )
 
 type PublishRankedReport struct {
-	Id              int
-	OrgId           int
-	Title           string
-	Abstract        string
-	PermissionNames interface{}
-	PublishedTime   string
+	Id              int         `json:"reportId"`
+	OrgId           int         `json:"orgId"`
+	Title           string      `json:"title"`
+	Abstract        string      `json:"abstract"`
+	PermissionNames interface{} `json:"permissionNames,omitempty"`
+	PublishedTime   string      `json:"publishedTime"`
+	CoverSrc        string      `json:"coverSrc"`
 }
 
 type HotRankedReport struct {
-	Id              int
-	OrgId           int
-	Count           int
-	Title           string
-	PublishedTime   string
-	PermissionNames interface{}
+	Id              int            `json:"reportId"`
+	OrgId           int            `json:"orgId"`
+	Abstract        string         `json:"abstract"`
+	Count           int            `json:"count"`
+	Title           string         `json:"title"`
+	PublishedTime   string         `json:"publishedTime"`
+	Permissions     map[int]string `json:"-"`
+	PermissionNames interface{}    `json:"permissionNames,omitempty"`
+	CoverSrc        string         `json:"coverSrc"`
 }
 
 type PermissionNode struct {
@@ -86,12 +90,19 @@ func GetReportById(reportId int) (report reportService.ReportDTO, err error) {
 func getETAReportDetail(report *reportService.ReportDTO) (etaReport reportService.ETAReportDTO, err error) {
 	return reportService.GetETAReport(report.OrgId)
 }
-func getHTReportDetail(report *reportService.ReportDTO) (err error) {
-	return
-}
+
 func GetTotalPageCount() (total int64) {
 	return reportService.GetTotalPageCount()
 }
+
+func GetTotalPageCountByPermissionIds(permissionIds []int) (total int64, latestId int64, ids []int) {
+	if len(permissionIds) == 0 {
+		total = GetTotalPageCount()
+		latestId = total
+		return total, latestId, []int{}
+	}
+	return reportService.GetTotalPageCountByPermissionIds(permissionIds)
+}
 func SearchReportList(key string, pageInfo page.PageInfo) (reports []reportService.ReportDTO, err error) {
 	offset := page.StartIndex(pageInfo.Current, pageInfo.PageSize)
 	reports, err = reportService.SearchReportList(key, offset, pageInfo.PageSize, pageInfo.LatestId)
@@ -115,7 +126,24 @@ func SearchMaxReportId() (id int64) {
 }
 
 // GetReportPage 分页获取报告列表
-func GetReportPage(pageInfo page.PageInfo) (list []reportService.ReportDTO, err error) {
+func GetReportPage(pageInfo page.PageInfo, orgIds []int) (list []reportService.ReportDTO, err error) {
+	list, err = reportService.GetReportPageByOrgIds(pageInfo, orgIds)
+	//并发获取研报的标签
+	var wg sync.WaitGroup
+	wg.Add(len(list))
+	for i := 0; i < len(list); i++ {
+		go func(report *reportService.ReportDTO) {
+			defer wg.Done()
+			report.PermissionNames = getReportPermissionNames(report.OrgId, report.Source)
+		}(&list[i])
+	}
+	wg.Wait()
+	if err != nil {
+		err = exception.New(exception.QueryReportPageFailed)
+	}
+	return
+}
+func GetReportPageByAlayyst(pageInfo page.PageInfo) (list []reportService.ReportDTO, err error) {
 	list, err = reportService.GetReportPage(pageInfo)
 	//并发获取研报的标签
 	var wg sync.WaitGroup
@@ -157,15 +185,21 @@ func GetRandedReportByWeeklyHot(limit int) (reports []HotRankedReport, err error
 		for i := 0; i < len(dtoList); i++ {
 			go func(report *reportService.ReportDTO) {
 				defer wg.Done()
-				report.PermissionNames = getReportPermissionNames(report.OrgId, report.Source)
+				report.Permissions = getReportPermissionsMap(report.OrgId, report.Source)
+				var label []string
+				for _, permission := range report.Permissions {
+					label = append(label, permission)
+				}
+				report.PermissionNames = label
 			}(&dtoList[i])
 		}
 		wg.Wait()
 		reports = make([]HotRankedReport, len(ids))
 		for i := 0; i < len(dtoList); i++ {
 			report := convertToHotRankedReport(dtoList[i])
-			for j := 0; j < len(ids); j++ {
-				if ids[j] == report.Id {
+			for j := 0; j < len(hotReports); j++ {
+				if hotReports[j].ReportId == report.Id {
+					report.Count = hotReports[j].Count
 					reports[j] = report
 					break
 				}
@@ -177,8 +211,8 @@ func GetRandedReportByWeeklyHot(limit int) (reports []HotRankedReport, err error
 	return
 }
 
-func GetRandedReportByPublishTime() (reports []PublishRankedReport, err error) {
-	dtoList, err := reportService.GetListOrderByCondition("published_time", 3, reportService.DESC)
+func GetRandedReportByPublishTimeWeekly(limit int, week bool) (reports []PublishRankedReport, err error) {
+	dtoList, err := reportService.GetListOrderByConditionWeekly(week, "published_time", limit, reportService.DESC)
 	if err != nil {
 		logger.Error("获取最新发布的研报列表失败:%v", err)
 		err = exception.New(exception.GetPublishedRandListFailed)
@@ -206,6 +240,14 @@ func getReportPermissionNames(id int, source string) (labels []string) {
 	return
 }
 
+func getReportPermissionsMap(id int, source string) (permissionMap map[int]string) {
+	permissionMap = make(map[int]string)
+	permissions := reportService.GetReportPermissionsById(id, source)
+	for _, permission := range permissions {
+		permissionMap[permission.ID] = permission.Name
+	}
+	return
+}
 func GetPermissionList() (root *PermissionNode, err error) {
 	list, err := reportService.GetPermissionList()
 	if err != nil {
@@ -240,9 +282,12 @@ func convertToHotRankedReport(dto reportService.ReportDTO) (report HotRankedRepo
 	report = HotRankedReport{
 		Id:              dto.ReportID,
 		OrgId:           dto.OrgId,
+		Abstract:        dto.Abstract,
 		PublishedTime:   dto.PublishedTime,
 		Title:           dto.Title,
+		Permissions:     dto.Permissions,
 		PermissionNames: dto.PermissionNames,
+		CoverSrc:        dto.CoverSrc,
 	}
 	return
 }
@@ -256,11 +301,8 @@ func convertToPublishRankedReportList(dtoList []reportService.ReportDTO) (report
 			Abstract:        dto.Abstract,
 			Title:           dto.Title,
 			PermissionNames: dto.PermissionNames,
+			CoverSrc:        dto.CoverSrc,
 		}
-		//publishDate, err := time.Parse(time.DateTime, report.PublishedTime)
-		//if err == nil {
-		//	report.PublishedTime = publishDate.Format(time.DateOnly)
-		//}
 		reports = append(reports, report)
 	}
 	return

+ 1 - 1
task/eta/author/eta_author_task.go

@@ -55,6 +55,6 @@ func convert(author eta.ReportAuthor) financial_analyst.FinancialAnalystDTO {
 	}
 }
 func init() {
-	authorTask := base.NewTask(taskName, cron, new(AuthorTask), base.DEV)
+	authorTask := base.NewTask(taskName, cron, new(AuthorTask), base.PROD)
 	base.RegisterTask(&authorTask)
 }

+ 2 - 2
task/eta/report/eta_report_task.go

@@ -11,7 +11,7 @@ import (
 
 var (
 	taskName base.TaskType = "ETAReportSyncTask"
-	cron                   = "0/60 * * * * *"
+	cron                   = "0/10 * * * * *"
 )
 
 // Execute Task ETA取研报的数据
@@ -44,6 +44,6 @@ type ReportTask struct {
 }
 
 func init() {
-	reportTask := base.NewTask(taskName, cron, new(ReportTask), base.PROD)
+	reportTask := base.NewTask(taskName, cron, new(ReportTask), base.DEV)
 	base.RegisterTask(&reportTask)
 }

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است