imetting/frontend/src/pages/admin/ParameterManagement.jsx

191 lines
6.7 KiB
JavaScript

import React, { useEffect, useState } from 'react';
import { App, Button, Drawer, Form, Input, Popconfirm, Select, Space, Switch, Table, Tag, Tooltip } from 'antd';
import { DeleteOutlined, EditOutlined, PlusOutlined, ReloadOutlined, SaveOutlined, SettingOutlined } from '@ant-design/icons';
import apiClient from '../../utils/apiClient';
import { API_ENDPOINTS, buildApiUrl } from '../../config/api';
import AdminModuleShell from '../../components/AdminModuleShell';
import ActionButton from '../../components/ActionButton';
import StatusTag from '../../components/StatusTag';
const ParameterManagement = () => {
const { message } = App.useApp();
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(false);
const [drawerOpen, setDrawerOpen] = useState(false);
const [editing, setEditing] = useState(null);
const [submitting, setSubmitting] = useState(false);
const [form] = Form.useForm();
const fetchItems = async () => {
setLoading(true);
try {
const res = await apiClient.get(buildApiUrl(API_ENDPOINTS.ADMIN.PARAMETERS));
setItems(res.data.items || []);
} catch {
message.error('获取参数列表失败');
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchItems();
}, []);
const openCreate = () => {
setEditing(null);
form.setFieldsValue({
param_key: '',
param_name: '',
param_value: '',
value_type: 'string',
category: 'system',
description: '',
is_active: true,
});
setDrawerOpen(true);
};
const openEdit = (row) => {
setEditing(row);
form.setFieldsValue({
...row,
is_active: Boolean(row.is_active),
});
setDrawerOpen(true);
};
const submit = async () => {
const values = await form.validateFields();
setSubmitting(true);
try {
if (editing) {
await apiClient.put(buildApiUrl(API_ENDPOINTS.ADMIN.PARAMETER_DETAIL(editing.param_key)), values);
message.success('参数更新成功');
} else {
await apiClient.post(buildApiUrl(API_ENDPOINTS.ADMIN.PARAMETERS), values);
message.success('参数创建成功');
}
setDrawerOpen(false);
fetchItems();
} catch (error) {
message.error(error?.response?.data?.message || '参数保存失败');
} finally {
setSubmitting(false);
}
};
const columns = [
{ title: '参数键', dataIndex: 'param_key', key: 'param_key', width: 220 },
{ title: '参数名', dataIndex: 'param_name', key: 'param_name', width: 180 },
{ title: '值', dataIndex: 'param_value', key: 'param_value' },
{ title: '类型', dataIndex: 'value_type', key: 'value_type', width: 100, render: (v) => <Tag>{v}</Tag> },
{ title: '分类', dataIndex: 'category', key: 'category', width: 120 },
{
title: '状态',
dataIndex: 'is_active',
key: 'is_active',
width: 90,
render: (v) => <StatusTag active={v} />,
},
{
title: '操作',
key: 'action',
width: 90,
render: (_, row) => (
<Space size={6}>
<ActionButton tone="edit" variant="iconSm" tooltip="编辑" icon={<EditOutlined />} onClick={() => openEdit(row)} />
<Popconfirm
title="确认删除参数?"
description={`参数键:${row.param_key}`}
okText="删除"
cancelText="取消"
okButtonProps={{ danger: true }}
onConfirm={async () => {
try {
await apiClient.delete(buildApiUrl(API_ENDPOINTS.ADMIN.PARAMETER_DELETE(row.param_key)));
message.success('参数删除成功');
fetchItems();
} catch (error) {
message.error(error?.response?.data?.message || '参数删除失败');
}
}}
>
<ActionButton tone="delete" variant="iconSm" tooltip="删除" icon={<DeleteOutlined />} />
</Popconfirm>
</Space>
),
},
];
return (
<div>
<AdminModuleShell
icon={<SettingOutlined style={{ fontSize: 18, color: '#1d4ed8' }} />}
title="参数管理"
subtitle="系统参数已从字典 system_config 迁移到专用参数表。"
rightActions={(
<Space>
<Button icon={<ReloadOutlined />} onClick={fetchItems} loading={loading}>刷新</Button>
<Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>新增参数</Button>
</Space>
)}
stats={[
{ label: '参数总数', value: items.length },
{ label: '启用参数', value: items.filter((item) => item.is_active).length },
]}
>
<div className="console-table">
<Table
rowKey="param_key"
columns={columns}
dataSource={items}
loading={loading}
pagination={{ pageSize: 10, showTotal: (count) => `${count}` }}
scroll={{ x: 1100 }}
/>
</div>
</AdminModuleShell>
<Drawer
title={editing ? '编辑参数' : '新增参数'}
placement="right"
width={560}
open={drawerOpen}
onClose={() => setDrawerOpen(false)}
extra={(
<Space>
<Button type="primary" icon={<SaveOutlined />} loading={submitting} onClick={submit}>保存</Button>
</Space>
)}
>
<Form form={form} layout="vertical">
<Form.Item name="param_key" label="参数键" rules={[{ required: true, message: '请输入参数键' }]}>
<Input placeholder="timeline_pagesize" disabled={Boolean(editing)} />
</Form.Item>
<Form.Item name="param_name" label="参数名" rules={[{ required: true, message: '请输入参数名' }]}>
<Input placeholder="会议时间轴分页大小" />
</Form.Item>
<Form.Item name="param_value" label="参数值" rules={[{ required: true, message: '请输入参数值' }]}>
<Input.TextArea rows={3} />
</Form.Item>
<Form.Item name="value_type" label="值类型" rules={[{ required: true, message: '请选择值类型' }]}>
<Select options={[{ label: 'string', value: 'string' }, { label: 'number', value: 'number' }, { label: 'json', value: 'json' }]} />
</Form.Item>
<Form.Item name="category" label="分类">
<Input placeholder="system" />
</Form.Item>
<Form.Item name="description" label="描述">
<Input.TextArea rows={2} />
</Form.Item>
<Form.Item name="is_active" label="启用状态" valuePropName="checked">
<Switch />
</Form.Item>
</Form>
</Drawer>
</div>
);
};
export default ParameterManagement;