feat(web): CRUD 页面批量操作 — 多选 + 批量删除

- 新增 selectedRowKeys 状态管理
- Table 添加 rowSelection 支持多选
- 新增批量操作栏,显示已选数量和批量删除按钮
- 批量删除调用 batchPluginData API
- compact 模式下隐藏批量操作
This commit is contained in:
iven
2026-04-17 11:02:01 +08:00
parent a333b3673f
commit 9549f896b6

View File

@@ -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<string>('table');
// 批量选择
const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
// 详情 Drawer
const [detailOpen, setDetailOpen] = useState(false);
const [detailRecord, setDetailRecord] = useState<Record<string, unknown> | 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({
</Space>
)}
{/* 批量操作栏 */}
{selectedRowKeys.length > 0 && !compact && (
<div
style={{
marginBottom: 16,
padding: '8px 16px',
background: 'var(--colorBgContainer, #fff)',
borderRadius: 8,
display: 'flex',
alignItems: 'center',
gap: 12,
}}
>
<span> <strong>{selectedRowKeys.length}</strong> </span>
<Popconfirm
title={`确定删除选中的 ${selectedRowKeys.length} 条记录?`}
onConfirm={handleBatchDelete}
>
<Button danger icon={<DeleteOutlined />}>
</Button>
</Popconfirm>
<Button onClick={() => setSelectedRowKeys([])}>
</Button>
</div>
)}
{viewMode === 'table' || enableViews.length <= 1 ? (
<Table
columns={columns}
@@ -539,6 +586,14 @@ export default function PluginCRUDPage({
rowKey="_id"
loading={loading}
size={compact ? 'small' : undefined}
rowSelection={
compact
? undefined
: {
selectedRowKeys,
onChange: (keys) => setSelectedRowKeys(keys as string[]),
}
}
onChange={(_pagination, _filters, sorter) => {
if (!Array.isArray(sorter) && sorter.field) {
const newSortBy = String(sorter.field);