feat(quota): add tunnel traffic quota with daily/monthly limits (#291) (#308)

Implement per-tunnel traffic quota feature:
- Add TunnelQuota model with daily/monthly usage tracking
- Integrate quota enforcement into flow accumulation path
- Pause forwards and disable tunnel when quota exceeded
- Block new forward creation/resume when tunnel quota disabled
- Auto-reset daily/monthly windows at 00:05 via maintenance job
- Add manual reset API endpoint for admins
- Include quota config in tunnel backup/restore
- Add frontend UI for quota settings and usage display

Entire-Checkpoint: e629b27ca437
This commit is contained in:
sagit
2026-03-11 16:09:03 +08:00
committed by GitHub
parent 69faeaa9a6
commit 5e96a8de72
16 changed files with 1133 additions and 13 deletions
+12
View File
@@ -8,6 +8,8 @@ interface TunnelFormInput {
inNodeId: TunnelChainNode[];
outNodeId?: TunnelChainNode[];
trafficRatio: number;
dailyQuotaGB?: number;
monthlyQuotaGB?: number;
}
interface TunnelNodeInput {
@@ -24,6 +26,8 @@ export const createTunnelFormDefaults = () => {
chainNodes: [],
flow: 1,
trafficRatio: 1.0,
dailyQuotaGB: 0,
monthlyQuotaGB: 0,
inIp: "",
ipPreference: "",
status: 1,
@@ -60,6 +64,14 @@ export const validateTunnelForm = (
errors.trafficRatio = "流量倍率须大于0,支持小数(如 0.5)";
}
if ((form.dailyQuotaGB ?? 0) < 0) {
errors.dailyQuotaGB = "每日配额不能小于 0";
}
if ((form.monthlyQuotaGB ?? 0) < 0) {
errors.monthlyQuotaGB = "每月配额不能小于 0";
}
if (form.type === 2) {
if (!form.outNodeId || form.outNodeId.length === 0) {
errors.outNodeId = "请至少选择一个出口节点";