package user import ( "errors" "eta/eta_mini_ht_api/common/component/cache" logger "eta/eta_mini_ht_api/common/component/log" "eta/eta_mini_ht_api/common/exception" "eta/eta_mini_ht_api/common/utils/page" "eta/eta_mini_ht_api/controllers" permissionService "eta/eta_mini_ht_api/domian/config" reportDomian "eta/eta_mini_ht_api/domian/report" chartService "eta/eta_mini_ht_api/service/media" "eta/eta_mini_ht_api/service/report" "eta/eta_mini_ht_api/service/user" userService "eta/eta_mini_ht_api/service/user" "gorm.io/gorm" "sync" ) // BookMarkController Operations about bookmark type BookMarkController struct { controllers.ListController redis *cache.RedisCache } const ( Chart = "chart" Report = "report" ) func (bk *BookMarkController) Prepare() { bk.ListController.Prepare() bk.redis = cache.GetInstance() } type BookMarkReq struct { SourceType string `json:"sourceType"` SourceId int `json:"sourceId"` ChartImage string `json:"chartImage"` ChartInfoId int `json:"chartInfoId"` ChartName string `json:"chartName"` UniqueCode string `json:"uniqueCode"` } // BookMark 收藏 // @Summary 收藏 // @Description 收藏 // @Success 200 {object} controllers.BaseResponse // @router /bookMark [post] func (bk *BookMarkController) BookMark() { controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) { result = bk.InitWrapData("收藏失败") bookMark := new(BookMarkReq) bk.GetPostParams(bookMark) var userInfo user.User userInfo = bk.Data["user"].(user.User) if bookMark.SourceType == "" { bk.FailedResult("收藏失败", result) err = exception.New(exception.IllegalSourceType) return } if bookMark.SourceId == 0 { bk.FailedResult("收藏失败", result) err = exception.New(exception.IllegalSourceId) return } err = userService.BookMark(userInfo.Id, bookMark.SourceId, bookMark.SourceType) if err != nil { err = exception.NewWithException(exception.FeedBackError, err.Error()) bk.FailedResult("收藏失败", result) return } //将图表加入es if bookMark.SourceType == Chart { chartService.AddChartToEs(chartService.ChartInfo{ ChartImage: bookMark.ChartImage, ChartInfoId: bookMark.ChartInfoId, ChartName: bookMark.ChartName, UniqueCode: bookMark.UniqueCode, }) } bk.SuccessResult("收藏成功", nil, result) return }) } // UnBookMark 取消收藏 // @Summary 取消收藏 // @Description 取消收藏 // @Success 200 {object} controllers.BaseResponse // @router /unBookMark [post] func (bk *BookMarkController) UnBookMark() { controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) { result = bk.InitWrapData("取消收藏失败") bookMark := new(BookMarkReq) bk.GetPostParams(bookMark) var userInfo user.User userInfo = bk.Data["user"].(user.User) if bookMark.SourceType == "" { bk.FailedResult("取消收藏失败", result) err = exception.New(exception.IllegalSourceType) return } if bookMark.SourceId == 0 { bk.FailedResult("取消收藏失败", result) err = exception.New(exception.IllegalSourceId) return } err = userService.UnBookMark(userInfo.Id, bookMark.SourceId, bookMark.SourceType) if err != nil { err = exception.NewWithException(exception.FeedBackError, err.Error()) bk.FailedResult("取消收藏失败", result) return } bk.SuccessResult("收藏成功", nil, result) return }) } type CheckBookMarkResp struct { IsBookMarked bool `json:"isBookMarked"` } // CheckBookMark 取消收藏 // @Summary 取消收藏 // @Description 取消收藏 // @Success 200 {object} controllers.BaseResponse // @router /checkBookMark [post] func (bk *BookMarkController) CheckBookMark() { controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) { result = bk.InitWrapData("取消收藏失败") bookMark := new(BookMarkReq) bk.GetPostParams(bookMark) var userInfo user.User userInfo = bk.Data["user"].(user.User) if bookMark.SourceType == "" { bk.FailedResult("获取是否收藏失败", result) err = exception.New(exception.IllegalSourceType) return } if bookMark.SourceId == 0 { bk.FailedResult("获取是否收藏失败", result) err = exception.New(exception.IllegalSourceId) return } isBookMarked, err := userService.CheckBookMarkStatus(userInfo.Id, bookMark.SourceId, bookMark.SourceType) if err != nil { err = exception.NewWithException(exception.FeedBackError, err.Error()) bk.FailedResult("获取是否收藏失败", result) return } bk.SuccessResult("获取是否收藏成功", &CheckBookMarkResp{ IsBookMarked: isBookMarked, }, result) return }) } // BookMarkSearch 搜索收藏列表 // @Description 搜索报告列表 // @Success 200 {object} // @router /bookMarkSearch [get] func (bk *BookMarkController) BookMarkSearch(key string) { controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) { result = bk.InitWrapData("分页搜索报告列表失败") if key == "" { err = exception.New(exception.SearchKeyEmptyError) bk.FailedResult("分页搜索报告列表失败", result) return } userInfo := bk.Data["user"].(user.User) pageRes := page.Page{ Current: bk.PageInfo.Current, PageSize: bk.PageInfo.PageSize, } //获取当前可以被搜索的报告原始ID //先要限制查询的id范围 var reportIds []int var mappingRiskLevel string var userRiskStatus string pageRes.Total, pageRes.LatestId, reportIds, _, mappingRiskLevel, userRiskStatus, err = report.RangeSearch(key, true, userInfo.Id) if err != nil { logger.Error("获取报告原始ID列表失败:%v", err) bk.FailedResult("分页搜索报告列表失败", result) return } if len(reportIds) == 0 { reports := new(page.PageResult) reports.Data = []reportDomian.ReportDTO{} reports.Page = pageRes logger.Info("没有可以查询的报告列表") bk.SuccessResult("分页搜索报告列表成功", reports, result) return } if bk.PageInfo.LatestId == 0 { //pageRes.Total, pageRes.LatestId = report.SearchMaxReportId(key) bk.PageInfo.LatestId = pageRes.LatestId bk.PageInfo.Total = pageRes.Total } else { pageRes.LatestId = bk.PageInfo.LatestId pageRes.Total = bk.PageInfo.Total } pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize) list := make([]reportDomian.ReportDTO, 0) if pageRes.LatestId > 0 { list, err = report.SearchReportList(key, reportIds, bk.PageInfo, true, userInfo.Id, mappingRiskLevel, userRiskStatus) if err != nil { bk.FailedResult("分页搜索报告列表失败", result) return } } reports := new(page.PageResult) reports.Data = list reports.Page = pageRes bk.SuccessResult("分页搜索报告列表成功", reports, result) return }) } type BookMarkListReq struct { SourceType string `json:"source_type"` } // SearchBookMark 获取收藏列表 // @Description 获取收藏列表 // @Success 200 {object} // @router /searchBookMark [get] func (bk *BookMarkController) SearchBookMark(sourceType string, key string) { controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) { result = bk.InitWrapData("分页搜索收藏列表失败") pageRes := page.Page{ Current: bk.PageInfo.Current, PageSize: bk.PageInfo.PageSize, } if sourceType == "" || (sourceType != Report && sourceType != Chart) { err = exception.New(exception.IllegalSourceType) bk.FailedResult("分页搜索收藏列表失败", result) return } userInfo := bk.Data["user"].(user.User) var sourceIds []int pageRes.Total, sourceIds, err = user.GetTotalBookMarkPageBySourceType(userInfo.Id, sourceType) //隐藏品种信息未设置风险等级的报告 if sourceType == Report { pageRes.Total, sourceIds, err = report.FilterReportIds(sourceIds) } if pageRes.Total == 0 { bookMarks := new(page.PageResult) bookMarks.Data = []interface{}{} bookMarks.Page = pageRes bk.SuccessResult("分页搜索收藏列表列表成功", bookMarks, result) return } pageRes.Total = bk.PageInfo.Total pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize) var bookMarkList []userService.BookMarkInterface bookMarkList, err = user.SearchBookMark(key, sourceType, sourceIds, bk.PageInfo, userInfo.Id) if err != nil { err = exception.New(exception.BookMarkListFailed) bk.FailedResult("分页搜索收藏列表失败", result) return } bookMarks := new(page.PageResult) bookMarks.Data = bookMarkList bookMarks.Page = pageRes bk.SuccessResult("分页搜索收藏列表成功", bookMarks, result) return }) } // BookMarkList 获取收藏列表 // @Description 获取收藏列表 // @Success 200 {object} // @router /bookMarkList [get] func (bk *BookMarkController) BookMarkList(sourceType string) { controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) { result = bk.InitWrapData("分页查询收藏列表失败") pageRes := page.Page{ Current: bk.PageInfo.Current, PageSize: bk.PageInfo.PageSize, } if sourceType == "" || (sourceType != Report && sourceType != Chart) { err = exception.New(exception.IllegalSourceType) bk.FailedResult("分页查询收藏列表失败", result) return } userInfo := bk.Data["user"].(user.User) var sourceIds []int pageRes.Total, sourceIds, err = user.GetTotalBookMarkPageBySourceType(userInfo.Id, sourceType) //隐藏品种信息未设置风险等级的报告 if sourceType == Report { pageRes.Total, sourceIds, err = report.FilterReportIds(sourceIds) } if pageRes.Total == 0 { bookMarks := new(page.PageResult) bookMarks.Data = []interface{}{} bookMarks.Page = pageRes bk.SuccessResult("分页查询收藏列表成功", bookMarks, result) return } pageRes.Total = bk.PageInfo.Total pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize) switch sourceType { case Report: var list []userService.BookMarkReport list, err = getReportList(bk.PageInfo, userInfo.Id, sourceIds) if err != nil { err = exception.NewWithException(exception.GetBookMarkListFailed, err.Error()) bk.FailedResult("分页查询收藏列表失败", result) return } bookMarks := new(page.PageResult) bookMarks.Data = list bookMarks.Page = pageRes bk.SuccessResult("分页查询收藏列表成功", bookMarks, result) return case Chart: var list []userService.BookMarkChart list, err = getChartList(bk.PageInfo, userInfo.Id) if err != nil { err = exception.NewWithException(exception.GetBookMarkListFailed, err.Error()) bk.FailedResult("分页查询收藏列表失败", result) return } bookMarks := new(page.PageResult) bookMarks.Data = list bookMarks.Page = pageRes bk.SuccessResult("分页查询收藏列表成功", bookMarks, result) return default: err = exception.New(exception.IllegalSourceType) bk.FailedResult("分页查询收藏列表失败", result) return } }) } func getReportList(info page.PageInfo, templateUserId int, sourceIds []int) (list []userService.BookMarkReport, err error) { sourceIds, err = userService.GetBookMarkPageRangeBySourceType(templateUserId, info, Report, sourceIds) if err != nil { return } userProfile, userErr := user.GetUserProfile(templateUserId) if userErr != nil { if errors.Is(userErr, gorm.ErrRecordNotFound) { err = exception.New(exception.TemplateUserNotFound) } else { err = exception.New(exception.TemplateUserFoundFailed) } logger.Error("获取临时客户信息失败:%v", err) return } var mappingRiskLevel, userRiskStatus string userRiskStatus = userProfile.RiskLevelStatus if userProfile.RiskLevel != "" { var mapping permissionService.CustomerProductRiskMappingDTO mapping, err = permissionService.GetRiskMappingByCustomerRiskLevel(userProfile.RiskLevel) if err != nil { logger.Error("查询产品风险等级映射失败:%v", err) return } mappingRiskLevel = mapping.ProductRiskLevel } reports, err := report.GetReportListById(templateUserId, sourceIds, mappingRiskLevel, userRiskStatus) if err != nil { return nil, err } list = make([]userService.BookMarkReport, len(sourceIds)) // 并发获取数据 for index, sourceId := range sourceIds { for _, reportDTO := range reports { if reportDTO.ReportID == sourceId { reportInfo := userService.ConvertToBookMarkReport(reportDTO) list[index] = reportInfo } } } return } func getChartList(info page.PageInfo, templateUserId int) (list []userService.BookMarkChart, err error) { sourceIds, err := userService.GetBookMarkPageBySourceType(templateUserId, info, Chart) if err != nil { return } // 创建一个切片来存储结果,长度与 sourceIds 相同 list = make([]userService.BookMarkChart, len(sourceIds)) // 使用 WaitGroup 来等待所有 goroutine 完成 var wg sync.WaitGroup wg.Add(len(sourceIds)) // 使用 Mutex 来保护对 list 的写操作 var mu sync.Mutex // 并发获取数据 for index, sourceId := range sourceIds { go func(index int, id int) { defer wg.Done() var data chartService.ChartInfo data, err = chartService.GetChartById(id) chartInfo := userService.ConvertToBookMarkChart(data) if err != nil { logger.Error("获取数据失败: %v", err) } // 使用 Mutex 保护对 list 的写操作 mu.Lock() list[index] = chartInfo mu.Unlock() }(index, sourceId) } // 等待所有 goroutine 完成 wg.Wait() return }