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