mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-05 17:46:37 +08:00
feat: 批量设置用户最大连接数
前端: - 用户列表添加 checkbox 多选(表格和网格视图) - 选中用户后显示「批量设置连接数」按钮 - 批量设置对话框,输入连接数后批量应用 后端: - 新增 BatchUpdateUserMaxConn repo 方法 - 新增 /api/v1/user/batch-set-max-conn API - 返回成功/失败计数 - 加入 admin-only 路由白名单
This commit is contained in:
@@ -138,6 +138,7 @@ func (h *Handler) Register(mux *http.ServeMux) {
|
||||
mux.HandleFunc("/api/v1/user/update", h.userUpdate)
|
||||
mux.HandleFunc("/api/v1/user/delete", h.userDelete)
|
||||
mux.HandleFunc("/api/v1/user/reset", h.userResetFlow)
|
||||
mux.HandleFunc("/api/v1/user/batch-set-max-conn", h.userBatchSetMaxConn)
|
||||
mux.HandleFunc("/api/v1/user/quota/reset", h.userQuotaReset)
|
||||
mux.HandleFunc("/api/v1/user/groups", h.userGroups)
|
||||
mux.HandleFunc("/api/v1/config/get", h.getConfigByName)
|
||||
|
||||
@@ -214,6 +214,26 @@ func (h *Handler) userUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
response.WriteJSON(w, response.OKEmpty())
|
||||
}
|
||||
|
||||
func (h *Handler) userBatchSetMaxConn(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
response.WriteJSON(w, response.ErrDefault("请求失败"))
|
||||
return
|
||||
}
|
||||
var req struct {
|
||||
UserIDs []int64 `json:"userIds"`
|
||||
MaxConn int `json:"maxConn"`
|
||||
}
|
||||
if err := decodeJSON(r.Body, &req); err != nil || len(req.UserIDs) == 0 {
|
||||
response.WriteJSON(w, response.ErrDefault("请求参数错误"))
|
||||
return
|
||||
}
|
||||
s, f := h.repo.BatchUpdateUserMaxConn(req.UserIDs, req.MaxConn)
|
||||
response.WriteJSON(w, response.OK(map[string]interface{}{
|
||||
"success": s,
|
||||
"failed": f,
|
||||
}))
|
||||
}
|
||||
|
||||
func (h *Handler) userGroups(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
response.WriteJSON(w, response.ErrDefault("请求失败"))
|
||||
|
||||
@@ -137,7 +137,7 @@ func requiresAdmin(path string) bool {
|
||||
}
|
||||
|
||||
switch path {
|
||||
case "/api/v1/user/create", "/api/v1/user/list", "/api/v1/user/update", "/api/v1/user/delete", "/api/v1/user/reset":
|
||||
case "/api/v1/user/create", "/api/v1/user/list", "/api/v1/user/update", "/api/v1/user/delete", "/api/v1/user/reset", "/api/v1/user/batch-set-max-conn":
|
||||
return true
|
||||
case "/api/v1/config/update", "/api/v1/config/update-single":
|
||||
return true
|
||||
|
||||
@@ -1320,6 +1320,23 @@ func (r *Repository) BatchUpdateForwardStatus(ids []int64, status int) (int, int
|
||||
return s, f
|
||||
}
|
||||
|
||||
func (r *Repository) BatchUpdateUserMaxConn(ids []int64, maxConn int) (int, int) {
|
||||
if r == nil || r.db == nil {
|
||||
return 0, len(ids)
|
||||
}
|
||||
s := 0
|
||||
f := 0
|
||||
now := time.Now().UnixMilli()
|
||||
for _, id := range ids {
|
||||
if err := r.db.Model(&model.User{}).Where("id = ?", id).Updates(map[string]interface{}{"max_conn": maxConn, "updated_time": now}).Error; err != nil {
|
||||
f++
|
||||
} else {
|
||||
s++
|
||||
}
|
||||
}
|
||||
return s, f
|
||||
}
|
||||
|
||||
func (r *Repository) CreateTunnelTx(tx *gorm.DB, name string, trafficRatio float64, typeVal int, flow int64, now int64, status int, inIP interface{}, inx int, ipPreference string) (int64, error) {
|
||||
inIPVal := nullStringFromInterface(inIP)
|
||||
tunnel := model.Tunnel{
|
||||
|
||||
Reference in New Issue
Block a user