From 9549f896b65dde5277ba767b20b942272400e126 Mon Sep 17 00:00:00 2001 From: iven Date: Fri, 17 Apr 2026 11:02:01 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20CRUD=20=E9=A1=B5=E9=9D=A2=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=93=8D=E4=BD=9C=20=E2=80=94=20=E5=A4=9A=E9=80=89=20?= =?UTF-8?q?+=20=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 selectedRowKeys 状态管理 - Table 添加 rowSelection 支持多选 - 新增批量操作栏,显示已选数量和批量删除按钮 - 批量删除调用 batchPluginData API - compact 模式下隐藏批量操作 --- apps/web/src/pages/PluginCRUDPage.tsx | 55 +++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/apps/web/src/pages/PluginCRUDPage.tsx b/apps/web/src/pages/PluginCRUDPage.tsx index 8f3fc58..22cef4a 100644 --- a/apps/web/src/pages/PluginCRUDPage.tsx +++ b/apps/web/src/pages/PluginCRUDPage.tsx @@ -31,6 +31,7 @@ import { createPluginData, updatePluginData, deletePluginData, + batchPluginData, type PluginDataListOptions, } from '../api/pluginData'; import EntitySelect from '../components/EntitySelect'; @@ -89,6 +90,9 @@ export default function PluginCRUDPage({ // 视图切换 const [viewMode, setViewMode] = useState('table'); + // 批量选择 + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + // 详情 Drawer const [detailOpen, setDetailOpen] = useState(false); const [detailRecord, setDetailRecord] = useState | null>(null); @@ -240,6 +244,21 @@ export default function PluginCRUDPage({ } }; + const handleBatchDelete = async () => { + if (!pluginId || !entityName || selectedRowKeys.length === 0) return; + try { + await batchPluginData(pluginId, entityName, { + action: 'delete', + ids: selectedRowKeys, + }); + message.success(`已删除 ${selectedRowKeys.length} 条记录`); + setSelectedRowKeys([]); + fetchData(); + } catch { + message.error('批量删除失败'); + } + }; + // 动态生成列 const columns = [ ...fields.slice(0, 5).map((f) => ({ @@ -532,6 +551,34 @@ export default function PluginCRUDPage({ )} + {/* 批量操作栏 */} + {selectedRowKeys.length > 0 && !compact && ( +
+ 已选择 {selectedRowKeys.length} + + + + +
+ )} + {viewMode === 'table' || enableViews.length <= 1 ? ( setSelectedRowKeys(keys as string[]), + } + } onChange={(_pagination, _filters, sorter) => { if (!Array.isArray(sorter) && sorter.field) { const newSortBy = String(sorter.field);