report_service.go 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178
  1. package report
  2. import (
  3. "encoding/json"
  4. "eta/eta_mini_ht_api/common/component/config"
  5. "eta/eta_mini_ht_api/common/component/es"
  6. logger "eta/eta_mini_ht_api/common/component/log"
  7. "eta/eta_mini_ht_api/common/contants"
  8. "eta/eta_mini_ht_api/common/utils/page"
  9. stringUtils "eta/eta_mini_ht_api/common/utils/string"
  10. configService "eta/eta_mini_ht_api/domian/config"
  11. analystService "eta/eta_mini_ht_api/domian/financial_analyst"
  12. messageDomian "eta/eta_mini_ht_api/domian/message"
  13. userService "eta/eta_mini_ht_api/domian/user"
  14. "eta/eta_mini_ht_api/models"
  15. configDao "eta/eta_mini_ht_api/models/config"
  16. permissionDao "eta/eta_mini_ht_api/models/config"
  17. "eta/eta_mini_ht_api/models/eta"
  18. etaDao "eta/eta_mini_ht_api/models/eta"
  19. "eta/eta_mini_ht_api/models/ht"
  20. mediaDao "eta/eta_mini_ht_api/models/image"
  21. merchantDao "eta/eta_mini_ht_api/models/merchant"
  22. "eta/eta_mini_ht_api/models/message"
  23. messageDao "eta/eta_mini_ht_api/models/message"
  24. reportDao "eta/eta_mini_ht_api/models/report"
  25. userDao "eta/eta_mini_ht_api/models/user"
  26. "math/rand"
  27. "strconv"
  28. "strings"
  29. "sync"
  30. "time"
  31. )
  32. const (
  33. SourceETA = "ETA"
  34. SourceHT = "HT"
  35. DESC models.Order = "desc"
  36. ASC models.Order = "asc"
  37. ESColumn = "title"
  38. ESRangeColumn = "reportId"
  39. )
  40. var (
  41. sortField = []string{"_score:desc"}
  42. htConfig = config.GetConfig(contants.HT).(*config.HTBizConfig)
  43. )
  44. func elastic() *es.ESClient {
  45. return es.GetInstance()
  46. }
  47. // ESReport Report ES研报mapping
  48. type ESReport struct {
  49. ReportID int `json:"reportId"`
  50. OrgId int `json:"orgId"`
  51. Title string `json:"title"`
  52. Author string `json:"author"`
  53. Source reportDao.ReportSource `json:"source"`
  54. Abstract string `json:"abstract"`
  55. CoverSrc int `json:"coverSrc"`
  56. Status reportDao.ReportStatus `json:"status"`
  57. PublishedTime string `json:"publishedTime"`
  58. }
  59. type ReportDTO struct {
  60. Type string `json:"type"`
  61. ReportID int `json:"reportId"`
  62. OrgId int `json:"orgId"`
  63. Title string `json:"title"`
  64. Author string `json:"author"`
  65. AuthorInfo []Anthor `json:"authorInfo"`
  66. Source string `json:"source"`
  67. Abstract string `json:"abstract"`
  68. PublishedTime string `json:"publishedTime"`
  69. RiskLevel string `json:"riskLevel"`
  70. PlateName string `json:"-"`
  71. ClassifyId int `json:"-"`
  72. SecondPermission map[int]string `json:"-"`
  73. Permissions map[int]string `json:"-"`
  74. PermissionNames interface {
  75. } `json:"permissionNames"`
  76. Highlight []string `json:"highlight"`
  77. Detail json.RawMessage `json:"detail"`
  78. PdfUrl string `json:"pdfUrl"`
  79. CoverSrc int `json:"coverSrc"`
  80. CoverUrl string `json:"coverUrl"`
  81. Login bool `json:"login"`
  82. RiskLevelStatus string `json:"riskLevelStatus"`
  83. IsFree bool `json:"isFree"`
  84. IsSubscribe bool `json:"isSubscribe"`
  85. SubscribeStatus string `json:"subscribeStatus"`
  86. Price string `json:"price"`
  87. ProductId int `json:"productId"`
  88. IsPackage bool `json:"isPackage"`
  89. Score float64 `json:"score"`
  90. Show bool `json:"-"`
  91. IsCollect bool `json:"isCollected"`
  92. }
  93. type Detail struct {
  94. }
  95. type Anthor struct {
  96. Id int `json:"id"`
  97. Name string `json:"name"`
  98. HeadImgUrl string `json:"headImgUrl"`
  99. Following string `json:"following"`
  100. }
  101. func GetReportById(reportId int, userId int) (ReportDTO ReportDTO, err error) {
  102. report, err := reportDao.GetReportById(reportId)
  103. if err != nil {
  104. return
  105. }
  106. ReportDTO = convertReportDTO(report, true)
  107. authorStr := ReportDTO.Author
  108. authorNames := strings.Split(authorStr, ",")
  109. authorNames = stringUtils.RemoveEmptyStrings(authorNames)
  110. var authorList []Anthor
  111. if len(authorNames) > 0 {
  112. for _, name := range authorNames {
  113. var author analystService.FinancialAnalystDTO
  114. author, err = analystService.GetAnalystByName(name)
  115. var item Anthor
  116. if err != nil {
  117. item = Anthor{
  118. Id: 0,
  119. Name: name,
  120. HeadImgUrl: "",
  121. Following: string(userDao.Unfollowed),
  122. }
  123. } else {
  124. item = Anthor{
  125. Id: author.Id,
  126. Name: author.Name,
  127. HeadImgUrl: author.HeadImgUrl,
  128. Following: userDao.GetFollowing(userId, author.Id),
  129. }
  130. }
  131. authorList = append(authorList, item)
  132. }
  133. }
  134. ReportDTO.AuthorInfo = authorList
  135. return
  136. }
  137. func GetTotalPageCountByAnalyst(analyst string, permissionIds []int) (total int64, latestId int64, ids []int) {
  138. ids, err := reportDao.GetReportsByAnalyst(analyst)
  139. if err != nil {
  140. logger.Error("查询研究研报告列表id失败:%v", err)
  141. return
  142. }
  143. var wg sync.WaitGroup
  144. wg.Add(2)
  145. var htOrgIds []int
  146. var etaOrgIds []int
  147. go func() {
  148. defer wg.Done()
  149. htOrgIds, err = getHtOrgIds(permissionIds)
  150. if err != nil {
  151. logger.Error("品种筛选ht报告id失败:%v", err)
  152. }
  153. }()
  154. go func() {
  155. defer wg.Done()
  156. etaOrgIds, err = getEtaOrgIds(permissionIds)
  157. if err != nil {
  158. logger.Error("品种筛选eta报告id失败:%v", err)
  159. }
  160. }()
  161. wg.Wait()
  162. totalCol := int64(len(etaOrgIds) + len(htOrgIds))
  163. if totalCol == 0 {
  164. latestId = 0
  165. return
  166. }
  167. if len(etaOrgIds) == 0 && len(htOrgIds) == 0 {
  168. logger.Info("没有符合权限的研报")
  169. return
  170. }
  171. orgIds := make(map[string][]int, 2)
  172. if len(etaOrgIds) == 0 {
  173. orgIds["ETA"] = []int{}
  174. } else {
  175. orgIds["ETA"] = etaOrgIds
  176. }
  177. if len(htOrgIds) == 0 {
  178. orgIds["HT"] = []int{}
  179. } else {
  180. orgIds["HT"] = htOrgIds
  181. }
  182. permitReportIds, err := reportDao.GetReportIdListByOrgIds(orgIds)
  183. if err != nil {
  184. logger.Error("根据原始报告id获取报告id列表失败:%v", err)
  185. return
  186. }
  187. var filterReportIds []int
  188. for _, id := range ids {
  189. for _, permitReportId := range permitReportIds {
  190. if id == permitReportId {
  191. filterReportIds = append(filterReportIds, id)
  192. }
  193. }
  194. }
  195. if len(filterReportIds) == 0 {
  196. logger.Info("没有符合权限的研究员研报")
  197. return
  198. }
  199. ids = filterReportIds
  200. //获取一下下架的报告产品
  201. var disCardReportIds []int
  202. offSaleProducts, err := merchantDao.GetOffSaleProducts([]merchantDao.MerchantProductType{merchantDao.Report, merchantDao.Package})
  203. if err != nil {
  204. logger.Error("获取下架的报告产品失败:%v", err)
  205. return
  206. }
  207. var ProductPermissionIds []int
  208. for _, product := range offSaleProducts {
  209. if product.Type == "package" {
  210. ProductPermissionIds = append(ProductPermissionIds, product.SourceId)
  211. }
  212. if product.Type == "report" {
  213. disCardReportIds = append(disCardReportIds, product.SourceId)
  214. }
  215. }
  216. if len(ProductPermissionIds) > 0 {
  217. wg.Add(2)
  218. var permissionNames []string
  219. var classifyIds []int
  220. go func() {
  221. defer wg.Done()
  222. var permissionErr error
  223. permissionNames, permissionErr = GetPermissionNamesByPermissionIds(ProductPermissionIds)
  224. if permissionErr != nil {
  225. logger.Error("获取ETA品种名称失败:%v", err)
  226. }
  227. }()
  228. go func() {
  229. defer wg.Done()
  230. var classifyErr error
  231. classifyIds, classifyErr = permissionDao.GetClassifyIdsByPermissionIds(ProductPermissionIds)
  232. if classifyErr != nil {
  233. logger.Error("获取ETA报告分类id失败:%v", err)
  234. }
  235. }()
  236. wg.Wait()
  237. disCardIds, _ := reportDao.GetHiddenReportIds(classifyIds, permissionNames)
  238. if len(disCardIds) > 0 {
  239. disCardReportIds = append(disCardReportIds, disCardIds...)
  240. }
  241. }
  242. //对数据去重
  243. disCardReportIds = uniqueArray(disCardReportIds)
  244. //获取报告中还包含上架套餐的id
  245. if len(disCardReportIds) > 0 {
  246. reportIdsSalePackage, _ := merchantDao.GetReportOnSalePackageIds(disCardReportIds)
  247. reportIdsSaleProduct, _ := merchantDao.GetOnSaleReportIds(disCardReportIds)
  248. showReportMap := make(map[int]bool)
  249. disCardMap := make(map[int]bool)
  250. for _, reportId := range reportIdsSalePackage {
  251. showReportMap[reportId] = true
  252. }
  253. for _, reportId := range reportIdsSaleProduct {
  254. showReportMap[reportId] = true
  255. }
  256. var filterDisCardReportIds []int
  257. for _, id := range disCardReportIds {
  258. if _, ok := showReportMap[id]; !ok {
  259. filterDisCardReportIds = append(filterDisCardReportIds, id)
  260. disCardMap[id] = true
  261. }
  262. }
  263. disCardReportIds = filterDisCardReportIds
  264. var cardReportIds []int
  265. for _, id := range filterReportIds {
  266. if _, ok := disCardMap[id]; !ok {
  267. cardReportIds = append(cardReportIds, id)
  268. }
  269. }
  270. filterReportIds = cardReportIds
  271. }
  272. total = int64(len(filterReportIds))
  273. latestId = int64(findMax(filterReportIds))
  274. return
  275. }
  276. // findMaxWithError 函数用于找到整型数组中的最大值,并返回错误信息
  277. func findMax(nums []int) (max int) {
  278. if len(nums) == 0 {
  279. return 0
  280. }
  281. // 初始化最大值为数组的第一个元素
  282. max = nums[0]
  283. // 遍历数组,找到最大值
  284. for _, num := range nums {
  285. if num > max {
  286. max = num
  287. }
  288. }
  289. return
  290. }
  291. func SearchMaxReportIdWithRange(key string, reportIds []int) (total int64) {
  292. sort := []string{"reportId:desc"}
  293. var docIds []string
  294. for _, reportId := range reportIds {
  295. docIds = append(docIds, strconv.Itoa(reportId))
  296. }
  297. request := CountByDocId(key, sort, docIds)
  298. //同步es
  299. re, err := elastic().Count(request)
  300. if err != nil {
  301. logger.Error("es搜索异常:%v", err)
  302. }
  303. count := re.Count
  304. total = int64(count)
  305. if total > 0 {
  306. request = match(key, 0, count, sort)
  307. re, err = elastic().Search(request)
  308. if err != nil {
  309. logger.Error("es搜索异常:%v", err)
  310. }
  311. hits := elastic().GetSource(re.Hits)
  312. data := hits[0].Source
  313. report := ReportDTO{}
  314. err = json.Unmarshal(data, &report)
  315. if err != nil {
  316. logger.Error("获取当前最大研报id失败:%v", err)
  317. return
  318. }
  319. }
  320. return
  321. }
  322. func SearchReportList(key string, ids []int, from int, size int, max int64) (reports []ReportDTO, err error) {
  323. //同步es
  324. var docIds []string
  325. for _, id := range ids {
  326. docIds = append(docIds, strconv.Itoa(id))
  327. }
  328. sorts := append(sortField, "publishedTime:desc")
  329. var request *es.ESQueryRequest
  330. if max == -1 {
  331. request = matchRangeWithDocIds(key, from, size, sorts, docIds)
  332. } else {
  333. request = matchRangeByDocId(key, from, size, max, sorts, docIds)
  334. }
  335. re, err := elastic().Search(request)
  336. if err != nil {
  337. logger.Error("es搜索异常:%v", err)
  338. }
  339. hits := elastic().GetSource(re.Hits)
  340. if len(hits) == 0 {
  341. reports = []ReportDTO{}
  342. return
  343. }
  344. for _, hit := range hits {
  345. var content map[string][]string
  346. err = json.Unmarshal(hit.Highlight, &content)
  347. report := ReportDTO{}
  348. err = json.Unmarshal(hit.Source, &report)
  349. if err != nil {
  350. logger.Error("解析研报数据失败:%v", err)
  351. continue
  352. }
  353. report.Highlight = content[ESColumn]
  354. report.Title = report.Highlight[0]
  355. report.PublishedTime = report.PublishedTime[:10]
  356. reports = append(reports, report)
  357. }
  358. return
  359. }
  360. func GetReportPageByAnalyst(pageInfo page.PageInfo, analyst string, reportIds []int) (list []ReportDTO, err error) {
  361. offset := page.StartIndex(pageInfo.Current, pageInfo.PageSize)
  362. reports, err := reportDao.GetReportPageByAnalyst(pageInfo.LatestId, pageInfo.PageSize, offset, analyst, reportIds)
  363. if err != nil {
  364. logger.Error("分页查询报告列表失败:%v", err)
  365. return
  366. }
  367. list = make([]ReportDTO, 0)
  368. if reports != nil {
  369. for _, report := range reports {
  370. dto := convertReportDTO(report, false)
  371. list = append(list, dto)
  372. }
  373. }
  374. return
  375. }
  376. func GetReportPageByOrgIds(pageInfo page.PageInfo, orgIds map[string][]int, discardIds []int) (list []ReportDTO, err error) {
  377. offset := page.StartIndex(pageInfo.Current, pageInfo.PageSize)
  378. reports, err := reportDao.GetReportPageByOrgIds(pageInfo.LatestId, pageInfo.PageSize, offset, orgIds, discardIds)
  379. if err != nil {
  380. logger.Error("分页查询报告列表失败:%v", err)
  381. return
  382. }
  383. list = make([]ReportDTO, 0)
  384. if reports != nil {
  385. for _, report := range reports {
  386. dto := convertReportDTO(report, false)
  387. list = append(list, dto)
  388. }
  389. }
  390. return
  391. }
  392. func getETAReportFirstPermissions(id int) (permissionDTOs []configService.PermissionDTO) {
  393. classifyId, err := etaDao.GetReportClassifyById(id)
  394. if err != nil || classifyId == 0 {
  395. logger.Error("获取研报分类信息失败:%v", err)
  396. return
  397. }
  398. permissions, err := permissionDao.GetFirstPermissionsByClassifyID(classifyId)
  399. if err != nil {
  400. logger.Error("获取研报一级品种信息失败:%v", err)
  401. return
  402. }
  403. for _, permission := range permissions {
  404. permissionDTOs = append(permissionDTOs, convertPermissionDTO(permission))
  405. }
  406. return
  407. }
  408. func getHTReportFirstPermissions(id int) (permissionDTOs []configService.PermissionDTO) {
  409. report, err := reportDao.GetReportByOrgId(id, SourceHT)
  410. if err != nil {
  411. logger.Error("获取报告失败:%v", err)
  412. }
  413. permissionName := report.PlateName
  414. plateName, err := reportDao.GetPlateNameByPermissionName(permissionName)
  415. if err != nil {
  416. return []configService.PermissionDTO{}
  417. }
  418. return []configService.PermissionDTO{
  419. {
  420. PermissionId: 0,
  421. PermissionName: plateName,
  422. ParentId: 0,
  423. },
  424. }
  425. }
  426. func getETAReportSecondPermissions(id int) (permissionDTOs []configService.PermissionDTO) {
  427. classifyId, err := reportDao.GetReportClassifyById(id)
  428. //classifyId, err := etaDao.GetReportClassifyById(id)
  429. if err != nil || classifyId == 0 {
  430. logger.Error("获取研报分类信息失败:%v", err)
  431. return
  432. }
  433. permissions, err := permissionDao.GetSecondPermissionsByClassifyID(classifyId)
  434. //permissions, err := eta.GetSecondPermissionsByClassifyID(classifyId)
  435. if err != nil {
  436. logger.Error("获取研报二级品种信息失败:%v", err)
  437. return
  438. }
  439. for _, permission := range permissions {
  440. permissionDTOs = append(permissionDTOs, convertPermissionDTO(permission))
  441. }
  442. return
  443. }
  444. func getHTReportSecondPermissions(id int) (permissionDTOs []configService.PermissionDTO) {
  445. report, err := reportDao.GetReportByOrgId(id, SourceHT)
  446. if err != nil {
  447. logger.Error("获取报告失败:%v", err)
  448. }
  449. var permission permissionDao.Permission
  450. if report.PlateName != "" {
  451. permission, err = permissionDao.GetPermissionByName(report.PlateName)
  452. if err != nil {
  453. logger.Error("获取品种信息失败:%v", err)
  454. }
  455. }
  456. return []configService.PermissionDTO{
  457. {
  458. PermissionId: permission.PermissionId,
  459. PermissionName: report.PlateName,
  460. ParentId: permission.ParentId,
  461. RiskLevel: permission.RiskLevel,
  462. },
  463. }
  464. }
  465. func (es ESReport) GetId() string {
  466. return strconv.Itoa(es.ReportID)
  467. }
  468. func GetETALatestReportId() (id int, err error) {
  469. return reportDao.GetLatestReportIdBySource(reportDao.SourceETA)
  470. }
  471. func GetHTLatestReportId() (id int, err error) {
  472. return reportDao.GetLatestReportIdBySource(reportDao.SourceHT)
  473. }
  474. func InitETAReportList(list []eta.ETAReport) (err error) {
  475. logger.Info("同步研报数量%d", len(list))
  476. var reports []reportDao.Report
  477. for _, etaRp := range list {
  478. var coverSrc int
  479. //var permissions []etaDao.ChartPermission
  480. //permissions, err = etaDao.GetSecondPermissionsByClassifyID(etaRp.ClassifyID)
  481. var permissions []permissionDao.Permission
  482. permissions, err = permissionDao.GetSecondPermissionsByClassifyID(etaRp.ClassifyID)
  483. if err != nil || len(permissions) == 0 {
  484. logger.Error("获取研报二级品种信息失败:%v", err)
  485. coverSrc = 0
  486. } else {
  487. coverSrc = 0
  488. for _, permission := range permissions {
  489. permissionsId := permission.PermissionId
  490. var ids []int
  491. ids, err = mediaDao.GetIdsByPermissionId(permissionsId)
  492. if err != nil {
  493. logger.Error("获取图片资源失败:%v", err)
  494. continue
  495. }
  496. if ids == nil || len(ids) == 0 {
  497. continue
  498. }
  499. src := rand.NewSource(time.Now().UnixNano())
  500. r := rand.New(src)
  501. // 从切片中随机选择一个元素
  502. randomIndex := r.Intn(len(ids))
  503. coverSrc = ids[randomIndex]
  504. break
  505. }
  506. }
  507. destRp := convertEtaReport(etaRp, reportDao.StatusPublish)
  508. //destRp.Author = authorName
  509. destRp.CoverSrc = coverSrc
  510. reports = append(reports, destRp)
  511. //}
  512. }
  513. err = reportDao.BatchInsertReport(&reports)
  514. if err != nil {
  515. logger.Error("同步ETA研报失败:%v", err)
  516. return
  517. }
  518. return initES(reports)
  519. }
  520. func etaStatus(status int) reportDao.ReportStatus {
  521. if status == etaDao.Passed || status == etaDao.Published {
  522. return reportDao.StatusPublish
  523. } else {
  524. return reportDao.StatusUnPublish
  525. }
  526. }
  527. func SyncETAReportList(list []eta.ETAReport) (err error) {
  528. logger.Info("同步研报数量%d", len(list))
  529. var reports []reportDao.Report
  530. for _, etaRp := range list {
  531. var coverSrc int
  532. //var permissions []etaDao.ChartPermission
  533. //permissions, err = etaDao.GetSecondPermissionsByClassifyID(etaRp.ClassifyID)
  534. var permissions []permissionDao.Permission
  535. permissions, err = permissionDao.GetSecondPermissionsByClassifyID(etaRp.ClassifyID)
  536. if err != nil || len(permissions) == 0 {
  537. logger.Error("获取研报二级品种信息失败:%v", err)
  538. coverSrc = 0
  539. } else {
  540. coverSrc = 0
  541. for _, permission := range permissions {
  542. permissionsId := permission.PermissionId
  543. var ids []int
  544. ids, err = mediaDao.GetIdsByPermissionId(permissionsId)
  545. if err != nil {
  546. logger.Error("获取图片资源失败:%v", err)
  547. continue
  548. }
  549. if ids == nil || len(ids) == 0 {
  550. continue
  551. }
  552. src := rand.NewSource(time.Now().UnixNano())
  553. r := rand.New(src)
  554. // 从切片中随机选择一个元素
  555. randomIndex := r.Intn(len(ids))
  556. coverSrc = ids[randomIndex]
  557. break
  558. }
  559. }
  560. status := etaStatus(etaRp.State)
  561. destRp := convertEtaReport(etaRp, status)
  562. destRp.CoverSrc = coverSrc
  563. reports = append(reports, destRp)
  564. }
  565. esList, err := reportDao.InsertOrUpdateReport(reports, SourceETA)
  566. if esList == nil {
  567. return
  568. }
  569. return syncESAndSendMessage(esList)
  570. }
  571. type UpdateESReport struct {
  572. Title string `json:"title"`
  573. Author string `json:"author"`
  574. Abstract string `json:"abstract"`
  575. PublishedTime string `json:"publishedTime"`
  576. Status string `json:"status"`
  577. }
  578. func syncESAndSendMessage(reports []reportDao.Report) (err error) {
  579. var esReports []es.ESBase
  580. for _, etaRp := range reports {
  581. esRp := convertEsReport(etaRp)
  582. esReports = append(esReports, esRp)
  583. }
  584. //同步es
  585. for _, report := range reports {
  586. var exist bool
  587. exist, err = elastic().Exist(htConfig.GetReportIndex(), report.ID)
  588. if err != nil {
  589. logger.Error("查询es失败,reportId::%d,err:%v", report.ID, err)
  590. }
  591. if exist {
  592. update := UpdateESReport{
  593. Title: report.Title,
  594. Author: report.Author,
  595. PublishedTime: report.PublishedTime,
  596. Abstract: report.Abstract,
  597. Status: string(report.Status),
  598. }
  599. success := elastic().Update(htConfig.GetReportIndex(), report.ID, update)
  600. if !success {
  601. logger.Error("更新es失败,reportId::%d,err:%v", report.ID, err)
  602. }
  603. if report.Status == reportDao.StatusUnPublish {
  604. //隐藏热度搜索
  605. err = userDao.HiddenFlows(report.ID, message.ReportSourceType)
  606. if err != nil {
  607. logger.Error("隐藏热度搜索失败,reportId::%d,err:%v", report.ID, err)
  608. }
  609. } else {
  610. err = userDao.ShowFlows(report.ID, message.ReportSourceType)
  611. if err != nil {
  612. logger.Error("重置热度搜索失败,reportId::%d,err:%v", report.ID, err)
  613. }
  614. }
  615. } else {
  616. insert := ESReport{
  617. ReportID: report.ID,
  618. OrgId: report.OrgID,
  619. Title: report.Title,
  620. Author: report.Author,
  621. Source: report.Source,
  622. Abstract: report.Abstract,
  623. CoverSrc: report.CoverSrc,
  624. Status: report.Status,
  625. PublishedTime: report.PublishedTime,
  626. }
  627. success := elastic().CreateDocument(htConfig.GetReportIndex(), report.ID, insert)
  628. if !success {
  629. logger.Error("创建es文档失败,reportId::%d,err:%v", report.ID, err)
  630. }
  631. }
  632. }
  633. //err = elastic().BulkInsert(htConfig.GetReportIndex(), esReports)
  634. if err != nil {
  635. logger.Error("同步ETA研报到es失败:%v", err)
  636. return
  637. }
  638. //生产meta信息
  639. logger.Info("生成推送META信息")
  640. for _, report := range reports {
  641. if report.Status == reportDao.StatusUnPublish {
  642. logger.Info("报告取消发布,不需要生成推送消息")
  643. continue
  644. }
  645. var From string
  646. switch report.Source {
  647. case SourceETA:
  648. From = "ETA"
  649. case SourceHT:
  650. From = "HT"
  651. default:
  652. From = "UNKNOWN"
  653. }
  654. authors := strings.Split(report.Author, ",")
  655. authors = stringUtils.RemoveEmptyStrings(authors)
  656. if len(authors) > 0 {
  657. for _, authorName := range authors {
  658. userIds := userService.GetPostUser(authorName, report.PublishedTime)
  659. if len(userIds) > 0 {
  660. logger.Info("推送META信息,用户ID:%v", userIds)
  661. var author analystService.FinancialAnalystDTO
  662. author, err = analystService.GetAnalystByName(authorName)
  663. if err != nil {
  664. logger.Error("获取研报作者失败:%v", err)
  665. continue
  666. }
  667. usersStr := stringUtils.IntToStringSlice(userIds)
  668. Meta := messageDao.MetaData{
  669. AuthorName: author.Name,
  670. AuthorId: author.Id,
  671. SourceId: report.ID,
  672. PublishedTime: report.PublishedTime,
  673. }
  674. metaStr, _ := json.Marshal(Meta)
  675. toStr := strings.Join(usersStr, ",")
  676. metaContent := messageDomian.MetaInfoDTO{
  677. From: From,
  678. Meta: string(metaStr),
  679. MetaType: "USER_NOTICE",
  680. SourceType: "REPORT",
  681. To: toStr,
  682. }
  683. err = messageDomian.CreateMetaInfo(metaContent)
  684. if err != nil {
  685. logger.Error("创建Meta信息失败:%v", err)
  686. return err
  687. }
  688. }
  689. }
  690. }
  691. }
  692. return
  693. }
  694. func initES(reports []reportDao.Report) (err error) {
  695. var esReports []es.ESBase
  696. for _, etaRp := range reports {
  697. esRp := convertEsReport(etaRp)
  698. esReports = append(esReports, esRp)
  699. }
  700. //同步es
  701. err = elastic().BulkInsert(htConfig.GetReportIndex(), esReports)
  702. if err != nil {
  703. logger.Error("同步ETA研报到es失败:%v", err)
  704. return
  705. }
  706. return
  707. }
  708. func InitHTReportList(list []ht.HTReport) (noRecord bool, err error) {
  709. var reports []reportDao.Report
  710. //获取系统中ht品种名
  711. permissions, err := reportDao.GetGLAuthorNames()
  712. if err != nil {
  713. logger.Error("获取钢联研报作者失败:%v", err)
  714. return
  715. }
  716. for _, htRp := range list {
  717. for _, permission := range permissions {
  718. if htRp.PermissionName == permission.Permission {
  719. if permission.AuthorNames != "" {
  720. htRp.PublishUserName = permission.AuthorNames
  721. }
  722. destRp := convertHTReport(htRp, reportDao.StatusPublish)
  723. var coverSrc int
  724. var permissionId int
  725. permissionId, err = permissionDao.GetPermissionIdByName(htRp.PermissionName)
  726. //permissionId, err = etaDao.GetPermissionIdByName(htRp.PermissionName)
  727. if err != nil {
  728. logger.Error("HT获取eta品种id失败:%v", err)
  729. coverSrc = 0
  730. }
  731. var ids []int
  732. ids, err = mediaDao.GetIdsByPermissionId(permissionId)
  733. if err != nil {
  734. logger.Error("获取图片资源失败:%v", err)
  735. coverSrc = 0
  736. }
  737. if ids == nil || len(ids) == 0 {
  738. coverSrc = 0
  739. } else {
  740. src := rand.NewSource(time.Now().UnixNano())
  741. r := rand.New(src)
  742. // 从切片中随机选择一个元素
  743. randomIndex := r.Intn(len(ids))
  744. coverSrc = ids[randomIndex]
  745. }
  746. destRp.CoverSrc = coverSrc
  747. destRp.PlateName = htRp.PermissionName
  748. reports = append(reports, destRp)
  749. }
  750. //}
  751. }
  752. }
  753. if len(reports) == 0 {
  754. return true, nil
  755. } else {
  756. logger.Info("同步研报数量%d", len(reports))
  757. err = reportDao.BatchInsertReport(&reports)
  758. if err != nil {
  759. logger.Error("同步HT研报失败:%v", err)
  760. return false, err
  761. }
  762. return false, initES(reports)
  763. }
  764. }
  765. func htStatus(status int, isDelete int) reportDao.ReportStatus {
  766. if isDelete == 1 || status != ht.Publish {
  767. return reportDao.StatusUnPublish
  768. }
  769. return reportDao.StatusPublish
  770. }
  771. func SyncHTReportList(list []ht.HTReport) (noRecord bool, err error) {
  772. var reports []reportDao.Report
  773. permissions, err := reportDao.GetGLAuthorNames()
  774. if err != nil {
  775. logger.Error("获取钢联研报作者失败:%v", err)
  776. return
  777. }
  778. for _, htRp := range list {
  779. for _, permission := range permissions {
  780. if htRp.PermissionName == permission.Permission {
  781. if permission.AuthorNames != "" {
  782. htRp.PublishUserName = permission.AuthorNames
  783. }
  784. status := htStatus(htRp.Status, htRp.IsDelete)
  785. destRp := convertHTReport(htRp, status)
  786. var coverSrc int
  787. var permissionId int
  788. permissionId, err = permissionDao.GetPermissionIdByName(htRp.PermissionName)
  789. //permissionId, err = etaDao.GetPermissionIdByName(htRp.PermissionName)
  790. if err != nil {
  791. logger.Error("HT获取eta品种id失败:%v", err)
  792. coverSrc = 0
  793. }
  794. var ids []int
  795. ids, err = mediaDao.GetIdsByPermissionId(permissionId)
  796. if err != nil {
  797. logger.Error("获取图片资源失败:%v", err)
  798. coverSrc = 0
  799. }
  800. if ids == nil || len(ids) == 0 {
  801. coverSrc = 0
  802. } else {
  803. src := rand.NewSource(time.Now().UnixNano())
  804. r := rand.New(src)
  805. // 从切片中随机选择一个元素
  806. randomIndex := r.Intn(len(ids))
  807. coverSrc = ids[randomIndex]
  808. }
  809. destRp.CoverSrc = coverSrc
  810. destRp.PlateName = htRp.PermissionName
  811. reports = append(reports, destRp)
  812. }
  813. //}
  814. }
  815. }
  816. if len(reports) == 0 {
  817. return true, nil
  818. } else {
  819. logger.Info("同步研报数量%d", len(list))
  820. }
  821. esList, err := reportDao.InsertOrUpdateReport(reports, SourceHT)
  822. if esList == nil {
  823. return false, err
  824. }
  825. return false, syncESAndSendMessage(reports)
  826. }
  827. func GetListOrderByConditionWeekly(week bool, column string, limit int, order models.Order) (dtoList []ReportDTO, err error) {
  828. reports, err := reportDao.GetListOrderByCondition(week, column, limit, order)
  829. if err != nil {
  830. logger.Error("获取研报失败:%v", err)
  831. return
  832. }
  833. for _, reportItem := range reports {
  834. dto := convertReportDTO(reportItem, false)
  835. dtoList = append(dtoList, dto)
  836. }
  837. return
  838. }
  839. func GetListByCondition[T any](column string, ids []T) (dtoList []ReportDTO, err error) {
  840. var values []interface{}
  841. for _, id := range ids {
  842. values = append(values, id)
  843. }
  844. reports, err := reportDao.GetListByCondition(column, ids)
  845. if err != nil {
  846. logger.Error("获取研报失败:%v", err)
  847. return
  848. }
  849. for _, reportItem := range reports {
  850. dto := convertReportDTO(reportItem, false)
  851. dtoList = append(dtoList, dto)
  852. }
  853. return
  854. }
  855. func GetReportByIdListByOrgIds(orgIds map[string][]int) (ids []int, err error) {
  856. return reportDao.GetReportIdListByOrgIds(orgIds)
  857. }
  858. func getHtOrgIds(permissionIds []int) (htOrgIds []int, err error) {
  859. return GetHTReportIdsByPermissionIdsWithRiskLevel(permissionIds)
  860. }
  861. func getEtaOrgIds(permissionIds []int) (htOrgIds []int, err error) {
  862. return GetETAReportIdsByPermissionIdsWithRiskLevel(permissionIds)
  863. }
  864. func GetTotalPageCountByPermissionIds(permissionIds []int) (total int64, latestId int64, ids map[string][]int, disCardReportIds []int) {
  865. var wg sync.WaitGroup
  866. wg.Add(2)
  867. var htOrgIds []int
  868. var etaOrgIds []int
  869. go func() {
  870. defer wg.Done()
  871. var err error
  872. htOrgIds, err = getHtOrgIds(permissionIds)
  873. if err != nil {
  874. logger.Error("品种筛选ht报告id失败:%v", err)
  875. }
  876. }()
  877. go func() {
  878. defer wg.Done()
  879. var err error
  880. etaOrgIds, err = getEtaOrgIds(permissionIds)
  881. if err != nil {
  882. logger.Error("品种筛选eta报告id失败:%v", err)
  883. }
  884. }()
  885. wg.Wait()
  886. totalCol := int64(len(etaOrgIds) + len(htOrgIds))
  887. if totalCol == 0 {
  888. latestId = 0
  889. return
  890. }
  891. ids = make(map[string][]int, 2)
  892. if len(etaOrgIds) == 0 {
  893. ids["ETA"] = []int{}
  894. } else {
  895. ids["ETA"] = etaOrgIds
  896. }
  897. if len(htOrgIds) == 0 {
  898. ids["HT"] = []int{}
  899. } else {
  900. ids["HT"] = htOrgIds
  901. }
  902. //获取一下下架的报告产品
  903. offSaleProducts, err := merchantDao.GetOffSaleProducts([]merchantDao.MerchantProductType{merchantDao.Report, merchantDao.Package})
  904. if err != nil {
  905. logger.Error("获取下架的报告产品失败:%v", err)
  906. return
  907. }
  908. var ProductPermissionIds []int
  909. for _, product := range offSaleProducts {
  910. if product.Type == "package" {
  911. ProductPermissionIds = append(ProductPermissionIds, product.SourceId)
  912. }
  913. if product.Type == "report" {
  914. disCardReportIds = append(disCardReportIds, product.SourceId)
  915. }
  916. }
  917. if len(ProductPermissionIds) > 0 {
  918. wg.Add(2)
  919. var permissionNames []string
  920. var classifyIds []int
  921. go func() {
  922. defer wg.Done()
  923. var permissionErr error
  924. permissionNames, permissionErr = GetPermissionNamesByPermissionIds(ProductPermissionIds)
  925. if permissionErr != nil {
  926. logger.Error("获取ETA品种名称失败:%v", err)
  927. }
  928. }()
  929. go func() {
  930. defer wg.Done()
  931. var classifyErr error
  932. classifyIds, classifyErr = permissionDao.GetClassifyIdsByPermissionIds(ProductPermissionIds)
  933. if classifyErr != nil {
  934. logger.Error("获取ETA报告分类id失败:%v", err)
  935. }
  936. }()
  937. wg.Wait()
  938. disCardIds, _ := reportDao.GetHiddenReportIds(classifyIds, permissionNames)
  939. if len(disCardIds) > 0 {
  940. disCardReportIds = append(disCardReportIds, disCardIds...)
  941. }
  942. }
  943. //对数据去重
  944. disCardReportIds = uniqueArray(disCardReportIds)
  945. //获取报告中还包含上架套餐的id
  946. if len(disCardReportIds) > 0 {
  947. reportIdsSalePackage, _ := merchantDao.GetReportOnSalePackageIds(disCardReportIds)
  948. reportIdsSaleProduct, _ := merchantDao.GetOnSaleReportIds(disCardReportIds)
  949. showReportMap := make(map[int]bool)
  950. for _, reportId := range reportIdsSalePackage {
  951. showReportMap[reportId] = true
  952. }
  953. for _, reportId := range reportIdsSaleProduct {
  954. showReportMap[reportId] = true
  955. }
  956. var filterDisCardReportIds []int
  957. for _, id := range disCardReportIds {
  958. if _, ok := showReportMap[id]; !ok {
  959. filterDisCardReportIds = append(filterDisCardReportIds, id)
  960. }
  961. }
  962. disCardReportIds = filterDisCardReportIds
  963. }
  964. //获取这些id的产品
  965. total, latestId, err = reportDao.GetMaxIdByPermissionIds(ids, disCardReportIds)
  966. if err != nil {
  967. logger.Error("获取筛选报告的最大记录和记录数失败:%v", err)
  968. return
  969. }
  970. return
  971. }
  972. type etaReport struct {
  973. Id int `json:"id"`
  974. ClassifyId int `json:"classifyId"`
  975. PermissionIds []int `json:"permissionIds"`
  976. }
  977. type htReport struct {
  978. Id int `json:"id"`
  979. PlateName string `json:"plateName"`
  980. PermissionId []int `json:"permissionId"`
  981. }
  982. func uniqueArray(arr []int) []int {
  983. uniqueMap := make(map[int]bool)
  984. var result []int
  985. for _, value := range arr {
  986. if _, exists := uniqueMap[value]; !exists {
  987. uniqueMap[value] = true
  988. result = append(result, value)
  989. }
  990. }
  991. return result
  992. }
  993. func convertEtaReport(etaRp eta.ETAReport, status reportDao.ReportStatus) reportDao.Report {
  994. return reportDao.Report{
  995. OrgID: etaRp.ID,
  996. Title: etaRp.Title,
  997. Abstract: etaRp.Abstract,
  998. Author: etaRp.Author,
  999. ClassifyId: etaRp.ClassifyID,
  1000. CoverSrc: 0,
  1001. PublishedTime: etaRp.PublishTime.Format(time.DateTime),
  1002. Source: reportDao.SourceETA,
  1003. SendStatus: reportDao.UNSEND,
  1004. Status: status,
  1005. }
  1006. }
  1007. func convertHTReport(etaRp ht.HTReport, status reportDao.ReportStatus) reportDao.Report {
  1008. return reportDao.Report{
  1009. OrgID: etaRp.Id,
  1010. Title: etaRp.ReportName,
  1011. Author: etaRp.PublishUserName,
  1012. PublishedTime: etaRp.PublishedTime,
  1013. CoverSrc: 0,
  1014. Source: reportDao.SourceHT,
  1015. SendStatus: reportDao.UNSEND,
  1016. Status: status,
  1017. }
  1018. }
  1019. func convertEsReport(report reportDao.Report) ESReport {
  1020. return ESReport{
  1021. ReportID: report.ID,
  1022. Title: report.Title,
  1023. OrgId: report.OrgID,
  1024. Author: report.Author,
  1025. Source: report.Source,
  1026. Abstract: report.Abstract,
  1027. Status: report.Status,
  1028. CoverSrc: report.CoverSrc,
  1029. PublishedTime: report.PublishedTime,
  1030. }
  1031. }
  1032. func convertReportDTO(report reportDao.Report, fullTime bool) (reportDTO ReportDTO) {
  1033. reportDTO = ReportDTO{
  1034. ReportID: report.ID,
  1035. Title: report.Title,
  1036. OrgId: report.OrgID,
  1037. Author: report.Author,
  1038. Source: string(report.Source),
  1039. CoverSrc: report.CoverSrc,
  1040. Abstract: report.Abstract,
  1041. PublishedTime: report.PublishedTime,
  1042. PlateName: report.PlateName,
  1043. ClassifyId: report.ClassifyId,
  1044. }
  1045. publishDate, err := time.Parse(time.DateTime, reportDTO.PublishedTime)
  1046. if err == nil && !fullTime {
  1047. reportDTO.PublishedTime = publishDate.Format(time.DateOnly)
  1048. }
  1049. return
  1050. }
  1051. func matchAll(sorts []string, key string) (request *es.ESQueryRequest) {
  1052. req := new(es.ESQueryRequest)
  1053. return req.CreateESQueryRequest(htConfig.GetReportIndex(), ESColumn, key, 0, 1, sorts, es.MatchAllByCondition).ByCondition("status", "PUBLISH")
  1054. }
  1055. func match(key string, from int, to int, sorts []string) (request *es.ESQueryRequest) {
  1056. req := new(es.ESQueryRequest)
  1057. return req.CreateESQueryRequest(htConfig.GetReportIndex(), ESColumn, key, from, to, sorts, es.MatchAllByCondition).ByCondition("status", "PUBLISH")
  1058. }
  1059. func matchRange(key string, from int, to int, max int64, sorts []string) (request *es.ESQueryRequest) {
  1060. req := new(es.ESQueryRequest)
  1061. return req.CreateESQueryRequest(htConfig.GetReportIndex(), ESColumn, key, from, to, sorts, es.RangeByCondition).Range(0, max, ESRangeColumn).ByCondition("status", "PUBLISH")
  1062. }
  1063. func matchRangeByDocId(key string, from int, to int, max int64, sorts []string, docIds []string) (request *es.ESQueryRequest) {
  1064. req := new(es.ESQueryRequest)
  1065. return req.CreateESQueryRequest(htConfig.GetReportIndex(), ESColumn, key, from, to, sorts, es.RangeByConditionWithDocIds).Range(0, max, ESRangeColumn).ByCondition("status", "PUBLISH").WithDocs(docIds)
  1066. }
  1067. func matchRangeWithDocIds(key string, from int, to int, sorts []string, docIds []string) (request *es.ESQueryRequest) {
  1068. req := new(es.ESQueryRequest)
  1069. return req.CreateESQueryRequest(htConfig.GetReportIndex(), ESColumn, key, from, to, sorts, es.RangeByConditionWithDocIds).ByCondition("status", "PUBLISH").WithDocs(docIds)
  1070. }
  1071. func CountByDocId(key string, sorts []string, docIds []string) (request *es.ESQueryRequest) {
  1072. req := new(es.ESQueryRequest)
  1073. return req.CreateESQueryRequest(htConfig.GetReportIndex(), ESColumn, key, 0, 1, sorts, es.CountWithDocIds).WithDocs(docIds)
  1074. }
  1075. func matchLimitByScore(key string, limit int, score float64, docIds []string) (request *es.ESQueryRequest) {
  1076. req := new(es.ESQueryRequest)
  1077. return req.CreateESQueryRequest(htConfig.GetReportIndex(), ESColumn, key, 0, limit, sortField, es.LimitByScore).WithScore(score).WithDocs(docIds)
  1078. }
  1079. func SearchReportProduct(key string, limit int, score float64, docIds []int) (reports []ReportDTO, err error) {
  1080. var docStrIds []string
  1081. for _, id := range docIds {
  1082. docStrIds = append(docStrIds, strconv.Itoa(id))
  1083. }
  1084. request := matchLimitByScore(key, limit, score, docStrIds)
  1085. re, err := elastic().Search(request)
  1086. if err != nil {
  1087. logger.Error("es搜索异常:%v", err)
  1088. }
  1089. hits := elastic().GetSource(re.Hits)
  1090. if len(hits) == 0 {
  1091. reports = []ReportDTO{}
  1092. return
  1093. }
  1094. for _, hit := range hits {
  1095. var content map[string][]string
  1096. err = json.Unmarshal(hit.Highlight, &content)
  1097. report := ReportDTO{}
  1098. err = json.Unmarshal(hit.Source, &report)
  1099. if err != nil {
  1100. logger.Error("解析研报数据失败:%v", err)
  1101. continue
  1102. }
  1103. report.Score = hit.Score
  1104. report.Highlight = content[ESColumn]
  1105. report.Title = report.Highlight[0]
  1106. report.PublishedTime = report.PublishedTime[:10]
  1107. reports = append(reports, report)
  1108. }
  1109. return
  1110. }
  1111. type ProductSearchDTO struct {
  1112. HighLight string
  1113. SourceId int
  1114. SourceType string
  1115. Score float64
  1116. }
  1117. func CountPermissionWeight(ids []int) (list []configDao.PermissionWeight, err error) {
  1118. return reportDao.CountPermissionWeight(ids)
  1119. }
  1120. func FilterReportIds(sourceIds []int) (total int64, reportIds []int, err error) {
  1121. return reportDao.FilterReportIds(sourceIds)
  1122. }
  1123. func GetReportListById(reportIds []int) (reportList []ReportDTO, err error) {
  1124. reports, err := reportDao.GetReportListById(reportIds)
  1125. if err != nil {
  1126. return
  1127. }
  1128. for _, report := range reports {
  1129. reportList = append(reportList, convertReportDTO(report, false))
  1130. }
  1131. return
  1132. }