article.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. package cygx
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/PuerkitoBio/goquery"
  6. "hongze/hz_crm_api/models/company"
  7. "hongze/hz_crm_api/models/cygx"
  8. "hongze/hz_crm_api/services"
  9. "hongze/hz_crm_api/services/alarm_msg"
  10. "hongze/hz_crm_api/utils"
  11. "html"
  12. "strconv"
  13. "strings"
  14. )
  15. func ArticlePublishDate(publishDate string) (newPublishDate string) {
  16. newPublishDate = strings.Replace(publishDate, "00:00:00", "", -1)
  17. newPublishDate = strings.Replace(newPublishDate, " ", "", -1)
  18. return
  19. }
  20. func GetReportContentTextSubNew(content string) (contentSub string, err error) {
  21. content = html.UnescapeString(content)
  22. doc, errdoc := goquery.NewDocumentFromReader(strings.NewReader(content))
  23. if errdoc != nil {
  24. err = errdoc
  25. return
  26. }
  27. docText := doc.Text()
  28. bodyRune := []rune(docText)
  29. bodyRuneLen := len(bodyRune)
  30. body := string(bodyRune[:bodyRuneLen])
  31. contentSub = body
  32. contentSub = strings.Replace(contentSub, "Powered by Froala Editor", "", -1)
  33. contentSub = strings.Replace(contentSub, " ", "", -1)
  34. contentSub = strings.Replace(contentSub, "<p data-f-id=\"pbf\" style=\"text-align: center; font-size: 14px; margin-top: 30px; opacity: 0.65; font-family: sanered by <a href=\"https://www.froala.com/wysiwyg-editor?pb=1\" title=\"Froala Editor\">Froala Editor</a></p>", "", -1)
  35. return
  36. }
  37. func ArticleComPanyLabelToStr(companyLabel []string) (label string) {
  38. for _, v := range companyLabel {
  39. label += v + "{|}"
  40. }
  41. label = strings.TrimRight(label, "{|}")
  42. return
  43. }
  44. // GetArticleStockMap 获取个股标签所对应的文章ID
  45. func GetArticleStockMap() (mapResp map[string]int, err error) {
  46. defer func() {
  47. if err != nil {
  48. go alarm_msg.SendAlarmMsg("获取个股标签所对应的文章ID失败"+err.Error(), 2)
  49. }
  50. }()
  51. list, err := cygx.GetArticleStock()
  52. if err != nil && err.Error() != utils.ErrNoRow() {
  53. return
  54. }
  55. mapResp = make(map[string]int, 0)
  56. if len(list) > 0 {
  57. //一对一精准匹配
  58. for _, v := range list {
  59. sliceSubjects := strings.Split(v.Stock, "/")
  60. if len(sliceSubjects) > 0 {
  61. for _, vSubject := range sliceSubjects {
  62. sliceKuohao := strings.Split(vSubject, "(") //过滤括号
  63. sliceXiahuaxian := strings.Split(sliceKuohao[0], "-") //过滤下划线
  64. subject := sliceXiahuaxian[0]
  65. mapResp[subject] = v.ArticleId
  66. }
  67. }
  68. }
  69. }
  70. return
  71. }
  72. // 处理文章来源类型
  73. func GetArticleSourcePlatform(SourcePlatform string) (sourcePlatformResp int) {
  74. //SourcePlatform string `description:"来源 'MOBILE:移动端小程序','PC:PC端小程序','CELUE:上海策略平台','WEB:查研观向网页版'"`
  75. if SourcePlatform == "MOBILE" || SourcePlatform == "PC" {
  76. sourcePlatformResp = 1
  77. } else if SourcePlatform == "WEB" {
  78. sourcePlatformResp = 2
  79. } else if SourcePlatform == "CELUE" {
  80. sourcePlatformResp = 3
  81. } else if SourcePlatform == "1" {
  82. sourcePlatformResp = 1
  83. } else if SourcePlatform == "2" {
  84. sourcePlatformResp = 2
  85. } else {
  86. sourcePlatformResp, _ = strconv.Atoi(SourcePlatform)
  87. }
  88. return
  89. }
  90. // 处理文章来源类型
  91. func GetArticleSourcePlatformText(sourcePlatformResp int) (sourcePlatformText string) {
  92. switch sourcePlatformResp {
  93. case 1:
  94. sourcePlatformText = "查研小程序"
  95. case 2:
  96. sourcePlatformText = "查研网页版"
  97. case 3:
  98. sourcePlatformText = "策略平台"
  99. case 5:
  100. sourcePlatformText = "研选小程序"
  101. case 6:
  102. sourcePlatformText = "研选网页版"
  103. default:
  104. sourcePlatformText = "查研小程序"
  105. }
  106. return
  107. }
  108. //func init() {
  109. // GetArticleSubjectLabelByArticleId([]int{9551, 9082})
  110. //}
  111. // 根据文章ID获取文章关联的产业名称
  112. func GetArticleIndustrialLabelByArticleId(articleIds []int) (respMap map[int][]string) {
  113. if len(articleIds) == 0 {
  114. return
  115. }
  116. var err error
  117. defer func() {
  118. if err != nil {
  119. go alarm_msg.SendAlarmMsg(fmt.Sprint("根据文章ID获取文章关联的产业名称失败 GetArticleIndustrialLabelByArticleId rticleIds: ", articleIds, err.Error()), 2)
  120. }
  121. }()
  122. list, e := cygx.GetIndustrialArticleGroupListByarticleIdsArr(articleIds)
  123. if e != nil && e.Error() != utils.ErrNoRow() {
  124. err = errors.New("GetIndustrialArticleGroupListByarticleIdsArr, Err: " + e.Error())
  125. return
  126. }
  127. respMap = make(map[int][]string, 0)
  128. for _, v := range list {
  129. respMap[v.ArticleId] = append(respMap[v.ArticleId], v.IndustryName)
  130. }
  131. return
  132. }
  133. // 根据文章ID获取文章关联的标的名称
  134. func GetArticleSubjectLabelByArticleId(articleIds []int) (respMap map[int][]string) {
  135. if len(articleIds) == 0 {
  136. return
  137. }
  138. var err error
  139. defer func() {
  140. if err != nil {
  141. go alarm_msg.SendAlarmMsg(fmt.Sprint("根据文章ID获取文章关联的产业名称 失败 GetArticleSubjectLabelByArticleId rticleIds: ", articleIds, err.Error()), 2)
  142. }
  143. }()
  144. list, e := cygx.GetSubjectArticleGroupListByarticleIdsArr(articleIds)
  145. if e != nil && e.Error() != utils.ErrNoRow() {
  146. err = errors.New("GetIndustrialArticleGroupListByarticleIdsArr, Err: " + e.Error())
  147. return
  148. }
  149. respMap = make(map[int][]string, 0)
  150. for _, v := range list {
  151. respMap[v.ArticleId] = append(respMap[v.ArticleId], v.SubjectName)
  152. }
  153. return
  154. }
  155. // 根据作者ID获取关联的文章下面的产业名称
  156. func GetArticleIndustrialLabelByDepartmentId(departmentIds []int) (respMap map[int][]string) {
  157. lenArr := len(departmentIds)
  158. if lenArr == 0 {
  159. return
  160. }
  161. var err error
  162. defer func() {
  163. if err != nil {
  164. go alarm_msg.SendAlarmMsg(fmt.Sprint("根据文章ID获取文章关联的产业名称失败 GetArticleIndustrialLabelByDepartmentId departmentIds: ", departmentIds, err.Error()), 2)
  165. }
  166. }()
  167. var condition string
  168. var pars []interface{}
  169. condition = " AND department_id IN(" + utils.GetOrmInReplace(lenArr) + ") ORDER BY publish_date DESC "
  170. pars = append(pars, departmentIds)
  171. //获取作者关联的文章
  172. listArticle, e := cygx.GetArticlList(condition, pars, 0, 9999)
  173. if e != nil && e.Error() != utils.ErrNoRow() {
  174. err = errors.New("GetArticlList, Err: " + e.Error())
  175. return
  176. }
  177. var articleIds []int
  178. for _, v := range listArticle {
  179. articleIds = append(articleIds, v.ArticleId)
  180. }
  181. //获取文章关联的产业
  182. list, e := cygx.GetIndustrialArticleGroupListByarticleIdsArr(articleIds)
  183. if e != nil && e.Error() != utils.ErrNoRow() {
  184. err = errors.New("GetIndustrialArticleGroupListByarticleIdsArr, Err: " + e.Error())
  185. return
  186. }
  187. respMap = make(map[int][]string, 0)
  188. artMap := make(map[int][]string)
  189. for _, v := range list {
  190. artMap[v.ArticleId] = append(respMap[v.ArticleId], v.IndustryName)
  191. }
  192. //建立作者与文章、产业的关系
  193. for _, v := range listArticle {
  194. if len(artMap[v.ArticleId]) == 0 {
  195. continue
  196. }
  197. respMap[v.DepartmentId] = append(respMap[v.DepartmentId], strings.Join(artMap[v.ArticleId], "/"))
  198. }
  199. return
  200. }
  201. // 处理文章、研选专栏的查询信息回显
  202. func HandleArticleAndYanxuanRecordList(items []*cygx.CygxArticleAndYanxuanRecordResp) (itemsResp []*cygx.UserInteraction, err error) {
  203. itemsResp = make([]*cygx.UserInteraction, 0)
  204. if len(items) > 0 {
  205. var articleIds []int // 文章ID
  206. var yanxuanSpecialIds []int // 研选专栏ID
  207. var sellerCompanyIds []int // 公司ID
  208. for _, v := range items {
  209. if v.Source == utils.CYGX_OBJ_ARTICLE {
  210. articleIds = append(articleIds, v.SourceId)
  211. }
  212. if v.Source == utils.CYGX_OBJ_YANXUANSPECIAL {
  213. yanxuanSpecialIds = append(yanxuanSpecialIds, v.SourceId)
  214. }
  215. sellerCompanyIds = append(sellerCompanyIds, v.CompanyId)
  216. }
  217. sellNameMap := services.GetSellNameMapByCompanyIds(sellerCompanyIds)
  218. mapIndustrialLabel := GetArticleIndustrialLabelByArticleId(articleIds) // 关联产业
  219. mapSubjectLabel := GetArticleSubjectLabelByArticleId(articleIds) // 关联标的
  220. var condition string
  221. var pars []interface{}
  222. //获取文章map
  223. mapArticle := make(map[int]*cygx.CygxReportArticle)
  224. lenarticleIds := len(articleIds)
  225. if lenarticleIds > 0 {
  226. condition = " AND art.article_id IN (" + utils.GetOrmInReplace(lenarticleIds) + ") GROUP BY art.article_id "
  227. pars = append(pars, articleIds)
  228. list, e := cygx.GetReportArticleList(condition, pars, 0, lenarticleIds, 1)
  229. if e != nil && e.Error() != utils.ErrNoRow() {
  230. err = e
  231. return
  232. }
  233. if len(list) > 0 {
  234. for _, v := range list {
  235. mapArticle[v.ArticleId] = v
  236. }
  237. }
  238. }
  239. //获取研选专栏map
  240. mapYanxuanSpecial := make(map[int]*cygx.CygxYanxuanSpeciaResplItem)
  241. lenyanxuanSpecialIds := len(yanxuanSpecialIds)
  242. if lenyanxuanSpecialIds > 0 {
  243. pars = make([]interface{}, 0)
  244. condition = " AND a.id IN (" + utils.GetOrmInReplace(lenyanxuanSpecialIds) + ")"
  245. pars = append(pars, yanxuanSpecialIds)
  246. list, e := cygx.GetYanxuanSpecialListByCondition(condition, pars, 0, lenyanxuanSpecialIds)
  247. if e != nil && e.Error() != utils.ErrNoRow() {
  248. err = e
  249. return
  250. }
  251. if len(list) > 0 {
  252. for _, v := range list {
  253. mapYanxuanSpecial[v.Id] = v
  254. }
  255. }
  256. }
  257. for _, v := range items {
  258. item := new(cygx.UserInteraction)
  259. if v.Source == utils.CYGX_OBJ_ARTICLE {
  260. item.IndustryName = strings.Join(mapIndustrialLabel[v.SourceId], ",")
  261. item.SubjectNameStr = strings.Join(mapSubjectLabel[v.SourceId], ",")
  262. if v.SourceId >= utils.SummaryArticleId {
  263. item.ArticleType = 1
  264. } else {
  265. item.ArticleType = 2
  266. }
  267. //如果对应的map不为空,就赋值
  268. if mapArticle[v.SourceId] != nil {
  269. item.Title = mapArticle[v.SourceId].Title
  270. item.PublishDate = mapArticle[v.SourceId].PublishDate
  271. item.PermissionName = mapArticle[v.SourceId].PermissionName
  272. item.ArticleIdMd5 = mapArticle[v.SourceId].ArticleIdMd5
  273. item.ReportId = mapArticle[v.SourceId].ReportId
  274. }
  275. }
  276. if v.Source == utils.CYGX_OBJ_YANXUANSPECIAL {
  277. item.PermissionName = utils.CHART_PERMISSION_NAME_MF_YANXUAN
  278. //如果对应的map不为空,就赋值
  279. if mapYanxuanSpecial[v.SourceId] != nil {
  280. item.Title = mapYanxuanSpecial[v.SourceId].Title
  281. item.PublishDate = mapYanxuanSpecial[v.SourceId].PublishTime
  282. item.SpecialType = mapYanxuanSpecial[v.SourceId].Type
  283. }
  284. }
  285. item.ArticleId = v.SourceId
  286. item.CreateTime = v.CreateTime
  287. item.UserId = v.UserId
  288. item.RealName = v.RealName
  289. item.Mobile = v.Mobile
  290. item.CompanyId = v.CompanyId
  291. item.CompanyName = v.CompanyName
  292. item.SellerName = sellNameMap[v.CompanyId]
  293. item.RegisterPlatform = v.RegisterPlatform
  294. item.RegisterPlatformText = GetArticleSourcePlatformText(v.RegisterPlatform)
  295. item.StopTime = strconv.Itoa(v.StopTime)
  296. itemsResp = append(itemsResp, item)
  297. }
  298. }
  299. return
  300. }
  301. //
  302. //func init() {
  303. // SendWxMsgWithroadshowEssence(1000546)
  304. //}
  305. // 路演精华的文章做模板消息推送
  306. func SendWxMsgWithroadshowEssence(articleId int) (err error) {
  307. defer func() {
  308. if err != nil {
  309. fmt.Println(err)
  310. go alarm_msg.SendAlarmMsg("路演精华的文章做模板消息推送送,发送模版消息失败,Err:"+err.Error(), 3)
  311. utils.FileLog.Info(fmt.Sprintf("路演精华的文章做模板消息推送失败,Err:%s,%s", err.Error()))
  312. }
  313. }()
  314. detail, e := cygx.GetArticleRoadshowEssenceDetail(articleId)
  315. if e != nil {
  316. err = errors.New("获取详情失败" + e.Error())
  317. return
  318. }
  319. if detail == nil {
  320. err = errors.New("获取详情失败")
  321. return
  322. }
  323. //fmt.Println(detail)
  324. permissionStr, e := company.GetPermissionIdById(strconv.Itoa(detail.ChartPermissionId))
  325. if e != nil {
  326. err = errors.New("获取主客观权限失败" + e.Error())
  327. return
  328. }
  329. // 获取所有有权的用户的 openid
  330. openidPowerList, e := cygx.GetCygxUserRecordPower(permissionStr)
  331. if e != nil {
  332. err = errors.New("获取所有有权的用户的 openid失败" + e.Error())
  333. return
  334. }
  335. //获取关注对应产业的用户信息
  336. industryFllowList, e := cygx.GetCygxUserFllowOpenid(articleId)
  337. if e != nil {
  338. err = errors.New("获取关注对应产业的用户信息失败 " + e.Error())
  339. return
  340. }
  341. mapOpenidFllow := make(map[int]string)
  342. for _, v := range industryFllowList {
  343. mapOpenidFllow[v.UserId] = v.OpenId
  344. }
  345. //获取拒绝接收推送的的用户的 openid
  346. mapOpenidRefuset := make(map[int]string)
  347. openidRefusetList, e := cygx.GetCygxUserRefusetOpenid()
  348. if e != nil && e.Error() != utils.ErrNoRow() {
  349. err = errors.New("获取拒绝接收推送的的用户的 openid 失败" + e.Error())
  350. return
  351. }
  352. for _, v := range openidRefusetList {
  353. mapOpenidRefuset[v.UserId] = v.OpenId
  354. }
  355. //获取提交过推送规则的用户的 openid
  356. mapUserIdChooseSend := make(map[int]int)
  357. chooseSendtList, err := cygx.GetCygxXzsChooseSend("")
  358. if err != nil && err.Error() != utils.ErrNoRow() {
  359. return err
  360. }
  361. for _, v := range chooseSendtList {
  362. mapUserIdChooseSend[v.UserId] = v.UserId
  363. }
  364. openIdArr := make([]string, len(openidPowerList))
  365. for i, v := range openidPowerList {
  366. if _, ok := mapOpenidRefuset[v.UserId]; ok {
  367. continue //如果用户选择了拒绝推送消息,那么就不做模板消息推送
  368. }
  369. if _, ok := mapUserIdChooseSend[v.UserId]; ok {
  370. if _, ok := mapOpenidFllow[v.UserId]; !ok {
  371. continue //如果用户提交过关注信息,而且这个产业他没有关注,那么不做推送
  372. }
  373. }
  374. openIdArr[i] = v.OpenId
  375. }
  376. fmt.Println(openIdArr)
  377. first := "【路演精华】已发布,欢迎查看"
  378. keyword1 := detail.Title
  379. keyword2 := "已发布"
  380. keyword3 := detail.PublishDate
  381. keyword4 := detail.Abstract
  382. remark := "点击查看详情"
  383. redirectUrl := utils.WX_MSG_PATH_ROAD_ESSENCE + strconv.Itoa(detail.ArticleId) + "&IsSendWx=1"
  384. sendInfo := new(services.SendWxTemplate)
  385. sendInfo.First = first
  386. sendInfo.Keyword1 = keyword1
  387. sendInfo.Keyword2 = keyword2
  388. sendInfo.Keyword3 = keyword3
  389. sendInfo.Keyword4 = keyword4
  390. sendInfo.Remark = remark
  391. sendInfo.TemplateId = utils.WxMsgTemplateIdActivityChangeApplyXzs
  392. sendInfo.RedirectUrl = redirectUrl
  393. sendInfo.RedirectTarget = 3
  394. sendInfo.Resource = strconv.Itoa(detail.ArticleId)
  395. sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ROADSHOW_VIDEO
  396. sendInfo.OpenIdArr = openIdArr
  397. e = services.SendTemplateMsg(sendInfo)
  398. if e != nil {
  399. err = errors.New("推送模板消息失败" + e.Error())
  400. return
  401. }
  402. return
  403. }