bookmark_controller.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. package user
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta/eta_mini_ht_api/common/component/cache"
  6. logger "eta/eta_mini_ht_api/common/component/log"
  7. "eta/eta_mini_ht_api/common/exception"
  8. "eta/eta_mini_ht_api/common/utils/page"
  9. "eta/eta_mini_ht_api/controllers"
  10. permissionService "eta/eta_mini_ht_api/domian/config"
  11. reportDomian "eta/eta_mini_ht_api/domian/report"
  12. chartService "eta/eta_mini_ht_api/service/media"
  13. "eta/eta_mini_ht_api/service/report"
  14. "eta/eta_mini_ht_api/service/user"
  15. userService "eta/eta_mini_ht_api/service/user"
  16. "gorm.io/gorm"
  17. "sync"
  18. )
  19. // BookMarkController Operations about bookmark
  20. type BookMarkController struct {
  21. controllers.ListController
  22. redis *cache.RedisCache
  23. }
  24. const (
  25. Chart = "chart"
  26. Report = "report"
  27. )
  28. func (bk *BookMarkController) Prepare() {
  29. bk.ListController.Prepare()
  30. bk.redis = cache.GetInstance()
  31. }
  32. type BookMarkReq struct {
  33. SourceType string `json:"sourceType"`
  34. SourceId int `json:"sourceId"`
  35. ChartImage string `json:"chartImage"`
  36. ChartInfoId int `json:"chartInfoId"`
  37. ChartName string `json:"chartName"`
  38. UniqueCode string `json:"uniqueCode"`
  39. }
  40. // BookMark 收藏
  41. // @Summary 收藏
  42. // @Description 收藏
  43. // @Success 200 {object} controllers.BaseResponse
  44. // @router /bookMark [post]
  45. func (bk *BookMarkController) BookMark() {
  46. controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) {
  47. result = bk.InitWrapData("收藏失败")
  48. bookMark := new(BookMarkReq)
  49. bk.GetPostParams(bookMark)
  50. var userInfo user.User
  51. userInfo = bk.Data["user"].(user.User)
  52. if bookMark.SourceType == "" {
  53. bk.FailedResult("收藏失败", result)
  54. err = exception.New(exception.IllegalSourceType)
  55. return
  56. }
  57. if bookMark.SourceId == 0 {
  58. bk.FailedResult("收藏失败", result)
  59. err = exception.New(exception.IllegalSourceId)
  60. return
  61. }
  62. err = userService.BookMark(userInfo.Id, bookMark.SourceId, bookMark.SourceType)
  63. if err != nil {
  64. err = exception.NewWithException(exception.FeedBackError, err.Error())
  65. bk.FailedResult("收藏失败", result)
  66. return
  67. }
  68. //将图表加入es
  69. if bookMark.SourceType == Chart {
  70. chartService.AddChartToEs(chartService.ChartInfo{
  71. ChartImage: bookMark.ChartImage,
  72. ChartInfoId: bookMark.ChartInfoId,
  73. ChartName: bookMark.ChartName,
  74. UniqueCode: bookMark.UniqueCode,
  75. })
  76. }
  77. bk.SuccessResult("收藏成功", nil, result)
  78. return
  79. })
  80. }
  81. // UnBookMark 取消收藏
  82. // @Summary 取消收藏
  83. // @Description 取消收藏
  84. // @Success 200 {object} controllers.BaseResponse
  85. // @router /unBookMark [post]
  86. func (bk *BookMarkController) UnBookMark() {
  87. controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) {
  88. result = bk.InitWrapData("取消收藏失败")
  89. bookMark := new(BookMarkReq)
  90. bk.GetPostParams(bookMark)
  91. var userInfo user.User
  92. userInfo = bk.Data["user"].(user.User)
  93. if bookMark.SourceType == "" {
  94. bk.FailedResult("取消收藏失败", result)
  95. err = exception.New(exception.IllegalSourceType)
  96. return
  97. }
  98. if bookMark.SourceId == 0 {
  99. bk.FailedResult("取消收藏失败", result)
  100. err = exception.New(exception.IllegalSourceId)
  101. return
  102. }
  103. err = userService.UnBookMark(userInfo.Id, bookMark.SourceId, bookMark.SourceType)
  104. if err != nil {
  105. err = exception.NewWithException(exception.FeedBackError, err.Error())
  106. bk.FailedResult("取消收藏失败", result)
  107. return
  108. }
  109. bk.SuccessResult("收藏成功", nil, result)
  110. return
  111. })
  112. }
  113. type CheckBookMarkResp struct {
  114. IsBookMarked bool `json:"isBookMarked"`
  115. }
  116. // CheckBookMark 取消收藏
  117. // @Summary 取消收藏
  118. // @Description 取消收藏
  119. // @Success 200 {object} controllers.BaseResponse
  120. // @router /checkBookMark [post]
  121. func (bk *BookMarkController) CheckBookMark() {
  122. controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) {
  123. result = bk.InitWrapData("取消收藏失败")
  124. bookMark := new(BookMarkReq)
  125. bk.GetPostParams(bookMark)
  126. var userInfo user.User
  127. userInfo = bk.Data["user"].(user.User)
  128. if bookMark.SourceType == "" {
  129. bk.FailedResult("获取是否收藏失败", result)
  130. err = exception.New(exception.IllegalSourceType)
  131. return
  132. }
  133. if bookMark.SourceId == 0 {
  134. bk.FailedResult("获取是否收藏失败", result)
  135. err = exception.New(exception.IllegalSourceId)
  136. return
  137. }
  138. isBookMarked, err := userService.CheckBookMarkStatus(userInfo.Id, bookMark.SourceId, bookMark.SourceType)
  139. if err != nil {
  140. err = exception.NewWithException(exception.FeedBackError, err.Error())
  141. bk.FailedResult("获取是否收藏失败", result)
  142. return
  143. }
  144. bk.SuccessResult("获取是否收藏成功", &CheckBookMarkResp{
  145. IsBookMarked: isBookMarked,
  146. }, result)
  147. return
  148. })
  149. }
  150. // BookMarkSearch 搜索收藏列表
  151. // @Description 搜索报告列表
  152. // @Success 200 {object}
  153. // @router /bookMarkSearch [get]
  154. func (bk *BookMarkController) BookMarkSearch(key string) {
  155. controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) {
  156. result = bk.InitWrapData("分页搜索报告列表失败")
  157. if key == "" {
  158. err = exception.New(exception.SearchKeyEmptyError)
  159. bk.FailedResult("分页搜索报告列表失败", result)
  160. return
  161. }
  162. userInfo := bk.Data["user"].(user.User)
  163. pageRes := page.Page{
  164. Current: bk.PageInfo.Current,
  165. PageSize: bk.PageInfo.PageSize,
  166. }
  167. //获取当前可以被搜索的报告原始ID
  168. //先要限制查询的id范围
  169. var reportIds []int
  170. var mappingRiskLevel string
  171. var userRiskStatus string
  172. pageRes.Total, pageRes.LatestId, reportIds, _, mappingRiskLevel, userRiskStatus, err = report.RangeSearch(key, true, userInfo.Id)
  173. if err != nil {
  174. logger.Error("获取报告原始ID列表失败:%v", err)
  175. bk.FailedResult("分页搜索报告列表失败", result)
  176. return
  177. }
  178. if len(reportIds) == 0 {
  179. reports := new(page.PageResult)
  180. reports.Data = []reportDomian.ReportDTO{}
  181. reports.Page = pageRes
  182. logger.Info("没有可以查询的报告列表")
  183. bk.SuccessResult("分页搜索报告列表成功", reports, result)
  184. return
  185. }
  186. if bk.PageInfo.LatestId == 0 {
  187. //pageRes.Total, pageRes.LatestId = report.SearchMaxReportId(key)
  188. bk.PageInfo.LatestId = pageRes.LatestId
  189. bk.PageInfo.Total = pageRes.Total
  190. } else {
  191. pageRes.LatestId = bk.PageInfo.LatestId
  192. pageRes.Total = bk.PageInfo.Total
  193. }
  194. pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
  195. list := make([]reportDomian.ReportDTO, 0)
  196. if pageRes.LatestId > 0 {
  197. list, err = report.SearchReportList(key, reportIds, bk.PageInfo, true, userInfo.Id, mappingRiskLevel, userRiskStatus)
  198. if err != nil {
  199. bk.FailedResult("分页搜索报告列表失败", result)
  200. return
  201. }
  202. }
  203. reports := new(page.PageResult)
  204. reports.Data = list
  205. reports.Page = pageRes
  206. bk.SuccessResult("分页搜索报告列表成功", reports, result)
  207. return
  208. })
  209. }
  210. type BookMarkListReq struct {
  211. SourceType string `json:"source_type"`
  212. }
  213. type BookMarkChart struct {
  214. ChartName string `json:"chartName"`
  215. ChartImage string `json:"chartImage"`
  216. UniqueCode string `json:"uniqueCode"`
  217. ChartInfoId int `json:"chartInfoId"`
  218. }
  219. type BookMarkReport struct {
  220. Type string `json:"type"`
  221. ReportID int `json:"reportId"`
  222. OrgId int `json:"orgId"`
  223. Title string `json:"title"`
  224. Author string `json:"author"`
  225. AuthorInfo []reportDomian.Anthor `json:"authorInfo"`
  226. Source string `json:"source"`
  227. Abstract string `json:"abstract"`
  228. PublishedTime string `json:"publishedTime"`
  229. RiskLevel string `json:"riskLevel"`
  230. PlateName string `json:"-"`
  231. ClassifyId int `json:"-"`
  232. SecondPermission map[int]string `json:"-"`
  233. Permissions map[int]string `json:"-"`
  234. PermissionNames interface {
  235. } `json:"permissionNames"`
  236. Highlight []string `json:"highlight"`
  237. Detail json.RawMessage `json:"detail"`
  238. PdfUrl string `json:"pdfUrl"`
  239. CoverSrc int `json:"coverSrc"`
  240. CoverUrl string `json:"coverUrl"`
  241. Login bool `json:"login"`
  242. RiskLevelStatus string `json:"riskLevelStatus"`
  243. IsFree bool `json:"isFree"`
  244. IsSubscribe bool `json:"isSubscribe"`
  245. SubscribeStatus string `json:"subscribeStatus"`
  246. Price string `json:"price"`
  247. ProductId int `json:"productId"`
  248. IsPackage bool `json:"isPackage"`
  249. Score float64 `json:"score"`
  250. Show bool `json:"-"`
  251. }
  252. // BookMarkList 获取收藏列表
  253. // @Description 获取收藏列表
  254. // @Success 200 {object}
  255. // @router /bookMarkList [get]
  256. func (bk *BookMarkController) BookMarkList(sourceType string) {
  257. controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) {
  258. result = bk.InitWrapData("分页查询收藏列表失败")
  259. pageRes := page.Page{
  260. Current: bk.PageInfo.Current,
  261. PageSize: bk.PageInfo.PageSize,
  262. }
  263. if sourceType == "" || (sourceType != Report && sourceType != Chart) {
  264. err = exception.New(exception.IllegalSourceType)
  265. bk.FailedResult("分页查询收藏列表失败", result)
  266. return
  267. }
  268. userInfo := bk.Data["user"].(user.User)
  269. var sourceIds []int
  270. pageRes.Total, sourceIds, err = user.GetTotalBookMarkPageBySourceType(userInfo.Id, sourceType)
  271. //隐藏品种信息未设置风险等级的报告
  272. if sourceType == Report {
  273. pageRes.Total, sourceIds, err = report.FilterReportIds(sourceIds)
  274. }
  275. if pageRes.Total == 0 {
  276. bookMarks := new(page.PageResult)
  277. bookMarks.Data = []interface{}{}
  278. bookMarks.Page = pageRes
  279. bk.SuccessResult("分页查询收藏列表成功", bookMarks, result)
  280. return
  281. }
  282. pageRes.Total = bk.PageInfo.Total
  283. pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
  284. switch sourceType {
  285. case Report:
  286. var list []BookMarkReport
  287. list, err = getReportList(bk.PageInfo, userInfo.Id, sourceIds)
  288. if err != nil {
  289. err = exception.NewWithException(exception.GetBookMarkListFailed, err.Error())
  290. bk.FailedResult("分页查询收藏列表失败", result)
  291. return
  292. }
  293. bookMarks := new(page.PageResult)
  294. bookMarks.Data = list
  295. bookMarks.Page = pageRes
  296. bk.SuccessResult("分页查询收藏列表成功", bookMarks, result)
  297. return
  298. case Chart:
  299. var list []BookMarkChart
  300. list, err = getChartList(bk.PageInfo, userInfo.Id)
  301. if err != nil {
  302. err = exception.NewWithException(exception.GetBookMarkListFailed, err.Error())
  303. bk.FailedResult("分页查询收藏列表失败", result)
  304. return
  305. }
  306. bookMarks := new(page.PageResult)
  307. bookMarks.Data = list
  308. bookMarks.Page = pageRes
  309. bk.SuccessResult("分页查询收藏列表成功", bookMarks, result)
  310. return
  311. default:
  312. err = exception.New(exception.IllegalSourceType)
  313. bk.FailedResult("分页查询收藏列表失败", result)
  314. return
  315. }
  316. })
  317. }
  318. func getReportList(info page.PageInfo, templateUserId int, sourceIds []int) (list []BookMarkReport, err error) {
  319. sourceIds, err = userService.GetBookMarkPageRangeBySourceType(templateUserId, info, Report, sourceIds)
  320. if err != nil {
  321. return
  322. }
  323. userProfile, userErr := user.GetUserProfile(templateUserId)
  324. if userErr != nil {
  325. if errors.Is(userErr, gorm.ErrRecordNotFound) {
  326. err = exception.New(exception.TemplateUserNotFound)
  327. } else {
  328. err = exception.New(exception.TemplateUserFoundFailed)
  329. }
  330. logger.Error("获取临时客户信息失败:%v", err)
  331. return
  332. }
  333. var mappingRiskLevel, userRiskStatus string
  334. userRiskStatus = userProfile.RiskLevelStatus
  335. if userProfile.RiskLevel != "" {
  336. var mapping permissionService.CustomerProductRiskMappingDTO
  337. mapping, err = permissionService.GetRiskMappingByCustomerRiskLevel(userProfile.RiskLevel)
  338. if err != nil {
  339. logger.Error("查询产品风险等级映射失败:%v", err)
  340. return
  341. }
  342. mappingRiskLevel = mapping.ProductRiskLevel
  343. }
  344. reports, err := report.GetReportListById(templateUserId, sourceIds, mappingRiskLevel, userRiskStatus)
  345. if err != nil {
  346. return nil, err
  347. }
  348. list = make([]BookMarkReport, len(sourceIds))
  349. // 并发获取数据
  350. for index, sourceId := range sourceIds {
  351. for _, reportDTO := range reports {
  352. if reportDTO.ReportID == sourceId {
  353. reportInfo := convertToBookMarkReport(reportDTO)
  354. list[index] = reportInfo
  355. }
  356. }
  357. }
  358. return
  359. }
  360. func getChartList(info page.PageInfo, templateUserId int) (list []BookMarkChart, err error) {
  361. sourceIds, err := userService.GetBookMarkPageBySourceType(templateUserId, info, Chart)
  362. if err != nil {
  363. return
  364. }
  365. // 创建一个切片来存储结果,长度与 sourceIds 相同
  366. list = make([]BookMarkChart, len(sourceIds))
  367. // 使用 WaitGroup 来等待所有 goroutine 完成
  368. var wg sync.WaitGroup
  369. wg.Add(len(sourceIds))
  370. // 使用 Mutex 来保护对 list 的写操作
  371. var mu sync.Mutex
  372. // 并发获取数据
  373. for index, sourceId := range sourceIds {
  374. go func(index int, id int) {
  375. defer wg.Done()
  376. var data chartService.ChartInfo
  377. data, err = chartService.GetChartById(id)
  378. chartInfo := convertToBookMarkChart(data)
  379. if err != nil {
  380. logger.Error("获取数据失败: %v", err)
  381. }
  382. // 使用 Mutex 保护对 list 的写操作
  383. mu.Lock()
  384. list[index] = chartInfo
  385. mu.Unlock()
  386. }(index, sourceId)
  387. }
  388. // 等待所有 goroutine 完成
  389. wg.Wait()
  390. return
  391. }
  392. func convertToBookMarkChart(chart chartService.ChartInfo) BookMarkChart {
  393. return BookMarkChart{
  394. ChartName: chart.ChartName,
  395. ChartImage: chart.ChartImage,
  396. UniqueCode: chart.UniqueCode,
  397. ChartInfoId: chart.ChartInfoId,
  398. }
  399. }
  400. func convertToBookMarkReport(report reportDomian.ReportDTO) BookMarkReport {
  401. return BookMarkReport{
  402. Abstract: report.Abstract,
  403. Author: report.Author,
  404. AuthorInfo: report.AuthorInfo,
  405. ClassifyId: report.ClassifyId,
  406. CoverSrc: report.CoverSrc,
  407. CoverUrl: report.CoverUrl,
  408. Detail: report.Detail,
  409. Highlight: report.Highlight,
  410. IsFree: report.IsFree,
  411. IsPackage: report.IsPackage,
  412. IsSubscribe: report.IsSubscribe,
  413. Login: report.Login,
  414. OrgId: report.OrgId,
  415. PdfUrl: report.PdfUrl,
  416. PermissionNames: report.PermissionNames,
  417. Permissions: report.Permissions,
  418. PlateName: report.PlateName,
  419. Price: report.Price,
  420. ProductId: report.ProductId,
  421. PublishedTime: report.PublishedTime,
  422. ReportID: report.ReportID,
  423. RiskLevel: report.RiskLevel,
  424. RiskLevelStatus: report.RiskLevelStatus,
  425. Score: report.Score,
  426. SecondPermission: report.SecondPermission,
  427. Show: report.Show,
  428. Source: report.Source,
  429. SubscribeStatus: report.SubscribeStatus,
  430. Title: report.Title,
  431. Type: report.Type,
  432. }
  433. }