Features:

- Node group CRUD operations with traffic-based filtering
  - Three grouping modes: average distribution, subscription-based, and traffic-based
  - Automatic and manual group recalculation with history tracking
  - Group assignment preview before applying changes
  - User subscription group locking to prevent automatic reassignment
  - Subscribe-to-group mapping configuration
  - Group calculation history and detailed reports
  - System configuration for group management (enabled/mode/auto_create)

  Database:
  - Add node_group table for group definitions
  - Add group_history and group_history_detail tables for tracking
  - Add node_group_ids (JSON) to nodes and subscribe tables
  - Add node_group_id and group_locked fields to user_subscribe table
  - Add migration files for schema changes
This commit is contained in:
EUForest
2026-03-08 23:22:38 +08:00
parent 7d46b31866
commit 39310d5b9a
72 changed files with 4682 additions and 282 deletions
+48
View File
@@ -12,6 +12,7 @@ import (
adminConsole "github.com/perfect-panel/server/internal/handler/admin/console"
adminCoupon "github.com/perfect-panel/server/internal/handler/admin/coupon"
adminDocument "github.com/perfect-panel/server/internal/handler/admin/document"
adminGroup "github.com/perfect-panel/server/internal/handler/admin/group"
adminLog "github.com/perfect-panel/server/internal/handler/admin/log"
adminMarketing "github.com/perfect-panel/server/internal/handler/admin/marketing"
adminOrder "github.com/perfect-panel/server/internal/handler/admin/order"
@@ -188,6 +189,53 @@ func RegisterHandlers(router *gin.Engine, serverCtx *svc.ServiceContext) {
adminDocumentGroupRouter.GET("/list", adminDocument.GetDocumentListHandler(serverCtx))
}
adminGroupGroupRouter := router.Group("/v1/admin/group")
adminGroupGroupRouter.Use(middleware.AuthMiddleware(serverCtx))
{
// Get group config
adminGroupGroupRouter.GET("/config", adminGroup.GetGroupConfigHandler(serverCtx))
// Update group config
adminGroupGroupRouter.PUT("/config", adminGroup.UpdateGroupConfigHandler(serverCtx))
// Export group result
adminGroupGroupRouter.GET("/export", adminGroup.ExportGroupResultHandler(serverCtx))
// Get group history
adminGroupGroupRouter.GET("/history", adminGroup.GetGroupHistoryHandler(serverCtx))
// Get group history detail
adminGroupGroupRouter.GET("/history/detail", adminGroup.GetGroupHistoryDetailHandler(serverCtx))
// Create node group
adminGroupGroupRouter.POST("/node", adminGroup.CreateNodeGroupHandler(serverCtx))
// Update node group
adminGroupGroupRouter.PUT("/node", adminGroup.UpdateNodeGroupHandler(serverCtx))
// Delete node group
adminGroupGroupRouter.DELETE("/node", adminGroup.DeleteNodeGroupHandler(serverCtx))
// Get node group list
adminGroupGroupRouter.GET("/node/list", adminGroup.GetNodeGroupListHandler(serverCtx))
// Preview user nodes
adminGroupGroupRouter.GET("/preview", adminGroup.PreviewUserNodesHandler(serverCtx))
// Recalculate group
adminGroupGroupRouter.POST("/recalculate", adminGroup.RecalculateGroupHandler(serverCtx))
// Get recalculation status
adminGroupGroupRouter.GET("/recalculation/status", adminGroup.GetRecalculationStatusHandler(serverCtx))
// Reset all groups
adminGroupGroupRouter.POST("/reset", adminGroup.ResetGroupsHandler(serverCtx))
// Get subscribe group mapping
adminGroupGroupRouter.GET("/subscribe/mapping", adminGroup.GetSubscribeGroupMappingHandler(serverCtx))
}
adminLogGroupRouter := router.Group("/v1/admin/log")
adminLogGroupRouter.Use(middleware.AuthMiddleware(serverCtx))