90 lines
2.4 KiB
Go
90 lines
2.4 KiB
Go
package wx
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"fmt"
|
||
"github.com/gogf/gf/v2/os/glog"
|
||
"io"
|
||
"os"
|
||
v1 "server/api/wx/v1"
|
||
"server/internal/consts"
|
||
"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(consts.WeChatLoginLimit, 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(consts.WeChatLoginCache, 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
|
||
}
|