123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. package controllers
  2. import (
  3. "bytes"
  4. "encoding/base64"
  5. "encoding/json"
  6. "io/ioutil"
  7. "net/http"
  8. "wechat-conf/models"
  9. "wechat-conf/models/model"
  10. "wechat-conf/service/autoreply"
  11. "wechat-conf/service/wechat"
  12. "wechat-conf/utils"
  13. "github.com/astaxie/beego"
  14. "github.com/kinisky564477/wechat/component"
  15. "github.com/kinisky564477/wechat/core"
  16. )
  17. // WechatController 用户
  18. type WechatController struct {
  19. BaseController
  20. serv *autoreply.AutoreplyServ
  21. wechatServ *wechat.WechatServ
  22. }
  23. // Constructor 初始化 Controller
  24. // @Title Constructor
  25. // @Description 初始化 Controller, 系统自动调用
  26. func (c *WechatController) Constructor() {
  27. c.serv = autoreply.NewAutoreplyServ(c.Context)
  28. c.wechatServ = wechat.NewWechatServ(c.Context)
  29. }
  30. const (
  31. INFOTYPE_TICKET = "component_verify_ticket"
  32. INFOTYPE_AUTHORIZED = "authorized"
  33. INFOTYPE_UNAUTHORIZED = "unauthorized"
  34. INFOTYPE_UPDATEAUTHORIZED = "updateauthorized"
  35. )
  36. // ComponentPush 第三方平台推送
  37. func (c *WechatController) ComponentPush() {
  38. utils.LogError("推送开始")
  39. r := c.Ctx.Request
  40. defer r.Body.Close()
  41. con, _ := ioutil.ReadAll(r.Body)
  42. utils.LogError("推送消息:", string(con))
  43. // 解析xml
  44. xp := &core.XMLParse{}
  45. resMsg, err := xp.Parse(string(con))
  46. if err != nil {
  47. utils.LogError("xml解析失败:", err)
  48. c.ResponseRaw([]byte("success"))
  49. }
  50. encrypt := resMsg["Encrypt"]
  51. conf, err := c.wechatServ.GetComponentInfo()
  52. if err != nil || conf == nil || conf.Appid == "" {
  53. utils.LogError("读取微信配置文件失败")
  54. c.ResponseRaw([]byte("success"))
  55. }
  56. EncodingAESKey := conf.Aeskey
  57. AESKey, err := base64.StdEncoding.DecodeString(EncodingAESKey + "=")
  58. if err != nil {
  59. utils.LogError("DecodeString失败:", err)
  60. c.ResponseRaw([]byte("success"))
  61. }
  62. EncryptVal, err := base64.StdEncoding.DecodeString(encrypt)
  63. if err != nil {
  64. utils.LogError("密文base64解析", err)
  65. c.ResponseRaw([]byte("success"))
  66. }
  67. msgbyte, err := utils.AesDecrypt(EncryptVal, AESKey)
  68. if err != nil {
  69. utils.LogError("解密失败:", err)
  70. c.ResponseRaw([]byte("success"))
  71. }
  72. utils.LogError("解密成功")
  73. // 解析xml
  74. msg, err := xp.Parse(string(msgbyte))
  75. if err != nil {
  76. utils.LogError("xml解析失败:", err)
  77. c.ResponseRaw([]byte("success"))
  78. }
  79. utils.LogError("xml解析成功:", msg)
  80. switch msg["InfoType"] {
  81. case INFOTYPE_TICKET:
  82. // 更新ticket
  83. conf.Ticket = msg["ComponentVerifyTicket"]
  84. err := c.wechatServ.UpdateComponentTicket(conf)
  85. if err != nil {
  86. utils.LogError("修改ticket失败:", err)
  87. }
  88. utils.RefreshComponentTicket(msg["ComponentVerifyTicket"])
  89. break
  90. case INFOTYPE_AUTHORIZED:
  91. // 授权成功
  92. var cert = map[string]string{
  93. "appid": msg["AuthorizerAppid"],
  94. "authorization_code": msg["AuthorizationCode"],
  95. }
  96. beego.Error("授权成功参数:", cert)
  97. wxclient := utils.WechatInit(cert, c.wechatServ.UpdateToken)
  98. if wxclient == nil {
  99. utils.LogError("获取wxclient失败")
  100. c.ResponseRaw([]byte("success"))
  101. }
  102. beego.Error(wxclient)
  103. utils.AppendWxClient(wxclient)
  104. // 获取微信信息
  105. info, err := wxclient.GetWechatInfo()
  106. if err != nil {
  107. utils.LogError("获取微信信息失败")
  108. c.ResponseRaw([]byte("success"))
  109. }
  110. beego.Error(info)
  111. authorizerInfo := (info["authorizer_info"]).(map[string]interface{})
  112. beego.Error(info["authorizer_info"])
  113. // 插入数据库
  114. mjson, _ := json.Marshal(msg)
  115. HeadImg := ""
  116. if authorizerInfo["head_img"] != nil {
  117. HeadImg = authorizerInfo["head_img"].(string)
  118. }
  119. var conf = model.SysWechatConf{
  120. Appid: msg["AuthorizerAppid"],
  121. AuthorizationCode: msg["AuthorizationCode"],
  122. AuthorizationInfo: string(mjson),
  123. WxNikeName: authorizerInfo["nick_name"].(string),
  124. HeadImg: HeadImg,
  125. UserName: authorizerInfo["user_name"].(string),
  126. PrincipalName: authorizerInfo["principal_name"].(string),
  127. QrcodeUrl: authorizerInfo["qrcode_url"].(string),
  128. }
  129. err = c.wechatServ.SaveWechatConf(conf)
  130. if err != nil {
  131. utils.LogError("保存微信授权信息失败:", err)
  132. c.ResponseRaw([]byte("success"))
  133. }
  134. break
  135. case INFOTYPE_UPDATEAUTHORIZED:
  136. // 授权更新
  137. break
  138. case INFOTYPE_UNAUTHORIZED:
  139. // 取消授权
  140. // 删除wechatConf信息,同时将org解绑
  141. appid := msg["AuthorizerAppid"]
  142. c.wechatServ.UnAuthorized(appid)
  143. // 删除第三方中的微信信息
  144. utils.Component.DelWxClient(appid)
  145. break
  146. }
  147. c.ResponseRaw([]byte("success"))
  148. }
  149. // WechatInfo 微信接入
  150. func (c *WechatController) WechatInfo() {
  151. method := c.Ctx.Input.Method()
  152. if method == http.MethodGet {
  153. echostr := c.GetString("echostr")
  154. c.ResponseRaw([]byte(echostr))
  155. } else {
  156. c.WxReceive()
  157. }
  158. }
  159. // WxReceive 微信消息接收
  160. func (c *WechatController) WxReceive() {
  161. beego.Error("微信消息接入")
  162. appid := c.GetString(":appid")
  163. wechat, err := utils.Component.GetWxClient(appid)
  164. if err != nil {
  165. utils.LogError("获取微信失败: " + err.Error())
  166. }
  167. msg, err := wechat.TransformMessage(string(c.Ctx.Input.RequestBody))
  168. if err != nil {
  169. utils.LogError("读取微信服务发送内容失败: " + err.Error())
  170. c.ResponseRaw([]byte(""))
  171. }
  172. xp := &core.XMLParse{}
  173. beego.Error("消息:", msg)
  174. encrypt := msg["Encrypt"]
  175. conf, err := c.wechatServ.GetComponentInfo()
  176. if err != nil || conf == nil || conf.Appid == "" {
  177. utils.LogError("读取微信配置文件失败")
  178. c.ResponseRaw([]byte("success"))
  179. }
  180. EncodingAESKey := conf.Aeskey
  181. AESKey, err := base64.StdEncoding.DecodeString(EncodingAESKey + "=")
  182. if err != nil {
  183. utils.LogError("DecodeString失败:", err)
  184. c.ResponseRaw([]byte("success"))
  185. }
  186. EncryptVal, err := base64.StdEncoding.DecodeString(encrypt)
  187. if err != nil {
  188. utils.LogError("密文base64解析", err)
  189. c.ResponseRaw([]byte("success"))
  190. }
  191. msgbyte, err := utils.AesDecrypt(EncryptVal, AESKey)
  192. if err != nil {
  193. utils.LogError("解密失败:", err)
  194. c.ResponseRaw([]byte("success"))
  195. }
  196. utils.LogError("解密成功")
  197. // 解析xml
  198. val, err := xp.Parse(string(msgbyte))
  199. if err != nil {
  200. utils.LogError("xml解析失败:", err)
  201. c.ResponseRaw([]byte("success"))
  202. }
  203. utils.LogError("xml解析成功:", val)
  204. var replay = new(model.TaAutoReply)
  205. switch val["MsgType"] {
  206. case "text":
  207. content := val["Content"]
  208. // 获取数据库存储返回类型
  209. replay, err = c.serv.GetAutoReplayByAppID(appid, content)
  210. break
  211. case "event":
  212. beego.Error(val)
  213. switch val["Event"] {
  214. case "subscribe":
  215. replay, err = c.serv.GetSubscribeByAppID(appid)
  216. break
  217. case "LICK":
  218. // 点击事件
  219. // key:=val["EventKey"]
  220. // keyreplay,err:=c.serv.GetReplayByKey(appid,key)
  221. // if err!=nil{
  222. // utils.LogError("获取按钮点击key失败: " + err.Error())
  223. // c.ResponseRaw([]byte(""))
  224. // }
  225. // if keyreplay!=nil && keyreplay.KeywordsId==""{
  226. // c.ResponseRaw([]byte(""))
  227. // }
  228. break
  229. }
  230. break
  231. }
  232. if err != nil {
  233. utils.LogError("获取微信自动回复信息失败: " + err.Error())
  234. c.ResponseRaw([]byte(""))
  235. }
  236. if replay == nil {
  237. c.ResponseRaw([]byte(""))
  238. }
  239. openID := val["FromUserName"]
  240. message, err := c.getReplayMessage(replay, openID, wechat)
  241. if err != nil {
  242. utils.LogError("转换回复信息失败: " + err.Error())
  243. c.ResponseRaw([]byte(""))
  244. }
  245. cipher, err := core.NewCipher(utils.Component.GetToken(), EncodingAESKey, appid)
  246. if err != nil {
  247. utils.LogError("获取解密失败: " + err.Error())
  248. c.ResponseRaw([]byte(""))
  249. }
  250. dt := bytes.NewBuffer([]byte{})
  251. cipher.Encrypt(dt, []byte(message))
  252. beego.Error("=========>", dt)
  253. c.ResponseRaw(dt.Bytes())
  254. // c.ResponseRaw([]byte("success"))
  255. }
  256. func (c *WechatController) getReplayMessage(replay *model.TaAutoReply, openid string, wx *component.WxClient) ([]byte, error) {
  257. switch replay.MessageType {
  258. case models.MESSAGE_TYPE_PARAGRAPH:
  259. msg, err := wx.ResponseMessageText(openid, replay.MessageParagraph)
  260. return msg, err
  261. case models.MESSAGE_TYPE_IMG:
  262. msg, err := wx.ResponseMessageImage(openid, replay.MessageImg)
  263. return msg, err
  264. // case models.MESSAGE_TYPE_PARAGRAPH:
  265. // msg, err := wx.ResponseMessageNews(openid, replay.MessageImg)
  266. // return msg, err
  267. }
  268. return nil, nil
  269. }
  270. // GetPreAuthCode 获取预授权码
  271. func (c *WechatController) GetPreAuthCode() {
  272. code, err := utils.Component.GetPreAuthCode()
  273. if err != nil {
  274. utils.LogError("获取预授权码错误: " + err.Error())
  275. c.ResponseError(err)
  276. }
  277. appid := utils.Component.GetCertificate()["appid"]
  278. c.ResponseJSON(map[string]string{
  279. "appid": appid,
  280. "code": code,
  281. })
  282. }
  283. // GetWechatMenuByAppID 根据appid获取微信详情
  284. func (c *WechatController) GetWechatInfoByAppID() {
  285. appid := c.GetString(":appid")
  286. wxclient, err := utils.Component.GetWxClient(appid)
  287. if err != nil {
  288. utils.LogError("获取微信信息失败: " + err.Error())
  289. c.ResponseError(err)
  290. }
  291. info, err := wxclient.GetWechatInfo()
  292. if err != nil {
  293. utils.LogError("获取微信详情失败: " + err.Error())
  294. c.ResponseError(err)
  295. }
  296. c.ResponseJSON(info)
  297. }
  298. // GetWechatMenuByAppID 获取菜单
  299. func (c *WechatController) GetMaterialByAppID() {
  300. appid := c.GetString(":appid")
  301. wxclient, err := utils.Component.GetWxClient(appid)
  302. if err != nil {
  303. utils.LogError("获取微信信息失败: " + err.Error())
  304. c.ResponseError(err)
  305. }
  306. var data = map[string]string{}
  307. data["offset"] = "0"
  308. data["type"] = "image"
  309. data["count"] = "10"
  310. menus, err := wxclient.GetMaterialList(data)
  311. if err != nil {
  312. utils.LogError("获取微信详情失败: " + err.Error())
  313. c.ResponseError(err)
  314. }
  315. c.ResponseJSON(menus)
  316. }
  317. // GetWechatByCode 根据code获取微信信息
  318. func (c *WechatController) GetWechatByCode() {
  319. code := c.GetString(":code")
  320. beego.Error(code)
  321. conf, err := c.wechatServ.GetWechatByCode(code)
  322. if err != nil {
  323. utils.LogError("获取微信详情失败: " + err.Error())
  324. c.ResponseError(err)
  325. }
  326. beego.Error(conf)
  327. if conf == nil || conf.ConfId == "" || conf.Status == models.STATUS_NORMAL {
  328. c.ResponseJSON("")
  329. }
  330. c.ResponseJSON(map[string]string{
  331. "ConfId": conf.ConfId,
  332. "NickName": conf.WxNikeName,
  333. "HeadImg": conf.HeadImg,
  334. })
  335. }