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={ } variant="borderless" >
{treeData.length > 0 ? ( ) : ( )}
{selectedNode ? '编辑字典项' : isEditing ? '新增字典项' : '字典详情'} } extra={ isEditing && ( {selectedNode && ( )} ) } variant="borderless" >
{isEditing ? ( <>