添加代理与节点的注册与端口分配接口功能

This commit is contained in:
2025-05-13 09:29:13 +08:00
parent 957d9ef443
commit 60df1548f0
17 changed files with 692 additions and 464 deletions

View File

@@ -13,7 +13,6 @@ var g *gen.Generator
func main() { func main() {
// 初始化 // 初始化
db, _ := gorm.Open( db, _ := gorm.Open(
postgres.Open("host=localhost user=test password=test dbname=app port=5432 sslmode=disable TimeZone=Asia/Shanghai"), postgres.Open("host=localhost user=test password=test dbname=app port=5432 sslmode=disable TimeZone=Asia/Shanghai"),
&gorm.Config{ &gorm.Config{
@@ -30,7 +29,7 @@ func main() {
}) })
g.UseDB(db) g.UseDB(db)
// 生成模型 // 公共参数
common := []gen.ModelOpt{ common := []gen.ModelOpt{
gen.FieldModify(func(field gen.Field) gen.Field { gen.FieldModify(func(field gen.Field) gen.Field {
if field.Type == "time.Time" { if field.Type == "time.Time" {
@@ -41,6 +40,7 @@ func main() {
gen.FieldRename("contact_qq", "ContactQQ"), gen.FieldRename("contact_qq", "ContactQQ"),
} }
// 生成模型
customs := make(map[string]any) customs := make(map[string]any)
resourcePss := g.GenerateModel("resource_pss", common...) resourcePss := g.GenerateModel("resource_pss", common...)
@@ -85,14 +85,28 @@ func main() {
)...) )...)
customs["bill"] = bill customs["bill"] = bill
edge := g.GenerateModel("edge", common...)
customs["edge"] = edge
proxy := g.GenerateModel("proxy", append(common,
gen.FieldRelate(field.HasMany, "Edges", edge, &field.RelateConfig{
GORMTag: field.GormTag{
"foreignKey": []string{"ProxyID"},
"references": []string{"ID"},
},
}),
)...)
customs["proxy"] = proxy
// 生成表结构
tables, _ := db.Migrator().GetTables() tables, _ := db.Migrator().GetTables()
models := make([]interface{}, len(tables)) models := make([]interface{}, len(tables))
for i, name := range tables { for i, name := range tables {
if customs[name] != nil { if customs[name] != nil {
models[i] = customs[name] models[i] = customs[name]
continue } else {
models[i] = g.GenerateModel(name, common...)
} }
models[i] = genBasic(name, common...)
} }
g.ApplyBasic(models...) g.ApplyBasic(models...)
@@ -101,7 +115,3 @@ func main() {
g.Execute() g.Execute()
} }
func genBasic(name string, opts ...gen.ModelOpt) any {
return g.GenerateModel(name, opts...)
}

View File

@@ -538,13 +538,14 @@ comment on column proxy.created_at is '创建时间';
comment on column proxy.updated_at is '更新时间'; comment on column proxy.updated_at is '更新时间';
comment on column proxy.deleted_at is '删除时间'; comment on column proxy.deleted_at is '删除时间';
-- node -- edge
drop table if exists node cascade; drop table if exists edge cascade;
create table node ( create table edge (
id serial primary key, id serial primary key,
proxy_id int references proxy (id) proxy_id int references proxy (id)
on update cascade on update cascade
on delete cascade, on delete cascade,
type int not null,
version int not null, version int not null,
name varchar(255) not null unique, name varchar(255) not null unique,
host varchar(255) not null, host varchar(255) not null,
@@ -559,29 +560,31 @@ create table node (
updated_at timestamp default current_timestamp, updated_at timestamp default current_timestamp,
deleted_at timestamp deleted_at timestamp
); );
create index node_isp_index on node (isp); create index edge_proxy_id_index on edge (proxy_id);
create index node_prov_index on node (prov); create index edge_type_index on edge (type);
create index node_city_index on node (city); create index edge_isp_index on edge (isp);
create index node_proxy_id_index on node (proxy_id); create index edge_prov_index on edge (prov);
create index node_deleted_at_index on node (deleted_at); create index edge_city_index on edge (city);
create index edge_deleted_at_index on edge (deleted_at);
-- node表字段注释 -- edge表字段注释
comment on table node is '节点表'; comment on table edge is '节点表';
comment on column node.id is '节点ID'; comment on column edge.id is '节点ID';
comment on column node.version is '节点版本'; comment on column edge.type is '节点类型1-自建';
comment on column node.name is '节点名称'; comment on column edge.version is '节点版本';
comment on column node.host is '节点地址'; comment on column edge.name is '节点名称';
comment on column node.isp is '运营商0-未知1-电信2-联通3-移动'; comment on column edge.host is '节点地址';
comment on column node.prov is '省份'; comment on column edge.isp is '运营商0-未知1-电信2-联通3-移动';
comment on column node.city is '城市'; comment on column edge.prov is '省份';
comment on column node.proxy_id is '代理ID'; comment on column edge.city is '城市';
comment on column node.proxy_port is '代理端口'; comment on column edge.proxy_id is '代理ID';
comment on column node.status is '节点状态0-离线1-正常'; comment on column edge.proxy_port is '代理端口';
comment on column node.rtt is '延迟'; comment on column edge.status is '节点状态0-离线1-正常';
comment on column node.loss is '丢包率'; comment on column edge.rtt is '最近平均延迟';
comment on column node.created_at is '创建时间'; comment on column edge.loss is '最近丢包率';
comment on column node.updated_at is '更新时间'; comment on column edge.created_at is '创建时间';
comment on column node.deleted_at is '删除时间'; comment on column edge.updated_at is '更新时间';
comment on column edge.deleted_at is '删除时间';
-- whitelist -- whitelist
drop table if exists whitelist cascade; drop table if exists whitelist cascade;
@@ -620,12 +623,12 @@ create table channel (
proxy_id int not null references proxy (id) -- proxy_id int not null references proxy (id) --
on update cascade -- on update cascade --
on delete set null, on delete set null,
node_id int references node (id) -- edge_id int references edge (id) --
on update cascade -- on update cascade --
on delete set null, on delete set null,
proxy_host varchar(255) not null default '', proxy_host varchar(255) not null default '',
proxy_port int not null, proxy_port int not null,
node_host varchar(255), edge_host varchar(255),
protocol int, protocol int,
auth_ip bool not null default false, auth_ip bool not null default false,
auth_pass bool not null default false, auth_pass bool not null default false,
@@ -638,10 +641,10 @@ create table channel (
); );
create index channel_user_id_index on channel (user_id); create index channel_user_id_index on channel (user_id);
create index channel_proxy_id_index on channel (proxy_id); create index channel_proxy_id_index on channel (proxy_id);
create index channel_node_id_index on channel (node_id); create index channel_edge_id_index on channel (edge_id);
create index channel_proxy_host_index on channel (proxy_host); create index channel_proxy_host_index on channel (proxy_host);
create index channel_proxy_port_index on channel (proxy_port); create index channel_proxy_port_index on channel (proxy_port);
create index channel_node_host_index on channel (node_host); create index channel_edge_host_index on channel (edge_host);
create index channel_auth_ip_index on channel (auth_ip); create index channel_auth_ip_index on channel (auth_ip);
create index channel_auth_pass_index on channel (auth_pass); create index channel_auth_pass_index on channel (auth_pass);
create index channel_username_index on channel (username); create index channel_username_index on channel (username);
@@ -653,10 +656,10 @@ comment on table channel is '通道表';
comment on column channel.id is '通道ID'; comment on column channel.id is '通道ID';
comment on column channel.user_id is '用户ID'; comment on column channel.user_id is '用户ID';
comment on column channel.proxy_id is '代理ID'; comment on column channel.proxy_id is '代理ID';
comment on column channel.node_id is '节点ID'; comment on column channel.edge_id is '节点ID';
comment on column channel.proxy_host is '代理地址'; comment on column channel.proxy_host is '代理地址';
comment on column channel.proxy_port is '转发端口'; comment on column channel.proxy_port is '转发端口';
comment on column channel.node_host is '节点地址'; comment on column channel.edge_host is '节点地址';
comment on column channel.protocol is '协议类型1-http2-https3-socks5'; comment on column channel.protocol is '协议类型1-http2-https3-socks5';
comment on column channel.auth_ip is 'IP认证'; comment on column channel.auth_ip is 'IP认证';
comment on column channel.auth_pass is '密码认证'; comment on column channel.auth_pass is '密码认证';

View File

@@ -1,4 +1,4 @@
package node package edge
type ISP int32 type ISP int32
@@ -8,3 +8,9 @@ const (
IspChinaUnicom // 中国联通 IspChinaUnicom // 中国联通
IspChinaMobile // 中国移动 IspChinaMobile // 中国移动
) )
type Type int32
const (
TypeSelfHosted Type = iota + 1 // 自建节点
)

View File

@@ -160,7 +160,7 @@ func CreateChannel(c *fiber.Ctx) error {
req.Protocol, req.Protocol,
req.AuthType, req.AuthType,
req.Count, req.Count,
s.NodeFilterConfig{ s.EdgeFilterConfig{
Isp: isp, Isp: isp,
Prov: req.Prov, Prov: req.Prov,
City: req.City, City: req.City,

63
web/handlers/edge.go Normal file
View File

@@ -0,0 +1,63 @@
package handlers
import (
"github.com/gofiber/fiber/v2"
"gorm.io/gen/field"
proxy2 "platform/web/domains/proxy"
g "platform/web/globals"
m "platform/web/models"
q "platform/web/queries"
)
type RegisterEdgeReq struct {
Name int `json:"name" validate:"required"`
Version int `json:"version" validate:"required"`
ISP int `json:"isp" validate:"required"`
Prov string `json:"prov" validate:"required"`
City string `json:"city" validate:"required"`
}
type RegisterEdgeResp struct {
Host string `json:"host"`
}
func OnlineEdge(c *fiber.Ctx) (err error) {
// 验证请求参数
var req = new(RegisterEdgeReq)
err = g.Validator.Validate(c, req)
if err != nil {
return err
}
// 挑选合适的转发服务
var fwd *m.Proxy
fwd, err = q.Proxy.Debug().
Select(q.Proxy.ALL, q.Edge.ALL.Count().As("count")).
LeftJoin(q.Edge, q.Edge.ProxyID.EqCol(q.Proxy.ID)).
Where(q.Proxy.Type.Eq(int32(proxy2.TypeSelfHosted))).
Group(q.Proxy.ID).
Order(field.NewField("", "count").Desc()).
First()
if err != nil {
return err
}
// 保存节点信息
err = q.Edge.Save(&m.Edge{
Version: int32(req.Version),
Host: c.IP(),
Isp: int32(req.ISP),
Prov: req.Prov,
City: req.City,
ProxyID: fwd.ID,
})
if err != nil {
return err
}
// 返回服务地址
return c.JSON(RegisterEdgeResp{
Host: fwd.Host,
})
}

54
web/handlers/proxy.go Normal file
View File

@@ -0,0 +1,54 @@
package handlers
import (
"github.com/gofiber/fiber/v2"
"gorm.io/gorm/clause"
auth2 "platform/web/auth"
proxy2 "platform/web/domains/proxy"
g "platform/web/globals"
m "platform/web/models"
q "platform/web/queries"
)
type RegisterProxyReq struct {
Name string `json:"name" validate:"required"`
Version int `json:"version" validate:"required"`
}
func OnlineProxy(c *fiber.Ctx) (err error) {
// 检查接口权限
_, err = auth2.NewProtect(c).Payload(
auth2.PayloadInternalServer,
).Do()
if err != nil {
return err
}
// 验证请求参数
var req = new(RegisterProxyReq)
err = g.Validator.Validate(c, req)
if err != nil {
return err
}
// 创建代理
err = q.Proxy.
Clauses(clause.OnConflict{
UpdateAll: true,
Columns: []clause.Column{
{Name: q.Proxy.Name.ColumnName().String()},
},
}).
Create(&m.Proxy{
Name: req.Name,
Version: int32(req.Version),
Host: c.IP(),
Type: int32(proxy2.TypeSelfHosted),
})
if err != nil {
return err
}
return nil
}

View File

@@ -17,10 +17,8 @@ type Channel 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
UserID int32 `gorm:"column:user_id;not null;comment:用户ID" json:"user_id"` // 用户ID UserID int32 `gorm:"column:user_id;not null;comment:用户ID" json:"user_id"` // 用户ID
ProxyID int32 `gorm:"column:proxy_id;not null;comment:代理ID" json:"proxy_id"` // 代理ID 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
ProxyHost string `gorm:"column:proxy_host;not null;comment:代理地址" json:"proxy_host"` // 代理地址 ProxyHost string `gorm:"column:proxy_host;not null;comment:代理地址" json:"proxy_host"` // 代理地址
ProxyPort int32 `gorm:"column:proxy_port;not null;comment:转发端口" json:"proxy_port"` // 转发端口 ProxyPort int32 `gorm:"column:proxy_port;not null;comment:转发端口" json:"proxy_port"` // 转发端口
NodeHost string `gorm:"column:node_host;comment:节点地址" json:"node_host"` // 节点地址
Protocol int32 `gorm:"column:protocol;comment:协议类型1-http2-https3-socks5" json:"protocol"` // 协议类型1-http2-https3-socks5 Protocol int32 `gorm:"column:protocol;comment:协议类型1-http2-https3-socks5" json:"protocol"` // 协议类型1-http2-https3-socks5
AuthIP bool `gorm:"column:auth_ip;not null;comment:IP认证" json:"auth_ip"` // IP认证 AuthIP bool `gorm:"column:auth_ip;not null;comment:IP认证" json:"auth_ip"` // IP认证
AuthPass bool `gorm:"column:auth_pass;not null;comment:密码认证" json:"auth_pass"` // 密码认证 AuthPass bool `gorm:"column:auth_pass;not null;comment:密码认证" json:"auth_pass"` // 密码认证
@@ -30,6 +28,8 @@ type Channel struct {
CreatedAt orm.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 CreatedAt orm.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
UpdatedAt orm.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 UpdatedAt orm.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"` // 删除时间
EdgeHost string `gorm:"column:edge_host;comment:节点地址" json:"edge_host"` // 节点地址
EdgeID int32 `gorm:"column:edge_id;comment:节点ID" json:"edge_id"` // 节点ID
} }
// TableName Channel's table name // TableName Channel's table name

View File

@@ -10,12 +10,13 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
const TableNameNode = "node" const TableNameEdge = "edge"
// Node mapped from table <node> // Edge mapped from table <edge>
type Node struct { type Edge 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
ProxyID int32 `gorm:"column:proxy_id;comment:代理ID" json:"proxy_id"` // 代理ID ProxyID int32 `gorm:"column:proxy_id;comment:代理ID" json:"proxy_id"` // 代理ID
Type int32 `gorm:"column:type;not null;comment:节点类型1-自建" json:"type"` // 节点类型1-自建
Version int32 `gorm:"column:version;not null;comment:节点版本" json:"version"` // 节点版本 Version int32 `gorm:"column:version;not null;comment:节点版本" json:"version"` // 节点版本
Name string `gorm:"column:name;not null;comment:节点名称" json:"name"` // 节点名称 Name string `gorm:"column:name;not null;comment:节点名称" json:"name"` // 节点名称
Host string `gorm:"column:host;not null;comment:节点地址" json:"host"` // 节点地址 Host string `gorm:"column:host;not null;comment:节点地址" json:"host"` // 节点地址
@@ -24,14 +25,14 @@ type Node struct {
City string `gorm:"column:city;not null;comment:城市" json:"city"` // 城市 City string `gorm:"column:city;not null;comment:城市" json:"city"` // 城市
ProxyPort int32 `gorm:"column:proxy_port;comment:代理端口" json:"proxy_port"` // 代理端口 ProxyPort int32 `gorm:"column:proxy_port;comment:代理端口" json:"proxy_port"` // 代理端口
Status int32 `gorm:"column:status;not null;comment:节点状态0-离线1-正常" json:"status"` // 节点状态0-离线1-正常 Status int32 `gorm:"column:status;not null;comment:节点状态0-离线1-正常" json:"status"` // 节点状态0-离线1-正常
Rtt int32 `gorm:"column:rtt;comment:延迟" json:"rtt"` // 延迟 Rtt int32 `gorm:"column:rtt;comment:最近平均延迟" json:"rtt"` // 最近平均延迟
Loss int32 `gorm:"column:loss;comment:丢包率" json:"loss"` // 丢包率 Loss int32 `gorm:"column:loss;comment:最近丢包率" json:"loss"` // 最近丢包率
CreatedAt orm.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 CreatedAt orm.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
UpdatedAt orm.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 UpdatedAt orm.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 Node's table name // TableName Edge's table name
func (*Node) TableName() string { func (*Edge) TableName() string {
return TableNameNode return TableNameEdge
} }

View File

@@ -23,6 +23,7 @@ type Proxy struct {
CreatedAt orm.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 CreatedAt orm.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
UpdatedAt orm.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 UpdatedAt orm.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"` // 删除时间
Edges []Edge `gorm:"foreignKey:ProxyID;references:ID" json:"edges"`
} }
// TableName Proxy's table name // TableName Proxy's table name

View File

@@ -30,10 +30,8 @@ func newChannel(db *gorm.DB, opts ...gen.DOOption) channel {
_channel.ID = field.NewInt32(tableName, "id") _channel.ID = field.NewInt32(tableName, "id")
_channel.UserID = field.NewInt32(tableName, "user_id") _channel.UserID = field.NewInt32(tableName, "user_id")
_channel.ProxyID = field.NewInt32(tableName, "proxy_id") _channel.ProxyID = field.NewInt32(tableName, "proxy_id")
_channel.NodeID = field.NewInt32(tableName, "node_id")
_channel.ProxyHost = field.NewString(tableName, "proxy_host") _channel.ProxyHost = field.NewString(tableName, "proxy_host")
_channel.ProxyPort = field.NewInt32(tableName, "proxy_port") _channel.ProxyPort = field.NewInt32(tableName, "proxy_port")
_channel.NodeHost = field.NewString(tableName, "node_host")
_channel.Protocol = field.NewInt32(tableName, "protocol") _channel.Protocol = field.NewInt32(tableName, "protocol")
_channel.AuthIP = field.NewBool(tableName, "auth_ip") _channel.AuthIP = field.NewBool(tableName, "auth_ip")
_channel.AuthPass = field.NewBool(tableName, "auth_pass") _channel.AuthPass = field.NewBool(tableName, "auth_pass")
@@ -43,6 +41,8 @@ func newChannel(db *gorm.DB, opts ...gen.DOOption) channel {
_channel.CreatedAt = field.NewField(tableName, "created_at") _channel.CreatedAt = field.NewField(tableName, "created_at")
_channel.UpdatedAt = field.NewField(tableName, "updated_at") _channel.UpdatedAt = field.NewField(tableName, "updated_at")
_channel.DeletedAt = field.NewField(tableName, "deleted_at") _channel.DeletedAt = field.NewField(tableName, "deleted_at")
_channel.EdgeHost = field.NewString(tableName, "edge_host")
_channel.EdgeID = field.NewInt32(tableName, "edge_id")
_channel.fillFieldMap() _channel.fillFieldMap()
@@ -56,10 +56,8 @@ type channel struct {
ID field.Int32 // 通道ID ID field.Int32 // 通道ID
UserID field.Int32 // 用户ID UserID field.Int32 // 用户ID
ProxyID field.Int32 // 代理ID ProxyID field.Int32 // 代理ID
NodeID field.Int32 // 节点ID
ProxyHost field.String // 代理地址 ProxyHost field.String // 代理地址
ProxyPort field.Int32 // 转发端口 ProxyPort field.Int32 // 转发端口
NodeHost field.String // 节点地址
Protocol field.Int32 // 协议类型1-http2-https3-socks5 Protocol field.Int32 // 协议类型1-http2-https3-socks5
AuthIP field.Bool // IP认证 AuthIP field.Bool // IP认证
AuthPass field.Bool // 密码认证 AuthPass field.Bool // 密码认证
@@ -69,6 +67,8 @@ type channel struct {
CreatedAt field.Field // 创建时间 CreatedAt field.Field // 创建时间
UpdatedAt field.Field // 更新时间 UpdatedAt field.Field // 更新时间
DeletedAt field.Field // 删除时间 DeletedAt field.Field // 删除时间
EdgeHost field.String // 节点地址
EdgeID field.Int32 // 节点ID
fieldMap map[string]field.Expr fieldMap map[string]field.Expr
} }
@@ -88,10 +88,8 @@ func (c *channel) updateTableName(table string) *channel {
c.ID = field.NewInt32(table, "id") c.ID = field.NewInt32(table, "id")
c.UserID = field.NewInt32(table, "user_id") c.UserID = field.NewInt32(table, "user_id")
c.ProxyID = field.NewInt32(table, "proxy_id") c.ProxyID = field.NewInt32(table, "proxy_id")
c.NodeID = field.NewInt32(table, "node_id")
c.ProxyHost = field.NewString(table, "proxy_host") c.ProxyHost = field.NewString(table, "proxy_host")
c.ProxyPort = field.NewInt32(table, "proxy_port") c.ProxyPort = field.NewInt32(table, "proxy_port")
c.NodeHost = field.NewString(table, "node_host")
c.Protocol = field.NewInt32(table, "protocol") c.Protocol = field.NewInt32(table, "protocol")
c.AuthIP = field.NewBool(table, "auth_ip") c.AuthIP = field.NewBool(table, "auth_ip")
c.AuthPass = field.NewBool(table, "auth_pass") c.AuthPass = field.NewBool(table, "auth_pass")
@@ -101,6 +99,8 @@ func (c *channel) updateTableName(table string) *channel {
c.CreatedAt = field.NewField(table, "created_at") c.CreatedAt = field.NewField(table, "created_at")
c.UpdatedAt = field.NewField(table, "updated_at") c.UpdatedAt = field.NewField(table, "updated_at")
c.DeletedAt = field.NewField(table, "deleted_at") c.DeletedAt = field.NewField(table, "deleted_at")
c.EdgeHost = field.NewString(table, "edge_host")
c.EdgeID = field.NewInt32(table, "edge_id")
c.fillFieldMap() c.fillFieldMap()
@@ -121,10 +121,8 @@ func (c *channel) fillFieldMap() {
c.fieldMap["id"] = c.ID c.fieldMap["id"] = c.ID
c.fieldMap["user_id"] = c.UserID c.fieldMap["user_id"] = c.UserID
c.fieldMap["proxy_id"] = c.ProxyID c.fieldMap["proxy_id"] = c.ProxyID
c.fieldMap["node_id"] = c.NodeID
c.fieldMap["proxy_host"] = c.ProxyHost c.fieldMap["proxy_host"] = c.ProxyHost
c.fieldMap["proxy_port"] = c.ProxyPort c.fieldMap["proxy_port"] = c.ProxyPort
c.fieldMap["node_host"] = c.NodeHost
c.fieldMap["protocol"] = c.Protocol c.fieldMap["protocol"] = c.Protocol
c.fieldMap["auth_ip"] = c.AuthIP c.fieldMap["auth_ip"] = c.AuthIP
c.fieldMap["auth_pass"] = c.AuthPass c.fieldMap["auth_pass"] = c.AuthPass
@@ -134,6 +132,8 @@ func (c *channel) fillFieldMap() {
c.fieldMap["created_at"] = c.CreatedAt c.fieldMap["created_at"] = c.CreatedAt
c.fieldMap["updated_at"] = c.UpdatedAt c.fieldMap["updated_at"] = c.UpdatedAt
c.fieldMap["deleted_at"] = c.DeletedAt c.fieldMap["deleted_at"] = c.DeletedAt
c.fieldMap["edge_host"] = c.EdgeHost
c.fieldMap["edge_id"] = c.EdgeID
} }
func (c channel) clone(db *gorm.DB) channel { func (c channel) clone(db *gorm.DB) channel {

379
web/queries/edge.gen.go Normal file
View File

@@ -0,0 +1,379 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package queries
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
"platform/web/models"
)
func newEdge(db *gorm.DB, opts ...gen.DOOption) edge {
_edge := edge{}
_edge.edgeDo.UseDB(db, opts...)
_edge.edgeDo.UseModel(&models.Edge{})
tableName := _edge.edgeDo.TableName()
_edge.ALL = field.NewAsterisk(tableName)
_edge.ID = field.NewInt32(tableName, "id")
_edge.ProxyID = field.NewInt32(tableName, "proxy_id")
_edge.Type = field.NewInt32(tableName, "type")
_edge.Version = field.NewInt32(tableName, "version")
_edge.Name = field.NewString(tableName, "name")
_edge.Host = field.NewString(tableName, "host")
_edge.Isp = field.NewInt32(tableName, "isp")
_edge.Prov = field.NewString(tableName, "prov")
_edge.City = field.NewString(tableName, "city")
_edge.ProxyPort = field.NewInt32(tableName, "proxy_port")
_edge.Status = field.NewInt32(tableName, "status")
_edge.Rtt = field.NewInt32(tableName, "rtt")
_edge.Loss = field.NewInt32(tableName, "loss")
_edge.CreatedAt = field.NewField(tableName, "created_at")
_edge.UpdatedAt = field.NewField(tableName, "updated_at")
_edge.DeletedAt = field.NewField(tableName, "deleted_at")
_edge.fillFieldMap()
return _edge
}
type edge struct {
edgeDo
ALL field.Asterisk
ID field.Int32 // 节点ID
ProxyID field.Int32 // 代理ID
Type field.Int32 // 节点类型1-自建
Version field.Int32 // 节点版本
Name field.String // 节点名称
Host field.String // 节点地址
Isp field.Int32 // 运营商0-未知1-电信2-联通3-移动
Prov field.String // 省份
City field.String // 城市
ProxyPort field.Int32 // 代理端口
Status field.Int32 // 节点状态0-离线1-正常
Rtt field.Int32 // 最近平均延迟
Loss field.Int32 // 最近丢包率
CreatedAt field.Field // 创建时间
UpdatedAt field.Field // 更新时间
DeletedAt field.Field // 删除时间
fieldMap map[string]field.Expr
}
func (e edge) Table(newTableName string) *edge {
e.edgeDo.UseTable(newTableName)
return e.updateTableName(newTableName)
}
func (e edge) As(alias string) *edge {
e.edgeDo.DO = *(e.edgeDo.As(alias).(*gen.DO))
return e.updateTableName(alias)
}
func (e *edge) updateTableName(table string) *edge {
e.ALL = field.NewAsterisk(table)
e.ID = field.NewInt32(table, "id")
e.ProxyID = field.NewInt32(table, "proxy_id")
e.Type = field.NewInt32(table, "type")
e.Version = field.NewInt32(table, "version")
e.Name = field.NewString(table, "name")
e.Host = field.NewString(table, "host")
e.Isp = field.NewInt32(table, "isp")
e.Prov = field.NewString(table, "prov")
e.City = field.NewString(table, "city")
e.ProxyPort = field.NewInt32(table, "proxy_port")
e.Status = field.NewInt32(table, "status")
e.Rtt = field.NewInt32(table, "rtt")
e.Loss = field.NewInt32(table, "loss")
e.CreatedAt = field.NewField(table, "created_at")
e.UpdatedAt = field.NewField(table, "updated_at")
e.DeletedAt = field.NewField(table, "deleted_at")
e.fillFieldMap()
return e
}
func (e *edge) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := e.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (e *edge) fillFieldMap() {
e.fieldMap = make(map[string]field.Expr, 16)
e.fieldMap["id"] = e.ID
e.fieldMap["proxy_id"] = e.ProxyID
e.fieldMap["type"] = e.Type
e.fieldMap["version"] = e.Version
e.fieldMap["name"] = e.Name
e.fieldMap["host"] = e.Host
e.fieldMap["isp"] = e.Isp
e.fieldMap["prov"] = e.Prov
e.fieldMap["city"] = e.City
e.fieldMap["proxy_port"] = e.ProxyPort
e.fieldMap["status"] = e.Status
e.fieldMap["rtt"] = e.Rtt
e.fieldMap["loss"] = e.Loss
e.fieldMap["created_at"] = e.CreatedAt
e.fieldMap["updated_at"] = e.UpdatedAt
e.fieldMap["deleted_at"] = e.DeletedAt
}
func (e edge) clone(db *gorm.DB) edge {
e.edgeDo.ReplaceConnPool(db.Statement.ConnPool)
return e
}
func (e edge) replaceDB(db *gorm.DB) edge {
e.edgeDo.ReplaceDB(db)
return e
}
type edgeDo struct{ gen.DO }
func (e edgeDo) Debug() *edgeDo {
return e.withDO(e.DO.Debug())
}
func (e edgeDo) WithContext(ctx context.Context) *edgeDo {
return e.withDO(e.DO.WithContext(ctx))
}
func (e edgeDo) ReadDB() *edgeDo {
return e.Clauses(dbresolver.Read)
}
func (e edgeDo) WriteDB() *edgeDo {
return e.Clauses(dbresolver.Write)
}
func (e edgeDo) Session(config *gorm.Session) *edgeDo {
return e.withDO(e.DO.Session(config))
}
func (e edgeDo) Clauses(conds ...clause.Expression) *edgeDo {
return e.withDO(e.DO.Clauses(conds...))
}
func (e edgeDo) Returning(value interface{}, columns ...string) *edgeDo {
return e.withDO(e.DO.Returning(value, columns...))
}
func (e edgeDo) Not(conds ...gen.Condition) *edgeDo {
return e.withDO(e.DO.Not(conds...))
}
func (e edgeDo) Or(conds ...gen.Condition) *edgeDo {
return e.withDO(e.DO.Or(conds...))
}
func (e edgeDo) Select(conds ...field.Expr) *edgeDo {
return e.withDO(e.DO.Select(conds...))
}
func (e edgeDo) Where(conds ...gen.Condition) *edgeDo {
return e.withDO(e.DO.Where(conds...))
}
func (e edgeDo) Order(conds ...field.Expr) *edgeDo {
return e.withDO(e.DO.Order(conds...))
}
func (e edgeDo) Distinct(cols ...field.Expr) *edgeDo {
return e.withDO(e.DO.Distinct(cols...))
}
func (e edgeDo) Omit(cols ...field.Expr) *edgeDo {
return e.withDO(e.DO.Omit(cols...))
}
func (e edgeDo) Join(table schema.Tabler, on ...field.Expr) *edgeDo {
return e.withDO(e.DO.Join(table, on...))
}
func (e edgeDo) LeftJoin(table schema.Tabler, on ...field.Expr) *edgeDo {
return e.withDO(e.DO.LeftJoin(table, on...))
}
func (e edgeDo) RightJoin(table schema.Tabler, on ...field.Expr) *edgeDo {
return e.withDO(e.DO.RightJoin(table, on...))
}
func (e edgeDo) Group(cols ...field.Expr) *edgeDo {
return e.withDO(e.DO.Group(cols...))
}
func (e edgeDo) Having(conds ...gen.Condition) *edgeDo {
return e.withDO(e.DO.Having(conds...))
}
func (e edgeDo) Limit(limit int) *edgeDo {
return e.withDO(e.DO.Limit(limit))
}
func (e edgeDo) Offset(offset int) *edgeDo {
return e.withDO(e.DO.Offset(offset))
}
func (e edgeDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *edgeDo {
return e.withDO(e.DO.Scopes(funcs...))
}
func (e edgeDo) Unscoped() *edgeDo {
return e.withDO(e.DO.Unscoped())
}
func (e edgeDo) Create(values ...*models.Edge) error {
if len(values) == 0 {
return nil
}
return e.DO.Create(values)
}
func (e edgeDo) CreateInBatches(values []*models.Edge, batchSize int) error {
return e.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (e edgeDo) Save(values ...*models.Edge) error {
if len(values) == 0 {
return nil
}
return e.DO.Save(values)
}
func (e edgeDo) First() (*models.Edge, error) {
if result, err := e.DO.First(); err != nil {
return nil, err
} else {
return result.(*models.Edge), nil
}
}
func (e edgeDo) Take() (*models.Edge, error) {
if result, err := e.DO.Take(); err != nil {
return nil, err
} else {
return result.(*models.Edge), nil
}
}
func (e edgeDo) Last() (*models.Edge, error) {
if result, err := e.DO.Last(); err != nil {
return nil, err
} else {
return result.(*models.Edge), nil
}
}
func (e edgeDo) Find() ([]*models.Edge, error) {
result, err := e.DO.Find()
return result.([]*models.Edge), err
}
func (e edgeDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.Edge, err error) {
buf := make([]*models.Edge, 0, batchSize)
err = e.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (e edgeDo) FindInBatches(result *[]*models.Edge, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return e.DO.FindInBatches(result, batchSize, fc)
}
func (e edgeDo) Attrs(attrs ...field.AssignExpr) *edgeDo {
return e.withDO(e.DO.Attrs(attrs...))
}
func (e edgeDo) Assign(attrs ...field.AssignExpr) *edgeDo {
return e.withDO(e.DO.Assign(attrs...))
}
func (e edgeDo) Joins(fields ...field.RelationField) *edgeDo {
for _, _f := range fields {
e = *e.withDO(e.DO.Joins(_f))
}
return &e
}
func (e edgeDo) Preload(fields ...field.RelationField) *edgeDo {
for _, _f := range fields {
e = *e.withDO(e.DO.Preload(_f))
}
return &e
}
func (e edgeDo) FirstOrInit() (*models.Edge, error) {
if result, err := e.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*models.Edge), nil
}
}
func (e edgeDo) FirstOrCreate() (*models.Edge, error) {
if result, err := e.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*models.Edge), nil
}
}
func (e edgeDo) FindByPage(offset int, limit int) (result []*models.Edge, count int64, err error) {
result, err = e.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = e.Offset(-1).Limit(-1).Count()
return
}
func (e edgeDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = e.Count()
if err != nil {
return
}
err = e.Offset(offset).Limit(limit).Scan(result)
return
}
func (e edgeDo) Scan(result interface{}) (err error) {
return e.DO.Scan(result)
}
func (e edgeDo) Delete(models ...*models.Edge) (result gen.ResultInfo, err error) {
return e.DO.Delete(models)
}
func (e *edgeDo) withDO(do gen.Dao) *edgeDo {
e.DO = *do.(*gen.DO)
return e
}

View File

@@ -27,8 +27,8 @@ var (
Client *client Client *client
ClientPermissionLink *clientPermissionLink ClientPermissionLink *clientPermissionLink
Coupon *coupon Coupon *coupon
Edge *edge
LogsRequest *logsRequest LogsRequest *logsRequest
Node *node
Permission *permission Permission *permission
Product *product Product *product
Proxy *proxy Proxy *proxy
@@ -58,8 +58,8 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
Client = &Q.Client Client = &Q.Client
ClientPermissionLink = &Q.ClientPermissionLink ClientPermissionLink = &Q.ClientPermissionLink
Coupon = &Q.Coupon Coupon = &Q.Coupon
Edge = &Q.Edge
LogsRequest = &Q.LogsRequest LogsRequest = &Q.LogsRequest
Node = &Q.Node
Permission = &Q.Permission Permission = &Q.Permission
Product = &Q.Product Product = &Q.Product
Proxy = &Q.Proxy Proxy = &Q.Proxy
@@ -90,8 +90,8 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
Client: newClient(db, opts...), Client: newClient(db, opts...),
ClientPermissionLink: newClientPermissionLink(db, opts...), ClientPermissionLink: newClientPermissionLink(db, opts...),
Coupon: newCoupon(db, opts...), Coupon: newCoupon(db, opts...),
Edge: newEdge(db, opts...),
LogsRequest: newLogsRequest(db, opts...), LogsRequest: newLogsRequest(db, opts...),
Node: newNode(db, opts...),
Permission: newPermission(db, opts...), Permission: newPermission(db, opts...),
Product: newProduct(db, opts...), Product: newProduct(db, opts...),
Proxy: newProxy(db, opts...), Proxy: newProxy(db, opts...),
@@ -123,8 +123,8 @@ type Query struct {
Client client Client client
ClientPermissionLink clientPermissionLink ClientPermissionLink clientPermissionLink
Coupon coupon Coupon coupon
Edge edge
LogsRequest logsRequest LogsRequest logsRequest
Node node
Permission permission Permission permission
Product product Product product
Proxy proxy Proxy proxy
@@ -157,8 +157,8 @@ func (q *Query) clone(db *gorm.DB) *Query {
Client: q.Client.clone(db), Client: q.Client.clone(db),
ClientPermissionLink: q.ClientPermissionLink.clone(db), ClientPermissionLink: q.ClientPermissionLink.clone(db),
Coupon: q.Coupon.clone(db), Coupon: q.Coupon.clone(db),
Edge: q.Edge.clone(db),
LogsRequest: q.LogsRequest.clone(db), LogsRequest: q.LogsRequest.clone(db),
Node: q.Node.clone(db),
Permission: q.Permission.clone(db), Permission: q.Permission.clone(db),
Product: q.Product.clone(db), Product: q.Product.clone(db),
Proxy: q.Proxy.clone(db), Proxy: q.Proxy.clone(db),
@@ -198,8 +198,8 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
Client: q.Client.replaceDB(db), Client: q.Client.replaceDB(db),
ClientPermissionLink: q.ClientPermissionLink.replaceDB(db), ClientPermissionLink: q.ClientPermissionLink.replaceDB(db),
Coupon: q.Coupon.replaceDB(db), Coupon: q.Coupon.replaceDB(db),
Edge: q.Edge.replaceDB(db),
LogsRequest: q.LogsRequest.replaceDB(db), LogsRequest: q.LogsRequest.replaceDB(db),
Node: q.Node.replaceDB(db),
Permission: q.Permission.replaceDB(db), Permission: q.Permission.replaceDB(db),
Product: q.Product.replaceDB(db), Product: q.Product.replaceDB(db),
Proxy: q.Proxy.replaceDB(db), Proxy: q.Proxy.replaceDB(db),
@@ -229,8 +229,8 @@ type queryCtx struct {
Client *clientDo Client *clientDo
ClientPermissionLink *clientPermissionLinkDo ClientPermissionLink *clientPermissionLinkDo
Coupon *couponDo Coupon *couponDo
Edge *edgeDo
LogsRequest *logsRequestDo LogsRequest *logsRequestDo
Node *nodeDo
Permission *permissionDo Permission *permissionDo
Product *productDo Product *productDo
Proxy *proxyDo Proxy *proxyDo
@@ -260,8 +260,8 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx {
Client: q.Client.WithContext(ctx), Client: q.Client.WithContext(ctx),
ClientPermissionLink: q.ClientPermissionLink.WithContext(ctx), ClientPermissionLink: q.ClientPermissionLink.WithContext(ctx),
Coupon: q.Coupon.WithContext(ctx), Coupon: q.Coupon.WithContext(ctx),
Edge: q.Edge.WithContext(ctx),
LogsRequest: q.LogsRequest.WithContext(ctx), LogsRequest: q.LogsRequest.WithContext(ctx),
Node: q.Node.WithContext(ctx),
Permission: q.Permission.WithContext(ctx), Permission: q.Permission.WithContext(ctx),
Product: q.Product.WithContext(ctx), Product: q.Product.WithContext(ctx),
Proxy: q.Proxy.WithContext(ctx), Proxy: q.Proxy.WithContext(ctx),

View File

@@ -1,375 +0,0 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package queries
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
"platform/web/models"
)
func newNode(db *gorm.DB, opts ...gen.DOOption) node {
_node := node{}
_node.nodeDo.UseDB(db, opts...)
_node.nodeDo.UseModel(&models.Node{})
tableName := _node.nodeDo.TableName()
_node.ALL = field.NewAsterisk(tableName)
_node.ID = field.NewInt32(tableName, "id")
_node.ProxyID = field.NewInt32(tableName, "proxy_id")
_node.Version = field.NewInt32(tableName, "version")
_node.Name = field.NewString(tableName, "name")
_node.Host = field.NewString(tableName, "host")
_node.Isp = field.NewInt32(tableName, "isp")
_node.Prov = field.NewString(tableName, "prov")
_node.City = field.NewString(tableName, "city")
_node.ProxyPort = field.NewInt32(tableName, "proxy_port")
_node.Status = field.NewInt32(tableName, "status")
_node.Rtt = field.NewInt32(tableName, "rtt")
_node.Loss = field.NewInt32(tableName, "loss")
_node.CreatedAt = field.NewField(tableName, "created_at")
_node.UpdatedAt = field.NewField(tableName, "updated_at")
_node.DeletedAt = field.NewField(tableName, "deleted_at")
_node.fillFieldMap()
return _node
}
type node struct {
nodeDo
ALL field.Asterisk
ID field.Int32 // 节点ID
ProxyID field.Int32 // 代理ID
Version field.Int32 // 节点版本
Name field.String // 节点名称
Host field.String // 节点地址
Isp field.Int32 // 运营商0-未知1-电信2-联通3-移动
Prov field.String // 省份
City field.String // 城市
ProxyPort field.Int32 // 代理端口
Status field.Int32 // 节点状态0-离线1-正常
Rtt field.Int32 // 延迟
Loss field.Int32 // 丢包率
CreatedAt field.Field // 创建时间
UpdatedAt field.Field // 更新时间
DeletedAt field.Field // 删除时间
fieldMap map[string]field.Expr
}
func (n node) Table(newTableName string) *node {
n.nodeDo.UseTable(newTableName)
return n.updateTableName(newTableName)
}
func (n node) As(alias string) *node {
n.nodeDo.DO = *(n.nodeDo.As(alias).(*gen.DO))
return n.updateTableName(alias)
}
func (n *node) updateTableName(table string) *node {
n.ALL = field.NewAsterisk(table)
n.ID = field.NewInt32(table, "id")
n.ProxyID = field.NewInt32(table, "proxy_id")
n.Version = field.NewInt32(table, "version")
n.Name = field.NewString(table, "name")
n.Host = field.NewString(table, "host")
n.Isp = field.NewInt32(table, "isp")
n.Prov = field.NewString(table, "prov")
n.City = field.NewString(table, "city")
n.ProxyPort = field.NewInt32(table, "proxy_port")
n.Status = field.NewInt32(table, "status")
n.Rtt = field.NewInt32(table, "rtt")
n.Loss = field.NewInt32(table, "loss")
n.CreatedAt = field.NewField(table, "created_at")
n.UpdatedAt = field.NewField(table, "updated_at")
n.DeletedAt = field.NewField(table, "deleted_at")
n.fillFieldMap()
return n
}
func (n *node) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := n.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (n *node) fillFieldMap() {
n.fieldMap = make(map[string]field.Expr, 15)
n.fieldMap["id"] = n.ID
n.fieldMap["proxy_id"] = n.ProxyID
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_port"] = n.ProxyPort
n.fieldMap["status"] = n.Status
n.fieldMap["rtt"] = n.Rtt
n.fieldMap["loss"] = n.Loss
n.fieldMap["created_at"] = n.CreatedAt
n.fieldMap["updated_at"] = n.UpdatedAt
n.fieldMap["deleted_at"] = n.DeletedAt
}
func (n node) clone(db *gorm.DB) node {
n.nodeDo.ReplaceConnPool(db.Statement.ConnPool)
return n
}
func (n node) replaceDB(db *gorm.DB) node {
n.nodeDo.ReplaceDB(db)
return n
}
type nodeDo struct{ gen.DO }
func (n nodeDo) Debug() *nodeDo {
return n.withDO(n.DO.Debug())
}
func (n nodeDo) WithContext(ctx context.Context) *nodeDo {
return n.withDO(n.DO.WithContext(ctx))
}
func (n nodeDo) ReadDB() *nodeDo {
return n.Clauses(dbresolver.Read)
}
func (n nodeDo) WriteDB() *nodeDo {
return n.Clauses(dbresolver.Write)
}
func (n nodeDo) Session(config *gorm.Session) *nodeDo {
return n.withDO(n.DO.Session(config))
}
func (n nodeDo) Clauses(conds ...clause.Expression) *nodeDo {
return n.withDO(n.DO.Clauses(conds...))
}
func (n nodeDo) Returning(value interface{}, columns ...string) *nodeDo {
return n.withDO(n.DO.Returning(value, columns...))
}
func (n nodeDo) Not(conds ...gen.Condition) *nodeDo {
return n.withDO(n.DO.Not(conds...))
}
func (n nodeDo) Or(conds ...gen.Condition) *nodeDo {
return n.withDO(n.DO.Or(conds...))
}
func (n nodeDo) Select(conds ...field.Expr) *nodeDo {
return n.withDO(n.DO.Select(conds...))
}
func (n nodeDo) Where(conds ...gen.Condition) *nodeDo {
return n.withDO(n.DO.Where(conds...))
}
func (n nodeDo) Order(conds ...field.Expr) *nodeDo {
return n.withDO(n.DO.Order(conds...))
}
func (n nodeDo) Distinct(cols ...field.Expr) *nodeDo {
return n.withDO(n.DO.Distinct(cols...))
}
func (n nodeDo) Omit(cols ...field.Expr) *nodeDo {
return n.withDO(n.DO.Omit(cols...))
}
func (n nodeDo) Join(table schema.Tabler, on ...field.Expr) *nodeDo {
return n.withDO(n.DO.Join(table, on...))
}
func (n nodeDo) LeftJoin(table schema.Tabler, on ...field.Expr) *nodeDo {
return n.withDO(n.DO.LeftJoin(table, on...))
}
func (n nodeDo) RightJoin(table schema.Tabler, on ...field.Expr) *nodeDo {
return n.withDO(n.DO.RightJoin(table, on...))
}
func (n nodeDo) Group(cols ...field.Expr) *nodeDo {
return n.withDO(n.DO.Group(cols...))
}
func (n nodeDo) Having(conds ...gen.Condition) *nodeDo {
return n.withDO(n.DO.Having(conds...))
}
func (n nodeDo) Limit(limit int) *nodeDo {
return n.withDO(n.DO.Limit(limit))
}
func (n nodeDo) Offset(offset int) *nodeDo {
return n.withDO(n.DO.Offset(offset))
}
func (n nodeDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *nodeDo {
return n.withDO(n.DO.Scopes(funcs...))
}
func (n nodeDo) Unscoped() *nodeDo {
return n.withDO(n.DO.Unscoped())
}
func (n nodeDo) Create(values ...*models.Node) error {
if len(values) == 0 {
return nil
}
return n.DO.Create(values)
}
func (n nodeDo) CreateInBatches(values []*models.Node, batchSize int) error {
return n.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (n nodeDo) Save(values ...*models.Node) error {
if len(values) == 0 {
return nil
}
return n.DO.Save(values)
}
func (n nodeDo) First() (*models.Node, error) {
if result, err := n.DO.First(); err != nil {
return nil, err
} else {
return result.(*models.Node), nil
}
}
func (n nodeDo) Take() (*models.Node, error) {
if result, err := n.DO.Take(); err != nil {
return nil, err
} else {
return result.(*models.Node), nil
}
}
func (n nodeDo) Last() (*models.Node, error) {
if result, err := n.DO.Last(); err != nil {
return nil, err
} else {
return result.(*models.Node), nil
}
}
func (n nodeDo) Find() ([]*models.Node, error) {
result, err := n.DO.Find()
return result.([]*models.Node), err
}
func (n nodeDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.Node, err error) {
buf := make([]*models.Node, 0, batchSize)
err = n.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (n nodeDo) FindInBatches(result *[]*models.Node, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return n.DO.FindInBatches(result, batchSize, fc)
}
func (n nodeDo) Attrs(attrs ...field.AssignExpr) *nodeDo {
return n.withDO(n.DO.Attrs(attrs...))
}
func (n nodeDo) Assign(attrs ...field.AssignExpr) *nodeDo {
return n.withDO(n.DO.Assign(attrs...))
}
func (n nodeDo) Joins(fields ...field.RelationField) *nodeDo {
for _, _f := range fields {
n = *n.withDO(n.DO.Joins(_f))
}
return &n
}
func (n nodeDo) Preload(fields ...field.RelationField) *nodeDo {
for _, _f := range fields {
n = *n.withDO(n.DO.Preload(_f))
}
return &n
}
func (n nodeDo) FirstOrInit() (*models.Node, error) {
if result, err := n.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*models.Node), nil
}
}
func (n nodeDo) FirstOrCreate() (*models.Node, error) {
if result, err := n.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*models.Node), nil
}
}
func (n nodeDo) FindByPage(offset int, limit int) (result []*models.Node, count int64, err error) {
result, err = n.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = n.Offset(-1).Limit(-1).Count()
return
}
func (n nodeDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = n.Count()
if err != nil {
return
}
err = n.Offset(offset).Limit(limit).Scan(result)
return
}
func (n nodeDo) Scan(result interface{}) (err error) {
return n.DO.Scan(result)
}
func (n nodeDo) Delete(models ...*models.Node) (result gen.ResultInfo, err error) {
return n.DO.Delete(models)
}
func (n *nodeDo) withDO(do gen.Dao) *nodeDo {
n.DO = *do.(*gen.DO)
return n
}

View File

@@ -36,6 +36,11 @@ func newProxy(db *gorm.DB, opts ...gen.DOOption) proxy {
_proxy.CreatedAt = field.NewField(tableName, "created_at") _proxy.CreatedAt = field.NewField(tableName, "created_at")
_proxy.UpdatedAt = field.NewField(tableName, "updated_at") _proxy.UpdatedAt = field.NewField(tableName, "updated_at")
_proxy.DeletedAt = field.NewField(tableName, "deleted_at") _proxy.DeletedAt = field.NewField(tableName, "deleted_at")
_proxy.Edges = proxyHasManyEdges{
db: db.Session(&gorm.Session{}),
RelationField: field.NewRelation("Edges", "models.Edge"),
}
_proxy.fillFieldMap() _proxy.fillFieldMap()
@@ -55,6 +60,7 @@ type proxy struct {
CreatedAt field.Field // 创建时间 CreatedAt field.Field // 创建时间
UpdatedAt field.Field // 更新时间 UpdatedAt field.Field // 更新时间
DeletedAt field.Field // 删除时间 DeletedAt field.Field // 删除时间
Edges proxyHasManyEdges
fieldMap map[string]field.Expr fieldMap map[string]field.Expr
} }
@@ -96,7 +102,7 @@ func (p *proxy) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
} }
func (p *proxy) fillFieldMap() { func (p *proxy) fillFieldMap() {
p.fieldMap = make(map[string]field.Expr, 9) p.fieldMap = make(map[string]field.Expr, 10)
p.fieldMap["id"] = p.ID p.fieldMap["id"] = p.ID
p.fieldMap["version"] = p.Version p.fieldMap["version"] = p.Version
p.fieldMap["name"] = p.Name p.fieldMap["name"] = p.Name
@@ -106,6 +112,7 @@ func (p *proxy) fillFieldMap() {
p.fieldMap["created_at"] = p.CreatedAt p.fieldMap["created_at"] = p.CreatedAt
p.fieldMap["updated_at"] = p.UpdatedAt p.fieldMap["updated_at"] = p.UpdatedAt
p.fieldMap["deleted_at"] = p.DeletedAt p.fieldMap["deleted_at"] = p.DeletedAt
} }
func (p proxy) clone(db *gorm.DB) proxy { func (p proxy) clone(db *gorm.DB) proxy {
@@ -118,6 +125,77 @@ func (p proxy) replaceDB(db *gorm.DB) proxy {
return p return p
} }
type proxyHasManyEdges struct {
db *gorm.DB
field.RelationField
}
func (a proxyHasManyEdges) Where(conds ...field.Expr) *proxyHasManyEdges {
if len(conds) == 0 {
return &a
}
exprs := make([]clause.Expression, 0, len(conds))
for _, cond := range conds {
exprs = append(exprs, cond.BeCond().(clause.Expression))
}
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
return &a
}
func (a proxyHasManyEdges) WithContext(ctx context.Context) *proxyHasManyEdges {
a.db = a.db.WithContext(ctx)
return &a
}
func (a proxyHasManyEdges) Session(session *gorm.Session) *proxyHasManyEdges {
a.db = a.db.Session(session)
return &a
}
func (a proxyHasManyEdges) Model(m *models.Proxy) *proxyHasManyEdgesTx {
return &proxyHasManyEdgesTx{a.db.Model(m).Association(a.Name())}
}
type proxyHasManyEdgesTx struct{ tx *gorm.Association }
func (a proxyHasManyEdgesTx) Find() (result []*models.Edge, err error) {
return result, a.tx.Find(&result)
}
func (a proxyHasManyEdgesTx) Append(values ...*models.Edge) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Append(targetValues...)
}
func (a proxyHasManyEdgesTx) Replace(values ...*models.Edge) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Replace(targetValues...)
}
func (a proxyHasManyEdgesTx) Delete(values ...*models.Edge) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Delete(targetValues...)
}
func (a proxyHasManyEdgesTx) Clear() error {
return a.tx.Clear()
}
func (a proxyHasManyEdgesTx) Count() int64 {
return a.tx.Count()
}
type proxyDo struct{ gen.DO } type proxyDo struct{ gen.DO }
func (p proxyDo) Debug() *proxyDo { func (p proxyDo) Debug() *proxyDo {

View File

@@ -62,4 +62,12 @@ func ApplyRouters(app *fiber.App) {
// 公告 // 公告
announcement := api.Group("/announcement") announcement := api.Group("/announcement")
announcement.Post("/list", handlers.ListAnnouncements) announcement.Post("/list", handlers.ListAnnouncements)
// 网关
proxy := api.Group("/proxy")
proxy.Post("/online", handlers.OnlineProxy)
// 节点
edge := api.Group("/edge")
edge.Post("/online", handlers.OnlineEdge)
} }

View File

@@ -211,13 +211,13 @@ func (s *channelService) CreateChannel(
protocol channel2.Protocol, protocol channel2.Protocol,
authType ChannelAuthType, authType ChannelAuthType,
count int, count int,
nodeFilter ...NodeFilterConfig, edgeFilter ...EdgeFilterConfig,
) (newChannels []*m.Channel, err error) { ) (newChannels []*m.Channel, err error) {
var now = time.Now() var now = time.Now()
var rid = ctx.Value(requestid.ConfigDefault.ContextKey).(string) var rid = ctx.Value(requestid.ConfigDefault.ContextKey).(string)
var filter = NodeFilterConfig{} var filter = EdgeFilterConfig{}
if len(nodeFilter) > 0 { if len(edgeFilter) > 0 {
filter = nodeFilter[0] filter = edgeFilter[0]
} }
err = q.Q.Transaction(func(q *q.Query) (err error) { err = q.Q.Transaction(func(q *q.Query) (err error) {
@@ -391,7 +391,7 @@ func calcChannels(
protocol channel2.Protocol, protocol channel2.Protocol,
authType ChannelAuthType, authType ChannelAuthType,
expiration time.Time, expiration time.Time,
filter NodeFilterConfig, filter EdgeFilterConfig,
) ([]*m.Channel, error) { ) ([]*m.Channel, error) {
var step = time.Now() var step = time.Now()
@@ -593,8 +593,8 @@ func updateResource(rid string, resource *ResourceInfo, count int, now time.Time
func saveChannels(channels []*m.Channel) (err error) { func saveChannels(channels []*m.Channel) (err error) {
err = q.Channel. err = q.Channel.
Omit( Omit(
q.Channel.NodeID, q.Channel.EdgeID,
q.Channel.NodeHost, q.Channel.EdgeHost,
q.Channel.DeletedAt, q.Channel.DeletedAt,
). ).
Create(channels...) Create(channels...)

View File

@@ -6,18 +6,18 @@ import (
m "platform/web/models" m "platform/web/models"
) )
type NodeServiceErr string type EdgeServiceErr string
func (e NodeServiceErr) Error() string { func (e EdgeServiceErr) Error() string {
return string(e) return string(e)
} }
var Node = &nodeService{} var Edge = &edgeService{}
type nodeService struct{} type edgeService struct{}
func (s *nodeService) Filter(ctx context.Context, userId int32, count int, config ...NodeFilterConfig) ([]*m.Node, error) { func (s *edgeService) Filter(ctx context.Context, userId int32, count int, config ...EdgeFilterConfig) ([]*m.Edge, error) {
_config := NodeFilterConfig{} _config := EdgeFilterConfig{}
if len(config) > 0 { if len(config) > 0 {
_config = config[0] _config = config[0]
} }
@@ -25,10 +25,10 @@ func (s *nodeService) Filter(ctx context.Context, userId int32, count int, confi
// 筛选符合条件且未分配给用户过的节点 // 筛选符合条件且未分配给用户过的节点
// 静态条件:省,市,运营商 // 静态条件:省,市,运营商
// 排序方式1.分配给该用户的次数 2.分配给全部用户的次数 3.todo 节点的健康状态 // 排序方式1.分配给该用户的次数 2.分配给全部用户的次数 3.todo 节点的健康状态
var nodes []*FilteredNode var edges []*FilteredEdge
g.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(&edges)
// todo 异步任务关闭代理 // todo 异步任务关闭代理
@@ -37,14 +37,14 @@ func (s *nodeService) Filter(ctx context.Context, userId int32, count int, confi
return nil, nil return nil, nil
} }
type NodeFilterConfig struct { type EdgeFilterConfig struct {
Isp string `json:"isp"` Isp string `json:"isp"`
Prov string `json:"prov"` Prov string `json:"prov"`
City string `json:"city"` City string `json:"city"`
} }
type NodeFilterAsyncTask struct { type EdgeFilterAsyncTask struct {
Config NodeFilterConfig `json:"config"` Config EdgeFilterConfig `json:"config"`
Count int `json:"count"` Count int `json:"count"`
} }
@@ -62,9 +62,9 @@ select
count(c.*) as total, count(c.*) as total,
count(c.*) filter ( where c.user_id = ? ) as assigned count(c.*) filter ( where c.user_id = ? ) as assigned
from from
node n edge n
left join public.channel c left join public.channel c
on n.id = c.node_id and c.expiration > now() and c.deleted_at is null on n.id = c.edge_id and c.expiration > now() and c.deleted_at is null
where where
n.isp = ? and n.isp = ? and
n.prov = ? and n.prov = ? and
@@ -75,7 +75,7 @@ order by
assigned, total assigned, total
` `
type FilteredNode struct { type FilteredEdge struct {
Id int32 `json:"id"` Id int32 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Host string `json:"host"` Host string `json:"host"`