2025-03-26 14:57:44 +08:00
|
|
|
|
package services
|
|
|
|
|
|
|
2025-03-26 16:34:54 +08:00
|
|
|
|
import (
|
2025-03-28 10:03:29 +08:00
|
|
|
|
"context"
|
2025-05-10 16:59:41 +08:00
|
|
|
|
g "platform/web/globals"
|
|
|
|
|
|
m "platform/web/models"
|
2025-03-26 16:34:54 +08:00
|
|
|
|
)
|
2025-03-26 14:57:44 +08:00
|
|
|
|
|
2025-05-13 09:29:13 +08:00
|
|
|
|
type EdgeServiceErr string
|
2025-03-28 10:03:29 +08:00
|
|
|
|
|
2025-05-13 09:29:13 +08:00
|
|
|
|
func (e EdgeServiceErr) Error() string {
|
2025-03-28 10:03:29 +08:00
|
|
|
|
return string(e)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-13 09:29:13 +08:00
|
|
|
|
var Edge = &edgeService{}
|
2025-03-26 14:57:44 +08:00
|
|
|
|
|
2025-05-13 09:29:13 +08:00
|
|
|
|
type edgeService struct{}
|
2025-03-26 14:57:44 +08:00
|
|
|
|
|
2025-05-13 09:29:13 +08:00
|
|
|
|
func (s *edgeService) Filter(ctx context.Context, userId int32, count int, config ...EdgeFilterConfig) ([]*m.Edge, error) {
|
|
|
|
|
|
_config := EdgeFilterConfig{}
|
2025-03-26 16:34:54 +08:00
|
|
|
|
if len(config) > 0 {
|
|
|
|
|
|
_config = config[0]
|
|
|
|
|
|
}
|
2025-03-26 14:57:44 +08:00
|
|
|
|
|
2025-03-26 16:34:54 +08:00
|
|
|
|
// 筛选符合条件且未分配给用户过的节点
|
|
|
|
|
|
// 静态条件:省,市,运营商
|
|
|
|
|
|
// 排序方式,1.分配给该用户的次数 2.分配给全部用户的次数 3.todo 节点的健康状态
|
2025-05-13 09:29:13 +08:00
|
|
|
|
var edges []*FilteredEdge
|
2025-05-10 16:59:41 +08:00
|
|
|
|
g.DB.Raw(filterSqlRaw, userId, _config.Isp, _config.Prov, _config.City).
|
2025-03-26 16:34:54 +08:00
|
|
|
|
Limit(count).
|
2025-05-13 09:29:13 +08:00
|
|
|
|
Find(&edges)
|
2025-03-26 16:34:54 +08:00
|
|
|
|
|
2025-03-28 10:03:29 +08:00
|
|
|
|
// todo 异步任务关闭代理
|
2025-03-26 16:34:54 +08:00
|
|
|
|
|
2025-03-28 10:03:29 +08:00
|
|
|
|
// todo 异步任务缩容
|
|
|
|
|
|
|
|
|
|
|
|
return nil, nil
|
2025-03-26 14:57:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-13 09:29:13 +08:00
|
|
|
|
type EdgeFilterConfig struct {
|
2025-03-28 10:03:29 +08:00
|
|
|
|
Isp string `json:"isp"`
|
|
|
|
|
|
Prov string `json:"prov"`
|
|
|
|
|
|
City string `json:"city"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-13 09:29:13 +08:00
|
|
|
|
type EdgeFilterAsyncTask struct {
|
|
|
|
|
|
Config EdgeFilterConfig `json:"config"`
|
2025-03-28 10:03:29 +08:00
|
|
|
|
Count int `json:"count"`
|
2025-03-26 16:34:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-28 10:03:29 +08:00
|
|
|
|
// 筛选节点的SQL语句,暂时用不到
|
|
|
|
|
|
// 筛选已连接的符合条件且未分配给用户过的节点
|
|
|
|
|
|
//
|
|
|
|
|
|
// 静态条件:省,市,运营商
|
|
|
|
|
|
// 排序方式,1.分配给该用户的次数 2.分配给全部用户的次数
|
2025-03-26 16:34:54 +08:00
|
|
|
|
const filterSqlRaw = `
|
|
|
|
|
|
select
|
|
|
|
|
|
n.id as id,
|
|
|
|
|
|
n.name as name,
|
2025-03-28 10:03:29 +08:00
|
|
|
|
n.host as host,
|
|
|
|
|
|
n.fwd_port as fwd_port,
|
2025-03-26 16:34:54 +08:00
|
|
|
|
count(c.*) as total,
|
|
|
|
|
|
count(c.*) filter ( where c.user_id = ? ) as assigned
|
|
|
|
|
|
from
|
2025-05-13 09:29:13 +08:00
|
|
|
|
edge n
|
2025-03-26 16:34:54 +08:00
|
|
|
|
left join public.channel c
|
2025-05-13 09:29:13 +08:00
|
|
|
|
on n.id = c.edge_id and c.expiration > now() and c.deleted_at is null
|
2025-03-26 16:34:54 +08:00
|
|
|
|
where
|
|
|
|
|
|
n.isp = ? and
|
|
|
|
|
|
n.prov = ? and
|
|
|
|
|
|
n.city = ?
|
|
|
|
|
|
group by
|
|
|
|
|
|
n.id
|
|
|
|
|
|
order by
|
|
|
|
|
|
assigned, total
|
|
|
|
|
|
`
|
|
|
|
|
|
|
2025-05-13 09:29:13 +08:00
|
|
|
|
type FilteredEdge struct {
|
2025-03-26 16:34:54 +08:00
|
|
|
|
Id int32 `json:"id"`
|
|
|
|
|
|
Name string `json:"name"`
|
2025-03-28 10:03:29 +08:00
|
|
|
|
Host string `json:"host"`
|
|
|
|
|
|
FwdPort int32 `json:"fwd_port"`
|
2025-03-26 16:34:54 +08:00
|
|
|
|
Total int32 `json:"total"`
|
|
|
|
|
|
Assigned int32 `json:"assigned"`
|
2025-03-26 14:57:44 +08:00
|
|
|
|
}
|