Jelajahi Sumber

refactor(waf): 优化 WAF 管理功能

- 将 WAF 恢复和同步续费操作的接口改为 POST 方法
- 添加 WAF 实例状态展示(已过期/未过期)
- 优化 WAF 管理列表的展示效果
- 调整任务调度的执行频率
- 修复 WAF 续费相关的一些小问题
fusu 6 hari lalu
induk
melakukan
b3f6d73737

+ 0 - 1
api/v1/admin/wagManage.go

@@ -28,5 +28,4 @@ type WafManageListRes struct {
 type RecoverWafRequest struct {
 	HostIds []int64 `json:"hostIds" form:"hostIds"`
 	Uid int64 `json:"uid" form:"uid"`
-
 }

+ 1 - 1
internal/handler/admin/wafmanage.go

@@ -62,7 +62,7 @@ func (h *WafManageHandler) SyncExecuteRenewalActions(ctx *gin.Context) {
 		return
 	}
 	defaults.SetDefaults(&req)
-	err := h.wafManageService.SyncExecuteRenewalActions(ctx,req)
+	err := h.wafManageService.SyncExecuteRenewalActions(ctx, req)
 	if err != nil {
 		v1.HandleError(ctx, http.StatusInternalServerError, err, err.Error())
 		return

+ 7 - 4
internal/repository/admin/wafmanage.go

@@ -1,10 +1,9 @@
 package admin
 
 import (
-    "context"
+	"context"
 	v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
 	adminApi "github.com/go-nunu/nunu-layout-advanced/api/v1/admin"
-	"github.com/go-nunu/nunu-layout-advanced/internal/model"
 	"github.com/go-nunu/nunu-layout-advanced/internal/repository"
 	"math"
 	"strings"
@@ -30,7 +29,7 @@ func (r *wafManageRepository) GetWafManageList(ctx context.Context,req adminApi.
 	var res []adminApi.WafManageListRes
 	var total int64
 
-	query := r.DB(ctx).Model(&model.GlobalLimit{}).Table("shd_waf as waf")
+	query := r.DB(ctx).Table("shd_waf as waf")
 
 	query = query.Joins("left join shd_clients as user on user.id = waf.uid")
 	query = query.Joins("left join shd_host as host on host.id = waf.host_id")
@@ -50,6 +49,10 @@ func (r *wafManageRepository) GetWafManageList(ctx context.Context,req adminApi.
 		query = query.Where("waf.host_id = ?", req.HostId)
 	}
 
+	if req.Uid > 0 {
+		query = query.Where("waf.uid = ?", req.Uid)
+	}
+
 	if req.Username != "" {
 		trimmedName := strings.TrimSpace(req.Username)
 		// 使用 LIKE 进行模糊匹配
@@ -84,7 +87,7 @@ func (r *wafManageRepository) GetWafManageList(ctx context.Context,req adminApi.
 	}
 
 	offset := (page - 1) * pageSize
-	result := query.Offset(offset).Limit(pageSize).Find(&res)
+	result := query.Select("waf.id, waf.host_id, waf.uid, waf.name, waf.expired_at, host.nextduedate as nextduedate, user.username as username").Offset(offset).Limit(pageSize).Find(&res)
 	if result.Error != nil {
 		return nil, result.Error
 	}

+ 2 - 2
internal/server/http.go

@@ -199,8 +199,8 @@ func NewHTTPServer(
 			strictAuthRouter.GET("admin/wafLog/getApiDescriptions", wafLogHandler.GetApiDescriptions)
 
 			strictAuthRouter.GET("/admin/wafManage/getList", wafManageHandler.GetWafManageList)
-			strictAuthRouter.GET("/admin/wafManage/recover", wafManageHandler.RecoverWaf)
-			strictAuthRouter.GET("/admin/wafManage/syncExecuteRenewalActions", wafManageHandler.SyncExecuteRenewalActions)
+			strictAuthRouter.POST("/admin/wafManage/recover", wafManageHandler.RecoverWaf)
+			strictAuthRouter.POST("/admin/wafManage/syncExecuteRenewalActions", wafManageHandler.SyncExecuteRenewalActions)
 		}
 	}
 

+ 4 - 4
internal/server/task.go

@@ -76,7 +76,7 @@ func (t *TaskServer) Start(ctx context.Context) error {
 
 
 
-	_, err := t.scheduler.Cron("0 * * * *").Do(func() {
+	_, err := t.scheduler.Cron("* * * * *").Do(func() {
 		err := t.wafTask.SynchronizationTime(ctx)
 		if err != nil {
 			t.log.Error("同步到期时间失败", zap.Error(err))
@@ -86,7 +86,7 @@ func (t *TaskServer) Start(ctx context.Context) error {
 		t.log.Error("同步到期时间注册任务失败", zap.Error(err))
 	}
 
-	_, err = t.scheduler.Cron("0 * * * *").Do(func() {
+	_, err = t.scheduler.Cron("* * * * *").Do(func() {
 		err := t.wafTask.StopPlan(ctx)
 		if err != nil {
 			t.log.Error("停止套餐失败", zap.Error(err))
@@ -97,7 +97,7 @@ func (t *TaskServer) Start(ctx context.Context) error {
 	}
 
 
-	_, err = t.scheduler.Cron("0 * * * *").Do(func() {
+	_, err = t.scheduler.Cron("* * * * *").Do(func() {
 		err := t.wafTask.RecoverRecentPlan(ctx)
 		if err != nil {
 			t.log.Error("续费失败", zap.Error(err))
@@ -108,7 +108,7 @@ func (t *TaskServer) Start(ctx context.Context) error {
 	}
 
 
-	_, err = t.scheduler.Cron("0 * * * *").Do(func() {
+	_, err = t.scheduler.Cron("* * * * *").Do(func() {
 		err := t.wafTask.CleanUpStaleRecords(ctx)
 		if err != nil {
 			t.log.Error("清理过期记录失败", zap.Error(err))

+ 2 - 3
internal/service/admin/wafmanage.go

@@ -9,7 +9,6 @@ import (
 	"github.com/go-nunu/nunu-layout-advanced/internal/repository/admin"
 	wafRep "github.com/go-nunu/nunu-layout-advanced/internal/repository/api/waf"
 	"github.com/go-nunu/nunu-layout-advanced/internal/service"
-	"go.uber.org/zap"
 	"slices"
 	"time"
 )
@@ -93,8 +92,8 @@ func (s *wafManageService) SyncExecuteRenewalActions(ctx context.Context,req adm
 		return err
 	}
 
-	if len(renewalRequest) != 0 {
-		return fmt.Errorf("续费失败,套餐距离到期时间不能小于一小时", zap.Any("实例Id", notExpiredHostIds))
+	if len(notExpiredHostIds) != 0 {
+		return fmt.Errorf("续费失败,套餐距离到期时间不能小于一小时,实例ID:%v", notExpiredHostIds)
 	}
 
 	return nil

+ 7 - 7
web/src/api/waf/wafmanage.js

@@ -3,7 +3,7 @@ import request from '~/utils/request.js'
 // 获取WAF管理列表
 export function getWafManageList(params) {
   return request({
-    url: '/v1/admin/wafManage/getList',
+    url: 'v1/admin/wafManage/getList',
     method: 'get',
     params
   })
@@ -12,17 +12,17 @@ export function getWafManageList(params) {
 // 恢复WAF实例
 export function recoverWaf(data) {
   return request({
-    url: '/v1/admin/wafManage/recover',
-    method: 'get',
-    params: data
+    url: 'v1/admin/wafManage/recover',
+    method: 'post',
+    data
   })
 }
 
 // 同步执行续费操作
 export function syncExecuteRenewalActions(data) {
   return request({
-    url: '/v1/admin/wafManage/syncExecuteRenewalActions',
-    method: 'get',
-    params: data
+    url: 'v1/admin/wafManage/syncExecuteRenewalActions',
+    method: 'post',
+    data
   })
 }

+ 32 - 5
web/src/pages/waf/instance-manage.vue

@@ -73,6 +73,11 @@
           <template v-if="column.dataIndex === 'nextDueDate'">
             {{ formatTimestamp(record.nextDueDate) }}
           </template>
+          <template v-if="column.dataIndex === 'status'">
+            <a-tag :color="getStatusColor(record.expiredAt)" style="font-weight: bold;">
+              {{ getStatusText(record.expiredAt) }}
+            </a-tag>
+          </template>
           <template v-if="column.dataIndex === 'action'">
             <a-button type="link" size="small" @click="handleSingleRecover(record)">恢复</a-button>
             <a-button type="link" size="small" @click="handleSingleSync(record)">同步</a-button>
@@ -159,7 +164,13 @@ const columns = [
     sorter: true
   },
   {
-    title: '下次到期时间',
+    title: '状态',
+    dataIndex: 'status',
+    width: 100,
+    align: 'center'
+  },
+  {
+    title: '实际套餐到期时间',
     dataIndex: 'nextDueDate',
     width: 180,
     sorter: true
@@ -194,6 +205,22 @@ const formatTimestamp = (timestamp) => {
   })
 }
 
+// 获取状态文本
+const getStatusText = (expiredAt) => {
+  if (!expiredAt) return '未知'
+  const now = Date.now()
+  const expiredTime = expiredAt * 1000
+  return expiredTime < now ? '已过期' : '未过期'
+}
+
+// 获取状态颜色
+const getStatusColor = (expiredAt) => {
+  if (!expiredAt) return 'default'
+  const now = Date.now()
+  const expiredTime = expiredAt * 1000
+  return expiredTime < now ? 'red' : 'green'
+}
+
 // 获取数据
 const fetchData = async () => {
   loading.value = true
@@ -282,7 +309,7 @@ const handleRecover = () => {
         }
 
         const response = await recoverWaf({
-          hostIds: selectedRowKeys.value,
+          hostIds: selectedRecords.map(item => item.hostId),
           uid: uids[0]
         })
         
@@ -327,7 +354,7 @@ const handleSyncTime = () => {
         }
 
         const response = await syncExecuteRenewalActions({
-          hostIds: selectedRowKeys.value,
+          hostIds: selectedRecords.map(item => item.hostId),
           uid: uids[0]
         })
         
@@ -356,7 +383,7 @@ const handleSingleRecover = (record) => {
     onOk: async () => {
       try {
         const response = await recoverWaf({
-          hostIds: [record.id],
+          hostIds: [record.hostId],
           uid: record.uid
         })
         
@@ -382,7 +409,7 @@ const handleSingleSync = (record) => {
     onOk: async () => {
       try {
         const response = await syncExecuteRenewalActions({
-          hostIds: [record.id],
+          hostIds: [record.hostId],
           uid: record.uid
         })