Files
arenax-server/internal/controller/wx/wx_v1_we_chat_event.go

99 lines
3.2 KiB
Go

package wx
import (
"context"
"fmt"
v1 "server/api/wx/v1"
"server/internal/consts"
"server/internal/model"
"server/internal/service"
"server/utility/wechat"
"strings"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/glog"
)
func (c *ControllerV1) WeChatEvent(ctx context.Context, req *v1.WeChatEventReq) (res *v1.WeChatEventRes, err error) {
glog.Infof(ctx, "【微信事件】收到事件 | event=%s, msgType=%s, eventKey=%s, fromUserName=%s, toUserName=%s, createTime=%d",
req.Event, req.MsgType, req.EventKey, req.FromUserName, req.ToUserName, req.CreateTime,
)
unionid, err := wechat.GetWeChatClient().GetUserUnionId(ctx, req.FromUserName)
if err != nil {
glog.Errorf(ctx, "【微信事件】获取用户信息失败 | error=%s", err.Error())
return nil, nil
}
switch req.MsgType {
case "event":
switch req.Event {
case "subscribe":
key := strings.TrimPrefix(req.EventKey, "qrscene_")
out, err := service.User().Login(ctx, &model.UserLoginIn{OpenId: unionid, SceneId: key})
if err != nil {
return nil, err
}
if err = updateLoginCache(ctx, key, out.Token); err != nil {
glog.Errorf(ctx, "【微信事件】更新登录缓存失败 | error=%s", err.Error())
}
return nil, nil
case "SCAN":
out, err := service.User().Login(ctx, &model.UserLoginIn{OpenId: unionid, SceneId: req.EventKey})
if err != nil {
return nil, err
}
if err = updateLoginCache(ctx, req.EventKey, out.Token); err != nil {
glog.Errorf(ctx, "【微信事件】更新登录缓存失败 | error=%s", err.Error())
}
return nil, nil
default:
glog.Infof(ctx, "【微信事件】不支持的事件 | event=%s", req.Event)
return nil, nil
}
default:
glog.Infof(ctx, "【微信事件】不支持的消息类型 | msgType=%s", req.MsgType)
return nil, nil
}
}
func updateLoginCache(ctx context.Context, key string, token string) error {
loginCacheKey := fmt.Sprintf(consts.WeChatLoginCache, key)
glog.Infof(ctx, "【微信事件】准备更新登录缓存 | redisKey=%s, token=%s", loginCacheKey, token)
// 获取原缓存
data, err := g.Redis().Get(ctx, loginCacheKey)
if err != nil {
glog.Errorf(ctx, "【微信事件】获取缓存失败 | key=%s, error=%v", loginCacheKey, err)
return err
}
if data.IsEmpty() {
glog.Warningf(ctx, "【微信事件】缓存不存在 | key=%s", loginCacheKey)
return nil // 不是错误,只是二维码超时或错误
}
// 反序列化
var loginCache model.LoginCache
if err := gjson.Unmarshal(data.Bytes(), &loginCache); err != nil {
glog.Errorf(ctx, "【微信事件】反序列化缓存失败 | key=%s, error=%v", loginCacheKey, err)
return err
}
// 更新状态与Token
loginCache.Status = 1
loginCache.Token = token
// 序列化并写回 Redis
newData, err := gjson.Marshal(loginCache)
if err != nil {
glog.Errorf(ctx, "【微信事件】序列化缓存失败 | key=%s, error=%v", loginCacheKey, err)
return err
}
if err := g.Redis().SetEX(ctx, loginCacheKey, newData, 60); err != nil {
glog.Errorf(ctx, "【微信事件】写入缓存失败 | key=%s, error=%v", loginCacheKey, err)
return err
}
glog.Infof(ctx, "【微信事件】缓存更新成功 | key=%s, token=%s", loginCacheKey, token)
return nil
}