优化数据库结构与数据插入逻辑

This commit is contained in:
2025-04-12 18:03:44 +08:00
parent 438a55cc3e
commit 8c268fd7a9
28 changed files with 218 additions and 213 deletions

View File

@@ -67,6 +67,7 @@ type PageResp struct {
type LocalDateTime time.Time
//goland:noinspection GoMixedReceiverTypes
func (ldt *LocalDateTime) Scan(value interface{}) (err error) {
nullTime := &sql.NullTime{}
@@ -85,27 +86,35 @@ func (ldt *LocalDateTime) Scan(value interface{}) (err error) {
return
}
//goland:noinspection GoMixedReceiverTypes
func (ldt LocalDateTime) Value() (driver.Value, error) {
return time.Time(ldt).In(time.Local), nil
return time.Time(ldt).Local(), nil
}
// GormDataType gorm common data type
//
//goland:noinspection GoMixedReceiverTy
//goland:noinspection GoMixedReceiverTypes
func (ldt LocalDateTime) GormDataType() string {
return "ldt"
}
//goland:noinspection GoMixedReceiverTypes
func (ldt LocalDateTime) GobEncode() ([]byte, error) {
return time.Time(ldt).GobEncode()
}
//goland:noinspection GoMixedReceiverTypes
func (ldt *LocalDateTime) GobDecode(b []byte) error {
return (*time.Time)(ldt).GobDecode(b)
}
//goland:noinspection GoMixedReceiverTypes
func (ldt LocalDateTime) MarshalJSON() ([]byte, error) {
return time.Time(ldt).MarshalJSON()
}
//goland:noinspection GoMixedReceiverTypes
func (ldt *LocalDateTime) UnmarshalJSON(b []byte) error {
return (*time.Time)(ldt).UnmarshalJSON(b)
}

View File

@@ -2,6 +2,7 @@ package handlers
import (
"errors"
"platform/pkg/u"
"platform/web/auth"
"platform/web/common"
m "platform/web/models"
@@ -67,7 +68,7 @@ func ListResourcePss(c *fiber.Ctx) error {
var resource []*m.Resource
err = do.Debug().
Order(q.ResourcePss.As(q.Resource.Pss.Name()).CreatedAt.Desc()).
Order(q.Resource.CreatedAt.Desc()).
Offset(req.GetOffset()).
Limit(req.GetLimit()).
Scan(&resource)
@@ -95,6 +96,51 @@ func ListResourcePss(c *fiber.Ctx) error {
// endregion
// region AllResource
type AllResourceReq struct {
}
func AllResource(c *fiber.Ctx) error {
// 检查权限
authContext, err := auth.Protect(c, []services.PayloadType{services.PayloadUser}, []string{})
if err != nil {
return err
}
// 查询资源列表
pss := q.ResourcePss.As(q.Resource.Pss.Name())
do := q.Resource.Debug().
Joins(q.Resource.Pss).
Where(
q.Resource.UserID.Eq(authContext.Payload.Id),
q.Resource.Active.Is(true),
q.Resource.Where(
pss.Type.Eq(1),
pss.Expire.Gte(common.LocalDateTime(time.Now())),
).Or(
pss.Type.Eq(2),
pss.Quota.GtCol(pss.Used),
),
q.Resource.Where(
pss.DailyLast.Lt(common.LocalDateTime(u.Today())),
).Or(
pss.DailyUsed.LtCol(pss.DailyLimit),
),
)
resources, err := do.Debug().
Order(q.Resource.CreatedAt.Desc()).
Find()
if err != nil {
return err
}
return c.JSON(resources)
}
// endregion
// region CreateResourceByBalance
type CreateResourceByBalanceReq struct {

View File

@@ -20,7 +20,6 @@ type Channel struct {
ProxyID int32 `gorm:"column:proxy_id;not null;comment:代理ID" json:"proxy_id"` // 代理ID
NodeID int32 `gorm:"column:node_id;comment:节点ID" json:"node_id"` // 节点ID
ProxyPort int32 `gorm:"column:proxy_port;not null;comment:转发端口" json:"proxy_port"` // 转发端口
Protocol string `gorm:"column:protocol;comment:协议" json:"protocol"` // 协议
UserHost string `gorm:"column:user_host;comment:用户地址" json:"user_host"` // 用户地址
NodeHost string `gorm:"column:node_host;comment:节点地址" json:"node_host"` // 节点地址
AuthIP bool `gorm:"column:auth_ip;not null;comment:IP认证" json:"auth_ip"` // IP认证
@@ -32,6 +31,7 @@ type Channel struct {
UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间
ProxyHost string `gorm:"column:proxy_host;not null" json:"proxy_host"`
Protocol int32 `gorm:"column:protocol" json:"protocol"`
}
// TableName Channel's table name

View File

@@ -18,7 +18,6 @@ type Node struct {
Version int32 `gorm:"column:version;not null;comment:节点版本" json:"version"` // 节点版本
Name string `gorm:"column:name;not null;comment:节点名称" json:"name"` // 节点名称
Host string `gorm:"column:host;not null;comment:节点地址" json:"host"` // 节点地址
Isp string `gorm:"column:isp;not null;comment:运营商" json:"isp"` // 运营商
Prov string `gorm:"column:prov;not null;comment:省份" json:"prov"` // 省份
City string `gorm:"column:city;not null;comment:城市" json:"city"` // 城市
ProxyID int32 `gorm:"column:proxy_id;comment:代理ID" json:"proxy_id"` // 代理ID
@@ -29,6 +28,7 @@ type Node struct {
CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间
Isp int32 `gorm:"column:isp;not null" json:"isp"`
}
// TableName Node's table name

View File

@@ -21,6 +21,8 @@ type Refund struct {
UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间
TradeID int32 `gorm:"column:trade_id;not null" json:"trade_id"`
Reason string `gorm:"column:reason" json:"reason"`
Status int32 `gorm:"column:status;not null" json:"status"`
}
// TableName Refund's table name

View File

@@ -21,6 +21,7 @@ type Resource struct {
UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间
ResourceNo string `gorm:"column:resource_no" json:"resource_no"`
Type int32 `gorm:"column:type;not null" json:"type"`
Pss *ResourcePss `gorm:"foreignKey:ResourceID;references:ID" json:"pss"`
}

View File

@@ -4,21 +4,12 @@
package models
import (
"platform/web/common"
"gorm.io/gorm"
)
const TableNameResourcePps = "resource_pps"
// ResourcePps mapped from table <resource_pps>
type ResourcePps struct {
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:ID" json:"id"` // ID
ResourceID int32 `gorm:"column:resource_id;not null;comment:套餐ID" json:"resource_id"` // 套餐ID
CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:ID" json:"id"` // ID
ResourceID int32 `gorm:"column:resource_id;not null;comment:套餐ID" json:"resource_id"` // 套餐ID
}
// TableName ResourcePps's table name

View File

@@ -5,25 +5,19 @@
package models
import (
"platform/web/common"
"time"
"gorm.io/gorm"
)
const TableNameResourcePsr = "resource_psr"
// ResourcePsr mapped from table <resource_psr>
type ResourcePsr struct {
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:ID" json:"id"` // ID
ResourceID int32 `gorm:"column:resource_id;not null;comment:套餐ID" json:"resource_id"` // 套餐ID
Live int32 `gorm:"column:live;comment:轮换周期(秒)" json:"live"` // 轮换周期(秒)
Conn int32 `gorm:"column:conn;comment:最大连接数" json:"conn"` // 最大连接数
Expire time.Time `gorm:"column:expire;comment:过期时间" json:"expire"` // 过期时间
Used bool `gorm:"column:used;comment:是否已使用" json:"used"` // 是否已使用
CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:ID" json:"id"` // ID
ResourceID int32 `gorm:"column:resource_id;not null;comment:套餐ID" json:"resource_id"` // 套餐ID
Live int32 `gorm:"column:live;comment:轮换周期(秒)" json:"live"` // 轮换周期(秒)
Conn int32 `gorm:"column:conn;comment:最大连接数" json:"conn"` // 最大连接数
Expire time.Time `gorm:"column:expire;comment:过期时间" json:"expire"` // 过期时间
Used bool `gorm:"column:used;comment:是否已使用" json:"used"` // 是否已使用
}
// TableName ResourcePsr's table name

View File

@@ -4,29 +4,22 @@
package models
import (
"platform/web/common"
"gorm.io/gorm"
)
import "platform/web/common"
const TableNameResourcePss = "resource_pss"
// ResourcePss mapped from table <resource_pss>
type ResourcePss struct {
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:ID" json:"id"` // ID
ResourceID int32 `gorm:"column:resource_id;not null;comment:套餐ID" json:"resource_id"` // 套餐ID
Type int32 `gorm:"column:type;comment:套餐类型1-包时2-包量" json:"type"` // 套餐类型1-包时2-包量
Live int32 `gorm:"column:live;comment:可用时长(秒)" json:"live"` // 可用时长(秒)
Quota int32 `gorm:"column:quota;comment:配额数量" json:"quota"` // 配额数量
Expire common.LocalDateTime `gorm:"column:expire;comment:过期时间" json:"expire"` // 过期时间
Used int32 `gorm:"column:used;not null;comment:已用数量" json:"used"` // 已用数量
DailyLimit int32 `gorm:"column:daily_limit;not null;comment:每日限制" json:"daily_limit"` // 每日限制
DailyUsed int32 `gorm:"column:daily_used;not null;comment:今日已用数量" json:"daily_used"` // 今日已用数量
DailyLast common.LocalDateTime `gorm:"column:daily_last;comment:今日最后使用时间" json:"daily_last"` // 今日最后使用时间
CreatedAt common.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
UpdatedAt common.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间
ID int32 `gorm:"column:id;primaryKey;autoIncrement:true;comment:ID" json:"id"` // ID
ResourceID int32 `gorm:"column:resource_id;not null;comment:套餐ID" json:"resource_id"` // 套餐ID
Type int32 `gorm:"column:type;comment:套餐类型1-包时2-包量" json:"type"` // 套餐类型1-包时2-包量
Live int32 `gorm:"column:live;comment:可用时长(秒)" json:"live"` // 可用时长(秒)
Quota int32 `gorm:"column:quota;comment:配额数量" json:"quota"` // 配额数量
Expire common.LocalDateTime `gorm:"column:expire;comment:过期时间" json:"expire"` // 过期时间
Used int32 `gorm:"column:used;not null;comment:已用数量" json:"used"` // 已用数量
DailyLimit int32 `gorm:"column:daily_limit;not null;comment:每日限制" json:"daily_limit"` // 每日限制
DailyUsed int32 `gorm:"column:daily_used;not null;comment:今日已用数量" json:"daily_used"` // 今日已用数量
DailyLast common.LocalDateTime `gorm:"column:daily_last;comment:今日最后使用时间" json:"daily_last"` // 今日最后使用时间
}
// TableName ResourcePss's table name

View File

@@ -32,7 +32,6 @@ func newChannel(db *gorm.DB, opts ...gen.DOOption) channel {
_channel.ProxyID = field.NewInt32(tableName, "proxy_id")
_channel.NodeID = field.NewInt32(tableName, "node_id")
_channel.ProxyPort = field.NewInt32(tableName, "proxy_port")
_channel.Protocol = field.NewString(tableName, "protocol")
_channel.UserHost = field.NewString(tableName, "user_host")
_channel.NodeHost = field.NewString(tableName, "node_host")
_channel.AuthIP = field.NewBool(tableName, "auth_ip")
@@ -44,6 +43,7 @@ func newChannel(db *gorm.DB, opts ...gen.DOOption) channel {
_channel.UpdatedAt = field.NewField(tableName, "updated_at")
_channel.DeletedAt = field.NewField(tableName, "deleted_at")
_channel.ProxyHost = field.NewString(tableName, "proxy_host")
_channel.Protocol = field.NewInt32(tableName, "protocol")
_channel.fillFieldMap()
@@ -59,7 +59,6 @@ type channel struct {
ProxyID field.Int32 // 代理ID
NodeID field.Int32 // 节点ID
ProxyPort field.Int32 // 转发端口
Protocol field.String // 协议
UserHost field.String // 用户地址
NodeHost field.String // 节点地址
AuthIP field.Bool // IP认证
@@ -71,6 +70,7 @@ type channel struct {
UpdatedAt field.Field // 更新时间
DeletedAt field.Field // 删除时间
ProxyHost field.String
Protocol field.Int32
fieldMap map[string]field.Expr
}
@@ -92,7 +92,6 @@ func (c *channel) updateTableName(table string) *channel {
c.ProxyID = field.NewInt32(table, "proxy_id")
c.NodeID = field.NewInt32(table, "node_id")
c.ProxyPort = field.NewInt32(table, "proxy_port")
c.Protocol = field.NewString(table, "protocol")
c.UserHost = field.NewString(table, "user_host")
c.NodeHost = field.NewString(table, "node_host")
c.AuthIP = field.NewBool(table, "auth_ip")
@@ -104,6 +103,7 @@ func (c *channel) updateTableName(table string) *channel {
c.UpdatedAt = field.NewField(table, "updated_at")
c.DeletedAt = field.NewField(table, "deleted_at")
c.ProxyHost = field.NewString(table, "proxy_host")
c.Protocol = field.NewInt32(table, "protocol")
c.fillFieldMap()
@@ -126,7 +126,6 @@ func (c *channel) fillFieldMap() {
c.fieldMap["proxy_id"] = c.ProxyID
c.fieldMap["node_id"] = c.NodeID
c.fieldMap["proxy_port"] = c.ProxyPort
c.fieldMap["protocol"] = c.Protocol
c.fieldMap["user_host"] = c.UserHost
c.fieldMap["node_host"] = c.NodeHost
c.fieldMap["auth_ip"] = c.AuthIP
@@ -138,6 +137,7 @@ func (c *channel) fillFieldMap() {
c.fieldMap["updated_at"] = c.UpdatedAt
c.fieldMap["deleted_at"] = c.DeletedAt
c.fieldMap["proxy_host"] = c.ProxyHost
c.fieldMap["protocol"] = c.Protocol
}
func (c channel) clone(db *gorm.DB) channel {

View File

@@ -31,7 +31,6 @@ func newNode(db *gorm.DB, opts ...gen.DOOption) node {
_node.Version = field.NewInt32(tableName, "version")
_node.Name = field.NewString(tableName, "name")
_node.Host = field.NewString(tableName, "host")
_node.Isp = field.NewString(tableName, "isp")
_node.Prov = field.NewString(tableName, "prov")
_node.City = field.NewString(tableName, "city")
_node.ProxyID = field.NewInt32(tableName, "proxy_id")
@@ -42,6 +41,7 @@ func newNode(db *gorm.DB, opts ...gen.DOOption) node {
_node.CreatedAt = field.NewField(tableName, "created_at")
_node.UpdatedAt = field.NewField(tableName, "updated_at")
_node.DeletedAt = field.NewField(tableName, "deleted_at")
_node.Isp = field.NewInt32(tableName, "isp")
_node.fillFieldMap()
@@ -56,7 +56,6 @@ type node struct {
Version field.Int32 // 节点版本
Name field.String // 节点名称
Host field.String // 节点地址
Isp field.String // 运营商
Prov field.String // 省份
City field.String // 城市
ProxyID field.Int32 // 代理ID
@@ -67,6 +66,7 @@ type node struct {
CreatedAt field.Field // 创建时间
UpdatedAt field.Field // 更新时间
DeletedAt field.Field // 删除时间
Isp field.Int32
fieldMap map[string]field.Expr
}
@@ -87,7 +87,6 @@ func (n *node) updateTableName(table string) *node {
n.Version = field.NewInt32(table, "version")
n.Name = field.NewString(table, "name")
n.Host = field.NewString(table, "host")
n.Isp = field.NewString(table, "isp")
n.Prov = field.NewString(table, "prov")
n.City = field.NewString(table, "city")
n.ProxyID = field.NewInt32(table, "proxy_id")
@@ -98,6 +97,7 @@ func (n *node) updateTableName(table string) *node {
n.CreatedAt = field.NewField(table, "created_at")
n.UpdatedAt = field.NewField(table, "updated_at")
n.DeletedAt = field.NewField(table, "deleted_at")
n.Isp = field.NewInt32(table, "isp")
n.fillFieldMap()
@@ -119,7 +119,6 @@ func (n *node) fillFieldMap() {
n.fieldMap["version"] = n.Version
n.fieldMap["name"] = n.Name
n.fieldMap["host"] = n.Host
n.fieldMap["isp"] = n.Isp
n.fieldMap["prov"] = n.Prov
n.fieldMap["city"] = n.City
n.fieldMap["proxy_id"] = n.ProxyID
@@ -130,6 +129,7 @@ func (n *node) fillFieldMap() {
n.fieldMap["created_at"] = n.CreatedAt
n.fieldMap["updated_at"] = n.UpdatedAt
n.fieldMap["deleted_at"] = n.DeletedAt
n.fieldMap["isp"] = n.Isp
}
func (n node) clone(db *gorm.DB) node {

View File

@@ -34,6 +34,8 @@ func newRefund(db *gorm.DB, opts ...gen.DOOption) refund {
_refund.UpdatedAt = field.NewField(tableName, "updated_at")
_refund.DeletedAt = field.NewField(tableName, "deleted_at")
_refund.TradeID = field.NewInt32(tableName, "trade_id")
_refund.Reason = field.NewString(tableName, "reason")
_refund.Status = field.NewInt32(tableName, "status")
_refund.fillFieldMap()
@@ -51,6 +53,8 @@ type refund struct {
UpdatedAt field.Field // 更新时间
DeletedAt field.Field // 删除时间
TradeID field.Int32
Reason field.String
Status field.Int32
fieldMap map[string]field.Expr
}
@@ -74,6 +78,8 @@ func (r *refund) updateTableName(table string) *refund {
r.UpdatedAt = field.NewField(table, "updated_at")
r.DeletedAt = field.NewField(table, "deleted_at")
r.TradeID = field.NewInt32(table, "trade_id")
r.Reason = field.NewString(table, "reason")
r.Status = field.NewInt32(table, "status")
r.fillFieldMap()
@@ -90,7 +96,7 @@ func (r *refund) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (r *refund) fillFieldMap() {
r.fieldMap = make(map[string]field.Expr, 7)
r.fieldMap = make(map[string]field.Expr, 9)
r.fieldMap["id"] = r.ID
r.fieldMap["product_id"] = r.ProductID
r.fieldMap["amount"] = r.Amount
@@ -98,6 +104,8 @@ func (r *refund) fillFieldMap() {
r.fieldMap["updated_at"] = r.UpdatedAt
r.fieldMap["deleted_at"] = r.DeletedAt
r.fieldMap["trade_id"] = r.TradeID
r.fieldMap["reason"] = r.Reason
r.fieldMap["status"] = r.Status
}
func (r refund) clone(db *gorm.DB) refund {

View File

@@ -34,6 +34,7 @@ func newResource(db *gorm.DB, opts ...gen.DOOption) resource {
_resource.UpdatedAt = field.NewField(tableName, "updated_at")
_resource.DeletedAt = field.NewField(tableName, "deleted_at")
_resource.ResourceNo = field.NewString(tableName, "resource_no")
_resource.Type = field.NewInt32(tableName, "type")
_resource.Pss = resourceHasOnePss{
db: db.Session(&gorm.Session{}),
@@ -56,6 +57,7 @@ type resource struct {
UpdatedAt field.Field // 更新时间
DeletedAt field.Field // 删除时间
ResourceNo field.String
Type field.Int32
Pss resourceHasOnePss
fieldMap map[string]field.Expr
@@ -80,6 +82,7 @@ func (r *resource) updateTableName(table string) *resource {
r.UpdatedAt = field.NewField(table, "updated_at")
r.DeletedAt = field.NewField(table, "deleted_at")
r.ResourceNo = field.NewString(table, "resource_no")
r.Type = field.NewInt32(table, "type")
r.fillFieldMap()
@@ -96,7 +99,7 @@ func (r *resource) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (r *resource) fillFieldMap() {
r.fieldMap = make(map[string]field.Expr, 8)
r.fieldMap = make(map[string]field.Expr, 9)
r.fieldMap["id"] = r.ID
r.fieldMap["user_id"] = r.UserID
r.fieldMap["active"] = r.Active
@@ -104,6 +107,7 @@ func (r *resource) fillFieldMap() {
r.fieldMap["updated_at"] = r.UpdatedAt
r.fieldMap["deleted_at"] = r.DeletedAt
r.fieldMap["resource_no"] = r.ResourceNo
r.fieldMap["type"] = r.Type
}

View File

@@ -29,9 +29,6 @@ func newResourcePps(db *gorm.DB, opts ...gen.DOOption) resourcePps {
_resourcePps.ALL = field.NewAsterisk(tableName)
_resourcePps.ID = field.NewInt32(tableName, "id")
_resourcePps.ResourceID = field.NewInt32(tableName, "resource_id")
_resourcePps.CreatedAt = field.NewField(tableName, "created_at")
_resourcePps.UpdatedAt = field.NewField(tableName, "updated_at")
_resourcePps.DeletedAt = field.NewField(tableName, "deleted_at")
_resourcePps.fillFieldMap()
@@ -44,9 +41,6 @@ type resourcePps struct {
ALL field.Asterisk
ID field.Int32 // ID
ResourceID field.Int32 // 套餐ID
CreatedAt field.Field // 创建时间
UpdatedAt field.Field // 更新时间
DeletedAt field.Field // 删除时间
fieldMap map[string]field.Expr
}
@@ -65,9 +59,6 @@ func (r *resourcePps) updateTableName(table string) *resourcePps {
r.ALL = field.NewAsterisk(table)
r.ID = field.NewInt32(table, "id")
r.ResourceID = field.NewInt32(table, "resource_id")
r.CreatedAt = field.NewField(table, "created_at")
r.UpdatedAt = field.NewField(table, "updated_at")
r.DeletedAt = field.NewField(table, "deleted_at")
r.fillFieldMap()
@@ -84,12 +75,9 @@ func (r *resourcePps) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (r *resourcePps) fillFieldMap() {
r.fieldMap = make(map[string]field.Expr, 5)
r.fieldMap = make(map[string]field.Expr, 2)
r.fieldMap["id"] = r.ID
r.fieldMap["resource_id"] = r.ResourceID
r.fieldMap["created_at"] = r.CreatedAt
r.fieldMap["updated_at"] = r.UpdatedAt
r.fieldMap["deleted_at"] = r.DeletedAt
}
func (r resourcePps) clone(db *gorm.DB) resourcePps {

View File

@@ -33,9 +33,6 @@ func newResourcePsr(db *gorm.DB, opts ...gen.DOOption) resourcePsr {
_resourcePsr.Conn = field.NewInt32(tableName, "conn")
_resourcePsr.Expire = field.NewTime(tableName, "expire")
_resourcePsr.Used = field.NewBool(tableName, "used")
_resourcePsr.CreatedAt = field.NewField(tableName, "created_at")
_resourcePsr.UpdatedAt = field.NewField(tableName, "updated_at")
_resourcePsr.DeletedAt = field.NewField(tableName, "deleted_at")
_resourcePsr.fillFieldMap()
@@ -52,9 +49,6 @@ type resourcePsr struct {
Conn field.Int32 // 最大连接数
Expire field.Time // 过期时间
Used field.Bool // 是否已使用
CreatedAt field.Field // 创建时间
UpdatedAt field.Field // 更新时间
DeletedAt field.Field // 删除时间
fieldMap map[string]field.Expr
}
@@ -77,9 +71,6 @@ func (r *resourcePsr) updateTableName(table string) *resourcePsr {
r.Conn = field.NewInt32(table, "conn")
r.Expire = field.NewTime(table, "expire")
r.Used = field.NewBool(table, "used")
r.CreatedAt = field.NewField(table, "created_at")
r.UpdatedAt = field.NewField(table, "updated_at")
r.DeletedAt = field.NewField(table, "deleted_at")
r.fillFieldMap()
@@ -96,16 +87,13 @@ func (r *resourcePsr) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (r *resourcePsr) fillFieldMap() {
r.fieldMap = make(map[string]field.Expr, 9)
r.fieldMap = make(map[string]field.Expr, 6)
r.fieldMap["id"] = r.ID
r.fieldMap["resource_id"] = r.ResourceID
r.fieldMap["live"] = r.Live
r.fieldMap["conn"] = r.Conn
r.fieldMap["expire"] = r.Expire
r.fieldMap["used"] = r.Used
r.fieldMap["created_at"] = r.CreatedAt
r.fieldMap["updated_at"] = r.UpdatedAt
r.fieldMap["deleted_at"] = r.DeletedAt
}
func (r resourcePsr) clone(db *gorm.DB) resourcePsr {

View File

@@ -37,9 +37,6 @@ func newResourcePss(db *gorm.DB, opts ...gen.DOOption) resourcePss {
_resourcePss.DailyLimit = field.NewInt32(tableName, "daily_limit")
_resourcePss.DailyUsed = field.NewInt32(tableName, "daily_used")
_resourcePss.DailyLast = field.NewField(tableName, "daily_last")
_resourcePss.CreatedAt = field.NewField(tableName, "created_at")
_resourcePss.UpdatedAt = field.NewField(tableName, "updated_at")
_resourcePss.DeletedAt = field.NewField(tableName, "deleted_at")
_resourcePss.fillFieldMap()
@@ -60,9 +57,6 @@ type resourcePss struct {
DailyLimit field.Int32 // 每日限制
DailyUsed field.Int32 // 今日已用数量
DailyLast field.Field // 今日最后使用时间
CreatedAt field.Field // 创建时间
UpdatedAt field.Field // 更新时间
DeletedAt field.Field // 删除时间
fieldMap map[string]field.Expr
}
@@ -89,9 +83,6 @@ func (r *resourcePss) updateTableName(table string) *resourcePss {
r.DailyLimit = field.NewInt32(table, "daily_limit")
r.DailyUsed = field.NewInt32(table, "daily_used")
r.DailyLast = field.NewField(table, "daily_last")
r.CreatedAt = field.NewField(table, "created_at")
r.UpdatedAt = field.NewField(table, "updated_at")
r.DeletedAt = field.NewField(table, "deleted_at")
r.fillFieldMap()
@@ -108,7 +99,7 @@ func (r *resourcePss) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (r *resourcePss) fillFieldMap() {
r.fieldMap = make(map[string]field.Expr, 13)
r.fieldMap = make(map[string]field.Expr, 10)
r.fieldMap["id"] = r.ID
r.fieldMap["resource_id"] = r.ResourceID
r.fieldMap["type"] = r.Type
@@ -119,9 +110,6 @@ func (r *resourcePss) fillFieldMap() {
r.fieldMap["daily_limit"] = r.DailyLimit
r.fieldMap["daily_used"] = r.DailyUsed
r.fieldMap["daily_last"] = r.DailyLast
r.fieldMap["created_at"] = r.CreatedAt
r.fieldMap["updated_at"] = r.UpdatedAt
r.fieldMap["deleted_at"] = r.DeletedAt
}
func (r resourcePss) clone(db *gorm.DB) resourcePss {

View File

@@ -28,9 +28,10 @@ func ApplyRouters(app *fiber.App) {
whitelist.Post("/update", handlers.UpdateWhitelist)
whitelist.Post("/remove", handlers.RemoveWhitelist)
// 资源
// 套餐
resource := api.Group("/resource")
resource.Post("/list/pss", handlers.ListResourcePss)
resource.Post("/all", handlers.AllResource)
resource.Post("/create/balance", handlers.CreateResourceByBalance)
// 用户

View File

@@ -12,7 +12,7 @@ import (
"platform/pkg/orm"
"platform/pkg/rds"
"platform/pkg/remote"
"platform/pkg/v"
"platform/pkg/u"
"platform/web/common"
"platform/web/models"
q "platform/web/queries"
@@ -37,12 +37,12 @@ const (
ChannelAuthTypePass
)
type ChannelProtocol string
type ChannelProtocol int32
const (
ProtocolSocks5 = ChannelProtocol("socks5")
ProtocolHTTP = ChannelProtocol("http")
ProtocolHttps = ChannelProtocol("https")
ProtocolHTTP = ChannelProtocol(1)
ProtocolHttps = ChannelProtocol(2)
ProtocolSocks5 = ChannelProtocol(3)
)
type ResourceInfo struct {
@@ -142,7 +142,7 @@ func (s *channelService) RemoveChannels(ctx context.Context, auth *AuthContext,
Port: int(channel.ProxyPort),
Edge: &[]string{},
AutoEdgeConfig: &remote.AutoEdgeConfig{
Count: v.P(0),
Count: u.P(0),
},
Status: false,
}
@@ -600,7 +600,7 @@ func assignPort(
Province: filter.Prov,
City: filter.City,
Isp: filter.Isp,
Count: v.P(1),
Count: u.P(1),
PacketLoss: 30,
},
})
@@ -608,7 +608,7 @@ func assignPort(
switch authType {
case ChannelAuthTypeIp:
configs[i].Whitelist = &whitelist
configs[i].Userpass = v.P("")
configs[i].Userpass = u.P("")
for _, item := range whitelist {
channels = append(channels, &models.Channel{
UserID: userId,
@@ -617,19 +617,19 @@ func assignPort(
ProxyPort: int32(port),
AuthIP: true,
AuthPass: false,
Protocol: string(protocol),
Protocol: int32(protocol),
Expiration: expiration,
})
}
result = append(result, &PortInfo{
Proto: string(protocol),
Proto: protocol,
Host: proxy.Host,
Port: port,
})
case ChannelAuthTypePass:
username, password := genPassPair()
configs[i].Whitelist = &[]string{}
configs[i].Userpass = v.P(fmt.Sprintf("%s:%s", username, password))
configs[i].Userpass = u.P(fmt.Sprintf("%s:%s", username, password))
channels = append(channels, &models.Channel{
UserID: userId,
ProxyID: proxy.ID,
@@ -638,11 +638,11 @@ func assignPort(
AuthPass: true,
Username: username,
Password: password,
Protocol: string(protocol),
Protocol: int32(protocol),
Expiration: expiration,
})
result = append(result, &PortInfo{
Proto: string(protocol),
Proto: protocol,
Host: proxy.Host,
Port: port,
Username: &username,
@@ -694,16 +694,17 @@ func assignPort(
}
type PortInfo struct {
Proto string `json:"-"`
Host string `json:"host"`
Port int `json:"port"`
Username *string `json:"username,omitempty"`
Password *string `json:"password,omitempty"`
Proto ChannelProtocol `json:"-"`
Host string `json:"host"`
Port int `json:"port"`
Username *string `json:"username,omitempty"`
Password *string `json:"password,omitempty"`
}
// endregion
func genPassPair() (string, string) {
//goland:noinspection SpellCheckingInspection
var alphabet = []rune("abcdefghjkmnpqrstuvwxyz")
var numbers = []rune("23456789")

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"platform/pkg/remote"
"platform/pkg/testutil"
"platform/web/common"
"platform/web/models"
"reflect"
"strings"
@@ -116,7 +117,7 @@ func Test_cache(t *testing.T) {
UserID: 100,
ProxyID: 10,
ProxyPort: 8080,
Protocol: "http",
Protocol: 1,
Expiration: expiration,
},
{
@@ -124,7 +125,7 @@ func Test_cache(t *testing.T) {
UserID: 101,
ProxyID: 11,
ProxyPort: 8081,
Protocol: "socks5",
Protocol: 3,
Expiration: expiration,
},
}
@@ -330,7 +331,7 @@ func Test_channelService_CreateChannel(t *testing.T) {
ResourceID: 1,
Type: 1,
Live: 180,
Expire: time.Now().AddDate(1, 0, 0),
Expire: common.LocalDateTime(time.Now().AddDate(1, 0, 0)),
DailyLimit: 10000,
}
db.Create(resourcePss)
@@ -419,8 +420,8 @@ func Test_channelService_CreateChannel(t *testing.T) {
// 验证结果
var gotMap = make(map[int]PortInfo)
for _, port := range got {
if port.Proto != "http" {
return fmt.Errorf("期望协议为 http得到 %s", port.Proto)
if port.Proto != 1 {
return fmt.Errorf("期望协议为 1(http),得到 %d", port.Proto)
}
if port.Host != proxy.Host {
return fmt.Errorf("期望主机为 %s得到 %s", proxy.Host, port.Host)
@@ -432,8 +433,8 @@ func Test_channelService_CreateChannel(t *testing.T) {
var channels []*models.Channel
db.Where("user_id = ? and deleted_at is null", userAuth.Payload.Id).Find(&channels)
for _, ch := range channels {
if ch.Protocol != "http" {
return fmt.Errorf("通道协议不正确,期望 http得到 %s", ch.Protocol)
if ch.Protocol != 1 {
return fmt.Errorf("通道协议不正确,期望 1(http),得到 %d", ch.Protocol)
}
if ch.UserID != userAuth.Payload.Id {
return fmt.Errorf("通道用户ID不正确期望 %d得到 %d", userAuth.Payload.Id, ch.UserID)
@@ -449,8 +450,8 @@ func Test_channelService_CreateChannel(t *testing.T) {
if ch.AuthPass != true && ch.AuthIP != false {
return fmt.Errorf("通道认证类型不正确,期望 Pass得到 %v", ch.AuthPass)
}
if ch.Protocol != info.Proto {
return fmt.Errorf("通道协议不正确,期望 %s,得到 %s", info.Proto, ch.Protocol)
if ch.Protocol != int32(info.Proto) {
return fmt.Errorf("通道协议不正确,期望 %d,得到 %d", info.Proto, ch.Protocol)
}
if ch.Username != *info.Username {
return fmt.Errorf("通道用户名不正确,期望 %s得到 %s", *info.Username, ch.Username)
@@ -485,7 +486,7 @@ func Test_channelService_CreateChannel(t *testing.T) {
if pss.DailyUsed != 3 {
return fmt.Errorf("套餐每日用量不正确,期望 3得到 %d", pss.DailyUsed)
}
if pss.DailyLast.IsZero() {
if time.Time(pss.DailyLast).IsZero() {
return fmt.Errorf("套餐每日最后更新时间不应为空")
}
if pss.Used != 3 {
@@ -569,8 +570,8 @@ func Test_channelService_CreateChannel(t *testing.T) {
// 验证结果
var gotMap = make(map[int]PortInfo)
for _, port := range got {
if port.Proto != "http" {
return fmt.Errorf("期望协议为 http得到 %s", port.Proto)
if port.Proto != 1 {
return fmt.Errorf("期望协议为 1(http),得到 %d", port.Proto)
}
if port.Host != proxy.Host {
return fmt.Errorf("期望主机为 %s得到 %s", proxy.Host, port.Host)
@@ -582,8 +583,8 @@ func Test_channelService_CreateChannel(t *testing.T) {
var channels []*models.Channel
db.Where("user_id = ? and deleted_at is null", userAuth.Payload.Id).Find(&channels)
for _, ch := range channels {
if ch.Protocol != "http" {
return fmt.Errorf("通道协议不正确,期望 http得到 %s", ch.Protocol)
if ch.Protocol != 1 {
return fmt.Errorf("通道协议不正确,期望 1(http),得到 %d", ch.Protocol)
}
if ch.UserID != userAuth.Payload.Id {
return fmt.Errorf("通道用户ID不正确期望 %d得到 %d", userAuth.Payload.Id, ch.UserID)
@@ -599,8 +600,8 @@ func Test_channelService_CreateChannel(t *testing.T) {
if ch.AuthPass != false && ch.AuthIP != true {
return fmt.Errorf("通道认证类型不正确,期望 Pass得到 %v", ch.AuthPass)
}
if ch.Protocol != info.Proto {
return fmt.Errorf("通道协议不正确,期望 %s,得到 %s", info.Proto, ch.Protocol)
if ch.Protocol != int32(info.Proto) {
return fmt.Errorf("通道协议不正确,期望 %d,得到 %d", info.Proto, ch.Protocol)
}
if ch.Expiration.IsZero() {
return fmt.Errorf("通道过期时间不应为空")
@@ -629,7 +630,7 @@ func Test_channelService_CreateChannel(t *testing.T) {
if pss.DailyUsed != 3 {
return fmt.Errorf("套餐每日用量不正确,期望 3得到 %d", pss.DailyUsed)
}
if pss.DailyLast.IsZero() {
if time.Time(pss.DailyLast).IsZero() {
return fmt.Errorf("套餐每日最后更新时间不应为空")
}
if pss.Used != 3 {
@@ -713,8 +714,8 @@ func Test_channelService_CreateChannel(t *testing.T) {
// 验证结果
var gotMap = make(map[int]PortInfo)
for _, port := range got {
if port.Proto != "socks5" {
return fmt.Errorf("期望协议为 http得到 %s", port.Proto)
if port.Proto != 3 {
return fmt.Errorf("期望协议为 1(http),得到 %d", port.Proto)
}
if port.Host != proxy.Host {
return fmt.Errorf("期望主机为 %s得到 %s", proxy.Host, port.Host)
@@ -726,8 +727,8 @@ func Test_channelService_CreateChannel(t *testing.T) {
var channels []*models.Channel
db.Where("user_id = ? and deleted_at is null", userAuth.Payload.Id).Find(&channels)
for _, ch := range channels {
if ch.Protocol != "http" {
return fmt.Errorf("通道协议不正确,期望 http得到 %s", ch.Protocol)
if ch.Protocol != 1 {
return fmt.Errorf("通道协议不正确,期望 1(http),得到 %d", ch.Protocol)
}
if ch.UserID != userAuth.Payload.Id {
return fmt.Errorf("通道用户ID不正确期望 %d得到 %d", userAuth.Payload.Id, ch.UserID)
@@ -743,8 +744,8 @@ func Test_channelService_CreateChannel(t *testing.T) {
if ch.AuthPass != true && ch.AuthIP != false {
return fmt.Errorf("通道认证类型不正确,期望 Pass得到 %v", ch.AuthPass)
}
if ch.Protocol != info.Proto {
return fmt.Errorf("通道协议不正确,期望 %s,得到 %s", info.Proto, ch.Protocol)
if ch.Protocol != int32(info.Proto) {
return fmt.Errorf("通道协议不正确,期望 %d,得到 %d", info.Proto, ch.Protocol)
}
if ch.Username != *info.Username {
return fmt.Errorf("通道用户名不正确,期望 %s得到 %s", *info.Username, ch.Username)
@@ -779,7 +780,7 @@ func Test_channelService_CreateChannel(t *testing.T) {
if pss.DailyUsed != 3 {
return fmt.Errorf("套餐每日用量不正确,期望 3得到 %d", pss.DailyUsed)
}
if pss.DailyLast.IsZero() {
if time.Time(pss.DailyLast).IsZero() {
return fmt.Errorf("套餐每日最后更新时间不应为空")
}
if pss.Used != 3 {
@@ -831,7 +832,7 @@ func Test_channelService_CreateChannel(t *testing.T) {
ResourceID: 2,
Type: 1,
Live: 180,
Expire: time.Now().AddDate(1, 0, 0),
Expire: common.LocalDateTime(time.Now().AddDate(1, 0, 0)),
DailyLimit: 10000,
}
db.Create(resourcePss2)
@@ -1022,9 +1023,9 @@ func Test_channelService_RemoveChannels(t *testing.T) {
// 创建通道
channels := []models.Channel{
{ID: 1, UserID: 101, ProxyID: 1, ProxyPort: 10001, Protocol: "http", Expiration: time.Now().Add(24 * time.Hour)},
{ID: 2, UserID: 101, ProxyID: 1, ProxyPort: 10002, Protocol: "http", Expiration: time.Now().Add(24 * time.Hour)},
{ID: 3, UserID: 101, ProxyID: 2, ProxyPort: 10001, Protocol: "socks5", Expiration: time.Now().Add(24 * time.Hour)},
{ID: 1, UserID: 101, ProxyID: 1, ProxyPort: 10001, Protocol: 1, Expiration: time.Now().Add(24 * time.Hour)},
{ID: 2, UserID: 101, ProxyID: 1, ProxyPort: 10002, Protocol: 1, Expiration: time.Now().Add(24 * time.Hour)},
{ID: 3, UserID: 101, ProxyID: 2, ProxyPort: 10001, Protocol: 3, Expiration: time.Now().Add(24 * time.Hour)},
}
// 保存预设数据
@@ -1136,9 +1137,9 @@ func Test_channelService_RemoveChannels(t *testing.T) {
// 创建通道
channels := []models.Channel{
{ID: 1, UserID: 101, ProxyID: 1, ProxyPort: 10001, Protocol: "http", Expiration: time.Now().Add(24 * time.Hour)},
{ID: 2, UserID: 101, ProxyID: 1, ProxyPort: 10002, Protocol: "http", Expiration: time.Now().Add(24 * time.Hour)},
{ID: 3, UserID: 101, ProxyID: 2, ProxyPort: 10001, Protocol: "socks5", Expiration: time.Now().Add(24 * time.Hour)},
{ID: 1, UserID: 101, ProxyID: 1, ProxyPort: 10001, Protocol: 1, Expiration: time.Now().Add(24 * time.Hour)},
{ID: 2, UserID: 101, ProxyID: 1, ProxyPort: 10002, Protocol: 1, Expiration: time.Now().Add(24 * time.Hour)},
{ID: 3, UserID: 101, ProxyID: 2, ProxyPort: 10001, Protocol: 3, Expiration: time.Now().Add(24 * time.Hour)},
}
// 保存预设数据
@@ -1250,9 +1251,9 @@ func Test_channelService_RemoveChannels(t *testing.T) {
// 创建通道
channels := []models.Channel{
{ID: 1, UserID: 101, ProxyID: 1, ProxyPort: 10001, Protocol: "http", Expiration: time.Now().Add(24 * time.Hour)},
{ID: 2, UserID: 101, ProxyID: 1, ProxyPort: 10002, Protocol: "http", Expiration: time.Now().Add(24 * time.Hour)},
{ID: 3, UserID: 102, ProxyID: 2, ProxyPort: 10001, Protocol: "socks5", Expiration: time.Now().Add(24 * time.Hour)},
{ID: 1, UserID: 101, ProxyID: 1, ProxyPort: 10001, Protocol: 1, Expiration: time.Now().Add(24 * time.Hour)},
{ID: 2, UserID: 101, ProxyID: 1, ProxyPort: 10002, Protocol: 1, Expiration: time.Now().Add(24 * time.Hour)},
{ID: 3, UserID: 102, ProxyID: 2, ProxyPort: 10001, Protocol: 3, Expiration: time.Now().Add(24 * time.Hour)},
}
// 保存预设数据

View File

@@ -13,7 +13,7 @@ import (
"github.com/redis/go-redis/v9"
)
var ID IdService = IdService{}
var ID = IdService{}
type IdService struct {
}

View File

@@ -11,6 +11,7 @@ import (
// 创建测试用的认证上下文
func createTestAuthContext() AuthContext {
//goland:noinspection ALL
return AuthContext{
Payload: Payload{
Type: PayloadUser,

View File

@@ -2,6 +2,7 @@ package services
import (
"context"
"errors"
"platform/pkg/testutil"
"strconv"
"testing"
@@ -85,8 +86,10 @@ func Test_verifierService_SendSms(t *testing.T) {
// 验证错误类型
if tt.wantErr && tt.wantErrType != nil {
if _, isSendLimitErr := err.(VerifierServiceSendLimitErr); isSendLimitErr {
if _, wantSendLimitErr := tt.wantErrType.(VerifierServiceSendLimitErr); !wantSendLimitErr {
var verifierServiceSendLimitErr VerifierServiceSendLimitErr
if errors.As(err, &verifierServiceSendLimitErr) {
var verifierServiceSendLimitErr VerifierServiceSendLimitErr
if !errors.As(tt.wantErrType, &verifierServiceSendLimitErr) {
t.Errorf("SendSms() error type = %T, wantErrType %T", err, tt.wantErrType)
}
}
@@ -216,7 +219,7 @@ func Test_verifierService_VerifySms(t *testing.T) {
}
// 检查错误类型
if tt.wantErr && tt.wantErrType != nil && err != tt.wantErrType {
if tt.wantErr && tt.wantErrType != nil && !errors.Is(err, tt.wantErrType) {
t.Errorf("VerifySms() error = %v, wantErrType %v", err, tt.wantErrType)
return
}