message.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. package service
  2. import (
  3. "crypto/sha1"
  4. "encoding/xml"
  5. "fmt"
  6. "io/ioutil"
  7. "sort"
  8. "strings"
  9. "time"
  10. "github.com/gin-gonic/gin"
  11. "github.com/pkg/errors"
  12. "kpt.notice/apiserver/model"
  13. "kpt.notice/apiserver/model/http"
  14. "kpt.notice/pkg/log"
  15. "kpt.notice/pkg/util"
  16. )
  17. func (svc *Service) UpdateMessage(msg *model.Message) (err error) {
  18. mtype := &http.MessageTypeReq{
  19. SysName: msg.SysName,
  20. PastureID: msg.PastureID,
  21. ServiceID: msg.ServiceID,
  22. }
  23. if mtypes, e := svc.QueryMsgType(mtype); e != nil {
  24. err = e
  25. return
  26. } else if len(mtypes) == 0 {
  27. err = errors.New("没有匹配的消息类型")
  28. return
  29. } else {
  30. m := make(map[string]interface{}, 3)
  31. if mtypes[0].RemindType == 1 {
  32. m["status"] = 1
  33. } else if mtypes[0].RemindType == 2 {
  34. if mtypes[0].CycleType == 1 || mtypes[0].CycleType == 3 {
  35. m["status"] = 1
  36. } else {
  37. m["updated_at"] = time.Now()
  38. m["push_count"] = msg.PushCount + 1
  39. if msg.PushCount+1 >= mtypes[0].PushLimit {
  40. m["status"] = 1
  41. }
  42. }
  43. } else if mtypes[0].RemindType == 3 {
  44. m["push_count"] = msg.PushCount + 1
  45. m["updated_at"] = time.Now()
  46. }
  47. if res := svc.DB.Table("message").Where("id=?", msg.ID).Updates(m); res.Error != nil {
  48. err = errors.Wrap(res.Error, "UpdateMessage.update=")
  49. log.Errorf("%v", err)
  50. }
  51. }
  52. return
  53. }
  54. func (svc *Service) UpdateMessageStatus(id int) (err error) {
  55. err = svc.DB.Exec(` update message set status = -1 where id = ? `, id).Error
  56. if err != nil {
  57. log.Error(err)
  58. return
  59. }
  60. return
  61. }
  62. func (svc *Service) QueryMsg() (msgs []model.Message, err error) {
  63. var sql2 string
  64. sql := `select sqltext from apisql where sqlname='getMessage' limit 1 `
  65. svc.DB.Raw(sql).Scan(&sql2)
  66. if err = svc.DB.Raw(sql2).Scan(&msgs).Error; err != nil {
  67. err = errors.Wrap(err, "queryMsg{query msg exec sql err}==%v")
  68. log.Errorf("%v", err)
  69. return
  70. }
  71. return
  72. }
  73. func (svc *Service) InsertMessage(msg *http.MessageReq, body []byte) (resp *http.MessageResp, err error) {
  74. tmp := make(map[string]interface{})
  75. tmp["miniprogram"] = msg.Miniprogram
  76. msgType := &http.MessageTypeReq{
  77. SysName: msg.SysName,
  78. PastureID: msg.PastureID,
  79. ServiceID: msg.ServiceID,
  80. }
  81. sysuserList, e := svc.GetSysUser(msg.Target, msg.SysName, msg.PastureID)
  82. if err != nil {
  83. err = e
  84. return
  85. }
  86. var targetList []string
  87. for _, user := range sysuserList {
  88. targetList = append(targetList, user.Openid)
  89. }
  90. if mt, e := svc.QueryMsgType(msgType); e != nil {
  91. err = e
  92. return
  93. } else if len(mt) == 0 {
  94. err = errors.New("没有匹配的消息类型")
  95. return
  96. } else {
  97. tmp["template_id"] = mt[0].TemplateID
  98. }
  99. data := make(map[string]http.Tag)
  100. for i, v := range msg.Keys {
  101. data[v] = msg.Content[i]
  102. }
  103. tmp["data"] = data
  104. status := -1
  105. for _, target := range targetList {
  106. if target != "" {
  107. status = 0
  108. break
  109. }
  110. }
  111. msgDb := model.Message{
  112. SysName: msg.SysName,
  113. PastureID: msg.PastureID,
  114. ServiceID: msg.ServiceID,
  115. Target: util.MarshalToString(targetList),
  116. MsgTypeID: msg.MsgTypeID,
  117. MsgContent: util.MarshalToString(tmp),
  118. UpdatedAt: time.Now(),
  119. BodyData: string(body),
  120. Status: status,
  121. }
  122. if err = svc.DB.Create(&msgDb).Error; err != nil {
  123. err = errors.Wrap(err, "InsertMessage{insert msg}==%v")
  124. log.Errorf("%v", err)
  125. return
  126. }
  127. resp = &http.MessageResp{
  128. ID: msgDb.ID,
  129. }
  130. return
  131. }
  132. // query the id or remind_type of the message by name
  133. func (svc *Service) QueryRemindTypeID(name string) (int, error) {
  134. m := new(http.MessageTypeReq)
  135. tx := svc.DB.Table("message_type").Where("type_name = ?").First(m)
  136. if tx.RowsAffected == 0 {
  137. return 0, errors.New("没有匹配的类型")
  138. }
  139. return m.ID, nil
  140. }
  141. func (svc *Service) InsertMsgType(req *http.MessageTypeReq) (resp *http.MessageTypeResp, err error) {
  142. //固定模板
  143. req.TemplateID = "1_zBqvbzD-edg0b-O5OD1kAEMefygikcmBZACSiwX0w"
  144. if query, e := svc.QueryMsgType(req); e != nil {
  145. err = e
  146. return
  147. } else {
  148. resp = new(http.MessageTypeResp)
  149. switch {
  150. case len(query) == 0:
  151. resp.Method = "insert"
  152. if res := svc.DB.Table("message_type").Create(req); res.Error != nil {
  153. err = errors.Wrap(res.Error, "InsertMsgType{create msg type===%v}")
  154. log.Errorf("%v", err)
  155. } else {
  156. resp.RowsAffected = int(res.RowsAffected)
  157. }
  158. break
  159. case len(query) > 0:
  160. resp.Method = "update"
  161. index := map[string]interface{}{
  162. "service_id": req.ServiceID,
  163. "pasture_id": req.PastureID,
  164. "sys_name": req.SysName,
  165. }
  166. log.Infof("msg type update index%v", index)
  167. req.PastureID = 0
  168. req.SysName = ""
  169. req.ServiceID = 0
  170. log.Infof("msg type update value%v", req)
  171. if res := svc.DB.Table("message_type").Where(index).Updates(req); res.Error != nil {
  172. err = errors.Wrap(err, "InsertMsgType{update msg type ===%v}")
  173. log.Errorf("%v", err)
  174. } else {
  175. resp.RowsAffected = int(res.RowsAffected)
  176. }
  177. break
  178. }
  179. }
  180. return
  181. }
  182. func (svc *Service) QueryMsgType(req *http.MessageTypeReq) (m []http.MessageTypeReq, err error) {
  183. index := map[string]interface{}{}
  184. if req.ServiceID != 0 {
  185. index["service_id"] = req.ServiceID
  186. }
  187. if req.PastureID != 0 {
  188. index["pasture_id"] = req.PastureID
  189. }
  190. if req.SysName != "" {
  191. index["sys_name"] = req.SysName
  192. }
  193. log.Infof("query msg type===%v", index)
  194. if err = svc.DB.Table("message_type").Where(index).Find(&m).Error; err != nil {
  195. err = errors.Wrap(err, "QueryMsgType.find=")
  196. log.Errorf("%v", err)
  197. }
  198. return
  199. }
  200. type WechatMessage struct {
  201. ToUserName string `xml:"ToUserName"`
  202. FromUserName string `xml:"FromUserName"`
  203. CreateTime int64 `xml:"CreateTime"`
  204. MsgType string `xml:"MsgType"`
  205. Content string `xml:"Content"`
  206. }
  207. // type WechatTransferResponse struct {
  208. // XMLName xml.Name `xml:"xml"`
  209. // ToUserName string `xml:"ToUserName"`
  210. // FromUserName string `xml:"FromUserName"`
  211. // CreateTime int64 `xml:"CreateTime"`
  212. // MsgType string `xml:"MsgType"`
  213. // // TransInfo TransInfo `xml:"TransInfo"`
  214. // }
  215. type WechatResponse struct {
  216. XMLName xml.Name `xml:"xml"`
  217. ToUserName string `xml:"ToUserName"`
  218. FromUserName string `xml:"FromUserName"`
  219. CreateTime int64 `xml:"CreateTime"`
  220. MsgType string `xml:"MsgType"`
  221. Content string `xml:"Content"`
  222. }
  223. // func main() {
  224. // r := gin.Default()
  225. // r.GET("/wechat", handleVerification)
  226. // r.POST("/wechat", handleMessage)
  227. // fmt.Println("Server started on :80")
  228. // r.Run(":80")
  229. // }
  230. func (svc *Service) HandleVerification(c *gin.Context) (bool, string) {
  231. signature := c.Query("signature")
  232. timestamp := c.Query("timestamp")
  233. nonce := c.Query("nonce")
  234. echostr := c.Query("echostr")
  235. fmt.Println(signature)
  236. fmt.Println(timestamp)
  237. fmt.Println(nonce)
  238. fmt.Println(echostr)
  239. return checkSignature(signature, timestamp, nonce), echostr
  240. }
  241. func (svc *Service) HandleMessage(c *gin.Context) []byte {
  242. body, _ := ioutil.ReadAll(c.Request.Body)
  243. fmt.Println(string(body))
  244. defer c.Request.Body.Close()
  245. var msg WechatMessage
  246. xml.Unmarshal(body, &msg)
  247. var count int64
  248. svc.DB.Table("public").Where("`create` between DATE_SUB(NOW(), INTERVAL 10 MINUTE) and NOW() ").Where(" wxid = ? ", msg.ToUserName).Count(&count)
  249. p := new(http.Public)
  250. p.Wxid = msg.ToUserName
  251. p.Context = msg.Content
  252. p.Create = time.Now().Format("2006-01-02 15:04:05")
  253. svc.DB.Table("public").Create(p)
  254. var content string
  255. if count == 0 {
  256. content = `您好!感谢您关注科湃腾!您哪个系统需要服务?
  257. <a href="weixin://bizmsgmenu?msgmenucontent=精准饲喂&msgmenuid=1">👉精准饲喂</a>
  258. <a href="weixin://bizmsgmenu?msgmenucontent=智能脖环&msgmenuid=1">👉智能脖环</a>
  259. <a href="weixin://bizmsgmenu?msgmenucontent=智能喷淋&msgmenuid=1">👉智能喷淋</a>
  260. <a href="weixin://bizmsgmenu?msgmenucontent=系统开发服务&msgmenuid=1">👉系统开发服务</a>
  261. <a href="weixin://bizmsgmenu?msgmenucontent=其他&msgmenuid=1">👉其他</a>
  262. 专线: 021- 6630 1586`
  263. } else if p.Context == "精准饲喂" || p.Context == "智能脖环" || p.Context == "智能喷淋" || p.Context == "系统开发服务" || p.Context == "其他" {
  264. content = `您所属那个大区?
  265. <a href="weixin://bizmsgmenu?msgmenucontent=东北大区&msgmenuid=1">👉东北大区</a>
  266. <a href="weixin://bizmsgmenu?msgmenucontent=西北大区&msgmenuid=1">👉西北大区</a>
  267. <a href="weixin://bizmsgmenu?msgmenucontent=华北大区&msgmenuid=1">👉华北大区</a>
  268. <a href="weixin://bizmsgmenu?msgmenucontent=南方大区&msgmenuid=1">👉南方大区</a>`
  269. } else if p.Context == "东北大区" || p.Context == "西北大区" || p.Context == "华北大区" || p.Context == "南方大区" {
  270. content = `东北大区服务老师联系方式
  271. 谭佳悦:18888309870
  272. 喻旭超:13594927924
  273. 您可通过电话进行咨询,若您现在不方便电话联系,可以留下您的联系方式,简单描述一下问题或者拍照,我们安排服务人员在4小时内联系您,请您留意电话接听,祝您生活愉快!`
  274. // new(notice.MessageRequest)
  275. // notice.SendMessage(nil)
  276. } else {
  277. }
  278. response := WechatResponse{
  279. ToUserName: msg.FromUserName,
  280. FromUserName: msg.ToUserName,
  281. CreateTime: time.Now().Unix(),
  282. MsgType: "text",
  283. Content: content,
  284. }
  285. responseXML, _ := xml.Marshal(response)
  286. return responseXML
  287. }
  288. func checkSignature(signature, timestamp, nonce string) bool {
  289. token := "e10adc3949ba59abbe56e057f20f883e"
  290. tmpList := []string{token, timestamp, nonce}
  291. sort.Strings(tmpList)
  292. tmpStr := strings.Join(tmpList, "")
  293. h := sha1.New()
  294. h.Write([]byte(tmpStr))
  295. digest := fmt.Sprintf("%x", h.Sum(nil))
  296. return digest == signature
  297. }
  298. type Message struct {
  299. ToUser string `json:"touser"`
  300. MsgType string `json:"msgtype"`
  301. Text struct {
  302. Content string `json:"content"`
  303. } `json:"text"`
  304. }
  305. // func sendCustomMessage(accessToken, openID, content string) error {
  306. // url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s", accessToken)
  307. // message := Message{
  308. // ToUser: openID,
  309. // MsgType: "text",
  310. // Text: struct {
  311. // Content string `json:"content"`
  312. // }{
  313. // Content: content,
  314. // },
  315. // }
  316. // payload, err := json.Marshal(message)
  317. // if err != nil {
  318. // return err
  319. // }
  320. // resp, err := http1.Post(url, "application/json", bytes.NewBuffer(payload))
  321. // if err != nil {
  322. // return err
  323. // }
  324. // defer resp.Body.Close()
  325. // var result map[string]interface{}
  326. // if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
  327. // return err
  328. // }
  329. // fmt.Println("Response:", result)
  330. // return nil
  331. // }