Skip to content

Commit d2cb472

Browse files
committed
Update.
1 parent f1a1c4b commit d2cb472

File tree

3 files changed

+97
-11
lines changed

3 files changed

+97
-11
lines changed

cmd/dashboard/controller/common_page.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -662,12 +662,14 @@ func (cp *commonPage) createFM(c *gin.Context) {
662662

663663
// 新增:/api/traffic handler,返回和首页相同结构的流量数据
664664
func (cp *commonPage) apiTraffic(c *gin.Context) {
665-
// 使用与 /server 相同的授权机制
666-
_, authorized := c.Get(model.CtxKeyAuthorizedUser)
667-
if !authorized {
665+
// 支持用户登录或view password验证
666+
_, isMember := c.Get(model.CtxKeyAuthorizedUser)
667+
_, isViewPasswordVerified := c.Get(model.CtxKeyViewPasswordVerified)
668+
669+
if !isMember && !isViewPasswordVerified {
668670
c.JSON(http.StatusForbidden, gin.H{
669671
"code": 403,
670-
"message": "请先登录",
672+
"message": "请先登录或输入访问密码",
671673
})
672674
return
673675
}
@@ -720,12 +722,14 @@ func (cp *commonPage) apiTraffic(c *gin.Context) {
720722

721723
// 新增:/api/server/:id/traffic handler,返回单个服务器的流量数据
722724
func (cp *commonPage) apiServerTraffic(c *gin.Context) {
723-
// 使用与 /server 相同的授权机制
724-
_, authorized := c.Get(model.CtxKeyAuthorizedUser)
725-
if !authorized {
725+
// 支持用户登录或view password验证
726+
_, isMember := c.Get(model.CtxKeyAuthorizedUser)
727+
_, isViewPasswordVerified := c.Get(model.CtxKeyViewPasswordVerified)
728+
729+
if !isMember && !isViewPasswordVerified {
726730
c.JSON(http.StatusForbidden, gin.H{
727731
"code": 403,
728-
"message": "请先登录",
732+
"message": "请先登录或输入访问密码",
729733
})
730734
return
731735
}

cmd/dashboard/controller/member_api.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func (ma *memberAPI) serve() {
4545
mr.POST("/cron", ma.addOrEditCron)
4646
mr.GET("/cron/:id/manual", ma.manualTrigger)
4747
mr.POST("/force-update", ma.forceUpdate)
48+
mr.POST("/traffic/refresh", ma.refreshTrafficCache)
4849
mr.POST("/batch-update-server-group", ma.batchUpdateServerGroup)
4950
mr.POST("/batch-delete-server", ma.batchDeleteServer)
5051
mr.POST("/notification", ma.addOrEditNotification)
@@ -1164,3 +1165,60 @@ func onServerDelete(id uint64) {
11641165

11651166
singleton.DB.Unscoped().Delete(&model.Transfer{}, "server_id = ?", id)
11661167
}
1168+
1169+
// refreshTrafficCache 强制刷新流量检测缓存
1170+
func (ma *memberAPI) refreshTrafficCache(c *gin.Context) {
1171+
user := c.MustGet(model.CtxKeyAuthorizedUser).(*model.User)
1172+
1173+
// 清空所有流量检测缓存
1174+
singleton.AlertsLock.Lock()
1175+
defer singleton.AlertsLock.Unlock()
1176+
1177+
clearedCount := 0
1178+
1179+
// 重置所有流量监控规则的下次更新时间
1180+
for i := 0; i < len(singleton.Alerts); i++ {
1181+
// 检查是否包含流量规则
1182+
hasTrafficRule := false
1183+
for j := 0; j < len(singleton.Alerts[i].Rules); j++ {
1184+
if singleton.Alerts[i].Rules[j].IsTransferDurationRule() {
1185+
hasTrafficRule = true
1186+
// 重置下次更新时间缓存,强制立即更新
1187+
if singleton.Alerts[i].Rules[j].NextTransferAt != nil {
1188+
for serverID := range singleton.Alerts[i].Rules[j].NextTransferAt {
1189+
singleton.Alerts[i].Rules[j].NextTransferAt[serverID] = time.Now()
1190+
clearedCount++
1191+
}
1192+
}
1193+
// 清空上次状态缓存
1194+
if singleton.Alerts[i].Rules[j].LastCycleStatus != nil {
1195+
for serverID := range singleton.Alerts[i].Rules[j].LastCycleStatus {
1196+
singleton.Alerts[i].Rules[j].LastCycleStatus[serverID] = nil
1197+
}
1198+
}
1199+
}
1200+
}
1201+
1202+
// 如果包含流量规则,也清理AlertsCycleTransferStatsStore
1203+
if hasTrafficRule && singleton.AlertsCycleTransferStatsStore[singleton.Alerts[i].ID] != nil {
1204+
for serverID := range singleton.AlertsCycleTransferStatsStore[singleton.Alerts[i].ID].NextUpdate {
1205+
singleton.AlertsCycleTransferStatsStore[singleton.Alerts[i].ID].NextUpdate[serverID] = time.Now()
1206+
}
1207+
}
1208+
}
1209+
1210+
// 同时清理流量管理器缓存
1211+
tm := singleton.GetTrafficManager()
1212+
if err := tm.SaveToDatabase(); err != nil {
1213+
c.JSON(http.StatusInternalServerError, model.Response{
1214+
Code: http.StatusInternalServerError,
1215+
Message: fmt.Sprintf("保存流量数据到数据库失败: %v", err),
1216+
})
1217+
return
1218+
}
1219+
1220+
c.JSON(http.StatusOK, model.Response{
1221+
Code: http.StatusOK,
1222+
Message: fmt.Sprintf("流量缓存刷新成功,用户: %s,清理了 %d 个服务器的流量缓存", user.Login, clearedCount),
1223+
})
1224+
}

model/rule.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,33 @@ func (u *Rule) Snapshot(cycleTransferStats *CycleTransferStats, server *Server,
139139

140140
// 循环区间流量检测 · 更新下次需要检测时间
141141
if u.IsTransferDurationRule() {
142-
seconds := 1800 * ((u.Max - src) / u.Max)
143-
if seconds < 180 {
144-
seconds = 180
142+
// 分层检测算法:根据使用率采用不同的检测频率
143+
var seconds float64
144+
if u.Max > 0 {
145+
usagePercent := (src / u.Max) * 100
146+
switch {
147+
case usagePercent >= 90:
148+
// 90%+ 使用率 → 1分钟检测(紧急)
149+
seconds = 60
150+
case usagePercent >= 60:
151+
// 60-89% 使用率 → 5分钟检测
152+
seconds = 300
153+
case usagePercent >= 25:
154+
// 25-59% 使用率 → 15分钟检测
155+
seconds = 900
156+
case usagePercent >= 5:
157+
// 5-24% 使用率 → 15分钟检测
158+
seconds = 900
159+
default:
160+
// 0-4% 使用率 → 30分钟检测,渐减到最短10分钟
161+
seconds = 1800 - (usagePercent/5.0)*600
162+
if seconds < 600 {
163+
seconds = 600
164+
}
165+
}
166+
} else {
167+
// 如果没有设置最大值,使用默认30分钟
168+
seconds = 1800
145169
}
146170
if u.NextTransferAt == nil {
147171
u.NextTransferAt = make(map[uint64]time.Time)

0 commit comments

Comments
 (0)