调整微信扫码登录相关接口,拆分门店奖励:奖励类型、奖励详情
This commit is contained in:
@ -5,7 +5,9 @@ import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/gcmd"
|
||||
"server/internal/controller/admin"
|
||||
"server/internal/controller/auth"
|
||||
"server/internal/controller/wx"
|
||||
"server/internal/middleware"
|
||||
)
|
||||
|
||||
@ -21,7 +23,15 @@ var (
|
||||
group.Middleware(ghttp.MiddlewareCORS)
|
||||
group.Bind(
|
||||
auth.NewV1(),
|
||||
wx.NewV1(),
|
||||
)
|
||||
group.Group("/x", func(group *ghttp.RouterGroup) {
|
||||
group.Middleware(middleware.Auth)
|
||||
group.Middleware(middleware.Casbin)
|
||||
group.Bind(
|
||||
admin.NewV1(),
|
||||
)
|
||||
})
|
||||
})
|
||||
s.Run()
|
||||
return nil
|
||||
|
||||
@ -1 +1,13 @@
|
||||
package consts
|
||||
|
||||
const (
|
||||
GuestPermission = "guest"
|
||||
UserPermission = "user"
|
||||
AdminPermission = "admin"
|
||||
MerchantPermission = "merchant"
|
||||
StorePermission = "store"
|
||||
)
|
||||
const (
|
||||
QRCodeExpireTime = 60
|
||||
QRCodeLimitTime = 10
|
||||
)
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -26,10 +26,7 @@ type AdminsColumns struct {
|
||||
RealName string // 真实姓名
|
||||
Phone string // 手机号
|
||||
Email string // 邮箱
|
||||
Role string // 角色:1=超级管理员,2=运营管理员,3=客服管理员,4=财务管理员
|
||||
Status string // 状态:1=正常,2=禁用
|
||||
LastLoginAt string // 最后登录时间
|
||||
LastLoginIp string // 最后登录IP
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
@ -43,10 +40,7 @@ var adminsColumns = AdminsColumns{
|
||||
RealName: "real_name",
|
||||
Phone: "phone",
|
||||
Email: "email",
|
||||
Role: "role",
|
||||
Status: "status",
|
||||
LastLoginAt: "last_login_at",
|
||||
LastLoginIp: "last_login_ip",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
|
||||
87
internal/dao/internal/reward_types.go
Normal file
87
internal/dao/internal/reward_types.go
Normal file
@ -0,0 +1,87 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// RewardTypesDao is the data access object for the table reward_types.
|
||||
type RewardTypesDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns RewardTypesColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// RewardTypesColumns defines and stores column names for the table reward_types.
|
||||
type RewardTypesColumns struct {
|
||||
Id string // 类型ID
|
||||
Name string // 类型名称
|
||||
Code string // 类型编码
|
||||
Description string // 类型描述
|
||||
Status string // 状态:1=启用,2=禁用
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间
|
||||
}
|
||||
|
||||
// rewardTypesColumns holds the columns for the table reward_types.
|
||||
var rewardTypesColumns = RewardTypesColumns{
|
||||
Id: "id",
|
||||
Name: "name",
|
||||
Code: "code",
|
||||
Description: "description",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewRewardTypesDao creates and returns a new DAO object for table data access.
|
||||
func NewRewardTypesDao() *RewardTypesDao {
|
||||
return &RewardTypesDao{
|
||||
group: "default",
|
||||
table: "reward_types",
|
||||
columns: rewardTypesColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *RewardTypesDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *RewardTypesDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *RewardTypesDao) Columns() RewardTypesColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *RewardTypesDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *RewardTypesDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *RewardTypesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@ -20,30 +20,30 @@ type StoreRewardsDao struct {
|
||||
|
||||
// StoreRewardsColumns defines and stores column names for the table store_rewards.
|
||||
type StoreRewardsColumns struct {
|
||||
Id string // 门店奖励ID
|
||||
StoreId string // 所属门店ID
|
||||
RewardType string // 奖励类型:1=积分,2=优惠券,3=商品,4=抽奖券
|
||||
RewardName string // 奖励名称
|
||||
Amount string // 奖励数量
|
||||
Total string // 该奖励总库存(NULL 表示无限)
|
||||
MerchantId string // 所属商户ID
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
Id string // 门店奖励ID
|
||||
StoreId string // 所属门店ID
|
||||
RewardTypeId string // 奖励类型ID
|
||||
RewardName string // 奖励名称
|
||||
Amount string // 奖励数量
|
||||
Total string // 该奖励总库存(NULL 表示无限)
|
||||
MerchantId string // 所属商户ID
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
}
|
||||
|
||||
// storeRewardsColumns holds the columns for the table store_rewards.
|
||||
var storeRewardsColumns = StoreRewardsColumns{
|
||||
Id: "id",
|
||||
StoreId: "store_id",
|
||||
RewardType: "reward_type",
|
||||
RewardName: "reward_name",
|
||||
Amount: "amount",
|
||||
Total: "total",
|
||||
MerchantId: "merchant_id",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
Id: "id",
|
||||
StoreId: "store_id",
|
||||
RewardTypeId: "reward_type_id",
|
||||
RewardName: "reward_name",
|
||||
Amount: "amount",
|
||||
Total: "total",
|
||||
MerchantId: "merchant_id",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewStoreRewardsDao creates and returns a new DAO object for table data access.
|
||||
|
||||
@ -23,10 +23,8 @@ type UserLoginRecordsColumns struct {
|
||||
Id string // 记录ID
|
||||
UserId string // 用户ID
|
||||
StoreId string // 登录门店ID
|
||||
MerchantId string // 所属商户ID
|
||||
LoginIp string // 登录IP地址
|
||||
LoginDevice string // 登录设备信息
|
||||
LoginPlatform string // 登录平台:1=Web,2=iOS,3=Android,4=微信小程序,5=支付宝小程序,6=其他
|
||||
LoginPlatform string // 登录平台:1=PC
|
||||
LoginType string // 登录方式:1=微信,2=手机号,3=账号密码,4=其他
|
||||
LoginStatus string // 登录状态:1=成功,2=失败
|
||||
FailReason string // 失败原因
|
||||
@ -40,9 +38,7 @@ var userLoginRecordsColumns = UserLoginRecordsColumns{
|
||||
Id: "id",
|
||||
UserId: "user_id",
|
||||
StoreId: "store_id",
|
||||
MerchantId: "merchant_id",
|
||||
LoginIp: "login_ip",
|
||||
LoginDevice: "login_device",
|
||||
LoginPlatform: "login_platform",
|
||||
LoginType: "login_type",
|
||||
LoginStatus: "login_status",
|
||||
|
||||
27
internal/dao/reward_types.go
Normal file
27
internal/dao/reward_types.go
Normal file
@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"server/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalRewardTypesDao is an internal type for wrapping the internal DAO implementation.
|
||||
type internalRewardTypesDao = *internal.RewardTypesDao
|
||||
|
||||
// rewardTypesDao is the data access object for the table reward_types.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type rewardTypesDao struct {
|
||||
internalRewardTypesDao
|
||||
}
|
||||
|
||||
var (
|
||||
// RewardTypes is a globally accessible object for table reward_types operations.
|
||||
RewardTypes = rewardTypesDao{
|
||||
internal.NewRewardTypesDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@ -2,6 +2,8 @@ package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"server/internal/consts"
|
||||
"server/internal/dao"
|
||||
"server/internal/model"
|
||||
"server/internal/model/do"
|
||||
@ -19,8 +21,29 @@ func New() service.IAdmin {
|
||||
return &sAdmin{}
|
||||
}
|
||||
|
||||
func checkAdmin() {
|
||||
ctx := context.Background()
|
||||
exist, err := dao.Admins.Ctx(ctx).Where(do.Admins{Username: "admin"}).Exist()
|
||||
if err != nil {
|
||||
panic("初始化管理员失败")
|
||||
}
|
||||
if !exist {
|
||||
passwordHash, _ := utility.EncryptPassword("Aa123456")
|
||||
_, err = dao.Admins.Ctx(ctx).Insert(do.Admins{
|
||||
Username: "admin",
|
||||
PasswordHash: passwordHash,
|
||||
Status: 1,
|
||||
})
|
||||
if err != nil {
|
||||
panic("初始化管理员失败")
|
||||
}
|
||||
}
|
||||
glog.Infof(ctx, "初始化管理员成功")
|
||||
}
|
||||
|
||||
func init() {
|
||||
service.RegisterAdmin(New())
|
||||
go checkAdmin()
|
||||
}
|
||||
func (s *sAdmin) Login(ctx context.Context, in *model.AdminLoginIn) (out *model.LoginOut, err error) {
|
||||
exist, err := dao.Admins.Ctx(ctx).Exist(do.Admins{Username: in.Username})
|
||||
@ -35,12 +58,13 @@ func (s *sAdmin) Login(ctx context.Context, in *model.AdminLoginIn) (out *model.
|
||||
return nil, ecode.Fail.Sub("查询管理员失败")
|
||||
}
|
||||
if !utility.ComparePassword(admin.PasswordHash, in.Password) {
|
||||
return nil, ecode.Auth.Sub("密码错误")
|
||||
return nil, ecode.Auth
|
||||
}
|
||||
token, err := jwt.GenerateToken(&jwt.TokenIn{UserId: admin.Id, Permission: "admin"})
|
||||
token, err := jwt.GenerateToken(&jwt.TokenIn{UserId: admin.Id, Permission: consts.AdminPermission})
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("生成token失败")
|
||||
}
|
||||
|
||||
out = &model.LoginOut{
|
||||
Token: token,
|
||||
}
|
||||
@ -55,5 +79,12 @@ func (s *sAdmin) Info(ctx context.Context, in *model.AdminInfoIn) (out *model.Ad
|
||||
if !exist {
|
||||
return nil, ecode.Params.Sub("该用户不存在")
|
||||
}
|
||||
var admin entity.Admins
|
||||
if err := dao.Admins.Ctx(ctx).WherePri(in.Id).Scan(&admin); err != nil {
|
||||
return nil, ecode.Fail.Sub("查询管理员失败")
|
||||
}
|
||||
out = &model.AdminInfoOut{
|
||||
Username: admin.Username,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -1 +1,102 @@
|
||||
package user
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/consts"
|
||||
"server/internal/dao"
|
||||
"server/internal/model"
|
||||
"server/internal/model/do"
|
||||
"server/internal/model/entity"
|
||||
"server/internal/service"
|
||||
"server/utility/ecode"
|
||||
"server/utility/jwt"
|
||||
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/grand"
|
||||
)
|
||||
|
||||
type sUser struct{}
|
||||
|
||||
func init() {
|
||||
service.RegisterUser(New())
|
||||
}
|
||||
|
||||
func New() service.IUser {
|
||||
return &sUser{}
|
||||
}
|
||||
|
||||
func (s *sUser) Login(ctx context.Context, in *model.UserLoginIn) (out *model.UserLoginOut, err error) {
|
||||
// 根据 OpenId 查找用户
|
||||
exist, err := dao.Users.Ctx(ctx).Where(do.Users{WxOpenId: in.OpenId}).Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("查找用户失败")
|
||||
}
|
||||
|
||||
var userId int64
|
||||
if !exist {
|
||||
// 用户不存在,创建新用户
|
||||
user := &entity.Users{
|
||||
WxOpenId: in.OpenId,
|
||||
Username: grand.Digits(10),
|
||||
FirstVisitAt: gtime.Now(),
|
||||
}
|
||||
result, err := dao.Users.Ctx(ctx).Insert(user)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("创建用户失败")
|
||||
}
|
||||
userId, err = result.LastInsertId()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("获取用户ID失败")
|
||||
}
|
||||
} else {
|
||||
// 用户存在,更新最后登录时间
|
||||
var user entity.Users
|
||||
if err := dao.Users.Ctx(ctx).Where(do.Users{WxOpenId: in.OpenId}).Scan(&user); err != nil {
|
||||
return nil, ecode.Fail.Sub("查找用户失败")
|
||||
}
|
||||
userId = user.Id
|
||||
if _, err := dao.Users.Ctx(ctx).Where(do.Users{Id: userId}).Update(do.Users{LastLoginAt: gtime.Now()}); err != nil {
|
||||
return nil, ecode.Fail.Sub("更新登录时间失败")
|
||||
}
|
||||
}
|
||||
|
||||
// 生成 token
|
||||
token, err := jwt.GenerateToken(&jwt.TokenIn{
|
||||
UserId: userId,
|
||||
Permission: consts.UserPermission,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("生成token失败")
|
||||
}
|
||||
|
||||
out = &model.UserLoginOut{
|
||||
Token: token,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sUser) Info(ctx context.Context, in *model.UserInfoIn) (out *model.UserInfoOut, err error) {
|
||||
exist, err := dao.Users.Ctx(ctx).Where(do.Users{WxOpenId: in.OpenId, Id: in.Id}).OmitEmptyWhere().Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("查找用户失败")
|
||||
}
|
||||
if !exist {
|
||||
return nil, ecode.Params.Sub("用户不存在")
|
||||
}
|
||||
var user entity.Users
|
||||
if err := dao.Users.Ctx(ctx).Where(do.Users{WxOpenId: in.OpenId, Id: in.Id}).OmitEmptyWhere().Scan(&user); err != nil {
|
||||
return nil, ecode.Fail.Sub("查找用户失败")
|
||||
}
|
||||
out = &model.UserInfoOut{
|
||||
Id: user.Id,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sUser) Update(ctx context.Context, in *model.UserUpdateIn) (out *model.UpdateOut, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sUser) BindPhone(ctx context.Context, in *model.UserBindPhoneIn) (out *model.UpdateOut, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ import (
|
||||
// - 若 Token 格式非法或解析失败:终止请求并返回错误。
|
||||
// - 若 Token 合法:将用户信息写入上下文,继续执行下一个中间件或处理函数。
|
||||
func Auth(r *ghttp.Request) {
|
||||
token := r.Header.Get("Authorization")
|
||||
token := r.GetHeader("Authorization")
|
||||
ctx := r.GetCtx()
|
||||
if token == "" {
|
||||
glog.Infof(ctx, "未登录用户访问: %s %s", r.URL.Path, r.Method)
|
||||
|
||||
@ -1,28 +1,27 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"server/utility/ecode"
|
||||
"server/utility/myCasbin"
|
||||
)
|
||||
|
||||
// Casbin 是用于访问权限控制的中间件。
|
||||
//
|
||||
//import (
|
||||
// "github.com/gogf/gf/v2/net/ghttp"
|
||||
// "server/utility/ecode"
|
||||
// "server/utility/myCasbin"
|
||||
//)
|
||||
// 该中间件基于 Casbin 权限控制框架,校验当前用户是否有权访问指定的 URL 和请求方法。
|
||||
// 用户权限从请求上下文中的 "permission" 字段获取,该字段通常由前置中间件(如 Auth)注入。
|
||||
//
|
||||
//// Casbin 是用于访问权限控制的中间件。
|
||||
////
|
||||
//// 该中间件基于 Casbin 权限控制框架,校验当前用户是否有权访问指定的 URL 和请求方法。
|
||||
//// 用户权限从请求上下文中的 "permission" 字段获取,该字段通常由前置中间件(如 Auth)注入。
|
||||
////
|
||||
//// 参数:
|
||||
////
|
||||
//// r *ghttp.Request - 当前的 HTTP 请求对象,由框架自动传入。
|
||||
////
|
||||
//// 行为:
|
||||
//// - 如果权限验证未通过:终止请求,返回权限不足的错误(ecode.Denied)。
|
||||
//// - 如果权限验证通过:继续执行后续中间件或处理逻辑。
|
||||
//func Casbin(r *ghttp.Request) {
|
||||
// permission := r.GetCtxVar("permission").String()
|
||||
// if !myCasbin.GetMyCasbin().HasPermission(permission, r.URL.Path, r.Method) {
|
||||
// Exit(r, ecode.Denied)
|
||||
// }
|
||||
// r.Middleware.Next()
|
||||
//}
|
||||
// 参数:
|
||||
//
|
||||
// r *ghttp.Request - 当前的 HTTP 请求对象,由框架自动传入。
|
||||
//
|
||||
// 行为:
|
||||
// - 如果权限验证未通过:终止请求,返回权限不足的错误(ecode.Denied)。
|
||||
// - 如果权限验证通过:继续执行后续中间件或处理逻辑。
|
||||
func Casbin(r *ghttp.Request) {
|
||||
permission := r.GetCtxVar("permission").String()
|
||||
if !myCasbin.GetMyCasbin().HasPermission(permission, r.URL.Path, r.Method) {
|
||||
Exit(r, ecode.Denied)
|
||||
}
|
||||
r.Middleware.Next()
|
||||
}
|
||||
|
||||
@ -10,6 +10,6 @@ type (
|
||||
Id int
|
||||
}
|
||||
AdminInfoOut struct {
|
||||
Token string
|
||||
Username string
|
||||
}
|
||||
)
|
||||
|
||||
@ -3,3 +3,14 @@ package model
|
||||
type LoginOut struct {
|
||||
Token string
|
||||
}
|
||||
|
||||
type UpdateOut struct {
|
||||
Success bool
|
||||
}
|
||||
type DeleteOut struct {
|
||||
Success bool
|
||||
}
|
||||
|
||||
type CreateOut struct {
|
||||
Id int64
|
||||
}
|
||||
|
||||
@ -18,10 +18,7 @@ type Admins struct {
|
||||
RealName interface{} // 真实姓名
|
||||
Phone interface{} // 手机号
|
||||
Email interface{} // 邮箱
|
||||
Role interface{} // 角色:1=超级管理员,2=运营管理员,3=客服管理员,4=财务管理员
|
||||
Status interface{} // 状态:1=正常,2=禁用
|
||||
LastLoginAt *gtime.Time // 最后登录时间
|
||||
LastLoginIp interface{} // 最后登录IP
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
DeletedAt *gtime.Time // 软删除时间戳
|
||||
|
||||
23
internal/model/do/reward_types.go
Normal file
23
internal/model/do/reward_types.go
Normal file
@ -0,0 +1,23 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// RewardTypes is the golang structure of table reward_types for DAO operations like Where/Data.
|
||||
type RewardTypes struct {
|
||||
g.Meta `orm:"table:reward_types, do:true"`
|
||||
Id interface{} // 类型ID
|
||||
Name interface{} // 类型名称
|
||||
Code interface{} // 类型编码
|
||||
Description interface{} // 类型描述
|
||||
Status interface{} // 状态:1=启用,2=禁用
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
DeletedAt *gtime.Time // 软删除时间
|
||||
}
|
||||
@ -11,15 +11,15 @@ import (
|
||||
|
||||
// StoreRewards is the golang structure of table store_rewards for DAO operations like Where/Data.
|
||||
type StoreRewards struct {
|
||||
g.Meta `orm:"table:store_rewards, do:true"`
|
||||
Id interface{} // 门店奖励ID
|
||||
StoreId interface{} // 所属门店ID
|
||||
RewardType interface{} // 奖励类型:1=积分,2=优惠券,3=商品,4=抽奖券
|
||||
RewardName interface{} // 奖励名称
|
||||
Amount interface{} // 奖励数量
|
||||
Total interface{} // 该奖励总库存(NULL 表示无限)
|
||||
MerchantId interface{} // 所属商户ID
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
DeletedAt *gtime.Time // 软删除时间戳
|
||||
g.Meta `orm:"table:store_rewards, do:true"`
|
||||
Id interface{} // 门店奖励ID
|
||||
StoreId interface{} // 所属门店ID
|
||||
RewardTypeId interface{} // 奖励类型ID
|
||||
RewardName interface{} // 奖励名称
|
||||
Amount interface{} // 奖励数量
|
||||
Total interface{} // 该奖励总库存(NULL 表示无限)
|
||||
MerchantId interface{} // 所属商户ID
|
||||
CreatedAt *gtime.Time // 创建时间
|
||||
UpdatedAt *gtime.Time // 更新时间
|
||||
DeletedAt *gtime.Time // 软删除时间戳
|
||||
}
|
||||
|
||||
@ -15,10 +15,8 @@ type UserLoginRecords struct {
|
||||
Id interface{} // 记录ID
|
||||
UserId interface{} // 用户ID
|
||||
StoreId interface{} // 登录门店ID
|
||||
MerchantId interface{} // 所属商户ID
|
||||
LoginIp interface{} // 登录IP地址
|
||||
LoginDevice interface{} // 登录设备信息
|
||||
LoginPlatform interface{} // 登录平台:1=Web,2=iOS,3=Android,4=微信小程序,5=支付宝小程序,6=其他
|
||||
LoginPlatform interface{} // 登录平台:1=PC
|
||||
LoginType interface{} // 登录方式:1=微信,2=手机号,3=账号密码,4=其他
|
||||
LoginStatus interface{} // 登录状态:1=成功,2=失败
|
||||
FailReason interface{} // 失败原因
|
||||
|
||||
@ -10,17 +10,14 @@ import (
|
||||
|
||||
// Admins is the golang structure for table admins.
|
||||
type Admins struct {
|
||||
Id int64 `json:"id" orm:"id" description:"管理员ID"` // 管理员ID
|
||||
Username string `json:"username" orm:"username" description:"管理员用户名"` // 管理员用户名
|
||||
PasswordHash string `json:"passwordHash" orm:"password_hash" description:"密码哈希"` // 密码哈希
|
||||
RealName string `json:"realName" orm:"real_name" description:"真实姓名"` // 真实姓名
|
||||
Phone string `json:"phone" orm:"phone" description:"手机号"` // 手机号
|
||||
Email string `json:"email" orm:"email" description:"邮箱"` // 邮箱
|
||||
Role int `json:"role" orm:"role" description:"角色:1=超级管理员,2=运营管理员,3=客服管理员,4=财务管理员"` // 角色:1=超级管理员,2=运营管理员,3=客服管理员,4=财务管理员
|
||||
Status int `json:"status" orm:"status" description:"状态:1=正常,2=禁用"` // 状态:1=正常,2=禁用
|
||||
LastLoginAt *gtime.Time `json:"lastLoginAt" orm:"last_login_at" description:"最后登录时间"` // 最后登录时间
|
||||
LastLoginIp string `json:"lastLoginIp" orm:"last_login_ip" description:"最后登录IP"` // 最后登录IP
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间戳"` // 软删除时间戳
|
||||
Id int64 `json:"id" orm:"id" description:"管理员ID"` // 管理员ID
|
||||
Username string `json:"username" orm:"username" description:"管理员用户名"` // 管理员用户名
|
||||
PasswordHash string `json:"passwordHash" orm:"password_hash" description:"密码哈希"` // 密码哈希
|
||||
RealName string `json:"realName" orm:"real_name" description:"真实姓名"` // 真实姓名
|
||||
Phone string `json:"phone" orm:"phone" description:"手机号"` // 手机号
|
||||
Email string `json:"email" orm:"email" description:"邮箱"` // 邮箱
|
||||
Status int `json:"status" orm:"status" description:"状态:1=正常,2=禁用"` // 状态:1=正常,2=禁用
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间戳"` // 软删除时间戳
|
||||
}
|
||||
|
||||
21
internal/model/entity/reward_types.go
Normal file
21
internal/model/entity/reward_types.go
Normal file
@ -0,0 +1,21 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// RewardTypes is the golang structure for table reward_types.
|
||||
type RewardTypes struct {
|
||||
Id int64 `json:"id" orm:"id" description:"类型ID"` // 类型ID
|
||||
Name string `json:"name" orm:"name" description:"类型名称"` // 类型名称
|
||||
Code string `json:"code" orm:"code" description:"类型编码"` // 类型编码
|
||||
Description string `json:"description" orm:"description" description:"类型描述"` // 类型描述
|
||||
Status int `json:"status" orm:"status" description:"状态:1=启用,2=禁用"` // 状态:1=启用,2=禁用
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间"` // 软删除时间
|
||||
}
|
||||
@ -10,14 +10,14 @@ import (
|
||||
|
||||
// StoreRewards is the golang structure for table store_rewards.
|
||||
type StoreRewards struct {
|
||||
Id int64 `json:"id" orm:"id" description:"门店奖励ID"` // 门店奖励ID
|
||||
StoreId int64 `json:"storeId" orm:"store_id" description:"所属门店ID"` // 所属门店ID
|
||||
RewardType int `json:"rewardType" orm:"reward_type" description:"奖励类型:1=积分,2=优惠券,3=商品,4=抽奖券"` // 奖励类型:1=积分,2=优惠券,3=商品,4=抽奖券
|
||||
RewardName string `json:"rewardName" orm:"reward_name" description:"奖励名称"` // 奖励名称
|
||||
Amount int `json:"amount" orm:"amount" description:"奖励数量"` // 奖励数量
|
||||
Total int `json:"total" orm:"total" description:"该奖励总库存(NULL 表示无限)"` // 该奖励总库存(NULL 表示无限)
|
||||
MerchantId int64 `json:"merchantId" orm:"merchant_id" description:"所属商户ID"` // 所属商户ID
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间戳"` // 软删除时间戳
|
||||
Id int64 `json:"id" orm:"id" description:"门店奖励ID"` // 门店奖励ID
|
||||
StoreId int64 `json:"storeId" orm:"store_id" description:"所属门店ID"` // 所属门店ID
|
||||
RewardTypeId int64 `json:"rewardTypeId" orm:"reward_type_id" description:"奖励类型ID"` // 奖励类型ID
|
||||
RewardName string `json:"rewardName" orm:"reward_name" description:"奖励名称"` // 奖励名称
|
||||
Amount int `json:"amount" orm:"amount" description:"奖励数量"` // 奖励数量
|
||||
Total int `json:"total" orm:"total" description:"该奖励总库存(NULL 表示无限)"` // 该奖励总库存(NULL 表示无限)
|
||||
MerchantId int64 `json:"merchantId" orm:"merchant_id" description:"所属商户ID"` // 所属商户ID
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间戳"` // 软删除时间戳
|
||||
}
|
||||
|
||||
@ -10,17 +10,15 @@ import (
|
||||
|
||||
// UserLoginRecords is the golang structure for table user_login_records.
|
||||
type UserLoginRecords struct {
|
||||
Id int64 `json:"id" orm:"id" description:"记录ID"` // 记录ID
|
||||
UserId int64 `json:"userId" orm:"user_id" description:"用户ID"` // 用户ID
|
||||
StoreId int64 `json:"storeId" orm:"store_id" description:"登录门店ID"` // 登录门店ID
|
||||
MerchantId int64 `json:"merchantId" orm:"merchant_id" description:"所属商户ID"` // 所属商户ID
|
||||
LoginIp string `json:"loginIp" orm:"login_ip" description:"登录IP地址"` // 登录IP地址
|
||||
LoginDevice string `json:"loginDevice" orm:"login_device" description:"登录设备信息"` // 登录设备信息
|
||||
LoginPlatform int `json:"loginPlatform" orm:"login_platform" description:"登录平台:1=Web,2=iOS,3=Android,4=微信小程序,5=支付宝小程序,6=其他"` // 登录平台:1=Web,2=iOS,3=Android,4=微信小程序,5=支付宝小程序,6=其他
|
||||
LoginType int `json:"loginType" orm:"login_type" description:"登录方式:1=微信,2=手机号,3=账号密码,4=其他"` // 登录方式:1=微信,2=手机号,3=账号密码,4=其他
|
||||
LoginStatus int `json:"loginStatus" orm:"login_status" description:"登录状态:1=成功,2=失败"` // 登录状态:1=成功,2=失败
|
||||
FailReason string `json:"failReason" orm:"fail_reason" description:"失败原因"` // 失败原因
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"登录时间"` // 登录时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间戳"` // 软删除时间戳
|
||||
Id int64 `json:"id" orm:"id" description:"记录ID"` // 记录ID
|
||||
UserId int64 `json:"userId" orm:"user_id" description:"用户ID"` // 用户ID
|
||||
StoreId int64 `json:"storeId" orm:"store_id" description:"登录门店ID"` // 登录门店ID
|
||||
LoginIp string `json:"loginIp" orm:"login_ip" description:"登录IP地址"` // 登录IP地址
|
||||
LoginPlatform int `json:"loginPlatform" orm:"login_platform" description:"登录平台:1=PC"` // 登录平台:1=PC
|
||||
LoginType int `json:"loginType" orm:"login_type" description:"登录方式:1=微信,2=手机号,3=账号密码,4=其他"` // 登录方式:1=微信,2=手机号,3=账号密码,4=其他
|
||||
LoginStatus int `json:"loginStatus" orm:"login_status" description:"登录状态:1=成功,2=失败"` // 登录状态:1=成功,2=失败
|
||||
FailReason string `json:"failReason" orm:"fail_reason" description:"失败原因"` // 失败原因
|
||||
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"登录时间"` // 登录时间
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间戳"` // 软删除时间戳
|
||||
}
|
||||
|
||||
29
internal/model/user.go
Normal file
29
internal/model/user.go
Normal file
@ -0,0 +1,29 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type LoginCache struct {
|
||||
Token string `json:"token"`
|
||||
Status int `json:"status" dc:"0-准备扫码,1-已扫码"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
type UserLoginIn struct {
|
||||
OpenId string
|
||||
}
|
||||
type UserLoginOut struct {
|
||||
Token string
|
||||
}
|
||||
|
||||
type UserInfoIn struct {
|
||||
Id int
|
||||
OpenId string
|
||||
}
|
||||
type UserInfoOut struct {
|
||||
Id int64
|
||||
}
|
||||
|
||||
type UserUpdateIn struct {
|
||||
}
|
||||
type UserBindPhoneIn struct {
|
||||
}
|
||||
@ -1,7 +1,8 @@
|
||||
package packed
|
||||
|
||||
import (
|
||||
//_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
|
||||
//_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
||||
_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
|
||||
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
||||
_ "server/utility/myCasbin"
|
||||
_ "server/utility/wechat"
|
||||
)
|
||||
|
||||
@ -5,4 +5,31 @@
|
||||
|
||||
package service
|
||||
|
||||
type ()
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
)
|
||||
|
||||
type (
|
||||
IUser interface {
|
||||
Login(ctx context.Context, in *model.UserLoginIn) (out *model.UserLoginOut, err error)
|
||||
Info(ctx context.Context, in *model.UserInfoIn) (out *model.UserInfoOut, err error)
|
||||
Update(ctx context.Context, in *model.UserUpdateIn) (out *model.UpdateOut, err error)
|
||||
BindPhone(ctx context.Context, in *model.UserBindPhoneIn) (out *model.UpdateOut, err error)
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
localUser IUser
|
||||
)
|
||||
|
||||
func User() IUser {
|
||||
if localUser == nil {
|
||||
panic("implement not found for interface IUser, forgot register?")
|
||||
}
|
||||
return localUser
|
||||
}
|
||||
|
||||
func RegisterUser(i IUser) {
|
||||
localUser = i
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user