bookmark_controller.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. package user
  2. import (
  3. "errors"
  4. "eta/eta_mini_ht_api/common/component/cache"
  5. logger "eta/eta_mini_ht_api/common/component/log"
  6. "eta/eta_mini_ht_api/common/exception"
  7. "eta/eta_mini_ht_api/common/utils/page"
  8. "eta/eta_mini_ht_api/controllers"
  9. permissionService "eta/eta_mini_ht_api/domian/config"
  10. reportDomian "eta/eta_mini_ht_api/domian/report"
  11. chartService "eta/eta_mini_ht_api/service/media"
  12. "eta/eta_mini_ht_api/service/report"
  13. "eta/eta_mini_ht_api/service/user"
  14. userService "eta/eta_mini_ht_api/service/user"
  15. "gorm.io/gorm"
  16. "sync"
  17. )
  18. // BookMarkController Operations about bookmark
  19. type BookMarkController struct {
  20. controllers.ListController
  21. redis *cache.RedisCache
  22. }
  23. const (
  24. Chart = "chart"
  25. Report = "report"
  26. )
  27. func (bk *BookMarkController) Prepare() {
  28. bk.ListController.Prepare()
  29. bk.redis = cache.GetInstance()
  30. }
  31. type BookMarkReq struct {
  32. SourceType string `json:"sourceType"`
  33. SourceId int `json:"sourceId"`
  34. ChartImage string `json:"chartImage"`
  35. ChartInfoId int `json:"chartInfoId"`
  36. ChartName string `json:"chartName"`
  37. UniqueCode string `json:"uniqueCode"`
  38. }
  39. // BookMark 收藏
  40. // @Summary 收藏
  41. // @Description 收藏
  42. // @Success 200 {object} controllers.BaseResponse
  43. // @router /bookMark [post]
  44. func (bk *BookMarkController) BookMark() {
  45. controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) {
  46. result = bk.InitWrapData("收藏失败")
  47. bookMark := new(BookMarkReq)
  48. bk.GetPostParams(bookMark)
  49. var userInfo user.User
  50. userInfo = bk.Data["user"].(user.User)
  51. if bookMark.SourceType == "" {
  52. bk.FailedResult("收藏失败", result)
  53. err = exception.New(exception.IllegalSourceType)
  54. return
  55. }
  56. if bookMark.SourceId == 0 {
  57. bk.FailedResult("收藏失败", result)
  58. err = exception.New(exception.IllegalSourceId)
  59. return
  60. }
  61. err = userService.BookMark(userInfo.Id, bookMark.SourceId, bookMark.SourceType)
  62. if err != nil {
  63. err = exception.NewWithException(exception.FeedBackError, err.Error())
  64. bk.FailedResult("收藏失败", result)
  65. return
  66. }
  67. //将图表加入es
  68. if bookMark.SourceType == Chart {
  69. chartService.AddChartToEs(chartService.ChartInfo{
  70. ChartImage: bookMark.ChartImage,
  71. ChartInfoId: bookMark.ChartInfoId,
  72. ChartName: bookMark.ChartName,
  73. UniqueCode: bookMark.UniqueCode,
  74. })
  75. }
  76. bk.SuccessResult("收藏成功", nil, result)
  77. return
  78. })
  79. }
  80. // UnBookMark 取消收藏
  81. // @Summary 取消收藏
  82. // @Description 取消收藏
  83. // @Success 200 {object} controllers.BaseResponse
  84. // @router /unBookMark [post]
  85. func (bk *BookMarkController) UnBookMark() {
  86. controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) {
  87. result = bk.InitWrapData("取消收藏失败")
  88. bookMark := new(BookMarkReq)
  89. bk.GetPostParams(bookMark)
  90. var userInfo user.User
  91. userInfo = bk.Data["user"].(user.User)
  92. if bookMark.SourceType == "" {
  93. bk.FailedResult("取消收藏失败", result)
  94. err = exception.New(exception.IllegalSourceType)
  95. return
  96. }
  97. if bookMark.SourceId == 0 {
  98. bk.FailedResult("取消收藏失败", result)
  99. err = exception.New(exception.IllegalSourceId)
  100. return
  101. }
  102. err = userService.UnBookMark(userInfo.Id, bookMark.SourceId, bookMark.SourceType)
  103. if err != nil {
  104. err = exception.NewWithException(exception.FeedBackError, err.Error())
  105. bk.FailedResult("取消收藏失败", result)
  106. return
  107. }
  108. bk.SuccessResult("收藏成功", nil, result)
  109. return
  110. })
  111. }
  112. type CheckBookMarkResp struct {
  113. IsBookMarked bool `json:"isBookMarked"`
  114. }
  115. // CheckBookMark 取消收藏
  116. // @Summary 取消收藏
  117. // @Description 取消收藏
  118. // @Success 200 {object} controllers.BaseResponse
  119. // @router /checkBookMark [post]
  120. func (bk *BookMarkController) CheckBookMark() {
  121. controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) {
  122. result = bk.InitWrapData("取消收藏失败")
  123. bookMark := new(BookMarkReq)
  124. bk.GetPostParams(bookMark)
  125. var userInfo user.User
  126. userInfo = bk.Data["user"].(user.User)
  127. if bookMark.SourceType == "" {
  128. bk.FailedResult("获取是否收藏失败", result)
  129. err = exception.New(exception.IllegalSourceType)
  130. return
  131. }
  132. if bookMark.SourceId == 0 {
  133. bk.FailedResult("获取是否收藏失败", result)
  134. err = exception.New(exception.IllegalSourceId)
  135. return
  136. }
  137. isBookMarked, err := userService.CheckBookMarkStatus(userInfo.Id, bookMark.SourceId, bookMark.SourceType)
  138. if err != nil {
  139. err = exception.NewWithException(exception.FeedBackError, err.Error())
  140. bk.FailedResult("获取是否收藏失败", result)
  141. return
  142. }
  143. bk.SuccessResult("获取是否收藏成功", &CheckBookMarkResp{
  144. IsBookMarked: isBookMarked,
  145. }, result)
  146. return
  147. })
  148. }
  149. // BookMarkSearch 搜索收藏列表
  150. // @Description 搜索报告列表
  151. // @Success 200 {object}
  152. // @router /bookMarkSearch [get]
  153. func (bk *BookMarkController) BookMarkSearch(key string) {
  154. controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) {
  155. result = bk.InitWrapData("分页搜索报告列表失败")
  156. if key == "" {
  157. err = exception.New(exception.SearchKeyEmptyError)
  158. bk.FailedResult("分页搜索报告列表失败", result)
  159. return
  160. }
  161. userInfo := bk.Data["user"].(user.User)
  162. pageRes := page.Page{
  163. Current: bk.PageInfo.Current,
  164. PageSize: bk.PageInfo.PageSize,
  165. }
  166. //获取当前可以被搜索的报告原始ID
  167. //先要限制查询的id范围
  168. var reportIds []int
  169. var mappingRiskLevel string
  170. var userRiskStatus string
  171. pageRes.Total, pageRes.LatestId, reportIds, _, mappingRiskLevel, userRiskStatus, err = report.RangeSearch(key, true, userInfo.Id)
  172. if err != nil {
  173. logger.Error("搜索收藏列表失败%v", err)
  174. err = exception.NewWithException(exception.GetBookMarkListFailed, err.Error())
  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. // SearchBookMark 搜索收藏列表
  214. // @Description 搜索收藏列表
  215. // @Success 200 {object}
  216. // @router /searchBookMark [get]
  217. func (bk *BookMarkController) SearchBookMark(sourceType string, key string) {
  218. controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) {
  219. result = bk.InitWrapData("分页搜索收藏列表失败")
  220. pageRes := page.Page{
  221. Current: bk.PageInfo.Current,
  222. PageSize: bk.PageInfo.PageSize,
  223. }
  224. if sourceType == "" || (sourceType != Report && sourceType != Chart) {
  225. err = exception.New(exception.IllegalSourceType)
  226. bk.FailedResult("分页搜索收藏列表失败", result)
  227. return
  228. }
  229. if key == "" {
  230. err = exception.New(exception.IllegalSearchKeyword)
  231. bk.FailedResult("分页搜索收藏列表失败", result)
  232. return
  233. }
  234. userInfo := bk.Data["user"].(user.User)
  235. var sourceIds []int
  236. pageRes.Total, sourceIds, err = user.GetTotalBookMarkPageBySourceType(userInfo.Id, sourceType)
  237. if err != nil {
  238. logger.Error("获取收藏列表失败%v", err)
  239. err = exception.NewWithException(exception.GetBookMarkListFailed, err.Error())
  240. bk.FailedResult("分页查询收藏列表失败", result)
  241. return
  242. }
  243. //隐藏品种信息未设置风险等级的报告
  244. if sourceType == Report {
  245. pageRes.Total, sourceIds, err = report.FilterReportIds(sourceIds)
  246. }
  247. if pageRes.Total == 0 {
  248. bookMarks := new(page.PageResult)
  249. bookMarks.Data = []interface{}{}
  250. bookMarks.Page = pageRes
  251. bk.SuccessResult("分页搜索收藏列表列表成功", bookMarks, result)
  252. return
  253. }
  254. pageRes.Total = bk.PageInfo.Total
  255. pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
  256. var bookMarkList []userService.BookMarkInterface
  257. switch sourceType {
  258. case Report:
  259. reportList, reportErr := report.SearchReportBookMark(key, sourceIds, bk.PageInfo, true, userInfo.Id)
  260. if reportErr != nil {
  261. logger.Error("搜索研报列表失败%v", err)
  262. err = exception.NewWithException(exception.GetBookMarkListFailed, reportErr.Error())
  263. bk.FailedResult("分页搜索收藏列表失败", result)
  264. return
  265. }
  266. for _, reportInfo := range reportList {
  267. bookMarkList = append(bookMarkList, ConvertToBookMarkReport(reportInfo))
  268. }
  269. case Chart:
  270. chartList, chartErr := chartService.SearchChartList(key, sourceIds, bk.PageInfo)
  271. if chartErr != nil {
  272. logger.Error("搜索研报列表失败%v", err)
  273. err = exception.NewWithException(exception.GetBookMarkListFailed, chartErr.Error())
  274. bk.FailedResult("分页搜索收藏列表失败", result)
  275. return
  276. }
  277. for _, chart := range chartList {
  278. bookMarkList = append(bookMarkList, ConvertToBookMarkChart(chart))
  279. }
  280. default:
  281. err = exception.NewWithException(exception.GetBookMarkListFailed, "不支持的收藏类型")
  282. bk.FailedResult("分页搜索收藏列表失败", result)
  283. return
  284. }
  285. //bookMarkList, err = user.SearchBookMark(key, sourceType, sourceIds, bk.PageInfo, userInfo.Id)
  286. bookMarks := new(page.PageResult)
  287. bookMarks.Data = bookMarkList
  288. bookMarks.Page = pageRes
  289. bk.SuccessResult("分页搜索收藏列表成功", bookMarks, result)
  290. return
  291. })
  292. }
  293. func ConvertToBookMarkChart(chart chartService.ChartInfo) userService.BookMarkChart {
  294. return userService.BookMarkChart{
  295. ChartName: chart.ChartName,
  296. ChartImage: chart.ChartImage,
  297. UniqueCode: chart.UniqueCode,
  298. ChartInfoId: chart.ChartInfoId,
  299. }
  300. }
  301. func ConvertToBookMarkReport(report reportDomian.ReportDTO) userService.BookMarkReport {
  302. return userService.BookMarkReport{
  303. Abstract: report.Abstract,
  304. Author: report.Author,
  305. AuthorInfo: report.AuthorInfo,
  306. ClassifyId: report.ClassifyId,
  307. CoverSrc: report.CoverSrc,
  308. CoverUrl: report.CoverUrl,
  309. Detail: report.Detail,
  310. Highlight: report.Highlight,
  311. IsFree: report.IsFree,
  312. IsPackage: report.IsPackage,
  313. IsSubscribe: report.IsSubscribe,
  314. Login: report.Login,
  315. OrgId: report.OrgId,
  316. PdfUrl: report.PdfUrl,
  317. PermissionNames: report.PermissionNames,
  318. Permissions: report.Permissions,
  319. PlateName: report.PlateName,
  320. Price: report.Price,
  321. ProductId: report.ProductId,
  322. PublishedTime: report.PublishedTime,
  323. ReportID: report.ReportID,
  324. RiskLevel: report.RiskLevel,
  325. RiskLevelStatus: report.RiskLevelStatus,
  326. Score: report.Score,
  327. SecondPermission: report.SecondPermission,
  328. Show: report.Show,
  329. Source: report.Source,
  330. SubscribeStatus: report.SubscribeStatus,
  331. Title: report.Title,
  332. Type: report.Type,
  333. }
  334. }
  335. // BookMarkList 获取收藏列表
  336. // @Description 获取收藏列表
  337. // @Success 200 {object}
  338. // @router /bookMarkList [get]
  339. func (bk *BookMarkController) BookMarkList(sourceType string) {
  340. controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) {
  341. result = bk.InitWrapData("分页查询收藏列表失败")
  342. pageRes := page.Page{
  343. Current: bk.PageInfo.Current,
  344. PageSize: bk.PageInfo.PageSize,
  345. }
  346. if sourceType == "" || (sourceType != Report && sourceType != Chart) {
  347. err = exception.New(exception.IllegalSourceType)
  348. bk.FailedResult("分页查询收藏列表失败", result)
  349. return
  350. }
  351. userInfo := bk.Data["user"].(user.User)
  352. var sourceIds []int
  353. pageRes.Total, sourceIds, err = user.GetTotalBookMarkPageBySourceType(userInfo.Id, sourceType)
  354. if err != nil {
  355. logger.Error("获取收藏列表失败%v", err)
  356. err = exception.NewWithException(exception.GetBookMarkListFailed, err.Error())
  357. bk.FailedResult("分页查询收藏列表失败", result)
  358. return
  359. }
  360. //隐藏品种信息未设置风险等级的报告
  361. if sourceType == Report {
  362. pageRes.Total, sourceIds, err = report.FilterReportIds(sourceIds)
  363. }
  364. if pageRes.Total == 0 {
  365. bookMarks := new(page.PageResult)
  366. bookMarks.Data = []interface{}{}
  367. bookMarks.Page = pageRes
  368. bk.SuccessResult("分页查询收藏列表成功", bookMarks, result)
  369. return
  370. }
  371. pageRes.Total = bk.PageInfo.Total
  372. pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
  373. switch sourceType {
  374. case Report:
  375. var list []userService.BookMarkReport
  376. list, err = getReportList(bk.PageInfo, userInfo.Id, sourceIds)
  377. if err != nil {
  378. err = exception.NewWithException(exception.GetBookMarkListFailed, err.Error())
  379. bk.FailedResult("分页查询收藏列表失败", result)
  380. return
  381. }
  382. bookMarks := new(page.PageResult)
  383. bookMarks.Data = list
  384. bookMarks.Page = pageRes
  385. bk.SuccessResult("分页查询收藏列表成功", bookMarks, result)
  386. return
  387. case Chart:
  388. var list []userService.BookMarkChart
  389. list, err = getChartList(bk.PageInfo, userInfo.Id)
  390. if err != nil {
  391. err = exception.NewWithException(exception.GetBookMarkListFailed, err.Error())
  392. bk.FailedResult("分页查询收藏列表失败", result)
  393. return
  394. }
  395. bookMarks := new(page.PageResult)
  396. bookMarks.Data = list
  397. bookMarks.Page = pageRes
  398. bk.SuccessResult("分页查询收藏列表成功", bookMarks, result)
  399. return
  400. default:
  401. err = exception.New(exception.IllegalSourceType)
  402. bk.FailedResult("分页查询收藏列表失败", result)
  403. return
  404. }
  405. })
  406. }
  407. // ChartList 获取收藏列表
  408. // @Description 获取收藏列表
  409. // @Success 200 {object}
  410. // @router /bookmark/chartList [get]
  411. func (bk *BookMarkController) ChartList(key string) {
  412. controllers.Wrap(&bk.BaseController, func() (result *controllers.WrapData, err error) {
  413. result = bk.InitWrapData("分页查询收藏列表失败")
  414. userInfo := bk.Data["user"].(user.User)
  415. if key == "" {
  416. var list []userService.BookMarkChart
  417. list, err = getAllChartList(userInfo.Id)
  418. if err != nil {
  419. err = exception.NewWithException(exception.GetBookMarkListFailed, err.Error())
  420. bk.FailedResult("分页查询收藏列表失败", result)
  421. return
  422. }
  423. //bookMarks := new(page.PageResult)
  424. //bookMarks.Data = list
  425. bk.SuccessResult("分页查询收藏列表成功", list, result)
  426. return
  427. } else {
  428. if key == "" {
  429. err = exception.New(exception.IllegalSearchKeyword)
  430. bk.FailedResult("分页搜索收藏列表失败", result)
  431. return
  432. }
  433. var sourceIds []int
  434. _, sourceIds, err = user.GetTotalBookMarkPageBySourceType(userInfo.Id, Chart)
  435. var bookMarkList []userService.BookMarkInterface
  436. chartList, chartErr := chartService.SearchAllChartList(key, sourceIds)
  437. if chartErr != nil {
  438. logger.Error("搜索研报列表失败%v", err)
  439. err = exception.NewWithException(exception.GetBookMarkListFailed, chartErr.Error())
  440. bk.FailedResult("分页搜索收藏列表失败", result)
  441. return
  442. }
  443. for _, chart := range chartList {
  444. bookMarkList = append(bookMarkList, ConvertToBookMarkChart(chart))
  445. }
  446. //bookMarkList, err = user.SearchBookMark(key, sourceType, sourceIds, bk.PageInfo, userInfo.Id)
  447. bk.SuccessResult("分页搜索收藏列表成功", bookMarkList, result)
  448. return
  449. }
  450. })
  451. }
  452. func getReportList(info page.PageInfo, templateUserId int, sourceIds []int) (list []userService.BookMarkReport, err error) {
  453. sourceIds, err = userService.GetBookMarkPageRangeBySourceType(templateUserId, info, Report, sourceIds)
  454. if err != nil {
  455. return
  456. }
  457. userProfile, userErr := user.GetUserProfile(templateUserId)
  458. if userErr != nil {
  459. if errors.Is(userErr, gorm.ErrRecordNotFound) {
  460. err = exception.New(exception.TemplateUserNotFound)
  461. } else {
  462. err = exception.New(exception.TemplateUserFoundFailed)
  463. }
  464. logger.Error("获取临时客户信息失败:%v", err)
  465. return
  466. }
  467. var mappingRiskLevel, userRiskStatus string
  468. userRiskStatus = userProfile.RiskLevelStatus
  469. if userProfile.RiskLevel != "" {
  470. var mapping permissionService.CustomerProductRiskMappingDTO
  471. mapping, err = permissionService.GetRiskMappingByCustomerRiskLevel(userProfile.RiskLevel)
  472. if err != nil {
  473. logger.Error("查询产品风险等级映射失败:%v", err)
  474. return
  475. }
  476. mappingRiskLevel = mapping.ProductRiskLevel
  477. }
  478. reports, err := report.GetReportListById(templateUserId, sourceIds, mappingRiskLevel, userRiskStatus)
  479. if err != nil {
  480. return nil, err
  481. }
  482. list = make([]userService.BookMarkReport, len(sourceIds))
  483. // 并发获取数据
  484. for index, sourceId := range sourceIds {
  485. for _, reportDTO := range reports {
  486. if reportDTO.ReportID == sourceId {
  487. reportInfo := ConvertToBookMarkReport(reportDTO)
  488. list[index] = reportInfo
  489. }
  490. }
  491. }
  492. return
  493. }
  494. func getChartList(info page.PageInfo, templateUserId int) (list []userService.BookMarkChart, err error) {
  495. sourceIds, err := userService.GetBookMarkPageBySourceType(templateUserId, info, Chart)
  496. if err != nil {
  497. return
  498. }
  499. // 创建一个切片来存储结果,长度与 sourceIds 相同
  500. list = make([]userService.BookMarkChart, len(sourceIds))
  501. // 使用 WaitGroup 来等待所有 goroutine 完成
  502. var wg sync.WaitGroup
  503. wg.Add(len(sourceIds))
  504. // 使用 Mutex 来保护对 list 的写操作
  505. var mu sync.Mutex
  506. // 并发获取数据
  507. for index, sourceId := range sourceIds {
  508. go func(index int, id int) {
  509. defer wg.Done()
  510. var data chartService.ChartInfo
  511. data, err = chartService.GetChartById(id)
  512. chartInfo := ConvertToBookMarkChart(data)
  513. if err != nil {
  514. logger.Error("获取数据失败: %v", err)
  515. }
  516. // 使用 Mutex 保护对 list 的写操作
  517. mu.Lock()
  518. list[index] = chartInfo
  519. mu.Unlock()
  520. }(index, sourceId)
  521. }
  522. // 等待所有 goroutine 完成
  523. wg.Wait()
  524. return
  525. }
  526. func getAllChartList(templateUserId int) (list []userService.BookMarkChart, err error) {
  527. sourceIds, err := userService.GetBookMarkListBySourceType(templateUserId, Chart)
  528. if err != nil {
  529. return
  530. }
  531. // 创建一个切片来存储结果,长度与 sourceIds 相同
  532. list = make([]userService.BookMarkChart, len(sourceIds))
  533. // 使用 WaitGroup 来等待所有 goroutine 完成
  534. var wg sync.WaitGroup
  535. wg.Add(len(sourceIds))
  536. // 使用 Mutex 来保护对 list 的写操作
  537. var mu sync.Mutex
  538. // 并发获取数据
  539. for index, sourceId := range sourceIds {
  540. go func(index int, id int) {
  541. defer wg.Done()
  542. var data chartService.ChartInfo
  543. data, err = chartService.GetChartById(id)
  544. chartInfo := ConvertToBookMarkChart(data)
  545. if err != nil {
  546. logger.Error("获取数据失败: %v", err)
  547. }
  548. // 使用 Mutex 保护对 list 的写操作
  549. mu.Lock()
  550. list[index] = chartInfo
  551. mu.Unlock()
  552. }(index, sourceId)
  553. }
  554. // 等待所有 goroutine 完成
  555. wg.Wait()
  556. return
  557. }