report.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. package services
  2. import (
  3. "errors"
  4. "eta/eta_task/models"
  5. "eta/eta_task/services/alarm_msg"
  6. "eta/eta_task/utils"
  7. "fmt"
  8. "golang.org/x/net/context"
  9. "html"
  10. "strconv"
  11. "strings"
  12. "time"
  13. )
  14. // UpdateReportEs 更新报告/章节Es
  15. func UpdateReportEs(reportId int, publishState int) (err error) {
  16. if reportId <= 0 {
  17. return
  18. }
  19. reportInfo, err := models.GetReportByReportId(reportId)
  20. if err != nil {
  21. return
  22. }
  23. categories := ""
  24. if reportInfo.HasChapter == 1 {
  25. // 晨周报
  26. chapterList, tmpErr := models.GetPublishedChapterListByReportId(reportInfo.Id)
  27. if tmpErr != nil {
  28. return
  29. }
  30. if len(chapterList) > 0 {
  31. for i := 0; i < len(chapterList); i++ {
  32. // 章节对应的品种
  33. permissionList, tmpErr := models.GetChapterTypePermissionByTypeIdAndResearchType(chapterList[i].TypeId, chapterList[i].ReportType)
  34. if tmpErr != nil {
  35. return
  36. }
  37. categoryArr := make([]string, 0)
  38. if len(permissionList) > 0 {
  39. for ii := 0; ii < len(permissionList); ii++ {
  40. categoryArr = append(categoryArr, permissionList[ii].PermissionName)
  41. }
  42. }
  43. aliasArr, _ := addCategoryAliasToArr(categoryArr)
  44. chapterCategories := strings.Join(aliasArr, ",")
  45. esChapter := &models.ElasticReportDetail{
  46. ReportId: chapterList[i].ReportId,
  47. ReportChapterId: chapterList[i].ReportChapterId,
  48. Title: chapterList[i].Title,
  49. Abstract: chapterList[i].Abstract,
  50. BodyContent: utils.TrimHtml(html.UnescapeString(chapterList[i].Content)),
  51. PublishTime: chapterList[i].PublishTime.Format(utils.FormatDateTime),
  52. PublishState: chapterList[i].PublishState,
  53. Author: chapterList[i].Author,
  54. ClassifyIdFirst: chapterList[i].ClassifyIdFirst,
  55. ClassifyNameFirst: chapterList[i].ClassifyNameFirst,
  56. ClassifyIdSecond: 0,
  57. ClassifyNameSecond: "",
  58. Categories: chapterCategories,
  59. StageStr: strconv.Itoa(chapterList[i].Stage),
  60. }
  61. chapterDocId := fmt.Sprintf("%d-%d", reportInfo.Id, chapterList[i].ReportChapterId)
  62. if err = EsAddOrEditReport(utils.EsReportIndexName, chapterDocId, esChapter); err != nil {
  63. return
  64. }
  65. }
  66. }
  67. } else {
  68. permissionList, tmpErr := models.GetChartPermissionNameFromMappingByKeyword(reportInfo.ClassifyNameSecond, "rddp")
  69. if tmpErr != nil {
  70. return
  71. }
  72. categoryArr := make([]string, 0)
  73. for i := 0; i < len(permissionList); i++ {
  74. categoryArr = append(categoryArr, permissionList[i].PermissionName)
  75. }
  76. aliasArr, _ := addCategoryAliasToArr(categoryArr)
  77. categories = strings.Join(aliasArr, ",")
  78. }
  79. // 新增报告ES
  80. esReport := &models.ElasticReportDetail{
  81. ReportId: reportInfo.Id,
  82. ReportChapterId: 0,
  83. Title: reportInfo.Title,
  84. Abstract: reportInfo.Abstract,
  85. BodyContent: utils.TrimHtml(html.UnescapeString(reportInfo.Content)),
  86. PublishTime: reportInfo.PublishTime.Format(utils.FormatDateTime),
  87. PublishState: publishState,
  88. Author: reportInfo.Author,
  89. ClassifyIdFirst: reportInfo.ClassifyIdFirst,
  90. ClassifyNameFirst: reportInfo.ClassifyNameFirst,
  91. ClassifyIdSecond: reportInfo.ClassifyIdSecond,
  92. ClassifyNameSecond: reportInfo.ClassifyNameSecond,
  93. Categories: categories,
  94. StageStr: strconv.Itoa(reportInfo.Stage),
  95. }
  96. docId := fmt.Sprintf("%d-%d", reportInfo.Id, 0)
  97. if err = EsAddOrEditReport(utils.EsReportIndexName, docId, esReport); err != nil {
  98. return
  99. }
  100. return
  101. }
  102. // addCategoryAliasToArr 品种别名
  103. func addCategoryAliasToArr(categoryArr []string) (aliasArr []string, err error) {
  104. aliasArr = categoryArr
  105. if len(categoryArr) > 0 {
  106. for i := 0; i < len(categoryArr); i++ {
  107. if strings.Contains(categoryArr[i], "沥青") {
  108. aliasArr = append(aliasArr, "BU")
  109. }
  110. if strings.Contains(categoryArr[i], "MEG") {
  111. aliasArr = append(aliasArr, "EG", "乙二醇")
  112. }
  113. if strings.Contains(categoryArr[i], "聚酯") {
  114. aliasArr = append(aliasArr, "长丝", "短纤", "瓶片")
  115. }
  116. if strings.Contains(categoryArr[i], "纯苯+苯乙烯") {
  117. aliasArr = append(aliasArr, "EB")
  118. }
  119. if strings.Contains(categoryArr[i], "聚乙烯") {
  120. aliasArr = append(aliasArr, "PP", "PE")
  121. }
  122. if strings.Contains(categoryArr[i], "玻璃纯碱") {
  123. aliasArr = append(aliasArr, "玻璃", "纯碱", "FG", "SA")
  124. }
  125. if strings.Contains(categoryArr[i], "甲醇") {
  126. aliasArr = append(aliasArr, "甲醇", "MA")
  127. }
  128. if strings.Contains(categoryArr[i], "橡胶") {
  129. aliasArr = append(aliasArr, "橡胶", "RU")
  130. }
  131. }
  132. }
  133. return
  134. }
  135. // PublishReport 定时发布研报-每秒
  136. func PublishReport(cont context.Context) (err error) {
  137. defer func() {
  138. if err != nil {
  139. go alarm_msg.SendAlarmMsg("PublishReport-定时发布研报失败, ErrMsg:\n"+err.Error(), 3)
  140. }
  141. }()
  142. now := time.Now().Format(utils.FormatDateTimeMinute)
  143. startTime := now + ":00"
  144. endTime := now + ":59"
  145. afterDate := time.Now().AddDate(0, -1, 0).Format(utils.FormatDate) //限制一下,只查询最近一个月的
  146. list, err := models.GetPrePublishedReports(startTime, endTime, afterDate)
  147. if err != nil {
  148. return
  149. }
  150. listLen := len(list)
  151. if listLen == 0 {
  152. return
  153. }
  154. // 比对时间(分钟),时间相等则发布并推送
  155. for i := 0; i < listLen; i++ {
  156. item := list[i]
  157. var publishTime time.Time
  158. if item.MsgIsSend == 1 && !item.PublishTime.IsZero() { //如果报告曾经发布过,并且已经发送过模版消息,则章节的发布时间为报告的发布时间
  159. publishTime = item.PublishTime
  160. } else {
  161. publishTime = time.Now()
  162. }
  163. if item.HasChapter == 1 && (item.ChapterType == utils.REPORT_TYPE_DAY || item.ChapterType == utils.REPORT_TYPE_WEEK) {
  164. continue
  165. }
  166. if err = models.PublishReportById(item.Id, publishTime); err != nil {
  167. return
  168. }
  169. go func() {
  170. // 生成音频
  171. if item.VideoUrl == "" {
  172. _ = CreateVideo(item)
  173. }
  174. //// 推送找钢网
  175. //if utils.RunMode == "release" && (report.ClassifyNameSecond == "知白守黑日评" || report.ClassifyNameSecond == "股债日评") {
  176. // _ = services.ZhaoGangSend(report)
  177. //}
  178. // 更新报告Es
  179. _ = UpdateReportEs(item.Id, 2)
  180. // 判断是否未发送模版消息,并且配置了立即推送模版消息的报告需要推送
  181. if utils.SendWxTemplateEnable == "1" {
  182. if item.MsgIsSend == 0 && item.PreMsgSend == 1 {
  183. _ = ReportSendTemplateMsg(item.Id)
  184. }
  185. }
  186. }()
  187. recordItem := &models.ReportStateRecord{
  188. ReportId: item.Id,
  189. ReportType: 1,
  190. State: 2,
  191. AdminId: item.AdminId,
  192. AdminName: item.AdminName,
  193. CreateTime: time.Now(),
  194. }
  195. go func() {
  196. _, _ = models.AddReportStateRecord(recordItem)
  197. }()
  198. }
  199. return
  200. }
  201. // PublishReportTest 定时发布研报-每秒
  202. /*func PublishReportTest() (err error) {
  203. defer func() {
  204. if err != nil {
  205. fmt.Println(err.Error())
  206. }
  207. }()
  208. item, err := models.GetReportById(3331)
  209. if err != nil {
  210. return
  211. }
  212. // 判断是否未发送模版消息,并且配置了立即推送模版消息的报告需要推送
  213. if item.MsgIsSend == 0 && item.PreMsgSend == 1 {
  214. err = ReportSendTemplateMsg(item.Id)
  215. if err != nil {
  216. return
  217. }
  218. }
  219. return
  220. }*/
  221. func ReportSendTemplateMsg(reportId int) (err error) {
  222. defer func() {
  223. if err != nil {
  224. msg := fmt.Sprintf("ReportSendTemplateMsg, 发送报告模版消息失败, ReportId:%s, Err:%s", reportId, err.Error())
  225. utils.FileLog.Error(msg)
  226. go alarm_msg.SendAlarmMsg(msg, 3)
  227. }
  228. }()
  229. report, err := models.GetReportById(reportId)
  230. if err != nil {
  231. err = errors.New("查询报告失败 Err:" + err.Error())
  232. return
  233. }
  234. if report.MsgIsSend == 1 {
  235. err = errors.New("模板消息已推送,请勿重复操作")
  236. return
  237. }
  238. videoNameDate := `(` + time.Now().Format("0102") + `)`
  239. err = models.UpdateReportPublishTime(reportId, videoNameDate)
  240. if err != nil {
  241. err = errors.New("修改发布时间失败,Err:" + err.Error())
  242. return
  243. }
  244. if report.HasChapter > 0 {
  245. err = models.UpdateReportChapterPublishTime(reportId, videoNameDate)
  246. if err != nil {
  247. err = errors.New("修改发布时间失败,Err:" + err.Error())
  248. return
  249. }
  250. }
  251. err = sendMiniProgramReportWxMsg(report)
  252. if err != nil {
  253. err = errors.New("发送失败,Err:" + err.Error())
  254. return
  255. }
  256. err = models.ModifyReportMsgIsSend(reportId)
  257. if err != nil {
  258. err = errors.New("发送失败,Err:" + err.Error())
  259. return
  260. }
  261. return
  262. }
  263. // sendMiniProgramReportWxMsg 推送报告微信模板消息-小程序链接
  264. func sendMiniProgramReportWxMsg(report *models.ReportDetail) (err error) {
  265. reportId := report.Id
  266. var msg string
  267. reportIdStr := strconv.Itoa(reportId)
  268. defer func() {
  269. if err != nil {
  270. fmt.Println("msg:", msg)
  271. utils.FileLog.Error(fmt.Sprintf("SendMiniProgramReportWxMsg, 发送报告模版消息失败, ReportId:%s, Err:%s", reportIdStr, err.Error()))
  272. go alarm_msg.SendAlarmMsg("SendMiniProgramReportWxMsg发送报告模版消息失败;"+"ReportId:"+reportIdStr+",Err:"+err.Error()+";msg:"+msg, 3)
  273. //go utils.SendEmail("SendMiniProgramReportWxMsg发送报告模版消息失败"+"【"+utils.APPNAME+"】"+"【"+utils.RunMode+"】"+time.Now().Format("2006-01-02 15:04:05"), "ReportId:"+reportIdStr+";"+msg+";Err:"+err.Error(), toUser)
  274. }
  275. }()
  276. utils.FileLog.Info("%s", "services SendMsg")
  277. if report == nil {
  278. utils.FileLog.Info("报告信息不存在")
  279. return
  280. }
  281. var openIdArr []string
  282. if report.ClassifyIdSecond <= 0 {
  283. openIdArr, err = models.GetOpenIdArr()
  284. if err != nil {
  285. msg = "get GetOpenIdArr err:" + err.Error()
  286. return
  287. }
  288. } else {
  289. classify, err := models.GetClassifyById(report.ClassifyIdSecond)
  290. if err != nil {
  291. msg = "获取报告分类失败 err:" + err.Error()
  292. return err
  293. }
  294. if classify.IsMassSend == 1 {
  295. openIdArr, err = models.GetOpenIdArr()
  296. if err != nil {
  297. msg = "get GetOpenIdArr err:" + err.Error()
  298. return err
  299. }
  300. } else {
  301. openIdArr, err = models.GetOpenIdArrByClassifyNameSecond(report.ClassifyNameSecond)
  302. if err != nil {
  303. msg = "GetOpenIdArrByClassifyNameSecond err:" + err.Error()
  304. return err
  305. }
  306. }
  307. }
  308. title := fmt.Sprintf("弘则%s", report.ClassifyNameFirst)
  309. if CheckTwoWeekOrMonthReport(report.ClassifyIdFirst, report.ClassifyNameFirst) {
  310. title = fmt.Sprintf("弘则%s", report.ClassifyNameSecond)
  311. }
  312. //redirectUrl := utils.TemplateRedirectUrl + strconv.Itoa(reportId)
  313. first := fmt.Sprintf("Hi,最新一期%s已上线,欢迎查看", report.ClassifyNameFirst)
  314. keyword1 := title
  315. keyword2 := report.Title
  316. keyword3 := report.PublishTime
  317. keyword4 := report.Abstract
  318. var wxAppPath string
  319. if report.ChapterType == utils.REPORT_TYPE_WEEK {
  320. wxAppPath = fmt.Sprintf("pages-report/chapterList?reportId=%s", reportIdStr)
  321. } else {
  322. wxAppPath = fmt.Sprintf("pages-report/reportDetail?reportId=%s", reportIdStr)
  323. }
  324. sendInfo := new(SendWxTemplate)
  325. sendInfo.First = first
  326. sendInfo.Keyword1 = keyword1
  327. sendInfo.Keyword2 = keyword2
  328. sendInfo.Keyword3 = keyword3
  329. sendInfo.Keyword4 = keyword4
  330. sendInfo.TemplateId = utils.TemplateIdByProduct
  331. sendInfo.RedirectUrl = wxAppPath
  332. sendInfo.Resource = wxAppPath
  333. sendInfo.SendType = utils.TEMPLATE_MSG_REPORT
  334. sendInfo.OpenIdArr = openIdArr
  335. sendInfo.RedirectTarget = 1
  336. err = SendTemplateMsgV2(sendInfo)
  337. return
  338. }
  339. // CheckTwoWeekOrMonthReport 校验推送报告是否为双周报或者月报
  340. func CheckTwoWeekOrMonthReport(classifyId int, classifyName string) (ok bool) {
  341. if utils.RunMode == "debug" {
  342. miniStrArr := []string{
  343. "双周报", "月报",
  344. }
  345. if utils.InArrayByStr(miniStrArr, classifyName) {
  346. ok = true
  347. }
  348. } else {
  349. // 此处生产环境用ID主要是担心分类改了名字...
  350. IdArr := []int{
  351. 96, 112,
  352. }
  353. if utils.InArrayByInt(IdArr, classifyId) {
  354. ok = true
  355. }
  356. }
  357. return
  358. }
  359. // ClearReportSaveLog 每天清理两周前的报告保存日志
  360. func ClearReportSaveLog(cont context.Context) (err error) {
  361. defer func() {
  362. if err != nil {
  363. tips := fmt.Sprintf("报告日志记录, SaveReportLogs error: %s", err.Error())
  364. fmt.Println(tips)
  365. go alarm_msg.SendAlarmMsg(tips, 2)
  366. }
  367. }()
  368. twoWeek := time.Now().Local().AddDate(0, 0, -14).Format(utils.FormatDateTime)
  369. e := models.ClearReportSaveLog(twoWeek)
  370. if e != nil {
  371. err = fmt.Errorf("ClearReportSaveLog: %s", e.Error())
  372. }
  373. return
  374. }