article.go 13 KB

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