wechat_send_msg.go 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. package services
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "hongze/hz_eta_api/models"
  8. "hongze/hz_eta_api/models/system"
  9. "hongze/hz_eta_api/services/alarm_msg"
  10. "hongze/hz_eta_api/utils"
  11. "io/ioutil"
  12. "net/http"
  13. "strconv"
  14. "strings"
  15. "time"
  16. )
  17. func SendWxTemplateMsg(reportId int) (err error) {
  18. var msg string
  19. defer func() {
  20. if err != nil {
  21. go alarm_msg.SendAlarmMsg("发送模版消息失败,Err:"+err.Error()+";msg:"+msg, 3)
  22. //go utils.SendEmail("发送模版消息失败"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  23. utils.FileLog.Info(fmt.Sprintf("发送模版消息失败,Err:%s,%s", err.Error(), msg))
  24. }
  25. if msg != "" {
  26. utils.FileLog.Info(fmt.Sprintf("发送模版消息失败,msg:%s", msg))
  27. }
  28. }()
  29. utils.FileLog.Info("%s", "services SendMsg")
  30. report, err := models.GetReportById(reportId)
  31. if err != nil {
  32. msg = "GetReportInfo Err:" + err.Error()
  33. return
  34. }
  35. if report == nil {
  36. utils.FileLog.Info("报告信息不存在")
  37. return
  38. }
  39. //accessToken, err := models.GetWxAccessToken()
  40. //if err != nil {
  41. // msg = "GetWxAccessToken Err:" + err.Error()
  42. // return
  43. //}
  44. //if accessToken == "" {
  45. // msg = "accessToken is empty"
  46. // return
  47. //}
  48. openIdArr, err := models.GetOpenIdArr()
  49. if err != nil {
  50. msg = "get GetOpenIdArr err:" + err.Error()
  51. return
  52. }
  53. //sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  54. //fmt.Println("send start")
  55. //utils.FileLog.Info("send start")
  56. ////if report.MsgIsSend == 0 {
  57. //sendMap := make(map[string]interface{})
  58. //sendData := make(map[string]interface{})
  59. redirectUrl := utils.TemplateRedirectUrl + strconv.Itoa(reportId)
  60. keyword1 := "弘则日度点评"
  61. first := "Hi,最新一期日度点评已上线,欢迎查看"
  62. if CheckTwoWeekOrMonthReport(report.ClassifyIdFirst, report.ClassifyNameFirst) {
  63. keyword1 = fmt.Sprintf("弘则%s", report.ClassifyNameSecond)
  64. first = fmt.Sprintf("Hi,最新一期%s已上线,欢迎查看", report.ClassifyNameFirst)
  65. }
  66. keyword2 := report.Title
  67. //keyword3 := report.PublishTime.Format(utils.FormatDateTime)
  68. keyword3 := report.PublishTime
  69. keyword4 := report.Abstract
  70. //sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  71. //sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  72. //sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  73. //sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": "#173177"}
  74. //sendData["keyword4"] = map[string]interface{}{"value": keyword4, "color": "#173177"}
  75. //
  76. //sendMap["template_id"] = utils.TemplateIdByProduct
  77. //sendMap["url"] = redirectUrl
  78. //sendMap["data"] = sendData
  79. //sendTemplateMsg(sendUrl, sendMap, openIdList, strconv.Itoa(reportId), utils.TEMPLATE_MSG_REPORT)
  80. //}
  81. sendInfo := new(SendWxTemplate)
  82. sendInfo.First = first
  83. sendInfo.Keyword1 = keyword1
  84. sendInfo.Keyword2 = keyword2
  85. sendInfo.Keyword3 = keyword3
  86. sendInfo.Keyword4 = keyword4
  87. sendInfo.TemplateId = utils.TemplateIdByProduct
  88. sendInfo.RedirectUrl = redirectUrl
  89. sendInfo.RedirectTarget = 1
  90. sendInfo.Resource = strconv.Itoa(reportId)
  91. sendInfo.SendType = utils.TEMPLATE_MSG_REPORT
  92. sendInfo.OpenIdArr = openIdArr
  93. err = SendTemplateMsg(sendInfo)
  94. return
  95. }
  96. func sendTemplateMsg(sendUrl string, sendMap map[string]interface{}, items []*models.OpenIdList, resource string, sendType int) (err error) {
  97. for _, v := range items {
  98. sendMap["touser"] = v.OpenId
  99. data, err := json.Marshal(sendMap)
  100. if err != nil {
  101. fmt.Println("SendTemplateMsgOne Marshal Err:", err.Error())
  102. utils.FileLog.Info(fmt.Sprintf("SendTemplateMsgOne Marshal Err:%s", err.Error()))
  103. return err
  104. }
  105. err = toSendTemplateMsg(sendUrl, data, resource, sendType, v)
  106. if err != nil {
  107. fmt.Println("send err:", err.Error())
  108. utils.FileLog.Info(fmt.Sprintf("ToSendTemplateMsg Err:%s", err.Error()))
  109. }
  110. }
  111. return
  112. }
  113. func toSendTemplateMsg(sendUrl string, data []byte, resource string, sendType int, dataItem *models.OpenIdList) (err error) {
  114. var msg string
  115. utils.FileLog.Info("Send:" + string(data))
  116. client := http.Client{}
  117. resp, err := client.Post(sendUrl, "application/json", bytes.NewBuffer(data))
  118. if err != nil {
  119. return
  120. }
  121. defer resp.Body.Close()
  122. body, _ := ioutil.ReadAll(resp.Body)
  123. utils.FileLog.Info("SendResult:" + string(body))
  124. var templateResponse SendTemplateResponse
  125. err = json.Unmarshal(body, &templateResponse)
  126. if err != nil {
  127. utils.FileLog.Info(fmt.Sprintf("SendResult Unmarshal Err:%s", err.Error()))
  128. return err
  129. }
  130. //新增模板消息推送记录
  131. {
  132. tr := new(models.UserTemplateRecord)
  133. tr.UserId = dataItem.UserId
  134. tr.OpenId = dataItem.OpenId
  135. tr.Resource = resource
  136. tr.SendData = string(data)
  137. tr.Result = string(body)
  138. tr.CreateDate = time.Now().Format(utils.FormatDate)
  139. tr.CreateTime = time.Now().Format(utils.FormatDateTime)
  140. if templateResponse.Errcode == 0 {
  141. tr.SendStatus = 1
  142. } else {
  143. tr.SendStatus = 0
  144. }
  145. tr.SendType = sendType
  146. go func() {
  147. err = models.AddUserTemplateRecord(tr)
  148. if err != nil {
  149. utils.FileLog.Info(fmt.Sprintf("AddUserTemplateRecord Err:%s", err.Error()))
  150. }
  151. }()
  152. }
  153. accessToken, err := models.GetWxAccessToken()
  154. if err != nil {
  155. msg = "GetWxAccessToken Err:" + err.Error()
  156. utils.FileLog.Info("获取Token失败,msg:" + msg)
  157. return
  158. }
  159. if accessToken == "" {
  160. msg = "accessToken is empty"
  161. utils.FileLog.Info("accessToken为空,msg:" + msg)
  162. return
  163. }
  164. //模板消息发送超过当日10万次限制错误处理
  165. if templateResponse.Errcode == 45009 {
  166. key := "CACHE_SendTemplateMsg_ERR"
  167. isExist := utils.Rc.IsExist(key)
  168. if isExist == true {
  169. return
  170. } else {
  171. result, _ := json.Marshal(templateResponse)
  172. if err != nil {
  173. utils.FileLog.Info(fmt.Sprintf("templateResponse Marshal Err:%s", err.Error()))
  174. return err
  175. }
  176. //发送邮件提醒异常
  177. go alarm_msg.SendAlarmMsg("模板消息发送超过当日10万次限制,templateResponse = "+string(result), 3)
  178. //go utils.SendEmail("异常提醒:", "模板消息发送超过当日10万次限制,templateResponse = "+string(result), utils.EmailSendToUsers)
  179. //设置3分钟缓存,不允许重复添加
  180. utils.Rc.SetNX(key, 1, 6*time.Minute)
  181. }
  182. //清空发送次数
  183. sendUrl := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/clear_quota?access_token=%s", accessToken)
  184. clearData := make(map[string]interface{})
  185. clearData["appid"] = utils.WxAppId
  186. clearJson, _ := json.Marshal(clearData)
  187. utils.FileLog.Info("clear_quota data:" + string(clearJson))
  188. resp, err := client.Post(sendUrl, "application/json", bytes.NewBuffer(clearJson))
  189. if err != nil {
  190. return err
  191. }
  192. defer resp.Body.Close()
  193. clearBody, err := ioutil.ReadAll(resp.Body)
  194. utils.FileLog.Info("clear_quota result:" + string(clearBody))
  195. var clearQuotaResponse ClearQuotaResponse
  196. err = json.Unmarshal(clearBody, &clearQuotaResponse)
  197. if err != nil {
  198. utils.FileLog.Info(fmt.Sprintf("clearQuotaResponse Unmarshal Err:%s", err.Error()))
  199. return err
  200. }
  201. if clearQuotaResponse.Errcode == 0 {
  202. //发送邮件解决异常
  203. go alarm_msg.SendAlarmMsg("异常已解决,自动清理限制接口,调用成功", 3)
  204. //go utils.SendEmail("异常已解决:", "自动清理限制接口,调用成功", utils.EmailSendToUsers)
  205. //重新推送一次
  206. toSendTemplateMsg(sendUrl, data, resource, sendType, dataItem)
  207. }
  208. }
  209. return
  210. }
  211. type SendTemplateResponse struct {
  212. Errcode int `json:"errcode"`
  213. Errmsg string `json:"errmsg"`
  214. MsgID int `json:"msgid"`
  215. }
  216. type ClearQuotaResponse struct {
  217. Errcode int `json:"errcode"`
  218. Errmsg string `json:"errmsg"`
  219. }
  220. // SendCompanyApplyWxTemplateMsg 微信审批通知模板消息
  221. func SendCompanyApplyWxTemplateMsg(mobile, redirectUrl, wxAppPath string, wxMsgMap map[int]string) (err error) {
  222. var msg string
  223. defer func() {
  224. if err != nil {
  225. go alarm_msg.SendAlarmMsg("发送模版消息失败,Err:"+err.Error()+";msg:"+msg, 3)
  226. //go utils.SendEmail("发送模版消息失败"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  227. utils.FileLog.Info(fmt.Sprintf("发送模版消息失败,Err:%s,%s", err.Error(), msg))
  228. }
  229. if msg != "" {
  230. utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
  231. }
  232. }()
  233. utils.FileLog.Info("%s", "services SendMsg")
  234. //accessToken, err := models.GetWxAccessToken()
  235. //if err != nil {
  236. // msg = "GetWxAccessToken Err:" + err.Error()
  237. // return
  238. //}
  239. //if accessToken == "" {
  240. // msg = "accessToken is empty"
  241. // return
  242. //}
  243. utils.FileLog.Info("mobile:%s", mobile)
  244. openIdList, err := system.GetAdminOpenIdListByMobile(mobile)
  245. if err != nil {
  246. msg = "get openIdList err:" + err.Error()
  247. return
  248. }
  249. utils.FileLog.Info("openIdListCount:%s", len(openIdList))
  250. //fmt.Println("openIdListCount:", len(openIdList))
  251. if len(openIdList) > 0 && utils.TemplateIdByCompanyApply != "" {
  252. utils.FileLog.Info("start send")
  253. //sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  254. fmt.Println("send start")
  255. utils.FileLog.Info("send start")
  256. //sendMap := make(map[string]interface{})
  257. //sendData := make(map[string]interface{})
  258. var first, keyword1, keyword2, keyword3, remark string
  259. if tmpStr, ok := wxMsgMap[0]; ok {
  260. first = tmpStr
  261. } else {
  262. first = "Hi,有新的订单需要审批"
  263. }
  264. if tmpStr, ok := wxMsgMap[1]; ok {
  265. keyword1 = tmpStr
  266. }
  267. if tmpStr, ok := wxMsgMap[2]; ok {
  268. keyword2 = tmpStr
  269. }
  270. if tmpStr, ok := wxMsgMap[3]; ok {
  271. keyword3 = tmpStr
  272. }
  273. if tmpStr, ok := wxMsgMap[4]; ok {
  274. remark = tmpStr
  275. }
  276. //sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  277. //sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  278. //sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  279. //sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": "#173177"}
  280. //sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
  281. //
  282. //sendMap["template_id"] = utils.TemplateIdByCompanyApply
  283. //sendMap["url"] = redirectUrl //跳转地址
  284. //sendMap["data"] = sendData
  285. //if wxAppPath != "" {
  286. // sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxCrmAppId, "pagepath": wxAppPath}
  287. //}
  288. //sendTemplateMsg(sendUrl, sendMap, openIdList, mobile, utils.TEMPLATE_MSG_APPLY)
  289. openIdArr := make([]string, len(openIdList))
  290. for i, v := range openIdList {
  291. openIdArr[i] = v.OpenId
  292. }
  293. sendInfo := new(SendWxTemplate)
  294. sendInfo.WxAppId = utils.AdminWxAppId
  295. sendInfo.First = first
  296. sendInfo.Keyword1 = keyword1
  297. sendInfo.Keyword2 = keyword2
  298. sendInfo.Keyword3 = keyword3
  299. sendInfo.Remark = remark
  300. sendInfo.TemplateId = utils.TemplateIdByCompanyApply
  301. sendInfo.RedirectUrl = redirectUrl
  302. sendInfo.RedirectTarget = 2
  303. sendInfo.Resource = mobile
  304. sendInfo.SendType = utils.TEMPLATE_MSG_APPLY
  305. sendInfo.OpenIdArr = openIdArr
  306. if wxAppPath != "" {
  307. sendInfo.RedirectUrl = wxAppPath
  308. }
  309. err = SendTemplateMsg(sendInfo)
  310. }
  311. utils.FileLog.Info("send end")
  312. return
  313. }
  314. // SendDayReportWxTemplateMsg 发送日报(周报、双周报、月报)模板消息
  315. func SendDayReportWxTemplateMsg(researchReport *models.ResearchReport) (err error) {
  316. var msg string
  317. defer func() {
  318. if err != nil {
  319. go alarm_msg.SendAlarmMsg("发送日报(周报)模版消息失败,Err:"+err.Error()+";msg:"+msg, 3)
  320. //go utils.SendEmail("发送日报(周报)模版消息失败"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  321. utils.FileLog.Info(fmt.Sprintf("发送日报(周报)模版消息失败,Err:%s,%s", err.Error(), msg))
  322. }
  323. if msg != "" {
  324. utils.FileLog.Info("发送日报(周报)模版消息失败,msg:%s", msg)
  325. }
  326. }()
  327. utils.FileLog.Info("%s", "services SendMsg")
  328. resource := strconv.Itoa(researchReport.ResearchReportId)
  329. //跳转地址
  330. redirectUrl := fmt.Sprint(utils.DayReportTemplateRedirectUrl, researchReport.ResearchReportId, "/", researchReport.Type)
  331. first := "Hi,最新一期晨报已上线,欢迎查看"
  332. keyword1 := "弘则晨报"
  333. keyword2 := researchReport.ResearchReportName
  334. keyword3 := researchReport.ResearchReportDate.Format(utils.FormatDate)
  335. keyword4 := researchReport.ResearchReportName
  336. switch researchReport.Type {
  337. case "day":
  338. first = "Hi,最新一期晨报已上线,欢迎查看"
  339. keyword1 = "弘则晨报"
  340. case "week":
  341. first = "Hi,最新一期周报已上线,欢迎查看"
  342. keyword1 = "弘则周报"
  343. case "two_week":
  344. first = "Hi,最新一期双周报已上线,欢迎查看"
  345. keyword1 = "弘则双周报"
  346. case "month":
  347. first = "Hi,最新一期月报已上线,欢迎查看"
  348. keyword1 = "弘则月报"
  349. // 模板消息的名称替换
  350. tmpReport, _ := models.GetReportByOldReportId(researchReport.ResearchReportId)
  351. if tmpReport != nil {
  352. keyword1 = fmt.Sprintf("弘则%s", tmpReport.ClassifyNameSecond)
  353. }
  354. case "other":
  355. first = "Hi,最新一期点评已上线,欢迎查看"
  356. keyword1 = "数据点评"
  357. }
  358. //accessToken, err := models.GetWxAccessToken()
  359. //if err != nil {
  360. // msg = "GetWxAccessToken Err:" + err.Error()
  361. // return
  362. //}
  363. //fmt.Println(accessToken)
  364. //if accessToken == "" {
  365. // msg = "accessToken is empty"
  366. // return
  367. //}
  368. openIdList, err := models.GetOpenIdList()
  369. if err != nil {
  370. msg = "get openIdList err:" + err.Error()
  371. return
  372. }
  373. fmt.Println("openIdListCount:", len(openIdList))
  374. //sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  375. fmt.Println("send start")
  376. utils.FileLog.Info("send start")
  377. //if report.MsgIsSend == 0 {
  378. //sendMap := make(map[string]interface{})
  379. //sendData := make(map[string]interface{})
  380. //sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  381. //sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  382. //sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  383. //sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": "#173177"}
  384. //sendData["keyword4"] = map[string]interface{}{"value": keyword4, "color": "#173177"}
  385. //sendMap["template_id"] = utils.TemplateIdByProduct
  386. //sendMap["url"] = redirectUrl
  387. //sendMap["data"] = sendData
  388. //sendTemplateMsg(sendUrl, sendMap, openIdList, resource, utils.TEMPLATE_MSG_CYGX_DAY_REPORT)
  389. //}
  390. openIdArr := make([]string, len(openIdList))
  391. for i, v := range openIdList {
  392. openIdArr[i] = v.OpenId
  393. }
  394. sendInfo := new(SendWxTemplate)
  395. sendInfo.First = first
  396. sendInfo.Keyword1 = keyword1
  397. sendInfo.Keyword2 = keyword2
  398. sendInfo.Keyword3 = keyword3
  399. sendInfo.Keyword4 = keyword4
  400. sendInfo.TemplateId = utils.TemplateIdByProduct
  401. sendInfo.RedirectUrl = redirectUrl
  402. sendInfo.RedirectTarget = 1
  403. sendInfo.Resource = resource
  404. sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_DAY_REPORT
  405. sendInfo.OpenIdArr = openIdArr
  406. err = SendTemplateMsg(sendInfo)
  407. fmt.Println("send end")
  408. utils.FileLog.Info("send end")
  409. return
  410. }
  411. // 路演->研究员收到待处理的申请
  412. func SendWxMsgWithRoadshowPending(first, keyword1, keyword2, keyword3, keyword4, remark, wxAppPath string, openIdList []*system.OpenIdList) (err error) {
  413. var msg string
  414. defer func() {
  415. if err != nil {
  416. go alarm_msg.SendAlarmMsg("发送模版消息失败,Err:"+err.Error()+";msg:"+msg, 3)
  417. //go utils.SendEmail("发送模版消息失败"+"【"+utils.APPNAME+"】"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  418. utils.FileLog.Info(fmt.Sprintf("发送模版消息失败,Err:%s", err.Error()))
  419. }
  420. }()
  421. utils.FileLog.Info("%s", "services SendMsg")
  422. //accessToken, err := models.GetWxAccessToken()
  423. //if err != nil {
  424. // msg = "GetWxAccessToken Err:" + err.Error()
  425. // return
  426. //}
  427. //if accessToken == "" {
  428. // msg = "accessToken is empty"
  429. // return
  430. //}
  431. //sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  432. //sendMap := make(map[string]interface{})
  433. //sendData := make(map[string]interface{})
  434. //sendMap["template_id"] = utils.WxMsgTemplateIdWithRoadshowPending
  435. //sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  436. //sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  437. //sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  438. //sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": "#173177"}
  439. //sendData["keyword4"] = map[string]interface{}{"value": keyword4, "color": "#173177"}
  440. //sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
  441. //if wxAppPath != "" && utils.RunMode == "release" {
  442. // sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxCrmAppId, "pagepath": wxAppPath}
  443. //}
  444. //sendMap["data"] = sendData
  445. //sendTemplateMsg(sendUrl, sendMap, openIdList, wxAppPath, utils.TEMPLATE_MSG_ACTIVITY_APPOINTMENT)
  446. openIdArr := make([]string, len(openIdList))
  447. for i, v := range openIdList {
  448. openIdArr[i] = v.OpenId
  449. }
  450. sendInfo := new(SendWxTemplate)
  451. sendInfo.WxAppId = utils.AdminWxAppId
  452. sendInfo.First = first
  453. sendInfo.Keyword1 = keyword1
  454. sendInfo.Keyword2 = keyword2
  455. sendInfo.Keyword3 = keyword3
  456. sendInfo.Keyword4 = keyword4
  457. sendInfo.Remark = remark
  458. sendInfo.TemplateId = utils.WxMsgTemplateIdWithRoadshowPending
  459. if wxAppPath != "" && utils.RunMode == "release" {
  460. sendInfo.RedirectUrl = wxAppPath
  461. }
  462. sendInfo.RedirectTarget = 2
  463. sendInfo.Resource = wxAppPath
  464. sendInfo.SendType = utils.TEMPLATE_MSG_ACTIVITY_APPOINTMENT
  465. sendInfo.OpenIdArr = openIdArr
  466. err = SendTemplateMsg(sendInfo)
  467. return
  468. }
  469. // 路演->销售收到处理结果
  470. func SendWxMsgWithRoadshowDetailResult(first, keyword1, keyword2, keyword3, keyword4, keyword5, remark, wxAppPath string, openIdList []*system.OpenIdList) (err error) {
  471. var msg string
  472. defer func() {
  473. if err != nil {
  474. go alarm_msg.SendAlarmMsg("发送模版消息失败,Err:"+err.Error()+";msg:"+msg, 3)
  475. //go utils.SendEmail("发送模版消息失败"+"【"+utils.APPNAME+"】"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  476. utils.FileLog.Info(fmt.Sprintf("发送模版消息失败,Err:%s", err.Error()))
  477. }
  478. }()
  479. utils.FileLog.Info("%s", "services SendMsg")
  480. //accessToken, err := models.GetWxAccessToken()
  481. //if err != nil {
  482. // msg = "GetWxAccessToken Err:" + err.Error()
  483. // return
  484. //}
  485. //if accessToken == "" {
  486. // msg = "accessToken is empty"
  487. // return
  488. //}
  489. //sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  490. //sendMap := make(map[string]interface{})
  491. //sendData := make(map[string]interface{})
  492. //sendMap["template_id"] = utils.WxMsgTemplateIdWithRoadshowDetailResult
  493. //sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  494. //sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  495. //sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  496. //sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
  497. //
  498. //if wxAppPath != "" && utils.RunMode == "release" {
  499. // sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxCrmAppId, "pagepath": wxAppPath}
  500. //}
  501. //sendMap["data"] = sendData
  502. //sendTemplateMsg(sendUrl, sendMap, openIdList, wxAppPath, utils.TEMPLATE_MSG_ACTIVITY_APPOINTMENT)
  503. openIdArr := make([]string, len(openIdList))
  504. for i, v := range openIdList {
  505. openIdArr[i] = v.OpenId
  506. }
  507. sendInfo := new(SendWxTemplate)
  508. sendInfo.WxAppId = utils.AdminWxAppId
  509. sendInfo.First = first
  510. sendInfo.Keyword1 = keyword1
  511. sendInfo.Keyword2 = keyword2
  512. sendInfo.Keyword3 = keyword3
  513. sendInfo.Keyword4 = keyword4
  514. sendInfo.Keyword5 = keyword5
  515. sendInfo.Remark = remark
  516. sendInfo.TemplateId = utils.WxMsgTemplateIdWithRoadshowDetailResult
  517. if wxAppPath != "" && utils.RunMode == "release" {
  518. sendInfo.RedirectUrl = wxAppPath
  519. }
  520. sendInfo.RedirectTarget = 2
  521. sendInfo.Resource = wxAppPath
  522. sendInfo.SendType = utils.TEMPLATE_MSG_ACTIVITY_APPOINTMENT
  523. sendInfo.OpenIdArr = openIdArr
  524. err = SendTemplateMsg(sendInfo)
  525. return
  526. }
  527. // 路演->研究员收到活动删除通知
  528. func SendWxMsgWithRoadshowDeleteNotice(first, keyword1, keyword2, remark, wxAppPath string, openIdList []*system.OpenIdList) (err error) {
  529. var msg string
  530. defer func() {
  531. if err != nil {
  532. go alarm_msg.SendAlarmMsg("发送模版消息失败,Err:"+err.Error()+";msg:"+msg, 3)
  533. //go utils.SendEmail("发送模版消息失败"+"【"+utils.APPNAME+"】"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  534. utils.FileLog.Info(fmt.Sprintf("发送模版消息失败,Err:%s", err.Error()))
  535. }
  536. }()
  537. utils.FileLog.Info("%s", "services SendMsg")
  538. //accessToken, err := models.GetWxAccessToken()
  539. //if err != nil {
  540. // msg = "GetWxAccessToken Err:" + err.Error()
  541. // return
  542. //}
  543. //if accessToken == "" {
  544. // msg = "accessToken is empty"
  545. // return
  546. //}
  547. //sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  548. //sendMap := make(map[string]interface{})
  549. //sendData := make(map[string]interface{})
  550. //sendMap["template_id"] = utils.WxMsgTemplateIdWithRoadshowDeleteNotice
  551. //sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  552. //sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  553. //sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  554. //sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
  555. //if wxAppPath != "" && utils.RunMode == "release" {
  556. // sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxCrmAppId, "pagepath": wxAppPath}
  557. //}
  558. //sendMap["data"] = sendData
  559. //sendTemplateMsg(sendUrl, sendMap, openIdList, wxAppPath, utils.TEMPLATE_MSG_ACTIVITY_APPOINTMENT)
  560. openIdArr := make([]string, len(openIdList))
  561. for i, v := range openIdList {
  562. openIdArr[i] = v.OpenId
  563. }
  564. sendInfo := new(SendWxTemplate)
  565. sendInfo.WxAppId = utils.AdminWxAppId
  566. sendInfo.First = first
  567. sendInfo.Keyword1 = keyword1
  568. sendInfo.Keyword2 = keyword2
  569. sendInfo.Remark = remark
  570. sendInfo.TemplateId = utils.WxMsgTemplateIdWithRoadshowDeleteNotice
  571. if wxAppPath != "" && utils.RunMode == "release" {
  572. sendInfo.RedirectUrl = wxAppPath
  573. }
  574. sendInfo.RedirectTarget = 2
  575. sendInfo.Resource = wxAppPath
  576. sendInfo.SendType = utils.TEMPLATE_MSG_ACTIVITY_APPOINTMENT
  577. sendInfo.OpenIdArr = openIdArr
  578. err = SendTemplateMsg(sendInfo)
  579. return
  580. }
  581. // SendMiniProgramReportWxMsg 推送报告微信模板消息-小程序链接
  582. func SendMiniProgramReportWxMsg(reportId int) (err error) {
  583. var msg string
  584. reportIdStr := strconv.Itoa(reportId)
  585. defer func() {
  586. if err != nil {
  587. fmt.Println("msg:", msg)
  588. utils.FileLog.Error(fmt.Sprintf("SendMiniProgramReportWxMsg, 发送报告模版消息失败, ReportId:%s, Err:%s", reportIdStr, err.Error()))
  589. go alarm_msg.SendAlarmMsg("SendMiniProgramReportWxMsg发送报告模版消息失败;"+"ReportId:"+reportIdStr+",Err:"+err.Error()+";msg:"+msg, 3)
  590. //go utils.SendEmail("SendMiniProgramReportWxMsg发送报告模版消息失败"+"【"+utils.APPNAME+"】"+"【"+utils.RunMode+"】"+time.Now().Format("2006-01-02 15:04:05"), "ReportId:"+reportIdStr+";"+msg+";Err:"+err.Error(), toUser)
  591. }
  592. }()
  593. utils.FileLog.Info("%s", "services SendMsg")
  594. report, err := models.GetReportById(reportId)
  595. if err != nil {
  596. msg = "GetReportInfo Err:" + err.Error()
  597. return
  598. }
  599. if report == nil {
  600. utils.FileLog.Info("报告信息不存在")
  601. return
  602. }
  603. //if report.MsgIsSend == 1 {
  604. // return
  605. //}
  606. //accessToken, err := models.GetWxAccessToken()
  607. //if err != nil {
  608. // msg = "GetWxAccessToken Err:" + err.Error()
  609. // return
  610. //}
  611. //if accessToken == "" {
  612. // msg = "accessToken is empty"
  613. // return
  614. //}
  615. var openIdArr []string
  616. if report.ClassifyIdSecond <= 0 {
  617. openIdArr, err = models.GetOpenIdArr()
  618. if err != nil {
  619. msg = "get GetOpenIdArr err:" + err.Error()
  620. return
  621. }
  622. } else {
  623. classify, err := models.GetClassifyById(report.ClassifyIdSecond)
  624. if err != nil {
  625. msg = "获取报告分类失败 err:" + err.Error()
  626. return err
  627. }
  628. if classify.IsMassSend == 1 {
  629. openIdArr, err = models.GetOpenIdArr()
  630. if err != nil {
  631. msg = "get GetOpenIdArr err:" + err.Error()
  632. return err
  633. }
  634. } else {
  635. openIdArr, err = models.GetOpenIdArrByClassifyNameSecond(report.ClassifyNameSecond)
  636. if err != nil {
  637. msg = "GetOpenIdArrByClassifyNameSecond err:" + err.Error()
  638. return err
  639. }
  640. }
  641. }
  642. //sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  643. //fmt.Println("send start")
  644. //utils.FileLog.Info("send start")
  645. //sendMap := make(map[string]interface{})
  646. //sendData := make(map[string]interface{})
  647. title := fmt.Sprintf("弘则%s", report.ClassifyNameFirst)
  648. if CheckTwoWeekOrMonthReport(report.ClassifyIdFirst, report.ClassifyNameFirst) {
  649. title = fmt.Sprintf("弘则%s", report.ClassifyNameSecond)
  650. }
  651. //redirectUrl := utils.TemplateRedirectUrl + strconv.Itoa(reportId)
  652. first := fmt.Sprintf("Hi,最新一期%s已上线,欢迎查看", report.ClassifyNameFirst)
  653. keyword1 := title
  654. keyword2 := report.Title
  655. keyword3 := report.PublishTime
  656. keyword4 := report.Abstract
  657. //sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  658. //sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  659. //sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  660. //sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": "#173177"}
  661. //sendData["keyword4"] = map[string]interface{}{"value": keyword4, "color": "#173177"}
  662. //
  663. //sendMap["template_id"] = utils.TemplateIdByProduct
  664. ////sendMap["url"] = redirectUrl
  665. //sendMap["data"] = sendData
  666. var wxAppPath string
  667. if report.ChapterType == utils.REPORT_TYPE_WEEK {
  668. wxAppPath = fmt.Sprintf("pages-report/chapterList?reportId=%s", reportIdStr)
  669. } else {
  670. wxAppPath = fmt.Sprintf("pages-report/reportDetail?reportId=%s", reportIdStr)
  671. }
  672. //if wxAppPath != "" {
  673. // sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxYbAppId, "pagepath": wxAppPath}
  674. //}
  675. //err = sendTemplateMsg(sendUrl, sendMap, openIdList, wxAppPath, utils.TEMPLATE_MSG_REPORT)
  676. sendInfo := new(SendWxTemplate)
  677. sendInfo.First = first
  678. sendInfo.Keyword1 = keyword1
  679. sendInfo.Keyword2 = keyword2
  680. sendInfo.Keyword3 = keyword3
  681. sendInfo.Keyword4 = keyword4
  682. sendInfo.TemplateId = utils.TemplateIdByProduct
  683. sendInfo.RedirectUrl = wxAppPath
  684. sendInfo.Resource = wxAppPath
  685. sendInfo.SendType = utils.TEMPLATE_MSG_REPORT
  686. sendInfo.OpenIdArr = openIdArr
  687. sendInfo.RedirectTarget = 1
  688. err = SendTemplateMsg(sendInfo)
  689. return
  690. }
  691. // CheckTwoWeekOrMonthReport 校验推送报告是否为双周报或者月报
  692. func CheckTwoWeekOrMonthReport(classifyId int, classifyName string) (ok bool) {
  693. if utils.RunMode == "debug" {
  694. miniStrArr := []string{
  695. "双周报", "月报",
  696. }
  697. if utils.InArrayByStr(miniStrArr, classifyName) {
  698. ok = true
  699. }
  700. } else {
  701. // 此处生产环境用ID主要是担心分类改了名字...
  702. IdArr := []int{
  703. 96, 112,
  704. }
  705. if utils.InArrayByInt(IdArr, classifyId) {
  706. ok = true
  707. }
  708. }
  709. return
  710. }
  711. type SendWxTemplate struct {
  712. WxAppId string `description:"公众号appId"`
  713. First string `description:"模板消息first字段"`
  714. Keyword1 string `description:"模板消息keyword1字段"`
  715. Keyword2 string `description:"模板消息keyword2字段"`
  716. Keyword3 string `description:"模板消息keyword3字段"`
  717. Keyword4 string `description:"模板消息keyword4字段"`
  718. Keyword5 string `description:"模板消息keyword5字段"`
  719. Remark string `description:"模板消息remark字段"`
  720. TemplateId string `description:"模板id"`
  721. RedirectUrl string `description:"跳转地址"`
  722. RedirectTarget int `description:"小程序跳转目标:1:弘则研报小程序,2:随手办公小程序"`
  723. Resource string `description:"资源唯一标识"`
  724. SendType int `description:"发送的消息类型:1:报告,2:指标更新提醒,3:审批通知,4:销售领取客户通知,5:活动取消通知,6活动更改时间通知,7:关注的作者发布报告通知,8:发送日报(周报、双周报、月报)模板消息,9:活动预约/报名时间通知"`
  725. OpenIdArr []string `description:"消息接收者openid"`
  726. }
  727. // 推送模板消息
  728. func SendTemplateMsg(sendInfo *SendWxTemplate) (err error) {
  729. postData, err := json.Marshal(sendInfo)
  730. if err != nil {
  731. alarm_msg.SendAlarmMsg("SendTemplateMsg json.Marshal Err:"+err.Error(), 1)
  732. return err
  733. }
  734. body := ioutil.NopCloser(strings.NewReader(string(postData)))
  735. client := &http.Client{}
  736. req, err := http.NewRequest("POST", utils.SendWxTemplateMsgUrl, body)
  737. if err != nil {
  738. alarm_msg.SendAlarmMsg("SendTemplateMsg http.NewRequest Err:"+err.Error(), 1)
  739. return err
  740. }
  741. contentType := "application/json;charset=utf-8"
  742. req.Header.Set("Content-Type", contentType)
  743. req.Header.Set("Authorization", utils.SendTemplateMsgAuthorization)
  744. resp, err := client.Do(req)
  745. if err != nil {
  746. fmt.Println("http client.Do Err:" + err.Error())
  747. return err
  748. }
  749. defer resp.Body.Close()
  750. b, err := ioutil.ReadAll(resp.Body)
  751. if err != nil {
  752. return err
  753. }
  754. result := new(models.BaseResponse)
  755. err = json.Unmarshal(b, &result)
  756. if err != nil {
  757. return err
  758. }
  759. if result.Ret != 200 {
  760. err = errors.New(string(b))
  761. return err
  762. }
  763. return
  764. }
  765. func PublicsendTemplateMsg(sendUrl string, sendMap map[string]interface{}, items []*models.OpenIdList, resource string, sendType int) (err error) {
  766. for _, v := range items {
  767. sendMap["touser"] = v.OpenId
  768. data, err := json.Marshal(sendMap)
  769. if err != nil {
  770. fmt.Println("SendTemplateMsgOne Marshal Err:", err.Error())
  771. utils.FileLog.Info(fmt.Sprintf("SendTemplateMsgOne Marshal Err:%s", err.Error()))
  772. return err
  773. }
  774. err = toSendTemplateMsg(sendUrl, data, resource, sendType, v)
  775. if err != nil {
  776. fmt.Println("send err:", err.Error())
  777. utils.FileLog.Info(fmt.Sprintf("ToSendTemplateMsg Err:%s", err.Error()))
  778. }
  779. }
  780. return
  781. }