重构增加模型枚举值定义
This commit is contained in:
@@ -6,6 +6,8 @@ import (
|
|||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
"platform/pkg/logs"
|
"platform/pkg/logs"
|
||||||
"platform/pkg/orm"
|
"platform/pkg/orm"
|
||||||
|
client2 "platform/web/domains/client"
|
||||||
|
proxy2 "platform/web/domains/proxy"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
)
|
)
|
||||||
@@ -24,13 +26,13 @@ func main() {
|
|||||||
Version: 1,
|
Version: 1,
|
||||||
Name: "7a17e8b4-cdc3-4500-bf16-4a665991a7f6",
|
Name: "7a17e8b4-cdc3-4500-bf16-4a665991a7f6",
|
||||||
Host: "110.40.82.248",
|
Host: "110.40.82.248",
|
||||||
Type: 2,
|
Type: int32(proxy2.TypeSelfHosted),
|
||||||
Secret: "api:123456",
|
Secret: "api:123456",
|
||||||
}, &m.Proxy{
|
}, &m.Proxy{
|
||||||
Version: 1,
|
Version: 1,
|
||||||
Name: "58e03f38-4cef-429c-8bb8-530142d0a745",
|
Name: "58e03f38-4cef-429c-8bb8-530142d0a745",
|
||||||
Host: "123.6.147.241",
|
Host: "123.6.147.241",
|
||||||
Type: 1,
|
Type: int32(proxy2.TypeThirdParty),
|
||||||
Secret: "api:123456",
|
Secret: "api:123456",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -65,13 +67,13 @@ func main() {
|
|||||||
GrantClient: true,
|
GrantClient: true,
|
||||||
GrantRefresh: true,
|
GrantRefresh: true,
|
||||||
GrantPassword: true,
|
GrantPassword: true,
|
||||||
Spec: 3,
|
Spec: int32(client2.SpecTrusted),
|
||||||
Name: "默认客户端",
|
Name: "默认客户端",
|
||||||
}, &m.Client{
|
}, &m.Client{
|
||||||
ClientID: "tasks",
|
ClientID: "tasks",
|
||||||
ClientSecret: string(tasksSecret),
|
ClientSecret: string(tasksSecret),
|
||||||
GrantClient: true,
|
GrantClient: true,
|
||||||
Spec: 3,
|
Spec: int32(client2.SpecTrusted),
|
||||||
Name: "异步任务处理服务",
|
Name: "异步任务处理服务",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ $$
|
|||||||
$$;
|
$$;
|
||||||
|
|
||||||
-- ====================
|
-- ====================
|
||||||
-- region 管理员信息
|
-- region 日志
|
||||||
-- ====================
|
-- ====================
|
||||||
|
|
||||||
-- logs_request
|
-- logs_request
|
||||||
@@ -44,7 +44,7 @@ create table logs_request (
|
|||||||
-- logs_access表字段注释
|
-- logs_access表字段注释
|
||||||
comment on table logs_request is '访问日志表';
|
comment on table logs_request is '访问日志表';
|
||||||
comment on column logs_request.id is '访问日志ID';
|
comment on column logs_request.id is '访问日志ID';
|
||||||
comment on column logs_request.identity is '访客身份:0-游客,1-用户,2-服务,3-管理员';
|
comment on column logs_request.identity is '访客身份:0-游客,1-用户,2-管理员,3-公共服务,4-安全服务,5-内部服务';
|
||||||
comment on column logs_request.visitor is '访客ID';
|
comment on column logs_request.visitor is '访客ID';
|
||||||
comment on column logs_request.ip is 'IP地址';
|
comment on column logs_request.ip is 'IP地址';
|
||||||
comment on column logs_request.ua is '用户代理';
|
comment on column logs_request.ua is '用户代理';
|
||||||
@@ -281,7 +281,7 @@ comment on column client.grant_code is '允许授权码授予';
|
|||||||
comment on column client.grant_client is '允许客户端凭证授予';
|
comment on column client.grant_client is '允许客户端凭证授予';
|
||||||
comment on column client.grant_refresh is '允许刷新令牌授予';
|
comment on column client.grant_refresh is '允许刷新令牌授予';
|
||||||
comment on column client.grant_password is '允许密码授予';
|
comment on column client.grant_password is '允许密码授予';
|
||||||
comment on column client.spec is '安全规范:1-native,2-browser,3-web';
|
comment on column client.spec is '安全规范:1-native,2-browser,3-web,4-trusted';
|
||||||
comment on column client.name is '名称';
|
comment on column client.name is '名称';
|
||||||
comment on column client.icon is '图标URL';
|
comment on column client.icon is '图标URL';
|
||||||
comment on column client.status is '状态:0-禁用,1-正常';
|
comment on column client.status is '状态:0-禁用,1-正常';
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
client2 "platform/web/domains/client"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -38,7 +39,7 @@ func Protect(c *fiber.Ctx, types []PayloadType, permissions []string) (*Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "Basic":
|
case "Basic":
|
||||||
if !slices.Contains(types, PayloadClientConfidential) {
|
if !slices.Contains(types, PayloadSecuredServer) {
|
||||||
slog.Debug("禁止使用 Basic 认证方式")
|
slog.Debug("禁止使用 Basic 认证方式")
|
||||||
return nil, fiber.NewError(fiber.StatusUnauthorized, "无效的令牌")
|
return nil, fiber.NewError(fiber.StatusUnauthorized, "无效的令牌")
|
||||||
}
|
}
|
||||||
@@ -106,7 +107,7 @@ func authBasic(_ context.Context, token string) (*Context, error) {
|
|||||||
client, err := q.Client.
|
client, err := q.Client.
|
||||||
Where(
|
Where(
|
||||||
q.Client.ClientID.Eq(clientID),
|
q.Client.ClientID.Eq(clientID),
|
||||||
q.Client.Spec.Eq(3),
|
q.Client.Spec.In(int32(client2.SpecWeb), int32(client2.SpecTrusted)),
|
||||||
q.Client.GrantClient.Is(true),
|
q.Client.GrantClient.Is(true),
|
||||||
q.Client.Status.Eq(1)).
|
q.Client.Status.Eq(1)).
|
||||||
Take()
|
Take()
|
||||||
@@ -126,7 +127,7 @@ func authBasic(_ context.Context, token string) (*Context, error) {
|
|||||||
return &Context{
|
return &Context{
|
||||||
Payload: Payload{
|
Payload: Payload{
|
||||||
Id: client.ID,
|
Id: client.ID,
|
||||||
Type: PayloadClientConfidential,
|
Type: PayloadSecuredServer,
|
||||||
Name: client.Name,
|
Name: client.Name,
|
||||||
Avatar: client.Icon,
|
Avatar: client.Icon,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -37,15 +37,18 @@ type Agent struct {
|
|||||||
type PayloadType int
|
type PayloadType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// PayloadNone 游客
|
||||||
PayloadNone PayloadType = iota
|
PayloadNone PayloadType = iota
|
||||||
// PayloadUser 用户类型
|
// PayloadUser 用户
|
||||||
PayloadUser
|
PayloadUser
|
||||||
// PayloadAdmin 管理员类型
|
// PayloadAdmin 管理员
|
||||||
PayloadAdmin
|
PayloadAdmin
|
||||||
// PayloadClientPublic 公共客户端类型
|
// PayloadPublicServer 公共服务(public_client)
|
||||||
PayloadClientPublic
|
PayloadPublicServer
|
||||||
// PayloadClientConfidential 机密客户端类型
|
// PayloadSecuredServer 安全服务(credential_client)
|
||||||
PayloadClientConfidential
|
PayloadSecuredServer
|
||||||
|
// PayloadInternalServer 内部服务
|
||||||
|
PayloadInternalServer
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t PayloadType) ToStr() string {
|
func (t PayloadType) ToStr() string {
|
||||||
@@ -54,9 +57,9 @@ func (t PayloadType) ToStr() string {
|
|||||||
return "user"
|
return "user"
|
||||||
case PayloadAdmin:
|
case PayloadAdmin:
|
||||||
return "admn"
|
return "admn"
|
||||||
case PayloadClientPublic:
|
case PayloadPublicServer:
|
||||||
return "cpub"
|
return "cpub"
|
||||||
case PayloadClientConfidential:
|
case PayloadSecuredServer:
|
||||||
return "ccnf"
|
return "ccnf"
|
||||||
default:
|
default:
|
||||||
return "none"
|
return "none"
|
||||||
@@ -70,9 +73,9 @@ func PayloadTypeFromStr(name string) PayloadType {
|
|||||||
case "admn":
|
case "admn":
|
||||||
return PayloadAdmin
|
return PayloadAdmin
|
||||||
case "cpub":
|
case "cpub":
|
||||||
return PayloadClientPublic
|
return PayloadPublicServer
|
||||||
case "ccnf":
|
case "ccnf":
|
||||||
return PayloadClientConfidential
|
return PayloadSecuredServer
|
||||||
default:
|
default:
|
||||||
return PayloadNone
|
return PayloadNone
|
||||||
}
|
}
|
||||||
|
|||||||
7
web/domains/announcement/types.go
Normal file
7
web/domains/announcement/types.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package announcement
|
||||||
|
|
||||||
|
type Type int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
TypeNormal Type = iota + 1 // 普通公告
|
||||||
|
)
|
||||||
9
web/domains/bill/types.go
Normal file
9
web/domains/bill/types.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package bill
|
||||||
|
|
||||||
|
type Type int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
TypeConsume Type = iota + 1 // 消费
|
||||||
|
TypeRefund // 退款
|
||||||
|
TypeRecharge // 充值
|
||||||
|
)
|
||||||
9
web/domains/channel/types.go
Normal file
9
web/domains/channel/types.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package channel
|
||||||
|
|
||||||
|
type Protocol int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
ProtocolHttp Protocol = iota + 1
|
||||||
|
ProtocolHttps
|
||||||
|
ProtocolSocks5
|
||||||
|
)
|
||||||
10
web/domains/client/types.go
Normal file
10
web/domains/client/types.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
type Spec int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
SpecNative Spec = iota + 1 // 原生客户端
|
||||||
|
SpecBrowser // 浏览器客户端
|
||||||
|
SpecWeb // Web 服务
|
||||||
|
SpecTrusted // 可信服务
|
||||||
|
)
|
||||||
9
web/domains/coupon/types.go
Normal file
9
web/domains/coupon/types.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package coupon
|
||||||
|
|
||||||
|
type Status int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
StatusUnused = iota // 未使用
|
||||||
|
StatusUsed // 已使用
|
||||||
|
StatusExpired // 已过期
|
||||||
|
)
|
||||||
10
web/domains/node/types.go
Normal file
10
web/domains/node/types.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
type ISP int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
IspUnknown ISP = iota // 未知
|
||||||
|
IspChinaTelecom // 中国电信
|
||||||
|
IspChinaUnicom // 中国联通
|
||||||
|
IspChinaMobile // 中国移动
|
||||||
|
)
|
||||||
8
web/domains/proxy/types.go
Normal file
8
web/domains/proxy/types.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package proxy
|
||||||
|
|
||||||
|
type Type int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
TypeThirdParty Type = iota + 1 // 三方代理
|
||||||
|
TypeSelfHosted // 自建代理
|
||||||
|
)
|
||||||
9
web/domains/refund/types.go
Normal file
9
web/domains/refund/types.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package refund
|
||||||
|
|
||||||
|
type Status int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
StatusHandling Status = iota + 1 // 待处理
|
||||||
|
StatusSuccess // 已退款
|
||||||
|
StatusRefused // 已拒绝
|
||||||
|
)
|
||||||
16
web/domains/resource/types.go
Normal file
16
web/domains/resource/types.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package resource
|
||||||
|
|
||||||
|
type Type int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
TypeDynamic Type = iota + 1 // 动态
|
||||||
|
TypeTunnel // 隧道
|
||||||
|
TypePrivate // 私有
|
||||||
|
)
|
||||||
|
|
||||||
|
type PssType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
PssTypeTime PssType = iota + 1 // 包时
|
||||||
|
PssTypeCount // 包量
|
||||||
|
)
|
||||||
24
web/domains/trade/types.go
Normal file
24
web/domains/trade/types.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package trade
|
||||||
|
|
||||||
|
type Type int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
TypePurchase Type = iota + 1 // 购买
|
||||||
|
TypeRecharge // 充值
|
||||||
|
)
|
||||||
|
|
||||||
|
type Method int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
MethodAlipay Method = iota + 1 // 支付宝
|
||||||
|
MethodWeChat // 微信
|
||||||
|
)
|
||||||
|
|
||||||
|
type Status int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
StatusPending Status = iota // 待支付
|
||||||
|
StatusSuccess // 已支付
|
||||||
|
StatusCanceled // 已取消
|
||||||
|
StatusRefunded
|
||||||
|
) // 已退款
|
||||||
9
web/domains/user/types.go
Normal file
9
web/domains/user/types.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
type IdType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
IdTypeNone IdType = iota // 未认证
|
||||||
|
IdTypePersonal // 个人认证
|
||||||
|
IdTypeEnterprise // 企业认证
|
||||||
|
)
|
||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
|
client2 "platform/web/domains/client"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
s "platform/web/services"
|
s "platform/web/services"
|
||||||
@@ -188,7 +189,7 @@ func protect(c *fiber.Ctx, grant s.OauthGrantType, clientId, clientSecret string
|
|||||||
return nil, s.ErrOauthUnauthorizedClient
|
return nil, s.ErrOauthUnauthorizedClient
|
||||||
}
|
}
|
||||||
case s.OauthGrantTypeClientCredentials:
|
case s.OauthGrantTypeClientCredentials:
|
||||||
if !client.GrantClient || client.Spec != 3 {
|
if !client.GrantClient || client.Spec != int32(client2.SpecWeb) || client.Spec != int32(client2.SpecTrusted) {
|
||||||
return nil, s.ErrOauthUnauthorizedClient
|
return nil, s.ErrOauthUnauthorizedClient
|
||||||
}
|
}
|
||||||
case s.OauthGrantTypeRefreshToken:
|
case s.OauthGrantTypeRefreshToken:
|
||||||
@@ -202,7 +203,7 @@ func protect(c *fiber.Ctx, grant s.OauthGrantType, clientId, clientSecret string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 如果客户端是 confidential,验证 client_secret,失败返回错误
|
// 如果客户端是 confidential,验证 client_secret,失败返回错误
|
||||||
if client.Spec == 3 {
|
if client.Spec == int32(client2.SpecWeb) || client.Spec == int32(client2.SpecTrusted) {
|
||||||
if clientSecret == "" {
|
if clientSecret == "" {
|
||||||
return nil, s.ErrOauthInvalidRequest
|
return nil, s.ErrOauthInvalidRequest
|
||||||
}
|
}
|
||||||
@@ -215,7 +216,7 @@ func protect(c *fiber.Ctx, grant s.OauthGrantType, clientId, clientSecret string
|
|||||||
auth.Locals(c, &auth.Context{
|
auth.Locals(c, &auth.Context{
|
||||||
Payload: auth.Payload{
|
Payload: auth.Payload{
|
||||||
Id: client.ID,
|
Id: client.ID,
|
||||||
Type: auth.PayloadClientConfidential,
|
Type: auth.PayloadSecuredServer,
|
||||||
Name: client.Name,
|
Name: client.Name,
|
||||||
Avatar: client.Icon,
|
Avatar: client.Icon,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
|
channel2 "platform/web/domains/channel"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
s "platform/web/services"
|
s "platform/web/services"
|
||||||
"time"
|
"time"
|
||||||
@@ -90,7 +91,7 @@ func ListChannels(c *fiber.Ctx) error {
|
|||||||
type CreateChannelReq struct {
|
type CreateChannelReq struct {
|
||||||
ResourceId int32 `json:"resource_id" validate:"required"`
|
ResourceId int32 `json:"resource_id" validate:"required"`
|
||||||
AuthType s.ChannelAuthType `json:"auth_type" validate:"required"`
|
AuthType s.ChannelAuthType `json:"auth_type" validate:"required"`
|
||||||
Protocol s.ChannelProtocol `json:"protocol" validate:"required"`
|
Protocol channel2.Protocol `json:"protocol" validate:"required"`
|
||||||
Count int `json:"count" validate:"required"`
|
Count int `json:"count" validate:"required"`
|
||||||
Prov string `json:"prov"`
|
Prov string `json:"prov"`
|
||||||
City string `json:"city"`
|
City string `json:"city"`
|
||||||
@@ -98,7 +99,7 @@ type CreateChannelReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CreateChannelRespItem struct {
|
type CreateChannelRespItem struct {
|
||||||
Proto s.ChannelProtocol `json:"-"`
|
Proto channel2.Protocol `json:"-"`
|
||||||
Host string `json:"host"`
|
Host string `json:"host"`
|
||||||
Port int32 `json:"port"`
|
Port int32 `json:"port"`
|
||||||
Username *string `json:"username,omitempty"`
|
Username *string `json:"username,omitempty"`
|
||||||
@@ -198,7 +199,7 @@ func RemoveChannels(c *fiber.Ctx) error {
|
|||||||
// 检查权限
|
// 检查权限
|
||||||
authCtx, err := auth.Protect(c, []auth.PayloadType{
|
authCtx, err := auth.Protect(c, []auth.PayloadType{
|
||||||
auth.PayloadUser,
|
auth.PayloadUser,
|
||||||
auth.PayloadClientConfidential,
|
auth.PayloadSecuredServer,
|
||||||
}, []string{})
|
}, []string{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"platform/pkg/u"
|
"platform/pkg/u"
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
|
resource2 "platform/web/domains/resource"
|
||||||
|
trade2 "platform/web/domains/trade"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
s "platform/web/services"
|
s "platform/web/services"
|
||||||
"time"
|
"time"
|
||||||
@@ -115,10 +117,10 @@ func AllResource(c *fiber.Ctx) error {
|
|||||||
q.Resource.UserID.Eq(authContext.Payload.Id),
|
q.Resource.UserID.Eq(authContext.Payload.Id),
|
||||||
q.Resource.Active.Is(true),
|
q.Resource.Active.Is(true),
|
||||||
q.Resource.Where(
|
q.Resource.Where(
|
||||||
pss.Type.Eq(1),
|
pss.Type.Eq(int32(resource2.PssTypeTime)),
|
||||||
pss.Expire.Gte(core.LocalDateTime(time.Now())),
|
pss.Expire.Gte(core.LocalDateTime(time.Now())),
|
||||||
).Or(
|
).Or(
|
||||||
pss.Type.Eq(2),
|
pss.Type.Eq(int32(resource2.PssTypeCount)),
|
||||||
pss.Quota.GtCol(pss.Used),
|
pss.Quota.GtCol(pss.Used),
|
||||||
),
|
),
|
||||||
q.Resource.Where(
|
q.Resource.Where(
|
||||||
@@ -174,7 +176,7 @@ func PrepareResourceByAlipay(c *fiber.Ctx) error {
|
|||||||
c.Context(),
|
c.Context(),
|
||||||
&req.CreateResourceData,
|
&req.CreateResourceData,
|
||||||
authContext.Payload.Id,
|
authContext.Payload.Id,
|
||||||
s.TransactionMethodAlipay,
|
trade2.MethodAlipay,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -206,7 +208,7 @@ func PrepareResourceByWechat(c *fiber.Ctx) error {
|
|||||||
c.Context(),
|
c.Context(),
|
||||||
&req.CreateResourceData,
|
&req.CreateResourceData,
|
||||||
authContext.Payload.Id,
|
authContext.Payload.Id,
|
||||||
s.TransactionMethodWeChat,
|
trade2.MethodWeChat,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -235,7 +237,7 @@ func CreateResourceByAlipay(c *fiber.Ctx) error {
|
|||||||
// 验证支付结果
|
// 验证支付结果
|
||||||
result, err := s.Transaction.VerifyTransaction(c.Context(), &s.TransactionVerifyData{
|
result, err := s.Transaction.VerifyTransaction(c.Context(), &s.TransactionVerifyData{
|
||||||
TradeNo: req.TradeNo,
|
TradeNo: req.TradeNo,
|
||||||
Method: s.TransactionMethodAlipay,
|
Method: trade2.MethodAlipay,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -266,7 +268,7 @@ func CreateResourceByWechat(c *fiber.Ctx) error {
|
|||||||
// 验证支付结果
|
// 验证支付结果
|
||||||
result, err := s.Transaction.VerifyTransaction(c.Context(), &s.TransactionVerifyData{
|
result, err := s.Transaction.VerifyTransaction(c.Context(), &s.TransactionVerifyData{
|
||||||
TradeNo: req.TradeNo,
|
TradeNo: req.TradeNo,
|
||||||
Method: s.TransactionMethodWeChat,
|
Method: trade2.MethodWeChat,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
trade2 "platform/web/domains/trade"
|
||||||
g "platform/web/globals"
|
g "platform/web/globals"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
s "platform/web/services"
|
s "platform/web/services"
|
||||||
@@ -65,17 +66,17 @@ func AlipayCallback(c *fiber.Ctx) error {
|
|||||||
Payment: payment,
|
Payment: payment,
|
||||||
Time: paidAt,
|
Time: paidAt,
|
||||||
}
|
}
|
||||||
switch trade.Type {
|
switch trade2.Type(trade.Type) {
|
||||||
|
|
||||||
// 余额充值
|
// 余额充值
|
||||||
case 2:
|
case trade2.TypeRecharge:
|
||||||
err := s.User.RechargeConfirm(c.Context(), notification.OutTradeNo, verified)
|
err := s.User.RechargeConfirm(c.Context(), notification.OutTradeNo, verified)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 购买产品
|
// 购买产品
|
||||||
case 1:
|
case trade2.TypePurchase:
|
||||||
err = s.Resource.CompleteResource(c.Context(), notification.OutTradeNo, verified)
|
err = s.Resource.CompleteResource(c.Context(), notification.OutTradeNo, verified)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -84,20 +85,21 @@ func AlipayCallback(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
// 支付关闭
|
// 支付关闭
|
||||||
case string(alipay.TradeStatusClosed):
|
case string(alipay.TradeStatusClosed):
|
||||||
switch trade.Type {
|
switch trade2.Type(trade.Type) {
|
||||||
|
|
||||||
// 购买产品
|
// 购买产品
|
||||||
case 1:
|
case trade2.TypePurchase:
|
||||||
|
|
||||||
cancelAt, err := time.Parse("2006-01-02 15:04:05", notification.GmtClose)
|
cancelAt, err := time.Parse("2006-01-02 15:04:05", notification.GmtClose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Resource.CancelResource(c.Context(), notification.OutTradeNo, cancelAt, s.TransactionMethodAlipay)
|
err = s.Resource.CancelResource(c.Context(), notification.OutTradeNo, cancelAt, trade2.MethodAlipay)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,14 +177,14 @@ func WechatPayCallback(c *fiber.Ctx) error {
|
|||||||
switch {
|
switch {
|
||||||
|
|
||||||
// 余额充值
|
// 余额充值
|
||||||
case trade.Type == 2:
|
case trade.Type == int32(trade2.TypeRecharge):
|
||||||
err := s.User.RechargeConfirm(c.Context(), *content.OutTradeNo, verified)
|
err := s.User.RechargeConfirm(c.Context(), *content.OutTradeNo, verified)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 购买产品
|
// 购买产品
|
||||||
case trade.Type == 1:
|
case trade.Type == int32(trade2.TypePurchase):
|
||||||
err = s.Resource.CompleteResource(c.Context(), *content.OutTradeNo, verified)
|
err = s.Resource.CompleteResource(c.Context(), *content.OutTradeNo, verified)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package handlers
|
|||||||
import (
|
import (
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
|
trade2 "platform/web/domains/trade"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
s "platform/web/services"
|
s "platform/web/services"
|
||||||
@@ -180,8 +181,8 @@ func RechargePrepareAlipay(c *fiber.Ctx) error {
|
|||||||
Subject: "账户充值 - " + strconv.FormatFloat(req.Amount, 'f', 2, 64) + "元",
|
Subject: "账户充值 - " + strconv.FormatFloat(req.Amount, 'f', 2, 64) + "元",
|
||||||
Amount: req.Amount,
|
Amount: req.Amount,
|
||||||
ExpireAt: time.Now().Add(30 * time.Minute),
|
ExpireAt: time.Now().Add(30 * time.Minute),
|
||||||
Type: s.TransactionTypeRecharge,
|
Type: trade2.TypeRecharge,
|
||||||
Method: s.TransactionMethodAlipay,
|
Method: trade2.MethodAlipay,
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
@@ -212,7 +213,7 @@ func RechargeConfirmAlipay(c *fiber.Ctx) error {
|
|||||||
// 验证支付结果
|
// 验证支付结果
|
||||||
result, err := s.Transaction.VerifyTransaction(c.Context(), &s.TransactionVerifyData{
|
result, err := s.Transaction.VerifyTransaction(c.Context(), &s.TransactionVerifyData{
|
||||||
TradeNo: req.TradeNo,
|
TradeNo: req.TradeNo,
|
||||||
Method: s.TransactionMethodAlipay,
|
Method: trade2.MethodAlipay,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -247,8 +248,8 @@ func RechargePrepareWechat(c *fiber.Ctx) error {
|
|||||||
Subject: "账户充值 - " + strconv.FormatFloat(req.Amount, 'f', 2, 64) + "元",
|
Subject: "账户充值 - " + strconv.FormatFloat(req.Amount, 'f', 2, 64) + "元",
|
||||||
Amount: req.Amount,
|
Amount: req.Amount,
|
||||||
ExpireAt: time.Now().Add(30 * time.Minute),
|
ExpireAt: time.Now().Add(30 * time.Minute),
|
||||||
Type: s.TransactionTypeRecharge,
|
Type: trade2.TypeRecharge,
|
||||||
Method: s.TransactionMethodWeChat,
|
Method: trade2.MethodWeChat,
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
@@ -281,7 +282,7 @@ func RechargeConfirmWechat(c *fiber.Ctx) error {
|
|||||||
// 验证支付结果
|
// 验证支付结果
|
||||||
result, err := s.Transaction.VerifyTransaction(c.Context(), &s.TransactionVerifyData{
|
result, err := s.Transaction.VerifyTransaction(c.Context(), &s.TransactionVerifyData{
|
||||||
TradeNo: req.TradeNo,
|
TradeNo: req.TradeNo,
|
||||||
Method: s.TransactionMethodWeChat,
|
Method: trade2.MethodWeChat,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ type VerifierReq struct {
|
|||||||
func SmsCode(c *fiber.Ctx) error {
|
func SmsCode(c *fiber.Ctx) error {
|
||||||
|
|
||||||
_, err := auth.Protect(c, []auth.PayloadType{
|
_, err := auth.Protect(c, []auth.PayloadType{
|
||||||
auth.PayloadClientConfidential,
|
auth.PayloadSecuredServer,
|
||||||
}, []string{})
|
}, []string{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -14,21 +14,21 @@ const TableNameClient = "client"
|
|||||||
|
|
||||||
// Client mapped from table <client>
|
// Client mapped from table <client>
|
||||||
type Client struct {
|
type Client struct {
|
||||||
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:客户端ID" json:"id"` // 客户端ID
|
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客户端标识符
|
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客户端密钥
|
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
|
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"` // 允许授权码授予
|
GrantCode bool `gorm:"column:grant_code;not null;comment:允许授权码授予" json:"grant_code"` // 允许授权码授予
|
||||||
GrantClient bool `gorm:"column:grant_client;not null;comment:允许客户端凭证授予" json:"grant_client"` // 允许客户端凭证授予
|
GrantClient bool `gorm:"column:grant_client;not null;comment:允许客户端凭证授予" json:"grant_client"` // 允许客户端凭证授予
|
||||||
GrantRefresh bool `gorm:"column:grant_refresh;not null;comment:允许刷新令牌授予" json:"grant_refresh"` // 允许刷新令牌授予
|
GrantRefresh bool `gorm:"column:grant_refresh;not null;comment:允许刷新令牌授予" json:"grant_refresh"` // 允许刷新令牌授予
|
||||||
GrantPassword bool `gorm:"column:grant_password;not null;comment:允许密码授予" json:"grant_password"` // 允许密码授予
|
GrantPassword bool `gorm:"column:grant_password;not null;comment:允许密码授予" json:"grant_password"` // 允许密码授予
|
||||||
Spec int32 `gorm:"column:spec;not null;comment:安全规范:1-native,2-browser,3-web" json:"spec"` // 安全规范:1-native,2-browser,3-web
|
Spec int32 `gorm:"column:spec;not null;comment:安全规范:1-native,2-browser,3-web,4-trusted" json:"spec"` // 安全规范:1-native,2-browser,3-web,4-trusted
|
||||||
Name string `gorm:"column:name;not null;comment:名称" json:"name"` // 名称
|
Name string `gorm:"column:name;not null;comment:名称" json:"name"` // 名称
|
||||||
Icon string `gorm:"column:icon;comment:图标URL" json:"icon"` // 图标URL
|
Icon string `gorm:"column:icon;comment:图标URL" json:"icon"` // 图标URL
|
||||||
Status int32 `gorm:"column:status;not null;default:1;comment:状态:0-禁用,1-正常" json:"status"` // 状态:0-禁用,1-正常
|
Status int32 `gorm:"column:status;not null;default:1;comment:状态:0-禁用,1-正常" json:"status"` // 状态:0-禁用,1-正常
|
||||||
CreatedAt core.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
|
CreatedAt core.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
|
||||||
UpdatedAt core.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
|
UpdatedAt core.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
|
||||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间
|
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName Client's table name
|
// TableName Client's table name
|
||||||
|
|||||||
@@ -10,17 +10,17 @@ const TableNameLogsRequest = "logs_request"
|
|||||||
|
|
||||||
// LogsRequest mapped from table <logs_request>
|
// LogsRequest mapped from table <logs_request>
|
||||||
type LogsRequest struct {
|
type LogsRequest struct {
|
||||||
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:访问日志ID" json:"id"` // 访问日志ID
|
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:访问日志ID" json:"id"` // 访问日志ID
|
||||||
Identity int32 `gorm:"column:identity;comment:访客身份:0-游客,1-用户,2-服务,3-管理员" json:"identity"` // 访客身份:0-游客,1-用户,2-服务,3-管理员
|
Identity int32 `gorm:"column:identity;comment:访客身份:0-游客,1-用户,2-管理员,3-公共服务,4-安全服务,5-内部服务" json:"identity"` // 访客身份:0-游客,1-用户,2-管理员,3-公共服务,4-安全服务,5-内部服务
|
||||||
Visitor int32 `gorm:"column:visitor;comment:访客ID" json:"visitor"` // 访客ID
|
Visitor int32 `gorm:"column:visitor;comment:访客ID" json:"visitor"` // 访客ID
|
||||||
IP string `gorm:"column:ip;not null;comment:IP地址" json:"ip"` // IP地址
|
IP string `gorm:"column:ip;not null;comment:IP地址" json:"ip"` // IP地址
|
||||||
Ua string `gorm:"column:ua;comment:用户代理" json:"ua"` // 用户代理
|
Ua string `gorm:"column:ua;comment:用户代理" json:"ua"` // 用户代理
|
||||||
Method string `gorm:"column:method;not null;comment:请求方法" json:"method"` // 请求方法
|
Method string `gorm:"column:method;not null;comment:请求方法" json:"method"` // 请求方法
|
||||||
Path string `gorm:"column:path;not null;comment:请求路径" json:"path"` // 请求路径
|
Path string `gorm:"column:path;not null;comment:请求路径" json:"path"` // 请求路径
|
||||||
Latency string `gorm:"column:latency;comment:请求延迟" json:"latency"` // 请求延迟
|
Latency string `gorm:"column:latency;comment:请求延迟" json:"latency"` // 请求延迟
|
||||||
Status int32 `gorm:"column:status;not null;comment:响应状态码" json:"status"` // 响应状态码
|
Status int32 `gorm:"column:status;not null;comment:响应状态码" json:"status"` // 响应状态码
|
||||||
Error string `gorm:"column:error;comment:错误信息" json:"error"` // 错误信息
|
Error string `gorm:"column:error;comment:错误信息" json:"error"` // 错误信息
|
||||||
Time core.LocalDateTime `gorm:"column:time;default:CURRENT_TIMESTAMP;comment:请求时间" json:"time"` // 请求时间
|
Time core.LocalDateTime `gorm:"column:time;default:CURRENT_TIMESTAMP;comment:请求时间" json:"time"` // 请求时间
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName LogsRequest's table name
|
// TableName LogsRequest's table name
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ type client struct {
|
|||||||
GrantClient field.Bool // 允许客户端凭证授予
|
GrantClient field.Bool // 允许客户端凭证授予
|
||||||
GrantRefresh field.Bool // 允许刷新令牌授予
|
GrantRefresh field.Bool // 允许刷新令牌授予
|
||||||
GrantPassword field.Bool // 允许密码授予
|
GrantPassword field.Bool // 允许密码授予
|
||||||
Spec field.Int32 // 安全规范:1-native,2-browser,3-web
|
Spec field.Int32 // 安全规范:1-native,2-browser,3-web,4-trusted
|
||||||
Name field.String // 名称
|
Name field.String // 名称
|
||||||
Icon field.String // 图标URL
|
Icon field.String // 图标URL
|
||||||
Status field.Int32 // 状态:0-禁用,1-正常
|
Status field.Int32 // 状态:0-禁用,1-正常
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ type logsRequest struct {
|
|||||||
|
|
||||||
ALL field.Asterisk
|
ALL field.Asterisk
|
||||||
ID field.Int32 // 访问日志ID
|
ID field.Int32 // 访问日志ID
|
||||||
Identity field.Int32 // 访客身份:0-游客,1-用户,2-服务,3-管理员
|
Identity field.Int32 // 访客身份:0-游客,1-用户,2-管理员,3-公共服务,4-安全服务,5-内部服务
|
||||||
Visitor field.Int32 // 访客ID
|
Visitor field.Int32 // 访客ID
|
||||||
IP field.String // IP地址
|
IP field.String // IP地址
|
||||||
Ua field.String // 用户代理
|
Ua field.String // 用户代理
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
|
client2 "platform/web/domains/client"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"time"
|
"time"
|
||||||
@@ -26,13 +27,11 @@ func (s *authService) OauthAuthorizationCode(ctx context.Context, client *m.Clie
|
|||||||
func (s *authService) OauthClientCredentials(ctx context.Context, client *m.Client, scope ...string) (*TokenDetails, error) {
|
func (s *authService) OauthClientCredentials(ctx context.Context, client *m.Client, scope ...string) (*TokenDetails, error) {
|
||||||
|
|
||||||
var clientType auth.PayloadType
|
var clientType auth.PayloadType
|
||||||
switch client.Spec {
|
switch client2.Spec(client.Spec) {
|
||||||
case 1:
|
case client2.SpecNative, client2.SpecBrowser:
|
||||||
clientType = auth.PayloadClientPublic
|
clientType = auth.PayloadPublicServer
|
||||||
case 2:
|
case client2.SpecWeb, client2.SpecTrusted:
|
||||||
clientType = auth.PayloadClientPublic
|
clientType = auth.PayloadSecuredServer
|
||||||
case 3:
|
|
||||||
clientType = auth.PayloadClientConfidential
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var permissions = make(map[string]struct{}, len(scope))
|
var permissions = make(map[string]struct{}, len(scope))
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import (
|
|||||||
"platform/pkg/u"
|
"platform/pkg/u"
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
|
channel2 "platform/web/domains/channel"
|
||||||
|
proxy2 "platform/web/domains/proxy"
|
||||||
g "platform/web/globals"
|
g "platform/web/globals"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
@@ -214,7 +216,7 @@ func (s *channelService) CreateChannel(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
authCtx *auth.Context,
|
authCtx *auth.Context,
|
||||||
resourceId int32,
|
resourceId int32,
|
||||||
protocol ChannelProtocol,
|
protocol channel2.Protocol,
|
||||||
authType ChannelAuthType,
|
authType ChannelAuthType,
|
||||||
count int,
|
count int,
|
||||||
nodeFilter ...NodeFilterConfig,
|
nodeFilter ...NodeFilterConfig,
|
||||||
@@ -340,7 +342,7 @@ func findResource(q *q.Query, resourceId int32, authCtx *auth.Context, count int
|
|||||||
|
|
||||||
func findProxies(q *q.Query) (proxies []*m.Proxy, err error) {
|
func findProxies(q *q.Query) (proxies []*m.Proxy, err error) {
|
||||||
proxies, err = q.Proxy.
|
proxies, err = q.Proxy.
|
||||||
Where(q.Proxy.Type.Eq(1)).
|
Where(q.Proxy.Type.Eq(int32(proxy2.TypeThirdParty))).
|
||||||
Find()
|
Find()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -394,7 +396,7 @@ func calcChannels(
|
|||||||
whitelist *[]string,
|
whitelist *[]string,
|
||||||
count int,
|
count int,
|
||||||
userId int32,
|
userId int32,
|
||||||
protocol ChannelProtocol,
|
protocol channel2.Protocol,
|
||||||
authType ChannelAuthType,
|
authType ChannelAuthType,
|
||||||
expiration time.Time,
|
expiration time.Time,
|
||||||
filter NodeFilterConfig,
|
filter NodeFilterConfig,
|
||||||
@@ -700,15 +702,6 @@ const (
|
|||||||
ChannelAuthTypePass
|
ChannelAuthTypePass
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChannelProtocol int32
|
|
||||||
|
|
||||||
const (
|
|
||||||
ProtocolAll ChannelProtocol = iota
|
|
||||||
ProtocolHTTP
|
|
||||||
ProtocolHttps
|
|
||||||
ProtocolSocks5
|
|
||||||
)
|
|
||||||
|
|
||||||
type ChannelServiceErr string
|
type ChannelServiceErr string
|
||||||
|
|
||||||
func (c ChannelServiceErr) Error() string {
|
func (c ChannelServiceErr) Error() string {
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"platform/pkg/rds"
|
"platform/pkg/rds"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
|
bill2 "platform/web/domains/bill"
|
||||||
|
resource2 "platform/web/domains/resource"
|
||||||
|
trade2 "platform/web/domains/trade"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -19,7 +22,7 @@ var Resource = &resourceService{}
|
|||||||
|
|
||||||
type resourceService struct{}
|
type resourceService struct{}
|
||||||
|
|
||||||
func (s *resourceService) PrepareResource(ctx context.Context, data *CreateResourceData, uid int32, method TransactionMethod) (*TransactionPrepareResult, error) {
|
func (s *resourceService) PrepareResource(ctx context.Context, data *CreateResourceData, uid int32, method trade2.Method) (*TransactionPrepareResult, error) {
|
||||||
amount := data.GetPrice()
|
amount := data.GetPrice()
|
||||||
|
|
||||||
// 保存到数据库
|
// 保存到数据库
|
||||||
@@ -32,7 +35,7 @@ func (s *resourceService) PrepareResource(ctx context.Context, data *CreateResou
|
|||||||
Subject: "购买套餐 - " + data.GetName(),
|
Subject: "购买套餐 - " + data.GetName(),
|
||||||
Amount: amount,
|
Amount: amount,
|
||||||
ExpireAt: time.Now().Add(30 * time.Minute),
|
ExpireAt: time.Now().Add(30 * time.Minute),
|
||||||
Type: TransactionTypePurchase,
|
Type: trade2.TypeRecharge,
|
||||||
Method: method,
|
Method: method,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -150,7 +153,7 @@ func (s *resourceService) CreateResource(data *CreateResourceData, uid int32) er
|
|||||||
ResourceID: resource.ID,
|
ResourceID: resource.ID,
|
||||||
BillNo: ID.GenReadable("bil"),
|
BillNo: ID.GenReadable("bil"),
|
||||||
Info: "购买套餐 - " + data.GetName(),
|
Info: "购买套餐 - " + data.GetName(),
|
||||||
Type: 1,
|
Type: int32(bill2.TypeConsume),
|
||||||
Amount: data.GetPrice(),
|
Amount: data.GetPrice(),
|
||||||
}
|
}
|
||||||
err = q.Bill.
|
err = q.Bill.
|
||||||
@@ -243,7 +246,7 @@ func createResource(q *q.Query, data *CreateResourceData, uid int32) (*m.Resourc
|
|||||||
UserID: uid,
|
UserID: uid,
|
||||||
ResourceNo: ID.GenReadable("res"),
|
ResourceNo: ID.GenReadable("res"),
|
||||||
Active: true,
|
Active: true,
|
||||||
Type: 1,
|
Type: int32(resource2.TypeDynamic),
|
||||||
Pss: &m.ResourcePss{
|
Pss: &m.ResourcePss{
|
||||||
Type: data.Type,
|
Type: data.Type,
|
||||||
Live: data.Live,
|
Live: data.Live,
|
||||||
@@ -260,7 +263,7 @@ func createResource(q *q.Query, data *CreateResourceData, uid int32) (*m.Resourc
|
|||||||
return &resource, nil
|
return &resource, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *resourceService) CancelResource(ctx context.Context, tradeNo string, at time.Time, method TransactionMethod) error {
|
func (s *resourceService) CancelResource(ctx context.Context, tradeNo string, at time.Time, method trade2.Method) error {
|
||||||
// 删除请求缓存
|
// 删除请求缓存
|
||||||
_, err := rds.Client.Del(ctx, tradeNo).Result()
|
_, err := rds.Client.Del(ctx, tradeNo).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ import (
|
|||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
"platform/pkg/u"
|
"platform/pkg/u"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
|
bill2 "platform/web/domains/bill"
|
||||||
|
coupon2 "platform/web/domains/coupon"
|
||||||
|
trade2 "platform/web/domains/trade"
|
||||||
g "platform/web/globals"
|
g "platform/web/globals"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
@@ -43,7 +46,7 @@ func (s *transactionService) PrepareTransaction(ctx context.Context, q *q.Query,
|
|||||||
coupon, err := q.Coupon.WithContext(ctx).
|
coupon, err := q.Coupon.WithContext(ctx).
|
||||||
Where(
|
Where(
|
||||||
q.Coupon.Code.Eq(data.CouponCode),
|
q.Coupon.Code.Eq(data.CouponCode),
|
||||||
q.Coupon.Status.Eq(0),
|
q.Coupon.Status.Eq(int32(coupon2.StatusUnused)),
|
||||||
).
|
).
|
||||||
Take()
|
Take()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -57,7 +60,7 @@ func (s *transactionService) PrepareTransaction(ctx context.Context, q *q.Query,
|
|||||||
if !expireAt.IsZero() && expireAt.Before(time.Now()) {
|
if !expireAt.IsZero() && expireAt.Before(time.Now()) {
|
||||||
_, err = q.Coupon.
|
_, err = q.Coupon.
|
||||||
Where(q.Coupon.ID.Eq(coupon.ID)).
|
Where(q.Coupon.ID.Eq(coupon.ID)).
|
||||||
Update(q.Coupon.Status, 2)
|
Update(q.Coupon.Status, coupon2.StatusExpired)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -83,7 +86,7 @@ func (s *transactionService) PrepareTransaction(ctx context.Context, q *q.Query,
|
|||||||
if time.Time(coupon.ExpireAt).IsZero() {
|
if time.Time(coupon.ExpireAt).IsZero() {
|
||||||
_, err = q.Coupon.
|
_, err = q.Coupon.
|
||||||
Where(q.Coupon.ID.Eq(coupon.ID)).
|
Where(q.Coupon.ID.Eq(coupon.ID)).
|
||||||
Update(q.Coupon.Status, 1)
|
Update(q.Coupon.Status, int32(coupon2.StatusUsed))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -102,7 +105,7 @@ func (s *transactionService) PrepareTransaction(ctx context.Context, q *q.Query,
|
|||||||
switch method {
|
switch method {
|
||||||
|
|
||||||
// 调用支付宝支付接口
|
// 调用支付宝支付接口
|
||||||
case TransactionMethodAlipay:
|
case trade2.MethodAlipay:
|
||||||
resp, err := g.Alipay.TradePagePay(alipay.TradePagePay{
|
resp, err := g.Alipay.TradePagePay(alipay.TradePagePay{
|
||||||
QRPayMode: "4",
|
QRPayMode: "4",
|
||||||
Trade: alipay.Trade{
|
Trade: alipay.Trade{
|
||||||
@@ -119,7 +122,7 @@ func (s *transactionService) PrepareTransaction(ctx context.Context, q *q.Query,
|
|||||||
payUrl = resp.String()
|
payUrl = resp.String()
|
||||||
|
|
||||||
// 调用微信支付接口
|
// 调用微信支付接口
|
||||||
case TransactionMethodWeChat:
|
case trade2.MethodWeChat:
|
||||||
resp, _, err := g.WechatPay.Native.Prepay(ctx, native.PrepayRequest{
|
resp, _, err := g.WechatPay.Native.Prepay(ctx, native.PrepayRequest{
|
||||||
Appid: &env.WechatPayAppId,
|
Appid: &env.WechatPayAppId,
|
||||||
Mchid: &env.WechatPayMchId,
|
Mchid: &env.WechatPayMchId,
|
||||||
@@ -142,15 +145,12 @@ func (s *transactionService) PrepareTransaction(ctx context.Context, q *q.Query,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 保存交易订单
|
// 保存交易订单
|
||||||
var tradeType int
|
var billType bill2.Type
|
||||||
var billType int
|
|
||||||
switch tType {
|
switch tType {
|
||||||
case TransactionTypeRecharge:
|
case trade2.TypeRecharge:
|
||||||
tradeType = 2
|
billType = bill2.TypeRecharge
|
||||||
billType = 3
|
case trade2.TypePurchase:
|
||||||
case TransactionTypePurchase:
|
billType = bill2.TypeConsume
|
||||||
tradeType = 1
|
|
||||||
billType = 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var trade = m.Trade{
|
var trade = m.Trade{
|
||||||
@@ -158,7 +158,7 @@ func (s *transactionService) PrepareTransaction(ctx context.Context, q *q.Query,
|
|||||||
InnerNo: tradeNo,
|
InnerNo: tradeNo,
|
||||||
Subject: subject,
|
Subject: subject,
|
||||||
Method: int32(method),
|
Method: int32(method),
|
||||||
Type: int32(tradeType),
|
Type: int32(tType),
|
||||||
Amount: amount,
|
Amount: amount,
|
||||||
PayURL: payUrl,
|
PayURL: payUrl,
|
||||||
}
|
}
|
||||||
@@ -202,7 +202,7 @@ func (s *transactionService) VerifyTransaction(ctx context.Context, data *Transa
|
|||||||
switch method {
|
switch method {
|
||||||
|
|
||||||
// 检查支付宝交易
|
// 检查支付宝交易
|
||||||
case TransactionMethodAlipay:
|
case trade2.MethodAlipay:
|
||||||
resp, err := g.Alipay.TradeQuery(ctx, alipay.TradeQuery{
|
resp, err := g.Alipay.TradeQuery(ctx, alipay.TradeQuery{
|
||||||
OutTradeNo: tradeNo,
|
OutTradeNo: tradeNo,
|
||||||
})
|
})
|
||||||
@@ -228,7 +228,7 @@ func (s *transactionService) VerifyTransaction(ctx context.Context, data *Transa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查微信交易
|
// 检查微信交易
|
||||||
case TransactionMethodWeChat:
|
case trade2.MethodWeChat:
|
||||||
resp, _, err := g.WechatPay.Native.QueryOrderByOutTradeNo(ctx, native.QueryOrderByOutTradeNoRequest{
|
resp, _, err := g.WechatPay.Native.QueryOrderByOutTradeNo(ctx, native.QueryOrderByOutTradeNoRequest{
|
||||||
OutTradeNo: &tradeNo,
|
OutTradeNo: &tradeNo,
|
||||||
Mchid: &env.WechatPayMchId,
|
Mchid: &env.WechatPayMchId,
|
||||||
@@ -274,12 +274,12 @@ func (s *transactionService) CompleteTransaction(ctx context.Context, q *q.Query
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查交易状态
|
// 检查交易状态
|
||||||
if trade.Status != 0 {
|
if trade.Status != int32(trade2.StatusPending) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新交易状态
|
// 更新交易状态
|
||||||
trade.Status = 1
|
trade.Status = int32(trade2.StatusSuccess)
|
||||||
trade.OuterNo = transId
|
trade.OuterNo = transId
|
||||||
trade.Payment = payment
|
trade.Payment = payment
|
||||||
trade.PaidAt = core.LocalDateTime(paidAt)
|
trade.PaidAt = core.LocalDateTime(paidAt)
|
||||||
@@ -294,11 +294,11 @@ func (s *transactionService) CompleteTransaction(ctx context.Context, q *q.Query
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *transactionService) RevokeTransaction(ctx context.Context, tradeNo string, method TransactionMethod) error {
|
func (s *transactionService) RevokeTransaction(ctx context.Context, tradeNo string, method trade2.Method) error {
|
||||||
|
|
||||||
switch method {
|
switch method {
|
||||||
|
|
||||||
case TransactionMethodAlipay:
|
case trade2.MethodAlipay:
|
||||||
resp, err := g.Alipay.TradeCancel(ctx, alipay.TradeCancel{
|
resp, err := g.Alipay.TradeCancel(ctx, alipay.TradeCancel{
|
||||||
OutTradeNo: tradeNo,
|
OutTradeNo: tradeNo,
|
||||||
})
|
})
|
||||||
@@ -310,7 +310,7 @@ func (s *transactionService) RevokeTransaction(ctx context.Context, tradeNo stri
|
|||||||
return errors.New("交易取消失败")
|
return errors.New("交易取消失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
case TransactionMethodWeChat:
|
case trade2.MethodWeChat:
|
||||||
resp, err := g.WechatPay.Native.CloseOrder(ctx, native.CloseOrderRequest{
|
resp, err := g.WechatPay.Native.CloseOrder(ctx, native.CloseOrderRequest{
|
||||||
Mchid: &env.WechatPayMchId,
|
Mchid: &env.WechatPayMchId,
|
||||||
OutTradeNo: &tradeNo,
|
OutTradeNo: &tradeNo,
|
||||||
@@ -333,7 +333,7 @@ func (s *transactionService) FinishTransaction(ctx context.Context, q *q.Query,
|
|||||||
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
||||||
Select(q.Trade.Status, q.Trade.CancelAt, q.Trade.PayURL).
|
Select(q.Trade.Status, q.Trade.CancelAt, q.Trade.PayURL).
|
||||||
Updates(m.Trade{
|
Updates(m.Trade{
|
||||||
Status: 2,
|
Status: int32(trade2.StatusCanceled),
|
||||||
CancelAt: core.LocalDateTime(time),
|
CancelAt: core.LocalDateTime(time),
|
||||||
PayURL: "",
|
PayURL: "",
|
||||||
})
|
})
|
||||||
@@ -344,26 +344,12 @@ func (s *transactionService) FinishTransaction(ctx context.Context, q *q.Query,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type TransactionType int32
|
|
||||||
|
|
||||||
const (
|
|
||||||
TransactionTypePurchase TransactionType = iota + 1
|
|
||||||
TransactionTypeRecharge
|
|
||||||
)
|
|
||||||
|
|
||||||
type TransactionMethod int32
|
|
||||||
|
|
||||||
const (
|
|
||||||
TransactionMethodAlipay TransactionMethod = iota
|
|
||||||
TransactionMethodWeChat
|
|
||||||
)
|
|
||||||
|
|
||||||
type TransactionPrepareData struct {
|
type TransactionPrepareData struct {
|
||||||
Subject string
|
Subject string
|
||||||
Amount float64
|
Amount float64
|
||||||
ExpireAt time.Time
|
ExpireAt time.Time
|
||||||
Type TransactionType
|
Type trade2.Type
|
||||||
Method TransactionMethod
|
Method trade2.Method
|
||||||
CouponCode string
|
CouponCode string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,7 +362,7 @@ type TransactionPrepareResult struct {
|
|||||||
|
|
||||||
type TransactionVerifyData struct {
|
type TransactionVerifyData struct {
|
||||||
TradeNo string
|
TradeNo string
|
||||||
Method TransactionMethod
|
Method trade2.Method
|
||||||
}
|
}
|
||||||
|
|
||||||
type TransactionVerifyResult struct {
|
type TransactionVerifyResult struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user