diff --git a/internal/web/actions/default/servers/iplists/deleteCount.go b/internal/web/actions/default/servers/iplists/deleteCount.go new file mode 100644 index 00000000..bc9d3a5e --- /dev/null +++ b/internal/web/actions/default/servers/iplists/deleteCount.go @@ -0,0 +1,82 @@ +// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. + +package iplists + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/helpers" + "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/types" + "strings" +) + +type DeleteCountAction struct { + actionutils.ParentAction +} + +func (this *DeleteCountAction) RunPost(params struct { + Ip string + Keyword string + GlobalOnly bool + Unread bool + EventLevel string + ListType string + + Count int64 +}) { + + var count = params.Count + if count <= 0 || count >= 100_000 { + this.Fail("'count' 参数错误") + return + } + + itemIdsResp, err := this.RPC().IPItemRPC().ListAllIPItemIds(this.AdminContext(), &pb.ListAllIPItemIdsRequest{ + Keyword: params.Keyword, + GlobalOnly: params.GlobalOnly, + Unread: params.Unread, + EventLevel: params.EventLevel, + ListType: params.ListType, + Ip: params.Ip, + Offset: 0, + Size: count, + }) + if err != nil { + this.ErrorPage(err) + return + } + + var itemIds = itemIdsResp.IpItemIds + + if len(itemIds) == 0 { + this.Success() + } + + // 记录日志 + defer func() { + var itemIdStrings = []string{} + for _, itemId := range itemIds { + itemIdStrings = append(itemIdStrings, types.String(itemId)) + } + + var itemIdsDescription = "" + if len(itemIdStrings) > 10 { + itemIdsDescription = strings.Join(itemIdStrings[:10], ", ") + " ..." + } else { + itemIdsDescription = strings.Join(itemIdStrings, ", ") + } + this.CreateLogInfo(codes.IPList_LogDeleteIPBatch, itemIdsDescription) + }() + + _, err = this.RPC().IPItemRPC().DeleteIPItems(this.AdminContext(), &pb.DeleteIPItemsRequest{IpItemIds: itemIds}) + if err != nil { + this.ErrorPage(err) + return + } + + // 通知左侧菜单Badge更新 + helpers.NotifyIPItemsCountChanges() + + this.Success() +} diff --git a/internal/web/actions/default/servers/iplists/index.go b/internal/web/actions/default/servers/iplists/index.go index be553dcb..ae351465 100644 --- a/internal/web/actions/default/servers/iplists/index.go +++ b/internal/web/actions/default/servers/iplists/index.go @@ -63,6 +63,7 @@ func (this *IndexAction) RunGet(params struct { } var count = countResp.Count var page = this.NewPage(count) + this.Data["totalItems"] = count this.Data["page"] = page.AsHTML() itemsResp, err := this.RPC().IPItemRPC().ListAllEnabledIPItems(this.AdminContext(), &pb.ListAllEnabledIPItemsRequest{ diff --git a/internal/web/actions/default/servers/iplists/init.go b/internal/web/actions/default/servers/iplists/init.go index 4d22db93..2a996508 100644 --- a/internal/web/actions/default/servers/iplists/init.go +++ b/internal/web/actions/default/servers/iplists/init.go @@ -22,6 +22,7 @@ func init() { Get("/exportData", new(ExportDataAction)). Post("/delete", new(DeleteAction)). Post("/deleteItems", new(DeleteItemsAction)). + Post("/deleteCount", new(DeleteCountAction)). GetPost("/test", new(TestAction)). GetPost("/update", new(UpdateAction)). Get("/items", new(ItemsAction)). diff --git a/web/public/js/components/iplist/ip-list-table.js b/web/public/js/components/iplist/ip-list-table.js index 329f1bea..068422b8 100644 --- a/web/public/js/components/iplist/ip-list-table.js +++ b/web/public/js/components/iplist/ip-list-table.js @@ -1,11 +1,18 @@ Vue.component("ip-list-table", { - props: ["v-items", "v-keyword", "v-show-search-button"], + props: ["v-items", "v-keyword", "v-show-search-button", "v-total"/** total items >= items length **/], data: function () { + let maxDeletes = 10000 + if (this.vTotal != null && this.vTotal > 0 && this.vTotal < maxDeletes) { + maxDeletes = this.vTotal + } + return { items: this.vItems, keyword: (this.vKeyword != null) ? this.vKeyword : "", selectedAll: false, - hasSelectedItems: false + hasSelectedItems: false, + + MaxDeletes: maxDeletes } }, methods: { @@ -71,6 +78,21 @@ Vue.component("ip-list-table", { teaweb.successToast("批量删除成功", 1200, teaweb.reload) }) }, + deleteCount: function () { + let that = this + teaweb.confirm("确定要批量删除当前列表中的" + this.MaxDeletes + "个IP吗?", function () { + let query = window.location.search + if (query.startsWith("?")) { + query = query.substring(1) + } + Tea.action("/servers/iplists/deleteCount?" + query) + .post() + .params({count: that.MaxDeletes}) + .success(function () { + teaweb.successToast("批量删除成功", 1200, teaweb.reload) + }) + }) + }, formatSeconds: function (seconds) { if (seconds < 60) { return seconds + "秒" @@ -86,7 +108,9 @@ Vue.component("ip-list-table", { }, template: `
- [批量删除] + +     +
diff --git a/web/views/@default/servers/iplists/index.html b/web/views/@default/servers/iplists/index.html index fb332729..7c7d8138 100644 --- a/web/views/@default/servers/iplists/index.html +++ b/web/views/@default/servers/iplists/index.html @@ -50,6 +50,6 @@

暂时还没有IP。

- +
\ No newline at end of file