重构项目结构,将 orm 和 rds 包迁移到 web/globals
This commit is contained in:
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
### 长期
|
### 长期
|
||||||
|
|
||||||
- 将 orm 和 rds 迁移到 web/globals 中
|
- 分离项目脚手架(env,logs,Server 结构体)
|
||||||
- 业务代码和测试代码共用的控制变量可以优化为环境变量
|
- 业务代码和测试代码共用的控制变量可以优化为环境变量
|
||||||
- 考虑统计接口调用频率并通过接口展示
|
- 考虑统计接口调用频率并通过接口展示
|
||||||
- 考虑登录时曾经输入过验证码的用户,登录成功后允许一段时间内免输验证码
|
- 考虑登录时曾经输入过验证码的用户,登录成功后允许一段时间内免输验证码
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"gorm.io/driver/postgres"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
"platform/pkg/logs"
|
"platform/pkg/logs"
|
||||||
"platform/pkg/orm"
|
|
||||||
client2 "platform/web/domains/client"
|
client2 "platform/web/domains/client"
|
||||||
proxy2 "platform/web/domains/proxy"
|
proxy2 "platform/web/domains/proxy"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
@@ -13,11 +16,29 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
env.Init()
|
env.Init()
|
||||||
logs.Init()
|
logs.Init()
|
||||||
orm.Init()
|
|
||||||
|
|
||||||
err := q.Q.Transaction(func(tx *q.Query) (err error) {
|
// 初始化数据库连接
|
||||||
|
dsn := fmt.Sprintf(
|
||||||
|
"host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Shanghai",
|
||||||
|
env.DbHost, env.DbUserName, env.DbPassword, env.DbName, env.DbPort,
|
||||||
|
)
|
||||||
|
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
|
||||||
|
NamingStrategy: schema.NamingStrategy{
|
||||||
|
SingularTable: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("gorm 初始化数据库失败:", slog.Any("err", err))
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
q.SetDefault(db)
|
||||||
|
|
||||||
|
// 填充数据
|
||||||
|
err = q.Q.Transaction(func(tx *q.Query) (err error) {
|
||||||
|
|
||||||
// 代理
|
// 代理
|
||||||
err = q.Proxy.
|
err = q.Proxy.
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
"platform/pkg/logs"
|
"platform/pkg/logs"
|
||||||
"platform/pkg/orm"
|
|
||||||
"platform/pkg/rds"
|
|
||||||
"platform/web"
|
"platform/web"
|
||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
@@ -18,13 +16,11 @@ func main() {
|
|||||||
shutdown := make(chan os.Signal, 1)
|
shutdown := make(chan os.Signal, 1)
|
||||||
signal.Notify(shutdown, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(shutdown, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
// init 先后顺序有依赖
|
// 初始化应用
|
||||||
env.Init()
|
env.Init()
|
||||||
logs.Init()
|
logs.Init()
|
||||||
orm.Init()
|
|
||||||
rds.Init()
|
|
||||||
|
|
||||||
// web 服务
|
// 创建服务
|
||||||
app, err := web.New(&web.Config{
|
app, err := web.New(&web.Config{
|
||||||
Listen: ":8080",
|
Listen: ":8080",
|
||||||
})
|
})
|
||||||
@@ -33,10 +29,11 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 异步运行服务
|
||||||
errCh := make(chan error)
|
errCh := make(chan error)
|
||||||
defer close(errCh)
|
defer close(errCh)
|
||||||
go func() {
|
go func() {
|
||||||
err = app.Run()
|
err := app.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("Failed to run server", slog.Any("err", err))
|
slog.Error("Failed to run server", slog.Any("err", err))
|
||||||
errCh <- err
|
errCh <- err
|
||||||
@@ -45,32 +42,14 @@ func main() {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// 关闭服务
|
// 关闭服务
|
||||||
exit := false
|
|
||||||
select {
|
select {
|
||||||
|
case err = <-errCh:
|
||||||
case <-shutdown:
|
case <-shutdown:
|
||||||
slog.Info("Received shutdown signal")
|
slog.Info("Received shutdown signal")
|
||||||
app.Stop()
|
app.Stop()
|
||||||
exit = true
|
err = <-errCh
|
||||||
case err := <-errCh:
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("Server error", slog.Any("err", err))
|
slog.Error("Server error", slog.Any("err", err))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if exit {
|
|
||||||
err := <-errCh
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("Server error", slog.Any("err", err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭资源
|
|
||||||
err = orm.Exit()
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("Failed to close database connection", slog.Any("err", err))
|
|
||||||
}
|
|
||||||
err = rds.Exit()
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("Failed to close redis connection", slog.Any("err", err))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
10
pkg/env/env.go
vendored
10
pkg/env/env.go
vendored
@@ -268,7 +268,6 @@ var (
|
|||||||
WechatPayPublicKey string
|
WechatPayPublicKey string
|
||||||
WechatPayApiCert string
|
WechatPayApiCert string
|
||||||
WechatPayCallbackUrl string
|
WechatPayCallbackUrl string
|
||||||
WechatPayProduction = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadWechatPay() {
|
func loadWechatPay() {
|
||||||
@@ -312,15 +311,6 @@ func loadWechatPay() {
|
|||||||
if WechatPayCallbackUrl == "" {
|
if WechatPayCallbackUrl == "" {
|
||||||
panic("环境变量 WECHATPAY_CALLBACK_URL 的值不能为空")
|
panic("环境变量 WECHATPAY_CALLBACK_URL 的值不能为空")
|
||||||
}
|
}
|
||||||
|
|
||||||
_WechatPayProduction := os.Getenv("WECHATPAY_PRODUCTION")
|
|
||||||
if _WechatPayProduction != "" {
|
|
||||||
value, err := strconv.ParseBool(_WechatPayProduction)
|
|
||||||
if err != nil {
|
|
||||||
panic("环境变量 WECHATPAY_PRODUCTION 的值不是布尔值")
|
|
||||||
}
|
|
||||||
WechatPayProduction = value
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"platform/pkg/rds"
|
g "platform/web/globals"
|
||||||
)
|
)
|
||||||
|
|
||||||
func find(ctx context.Context, token string) (*Context, error) {
|
func find(ctx context.Context, token string) (*Context, error) {
|
||||||
|
|
||||||
// 读取认证数据
|
// 读取认证数据
|
||||||
authJSON, err := rds.Client.Get(ctx, accessKey(token)).Result()
|
authJSON, err := g.Redis.Get(ctx, accessKey(token)).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, redis.Nil) {
|
if errors.Is(err, redis.Nil) {
|
||||||
return nil, errors.New("invalid_token")
|
return nil, errors.New("invalid_token")
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
var Alipay *alipay.Client
|
var Alipay *alipay.Client
|
||||||
|
|
||||||
func InitAlipay() {
|
func initAlipay() {
|
||||||
var client, err = alipay.New(
|
var client, err = alipay.New(
|
||||||
env.AlipayAppId,
|
env.AlipayAppId,
|
||||||
env.AlipayAppPrivateKey,
|
env.AlipayAppPrivateKey,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type aliyunClient struct {
|
|||||||
Sms *sms.Client
|
Sms *sms.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitAliyun() {
|
func initAliyun() {
|
||||||
client, err := sms.NewClient(&openapi.Config{
|
client, err := sms.NewClient(&openapi.Config{
|
||||||
AccessKeyId: &env.AliyunAccessKey,
|
AccessKeyId: &env.AliyunAccessKey,
|
||||||
AccessKeySecret: &env.AliyunAccessKeySecret,
|
AccessKeySecret: &env.AliyunAccessKeySecret,
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"net/url"
|
"net/url"
|
||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
"platform/pkg/rds"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -36,7 +35,7 @@ type cloud struct {
|
|||||||
|
|
||||||
var Cloud CloudClient
|
var Cloud CloudClient
|
||||||
|
|
||||||
func InitBaiyin() {
|
func initBaiyin() {
|
||||||
Cloud = &cloud{
|
Cloud = &cloud{
|
||||||
url: env.BaiyinAddr,
|
url: env.BaiyinAddr,
|
||||||
}
|
}
|
||||||
@@ -304,7 +303,7 @@ func (c *cloud) requestCloud(method string, url string, data string) (*http.Resp
|
|||||||
func (c *cloud) token(refresh bool) (string, error) {
|
func (c *cloud) token(refresh bool) (string, error) {
|
||||||
// redis 获取令牌
|
// redis 获取令牌
|
||||||
if !refresh {
|
if !refresh {
|
||||||
token, err := rds.Client.Get(context.Background(), "remote:token").Result()
|
token, err := Redis.Get(context.Background(), "remote:token").Result()
|
||||||
if err == nil && token != "" {
|
if err == nil && token != "" {
|
||||||
return token, nil
|
return token, nil
|
||||||
}
|
}
|
||||||
@@ -347,7 +346,7 @@ func (c *cloud) token(refresh bool) (string, error) {
|
|||||||
|
|
||||||
// redis 设置令牌
|
// redis 设置令牌
|
||||||
token := result["token"].(string)
|
token := result["token"].(string)
|
||||||
err = rds.Client.Set(context.Background(), "remote:token", token, 1*time.Hour).Err()
|
err = Redis.Set(context.Background(), "remote:token", token, 1*time.Hour).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -521,6 +520,7 @@ func (c *gateway) GatewayPortActive(param ...PortActiveReq) (map[string]PortData
|
|||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
func (c *gateway) requestGateway(method string, url string, data string) (*http.Response, error) {
|
func (c *gateway) requestGateway(method string, url string, data string) (*http.Response, error) {
|
||||||
|
//goland:noinspection ALL
|
||||||
url = fmt.Sprintf("http://%s:%s@%s:9990%s", c.username, c.password, c.url, url)
|
url = fmt.Sprintf("http://%s:%s@%s:9990%s", c.username, c.password, c.url, url)
|
||||||
req, err := http.NewRequest(method, url, strings.NewReader(data))
|
req, err := http.NewRequest(method, url, strings.NewReader(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
11
web/globals/init.go
Normal file
11
web/globals/init.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package globals
|
||||||
|
|
||||||
|
func Init() {
|
||||||
|
initBaiyin()
|
||||||
|
initAlipay()
|
||||||
|
initWechatPay()
|
||||||
|
initAliyun()
|
||||||
|
initValidator()
|
||||||
|
initRedis()
|
||||||
|
initOrm()
|
||||||
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
package orm
|
package globals
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"gorm.io/driver/postgres"
|
"gorm.io/driver/postgres"
|
||||||
"gorm.io/gen"
|
|
||||||
"gorm.io/gen/field"
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/schema"
|
"gorm.io/gorm/schema"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
@@ -13,7 +11,7 @@ import (
|
|||||||
|
|
||||||
var DB *gorm.DB
|
var DB *gorm.DB
|
||||||
|
|
||||||
func Init() {
|
func initOrm() {
|
||||||
|
|
||||||
// 连接数据库
|
// 连接数据库
|
||||||
dsn := fmt.Sprintf(
|
dsn := fmt.Sprintf(
|
||||||
@@ -43,7 +41,7 @@ func Init() {
|
|||||||
DB = db
|
DB = db
|
||||||
}
|
}
|
||||||
|
|
||||||
func Exit() error {
|
func ExitOrm() error {
|
||||||
if DB != nil {
|
if DB != nil {
|
||||||
conn, err := DB.DB()
|
conn, err := DB.DB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -53,13 +51,3 @@ func Exit() error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type WithAlias interface {
|
|
||||||
Alias() string
|
|
||||||
}
|
|
||||||
|
|
||||||
func Alias(model WithAlias) func(db gen.Dao) gen.Dao {
|
|
||||||
return func(db gen.Dao) gen.Dao {
|
|
||||||
return db.Unscoped().Where(field.NewBool(model.Alias(), "deleted_at").IsNull())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
16
web/globals/orm/alias.go
Normal file
16
web/globals/orm/alias.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package orm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gen"
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WithAlias interface {
|
||||||
|
Alias() string
|
||||||
|
}
|
||||||
|
|
||||||
|
func Alias(model WithAlias) func(db gen.Dao) gen.Dao {
|
||||||
|
return func(db gen.Dao) gen.Dao {
|
||||||
|
return db.Unscoped().Where(field.NewBool(model.Alias(), "deleted_at").IsNull())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package rds
|
package globals
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
@@ -7,19 +7,19 @@ import (
|
|||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Client *redis.Client
|
var Redis *redis.Client
|
||||||
|
|
||||||
func Init() {
|
func initRedis() {
|
||||||
Client = redis.NewClient(&redis.Options{
|
Redis = redis.NewClient(&redis.Options{
|
||||||
Addr: net.JoinHostPort(env.RedisHost, env.RedisPort),
|
Addr: net.JoinHostPort(env.RedisHost, env.RedisPort),
|
||||||
DB: env.RedisDb,
|
DB: env.RedisDb,
|
||||||
Password: env.RedisPass,
|
Password: env.RedisPass,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Exit() error {
|
func ExitRedis() error {
|
||||||
if Client != nil {
|
if Redis != nil {
|
||||||
return Client.Close()
|
return Redis.Close()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -2,23 +2,22 @@ package globals
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/go-playground/locales/zh"
|
"github.com/go-playground/locales/zh"
|
||||||
ut "github.com/go-playground/universal-translator"
|
ut "github.com/go-playground/universal-translator"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
zhtrans "github.com/go-playground/validator/v10/translations/zh"
|
zhtrans "github.com/go-playground/validator/v10/translations/zh"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Validator *ValidatorHolder
|
var Validator *ValidatorClient
|
||||||
|
|
||||||
type ValidatorHolder struct {
|
type ValidatorClient struct {
|
||||||
validator *validator.Validate
|
validator *validator.Validate
|
||||||
translator ut.Translator
|
translator ut.Translator
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *ValidatorHolder) Validate(c *fiber.Ctx, data any) error {
|
func (v *ValidatorClient) Validate(c *fiber.Ctx, data any) error {
|
||||||
|
|
||||||
if err := c.BodyParser(data); err != nil {
|
if err := c.BodyParser(data); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -39,7 +38,7 @@ func (v *ValidatorHolder) Validate(c *fiber.Ctx, data any) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitValidator() {
|
func initValidator() {
|
||||||
var validate = validator.New(validator.WithRequiredStructEnabled())
|
var validate = validator.New(validator.WithRequiredStructEnabled())
|
||||||
|
|
||||||
var translator = ut.New(zh.New()).GetFallback()
|
var translator = ut.New(zh.New()).GetFallback()
|
||||||
@@ -48,7 +47,7 @@ func InitValidator() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
Validator = &ValidatorHolder{
|
Validator = &ValidatorClient{
|
||||||
validator: validate,
|
validator: validate,
|
||||||
translator: translator,
|
translator: translator,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ type WechatPayClient struct {
|
|||||||
Notify *notify.Handler
|
Notify *notify.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitWechatPay() {
|
func initWechatPay() {
|
||||||
|
|
||||||
// 加载商户私钥
|
// 加载商户私钥
|
||||||
private, err := base64.StdEncoding.DecodeString(env.WechatPayMchPrivateKey)
|
private, err := base64.StdEncoding.DecodeString(env.WechatPayMchPrivateKey)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
|
"platform/web/globals/orm"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ package handlers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"platform/pkg/orm"
|
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
channel2 "platform/web/domains/channel"
|
channel2 "platform/web/domains/channel"
|
||||||
|
"platform/web/globals/orm"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
s "platform/web/services"
|
s "platform/web/services"
|
||||||
"time"
|
"time"
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
"platform/pkg/rds"
|
|
||||||
"platform/pkg/u"
|
"platform/pkg/u"
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
|
g "platform/web/globals"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"platform/web/services"
|
"platform/web/services"
|
||||||
@@ -87,7 +87,7 @@ func Identify(c *fiber.Ctx) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = rds.Client.Set(c.Context(), idenKey(id), infoStr, 30*time.Minute).Err()
|
err = g.Redis.Set(c.Context(), idenKey(id), infoStr, 30*time.Minute).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ func IdentifyCallback(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取 token
|
// 获取 token
|
||||||
infoStr, err := rds.Client.Get(c.Context(), idenKey(req.Id)).Result()
|
infoStr, err := g.Redis.Get(c.Context(), idenKey(req.Id)).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, redis.Nil) {
|
if errors.Is(err, redis.Nil) {
|
||||||
return c.JSON(IdentifyCallbackRes{
|
return c.JSON(IdentifyCallbackRes{
|
||||||
@@ -179,7 +179,7 @@ func IdentifyCallback(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 删除认证中间状态
|
// 删除认证中间状态
|
||||||
err = rds.Client.Del(c.Context(), idenKey(req.Id)).Err()
|
err = g.Redis.Del(c.Context(), idenKey(req.Id)).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
|
||||||
"platform/pkg/u"
|
"platform/pkg/u"
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
resource2 "platform/web/domains/resource"
|
resource2 "platform/web/domains/resource"
|
||||||
trade2 "platform/web/domains/trade"
|
trade2 "platform/web/domains/trade"
|
||||||
|
"platform/web/globals/orm"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
s "platform/web/services"
|
s "platform/web/services"
|
||||||
"time"
|
"time"
|
||||||
@@ -112,7 +112,7 @@ func AllResource(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
// 查询套餐列表
|
// 查询套餐列表
|
||||||
pss := q.ResourcePss.As(q.Resource.Pss.Name())
|
pss := q.ResourcePss.As(q.Resource.Pss.Name())
|
||||||
do := q.Resource.Debug().
|
do := q.Resource.
|
||||||
Joins(q.Resource.Pss).
|
Joins(q.Resource.Pss).
|
||||||
Where(
|
Where(
|
||||||
q.Resource.UserID.Eq(authContext.Payload.Id),
|
q.Resource.UserID.Eq(authContext.Payload.Id),
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import "platform/pkg/orm"
|
import (
|
||||||
|
"platform/web/globals/orm"
|
||||||
|
)
|
||||||
|
|
||||||
const TableNameLogsRequest = "logs_request"
|
const TableNameLogsRequest = "logs_request"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import "platform/pkg/orm"
|
import (
|
||||||
|
"platform/web/globals/orm"
|
||||||
|
)
|
||||||
|
|
||||||
const TableNameResourcePsr = "resource_psr"
|
const TableNameResourcePsr = "resource_psr"
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import "platform/pkg/orm"
|
import (
|
||||||
|
"platform/web/globals/orm"
|
||||||
|
)
|
||||||
|
|
||||||
const TableNameResourcePss = "resource_pss"
|
const TableNameResourcePss = "resource_pss"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
"platform/web/globals/orm"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package services
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"platform/pkg/orm"
|
|
||||||
auth2 "platform/web/auth"
|
auth2 "platform/web/auth"
|
||||||
client2 "platform/web/domains/client"
|
client2 "platform/web/domains/client"
|
||||||
|
"platform/web/globals/orm"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"time"
|
"time"
|
||||||
|
|||||||
@@ -10,14 +10,13 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"math/rand/v2"
|
"math/rand/v2"
|
||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
"platform/pkg/orm"
|
|
||||||
"platform/pkg/rds"
|
|
||||||
"platform/pkg/u"
|
"platform/pkg/u"
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
channel2 "platform/web/domains/channel"
|
channel2 "platform/web/domains/channel"
|
||||||
proxy2 "platform/web/domains/proxy"
|
proxy2 "platform/web/domains/proxy"
|
||||||
g "platform/web/globals"
|
g "platform/web/globals"
|
||||||
|
"platform/web/globals/orm"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -652,7 +651,7 @@ func cache(ctx context.Context, channels []*m.Channel) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe := rds.Client.TxPipeline()
|
pipe := g.Redis.TxPipeline()
|
||||||
|
|
||||||
zList := make([]redis.Z, 0, len(channels))
|
zList := make([]redis.Z, 0, len(channels))
|
||||||
for _, channel := range channels {
|
for _, channel := range channels {
|
||||||
@@ -686,7 +685,7 @@ func deleteCache(ctx context.Context, channels []*m.Channel) error {
|
|||||||
for i := range channels {
|
for i := range channels {
|
||||||
keys[i] = chKey(channels[i])
|
keys[i] = chKey(channels[i])
|
||||||
}
|
}
|
||||||
_, err := rds.Client.Del(ctx, keys...).Result()
|
_, err := g.Redis.Del(ctx, keys...).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"platform/pkg/orm"
|
|
||||||
"platform/pkg/testutil"
|
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
g "platform/web/globals"
|
g "platform/web/globals"
|
||||||
|
"platform/web/globals/orm"
|
||||||
"platform/web/models"
|
"platform/web/models"
|
||||||
|
testutil2 "platform/web/testutil"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -101,7 +101,7 @@ func Test_chKey(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_cache(t *testing.T) {
|
func Test_cache(t *testing.T) {
|
||||||
mr := testutil.SetupRedisTest(t)
|
mr := testutil2.SetupRedisTest(t)
|
||||||
|
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
@@ -202,7 +202,7 @@ func Test_cache(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_deleteCache(t *testing.T) {
|
func Test_deleteCache(t *testing.T) {
|
||||||
mr := testutil.SetupRedisTest(t)
|
mr := testutil2.SetupRedisTest(t)
|
||||||
|
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
@@ -270,10 +270,10 @@ func Test_deleteCache(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_channelService_CreateChannel(t *testing.T) {
|
func Test_channelService_CreateChannel(t *testing.T) {
|
||||||
mr := testutil.SetupRedisTest(t)
|
mr := testutil2.SetupRedisTest(t)
|
||||||
db := testutil.SetupDBTest(t)
|
db := testutil2.SetupDBTest(t)
|
||||||
mc := testutil.SetupCloudClientMock(t)
|
mc := testutil2.SetupCloudClientMock(t)
|
||||||
mg := testutil.SetupGatewayClientMock(t)
|
mg := testutil2.SetupGatewayClientMock(t)
|
||||||
|
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
@@ -390,7 +390,7 @@ func Test_channelService_CreateChannel(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
mg.PortConfigsMock = func(c *testutil.MockGatewayClient, params []g.PortConfigsReq) error {
|
mg.PortConfigsMock = func(c *testutil2.MockGatewayClient, params []g.PortConfigsReq) error {
|
||||||
if c.Host != proxy.Host {
|
if c.Host != proxy.Host {
|
||||||
return fmt.Errorf("代理主机不符合预期: %s", c.Host)
|
return fmt.Errorf("代理主机不符合预期: %s", c.Host)
|
||||||
}
|
}
|
||||||
@@ -540,7 +540,7 @@ func Test_channelService_CreateChannel(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
mg.PortConfigsMock = func(c *testutil.MockGatewayClient, params []g.PortConfigsReq) error {
|
mg.PortConfigsMock = func(c *testutil2.MockGatewayClient, params []g.PortConfigsReq) error {
|
||||||
if c.Host != proxy.Host {
|
if c.Host != proxy.Host {
|
||||||
return fmt.Errorf("代理主机不符合预期: %s", c.Host)
|
return fmt.Errorf("代理主机不符合预期: %s", c.Host)
|
||||||
}
|
}
|
||||||
@@ -684,7 +684,7 @@ func Test_channelService_CreateChannel(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
mg.PortConfigsMock = func(c *testutil.MockGatewayClient, params []g.PortConfigsReq) error {
|
mg.PortConfigsMock = func(c *testutil2.MockGatewayClient, params []g.PortConfigsReq) error {
|
||||||
if c.Host != proxy.Host {
|
if c.Host != proxy.Host {
|
||||||
return fmt.Errorf("代理主机不符合预期: %s", c.Host)
|
return fmt.Errorf("代理主机不符合预期: %s", c.Host)
|
||||||
}
|
}
|
||||||
@@ -961,10 +961,10 @@ func Test_channelService_CreateChannel(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_channelService_RemoveChannels(t *testing.T) {
|
func Test_channelService_RemoveChannels(t *testing.T) {
|
||||||
mr := testutil.SetupRedisTest(t)
|
mr := testutil2.SetupRedisTest(t)
|
||||||
md := testutil.SetupDBTest(t)
|
md := testutil2.SetupDBTest(t)
|
||||||
mg := testutil.SetupGatewayClientMock(t)
|
mg := testutil2.SetupGatewayClientMock(t)
|
||||||
mc := testutil.SetupCloudClientMock(t)
|
mc := testutil2.SetupCloudClientMock(t)
|
||||||
|
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
@@ -1055,7 +1055,7 @@ func Test_channelService_RemoveChannels(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 模拟网关客户端的响应
|
// 模拟网关客户端的响应
|
||||||
mg.PortActiveMock = func(m *testutil.MockGatewayClient, param ...g.PortActiveReq) (map[string]g.PortData, error) {
|
mg.PortActiveMock = func(m *testutil2.MockGatewayClient, param ...g.PortActiveReq) (map[string]g.PortData, error) {
|
||||||
switch {
|
switch {
|
||||||
case m.Host == proxy.Host:
|
case m.Host == proxy.Host:
|
||||||
return map[string]g.PortData{
|
return map[string]g.PortData{
|
||||||
@@ -1069,7 +1069,7 @@ func Test_channelService_RemoveChannels(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return nil, fmt.Errorf("代理主机不符合预期: %s", m.Host)
|
return nil, fmt.Errorf("代理主机不符合预期: %s", m.Host)
|
||||||
}
|
}
|
||||||
mg.PortConfigsMock = func(m *testutil.MockGatewayClient, params []g.PortConfigsReq) error {
|
mg.PortConfigsMock = func(m *testutil2.MockGatewayClient, params []g.PortConfigsReq) error {
|
||||||
switch {
|
switch {
|
||||||
case m.Host == proxy.Host:
|
case m.Host == proxy.Host:
|
||||||
for _, param := range params {
|
for _, param := range params {
|
||||||
@@ -1104,7 +1104,7 @@ func Test_channelService_RemoveChannels(t *testing.T) {
|
|||||||
switch {
|
switch {
|
||||||
case param.Uuid == proxy.Name:
|
case param.Uuid == proxy.Name:
|
||||||
var edges = []string{"edge1", "edge2", "edge4"}
|
var edges = []string{"edge1", "edge2", "edge4"}
|
||||||
if !testutil.SliceEqual(edges, param.Edge) {
|
if !testutil2.SliceEqual(edges, param.Edge) {
|
||||||
return 0, fmt.Errorf("边缘节点不符合预期3: %v", param.Edge)
|
return 0, fmt.Errorf("边缘节点不符合预期3: %v", param.Edge)
|
||||||
}
|
}
|
||||||
if len(param.Config) != 0 {
|
if len(param.Config) != 0 {
|
||||||
@@ -1113,7 +1113,7 @@ func Test_channelService_RemoveChannels(t *testing.T) {
|
|||||||
return len(param.Edge), nil
|
return len(param.Edge), nil
|
||||||
case param.Uuid == proxy2.Name:
|
case param.Uuid == proxy2.Name:
|
||||||
var edges = []string{"edge3"}
|
var edges = []string{"edge3"}
|
||||||
if !testutil.SliceEqual(edges, param.Edge) {
|
if !testutil2.SliceEqual(edges, param.Edge) {
|
||||||
return 0, fmt.Errorf("边缘节点不符合预期4: %v", param.Edge)
|
return 0, fmt.Errorf("边缘节点不符合预期4: %v", param.Edge)
|
||||||
}
|
}
|
||||||
if len(param.Config) != 0 {
|
if len(param.Config) != 0 {
|
||||||
@@ -1169,7 +1169,7 @@ func Test_channelService_RemoveChannels(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 模拟网关客户端的响应
|
// 模拟网关客户端的响应
|
||||||
mg.PortActiveMock = func(m *testutil.MockGatewayClient, param ...g.PortActiveReq) (map[string]g.PortData, error) {
|
mg.PortActiveMock = func(m *testutil2.MockGatewayClient, param ...g.PortActiveReq) (map[string]g.PortData, error) {
|
||||||
switch {
|
switch {
|
||||||
case m.Host == proxy.Host:
|
case m.Host == proxy.Host:
|
||||||
return map[string]g.PortData{
|
return map[string]g.PortData{
|
||||||
@@ -1183,7 +1183,7 @@ func Test_channelService_RemoveChannels(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return nil, fmt.Errorf("代理主机不符合预期: %s", m.Host)
|
return nil, fmt.Errorf("代理主机不符合预期: %s", m.Host)
|
||||||
}
|
}
|
||||||
mg.PortConfigsMock = func(m *testutil.MockGatewayClient, params []g.PortConfigsReq) error {
|
mg.PortConfigsMock = func(m *testutil2.MockGatewayClient, params []g.PortConfigsReq) error {
|
||||||
switch {
|
switch {
|
||||||
case m.Host == proxy.Host:
|
case m.Host == proxy.Host:
|
||||||
for _, param := range params {
|
for _, param := range params {
|
||||||
@@ -1218,7 +1218,7 @@ func Test_channelService_RemoveChannels(t *testing.T) {
|
|||||||
switch {
|
switch {
|
||||||
case param.Uuid == proxy.Name:
|
case param.Uuid == proxy.Name:
|
||||||
var edges = []string{"edge1", "edge2", "edge4"}
|
var edges = []string{"edge1", "edge2", "edge4"}
|
||||||
if !testutil.SliceEqual(edges, param.Edge) {
|
if !testutil2.SliceEqual(edges, param.Edge) {
|
||||||
return 0, fmt.Errorf("边缘节点不符合预期7: %v", param.Edge)
|
return 0, fmt.Errorf("边缘节点不符合预期7: %v", param.Edge)
|
||||||
}
|
}
|
||||||
if len(param.Config) != 0 {
|
if len(param.Config) != 0 {
|
||||||
@@ -1227,7 +1227,7 @@ func Test_channelService_RemoveChannels(t *testing.T) {
|
|||||||
return len(param.Edge), nil
|
return len(param.Edge), nil
|
||||||
case param.Uuid == proxy2.Name:
|
case param.Uuid == proxy2.Name:
|
||||||
var edges = []string{"edge3"}
|
var edges = []string{"edge3"}
|
||||||
if !testutil.SliceEqual(edges, param.Edge) {
|
if !testutil2.SliceEqual(edges, param.Edge) {
|
||||||
return 0, fmt.Errorf("边缘节点不符合预期8: %v", param.Edge)
|
return 0, fmt.Errorf("边缘节点不符合预期8: %v", param.Edge)
|
||||||
}
|
}
|
||||||
if len(param.Config) != 0 {
|
if len(param.Config) != 0 {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"platform/pkg/rds"
|
g "platform/web/globals"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -50,7 +50,7 @@ func (s *IdService) GenSerial(ctx context.Context) (string, error) {
|
|||||||
|
|
||||||
// 使用Redis事务确保原子操作
|
// 使用Redis事务确保原子操作
|
||||||
var sequence int64
|
var sequence int64
|
||||||
err := rds.Client.Watch(ctx, func(tx *redis.Tx) error {
|
err := g.Redis.Watch(ctx, func(tx *redis.Tx) error {
|
||||||
|
|
||||||
// 获取当前序列号
|
// 获取当前序列号
|
||||||
currentVal, err := tx.Get(ctx, key).Int64()
|
currentVal, err := tx.Get(ctx, key).Int64()
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"platform/pkg/orm"
|
g "platform/web/globals"
|
||||||
"platform/web/models"
|
m "platform/web/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NodeServiceErr string
|
type NodeServiceErr string
|
||||||
@@ -16,7 +16,7 @@ var Node = &nodeService{}
|
|||||||
|
|
||||||
type nodeService struct{}
|
type nodeService struct{}
|
||||||
|
|
||||||
func (s *nodeService) Filter(ctx context.Context, userId int32, count int, config ...NodeFilterConfig) ([]*models.Node, error) {
|
func (s *nodeService) Filter(ctx context.Context, userId int32, count int, config ...NodeFilterConfig) ([]*m.Node, error) {
|
||||||
_config := NodeFilterConfig{}
|
_config := NodeFilterConfig{}
|
||||||
if len(config) > 0 {
|
if len(config) > 0 {
|
||||||
_config = config[0]
|
_config = config[0]
|
||||||
@@ -26,7 +26,7 @@ func (s *nodeService) Filter(ctx context.Context, userId int32, count int, confi
|
|||||||
// 静态条件:省,市,运营商
|
// 静态条件:省,市,运营商
|
||||||
// 排序方式,1.分配给该用户的次数 2.分配给全部用户的次数 3.todo 节点的健康状态
|
// 排序方式,1.分配给该用户的次数 2.分配给全部用户的次数 3.todo 节点的健康状态
|
||||||
var nodes []*FilteredNode
|
var nodes []*FilteredNode
|
||||||
orm.DB.Raw(filterSqlRaw, userId, _config.Isp, _config.Prov, _config.City).
|
g.DB.Raw(filterSqlRaw, userId, _config.Isp, _config.Prov, _config.City).
|
||||||
Limit(count).
|
Limit(count).
|
||||||
Find(&nodes)
|
Find(&nodes)
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"platform/pkg/orm"
|
|
||||||
"platform/pkg/rds"
|
|
||||||
bill2 "platform/web/domains/bill"
|
bill2 "platform/web/domains/bill"
|
||||||
resource2 "platform/web/domains/resource"
|
resource2 "platform/web/domains/resource"
|
||||||
trade2 "platform/web/domains/trade"
|
trade2 "platform/web/domains/trade"
|
||||||
|
g "platform/web/globals"
|
||||||
|
"platform/web/globals/orm"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -52,7 +52,7 @@ func (s *resourceService) PrepareResource(ctx context.Context, data *CreateResou
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = rds.Client.Set(ctx, result.TradeNo, reqStr, 30*time.Minute).Err()
|
err = g.Redis.Set(ctx, result.TradeNo, reqStr, 30*time.Minute).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ func (s *resourceService) PrepareResource(ctx context.Context, data *CreateResou
|
|||||||
func (s *resourceService) CompleteResource(ctx context.Context, tradeNo string, rs *TransactionVerifyResult) error {
|
func (s *resourceService) CompleteResource(ctx context.Context, tradeNo string, rs *TransactionVerifyResult) error {
|
||||||
|
|
||||||
// 获取请求缓存
|
// 获取请求缓存
|
||||||
reqStr, err := rds.Client.Get(ctx, tradeNo).Result()
|
reqStr, err := g.Redis.Get(ctx, tradeNo).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ func (s *resourceService) CompleteResource(ctx context.Context, tradeNo string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 删除缓存
|
// 删除缓存
|
||||||
err = rds.Client.Del(ctx, tradeNo).Err()
|
err = g.Redis.Del(ctx, tradeNo).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -265,7 +265,7 @@ func createResource(q *q.Query, data *CreateResourceData, uid int32) (*m.Resourc
|
|||||||
|
|
||||||
func (s *resourceService) CancelResource(ctx context.Context, tradeNo string, at time.Time, method trade2.Method) 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 := g.Redis.Del(ctx, tradeNo).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
"platform/pkg/rds"
|
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
|
g "platform/web/globals"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@@ -45,7 +45,7 @@ type sessionService struct{}
|
|||||||
func (s *sessionService) Find(ctx context.Context, token string) (*auth.Context, error) {
|
func (s *sessionService) Find(ctx context.Context, token string) (*auth.Context, error) {
|
||||||
|
|
||||||
// 读取认证数据
|
// 读取认证数据
|
||||||
authJSON, err := rds.Client.Get(ctx, accessKey(token)).Result()
|
authJSON, err := g.Redis.Get(ctx, accessKey(token)).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, redis.Nil) {
|
if errors.Is(err, redis.Nil) {
|
||||||
return nil, ErrInvalidToken
|
return nil, ErrInvalidToken
|
||||||
@@ -89,7 +89,7 @@ func (s *sessionService) Create(ctx context.Context, authCtx auth.Context, remem
|
|||||||
var accessExpire = time.Duration(env.SessionAccessExpire) * time.Second
|
var accessExpire = time.Duration(env.SessionAccessExpire) * time.Second
|
||||||
var refreshExpire = time.Duration(env.SessionRefreshExpire) * time.Second
|
var refreshExpire = time.Duration(env.SessionRefreshExpire) * time.Second
|
||||||
|
|
||||||
pipe := rds.Client.TxPipeline()
|
pipe := g.Redis.TxPipeline()
|
||||||
pipe.Set(ctx, accessKey(accessToken), authData, accessExpire)
|
pipe.Set(ctx, accessKey(accessToken), authData, accessExpire)
|
||||||
if remember {
|
if remember {
|
||||||
pipe.Set(ctx, refreshKey(refreshToken), refreshData, refreshExpire)
|
pipe.Set(ctx, refreshKey(refreshToken), refreshData, refreshExpire)
|
||||||
@@ -116,7 +116,7 @@ func (s *sessionService) Refresh(ctx context.Context, refreshToken string) (*Tok
|
|||||||
var tokenDetails *TokenDetails
|
var tokenDetails *TokenDetails
|
||||||
|
|
||||||
// 刷新令牌
|
// 刷新令牌
|
||||||
err := rds.Client.Watch(ctx, func(tx *redis.Tx) error {
|
err := g.Redis.Watch(ctx, func(tx *redis.Tx) error {
|
||||||
|
|
||||||
// 先获取刷新令牌数据
|
// 先获取刷新令牌数据
|
||||||
refreshJson, err := tx.Get(ctx, rKey).Result()
|
refreshJson, err := tx.Get(ctx, rKey).Result()
|
||||||
@@ -185,7 +185,7 @@ func (s *sessionService) Refresh(ctx context.Context, refreshToken string) (*Tok
|
|||||||
|
|
||||||
// Remove 删除会话
|
// Remove 删除会话
|
||||||
func (s *sessionService) Remove(ctx context.Context, accessToken, refreshToken string) error {
|
func (s *sessionService) Remove(ctx context.Context, accessToken, refreshToken string) error {
|
||||||
rds.Client.Del(ctx, accessKey(accessToken), refreshKey(refreshToken))
|
g.Redis.Del(ctx, accessKey(accessToken), refreshKey(refreshToken))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package services
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"platform/pkg/testutil"
|
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
|
"platform/web/testutil"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
"platform/pkg/orm"
|
|
||||||
"platform/pkg/u"
|
"platform/pkg/u"
|
||||||
bill2 "platform/web/domains/bill"
|
bill2 "platform/web/domains/bill"
|
||||||
coupon2 "platform/web/domains/coupon"
|
coupon2 "platform/web/domains/coupon"
|
||||||
trade2 "platform/web/domains/trade"
|
trade2 "platform/web/domains/trade"
|
||||||
g "platform/web/globals"
|
g "platform/web/globals"
|
||||||
|
"platform/web/globals/orm"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
"platform/pkg/rds"
|
|
||||||
"platform/pkg/u"
|
"platform/pkg/u"
|
||||||
g "platform/web/globals"
|
g "platform/web/globals"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -50,7 +49,7 @@ func (s *verifierService) SendSms(ctx context.Context, phone string, purpose Ver
|
|||||||
keyLock := key + ":lock"
|
keyLock := key + ":lock"
|
||||||
|
|
||||||
// 检查发送频率,1 分钟内只能发送一次
|
// 检查发送频率,1 分钟内只能发送一次
|
||||||
err := rds.Client.Watch(ctx, func(tx *redis.Tx) error {
|
err := g.Redis.Watch(ctx, func(tx *redis.Tx) error {
|
||||||
result, err := tx.TTL(ctx, keyLock).Result()
|
result, err := tx.TTL(ctx, keyLock).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -62,7 +61,7 @@ func (s *verifierService) SendSms(ctx context.Context, phone string, purpose Ver
|
|||||||
return VerifierServiceError("验证码检查异常")
|
return VerifierServiceError("验证码检查异常")
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe := rds.Client.Pipeline()
|
pipe := g.Redis.Pipeline()
|
||||||
pipe.Set(ctx, keyLock, "", 1*time.Minute)
|
pipe.Set(ctx, keyLock, "", 1*time.Minute)
|
||||||
_, err = pipe.Exec(ctx)
|
_, err = pipe.Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -92,19 +91,19 @@ func (s *verifierService) SendSms(ctx context.Context, phone string, purpose Ver
|
|||||||
TemplateParam: u.P(string(params)),
|
TemplateParam: u.P(string(params)),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = rds.Client.Del(ctx, key, keyLock).Err()
|
_ = g.Redis.Del(ctx, key, keyLock).Err()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if response.Body.Code == nil || *response.Body.Code != "OK" {
|
if response.Body.Code == nil || *response.Body.Code != "OK" {
|
||||||
_ = rds.Client.Del(ctx, key, keyLock).Err()
|
_ = g.Redis.Del(ctx, key, keyLock).Err()
|
||||||
return VerifierServiceError("验证码发送失败")
|
return VerifierServiceError("验证码发送失败")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置验证码
|
// 设置验证码
|
||||||
err = rds.Client.Set(ctx, key, code, 5*time.Minute).Err()
|
err = g.Redis.Set(ctx, key, code, 5*time.Minute).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = rds.Client.Del(ctx, key, keyLock).Err()
|
_ = g.Redis.Del(ctx, key, keyLock).Err()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,10 +115,10 @@ func (s *verifierService) VerifySms(ctx context.Context, phone, code string) err
|
|||||||
key := smsKey(phone, VerifierSmsPurposeLogin)
|
key := smsKey(phone, VerifierSmsPurposeLogin)
|
||||||
keyLock := key + ":lock"
|
keyLock := key + ":lock"
|
||||||
|
|
||||||
err := rds.Client.Watch(ctx, func(tx *redis.Tx) error {
|
err := g.Redis.Watch(ctx, func(tx *redis.Tx) error {
|
||||||
|
|
||||||
// 检查验证码
|
// 检查验证码
|
||||||
val, err := rds.Client.Get(ctx, key).Result()
|
val, err := g.Redis.Get(ctx, key).Result()
|
||||||
if err != nil && !errors.Is(err, redis.Nil) {
|
if err != nil && !errors.Is(err, redis.Nil) {
|
||||||
slog.Error("验证码获取失败", slog.Any("err", err))
|
slog.Error("验证码获取失败", slog.Any("err", err))
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package services
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"platform/pkg/testutil"
|
"platform/web/testutil"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package testutil
|
package testutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/orm"
|
g"platform/web/globals"
|
||||||
"platform/web/models"
|
m"platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -20,12 +20,12 @@ func SetupDBTest(t *testing.T) *gorm.DB {
|
|||||||
|
|
||||||
// 自动迁移数据表结构
|
// 自动迁移数据表结构
|
||||||
err = gormDB.AutoMigrate(
|
err = gormDB.AutoMigrate(
|
||||||
&models.User{},
|
&m.User{},
|
||||||
&models.Whitelist{},
|
&m.Whitelist{},
|
||||||
&models.Resource{},
|
&m.Resource{},
|
||||||
&models.ResourcePss{},
|
&m.ResourcePss{},
|
||||||
&models.Proxy{},
|
&m.Proxy{},
|
||||||
&models.Channel{},
|
&m.Channel{},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("自动迁移表结构失败: %v", err)
|
t.Fatalf("自动迁移表结构失败: %v", err)
|
||||||
@@ -33,7 +33,7 @@ func SetupDBTest(t *testing.T) *gorm.DB {
|
|||||||
|
|
||||||
// 设置全局数据库连接
|
// 设置全局数据库连接
|
||||||
q.SetDefault(gormDB)
|
q.SetDefault(gormDB)
|
||||||
orm.DB = gormDB
|
g.DB = gormDB
|
||||||
|
|
||||||
return gormDB
|
return gormDB
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package testutil
|
package testutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"platform/pkg/rds"
|
g "platform/web/globals"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/alicebob/miniredis/v2"
|
"github.com/alicebob/miniredis/v2"
|
||||||
@@ -17,7 +17,7 @@ func SetupRedisTest(t *testing.T) *miniredis.Miniredis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 替换 Redis 客户端为测试客户端
|
// 替换 Redis 客户端为测试客户端
|
||||||
rds.Client = redis.NewClient(&redis.Options{
|
g.Redis = redis.NewClient(&redis.Options{
|
||||||
Addr: mr.Addr(),
|
Addr: mr.Addr(),
|
||||||
})
|
})
|
||||||
|
|
||||||
22
web/web.go
22
web/web.go
@@ -9,9 +9,9 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
"platform/pkg/orm"
|
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
g "platform/web/globals"
|
g "platform/web/globals"
|
||||||
|
"platform/web/globals/orm"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
"runtime"
|
"runtime"
|
||||||
@@ -45,12 +45,8 @@ func New(config *Config) (*Server, error) {
|
|||||||
func (s *Server) Run() error {
|
func (s *Server) Run() error {
|
||||||
|
|
||||||
// inits
|
// inits
|
||||||
g.InitBaiyin()
|
g.Init()
|
||||||
g.InitAlipay()
|
q.SetDefault(g.DB)
|
||||||
g.InitWechatPay()
|
|
||||||
g.InitAliyun()
|
|
||||||
g.InitValidator()
|
|
||||||
q.SetDefault(orm.DB)
|
|
||||||
|
|
||||||
// config
|
// config
|
||||||
s.fiber = fiber.New(fiber.Config{
|
s.fiber = fiber.New(fiber.Config{
|
||||||
@@ -86,7 +82,17 @@ func (s *Server) Run() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Stop() {
|
func (s *Server) Stop() {
|
||||||
err := s.fiber.Shutdown()
|
err := g.ExitRedis()
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("Failed to close Redis connection", slog.Any("err", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = g.ExitOrm()
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("Failed to close database connection", slog.Any("err", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.fiber.Shutdown()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("Failed to shutdown server", slog.Any("err", err))
|
slog.Error("Failed to shutdown server", slog.Any("err", err))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user