Files
sub2api/backend/internal/service/proxy_fallback.go
T
DaydreamCoding af19d44327 feat(proxies): 代理有效期与失败回退
- 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 问题修复
2026-06-08 00:01:30 +08:00

48 lines
1.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}
}