mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-24 16:05:44 +08:00
- schema/迁移: 代理有效期、提醒天数、失败回退配置 + 账号 fallback 来源字段 - service/repo/DTO/handler: CRUD 透传新字段 + 校验 - fallback 目标解析纯函数(链式解析 + 环检测 + 兜底) - SweepExpiredProxies 到期改投账号 + outbox 失效 - ProxyExpiryService 后台到期扫描任务 + wire 注册 - 账号侧手动回切原代理 + fallback 来源徽章/按钮 - 前端: 创建/编辑表单、列表到期徽章、类型/API/i18n - ops 告警: proxy_expired_count / proxy_expiring_soon_count 指标 - 导入导出携带有效期/回退字段(备用按 name 映射) - 补全测试 stub + 集成测试 + review 问题修复
48 lines
1.2 KiB
Go
48 lines
1.2 KiB
Go
package service
|
||
|
||
import "time"
|
||
|
||
// ResolveProxyFallbackTarget 计算一个过期代理 start 应把账号改投到哪里。
|
||
// 返回 (targetID, change):
|
||
// - change=false:不改动账号(mode=none,或链路成环/无解的兜底)
|
||
// - change=true, targetID=nil:改投为直连
|
||
// - change=true, targetID!=nil:改投到该备用代理 id
|
||
//
|
||
// byID 是「全部代理」的快照(id -> Proxy),now 为判定基准时间。
|
||
func ResolveProxyFallbackTarget(start Proxy, byID map[int64]Proxy, now time.Time) (*int64, bool) {
|
||
switch start.FallbackMode {
|
||
case FallbackModeDirect:
|
||
return nil, true
|
||
case FallbackModeProxy:
|
||
visited := map[int64]struct{}{start.ID: {}}
|
||
curID := start.BackupProxyID
|
||
for {
|
||
if curID == nil {
|
||
return nil, false
|
||
}
|
||
if _, seen := visited[*curID]; seen {
|
||
return nil, false
|
||
}
|
||
p, ok := byID[*curID]
|
||
if !ok {
|
||
return nil, false
|
||
}
|
||
if !(&p).IsExpired(now) && p.Status != StatusExpired {
|
||
id := p.ID
|
||
return &id, true
|
||
}
|
||
visited[*curID] = struct{}{}
|
||
switch p.FallbackMode {
|
||
case FallbackModeDirect:
|
||
return nil, true
|
||
case FallbackModeProxy:
|
||
curID = p.BackupProxyID
|
||
default:
|
||
return nil, false
|
||
}
|
||
}
|
||
default:
|
||
return nil, false
|
||
}
|
||
}
|