import React, { useState, useEffect } from 'react';
import { Tree, Button, Form, Input, InputNumber, Select, Switch, Space, Card, Empty, Popconfirm, App, Row, Col, Typography, Checkbox } from 'antd';
import {
BookOutlined,
PlusOutlined,
SaveOutlined,
DeleteOutlined,
FolderOpenOutlined,
FileOutlined,
CloseOutlined
} from '@ant-design/icons';
import apiClient from '../../utils/apiClient';
import { buildApiUrl, API_ENDPOINTS } from '../../config/api';
const { Option } = Select;
const { TextArea } = Input;
const { Title, Text } = Typography;
const DictManagement = () => {
const { message } = App.useApp();
const [loading, setLoading] = useState(false);
const [dictTypes, setDictTypes] = useState([]); // 字典类型列表
const [selectedDictType, setSelectedDictType] = useState('client_platform'); // 当前选中的字典类型
const [dictData, setDictData] = useState([]); // 当前字典类型的数据
const [treeData, setTreeData] = useState([]); // 树形结构数据
const [selectedNode, setSelectedNode] = useState(null); // 当前选中的节点
const [isEditing, setIsEditing] = useState(false); // 是否处于编辑状态
const [form] = Form.useForm();
// 获取所有字典类型
const fetchDictTypes = async () => {
try {
const response = await apiClient.get(buildApiUrl(API_ENDPOINTS.DICT_DATA.TYPES));
if (response.code === '200') {
const types = (response.data.types || []).filter((type) => type !== 'system_config');
setDictTypes(types);
if (!types.includes(selectedDictType)) {
setSelectedDictType(types[0] || '');
}
}
} catch (error) {
message.error('获取字典类型失败');
}
};
// 获取指定类型的字典数据
const fetchDictData = async (dictType) => {
setLoading(true);
try {
const response = await apiClient.get(buildApiUrl(API_ENDPOINTS.DICT_DATA.BY_TYPE(dictType)));
if (response.code === '200') {
setDictData(response.data.items);
// 转换为 antd Tree 需要的格式
const antdTreeData = buildAntdTreeData(response.data.tree);
setTreeData(antdTreeData);
// 清空选中节点
setSelectedNode(null);
setIsEditing(false);
form.resetFields();
}
} catch (error) {
message.error('获取字典数据失败');
} finally {
setLoading(false);
}
};
// 将树形数据转换为 antd Tree 组件格式
const buildAntdTreeData = (tree) => {
return tree.map(node => ({
title: (
{node.parent_code === 'ROOT' ? : }
{node.label_cn}
({node.dict_code})
),
key: node.dict_code,
data: node,
children: node.children && node.children.length > 0 ? buildAntdTreeData(node.children) : []
}));
};
useEffect(() => {
fetchDictTypes();
}, []);
useEffect(() => {
if (selectedDictType) {
fetchDictData(selectedDictType);
}
}, [selectedDictType]);
// 选中树节点
const handleSelectNode = (selectedKeys, info) => {
if (selectedKeys.length > 0) {
const nodeData = info.node.data;
setSelectedNode(nodeData);
setIsEditing(true);
// 填充表单
form.setFieldsValue({
dict_type: nodeData.dict_type,
dict_code: nodeData.dict_code,
parent_code: nodeData.parent_code,
label_cn: nodeData.label_cn,
label_en: nodeData.label_en,
sort_order: nodeData.sort_order,
extension_attr: nodeData.extension_attr ? JSON.stringify(nodeData.extension_attr, null, 2) : '',
is_default: nodeData.is_default === 1,
status: nodeData.status
});
}
};
// 新增节点
const handleAddNode = () => {
setSelectedNode(null);
setIsEditing(true);
form.resetFields();
form.setFieldsValue({
dict_type: selectedDictType,
parent_code: 'ROOT',
sort_order: 0,
status: 1,
is_default: false
});
};
// 保存
const handleSave = async () => {
try {
const values = await form.validateFields();
// 解析 extension_attr JSON
if (values.extension_attr) {
try {
values.extension_attr = JSON.parse(values.extension_attr);
} catch (e) {
message.error('扩展属性 JSON 格式错误');
return;
}
}
// 转换 is_default 为数字
values.is_default = values.is_default ? 1 : 0;
if (selectedNode) {
// 更新
const response = await apiClient.put(
buildApiUrl(API_ENDPOINTS.DICT_DATA.UPDATE(selectedNode.id)),
values
);
if (response.code === '200') {
message.success('更新成功');
fetchDictData(selectedDictType);
}
} else {
// 新增
const response = await apiClient.post(
buildApiUrl(API_ENDPOINTS.DICT_DATA.CREATE),
values
);
if (response.code === '200') {
message.success('创建成功');
fetchDictData(selectedDictType);
}
}
} catch (error) {
if (!error.errorFields) {
message.error(error.response?.data?.message || '操作失败');
}
}
};
// 删除
const handleDelete = async () => {
if (!selectedNode) return;
try {
await apiClient.delete(buildApiUrl(API_ENDPOINTS.DICT_DATA.DELETE(selectedNode.id)));
message.success('删除成功');
setSelectedNode(null);
setIsEditing(false);
form.resetFields();
fetchDictData(selectedDictType);
} catch (error) {
message.error('删除失败');
}
};
// 取消编辑
const handleCancel = () => {
setIsEditing(false);
setSelectedNode(null);
form.resetFields();
};
// 获取父级选项
const getParentOptions = () => {
const options = [{ label: 'ROOT(顶级)', value: 'ROOT' }];
dictData.forEach(item => {
if (item.parent_code === 'ROOT') {
options.push({ label: `${item.label_cn} (${item.dict_code})`, value: item.dict_code });
}
});
return options;
};
return (
字典管理
字典树
}
extra={
}
onClick={handleAddNode}
>
新增
}
variant="borderless"
>
{treeData.length > 0 ? (
) : (
)}
{selectedNode ? '编辑字典项' : isEditing ? '新增字典项' : '字典详情'}
}
extra={
isEditing && (
{selectedNode && (
} className="btn-soft-red">删除
)}
} onClick={handleCancel}>取消
}
onClick={handleSave}
>
保存
)
}
variant="borderless"
>
设为默认
>
) : (
)}
);
};
export default DictManagement;