english_policy_report.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. package services
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "github.com/PuerkitoBio/goquery"
  7. "github.com/rdlucklib/rdluck_tools/http"
  8. "hongze/hongze_open_api/models/tables"
  9. "hongze/hongze_open_api/services/alarm_msg"
  10. "hongze/hongze_open_api/utils"
  11. "html"
  12. "strconv"
  13. "strings"
  14. "time"
  15. )
  16. type EnPolicyReportDataListResp struct {
  17. Code int `json:"code"`
  18. Msg string `json:"msg"`
  19. Data []EnPolicyReportDataListItem `json:"data"`
  20. Pagination EnPolicyReportDataPage `json:"pagination"`
  21. }
  22. type EnPolicyReportDataDetailResp struct {
  23. Code int `json:"code"`
  24. Msg string `json:"msg"`
  25. Data EnPolicyReportDataListItem `json:"data"`
  26. }
  27. type EnPolicyReportDataPage struct {
  28. Total int `json:"total"`
  29. Page int `json:"page"`
  30. PageSize int `json:"page_size"`
  31. PageTotal int `json:"page_total"`
  32. }
  33. type EnPolicyReportDataListItem struct {
  34. Id int `json:"id"`
  35. Title string `json:"title"`
  36. TitleEn string `json:"title_en"`
  37. Frequency string `json:"frequency"`
  38. CreateDate time.Time `json:"create_date"`
  39. UpdateDate time.Time `json:"update_date"`
  40. PublishDate time.Time `json:"publish_date"`
  41. PublishStatus int `json:"publish_status"`
  42. VerifyStatus int `json:"verify_status"`
  43. PublishArea string `json:"publish_area"`
  44. AccessLevel int `json:"access_level"`
  45. IsActive bool `json:"is_active"`
  46. AuthorPhoneNumber string `json:"author_phone_number"`
  47. Cover string `json:"cover"`
  48. IndustryId int `json:"industry_id"`
  49. ContentId int `json:"content_id"`
  50. TypeId int `json:"type_id"`
  51. FieldId int `json:"field_id"`
  52. SeriesId int `json:"series_id"`
  53. File interface{} `json:"file"`
  54. Stock []string `json:"stock"`
  55. IsFocused int `json:"is_focused"`
  56. Content EnPolicyReportDataListItemContent `json:"content"`
  57. Industry EnPolicyReportDataListItemInfo `json:"industry"`
  58. Type EnPolicyReportDataListItemInfo `json:"type"`
  59. Field EnPolicyReportDataListItemInfoMore `json:"field"`
  60. Series EnPolicyReportDataListItemInfoMore `json:"series"`
  61. Author EnPolicyReportDataListItemAuthor `json:"author"`
  62. }
  63. type EnPolicyReportDataListItemContent struct {
  64. Id int `json:"id"`
  65. Body string `json:"body"`
  66. Abstract string `json:"abstract"`
  67. Annotation string `json:"annotation"`
  68. }
  69. type EnPolicyReportDataListItemInfo struct {
  70. Id int `json:"id"`
  71. Name string `json:"name"`
  72. Description string `json:"description"`
  73. }
  74. type EnPolicyReportDataListItemInfoMore struct {
  75. Id int `json:"id"`
  76. Name string `json:"name"`
  77. Description string `json:"description"`
  78. IndustryId int `json:"industry_id"`
  79. }
  80. type EnPolicyReportDataListItemAuthor struct {
  81. PhoneNumber string `json:"phone_number"`
  82. Name string `json:"name"`
  83. }
  84. // PullEnglishPolicyReportSingle 根据报告ID 拉取报告
  85. func PullEnglishPolicyReportSingle(sourceId int) (ret tables.PullEnglishPolicyDataResp, err error, msg string) {
  86. defer func() {
  87. if err != nil {
  88. go alarm_msg.SendAlarmMsg("拉取单个英文策略报告失败,Err:"+err.Error()+";msg:"+msg, 3)
  89. utils.FileLog.Info(fmt.Sprintf("拉取单个英文策略报告失败 PullEnglishPolicyReportSingle,Err:%s,%s", err.Error(), msg))
  90. }
  91. }()
  92. //获取已插入的报告ID,避免重复插入
  93. _, err = tables.GetEnglishPolicyReportBySourceReportId(sourceId)
  94. if err != nil {
  95. if err.Error() == utils.ErrNoRow() {
  96. err = nil
  97. } else {
  98. msg = "查询已存在的英文策略报告列表接口失败"
  99. return
  100. }
  101. } else {
  102. // 该报告已存在
  103. return
  104. }
  105. originDetail, e := getOriginPolicyReportDetail(sourceId)
  106. if e != nil {
  107. msg = "拉取英文策略报告详情失败"
  108. err = e
  109. return
  110. }
  111. if originDetail.IndustryId != 1 || originDetail.FieldId != 1 || originDetail.TypeId != 9 {
  112. // 类型不匹配,当前只获取英文策略报告
  113. return
  114. }
  115. tmp := &tables.EnglishPolicyReport{
  116. ClassifyIdFirst: originDetail.Industry.Id,
  117. ClassifyNameFirst: originDetail.Industry.Description,
  118. ClassifyIdSecond: originDetail.FieldId,
  119. ClassifyNameSecond: originDetail.Field.Description,
  120. Title: originDetail.TitleEn,
  121. Abstract: originDetail.Content.Abstract,
  122. Author: originDetail.Author.Name,
  123. Frequency: originDetail.Frequency,
  124. CreateTime: time.Now(),
  125. ModifyTime: time.Now(),
  126. State: 1,
  127. Content: originDetail.Content.Body,
  128. PublishStatus: originDetail.PublishStatus,
  129. PublishTime: originDetail.PublishDate,
  130. KeyTakeaways: originDetail.Content.Annotation,
  131. AuthorMobile: originDetail.AuthorPhoneNumber,
  132. SourceReportId: originDetail.Id,
  133. ReportCoverUrl: originDetail.Cover,
  134. }
  135. err = tables.AddEnglishPolicyReport(tmp)
  136. if err != nil {
  137. msg = "新增英文策略报告信息失败"
  138. return
  139. }
  140. //同步到英文研报
  141. err, msg = EnglishPolicyReportSync(tmp.Id)
  142. return
  143. }
  144. func getOriginPolicyReportDetail(id int) (detail EnPolicyReportDataListItem, err error) {
  145. //设置接口地址
  146. //处理返回值
  147. url := utils.EnPolicyReportUrl + `articles/en/%d`
  148. url = fmt.Sprintf(url, id)
  149. utils.FileLog.Info("url:%s", url)
  150. body, err := http.Get(url)
  151. fmt.Println("getOriginPolicyReportDetail body:")
  152. fmt.Println(string(body))
  153. item := new(EnPolicyReportDataDetailResp)
  154. err = json.Unmarshal(body, &item)
  155. if err != nil {
  156. return
  157. }
  158. if item.Code != 0 {
  159. err = fmt.Errorf("getOriginPolicyReportDetail ErrCode: %d, ErrMsg: %s", item.Code, item.Msg)
  160. return
  161. }
  162. detail = item.Data
  163. return
  164. }
  165. // EnglishPolicyReportSync 英文策略报告一键同步功能
  166. func EnglishPolicyReportSync(id int) (err error, errMsg string) {
  167. //查询报告是否存在
  168. policyReport, err := tables.GetEnglishPolicyReportById(id)
  169. if err != nil {
  170. if err.Error() == utils.ErrNoRow() {
  171. err = fmt.Errorf("报告不存在!")
  172. return
  173. }
  174. errMsg = "获取报告信息失败,Err:" + err.Error()
  175. err = fmt.Errorf("获取报告信息失败")
  176. return
  177. }
  178. //判断报告是否已同步
  179. if policyReport.State == 2 {
  180. err = fmt.Errorf("报告已同步,无需重复同步")
  181. return
  182. }
  183. //新增英文研报
  184. classifyNameFirst := "Equity"
  185. classifySecondName := "A-share Daily"
  186. // 根据分类名称查询分类ID
  187. classifyInfo, err := tables.GetEnglishClassifyByClassifyNameAndParentName(classifyNameFirst, classifySecondName)
  188. if err != nil {
  189. if err.Error() == utils.ErrNoRow() {
  190. err = fmt.Errorf("报告分类不存在!")
  191. return
  192. }
  193. errMsg = "获取报告分类失败,Err:" + err.Error()
  194. err = fmt.Errorf("获取报告分类失败")
  195. return
  196. }
  197. // 获取期数
  198. maxStage, err := tables.GetEnglishReportStage(classifyInfo.ParentId, classifyInfo.Id)
  199. if err != nil {
  200. errMsg = "期数获取失败,Err:" + err.Error()
  201. err = fmt.Errorf("期数获取失败")
  202. return
  203. }
  204. var contentSub string
  205. if policyReport.Content != "" {
  206. contentSub, err = GetReportContentSub(policyReport.Content)
  207. if err != nil {
  208. go alarm_msg.SendAlarmMsg("策略报告 一键同步 ContentSub 失败,Err:"+err.Error(), 3)
  209. }
  210. }
  211. item := new(tables.EnglishReport)
  212. item.AddType = 1
  213. item.ClassifyIdFirst = classifyInfo.ParentId
  214. item.ClassifyNameFirst = classifyInfo.ParentClassifyName
  215. item.ClassifyIdSecond = classifyInfo.Id
  216. item.ClassifyNameSecond = classifyInfo.ClassifyName
  217. item.Title = "China A-share Daily Check-in"
  218. item.Abstract = "China A-share market and economic data review"
  219. item.Author = "Horizon Insights FICC Team"
  220. item.Frequency = policyReport.Frequency
  221. item.State = 1
  222. item.Content = policyReport.Content
  223. item.Stage = maxStage + 1
  224. item.ContentSub = html.EscapeString(contentSub)
  225. item.CreateTime = time.Now().Format(utils.FormatDateTime)
  226. item.ModifyTime = time.Now()
  227. item.Overview = policyReport.Abstract
  228. item.KeyTakeaways = policyReport.KeyTakeaways
  229. item.FromReportId = policyReport.Id
  230. newReportId, err := tables.AddEnglishReport(item)
  231. if err != nil {
  232. errMsg = "保存研报失败,Err:" + err.Error()
  233. err = fmt.Errorf("保存研报失败")
  234. return
  235. }
  236. reportCode := utils.MD5(strconv.Itoa(int(newReportId)))
  237. //修改唯一编码
  238. err = tables.ModifyEnglishReportCode(newReportId, reportCode)
  239. if err != nil {
  240. errMsg = "更新英文研报失败,Err:" + err.Error()
  241. err = fmt.Errorf("更新英文研报失败")
  242. return
  243. }
  244. //更新策略报告状态为已同步
  245. if err = tables.SyncEnglishPolicyReportById(policyReport.Id, int(newReportId)); err != nil {
  246. errMsg = "更新策略报告失败,Err:" + err.Error()
  247. err = fmt.Errorf("更新策略报告失败")
  248. return
  249. }
  250. return
  251. }
  252. func GetReportContentSub(content string) (contentSub string, err error) {
  253. content = html.UnescapeString(content)
  254. doc, err := goquery.NewDocumentFromReader(strings.NewReader(content))
  255. if err != nil {
  256. fmt.Println("create doc err:", err.Error())
  257. return
  258. }
  259. n := 0
  260. doc.Find("p").Each(func(i int, s *goquery.Selection) {
  261. if n >= 5 {
  262. return
  263. }
  264. n++
  265. phtml, err := s.Html()
  266. if err != nil {
  267. fmt.Println("get html err", err.Error())
  268. return
  269. }
  270. if s.Text() != "" || strings.Contains(phtml, "src") {
  271. contentSub = contentSub + "<p>" + phtml + "</p>"
  272. }
  273. })
  274. return
  275. }
  276. type ApiDebugResponse struct {
  277. Code int `json:"code"`
  278. Msg string `json:"msg"`
  279. ErrMsg string `json:"err_msg"`
  280. }
  281. func TestDebugEnglishPolicyReport(id int) (err error) {
  282. url := fmt.Sprintf("http://8.136.199.33:8608/api/en/report/notify?id=%d", id)
  283. ret, err := http.Get(url)
  284. if err != nil {
  285. return
  286. }
  287. var resp ApiDebugResponse
  288. err = json.Unmarshal(ret, &resp)
  289. if err != nil {
  290. return
  291. }
  292. if resp.Code != 200 {
  293. err = errors.New(resp.Msg)
  294. return
  295. }
  296. return
  297. }