component.go 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. package controllers
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "io/ioutil"
  6. "net/http"
  7. "wechat-conf/models"
  8. "wechat-conf/models/model"
  9. "wechat-conf/service/autoreply"
  10. "wechat-conf/service/wechat"
  11. "wechat-conf/utils"
  12. "github.com/astaxie/beego"
  13. "github.com/kinisky564477/wechat/component"
  14. "github.com/zjxpcyc/wechat/core"
  15. )
  16. // WechatController 用户
  17. type WechatController struct {
  18. BaseController
  19. serv *autoreply.AutoreplyServ
  20. wechatServ *wechat.WechatServ
  21. }
  22. // Constructor 初始化 Controller
  23. // @Title Constructor
  24. // @Description 初始化 Controller, 系统自动调用
  25. func (c *WechatController) Constructor() {
  26. c.serv = autoreply.NewAutoreplyServ(c.Context)
  27. c.wechatServ = wechat.NewWechatServ(c.Context)
  28. }
  29. const (
  30. INFOTYPE_TICKET = "component_verify_ticket"
  31. INFOTYPE_AUTHORIZED = "authorized"
  32. INFOTYPE_UNAUTHORIZED = "unauthorized"
  33. INFOTYPE_UPDATEAUTHORIZED = "updateauthorized"
  34. )
  35. // ComponentPush 第三方平台推送
  36. func (c *WechatController) ComponentPush() {
  37. utils.LogError("推送开始")
  38. r := c.Ctx.Request
  39. defer r.Body.Close()
  40. con, _ := ioutil.ReadAll(r.Body)
  41. beego.Error(string(con))
  42. // 解析xml
  43. xp := &core.XMLParse{}
  44. resMsg, err := xp.Parse(string(con))
  45. if err != nil {
  46. utils.LogError("xml解析失败:", err)
  47. c.ResponseRaw([]byte("success"))
  48. }
  49. utils.LogError("解析xml成功:", resMsg)
  50. encrypt := resMsg["Encrypt"]
  51. beego.Error(encrypt)
  52. conf, err := c.wechatServ.GetComponentInfo()
  53. if err != nil || conf == nil || conf.Appid == "" {
  54. utils.LogError("读取微信配置文件失败")
  55. c.ResponseRaw([]byte("success"))
  56. }
  57. beego.Error(conf.Aeskey)
  58. EncodingAESKey := conf.Aeskey
  59. AESKey, err := base64.StdEncoding.DecodeString(EncodingAESKey + "=")
  60. if err != nil {
  61. utils.LogError("DecodeString失败:", err)
  62. c.ResponseRaw([]byte("success"))
  63. }
  64. beego.Error(AESKey)
  65. EncryptVal, err := base64.StdEncoding.DecodeString(encrypt)
  66. if err != nil {
  67. utils.LogError("密文解析失败:", err)
  68. c.ResponseRaw([]byte("success"))
  69. }
  70. msgbyte, err := utils.AesDecrypt(EncryptVal, AESKey)
  71. if err != nil {
  72. utils.LogError("解密失败:", err)
  73. c.ResponseRaw([]byte("success"))
  74. }
  75. beego.Error("解密数据:", string(msgbyte))
  76. beego.Error("解密成功")
  77. // 解析xml
  78. msg, err := xp.Parse(string(msgbyte))
  79. if err != nil {
  80. utils.LogError("xml解析失败:", err)
  81. c.ResponseRaw([]byte("success"))
  82. }
  83. beego.Error("解析xml成功:", msg)
  84. switch msg["InfoType"] {
  85. case INFOTYPE_TICKET:
  86. // 更新ticket
  87. conf.Ticket = msg["ComponentVerifyTicket"]
  88. err := c.wechatServ.UpdateComponentTicket(conf)
  89. if err != nil {
  90. utils.LogError("修改ticket失败:", err)
  91. }
  92. utils.RefreshComponentTicket(msg["ComponentVerifyTicket"])
  93. break
  94. case INFOTYPE_AUTHORIZED:
  95. // 授权成功
  96. var cert = map[string]string{
  97. "appid": msg["AuthorizerAppid"],
  98. "authorization_code": msg["AuthorizationCode"],
  99. }
  100. wxclient := utils.WechatInit(cert, c.wechatServ.UpdateToken)
  101. utils.AppendWxClient(wxclient)
  102. // 插入数据库
  103. mjson, _ := json.Marshal(msg)
  104. var conf = model.SysWechatConf{
  105. Appid: msg["AuthorizerAppid"],
  106. AuthorizationCode: msg["AuthorizationCode"],
  107. AuthorizationInfo: string(mjson),
  108. }
  109. err := c.wechatServ.SaveWechatConf(conf)
  110. if err != nil {
  111. utils.LogError("保存微信授权信息失败:", err)
  112. c.ResponseRaw([]byte("success"))
  113. }
  114. break
  115. case INFOTYPE_UPDATEAUTHORIZED:
  116. // 授权更新
  117. break
  118. case INFOTYPE_UNAUTHORIZED:
  119. // 取消授权
  120. break
  121. }
  122. c.ResponseRaw([]byte("success"))
  123. }
  124. // WechatInfo 微信接入
  125. func (c *WechatController) WechatInfo() {
  126. method := c.Ctx.Input.Method()
  127. if method == http.MethodGet {
  128. echostr := c.GetString("echostr")
  129. c.ResponseRaw([]byte(echostr))
  130. } else {
  131. c.WxReceive()
  132. }
  133. }
  134. // WxReceive 微信消息接收
  135. func (c *WechatController) WxReceive() {
  136. appid := c.GetString(":appid")
  137. wechat, err := utils.Component.GetWxClient(appid)
  138. if err != nil {
  139. utils.LogError("获取微信失败: " + err.Error())
  140. }
  141. val, err := wechat.TransformMessage(string(c.Ctx.Input.RequestBody))
  142. if err != nil {
  143. utils.LogError("读取微信服务发送内容失败: " + err.Error())
  144. c.ResponseRaw([]byte(""))
  145. }
  146. var replay = new(model.TaAutoReply)
  147. switch val["MsgType"] {
  148. case "text":
  149. content := val["Content"]
  150. // 获取数据库存储返回类型
  151. replay, err = c.serv.GetAutoReplayByAppID(appid, content)
  152. break
  153. case "event":
  154. if val["Event"] == "subscribe" {
  155. replay, err = c.serv.GetSubscribeByAppID(appid)
  156. }
  157. break
  158. }
  159. if err != nil {
  160. utils.LogError("获取微信自动回复信息失败: " + err.Error())
  161. c.ResponseRaw([]byte(""))
  162. }
  163. if replay == nil {
  164. c.ResponseRaw([]byte(""))
  165. }
  166. openID := val["FromUserName"]
  167. message, err := c.getReplayMessage(replay, openID, wechat)
  168. if err != nil {
  169. utils.LogError("转换回复信息失败: " + err.Error())
  170. c.ResponseRaw([]byte(""))
  171. }
  172. c.ResponseRaw(message, false)
  173. c.DestroyContext()
  174. c.StopRun()
  175. }
  176. func (c *WechatController) getReplayMessage(replay *model.TaAutoReply, openid string, wx *component.WxClient) ([]byte, error) {
  177. switch replay.MessageType {
  178. case models.MESSAGE_TYPE_CONTENT:
  179. msg, err := wx.ResponseMessageText(openid, replay.MessageParagraph)
  180. return msg, err
  181. case models.MESSAGE_TYPE_IMG:
  182. msg, err := wx.ResponseMessageImage(openid, replay.MessageImg)
  183. return msg, err
  184. // case models.MESSAGE_TYPE_PARAGRAPH:
  185. // msg, err := wx.ResponseMessageNews(openid, replay.MessageImg)
  186. // return msg, err
  187. }
  188. return nil, nil
  189. }
  190. // GetPreAuthCode 获取预授权码
  191. func (c *WechatController) GetPreAuthCode() {
  192. code, err := utils.Component.GetPreAuthCode()
  193. if err != nil {
  194. utils.LogError("获取预授权码错误: " + err.Error())
  195. c.ResponseError(err)
  196. }
  197. appid := utils.Component.GetCertificate()["appid"]
  198. c.ResponseJSON(map[string]string{
  199. "appid": appid,
  200. "code": code,
  201. })
  202. }