diff --git a/go.mod b/go.mod index 995f6e5..f9fb4e3 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/google/uuid v1.6.0 github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 + github.com/silenceper/wechat/v2 v2.1.12 github.com/sirupsen/logrus v1.9.4 golang.org/x/crypto v0.49.0 gorm.io/driver/mysql v1.6.0 @@ -48,7 +49,6 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/quic-go/qpack v0.6.0 // indirect github.com/quic-go/quic-go v0.59.0 // indirect - github.com/silenceper/wechat/v2 v2.1.12 // indirect github.com/spf13/cast v1.10.0 // indirect github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.2.0 // indirect diff --git a/model/wechat-model.go b/model/wechat-model.go new file mode 100644 index 0000000..03fbe06 --- /dev/null +++ b/model/wechat-model.go @@ -0,0 +1,15 @@ +package model + +import ( + "time" +) + +type WechatEvent struct { + ID uint `gorm:"primarykey"` + ToUserName string `gorm:"column:to_username;type:varchar(50);not null;comment:微信openid"` + FromUserName string `gorm:"column:from_username;type:varchar(30);not null;comment:微信服务号APPID"` + EventType string `gorm:"column:event_type;type:varchar(30);comment:事件类型"` //事件类型 + EventTime time.Time `gorm:"column:event_time"` + EventKey string `gorm:"column:event_key;type:varchar(50);not null;index;comment:事件key"` + CreatedAt time.Time `gorm:"autoCreateTime"` +} diff --git a/mysql/tables-mysql.go b/mysql/tables-mysql.go index fc6405e..746e323 100644 --- a/mysql/tables-mysql.go +++ b/mysql/tables-mysql.go @@ -21,6 +21,13 @@ func init() { panic(err) } + //微信相关 + if err := db.AutoMigrate( + &model.WechatEvent{}, + ); err != nil { + panic(err) + } + //业务相关表 if err := db.AutoMigrate( &model.Project{}, diff --git a/mysql/wechat-mysql.go b/mysql/wechat-mysql.go new file mode 100644 index 0000000..92da267 --- /dev/null +++ b/mysql/wechat-mysql.go @@ -0,0 +1,17 @@ +package mysql + +import ( + "myschools.me/heritage/heritage-api/model" +) + +// WechatEvent创建 +func WechatEventCreate(obj *model.WechatEvent) error { + db, err := newDB() + if err != nil { + return err + } + if err := db.Create(obj).Error; err != nil { + return err + } + return nil +} diff --git a/redis/wechat-redis.go b/redis/wechat-redis.go new file mode 100644 index 0000000..476afc4 --- /dev/null +++ b/redis/wechat-redis.go @@ -0,0 +1,31 @@ +package redis + +import ( + "encoding/json" + "fmt" + "time" + + "myschools.me/heritage/heritage-api/model" +) + +var ( + EventKey = "wechat:event_%s" +) + +func WechatEventSet(id *string, obj *model.WechatEvent) error { + key := fmt.Sprintf(EventKey, id) + return set(&key, obj, time.Minute) +} + +func WechatEventGet(id *string) (*model.WechatEvent, error) { + key := fmt.Sprintf(EventKey, id) + data, err := getBytes(&key) + if err != nil { + return nil, err + } + reply := &model.WechatEvent{} + if err = json.Unmarshal(*data, reply); err != nil { + return nil, err + } + return reply, nil +} diff --git a/service/wechat-service.go b/service/wechat-service.go index 6cb8394..b75cfa9 100644 --- a/service/wechat-service.go +++ b/service/wechat-service.go @@ -1,16 +1,23 @@ package service import ( + "context" "encoding/json" "fmt" "os" "strconv" + "strings" + "time" "github.com/silenceper/wechat/v2" "github.com/silenceper/wechat/v2/cache" "github.com/silenceper/wechat/v2/officialaccount" "github.com/silenceper/wechat/v2/officialaccount/config" + "github.com/silenceper/wechat/v2/officialaccount/message" "github.com/sirupsen/logrus" + "myschools.me/heritage/heritage-api/model" + "myschools.me/heritage/heritage-api/mysql" + "myschools.me/heritage/heritage-api/redis" ) type ticketRequest struct { @@ -43,7 +50,7 @@ var ( func init() { wx := wechat.NewWechat() - wx.SetCache(cache.NewRedis(nil, &cache.RedisOpts{ + wx.SetCache(cache.NewRedis(context.TODO(), &cache.RedisOpts{ Host: os.Getenv("REDIS_HOST"), Password: os.Getenv("REDIS_PWD"), Database: func() int { @@ -118,6 +125,65 @@ func WechatQrGet(reqid *string) (any, error) { return resp, nil } -func WechatAuth(reqid, code *string) (any, error) { - return nil, nil +// 消息处理 +func WechatEvent(msg *message.MixMessage) *message.Reply { + e := &model.WechatEvent{ + FromUserName: string(msg.FromUserName), + ToUserName: string(msg.ToUserName), + EventKey: msg.EventKey, + EventTime: time.Unix(msg.CreateTime, 0), + EventType: string(msg.Event), + CreatedAt: time.Now(), + } + //打印请求参数 + logrus.WithFields(logrus.Fields{ + "func": "WechatEvent", + }).Warnf("EventMessage.EventKey: %s", msg.EventKey) + + if err := mysql.WechatEventCreate(e); err != nil { + logrus.WithFields(logrus.Fields{ + "func": "WechatEvent", + }).Warnf("mysql.WechatEventSet: %s,Event: %v", err.Error(), msg) + return nil + } + + key := strings.Split(msg.EventKey, "_") + e.EventKey = key[len(key)-1] + + switch msg.Event { + case message.EventScan: + if err := redis.WechatEventSet(&e.EventKey, e); err != nil { + logrus.WithFields(logrus.Fields{ + "func": "WechatEvent", + }).Warnf("redis.WechatEventSet: %s", err.Error()) + return nil + } + case message.EventSubscribe: + if err := redis.WechatEventSet(&e.EventKey, e); err != nil { + logrus.WithFields(logrus.Fields{ + "func": "WechatEvent", + }).Warnf("redis.WechatEventSet: %s", err.Error()) + return nil + } + // text := message.NewText("欢迎登录") + + case message.EventUnsubscribe: + } + return nil + +} + +func WechatAuth(reqid *string) (*string, error) { + event, err := redis.WechatEventGet(reqid) + if err != nil { + if !strings.Contains(err.Error(), "redigo: nil returned") { + logrus.WithFields(logrus.Fields{ + "func": "WechatAuth", + }).Warnf("redis.WechatEventGet: %v", err) + return nil, err + } + return nil, nil + } + + return &event.FromUserName, nil }