Skip to content

Commit

Permalink
add: 微信换绑
Browse files Browse the repository at this point in the history
  • Loading branch information
liangjies committed Jul 13, 2024
1 parent 221466d commit 853866d
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 42 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ require (
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/allegro/bigcache/v3 v3.1.0 // indirect
github.com/andybalholm/cascadia v1.3.1 // indirect
github.com/bits-and-blooms/bitset v1.5.0 // indirect
github.com/blendle/zapdriver v1.3.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGn
github.com/alicebob/miniredis/v2 v2.30.0 h1:uA3uhDbCxfO9+DI/DuGeAMr9qI+noVWwGPNTFuKID5M=
github.com/alicebob/miniredis/v2 v2.30.0/go.mod h1:84TWKZlxYkfgMucPBf5SOQBYJceZeQRFIaQgNMiCX6Q=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/allegro/bigcache/v3 v3.1.0 h1:H2Vp8VOvxcrB91o86fUSVJFqeuz8kpyyB02eH3bSzwk=
github.com/allegro/bigcache/v3 v3.1.0/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I=
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
Expand Down
3 changes: 2 additions & 1 deletion internal/app/api/v1/social.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ func WechatBindAddress(c *gin.Context) {
type WechatBind struct {
Address string `json:"address" form:"address" binding:"required"`
Code string `json:"code" form:"code" binding:"required"`
Replace bool `json:"replace" form:"replace"`
}
var wechatBind WechatBind
err := c.ShouldBindJSON(&wechatBind)
if err != nil {
FailWithMessage(GetMessage(c, "ParameterError"), c)
return
}
if err := srv.WechatBindAddress(c, wechatBind.Address, wechatBind.Code); err != nil {
if err := srv.WechatBindAddress(c, wechatBind.Address, wechatBind.Code, wechatBind.Replace); err != nil {
FailWithMessage(err.Error(), c)
} else {
Ok(c)
Expand Down
23 changes: 18 additions & 5 deletions internal/app/dao/social.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"gorm.io/gorm"
"math/rand"
"time"
)
Expand All @@ -20,8 +21,11 @@ func (d *Dao) WechatQueryByAddress(address string) (wechatData string, err error
// WechatIsBinding 判断是否已经绑定过
func (d *Dao) WechatIsBinding(fromUserName string) (string, bool, error) {
var address string
err := d.db.Raw("SELECT address FROM users WHERE socials->'wechat'->>'openid' = ?", fromUserName).Scan(&address).Error
err := d.db.Raw("SELECT address FROM users WHERE socials->'wechat'->>'openid' = ?", fromUserName).First(&address).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return "", false, nil
}
return "", false, err
}
return address, true, nil
Expand Down Expand Up @@ -92,7 +96,7 @@ func (d *Dao) DiscordBindAddress(discordID, username, address string) (err error

// DiscordQueryByAddress 查询地址绑定的discord信息
func (d *Dao) DiscordQueryByAddress(address string) (discordData string, err error) {
err = d.db.Raw("SELECT COALESCE(socials->'discord', '{}') FROM users WHERE address = ? LIMIT 1", address).Scan(&discordData).Error
err = d.db.Raw("SELECT COALESCE(socials->'discord', '{}') FROM users WHERE address = ? LIMIT 1", address).First(&discordData).Error
if err != nil {
return discordData, err
}
Expand All @@ -102,8 +106,11 @@ func (d *Dao) DiscordQueryByAddress(address string) (discordData string, err err
// DiscordIsBinding 判断Discord是否已经绑定过
func (d *Dao) DiscordIsBinding(discordID string) (string, bool, error) {
var address string
err := d.db.Raw("SELECT address FROM users WHERE socials->'discord'->>'id' = ? LIMIT 1", discordID).Scan(&address).Error
err := d.db.Raw("SELECT address FROM users WHERE socials->'discord'->>'id' = ?", discordID).First(&address).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return "", false, nil
}
return "", false, err
}
return address, true, nil
Expand All @@ -112,8 +119,11 @@ func (d *Dao) DiscordIsBinding(discordID string) (string, bool, error) {
// EmailIsBinding 判断邮箱是否已经绑定过
func (d *Dao) EmailIsBinding(email string) (string, bool, error) {
var address string
err := d.db.Raw("SELECT address FROM users WHERE socials->>'email' = ?", email).Scan(&address).Error
err := d.db.Raw("SELECT address FROM users WHERE socials->>'email' = ?", email).First(&address).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return "", false, nil
}
return "", false, err
}
return address, true, nil
Expand Down Expand Up @@ -185,8 +195,11 @@ func (d *Dao) GithubQueryByAddress(address string) (githubData string, err error
// GithubIsBinding 判断Github是否已经绑定过
func (d *Dao) GithubIsBinding(githubID string) (string, bool, error) {
var address string
err := d.db.Raw("SELECT address FROM users WHERE socials->'github'->>'id' = ?", githubID).Scan(&address).Error
err := d.db.Raw("SELECT address FROM users WHERE socials->'github'->>'id' = ?", githubID).First(&address).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return "", false, nil
}
return "", false, err
}
return address, true, nil
Expand Down
19 changes: 15 additions & 4 deletions internal/app/service/social.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (s *Service) GetWechatQrcode(address string) (data string, err error) {
}

// WechatBindAddress 处理地址绑定
func (s *Service) WechatBindAddress(c *gin.Context, address, fromUserName string) (err error) {
func (s *Service) WechatBindAddress(c *gin.Context, address, fromUserName string, replace bool) (err error) {
// 校验key
if c.GetHeader("x-api-key") != s.c.Social.Wechat.APIKey {
log.Errorv("非法请求", zap.String("x-api-key", c.GetHeader("x-api-key")))
Expand All @@ -51,12 +51,23 @@ func (s *Service) WechatBindAddress(c *gin.Context, address, fromUserName string
return errors.New("钱包地址已绑定,请勿重复操作")
}
// 判断微信是否被别的地址绑定过
_, isBinding, err := s.dao.WechatIsBinding(fromUserName)
bindingAddress, isBinding, err := s.dao.WechatIsBinding(fromUserName)
if err != nil {
return errors.New("服务器内部错误")
}
if isBinding {
return errors.New("微信已经绑定过地址")
// 替换绑定
if replace {
err = s.dao.UnbindSocial(address, "wechat")
if err != nil {
return errors.New("UnexpectedError")
}
} else {
bindingAddStr := fmt.Sprintf("%s...%s", bindingAddress[:6], bindingAddress[len(bindingAddress)-4:])
thisAddStr := fmt.Sprintf("%s...%s", address[:6], address[len(address)-4:])
errMsg := fmt.Sprintf("微信已经绑定到另一个用户 %s,回复 确认 解绑并绑定当前账户 %s", bindingAddStr, thisAddStr)
return errors.New(errMsg)
}
}
// 绑定
return s.dao.WechatBindAddress(address, fromUserName)
Expand Down Expand Up @@ -113,7 +124,7 @@ func (s *Service) DiscordCallback(address string, discordCallback interface{}, r
if Binding {
// 替换绑定
if replace {
err := s.dao.UnbindSocial(address, "email")
err = s.dao.UnbindSocial(address, "email")
if err != nil {
return res, errors.New("UnexpectedError")
}
Expand Down
7 changes: 5 additions & 2 deletions internal/auth/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@ package service
import (
"backend-go/internal/auth/config"
"context"
"github.com/allegro/bigcache/v3"
"time"
)

// Service struct
type Service struct {
c *config.Config
c *config.Config
cache *bigcache.BigCache
}

// New init.
func New(c *config.Config) (s *Service) {
s = &Service{
c: c,
}

s.cache, _ = bigcache.New(context.Background(), bigcache.DefaultConfig(10*time.Minute))
return
}

Expand Down
92 changes: 62 additions & 30 deletions internal/auth/service/wechat.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,7 @@ func (s *Service) WechatService(c *gin.Context) (err error) {
officialAccount := wc.GetOfficialAccount(cfg)
// 传入request和responseWriter
server := officialAccount.GetServer(req, rw)
//m := officialAccount.GetMaterial().AddMaterial("image", "/Users/chenzhen/Downloads/1.jpg")
//设置接收消息的处理方法
server.SetMessageHandler(func(msg *message.MixMessage) *message.Reply {
if msg.MsgType == message.MsgTypeEvent {
if msg.Event == message.EventSubscribe || msg.Event == message.EventScan {
if msgData, err := s.WechatBindAddress(msg.EventKey, string(msg.FromUserName)); err != nil {
if msgData != "" {
return &message.Reply{MsgType: message.MsgTypeText, MsgData: message.NewText("钱包地址绑定失败:" + msgData)}
} else {
return nil
}
}
return &message.Reply{MsgType: message.MsgTypeText, MsgData: message.NewText("钱包地址绑定成功")}
}

if msg.Event == message.EventClick {
// 社区二维码
image := message.NewImage("hE1FXKcBCLuXNojNQvWrBrvVQgQfoMgW2Eqv6hePAkLC4MZPj7ZjQr0wvHtuIjbB")
if msg.EventKey == "V1001_GOOD" {
return &message.Reply{MsgType: message.MsgTypeImage, MsgData: image}
}
}
}

fmt.Println(msg.MsgType)
fmt.Println(msg)
return nil
})
server.SetMessageHandler(s.messageHandler)
//处理消息接收以及回复
err = server.Serve()
if err != nil {
Expand All @@ -74,6 +47,63 @@ func (s *Service) WechatService(c *gin.Context) (err error) {
return
}

// messageHandler 消息处理
func (s *Service) messageHandler(msg *message.MixMessage) *message.Reply {
switch msg.MsgType {
case message.MsgTypeEvent:
return s.handleEvent(msg)
case message.MsgTypeText:
return s.handleText(msg)
}
return nil
}

// handleText 处理文本消息
func (s *Service) handleText(msg *message.MixMessage) *message.Reply {
if msg.Content == "确认" || msg.Content == "确定" {
return s.handleConfirmation(msg)
}
return nil
}

// handleEvent 处理事件消息
func (s *Service) handleEvent(msg *message.MixMessage) *message.Reply {
if msg.Event == message.EventSubscribe || msg.Event == message.EventScan {
return s.handleSubscription(msg)
}
if msg.Event == message.EventClick && msg.EventKey == "V1001_GOOD" {
return &message.Reply{MsgType: message.MsgTypeImage, MsgData: message.NewImage("hE1FXKcBCLuXNojNQvWrBrvVQgQfoMgW2Eqv6hePAkLC4MZPj7ZjQr0wvHtuIjbB")}
}
return nil
}

// handleSubscription 处理订阅事件
func (s *Service) handleSubscription(msg *message.MixMessage) *message.Reply {
err := s.cache.Set("wechat::"+string(msg.FromUserName), []byte(msg.EventKey))
if err != nil {
log.Errorv("缓存失败", zap.Error(err))
return nil
}
msgData, err := s.WechatBindAddress(msg.EventKey, string(msg.FromUserName), false)
if err != nil && msgData != "" {
return &message.Reply{MsgType: message.MsgTypeText, MsgData: message.NewText("钱包地址绑定失败:" + msgData)}
}
return &message.Reply{MsgType: message.MsgTypeText, MsgData: message.NewText("钱包地址绑定成功")}
}

// handleConfirmation 处理确认绑定消息
func (s *Service) handleConfirmation(msg *message.MixMessage) *message.Reply {
eventKey, err := s.cache.Get("wechat::" + string(msg.FromUserName))
if err != nil {
return &message.Reply{MsgType: message.MsgTypeText, MsgData: message.NewText("绑定信息已过期,请重新绑定")}
}
msgData, err := s.WechatBindAddress(string(eventKey), string(msg.FromUserName), true)
if err != nil && msgData != "" {
return &message.Reply{MsgType: message.MsgTypeText, MsgData: message.NewText("钱包地址绑定失败:" + msgData)}
}
return &message.Reply{MsgType: message.MsgTypeText, MsgData: message.NewText("钱包地址绑定成功")}
}

// GetWechatQrcode 获取关注二维码
func (s *Service) GetWechatQrcode(c *gin.Context, app, address string) (data string, err error) {
// 项目配置
Expand Down Expand Up @@ -103,7 +133,7 @@ func (s *Service) GetWechatQrcode(c *gin.Context, app, address string) (data str
}

// WechatBindAddress 处理地址绑定
func (s *Service) WechatBindAddress(eventKey, fromUserName string) (msg string, err error) {
func (s *Service) WechatBindAddress(eventKey, fromUserName string, replace bool) (msg string, err error) {
// 判断是否为绑定事件
if !strings.Contains(strings.Split(eventKey, "::")[1], "bind") {
log.Errorv("非绑定事件", zap.String("eventKey", eventKey))
Expand All @@ -121,16 +151,18 @@ func (s *Service) WechatBindAddress(eventKey, fromUserName string) (msg string,
type WechatBind struct {
Address string `json:"address" form:"address" binding:"required"`
Code string `json:"code" form:"code" binding:"required"`
Replace bool `json:"replace" form:"replace"`
}
wechatBind := WechatBind{
Address: address,
Code: fromUserName,
Replace: replace,
}
r, err := client.R().SetBodyJsonMarshal(wechatBind).Post(wechatConfig.CallBackURL + "/v1/social/wechatBindAddress")
if err != nil || r.StatusCode != 200 {
return "绑定失败", errors.New("绑定失败")
}
fmt.Println(r.String())
//fmt.Println(r.String())
// 绑定失败
if gjson.Get(r.String(), "status").Int() != 0 {
return gjson.Get(r.String(), "message").String(), errors.New("绑定失败")
Expand Down

0 comments on commit 853866d

Please sign in to comment.