article.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  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 = 1
  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. }
  104. return
  105. }
  106. //func init() {
  107. // GetArticleSubjectLabelByArticleId([]int{9551, 9082})
  108. //}
  109. // 根据文章ID获取文章关联的产业名称
  110. func GetArticleIndustrialLabelByArticleId(articleIds []int) (respMap map[int][]string) {
  111. if len(articleIds) == 0 {
  112. return
  113. }
  114. var err error
  115. defer func() {
  116. if err != nil {
  117. go alarm_msg.SendAlarmMsg(fmt.Sprint("根据文章ID获取文章关联的产业名称失败 GetArticleIndustrialLabelByArticleId rticleIds: ", articleIds, err.Error()), 2)
  118. }
  119. }()
  120. list, e := cygx.GetIndustrialArticleGroupListByarticleIdsArr(articleIds)
  121. if e != nil && e.Error() != utils.ErrNoRow() {
  122. err = errors.New("GetIndustrialArticleGroupListByarticleIdsArr, Err: " + e.Error())
  123. return
  124. }
  125. respMap = make(map[int][]string, 0)
  126. for _, v := range list {
  127. respMap[v.ArticleId] = append(respMap[v.ArticleId], v.IndustryName)
  128. }
  129. return
  130. }
  131. // 根据文章ID获取文章关联的标的名称
  132. func GetArticleSubjectLabelByArticleId(articleIds []int) (respMap map[int][]string) {
  133. if len(articleIds) == 0 {
  134. return
  135. }
  136. var err error
  137. defer func() {
  138. if err != nil {
  139. go alarm_msg.SendAlarmMsg(fmt.Sprint("根据文章ID获取文章关联的产业名称 失败 GetArticleSubjectLabelByArticleId rticleIds: ", articleIds, err.Error()), 2)
  140. }
  141. }()
  142. list, e := cygx.GetSubjectArticleGroupListByarticleIdsArr(articleIds)
  143. if e != nil && e.Error() != utils.ErrNoRow() {
  144. err = errors.New("GetIndustrialArticleGroupListByarticleIdsArr, Err: " + e.Error())
  145. return
  146. }
  147. respMap = make(map[int][]string, 0)
  148. for _, v := range list {
  149. respMap[v.ArticleId] = append(respMap[v.ArticleId], v.SubjectName)
  150. }
  151. return
  152. }
  153. // 根据作者ID获取关联的文章下面的产业名称
  154. func GetArticleIndustrialLabelByDepartmentId(departmentIds []int) (respMap map[int][]string) {
  155. lenArr := len(departmentIds)
  156. if lenArr == 0 {
  157. return
  158. }
  159. var err error
  160. defer func() {
  161. if err != nil {
  162. go alarm_msg.SendAlarmMsg(fmt.Sprint("根据文章ID获取文章关联的产业名称失败 GetArticleIndustrialLabelByDepartmentId departmentIds: ", departmentIds, err.Error()), 2)
  163. }
  164. }()
  165. var condition string
  166. var pars []interface{}
  167. condition = " AND department_id IN(" + utils.GetOrmInReplace(lenArr) + ") ORDER BY publish_date DESC "
  168. pars = append(pars, departmentIds)
  169. //获取作者关联的文章
  170. listArticle, e := cygx.GetArticlList(condition, pars, 0, 9999)
  171. if e != nil && e.Error() != utils.ErrNoRow() {
  172. err = errors.New("GetArticlList, Err: " + e.Error())
  173. return
  174. }
  175. var articleIds []int
  176. for _, v := range listArticle {
  177. articleIds = append(articleIds, v.ArticleId)
  178. }
  179. //获取文章关联的产业
  180. list, e := cygx.GetIndustrialArticleGroupListByarticleIdsArr(articleIds)
  181. if e != nil && e.Error() != utils.ErrNoRow() {
  182. err = errors.New("GetIndustrialArticleGroupListByarticleIdsArr, Err: " + e.Error())
  183. return
  184. }
  185. respMap = make(map[int][]string, 0)
  186. artMap := make(map[int][]string)
  187. for _, v := range list {
  188. artMap[v.ArticleId] = append(respMap[v.ArticleId], v.IndustryName)
  189. }
  190. //建立作者与文章、产业的关系
  191. for _, v := range listArticle {
  192. if len(artMap[v.ArticleId]) == 0 {
  193. continue
  194. }
  195. respMap[v.DepartmentId] = append(respMap[v.DepartmentId], strings.Join(artMap[v.ArticleId], "/"))
  196. }
  197. return
  198. }
  199. // 处理文章、研选专栏的查询信息回显
  200. func HandleArticleAndYanxuanRecordList(items []*cygx.CygxArticleAndYanxuanRecordResp) (itemsResp []*cygx.UserInteraction, err error) {
  201. itemsResp = make([]*cygx.UserInteraction, 0)
  202. if len(items) > 0 {
  203. var articleIds []int // 文章ID
  204. var yanxuanSpecialIds []int // 研选专栏ID
  205. var sellerCompanyIds []int // 公司ID
  206. for _, v := range items {
  207. if v.Source == utils.CYGX_OBJ_ARTICLE {
  208. articleIds = append(articleIds, v.SourceId)
  209. }
  210. if v.Source == utils.CYGX_OBJ_YANXUANSPECIAL {
  211. yanxuanSpecialIds = append(yanxuanSpecialIds, v.SourceId)
  212. }
  213. sellerCompanyIds = append(sellerCompanyIds, v.CompanyId)
  214. }
  215. sellNameMap := services.GetSellNameMapByCompanyIds(sellerCompanyIds)
  216. mapIndustrialLabel := GetArticleIndustrialLabelByArticleId(articleIds) // 关联产业
  217. mapSubjectLabel := GetArticleSubjectLabelByArticleId(articleIds) // 关联标的
  218. var condition string
  219. var pars []interface{}
  220. //获取文章map
  221. mapArticle := make(map[int]*cygx.CygxReportArticle)
  222. lenarticleIds := len(articleIds)
  223. if lenarticleIds > 0 {
  224. condition = " AND art.article_id IN (" + utils.GetOrmInReplace(lenarticleIds) + ") GROUP BY art.article_id "
  225. pars = append(pars, articleIds)
  226. list, e := cygx.GetReportArticleList(condition, pars, 0, lenarticleIds, 1)
  227. if e != nil && e.Error() != utils.ErrNoRow() {
  228. err = e
  229. return
  230. }
  231. if len(list) > 0 {
  232. for _, v := range list {
  233. mapArticle[v.ArticleId] = v
  234. }
  235. }
  236. }
  237. //获取研选专栏map
  238. mapYanxuanSpecial := make(map[int]*cygx.CygxYanxuanSpeciaResplItem)
  239. lenyanxuanSpecialIds := len(yanxuanSpecialIds)
  240. if lenyanxuanSpecialIds > 0 {
  241. pars = make([]interface{}, 0)
  242. condition = " AND a.id IN (" + utils.GetOrmInReplace(lenyanxuanSpecialIds) + ")"
  243. pars = append(pars, yanxuanSpecialIds)
  244. list, e := cygx.GetYanxuanSpecialListByCondition(condition, pars, 0, lenyanxuanSpecialIds)
  245. if e != nil && e.Error() != utils.ErrNoRow() {
  246. err = e
  247. return
  248. }
  249. if len(list) > 0 {
  250. for _, v := range list {
  251. mapYanxuanSpecial[v.Id] = v
  252. }
  253. }
  254. }
  255. for _, v := range items {
  256. item := new(cygx.UserInteraction)
  257. if v.Source == utils.CYGX_OBJ_ARTICLE {
  258. item.IndustryName = strings.Join(mapIndustrialLabel[v.SourceId], ",")
  259. item.SubjectNameStr = strings.Join(mapSubjectLabel[v.SourceId], ",")
  260. if v.SourceId >= utils.SummaryArticleId {
  261. item.ArticleType = 1
  262. } else {
  263. item.ArticleType = 2
  264. }
  265. //如果对应的map不为空,就赋值
  266. if mapArticle[v.SourceId] != nil {
  267. item.Title = mapArticle[v.SourceId].Title
  268. item.PublishDate = mapArticle[v.SourceId].PublishDate
  269. item.PermissionName = mapArticle[v.SourceId].PermissionName
  270. item.ArticleIdMd5 = mapArticle[v.SourceId].ArticleIdMd5
  271. }
  272. }
  273. if v.Source == utils.CYGX_OBJ_YANXUANSPECIAL {
  274. item.PermissionName = utils.CHART_PERMISSION_NAME_MF_YANXUAN
  275. //如果对应的map不为空,就赋值
  276. if mapYanxuanSpecial[v.SourceId] != nil {
  277. item.Title = mapYanxuanSpecial[v.SourceId].Title
  278. item.PublishDate = mapYanxuanSpecial[v.SourceId].PublishTime
  279. item.SpecialType = mapYanxuanSpecial[v.SourceId].Type
  280. }
  281. }
  282. item.ArticleId = v.SourceId
  283. item.CreateTime = v.CreateTime
  284. item.UserId = v.UserId
  285. item.RealName = v.RealName
  286. item.Mobile = v.Mobile
  287. item.CompanyId = v.CompanyId
  288. item.CompanyName = v.CompanyName
  289. item.SellerName = sellNameMap[v.CompanyId]
  290. item.RegisterPlatform = v.RegisterPlatform
  291. item.StopTime = strconv.Itoa(v.StopTime)
  292. itemsResp = append(itemsResp, item)
  293. }
  294. }
  295. return
  296. }
  297. //
  298. //func init() {
  299. // SendWxMsgWithroadshowEssence(1000546)
  300. //}
  301. // 路演精华的文章做模板消息推送
  302. func SendWxMsgWithroadshowEssence(articleId int) (err error) {
  303. defer func() {
  304. if err != nil {
  305. fmt.Println(err)
  306. go alarm_msg.SendAlarmMsg("路演精华的文章做模板消息推送送,发送模版消息失败,Err:"+err.Error(), 3)
  307. utils.FileLog.Info(fmt.Sprintf("路演精华的文章做模板消息推送失败,Err:%s,%s", err.Error()))
  308. }
  309. }()
  310. detail, e := cygx.GetArticleRoadshowEssenceDetail(articleId)
  311. if e != nil {
  312. err = errors.New("获取详情失败" + e.Error())
  313. return
  314. }
  315. if detail == nil {
  316. err = errors.New("获取详情失败")
  317. return
  318. }
  319. //fmt.Println(detail)
  320. permissionStr, e := company.GetPermissionIdById(strconv.Itoa(detail.ChartPermissionId))
  321. if e != nil {
  322. err = errors.New("获取主客观权限失败" + e.Error())
  323. return
  324. }
  325. // 获取所有有权的用户的 openid
  326. openidPowerList, e := cygx.GetCygxUserRecordPower(permissionStr)
  327. if e != nil {
  328. err = errors.New("获取所有有权的用户的 openid失败" + e.Error())
  329. return
  330. }
  331. //获取关注对应产业的用户信息
  332. industryFllowList, e := cygx.GetCygxUserFllowOpenid(articleId)
  333. if e != nil {
  334. err = errors.New("获取关注对应产业的用户信息失败 " + e.Error())
  335. return
  336. }
  337. mapOpenidFllow := make(map[int]string)
  338. for _, v := range industryFllowList {
  339. mapOpenidFllow[v.UserId] = v.OpenId
  340. }
  341. //获取拒绝接收推送的的用户的 openid
  342. mapOpenidRefuset := make(map[int]string)
  343. openidRefusetList, e := cygx.GetCygxUserRefusetOpenid()
  344. if e != nil && e.Error() != utils.ErrNoRow() {
  345. err = errors.New("获取拒绝接收推送的的用户的 openid 失败" + e.Error())
  346. return
  347. }
  348. for _, v := range openidRefusetList {
  349. mapOpenidRefuset[v.UserId] = v.OpenId
  350. }
  351. //获取提交过推送规则的用户的 openid
  352. mapUserIdChooseSend := make(map[int]int)
  353. chooseSendtList, err := cygx.GetCygxXzsChooseSend("")
  354. if err != nil && err.Error() != utils.ErrNoRow() {
  355. return err
  356. }
  357. for _, v := range chooseSendtList {
  358. mapUserIdChooseSend[v.UserId] = v.UserId
  359. }
  360. openIdArr := make([]string, len(openidPowerList))
  361. for i, v := range openidPowerList {
  362. if _, ok := mapOpenidRefuset[v.UserId]; ok {
  363. continue //如果用户选择了拒绝推送消息,那么就不做模板消息推送
  364. }
  365. if _, ok := mapUserIdChooseSend[v.UserId]; ok {
  366. if _, ok := mapOpenidFllow[v.UserId]; !ok {
  367. continue //如果用户提交过关注信息,而且这个产业他没有关注,那么不做推送
  368. }
  369. }
  370. openIdArr[i] = v.OpenId
  371. }
  372. fmt.Println(openIdArr)
  373. first := "【路演精华】已发布,欢迎查看"
  374. keyword1 := detail.Title
  375. keyword2 := "已发布"
  376. keyword3 := detail.PublishDate
  377. keyword4 := detail.Abstract
  378. remark := "点击查看详情"
  379. redirectUrl := utils.WX_MSG_PATH_ROAD_ESSENCE + strconv.Itoa(detail.ArticleId) + "&IsSendWx=1"
  380. sendInfo := new(services.SendWxTemplate)
  381. sendInfo.First = first
  382. sendInfo.Keyword1 = keyword1
  383. sendInfo.Keyword2 = keyword2
  384. sendInfo.Keyword3 = keyword3
  385. sendInfo.Keyword4 = keyword4
  386. sendInfo.Remark = remark
  387. sendInfo.TemplateId = utils.WxMsgTemplateIdActivityChangeApplyXzs
  388. sendInfo.RedirectUrl = redirectUrl
  389. sendInfo.RedirectTarget = 3
  390. sendInfo.Resource = strconv.Itoa(detail.ArticleId)
  391. sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_ROADSHOW_VIDEO
  392. sendInfo.OpenIdArr = openIdArr
  393. e = services.SendTemplateMsg(sendInfo)
  394. if e != nil {
  395. err = errors.New("推送模板消息失败" + e.Error())
  396. return
  397. }
  398. return
  399. }