一物一码
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

232 satır
6.8 KiB

  1. package hdl
  2. import (
  3. "applet/app/db"
  4. "applet/app/db/model"
  5. "applet/app/enum"
  6. "applet/app/md"
  7. "applet/app/utils"
  8. "encoding/json"
  9. "encoding/xml"
  10. "errors"
  11. "fmt"
  12. "log"
  13. "net/http"
  14. "time"
  15. "github.com/gin-gonic/gin"
  16. )
  17. const Token = "temptoken"
  18. // WXCheckSignature 微信接入校验
  19. func WXCheckSignature(c *gin.Context) {
  20. signature := c.Query("signature")
  21. timestamp := c.Query("timestamp")
  22. nonce := c.Query("nonce")
  23. echostr := c.Query("echostr")
  24. ok := utils.CheckSignature(signature, timestamp, nonce, Token)
  25. if !ok {
  26. log.Println("[微信接入] - 微信公众号接入校验失败!")
  27. return
  28. }
  29. log.Println("[微信接入] - 微信公众号接入校验成功!")
  30. _, _ = c.Writer.WriteString(echostr)
  31. }
  32. // WXMsg 微信消息结构体
  33. type WXMsg struct {
  34. ToUserName string
  35. FromUserName string
  36. CreateTime int64
  37. MsgType string
  38. Content string
  39. MsgId int64
  40. Event string //事件类型,subscribe
  41. EventKey string //事件KEY值,qrscene_为前缀,后面为二维码的参数值
  42. Ticket string //二维码的ticket,可用来换取二维码图片
  43. }
  44. // WXTextMsg 微信文本消息结构体
  45. type WXTextMsg struct {
  46. ToUserName string
  47. FromUserName string
  48. CreateTime int64
  49. MsgType string
  50. Content string
  51. MsgId int64
  52. }
  53. // WXEventForSubscribeMsg 扫描带参数二维码事件消息结构体(用户未关注时,进行关注后的事件推送)
  54. type WXEventForSubscribeMsg struct {
  55. ToUserName string //开发者微信号
  56. FromUserName string //发送方帐号(一个OpenID)
  57. CreateTime int64 //消息创建时间 (整型)
  58. MsgType string //消息类型,event
  59. Event string //事件类型,subscribe
  60. EventKey string //事件KEY值,qrscene_为前缀,后面为二维码的参数值
  61. Ticket string //二维码的ticket,可用来换取二维码图片
  62. }
  63. // WXEventForScanMsg 扫描带参数二维码事件消息结构体(用户已关注时的事件推送)
  64. type WXEventForScanMsg struct {
  65. ToUserName string //开发者微信号
  66. FromUserName string //发送方帐号(一个OpenID)
  67. CreateTime int64 //消息创建时间 (整型)
  68. MsgType string //消息类型,event
  69. Event string //事件类型,subscribe
  70. EventKey string //事件KEY值,是一个32位无符号整数,即创建二维码时的二维码scene_id
  71. Ticket string //二维码的ticket,可用来换取二维码图片
  72. }
  73. // WXMsgReceive 微信消息接收
  74. func WXMsgReceive(c *gin.Context) {
  75. log.Printf("[消息接收] - 收到新消息")
  76. var msg WXMsg
  77. err := c.ShouldBindXML(&msg)
  78. if err != nil {
  79. log.Printf("[消息接收] - XML数据包解析失败: %v\n", err)
  80. return
  81. }
  82. utils.FilePutContents("WXMsgReceive", utils.SerializeStr(msg))
  83. log.Printf("[消息接收] - 收到消息, 消息类型为: %s", msg.MsgType)
  84. if msg.MsgType == "event" {
  85. //事件类型消息
  86. eventMsg := msg
  87. log.Printf("[事件类型]-收到消息, 事件类型为: %s, 事件KEY值为: %s\n, 二维码的ticket值为: %s\n", eventMsg.Event, eventMsg.EventKey, eventMsg.Ticket)
  88. if eventMsg.Event == "subscribe" {
  89. //用户未关注时,进行关注后的事件推送
  90. err := DealCallBack(eventMsg.FromUserName, eventMsg.Ticket)
  91. if err != nil {
  92. WXMsgReply(c, eventMsg.ToUserName, eventMsg.FromUserName, err.Error())
  93. }
  94. }
  95. if eventMsg.Event == "SCAN" {
  96. //用户已关注时的事件推送
  97. err := DealCallBack(eventMsg.FromUserName, eventMsg.Ticket)
  98. if err != nil {
  99. WXMsgReply(c, eventMsg.ToUserName, eventMsg.FromUserName, err.Error())
  100. }
  101. }
  102. }
  103. if msg.MsgType == "text" {
  104. //文本类型消息
  105. textMsg := msg
  106. log.Printf("[文本消息]-收到消息, 消息内容为: %s", textMsg.Content)
  107. WXMsgReply(c, textMsg.ToUserName, textMsg.FromUserName, textMsg.Content)
  108. }
  109. c.String(http.StatusOK, "")
  110. }
  111. // WXRepTextMsg 微信回复文本消息结构体
  112. type WXRepTextMsg struct {
  113. ToUserName string
  114. FromUserName string
  115. CreateTime int64
  116. MsgType string
  117. Content string
  118. // 若不标记XMLName, 则解析后的xml名为该结构体的名称
  119. XMLName xml.Name `xml:"xml"`
  120. }
  121. // WXMsgReply 微信消息回复
  122. func WXMsgReply(c *gin.Context, fromUser, toUser, content string) {
  123. repTextMsg := WXRepTextMsg{
  124. ToUserName: toUser,
  125. FromUserName: fromUser,
  126. CreateTime: time.Now().Unix(),
  127. MsgType: "text",
  128. Content: fmt.Sprintf("[消息回复] - %s \n %s", time.Now().Format("2006-01-02 15:04:05"), content),
  129. }
  130. msg, err := xml.Marshal(&repTextMsg)
  131. if err != nil {
  132. log.Printf("[消息回复] - 将对象进行XML编码出错: %v\n", err)
  133. return
  134. }
  135. _, _ = c.Writer.Write(msg)
  136. }
  137. func DealCallBack(openId, ticket string) error {
  138. //1、查找对应的二维码记录
  139. qrcodeDb := db.QrcodeDb{}
  140. qrcodeDb.Set()
  141. qrcode, err := qrcodeDb.GetQrcodeByIndex(ticket)
  142. if err != nil {
  143. return err
  144. }
  145. if qrcode == nil {
  146. return errors.New("未查询到对应二维码记录")
  147. }
  148. //2、查找当前二维码是否可用
  149. qrcodeWithBatchRecordsDb := db.QrcodeWithBatchRecordsDb{}
  150. qrcodeWithBatchRecordsDb.Set()
  151. qrcodeWithBatchRecord, err := qrcodeWithBatchRecordsDb.GetQrcodeWithBatchRecordsByQrcodeId(qrcode.Id)
  152. if err != nil {
  153. return err
  154. }
  155. if qrcodeWithBatchRecord == nil {
  156. return errors.New("当前二维码不可使用!")
  157. }
  158. //3、查找当前用户是否使用过当前二维码
  159. userUseQrcodeRecordsDb := db.UserUseQrcodeRecordsDb{}
  160. userUseQrcodeRecordsDb.Set()
  161. userUseQrcodeRecords, err := userUseQrcodeRecordsDb.GetUserUseQrcodeRecordsByOpenId(openId)
  162. if err != nil {
  163. return err
  164. }
  165. if userUseQrcodeRecords != nil {
  166. return errors.New("请勿重复使用二维码!")
  167. }
  168. //4、发送微信红包
  169. post, err := utils.CurlPost("http://pay.com/wx/redPackage/index", map[string]string{
  170. "openid": openId,
  171. "amount": utils.Float64ToStr(utils.StrToFloat64(qrcodeWithBatchRecord.Amount) * 100),
  172. }, nil)
  173. if err != nil {
  174. return err
  175. }
  176. var data md.SendRedPackageResp
  177. err = json.Unmarshal(post, &data)
  178. if err != nil {
  179. return err
  180. }
  181. if data.ReturnCode != "SUCCESS" || data.ResultCode != "SUCCESS" {
  182. return errors.New(data.ReturnMsg)
  183. }
  184. //5、将当前二维码状态修改为“可用”
  185. qrcode.State = enum.QrcodeSateAllowUse
  186. _, err = qrcodeDb.BatchUpdateQrcode(qrcode, "state")
  187. if err != nil {
  188. return err
  189. }
  190. //6、将当前二维码记录修改为“已使用”
  191. qrcodeWithBatchRecord.State = enum.QrcodeWithBatchRecordsStateForAlready
  192. _, err = qrcodeWithBatchRecordsDb.UpdateQrcodeWithBatchRecord(qrcodeWithBatchRecord)
  193. if err != nil {
  194. return err
  195. }
  196. //7、新增用户使用记录
  197. _, err = userUseQrcodeRecordsDb.InsertUserUseQrcodeRecords(&model.UserUseQrcodeRecords{
  198. UserWxOpenId: openId,
  199. RecordsId: qrcodeWithBatchRecord.Id,
  200. State: 1,
  201. CreateAt: time.Now().Format("2006-01-02 15:04:05"),
  202. UpdateAt: time.Now().Format("2006-01-02 15:04:05"),
  203. })
  204. if err != nil {
  205. return err
  206. }
  207. return nil
  208. }