feat(web): CRUD 页面批量操作 — 多选 + 批量删除
- 新增 selectedRowKeys 状态管理 - Table 添加 rowSelection 支持多选 - 新增批量操作栏,显示已选数量和批量删除按钮 - 批量删除调用 batchPluginData API - compact 模式下隐藏批量操作
This commit is contained in:
@@ -31,6 +31,7 @@ import {
|
|||||||
createPluginData,
|
createPluginData,
|
||||||
updatePluginData,
|
updatePluginData,
|
||||||
deletePluginData,
|
deletePluginData,
|
||||||
|
batchPluginData,
|
||||||
type PluginDataListOptions,
|
type PluginDataListOptions,
|
||||||
} from '../api/pluginData';
|
} from '../api/pluginData';
|
||||||
import EntitySelect from '../components/EntitySelect';
|
import EntitySelect from '../components/EntitySelect';
|
||||||
@@ -89,6 +90,9 @@ export default function PluginCRUDPage({
|
|||||||
// 视图切换
|
// 视图切换
|
||||||
const [viewMode, setViewMode] = useState<string>('table');
|
const [viewMode, setViewMode] = useState<string>('table');
|
||||||
|
|
||||||
|
// 批量选择
|
||||||
|
const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
|
||||||
|
|
||||||
// 详情 Drawer
|
// 详情 Drawer
|
||||||
const [detailOpen, setDetailOpen] = useState(false);
|
const [detailOpen, setDetailOpen] = useState(false);
|
||||||
const [detailRecord, setDetailRecord] = useState<Record<string, unknown> | null>(null);
|
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 = [
|
const columns = [
|
||||||
...fields.slice(0, 5).map((f) => ({
|
...fields.slice(0, 5).map((f) => ({
|
||||||
@@ -532,6 +551,34 @@ export default function PluginCRUDPage({
|
|||||||
</Space>
|
</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 ? (
|
{viewMode === 'table' || enableViews.length <= 1 ? (
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
@@ -539,6 +586,14 @@ export default function PluginCRUDPage({
|
|||||||
rowKey="_id"
|
rowKey="_id"
|
||||||
loading={loading}
|
loading={loading}
|
||||||
size={compact ? 'small' : undefined}
|
size={compact ? 'small' : undefined}
|
||||||
|
rowSelection={
|
||||||
|
compact
|
||||||
|
? undefined
|
||||||
|
: {
|
||||||
|
selectedRowKeys,
|
||||||
|
onChange: (keys) => setSelectedRowKeys(keys as string[]),
|
||||||
|
}
|
||||||
|
}
|
||||||
onChange={(_pagination, _filters, sorter) => {
|
onChange={(_pagination, _filters, sorter) => {
|
||||||
if (!Array.isArray(sorter) && sorter.field) {
|
if (!Array.isArray(sorter) && sorter.field) {
|
||||||
const newSortBy = String(sorter.field);
|
const newSortBy = String(sorter.field);
|
||||||
|
|||||||
Reference in New Issue
Block a user