一物一码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

288 lines
8.5 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. utils.FilePutContents("WXCheckSignature", utils.SerializeStr(map[string]interface{}{
  26. "signature": signature,
  27. "timestamp": timestamp,
  28. "nonce": nonce,
  29. "echostr": echostr,
  30. "ok": ok,
  31. }))
  32. if !ok {
  33. log.Println("[微信接入] - 微信公众号接入校验失败!")
  34. return
  35. }
  36. log.Println("[微信接入] - 微信公众号接入校验成功!")
  37. _, _ = c.Writer.WriteString(echostr)
  38. }
  39. // WXMsg 微信消息结构体
  40. type WXMsg struct {
  41. ToUserName string
  42. FromUserName string
  43. CreateTime int64
  44. MsgType string
  45. Content string
  46. MsgId int64
  47. Event string //事件类型,subscribe
  48. EventKey string //事件KEY值,qrscene_为前缀,后面为二维码的参数值
  49. Ticket string //二维码的ticket,可用来换取二维码图片
  50. }
  51. // WXTextMsg 微信文本消息结构体
  52. type WXTextMsg struct {
  53. ToUserName string
  54. FromUserName string
  55. CreateTime int64
  56. MsgType string
  57. Content string
  58. MsgId int64
  59. }
  60. // WXEventForSubscribeMsg 扫描带参数二维码事件消息结构体(用户未关注时,进行关注后的事件推送)
  61. type WXEventForSubscribeMsg struct {
  62. ToUserName string //开发者微信号
  63. FromUserName string //发送方帐号(一个OpenID)
  64. CreateTime int64 //消息创建时间 (整型)
  65. MsgType string //消息类型,event
  66. Event string //事件类型,subscribe
  67. EventKey string //事件KEY值,qrscene_为前缀,后面为二维码的参数值
  68. Ticket string //二维码的ticket,可用来换取二维码图片
  69. }
  70. // WXEventForScanMsg 扫描带参数二维码事件消息结构体(用户已关注时的事件推送)
  71. type WXEventForScanMsg struct {
  72. ToUserName string //开发者微信号
  73. FromUserName string //发送方帐号(一个OpenID)
  74. CreateTime int64 //消息创建时间 (整型)
  75. MsgType string //消息类型,event
  76. Event string //事件类型,subscribe
  77. EventKey string //事件KEY值,是一个32位无符号整数,即创建二维码时的二维码scene_id
  78. Ticket string //二维码的ticket,可用来换取二维码图片
  79. }
  80. // WXMsgReceive 微信消息接收
  81. func WXMsgReceive(c *gin.Context) {
  82. //log.Printf("[消息接收] - 收到新消息")
  83. //var msg WXMsg
  84. //err := c.ShouldBindXML(&msg)
  85. //if err != nil {
  86. // log.Printf("[消息接收] - XML数据包解析失败: %v\n", err)
  87. // return
  88. //}
  89. //utils.FilePutContents("WXMsgReceive", utils.SerializeStr(msg))
  90. //log.Printf("[消息接收] - 收到消息, 消息类型为: %s", msg.MsgType)
  91. //if msg.MsgType == "event" {
  92. // //事件类型消息
  93. // eventMsg := msg
  94. // log.Printf("[事件类型]-收到消息, 事件类型为: %s, 事件KEY值为: %s\n, 二维码的ticket值为: %s\n", eventMsg.Event, eventMsg.EventKey, eventMsg.Ticket)
  95. // if eventMsg.Event == "subscribe" {
  96. // //用户未关注时,进行关注后的事件推送
  97. // err := DealCallBack(eventMsg.FromUserName, eventMsg.EventKey)
  98. // if err != nil {
  99. // WXMsgReply(c, eventMsg.ToUserName, eventMsg.FromUserName, err.Error())
  100. // }
  101. // }
  102. // if eventMsg.Event == "SCAN" {
  103. // //用户已关注时的事件推送
  104. // err := DealCallBack(eventMsg.FromUserName, eventMsg.EventKey)
  105. // if err != nil {
  106. // WXMsgReply(c, eventMsg.ToUserName, eventMsg.FromUserName, err.Error())
  107. // }
  108. // }
  109. // if eventMsg.Event == "CLICK" { //公众号点击
  110. // if strings.Contains(strings.ToLower(eventMsg.EventKey), "official_account_custom_reply") {
  111. // id := strings.ReplaceAll(strings.ToLower(eventMsg.EventKey), "official_account_custom_reply_", "")
  112. // var mod model.SysModule
  113. // db.Db.Where("mod_id=?", id).Get(&mod)
  114. // fmt.Println(mod)
  115. // if mod.Data == "" {
  116. // fmt.Println(333)
  117. //
  118. // return
  119. // }
  120. // var data []md.ReplyContent
  121. // json.Unmarshal([]byte(mod.Data), &data)
  122. // for _, v := range data {
  123. // if v.MsgType == "text" {
  124. // fmt.Println(1111)
  125. //
  126. // svc.WXMsgTextReply(c, msg.ToUserName, msg.FromUserName, v.Text.Content)
  127. // }
  128. // if v.MsgType == "image" {
  129. // fmt.Println(22222)
  130. // svc.WXMsgImageReply(c, msg.ToUserName, msg.FromUserName, v.Image.MediaId)
  131. // }
  132. // }
  133. // }
  134. // }
  135. //}
  136. //if msg.MsgType == "text" {
  137. // //文本类型消息
  138. // textMsg := msg
  139. // log.Printf("[文本消息]-收到消息, 消息内容为: %s", textMsg.Content)
  140. // WXMsgReply(c, textMsg.ToUserName, textMsg.FromUserName, textMsg.Content)
  141. //}
  142. c.JSON(http.StatusOK, "")
  143. return
  144. }
  145. // WXRepTextMsg 微信回复文本消息结构体
  146. type WXRepTextMsg struct {
  147. ToUserName string
  148. FromUserName string
  149. CreateTime int64
  150. MsgType string
  151. Content string
  152. // 若不标记XMLName, 则解析后的xml名为该结构体的名称
  153. XMLName xml.Name `xml:"xml"`
  154. }
  155. // WXMsgReply 微信消息回复
  156. func WXMsgReply(c *gin.Context, fromUser, toUser, content string) {
  157. repTextMsg := WXRepTextMsg{
  158. ToUserName: toUser,
  159. FromUserName: fromUser,
  160. CreateTime: time.Now().Unix(),
  161. MsgType: "text",
  162. Content: fmt.Sprintf("[消息回复] - %s \n %s", time.Now().Format("2006-01-02 15:04:05"), content),
  163. }
  164. msg, err := xml.Marshal(&repTextMsg)
  165. if err != nil {
  166. log.Printf("[消息回复] - 将对象进行XML编码出错: %v\n", err)
  167. return
  168. }
  169. _, _ = c.Writer.Write(msg)
  170. }
  171. func DealCallBack(openId, ticket string) error {
  172. //1、查找对应的二维码记录
  173. qrcodeDb := db.QrcodeDb{}
  174. qrcodeDb.Set()
  175. qrcode, err := qrcodeDb.GetQrcodeByIndex(ticket)
  176. if err != nil {
  177. return err
  178. }
  179. if qrcode == nil {
  180. return errors.New("未查询到对应二维码记录")
  181. }
  182. //2、查找当前二维码是否可用
  183. qrcodeWithBatchRecordsDb := db.QrcodeWithBatchRecordsDb{}
  184. qrcodeWithBatchRecordsDb.Set()
  185. qrcodeWithBatchRecord, err := qrcodeWithBatchRecordsDb.GetQrcodeWithBatchRecordsByQrcodeId(qrcode.Id)
  186. if err != nil {
  187. return err
  188. }
  189. if qrcodeWithBatchRecord == nil {
  190. return errors.New("当前二维码不可使用!")
  191. }
  192. //3、查找当前用户是否使用过当前二维码
  193. userUseQrcodeRecordsDb := db.UserUseQrcodeRecordsDb{}
  194. userUseQrcodeRecordsDb.Set()
  195. userUseQrcodeRecords, err := userUseQrcodeRecordsDb.GetUserUseQrcodeRecordsByOpenId(openId)
  196. if err != nil {
  197. return err
  198. }
  199. if userUseQrcodeRecords != nil {
  200. return errors.New("请勿重复使用二维码!")
  201. }
  202. //4、发送微信红包
  203. post, err := utils.CurlPost("http://pay.izhyin.com/wx/redPackage/index", utils.SerializeStr(map[string]string{
  204. "openid": openId,
  205. "amount": utils.Float64ToStr(utils.StrToFloat64(qrcodeWithBatchRecord.Amount) * 100),
  206. }), nil)
  207. if err != nil {
  208. return err
  209. }
  210. utils.FilePutContents("send_redPackage", utils.SerializeStr(map[string]interface{}{
  211. "args": map[string]string{
  212. "openid": openId,
  213. "amount": utils.Float64ToStr(utils.StrToFloat64(qrcodeWithBatchRecord.Amount) * 100),
  214. },
  215. "resp": string(post),
  216. }))
  217. var result struct {
  218. Code int `json:"code"`
  219. Msg string `json:"msg"`
  220. Data interface{} `json:"data"`
  221. }
  222. err = json.Unmarshal(post, &result)
  223. if err != nil {
  224. return err
  225. }
  226. var data md.SendRedPackageResp
  227. err = json.Unmarshal(utils.Serialize(result.Data), &data)
  228. if err != nil {
  229. return err
  230. }
  231. utils.FilePutContents("send_redPackage", utils.SerializeStr(map[string]interface{}{
  232. "data": data,
  233. }))
  234. if data.ReturnCode != "SUCCESS" || data.ResultCode != "SUCCESS" {
  235. return errors.New(data.ReturnMsg)
  236. }
  237. //5、将当前二维码状态修改为“可用”
  238. qrcode.State = enum.QrcodeSateAllowUse
  239. _, err = qrcodeDb.BatchUpdateQrcode(qrcode, "state")
  240. if err != nil {
  241. return err
  242. }
  243. //6、将当前二维码记录修改为“已使用”
  244. qrcodeWithBatchRecord.State = enum.QrcodeWithBatchRecordsStateForAlready
  245. _, err = qrcodeWithBatchRecordsDb.UpdateQrcodeWithBatchRecord(qrcodeWithBatchRecord)
  246. if err != nil {
  247. return err
  248. }
  249. //7、新增用户使用记录
  250. _, err = userUseQrcodeRecordsDb.InsertUserUseQrcodeRecords(&model.UserUseQrcodeRecords{
  251. UserWxOpenId: openId,
  252. RecordsId: qrcodeWithBatchRecord.Id,
  253. State: 1,
  254. CreateAt: time.Now().Format("2006-01-02 15:04:05"),
  255. UpdateAt: time.Now().Format("2006-01-02 15:04:05"),
  256. })
  257. if err != nil {
  258. return err
  259. }
  260. return nil
  261. }