From 1374757eabe4b4f45db7b5daad152ae21b36cbfb Mon Sep 17 00:00:00 2001 From: luorijun Date: Wed, 23 Apr 2025 19:01:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E7=99=BB=E5=BD=95=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E7=99=BB=E5=BD=95=E6=8E=A5=E5=8F=A3=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E5=88=B0=20/token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 + docs/{todo.txt => 测试点.txt} | 0 scripts/sql/init.sql | 50 +++---- web/auth/auth.go | 131 ++++++++----------- web/handlers/bill.go | 2 +- web/handlers/oauth.go | 239 ++++++++++++++++++++++++++-------- web/handlers/verifier.go | 8 ++ web/models/bill.gen.go | 12 +- web/models/channel.gen.go | 2 +- web/models/client.gen.go | 29 +++-- web/models/coupon.gen.go | 22 ++-- web/models/node.gen.go | 4 +- web/models/refund.gen.go | 6 +- web/models/resource.gen.go | 4 +- web/models/trade.gen.go | 8 +- web/models/whitelist.gen.go | 2 +- web/queries/bill.gen.go | 24 ++-- web/queries/channel.gen.go | 2 +- web/queries/client.gen.go | 36 ++--- web/queries/coupon.gen.go | 22 ++-- web/queries/node.gen.go | 4 +- web/queries/refund.gen.go | 6 +- web/queries/resource.gen.go | 16 +-- web/queries/trade.gen.go | 8 +- web/queries/whitelist.gen.go | 2 +- web/router.go | 2 +- web/services/auth.go | 17 ++- web/services/session.go | 6 + 28 files changed, 404 insertions(+), 266 deletions(-) rename docs/{todo.txt => 测试点.txt} (100%) diff --git a/README.md b/README.md index 21754bf..e2d313c 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,12 @@ - [ ] Limiter - [ ] Compress +使用 fiber 自带 validator 进行参数验证 + +增加 domain 层,缓解同包字段过长的问题 + +移动端适配 + 授权过期跳转登录,成功后返回原链接 错误处理类型转换失败问题 diff --git a/docs/todo.txt b/docs/测试点.txt similarity index 100% rename from docs/todo.txt rename to docs/测试点.txt diff --git a/scripts/sql/init.sql b/scripts/sql/init.sql index eb10c5f..0e49b4d 100644 --- a/scripts/sql/init.sql +++ b/scripts/sql/init.sql @@ -179,20 +179,21 @@ comment on column user_role.deleted_at is '删除时间'; drop table if exists client cascade; create table client ( - id serial primary key, - client_id varchar(255) not null unique, - client_secret varchar(255) not null, - redirect_uri varchar(255), - grant_code bool not null default false, - grant_client bool not null default false, - grant_refresh bool not null default false, - spec int not null, - name varchar(255) not null, - icon varchar(255), - status int not null default 1, - created_at timestamp default current_timestamp, - updated_at timestamp default current_timestamp, - deleted_at timestamp + id serial primary key, + client_id varchar(255) not null unique, + client_secret varchar(255) not null, + redirect_uri varchar(255), + grant_code bool not null default false, + grant_client bool not null default false, + grant_refresh bool not null default false, + grant_password bool not null default false, + spec int not null, + name varchar(255) not null, + icon varchar(255), + status int not null default 1, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp ); create index client_client_id_index on client (client_id); @@ -209,6 +210,7 @@ comment on column client.redirect_uri is 'OAuth2 重定向URI'; comment on column client.grant_code is '允许授权码授予'; comment on column client.grant_client is '允许客户端凭证授予'; comment on column client.grant_refresh is '允许刷新令牌授予'; +comment on column client.grant_password is '允许密码授予'; comment on column client.spec is '安全规范:0-web,1-native,2-browser'; comment on column client.name is '名称'; comment on column client.icon is '图标URL'; @@ -822,19 +824,19 @@ comment on column bill.deleted_at is '删除时间'; -- coupon 优惠券 drop table if exists coupon cascade; create table coupon ( - id serial primary key, - user_id int references "user" (id) + id serial primary key, + user_id int references "user" (id) on update cascade on delete cascade, - code varchar(255) not null unique, - remark varchar(255), - amount decimal(12, 2) not null default 0, + code varchar(255) not null unique, + remark varchar(255), + amount decimal(12, 2) not null default 0, min_amount decimal(12, 2) not null default 0, - status int not null default 0, - expire_at timestamp, - created_at timestamp default current_timestamp, - updated_at timestamp default current_timestamp, - deleted_at timestamp + status int not null default 0, + expire_at timestamp, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp ); create index coupon_user_id_index on coupon (user_id); create index coupon_code_index on coupon (code); diff --git a/web/auth/auth.go b/web/auth/auth.go index ece5770..e45a96b 100644 --- a/web/auth/auth.go +++ b/web/auth/auth.go @@ -76,7 +76,6 @@ func Permit(types []services.PayloadType, permissions ...string) fiber.Handler { return c.Next() } - } func PermitAll(permissions ...string) fiber.Handler { @@ -88,14 +87,6 @@ func PermitAll(permissions ...string) fiber.Handler { }, permissions...) } -// PermitUser 创建针对单个路由的鉴权中间件 -func PermitUser(permissions ...string) fiber.Handler { - return Permit([]services.PayloadType{ - services.PayloadUser, - services.PayloadAdmin, - }, permissions...) -} - func PermitDevice(permissions ...string) fiber.Handler { return Permit([]services.PayloadType{ services.PayloadClientPublic, @@ -104,74 +95,6 @@ func PermitDevice(permissions ...string) fiber.Handler { }, permissions...) } -func PermitPublic(permissions ...string) fiber.Handler { - return Permit([]services.PayloadType{ - services.PayloadClientPublic, - services.PayloadAdmin, - }, permissions...) -} - -func PermitConfidential(permissions ...string) fiber.Handler { - return Permit([]services.PayloadType{ - services.PayloadClientConfidential, - services.PayloadAdmin, - }, permissions...) -} - -func authBearer(ctx context.Context, token string) (*services.AuthContext, error) { - auth, err := services.Session.Find(ctx, token) - if err != nil { - slog.Debug(err.Error()) - return nil, err - } - return auth, nil -} - -func authBasic(ctx context.Context, token string) (*services.AuthContext, error) { - - // 解析 Basic 认证信息 - var base, err = base64.URLEncoding.DecodeString(token) - if err != nil { - slog.Debug(err.Error()) - return nil, err - } - - var split = strings.Split(string(base), ":") - if len(split) != 2 { - msg := "无法解析 Basic 认证信息" - slog.Debug(msg) - return nil, errors.New(msg) - } - - var clientID = split[0] - - // 获取客户端信息 - client, err := q.Client. - Where( - q.Client.ClientID.Eq(clientID), - q.Client.Spec.Eq(0), - q.Client.GrantClient.Is(true), - q.Client.Status.Eq(1)). - Take() - if err != nil { - return nil, err - } - - // todo 查询客户端关联权限 - - // 组织授权信息(一次性请求) - return &services.AuthContext{ - Payload: services.Payload{ - Id: client.ID, - Type: services.PayloadClientConfidential, - Name: client.Name, - Avatar: client.Icon, - }, - Permissions: nil, - Metadata: nil, - }, nil -} - func Protect(c *fiber.Ctx, types []services.PayloadType, permissions []string) (*services.AuthContext, error) { // 获取令牌 var header = c.Get("Authorization") @@ -216,3 +139,57 @@ func Protect(c *fiber.Ctx, types []services.PayloadType, permissions []string) ( return auth, nil } + +func authBearer(ctx context.Context, token string) (*services.AuthContext, error) { + auth, err := services.Session.Find(ctx, token) + if err != nil { + slog.Debug(err.Error()) + return nil, err + } + return auth, nil +} + +func authBasic(_ context.Context, token string) (*services.AuthContext, error) { + + // 解析 Basic 认证信息 + var base, err = base64.URLEncoding.DecodeString(token) + if err != nil { + slog.Debug(err.Error()) + return nil, err + } + + var split = strings.Split(string(base), ":") + if len(split) != 2 { + msg := "无法解析 Basic 认证信息" + slog.Debug(msg) + return nil, errors.New(msg) + } + + var clientID = split[0] + + // 获取客户端信息 + client, err := q.Client. + Where( + q.Client.ClientID.Eq(clientID), + q.Client.Spec.Eq(0), + q.Client.GrantClient.Is(true), + q.Client.Status.Eq(1)). + Take() + if err != nil { + return nil, err + } + + // todo 查询客户端关联权限 + + // 组织授权信息(一次性请求) + return &services.AuthContext{ + Payload: services.Payload{ + Id: client.ID, + Type: services.PayloadClientConfidential, + Name: client.Name, + Avatar: client.Icon, + }, + Permissions: nil, + Metadata: nil, + }, nil +} diff --git a/web/handlers/bill.go b/web/handlers/bill.go index 7b392bf..fae4897 100644 --- a/web/handlers/bill.go +++ b/web/handlers/bill.go @@ -51,7 +51,7 @@ func ListBill(c *fiber.Ctx) error { do = do.Where(q.Bill.BillNo.Eq(*req.BillNo)) } - bills, err := do.Debug(). + bills, err := do. Preload(q.Bill.Resource, q.Bill.Trade, q.Bill.Refund). Preload(q.Bill.Resource.Pss). Order(q.Bill.CreatedAt.Desc()). diff --git a/web/handlers/oauth.go b/web/handlers/oauth.go index e29bc09..0549d76 100644 --- a/web/handlers/oauth.go +++ b/web/handlers/oauth.go @@ -3,9 +3,10 @@ package handlers import ( "encoding/base64" "errors" - "platform/web/models" + "log/slog" + m "platform/web/models" q "platform/web/queries" - "platform/web/services" + s "platform/web/services" "strings" "time" @@ -17,22 +18,42 @@ import ( // region Token type TokenReq struct { - ClientID string `json:"client_id" form:"client_id"` - ClientSecret string `json:"client_secret" form:"client_secret"` - GrantType TokenGrantType `json:"grant_type" form:"grant_type"` - Code string `json:"code" form:"code"` - RedirectURI string `json:"redirect_uri" form:"redirect_uri"` - CodeVerifier string `json:"code_verifier" form:"code_verifier"` - RefreshToken string `json:"refresh_token" form:"refresh_token"` - Scope string `json:"scope" form:"scope"` + GrantType s.OauthGrantType `json:"grant_type" form:"grant_type"` + ClientID string `json:"client_id" form:"client_id"` + ClientSecret string `json:"client_secret" form:"client_secret"` + Scope string `json:"scope" form:"scope"` + TokenReqCode + TokenReqClient + TokenReqRefresh + TokenReqPassword +} + +type TokenReqCode struct { + Code string `json:"code" form:"code"` + RedirectURI string `json:"redirect_uri" form:"redirect_uri"` + CodeVerifier string `json:"code_verifier" form:"code_verifier"` +} + +type TokenReqClient struct { +} + +type TokenReqRefresh struct { + RefreshToken string `json:"refresh_token" form:"refresh_token"` +} + +type TokenReqPassword struct { + LoginType s.OauthGrantLoginType `json:"login_type" form:"login_type"` + Username string `json:"username" form:"username"` + Password string `json:"password" form:"password"` + Remember bool `json:"remember" form:"remember"` } type TokenResp struct { AccessToken string `json:"access_token"` RefreshToken string `json:"refresh_token,omitempty"` + ExpiresIn int `json:"expires_in"` TokenType string `json:"token_type"` Scope string `json:"scope,omitempty"` - ExpiresIn int `json:"expires_in"` } type TokenErrResp struct { @@ -40,57 +61,57 @@ type TokenErrResp struct { Description string `json:"error_description,omitempty"` } -type TokenGrantType string - -const ( - AuthorizationCode = TokenGrantType("authorization_code") - ClientCredentials = TokenGrantType("client_credentials") - RefreshToken = TokenGrantType("refresh_token") -) - // Token 处理 OAuth2.0 授权请求 func Token(c *fiber.Ctx) error { // 验证请求参数 req := new(TokenReq) if err := c.BodyParser(req); err != nil { - return sendError(c, services.ErrOauthInvalidRequest, "无法解析请求参数") + return sendError(c, s.ErrOauthInvalidRequest, "无法解析请求参数") } if req.GrantType == "" { - return sendError(c, services.ErrOauthInvalidRequest, "缺少必要参数:grant_type") + return sendError(c, s.ErrOauthInvalidRequest, "缺少必要参数:grant_type") } + slog.Debug("oauth token", slog.String("grant_type", + string(req.GrantType)), + slog.String("client_id", req.ClientID), + ) + // 基于授权类型处理请求 switch req.GrantType { - case AuthorizationCode: + case s.OauthGrantTypeAuthorizationCode: return authorizationCode(c, req) - case ClientCredentials: + case s.OauthGrantTypeClientCredentials: return clientCredentials(c, req) - case RefreshToken: + case s.OauthGrantTypeRefreshToken: return refreshToken(c, req) + case s.OauthGrantTypePassword: + return password(c, req) + default: - return sendError(c, services.ErrOauthUnsupportedGrantType) + return sendError(c, s.ErrOauthUnsupportedGrantType) } } // 授权码 func authorizationCode(c *fiber.Ctx, req *TokenReq) error { if req.Code == "" { - return sendError(c, services.ErrOauthInvalidRequest, "缺少必要参数:code") + return sendError(c, s.ErrOauthInvalidRequest, "缺少必要参数:code") } - client, err := protect(c, services.GrantTypeAuthorizationCode, req.ClientID, req.ClientSecret) + client, err := protect(c, s.OauthGrantTypeAuthorizationCode, req.ClientID, req.ClientSecret) if err != nil { return sendError(c, err) } - token, err := services.Auth.OauthAuthorizationCode(c.Context(), client, req.Code, req.RedirectURI, req.CodeVerifier) + token, err := s.Auth.OauthAuthorizationCode(c.Context(), client, req.Code, req.RedirectURI, req.CodeVerifier) if err != nil { - return sendError(c, err.(services.AuthServiceOauthError)) + return sendError(c, err.(s.AuthServiceOauthError)) } return sendSuccess(c, token) @@ -98,15 +119,15 @@ func authorizationCode(c *fiber.Ctx, req *TokenReq) error { // 客户端凭证 func clientCredentials(c *fiber.Ctx, req *TokenReq) error { - client, err := protect(c, services.GrantTypeClientCredentials, req.ClientID, req.ClientSecret) + client, err := protect(c, s.OauthGrantTypeClientCredentials, req.ClientID, req.ClientSecret) if err != nil { return sendError(c, err) } scope := strings.Split(req.Scope, ",") - token, err := services.Auth.OauthClientCredentials(c.Context(), client, scope...) + token, err := s.Auth.OauthClientCredentials(c.Context(), client, scope...) if err != nil { - return sendError(c, err.(services.AuthServiceOauthError)) + return sendError(c, err.(s.AuthServiceOauthError)) } return sendSuccess(c, token) @@ -115,19 +136,19 @@ func clientCredentials(c *fiber.Ctx, req *TokenReq) error { // 刷新令牌 func refreshToken(c *fiber.Ctx, req *TokenReq) error { if req.RefreshToken == "" { - return sendError(c, services.ErrOauthInvalidRequest, "缺少必要参数:refresh_token") + return sendError(c, s.ErrOauthInvalidRequest, "缺少必要参数:refresh_token") } - client, err := protect(c, services.GrantTypeRefreshToken, req.ClientID, req.ClientSecret) + client, err := protect(c, s.OauthGrantTypeRefreshToken, req.ClientID, req.ClientSecret) if err != nil { return sendError(c, err) } scope := strings.Split(req.Scope, ",") - token, err := services.Auth.OauthRefreshToken(c.Context(), client, req.RefreshToken, scope) + token, err := s.Auth.OauthRefreshToken(c.Context(), client, req.RefreshToken, scope) if err != nil { - if errors.Is(err, services.ErrInvalidToken) { - return sendError(c, services.ErrOauthInvalidGrant) + if errors.Is(err, s.ErrInvalidToken) { + return sendError(c, s.ErrOauthInvalidGrant) } return sendError(c, err) } @@ -135,8 +156,108 @@ func refreshToken(c *fiber.Ctx, req *TokenReq) error { return sendSuccess(c, token) } +func password(c *fiber.Ctx, req *TokenReq) error { + if req.LoginType == "" { + return sendError(c, s.ErrOauthInvalidRequest, "缺少必要参数:password_type") + } + if req.Username == "" { + return sendError(c, s.ErrOauthInvalidRequest, "缺少必要参数:username") + } + if req.Password == "" { + return sendError(c, s.ErrOauthInvalidRequest, "缺少必要参数:password") + } + + // 验证客户端凭证 + _, err := protect(c, s.OauthGrantTypePassword, req.ClientID, req.ClientSecret) + if err != nil { + return sendError(c, err) + } + + // 验证验证码 + err = s.Verifier.VerifySms(c.Context(), req.Username, req.Password) + if err != nil { + if errors.Is(err, s.ErrVerifierServiceInvalid) { + return fiber.NewError(fiber.StatusBadRequest, "验证码错误") + } + return err + } + + // 查找用户 + var user *m.User + err = q.Q.Transaction(func(tx *q.Query) error { + + switch req.LoginType { + case s.OauthGrantPasswordTypePhoneCode: + user, err = tx.User.Where(tx.User.Phone.Eq(req.Username)).Take() + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + return err + } + case s.OauthGrantPasswordTypeEmailCode: + user, err = tx.User.Where(tx.User.Email.Eq(req.Username)).Take() + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + return err + } + case s.OauthGrantPasswordTypePassword: + user, err = tx.User. + Where(tx.User.Or( + tx.User.Phone.Eq(req.Username), + tx.User.Email.Eq(req.Username), + tx.User.Username.Eq(req.Username), + )). + Take() + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + return err + } + default: + return sendError(c, s.ErrOauthInvalidRequest, "无效的登录类型") + } + + // 如果用户不存在,初始化用户 todo 初始化默认权限信息 + if user == nil { + user = &m.User{ + Phone: req.Username, + Username: req.Username, + } + } + + // 更新用户的登录时间 + user.LastLogin = time.Now() + user.LastLoginHost = c.IP() + user.LastLoginAgent = c.Get("User-Agent") + if err := tx.User.Omit(q.User.AdminID).Save(user); err != nil { + return err + } + + return nil + }) + if err != nil { + return err + } + + // 保存到会话 + auth := s.AuthContext{ + Payload: s.Payload{ + Id: user.ID, + Type: s.PayloadUser, + Name: user.Name, + Avatar: user.Avatar, + }, + } + + duration := s.DefaultSessionConfig + if !req.Remember { + duration.RefreshTokenDuration = 0 + } + token, err := s.Session.Create(c.Context(), auth) + if err != nil { + return err + } + + return sendSuccess(c, token) +} + // 检查客户端凭证 -func protect(c *fiber.Ctx, grant services.GrantType, clientId, clientSecret string) (*models.Client, error) { +func protect(c *fiber.Ctx, grant s.OauthGrantType, clientId, clientSecret string) (*m.Client, error) { header := c.Get("Authorization") if header != "" { basic := strings.TrimPrefix(header, "Basic ") @@ -155,44 +276,48 @@ func protect(c *fiber.Ctx, grant services.GrantType, clientId, clientSecret stri // 查找客户端 if clientId == "" { - return nil, services.ErrOauthInvalidRequest + return nil, s.ErrOauthInvalidRequest } client, err := q.Client.Where(q.Client.ClientID.Eq(clientId)).Take() if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, services.ErrOauthInvalidClient + return nil, s.ErrOauthInvalidClient } return nil, err } // 验证客户端状态 if client.Status != 1 { - return nil, services.ErrOauthUnauthorizedClient + return nil, s.ErrOauthUnauthorizedClient } // 验证授权类型 switch grant { - case services.GrantTypeAuthorizationCode: + case s.OauthGrantTypeAuthorizationCode: if !client.GrantCode { - return nil, services.ErrOauthUnauthorizedClient + return nil, s.ErrOauthUnauthorizedClient } - case services.GrantTypeClientCredentials: + case s.OauthGrantTypeClientCredentials: if !client.GrantClient || client.Spec != 0 { - return nil, services.ErrOauthUnauthorizedClient + return nil, s.ErrOauthUnauthorizedClient } - case services.GrantTypeRefreshToken: + case s.OauthGrantTypeRefreshToken: if !client.GrantRefresh { - return nil, services.ErrOauthUnauthorizedClient + return nil, s.ErrOauthUnauthorizedClient + } + case s.OauthGrantTypePassword: + if !client.GrantPassword { + return nil, s.ErrOauthUnauthorizedClient } } // 如果客户端是 confidential,验证 client_secret,失败返回错误 if client.Spec == 0 { if clientSecret == "" { - return nil, services.ErrOauthInvalidRequest + return nil, s.ErrOauthInvalidRequest } if bcrypt.CompareHashAndPassword([]byte(client.ClientSecret), []byte(clientSecret)) != nil { - return nil, services.ErrOauthInvalidClient + return nil, s.ErrOauthInvalidClient } } @@ -200,7 +325,7 @@ func protect(c *fiber.Ctx, grant services.GrantType, clientId, clientSecret stri } // 发送成功响应 -func sendSuccess(c *fiber.Ctx, details *services.TokenDetails) error { +func sendSuccess(c *fiber.Ctx, details *s.TokenDetails) error { return c.JSON(TokenResp{ AccessToken: details.AccessToken, TokenType: "Bearer", @@ -211,23 +336,23 @@ func sendSuccess(c *fiber.Ctx, details *services.TokenDetails) error { // 发送错误响应 func sendError(c *fiber.Ctx, err error, description ...string) error { - var sErr services.AuthServiceOauthError + var sErr s.AuthServiceOauthError if errors.As(err, &sErr) { status := fiber.StatusBadRequest var desc string switch { - case errors.Is(sErr, services.ErrOauthInvalidRequest): + case errors.Is(sErr, s.ErrOauthInvalidRequest): desc = "无效的请求" - case errors.Is(sErr, services.ErrOauthInvalidClient): + case errors.Is(sErr, s.ErrOauthInvalidClient): status = fiber.StatusUnauthorized desc = "无效的客户端凭证" - case errors.Is(sErr, services.ErrOauthInvalidGrant): + case errors.Is(sErr, s.ErrOauthInvalidGrant): desc = "无效的授权凭证" - case errors.Is(sErr, services.ErrOauthInvalidScope): + case errors.Is(sErr, s.ErrOauthInvalidScope): desc = "无效的授权范围" - case errors.Is(sErr, services.ErrOauthUnauthorizedClient): + case errors.Is(sErr, s.ErrOauthUnauthorizedClient): desc = "未授权的客户端" - case errors.Is(sErr, services.ErrOauthUnsupportedGrantType): + case errors.Is(sErr, s.ErrOauthUnsupportedGrantType): desc = "不支持的授权类型" } if len(description) > 0 { diff --git a/web/handlers/verifier.go b/web/handlers/verifier.go index c64beb1..d366784 100644 --- a/web/handlers/verifier.go +++ b/web/handlers/verifier.go @@ -2,6 +2,7 @@ package handlers import ( "errors" + "platform/web/auth" "platform/web/services" "regexp" "strconv" @@ -16,6 +17,13 @@ type VerifierReq struct { func SmsCode(c *fiber.Ctx) error { + _, err := auth.Protect(c, []services.PayloadType{ + services.PayloadClientConfidential, + }, []string{}) + if err != nil { + return err + } + // 解析请求参数 req := new(VerifierReq) if err := c.BodyParser(req); err != nil { diff --git a/web/models/bill.gen.go b/web/models/bill.gen.go index 3e070f0..c788a7f 100644 --- a/web/models/bill.gen.go +++ b/web/models/bill.gen.go @@ -20,12 +20,12 @@ type Bill struct { CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间 - TradeID int32 `gorm:"column:trade_id" json:"trade_id"` - ResourceID int32 `gorm:"column:resource_id" json:"resource_id"` - Type int32 `gorm:"column:type;not null" json:"type"` - BillNo string `gorm:"column:bill_no;not null" json:"bill_no"` - RefundID int32 `gorm:"column:refund_id" json:"refund_id"` - Amount float64 `gorm:"column:amount;not null" json:"amount"` + TradeID int32 `gorm:"column:trade_id;comment:订单ID" json:"trade_id"` // 订单ID + ResourceID int32 `gorm:"column:resource_id;comment:套餐ID" json:"resource_id"` // 套餐ID + Type int32 `gorm:"column:type;not null;comment:账单类型:0-充值,1-消费,2-退款" json:"type"` // 账单类型:0-充值,1-消费,2-退款 + BillNo string `gorm:"column:bill_no;not null;comment:易读账单号" json:"bill_no"` // 易读账单号 + RefundID int32 `gorm:"column:refund_id;comment:退款ID" json:"refund_id"` // 退款ID + Amount float64 `gorm:"column:amount;not null;comment:账单金额" json:"amount"` // 账单金额 Trade *Trade `gorm:"foreignKey:TradeID" json:"trade"` Refund *Refund `gorm:"foreignKey:RefundID" json:"refund"` Resource *Resource `gorm:"foreignKey:ResourceID" json:"resource"` diff --git a/web/models/channel.gen.go b/web/models/channel.gen.go index 75a02f4..bd41695 100644 --- a/web/models/channel.gen.go +++ b/web/models/channel.gen.go @@ -31,7 +31,7 @@ type Channel struct { UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间 ProxyHost string `gorm:"column:proxy_host;not null" json:"proxy_host"` - Protocol int32 `gorm:"column:protocol" json:"protocol"` + Protocol int32 `gorm:"column:protocol;comment:协议类型:1-http,2-https,3-socks5" json:"protocol"` // 协议类型:1-http,2-https,3-socks5 } // TableName Channel's table name diff --git a/web/models/client.gen.go b/web/models/client.gen.go index 52c7bb7..a8790c9 100644 --- a/web/models/client.gen.go +++ b/web/models/client.gen.go @@ -14,20 +14,21 @@ const TableNameClient = "client" // Client mapped from table type Client struct { - ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:客户端ID" json:"id"` // 客户端ID - ClientID string `gorm:"column:client_id;not null;comment:OAuth2客户端标识符" json:"client_id"` // OAuth2客户端标识符 - ClientSecret string `gorm:"column:client_secret;not null;comment:OAuth2客户端密钥" json:"client_secret"` // OAuth2客户端密钥 - RedirectURI string `gorm:"column:redirect_uri;comment:OAuth2 重定向URI" json:"redirect_uri"` // OAuth2 重定向URI - GrantCode bool `gorm:"column:grant_code;not null;comment:允许授权码授予" json:"grant_code"` // 允许授权码授予 - GrantClient bool `gorm:"column:grant_client;not null;comment:允许客户端凭证授予" json:"grant_client"` // 允许客户端凭证授予 - GrantRefresh bool `gorm:"column:grant_refresh;not null;comment:允许刷新令牌授予" json:"grant_refresh"` // 允许刷新令牌授予 - Spec int32 `gorm:"column:spec;not null;comment:安全规范:0-web,1-native,2-browser" json:"spec"` // 安全规范:0-web,1-native,2-browser - Name string `gorm:"column:name;not null;comment:名称" json:"name"` // 名称 - Icon string `gorm:"column:icon;comment:图标URL" json:"icon"` // 图标URL - Status int32 `gorm:"column:status;not null;default:1;comment:状态:1-正常,0-禁用" json:"status"` // 状态:1-正常,0-禁用 - CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 - UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 - DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间 + ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:客户端ID" json:"id"` // 客户端ID + ClientID string `gorm:"column:client_id;not null;comment:OAuth2客户端标识符" json:"client_id"` // OAuth2客户端标识符 + ClientSecret string `gorm:"column:client_secret;not null;comment:OAuth2客户端密钥" json:"client_secret"` // OAuth2客户端密钥 + RedirectURI string `gorm:"column:redirect_uri;comment:OAuth2 重定向URI" json:"redirect_uri"` // OAuth2 重定向URI + GrantCode bool `gorm:"column:grant_code;not null;comment:允许授权码授予" json:"grant_code"` // 允许授权码授予 + GrantClient bool `gorm:"column:grant_client;not null;comment:允许客户端凭证授予" json:"grant_client"` // 允许客户端凭证授予 + GrantRefresh bool `gorm:"column:grant_refresh;not null;comment:允许刷新令牌授予" json:"grant_refresh"` // 允许刷新令牌授予 + Spec int32 `gorm:"column:spec;not null;comment:安全规范:0-web,1-native,2-browser" json:"spec"` // 安全规范:0-web,1-native,2-browser + Name string `gorm:"column:name;not null;comment:名称" json:"name"` // 名称 + Icon string `gorm:"column:icon;comment:图标URL" json:"icon"` // 图标URL + Status int32 `gorm:"column:status;not null;default:1;comment:状态:1-正常,0-禁用" json:"status"` // 状态:1-正常,0-禁用 + CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 + UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 + DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间 + GrantPassword bool `gorm:"column:grant_password;not null" json:"grant_password"` } // TableName Client's table name diff --git a/web/models/coupon.gen.go b/web/models/coupon.gen.go index cc06fd6..415370f 100644 --- a/web/models/coupon.gen.go +++ b/web/models/coupon.gen.go @@ -15,17 +15,17 @@ const TableNameCoupon = "coupon" // Coupon mapped from table type Coupon struct { - ExpireAt time.Time `gorm:"column:expire_at" json:"expire_at"` - CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP" json:"created_at"` - UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP" json:"updated_at"` - DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` - ID int32 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` - UserID int32 `gorm:"column:user_id" json:"user_id"` - Status int32 `gorm:"column:status;not null" json:"status"` - Code string `gorm:"column:code;not null" json:"code"` - Remark string `gorm:"column:remark" json:"remark"` - Amount float64 `gorm:"column:amount;not null" json:"amount"` - MinAmount float64 `gorm:"column:min_amount;not null" json:"min_amount"` + ExpireAt time.Time `gorm:"column:expire_at;comment:过期时间" json:"expire_at"` // 过期时间 + CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 + UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 + DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间 + ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:优惠券ID" json:"id"` // 优惠券ID + UserID int32 `gorm:"column:user_id;comment:用户ID" json:"user_id"` // 用户ID + Status int32 `gorm:"column:status;not null;comment:优惠券状态:0-未使用,1-已使用,2-已过期" json:"status"` // 优惠券状态:0-未使用,1-已使用,2-已过期 + Code string `gorm:"column:code;not null;comment:优惠券代码" json:"code"` // 优惠券代码 + Remark string `gorm:"column:remark;comment:优惠券备注" json:"remark"` // 优惠券备注 + Amount float64 `gorm:"column:amount;not null;comment:优惠券金额" json:"amount"` // 优惠券金额 + MinAmount float64 `gorm:"column:min_amount;not null;comment:最低消费金额" json:"min_amount"` // 最低消费金额 } // TableName Coupon's table name diff --git a/web/models/node.gen.go b/web/models/node.gen.go index 07ede4f..1b7fe76 100644 --- a/web/models/node.gen.go +++ b/web/models/node.gen.go @@ -22,13 +22,13 @@ type Node struct { City string `gorm:"column:city;not null;comment:城市" json:"city"` // 城市 ProxyID int32 `gorm:"column:proxy_id;comment:代理ID" json:"proxy_id"` // 代理ID ProxyPort int32 `gorm:"column:proxy_port;comment:代理端口" json:"proxy_port"` // 代理端口 - Status int32 `gorm:"column:status;not null;comment:节点状态:1-正常,0-离线" json:"status"` // 节点状态:1-正常,0-离线 + Status int32 `gorm:"column:status;not null;comment:节点状态:0-离线,1-正常" json:"status"` // 节点状态:0-离线,1-正常 Rtt int32 `gorm:"column:rtt;comment:延迟" json:"rtt"` // 延迟 Loss int32 `gorm:"column:loss;comment:丢包率" json:"loss"` // 丢包率 CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间 - Isp int32 `gorm:"column:isp;not null" json:"isp"` + Isp int32 `gorm:"column:isp;not null;comment:运营商:0-其他,1-电信,2-联通,3-移动" json:"isp"` // 运营商:0-其他,1-电信,2-联通,3-移动 } // TableName Node's table name diff --git a/web/models/refund.gen.go b/web/models/refund.gen.go index e0be82f..942debd 100644 --- a/web/models/refund.gen.go +++ b/web/models/refund.gen.go @@ -20,9 +20,9 @@ type Refund struct { CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间 - TradeID int32 `gorm:"column:trade_id;not null" json:"trade_id"` - Reason string `gorm:"column:reason" json:"reason"` - Status int32 `gorm:"column:status;not null" json:"status"` + TradeID int32 `gorm:"column:trade_id;not null;comment:订单ID" json:"trade_id"` // 订单ID + Reason string `gorm:"column:reason;comment:退款原因" json:"reason"` // 退款原因 + Status int32 `gorm:"column:status;not null;comment:退款状态:0-待处理,1-已退款,2-已拒绝" json:"status"` // 退款状态:0-待处理,1-已退款,2-已拒绝 } // TableName Refund's table name diff --git a/web/models/resource.gen.go b/web/models/resource.gen.go index dc6f2d6..fced9c4 100644 --- a/web/models/resource.gen.go +++ b/web/models/resource.gen.go @@ -20,8 +20,8 @@ type Resource struct { CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间 - ResourceNo string `gorm:"column:resource_no" json:"resource_no"` - Type int32 `gorm:"column:type;not null" json:"type"` + ResourceNo string `gorm:"column:resource_no;comment:套餐编号" json:"resource_no"` // 套餐编号 + Type int32 `gorm:"column:type;not null;comment:套餐类型:1-动态,2-隧道,3-独享" json:"type"` // 套餐类型:1-动态,2-隧道,3-独享 Pss *ResourcePss `gorm:"foreignKey:ResourceID;references:ID" json:"pss"` } diff --git a/web/models/trade.gen.go b/web/models/trade.gen.go index 22f9764..7a2bad8 100644 --- a/web/models/trade.gen.go +++ b/web/models/trade.gen.go @@ -27,10 +27,10 @@ type Trade struct { CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间 - Type int32 `gorm:"column:type;not null" json:"type"` - CancelAt common.LocalDateTime `gorm:"column:cancel_at" json:"cancel_at"` - PaidAt common.LocalDateTime `gorm:"column:paid_at" json:"paid_at"` - PayURL string `gorm:"column:pay_url" json:"pay_url"` + Type int32 `gorm:"column:type;not null;comment:订单类型:0-充值余额,1-购买产品" json:"type"` // 订单类型:0-充值余额,1-购买产品 + CancelAt common.LocalDateTime `gorm:"column:cancel_at;comment:取消时间" json:"cancel_at"` // 取消时间 + PaidAt common.LocalDateTime `gorm:"column:paid_at;comment:支付时间" json:"paid_at"` // 支付时间 + PayURL string `gorm:"column:pay_url;comment:支付链接" json:"pay_url"` // 支付链接 } // TableName Trade's table name diff --git a/web/models/whitelist.gen.go b/web/models/whitelist.gen.go index 7840209..2a04935 100644 --- a/web/models/whitelist.gen.go +++ b/web/models/whitelist.gen.go @@ -20,7 +20,7 @@ type Whitelist struct { CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间 - Remark string `gorm:"column:remark" json:"remark"` + Remark string `gorm:"column:remark;comment:备注" json:"remark"` // 备注 } // TableName Whitelist's table name diff --git a/web/queries/bill.gen.go b/web/queries/bill.gen.go index 4c62b47..71e2a32 100644 --- a/web/queries/bill.gen.go +++ b/web/queries/bill.gen.go @@ -71,18 +71,18 @@ type bill struct { billDo ALL field.Asterisk - ID field.Int32 // 账单ID - UserID field.Int32 // 用户ID - Info field.String // 产品可读信息 - CreatedAt field.Field // 创建时间 - UpdatedAt field.Field // 更新时间 - DeletedAt field.Field // 删除时间 - TradeID field.Int32 - ResourceID field.Int32 - Type field.Int32 - BillNo field.String - RefundID field.Int32 - Amount field.Float64 + ID field.Int32 // 账单ID + UserID field.Int32 // 用户ID + Info field.String // 产品可读信息 + CreatedAt field.Field // 创建时间 + UpdatedAt field.Field // 更新时间 + DeletedAt field.Field // 删除时间 + TradeID field.Int32 // 订单ID + ResourceID field.Int32 // 套餐ID + Type field.Int32 // 账单类型:0-充值,1-消费,2-退款 + BillNo field.String // 易读账单号 + RefundID field.Int32 // 退款ID + Amount field.Float64 // 账单金额 Trade billBelongsToTrade Refund billBelongsToRefund diff --git a/web/queries/channel.gen.go b/web/queries/channel.gen.go index cb951c1..850e466 100644 --- a/web/queries/channel.gen.go +++ b/web/queries/channel.gen.go @@ -70,7 +70,7 @@ type channel struct { UpdatedAt field.Field // 更新时间 DeletedAt field.Field // 删除时间 ProxyHost field.String - Protocol field.Int32 + Protocol field.Int32 // 协议类型:1-http,2-https,3-socks5 fieldMap map[string]field.Expr } diff --git a/web/queries/client.gen.go b/web/queries/client.gen.go index 21ba38f..adbc383 100644 --- a/web/queries/client.gen.go +++ b/web/queries/client.gen.go @@ -41,6 +41,7 @@ func newClient(db *gorm.DB, opts ...gen.DOOption) client { _client.CreatedAt = field.NewField(tableName, "created_at") _client.UpdatedAt = field.NewField(tableName, "updated_at") _client.DeletedAt = field.NewField(tableName, "deleted_at") + _client.GrantPassword = field.NewBool(tableName, "grant_password") _client.fillFieldMap() @@ -50,21 +51,22 @@ func newClient(db *gorm.DB, opts ...gen.DOOption) client { type client struct { clientDo - ALL field.Asterisk - ID field.Int32 // 客户端ID - ClientID field.String // OAuth2客户端标识符 - ClientSecret field.String // OAuth2客户端密钥 - RedirectURI field.String // OAuth2 重定向URI - GrantCode field.Bool // 允许授权码授予 - GrantClient field.Bool // 允许客户端凭证授予 - GrantRefresh field.Bool // 允许刷新令牌授予 - Spec field.Int32 // 安全规范:0-web,1-native,2-browser - Name field.String // 名称 - Icon field.String // 图标URL - Status field.Int32 // 状态:1-正常,0-禁用 - CreatedAt field.Field // 创建时间 - UpdatedAt field.Field // 更新时间 - DeletedAt field.Field // 删除时间 + ALL field.Asterisk + ID field.Int32 // 客户端ID + ClientID field.String // OAuth2客户端标识符 + ClientSecret field.String // OAuth2客户端密钥 + RedirectURI field.String // OAuth2 重定向URI + GrantCode field.Bool // 允许授权码授予 + GrantClient field.Bool // 允许客户端凭证授予 + GrantRefresh field.Bool // 允许刷新令牌授予 + Spec field.Int32 // 安全规范:0-web,1-native,2-browser + Name field.String // 名称 + Icon field.String // 图标URL + Status field.Int32 // 状态:1-正常,0-禁用 + CreatedAt field.Field // 创建时间 + UpdatedAt field.Field // 更新时间 + DeletedAt field.Field // 删除时间 + GrantPassword field.Bool fieldMap map[string]field.Expr } @@ -95,6 +97,7 @@ func (c *client) updateTableName(table string) *client { c.CreatedAt = field.NewField(table, "created_at") c.UpdatedAt = field.NewField(table, "updated_at") c.DeletedAt = field.NewField(table, "deleted_at") + c.GrantPassword = field.NewBool(table, "grant_password") c.fillFieldMap() @@ -111,7 +114,7 @@ func (c *client) GetFieldByName(fieldName string) (field.OrderExpr, bool) { } func (c *client) fillFieldMap() { - c.fieldMap = make(map[string]field.Expr, 14) + c.fieldMap = make(map[string]field.Expr, 15) c.fieldMap["id"] = c.ID c.fieldMap["client_id"] = c.ClientID c.fieldMap["client_secret"] = c.ClientSecret @@ -126,6 +129,7 @@ func (c *client) fillFieldMap() { c.fieldMap["created_at"] = c.CreatedAt c.fieldMap["updated_at"] = c.UpdatedAt c.fieldMap["deleted_at"] = c.DeletedAt + c.fieldMap["grant_password"] = c.GrantPassword } func (c client) clone(db *gorm.DB) client { diff --git a/web/queries/coupon.gen.go b/web/queries/coupon.gen.go index 8f88d70..4386220 100644 --- a/web/queries/coupon.gen.go +++ b/web/queries/coupon.gen.go @@ -48,17 +48,17 @@ type coupon struct { couponDo ALL field.Asterisk - ExpireAt field.Time - CreatedAt field.Field - UpdatedAt field.Field - DeletedAt field.Field - ID field.Int32 - UserID field.Int32 - Status field.Int32 - Code field.String - Remark field.String - Amount field.Float64 - MinAmount field.Float64 + ExpireAt field.Time // 过期时间 + CreatedAt field.Field // 创建时间 + UpdatedAt field.Field // 更新时间 + DeletedAt field.Field // 删除时间 + ID field.Int32 // 优惠券ID + UserID field.Int32 // 用户ID + Status field.Int32 // 优惠券状态:0-未使用,1-已使用,2-已过期 + Code field.String // 优惠券代码 + Remark field.String // 优惠券备注 + Amount field.Float64 // 优惠券金额 + MinAmount field.Float64 // 最低消费金额 fieldMap map[string]field.Expr } diff --git a/web/queries/node.gen.go b/web/queries/node.gen.go index a3dcfb1..b6a597f 100644 --- a/web/queries/node.gen.go +++ b/web/queries/node.gen.go @@ -60,13 +60,13 @@ type node struct { City field.String // 城市 ProxyID field.Int32 // 代理ID ProxyPort field.Int32 // 代理端口 - Status field.Int32 // 节点状态:1-正常,0-离线 + Status field.Int32 // 节点状态:0-离线,1-正常 Rtt field.Int32 // 延迟 Loss field.Int32 // 丢包率 CreatedAt field.Field // 创建时间 UpdatedAt field.Field // 更新时间 DeletedAt field.Field // 删除时间 - Isp field.Int32 + Isp field.Int32 // 运营商:0-其他,1-电信,2-联通,3-移动 fieldMap map[string]field.Expr } diff --git a/web/queries/refund.gen.go b/web/queries/refund.gen.go index c5e4dd7..89f0a5f 100644 --- a/web/queries/refund.gen.go +++ b/web/queries/refund.gen.go @@ -52,9 +52,9 @@ type refund struct { CreatedAt field.Field // 创建时间 UpdatedAt field.Field // 更新时间 DeletedAt field.Field // 删除时间 - TradeID field.Int32 - Reason field.String - Status field.Int32 + TradeID field.Int32 // 订单ID + Reason field.String // 退款原因 + Status field.Int32 // 退款状态:0-待处理,1-已退款,2-已拒绝 fieldMap map[string]field.Expr } diff --git a/web/queries/resource.gen.go b/web/queries/resource.gen.go index 05e0787..8afe6fa 100644 --- a/web/queries/resource.gen.go +++ b/web/queries/resource.gen.go @@ -50,14 +50,14 @@ type resource struct { resourceDo ALL field.Asterisk - ID field.Int32 // 套餐ID - UserID field.Int32 // 用户ID - Active field.Bool // 套餐状态 - CreatedAt field.Field // 创建时间 - UpdatedAt field.Field // 更新时间 - DeletedAt field.Field // 删除时间 - ResourceNo field.String - Type field.Int32 + ID field.Int32 // 套餐ID + UserID field.Int32 // 用户ID + Active field.Bool // 套餐状态 + CreatedAt field.Field // 创建时间 + UpdatedAt field.Field // 更新时间 + DeletedAt field.Field // 删除时间 + ResourceNo field.String // 套餐编号 + Type field.Int32 // 套餐类型:1-动态,2-隧道,3-独享 Pss resourceHasOnePss fieldMap map[string]field.Expr diff --git a/web/queries/trade.gen.go b/web/queries/trade.gen.go index e6f5319..b2c7f0f 100644 --- a/web/queries/trade.gen.go +++ b/web/queries/trade.gen.go @@ -67,10 +67,10 @@ type trade struct { CreatedAt field.Field // 创建时间 UpdatedAt field.Field // 更新时间 DeletedAt field.Field // 删除时间 - Type field.Int32 - CancelAt field.Field - PaidAt field.Field - PayURL field.String + Type field.Int32 // 订单类型:0-充值余额,1-购买产品 + CancelAt field.Field // 取消时间 + PaidAt field.Field // 支付时间 + PayURL field.String // 支付链接 fieldMap map[string]field.Expr } diff --git a/web/queries/whitelist.gen.go b/web/queries/whitelist.gen.go index 4e62ed6..ca406c9 100644 --- a/web/queries/whitelist.gen.go +++ b/web/queries/whitelist.gen.go @@ -50,7 +50,7 @@ type whitelist struct { CreatedAt field.Field // 创建时间 UpdatedAt field.Field // 更新时间 DeletedAt field.Field // 删除时间 - Remark field.String + Remark field.String // 备注 fieldMap map[string]field.Expr } diff --git a/web/router.go b/web/router.go index f4f1eb3..42580e8 100644 --- a/web/router.go +++ b/web/router.go @@ -12,7 +12,7 @@ func ApplyRouters(app *fiber.App) { // 认证 auth := api.Group("/auth") - auth.Post("/verify/sms", auth2.PermitDevice(), handlers.SmsCode) + auth.Post("/verify/sms", handlers.SmsCode) auth.Post("/login/sms", auth2.PermitDevice(), handlers.Login) auth.Post("/logout", handlers.Logout) auth.Post("/token", handlers.Token) diff --git a/web/services/auth.go b/web/services/auth.go index 3c8ae5e..7c77554 100644 --- a/web/services/auth.go +++ b/web/services/auth.go @@ -85,10 +85,19 @@ func (s *authService) OauthRefreshToken(ctx context.Context, client *models.Clie return details, nil } -type GrantType int +type OauthGrantType string const ( - GrantTypeAuthorizationCode GrantType = iota - GrantTypeClientCredentials - GrantTypeRefreshToken + OauthGrantTypeAuthorizationCode = OauthGrantType("authorization_code") + OauthGrantTypeClientCredentials = OauthGrantType("client_credentials") + OauthGrantTypeRefreshToken = OauthGrantType("refresh_token") + OauthGrantTypePassword = OauthGrantType("password") +) + +type OauthGrantLoginType string + +const ( + OauthGrantPasswordTypePassword = OauthGrantLoginType("password") + OauthGrantPasswordTypePhoneCode = OauthGrantLoginType("phone_code") + OauthGrantPasswordTypeEmailCode = OauthGrantLoginType("email_code") ) diff --git a/web/services/session.go b/web/services/session.go index 5f9852e..166167b 100644 --- a/web/services/session.go +++ b/web/services/session.go @@ -239,6 +239,7 @@ func mergeConfig(defaultCfg SessionConfig, customCfg SessionConfig) SessionConfi // AuthContext 定义认证信息 type AuthContext struct { Payload Payload `json:"payload"` + Agent Agent `json:"agent,omitempty"` Permissions map[string]struct{} `json:"permissions,omitempty"` Metadata map[string]interface{} `json:"metadata,omitempty"` } @@ -265,6 +266,11 @@ const ( PayloadClientConfidential ) +type Agent struct { + Id int32 `json:"id,omitempty"` + Addr string `json:"addr,omitempty"` +} + // AnyPermission 检查认证是否包含指定权限 func (a *AuthContext) AnyPermission(requiredPermission ...string) bool { if a == nil || a.Permissions == nil {