package wx import ( "context" "encoding/json" "fmt" "github.com/gogf/gf/v2/os/glog" "io" "os" v1 "server/api/wx/v1" "server/internal/model" "server/utility/ecode" "server/utility/wechat" "time" "github.com/gogf/gf/v2/frame/g" ) func (c *ControllerV1) WeChatLogin(ctx context.Context, req *v1.WeChatLoginReq) (res *v1.WeChatLoginRes, err error) { glog.Infof(ctx, "收到微信登录请求,SceneId: %s", req.SceneId) loginLimitKey := fmt.Sprintf("wx:login:limit:%s", req.SceneId) // 检查登录限制 va, err := g.Redis().Get(ctx, loginLimitKey) if err != nil { glog.Errorf(ctx, "Redis 获取登录限制失败: %v", err) return nil, ecode.Fail.Sub("获取登录限制失败") } if !va.IsEmpty() { glog.Warningf(ctx, "SceneId %s 登录请求过于频繁", req.SceneId) return nil, ecode.InvalidOperation.Sub("请勿重复请求登录二维码") } if err = g.Redis().SetEX(ctx, loginLimitKey, 1, 60); err != nil { glog.Errorf(ctx, "Redis 设置登录限制失败: %v", err) return nil, ecode.Fail.Sub("登录频率限制设置失败") } client := wechat.GetWeChatClient() ticket, err := client.GetTicket(fmt.Sprintf("%s", req.SceneId)) if err != nil { glog.Errorf(ctx, "获取微信 ticket 失败: %v", err) return nil, err } qrCode, err := client.GetQrCode(ticket) if err != nil { glog.Errorf(ctx, "生成二维码失败: %v", err) return nil, err } file, err := os.Open(qrCode) if err != nil { glog.Errorf(ctx, "二维码文件打开失败: %v", err) return nil, ecode.Fail.Sub("二维码文件打开失败") } defer func() { file.Close() os.Remove(qrCode) }() imgBytes, err := io.ReadAll(file) if err != nil { glog.Errorf(ctx, "读取二维码失败: %v", err) return nil, ecode.Fail.Sub("二维码读取失败") } resp := g.RequestFromCtx(ctx).Response resp.Header().Set("Content-Type", "image/jpeg") resp.Write(imgBytes) loginCache := model.LoginCache{ Status: 0, CreatedAt: time.Now(), } data, err := json.Marshal(loginCache) if err == nil { _ = g.Redis().SetEX(ctx, fmt.Sprintf("wx:login:cache:%s", req.SceneId), data, 60) glog.Infof(ctx, "SceneId %s 登录缓存已写入 Redis", req.SceneId) } else { glog.Warningf(ctx, "SceneId %s登录缓存序列化失败: %v", req.SceneId, err) } glog.Infof(ctx, "SceneId %s 登录二维码已返回", req.SceneId) return nil, nil }