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 }