feat: 用户订阅显示节点分组名及限速起止时间
Build docker and publish / build (20.15.1) (push) Successful in 7m28s

- UserSubscribe/UserSubscribeDetail 新增 node_group_id/node_group_name 字段
- 管理员查询用户订阅列表批量填充分组名
- 管理员查询单个订阅详情填充分组名
- ThrottleResult/UserSubscribeDetail 新增 throttle_start/throttle_end 字段
- 限速时返回限速窗口起止时间(秒级 Unix 时间戳)

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
2026-03-29 10:07:17 -07:00
parent 1dbc3a81e9
commit a9205cc3fc
4 changed files with 49 additions and 5 deletions
+9 -5
View File
@@ -19,11 +19,13 @@ type TrafficLimitRule struct {
// ThrottleResult contains the computed speed limit status for a user subscription.
type ThrottleResult struct {
BaseSpeed int64 `json:"base_speed"` // Plan base speed limit (Mbps, 0=unlimited)
EffectiveSpeed int64 `json:"effective_speed"` // Current effective speed limit (Mbps)
IsThrottled bool `json:"is_throttled"` // Whether the user is currently throttled
ThrottleRule string `json:"throttle_rule"` // Description of the matched rule (empty if not throttled)
UsedTrafficGB float64 `json:"used_traffic_gb"` // Traffic used in the matched rule's window (GB)
BaseSpeed int64 `json:"base_speed"` // Plan base speed limit (Mbps, 0=unlimited)
EffectiveSpeed int64 `json:"effective_speed"` // Current effective speed limit (Mbps)
IsThrottled bool `json:"is_throttled"` // Whether the user is currently throttled
ThrottleRule string `json:"throttle_rule"` // Description of the matched rule (empty if not throttled)
UsedTrafficGB float64 `json:"used_traffic_gb"` // Traffic used in the matched rule's window (GB)
ThrottleStart int64 `json:"throttle_start"` // Window start Unix timestamp (seconds), 0 if not throttled
ThrottleEnd int64 `json:"throttle_end"` // Window end Unix timestamp (seconds), 0 if not throttled
}
// Calculate computes the effective speed limit for a user subscription,
@@ -89,6 +91,8 @@ func Calculate(ctx context.Context, db *gorm.DB, userId, subscribeId, baseSpeedL
result.EffectiveSpeed = rule.SpeedLimit
result.IsThrottled = true
result.UsedTrafficGB = usedGB
result.ThrottleStart = startTime.Unix()
result.ThrottleEnd = now.Unix()
statLabel := "小时"
if rule.StatType == "day" {