调整微信扫码登录相关接口,拆分门店奖励:奖励类型、奖励详情
This commit is contained in:
@ -2,13 +2,19 @@ package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
"server/api/admin/v1"
|
||||
v1 "server/api/admin/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) AdminInfo(ctx context.Context, req *v1.AdminInfoReq) (res *v1.AdminInfoRes, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
userId := g.RequestFromCtx(ctx).GetCtxVar("userId").Int()
|
||||
out, err := service.Admin().Info(ctx, &model.AdminInfoIn{Id: userId})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.AdminInfoRes{Username: out.Username}, nil
|
||||
}
|
||||
|
||||
@ -2,13 +2,19 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
|
||||
"server/api/auth/v1"
|
||||
v1 "server/api/auth/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) AdminLogin(ctx context.Context, req *v1.AdminLoginReq) (res *v1.AdminLoginRes, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
|
||||
out, err := service.Admin().Login(ctx, &model.AdminLoginIn{
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.AdminLoginRes{Token: out.Token}, nil
|
||||
}
|
||||
|
||||
@ -2,32 +2,90 @@ package wx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"fmt"
|
||||
v1 "server/api/wx/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
"strings"
|
||||
|
||||
"server/api/auth/v1"
|
||||
"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,
|
||||
"微信消息推送:时间=%d, 消息类型=%s, 事件=%s, 事件Key=%s",
|
||||
req.CreateTime,
|
||||
req.MsgType,
|
||||
req.Event,
|
||||
req.EventKey,
|
||||
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,
|
||||
)
|
||||
// 根据事件类型进行不同的处理:
|
||||
switch req.MsgType {
|
||||
case "event":
|
||||
switch req.Event {
|
||||
case "subscribe":
|
||||
// 未关注,扫描关注后, 注册账号,关联微信的 open_id
|
||||
key := strings.TrimPrefix(req.EventKey, "qrscene_")
|
||||
out, err := service.User().Login(ctx, &model.UserLoginIn{OpenId: req.FromUserName})
|
||||
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":
|
||||
// 已关注,扫描后,根据 open_id 查找用户生成 token
|
||||
out, err := service.User().Login(ctx, &model.UserLoginIn{OpenId: req.FromUserName})
|
||||
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
|
||||
}
|
||||
return nil, nil
|
||||
|
||||
}
|
||||
|
||||
func updateLoginCache(ctx context.Context, key string, token string) error {
|
||||
loginCacheKey := fmt.Sprintf("wx:login:cache:%s", 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
|
||||
}
|
||||
|
||||
@ -2,14 +2,54 @@ package wx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
v1 "server/api/wx/v1"
|
||||
"server/internal/model"
|
||||
"server/utility/ecode"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
|
||||
"server/api/auth/v1"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) WeChatPolling(ctx context.Context, req *v1.WeChatPollingReq) (res *v1.WeChatPollingRes, err error) {
|
||||
// 收到请求根据 uuid 查询缓存中的数据,看看是否生成了 token
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
loginCacheKey := fmt.Sprintf("wx:login:cache:%s", req.SceneId)
|
||||
glog.Infof(ctx, "开始处理微信长轮询请求,SceneID: %s", req.SceneId)
|
||||
|
||||
var loginCache model.LoginCache
|
||||
|
||||
data, err := g.Redis().Get(ctx, loginCacheKey)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "从 Redis 获取登录缓存失败,SceneID: %s,错误: %v", req.SceneId, err)
|
||||
return nil, ecode.Fail.Sub("获取登录状态失败")
|
||||
}
|
||||
|
||||
if data.IsEmpty() {
|
||||
glog.Warningf(ctx, "用户尚未扫码登录,SceneID: %s", req.SceneId)
|
||||
return nil, ecode.InvalidOperation.Sub("请先调用获取二维码登录")
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(data.Bytes(), &loginCache); err != nil {
|
||||
glog.Errorf(ctx, "解析登录状态失败,SceneID: %s,错误: %v", req.SceneId, err)
|
||||
return nil, ecode.Fail.Sub("解析登录状态失败")
|
||||
}
|
||||
|
||||
switch loginCache.Status {
|
||||
case 0:
|
||||
glog.Infof(ctx, "用户尚未扫码登录,SceneID: %s", req.SceneId)
|
||||
return &v1.WeChatPollingRes{
|
||||
Status: "waiting",
|
||||
Token: "",
|
||||
}, nil
|
||||
case 1:
|
||||
// 直接返回缓存的token
|
||||
glog.Infof(ctx, "用户扫码登录成功,SceneID: %s,返回缓存Token", req.SceneId)
|
||||
return &v1.WeChatPollingRes{
|
||||
Status: "success",
|
||||
Token: loginCache.Token,
|
||||
}, nil
|
||||
default:
|
||||
glog.Warningf(ctx, "未知登录状态 %d,SceneID: %s", loginCache.Status, req.SceneId)
|
||||
return nil, ecode.InvalidOperation.Sub("未知登录状态")
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,31 +2,34 @@ package wx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/crypto/gsha1"
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"server/utility/ecode"
|
||||
"server/utility/wechat"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"server/api/auth/v1"
|
||||
"server/api/wx/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) WeChatVertify(ctx context.Context, req *v1.WeChatVertifyReq) (res *v1.WeChatVertifyRes, err error) {
|
||||
|
||||
weChatToken := g.Config().MustGet(ctx, "wechat.token").String()
|
||||
// 1. 将 token、timestamp、nonce 组成 slice
|
||||
params := []string{weChatToken, req.Timestamp, req.Nonce}
|
||||
// 2. 字典序排序
|
||||
// 1. 排序
|
||||
params := []string{wechat.GetWeChatClient().GetToken(), req.Timestamp, req.Nonce}
|
||||
sort.Strings(params)
|
||||
// 3. 拼接字符串
|
||||
joined := strings.Join(params, "")
|
||||
// 4. SHA1 加密
|
||||
encrypt := gsha1.Encrypt(joined)
|
||||
|
||||
// 5. 与 signature 对比
|
||||
if encrypt != req.Signature {
|
||||
return nil, ecode.InvalidOperation.Sub("微信服务器验证失败")
|
||||
// 2. 拼接成字符串
|
||||
str := strings.Join(params, "")
|
||||
|
||||
// 3. SHA1 加密
|
||||
h := sha1.New()
|
||||
h.Write([]byte(str))
|
||||
sha1Str := fmt.Sprintf("%x", h.Sum(nil))
|
||||
|
||||
// 4. 比较签名
|
||||
if sha1Str != req.Signature {
|
||||
return nil, fmt.Errorf("签名错误")
|
||||
}
|
||||
g.RequestFromCtx(ctx).Response.WriteJson(req.EchoStr)
|
||||
return
|
||||
g.RequestFromCtx(ctx).Response.Write(req.EchoStr)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user