frist
This commit is contained in:
16
internal/model/errors.go
Normal file
16
internal/model/errors.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package model
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrNoProxy = errors.New("no available proxy")
|
||||
ErrBadModulo = errors.New("modulo must be positive")
|
||||
ErrBadPolicy = errors.New("unknown selection policy")
|
||||
ErrLeaseExpired = errors.New("lease expired or not found")
|
||||
ErrProxyNotFound = errors.New("proxy not found")
|
||||
ErrInvalidURL = errors.New("invalid URL")
|
||||
ErrPrivateIP = errors.New("private IP address not allowed")
|
||||
ErrUnsafeScheme = errors.New("only http and https schemes are allowed")
|
||||
ErrInvalidPatch = errors.New("invalid patch: no fields to update")
|
||||
ErrBulkDeleteEmpty = errors.New("bulk delete requires at least one condition")
|
||||
)
|
||||
258
internal/model/types.go
Normal file
258
internal/model/types.go
Normal file
@@ -0,0 +1,258 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// ProxyProtocol 代理协议类型
|
||||
type ProxyProtocol string
|
||||
|
||||
const (
|
||||
ProtoHTTP ProxyProtocol = "http"
|
||||
ProtoHTTPS ProxyProtocol = "https"
|
||||
ProtoSOCKS5 ProxyProtocol = "socks5"
|
||||
)
|
||||
|
||||
// ProxyStatus 代理状态
|
||||
type ProxyStatus string
|
||||
|
||||
const (
|
||||
StatusUnknown ProxyStatus = "unknown"
|
||||
StatusAlive ProxyStatus = "alive"
|
||||
StatusDead ProxyStatus = "dead"
|
||||
)
|
||||
|
||||
// Proxy 代理实体
|
||||
type Proxy struct {
|
||||
ID string // uuid
|
||||
|
||||
Protocol ProxyProtocol
|
||||
Host string
|
||||
Port int
|
||||
Username string
|
||||
Password string
|
||||
|
||||
Group string
|
||||
Tags []string
|
||||
|
||||
Status ProxyStatus
|
||||
Score int
|
||||
LatencyMs int64
|
||||
LastCheckAt time.Time
|
||||
|
||||
FailCount int
|
||||
SuccessCount int
|
||||
Disabled bool
|
||||
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// HealthPatch 健康度更新补丁
|
||||
type HealthPatch struct {
|
||||
Status *ProxyStatus
|
||||
ScoreDelta int
|
||||
LatencyMs *int64
|
||||
CheckedAt *time.Time
|
||||
FailInc int
|
||||
SuccessInc int
|
||||
}
|
||||
|
||||
// TestSpec 测试规格
|
||||
type TestSpec struct {
|
||||
URL string
|
||||
Method string
|
||||
Timeout time.Duration
|
||||
ExpectStatus []int
|
||||
ExpectContains string
|
||||
}
|
||||
|
||||
// TestResult 测试结果
|
||||
type TestResult struct {
|
||||
ProxyID string
|
||||
OK bool
|
||||
LatencyMs int64
|
||||
ErrorText string
|
||||
CheckedAt time.Time
|
||||
}
|
||||
|
||||
// Lease 租约
|
||||
type Lease struct {
|
||||
LeaseID string
|
||||
ProxyID string
|
||||
Proxy Proxy
|
||||
ExpireAt time.Time
|
||||
Group string
|
||||
Site string
|
||||
}
|
||||
|
||||
// ProxyQuery 代理查询条件
|
||||
type ProxyQuery struct {
|
||||
Group string
|
||||
TagsAny []string
|
||||
StatusIn []ProxyStatus
|
||||
OnlyEnabled bool
|
||||
Limit int
|
||||
OrderBy string // "random", "score", "latency",默认按 score 降序
|
||||
}
|
||||
|
||||
// InvalidLine 无效行记录
|
||||
type InvalidLine struct {
|
||||
Raw string `json:"raw"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
// SelectRequest 代理选择请求
|
||||
type SelectRequest struct {
|
||||
Group string
|
||||
Site string
|
||||
Policy string // round_robin, random, weighted
|
||||
TagsAny []string
|
||||
}
|
||||
|
||||
// ImportInput 导入输入参数
|
||||
type ImportInput struct {
|
||||
Group string
|
||||
Tags []string
|
||||
ProtocolHint string // auto, http, https, socks5
|
||||
}
|
||||
|
||||
// ImportResult 导入结果
|
||||
type ImportResult struct {
|
||||
Imported int `json:"imported"`
|
||||
Duplicated int `json:"duplicated"`
|
||||
Invalid int `json:"invalid"`
|
||||
InvalidItems []InvalidLine `json:"invalid_items,omitempty"`
|
||||
}
|
||||
|
||||
// TestSummary 测试摘要
|
||||
type TestSummary struct {
|
||||
Tested int `json:"tested"`
|
||||
Alive int `json:"alive"`
|
||||
Dead int `json:"dead"`
|
||||
}
|
||||
|
||||
// TestBatchResult 批量测试结果
|
||||
type TestBatchResult struct {
|
||||
Summary TestSummary `json:"summary"`
|
||||
Results []TestResult `json:"results"`
|
||||
}
|
||||
|
||||
// NextProxyResponse 获取下一个代理的响应
|
||||
type NextProxyResponse struct {
|
||||
Proxy ProxyInfo `json:"proxy"`
|
||||
LeaseID string `json:"lease_id"`
|
||||
TTLMs int64 `json:"ttl_ms"`
|
||||
}
|
||||
|
||||
// ProxyInfo 代理信息(用于 API 响应)
|
||||
type ProxyInfo struct {
|
||||
ID string `json:"id"`
|
||||
Protocol ProxyProtocol `json:"protocol"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
}
|
||||
|
||||
// ReportRequest 上报请求
|
||||
type ReportRequest struct {
|
||||
LeaseID string `json:"lease_id"`
|
||||
ProxyID string `json:"proxy_id"`
|
||||
Success bool `json:"success"`
|
||||
Error string `json:"error,omitempty"`
|
||||
LatencyMs int64 `json:"latency_ms"`
|
||||
}
|
||||
|
||||
// TestRequest 测试请求
|
||||
type TestRequest struct {
|
||||
Group string `json:"group"`
|
||||
Filter ProxyFilter `json:"filter"`
|
||||
TestSpec TestSpecReq `json:"test_spec"`
|
||||
Concurrency int `json:"concurrency"`
|
||||
UpdateStore bool `json:"update_store"`
|
||||
WriteLog bool `json:"write_log"`
|
||||
}
|
||||
|
||||
// ProxyFilter 代理过滤条件
|
||||
type ProxyFilter struct {
|
||||
Status []string `json:"status"`
|
||||
TagsAny []string `json:"tags_any"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
// TestSpecReq 测试规格请求
|
||||
type TestSpecReq struct {
|
||||
URL string `json:"url"`
|
||||
Method string `json:"method"`
|
||||
TimeoutMs int `json:"timeout_ms"`
|
||||
ExpectStatus []int `json:"expect_status"`
|
||||
ExpectContains string `json:"expect_contains"`
|
||||
}
|
||||
|
||||
// ImportTextRequest 文本导入请求
|
||||
type ImportTextRequest struct {
|
||||
Group string `json:"group"`
|
||||
Tags []string `json:"tags"`
|
||||
ProtocolHint string `json:"protocol_hint"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
// ProxyListQuery 代理列表查询条件(带分页)
|
||||
type ProxyListQuery struct {
|
||||
Group string
|
||||
TagsAny []string
|
||||
StatusIn []ProxyStatus
|
||||
OnlyEnabled bool
|
||||
Offset int
|
||||
Limit int
|
||||
}
|
||||
|
||||
// ProxyListResponse 代理列表分页响应
|
||||
type ProxyListResponse struct {
|
||||
Data []Proxy `json:"data"`
|
||||
Total int `json:"total"`
|
||||
Offset int `json:"offset"`
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
// ProxyPatch 代理更新补丁
|
||||
type ProxyPatch struct {
|
||||
Group *string `json:"group,omitempty"`
|
||||
Tags *[]string `json:"tags,omitempty"`
|
||||
AddTags []string `json:"add_tags,omitempty"`
|
||||
Disabled *bool `json:"disabled,omitempty"`
|
||||
}
|
||||
|
||||
// BulkDeleteRequest 批量删除请求
|
||||
type BulkDeleteRequest struct {
|
||||
IDs []string `json:"ids,omitempty"`
|
||||
Status ProxyStatus `json:"status,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
Disabled *bool `json:"disabled,omitempty"`
|
||||
}
|
||||
|
||||
// BulkDeleteResponse 批量删除响应
|
||||
type BulkDeleteResponse struct {
|
||||
Deleted int `json:"deleted"`
|
||||
}
|
||||
|
||||
// SingleTestRequest 单个代理测试请求
|
||||
type SingleTestRequest struct {
|
||||
URL string `json:"url"`
|
||||
Method string `json:"method,omitempty"`
|
||||
TimeoutMs int `json:"timeout_ms,omitempty"`
|
||||
ExpectStatus []int `json:"expect_status,omitempty"`
|
||||
ExpectContains string `json:"expect_contains,omitempty"`
|
||||
UpdateStore bool `json:"update_store"`
|
||||
WriteLog bool `json:"write_log"`
|
||||
}
|
||||
|
||||
// ProxyStats 代理统计信息
|
||||
type ProxyStats struct {
|
||||
Total int `json:"total"`
|
||||
ByStatus map[ProxyStatus]int `json:"by_status"`
|
||||
ByGroup map[string]int `json:"by_group"`
|
||||
ByProtocol map[ProxyProtocol]int `json:"by_protocol"`
|
||||
Disabled int `json:"disabled"`
|
||||
AvgLatencyMs int64 `json:"avg_latency_ms"`
|
||||
AvgScore float64 `json:"avg_score"`
|
||||
}
|
||||
Reference in New Issue
Block a user