feat(subscribe): add traffic limit rules and user traffic stats

- Add subscribe traffic_limit schema and migration\n- Support traffic_limit in admin create/update and list/details\n- Apply traffic_limit when building server user list speed limits\n- Add public user traffic stats API
This commit is contained in:
EUForest
2026-03-14 12:41:52 +08:00
parent 17163486f6
commit 06a2425474
34 changed files with 974 additions and 153 deletions
+21 -13
View File
@@ -28,22 +28,30 @@ type (
}
// CreateNodeGroupRequest
CreateNodeGroupRequest {
Name string `json:"name" validate:"required"`
Description string `json:"description"`
Sort int `json:"sort"`
ForCalculation *bool `json:"for_calculation"`
MinTrafficGB *int64 `json:"min_traffic_gb,omitempty"`
MaxTrafficGB *int64 `json:"max_traffic_gb,omitempty"`
Name string `json:"name" validate:"required"`
Description string `json:"description"`
Sort int `json:"sort"`
ForCalculation *bool `json:"for_calculation"`
IsExpiredGroup *bool `json:"is_expired_group"`
ExpiredDaysLimit *int `json:"expired_days_limit"`
MaxTrafficGBExpired *int64 `json:"max_traffic_gb_expired,omitempty"`
SpeedLimit *int `json:"speed_limit"`
MinTrafficGB *int64 `json:"min_traffic_gb,omitempty"`
MaxTrafficGB *int64 `json:"max_traffic_gb,omitempty"`
}
// UpdateNodeGroupRequest
UpdateNodeGroupRequest {
Id int64 `json:"id" validate:"required"`
Name string `json:"name"`
Description string `json:"description"`
Sort int `json:"sort"`
ForCalculation *bool `json:"for_calculation"`
MinTrafficGB *int64 `json:"min_traffic_gb,omitempty"`
MaxTrafficGB *int64 `json:"max_traffic_gb,omitempty"`
Id int64 `json:"id" validate:"required"`
Name string `json:"name"`
Description string `json:"description"`
Sort int `json:"sort"`
ForCalculation *bool `json:"for_calculation"`
IsExpiredGroup *bool `json:"is_expired_group"`
ExpiredDaysLimit *int `json:"expired_days_limit"`
MaxTrafficGBExpired *int64 `json:"max_traffic_gb_expired,omitempty"`
SpeedLimit *int `json:"speed_limit"`
MinTrafficGB *int64 `json:"min_traffic_gb,omitempty"`
MaxTrafficGB *int64 `json:"max_traffic_gb,omitempty"`
}
// DeleteNodeGroupRequest
DeleteNodeGroupRequest {
+2
View File
@@ -50,6 +50,7 @@ type (
NodeTags []string `json:"node_tags"`
NodeGroupIds []int64 `json:"node_group_ids,omitempty"`
NodeGroupId int64 `json:"node_group_id"`
TrafficLimit []TrafficLimit `json:"traffic_limit"`
Show *bool `json:"show"`
Sell *bool `json:"sell"`
DeductionRatio int64 `json:"deduction_ratio"`
@@ -77,6 +78,7 @@ type (
NodeTags []string `json:"node_tags"`
NodeGroupIds []int64 `json:"node_group_ids,omitempty"`
NodeGroupId int64 `json:"node_group_id"`
TrafficLimit []TrafficLimit `json:"traffic_limit"`
Show *bool `json:"show"`
Sell *bool `json:"sell"`
Sort int64 `json:"sort"`
+20
View File
@@ -144,6 +144,22 @@ type (
HistoryContinuousDays int64 `json:"history_continuous_days"`
LongestSingleConnection int64 `json:"longest_single_connection"`
}
GetUserTrafficStatsRequest {
UserSubscribeId string `form:"user_subscribe_id" validate:"required"`
Days int `form:"days" validate:"required,oneof=7 30"`
}
DailyTrafficStats {
Date string `json:"date"`
Upload int64 `json:"upload"`
Download int64 `json:"download"`
Total int64 `json:"total"`
}
GetUserTrafficStatsResponse {
List []DailyTrafficStats `json:"list"`
TotalUpload int64 `json:"total_upload"`
TotalDownload int64 `json:"total_download"`
TotalTraffic int64 `json:"total_traffic"`
}
)
@server (
@@ -271,6 +287,10 @@ service ppanel {
@doc "Delete Current User Account"
@handler DeleteCurrentUserAccount
delete /current_user_account
@doc "Get User Traffic Statistics"
@handler GetUserTrafficStats
get /traffic_stats (GetUserTrafficStatsRequest) returns (GetUserTrafficStatsResponse)
}
@server (
+22 -10
View File
@@ -211,6 +211,12 @@ type (
Quantity int64 `json:"quantity"`
Discount float64 `json:"discount"`
}
TrafficLimit {
StatType string `json:"stat_type"`
StatValue int64 `json:"stat_value"`
TrafficUsage int64 `json:"traffic_usage"`
SpeedLimit int64 `json:"speed_limit"`
}
Subscribe {
Id int64 `json:"id"`
Name string `json:"name"`
@@ -229,6 +235,7 @@ type (
NodeTags []string `json:"node_tags"`
NodeGroupIds []int64 `json:"node_group_ids,omitempty"`
NodeGroupId int64 `json:"node_group_id"`
TrafficLimit []TrafficLimit `json:"traffic_limit"`
Show bool `json:"show"`
Sell bool `json:"sell"`
Sort int64 `json:"sort"`
@@ -486,6 +493,7 @@ type (
}
UserSubscribe {
Id int64 `json:"id"`
IdStr string `json:"id_str"`
UserId int64 `json:"user_id"`
OrderId int64 `json:"order_id"`
SubscribeId int64 `json:"subscribe_id"`
@@ -882,16 +890,20 @@ type (
// ===== 分组功能类型定义 =====
// NodeGroup 节点组
NodeGroup {
Id int64 `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Sort int `json:"sort"`
ForCalculation bool `json:"for_calculation"`
MinTrafficGB int64 `json:"min_traffic_gb,omitempty"`
MaxTrafficGB int64 `json:"max_traffic_gb,omitempty"`
NodeCount int64 `json:"node_count,omitempty"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
Id int64 `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Sort int `json:"sort"`
ForCalculation bool `json:"for_calculation"`
IsExpiredGroup bool `json:"is_expired_group"`
ExpiredDaysLimit int `json:"expired_days_limit"`
MaxTrafficGBExpired int64 `json:"max_traffic_gb_expired,omitempty"`
SpeedLimit int `json:"speed_limit"`
MinTrafficGB int64 `json:"min_traffic_gb,omitempty"`
MaxTrafficGB int64 `json:"max_traffic_gb,omitempty"`
NodeCount int64 `json:"node_count,omitempty"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
// GroupHistory 分组历史记录
GroupHistory {