import * as dictApi from '@/servers/api/dict'; import { ActionType, PageContainer, ProColumns, ProTable, } from '@ant-design/pro-components'; import { request } from '@umijs/max'; import { Button, Input, Layout, Space, Table, message } from 'antd'; import React, { useEffect, useRef, useState } from 'react'; import DictItemActions from '../../Dict/components/DictItemActions'; import DictItemModal from '../../Dict/components/DictItemModal'; const { Sider, Content } = Layout; import { notAttributes } from './consts'; const AttributePage: React.FC = () => { // 左侧字典列表状态 const [dicts, setDicts] = useState([]); const [loadingDicts, setLoadingDicts] = useState(false); const [searchText, setSearchText] = useState(''); const [selectedDict, setSelectedDict] = useState(null); // 右侧字典项 ProTable 的引用 const actionRef = useRef(); // 字典项模态框状态(由 DictItemModal 组件管理) const [isDictItemModalVisible, setIsDictItemModalVisible] = useState(false); const [isEditDictItem, setIsEditDictItem] = useState(false); const [editingDictItemData, setEditingDictItemData] = useState(null); // 导出字典项数据 const handleExportDictItems = async () => { // 条件判断,确保已选择字典 if (!selectedDict) { message.warning('请先选择字典'); return; } try { // 获取当前字典的所有数据 const response = await request('/dict/items', { params: { dictId: selectedDict.id, }, }); // 确保返回的是数组 const data = Array.isArray(response) ? response : response?.data || []; // 条件判断,检查是否有数据可导出 if (data.length === 0) { message.warning('当前字典没有数据可导出'); return; } // 将数据转换为CSV格式 const headers = [ 'name', 'title', 'titleCN', 'value', 'sort', 'image', 'shortName', ]; const csvContent = [ headers.join(','), ...data.map((item: any) => headers .map((header) => { const value = item[header] || ''; // 条件判断,如果值包含逗号或引号,需要转义 if ( typeof value === 'string' && (value.includes(',') || value.includes('"')) ) { return `"${value.replace(/"/g, '""')}"`; } return value; }) .join(','), ), ].join('\n'); // 创建blob并下载 const blob = new Blob(['\ufeff' + csvContent], { // 添加BOM以支持中文 type: 'text/csv;charset=utf-8', }); const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.setAttribute('download', `${selectedDict.name}_dict_items.csv`); document.body.appendChild(link); link.click(); link.remove(); window.URL.revokeObjectURL(url); message.success(`成功导出 ${data.length} 条数据`); } catch (error: any) { message.error('导出字典项失败:' + (error.message || '未知错误')); } }; const fetchDicts = async (title?: string) => { setLoadingDicts(true); try { const res = await request('/dict/list', { params: { title } }); // 条件判断,确保res是数组再进行过滤 const dataList = Array.isArray(res) ? res : res?.data || []; const filtered = dataList.filter((d: any) => !notAttributes.has(d?.name)); setDicts(filtered); } catch (error) { console.error('获取字典列表失败:', error); message.error('获取字典列表失败'); setDicts([]); } setLoadingDicts(false); }; // 组件挂载时初始化数据 useEffect(() => { fetchDicts(); }, []); // 搜索触发过滤 const handleSearch = (value: string) => { fetchDicts(value); }; // 打开添加字典项模态框 const handleAddDictItem = () => { setIsEditDictItem(false); setEditingDictItemData(null); setIsDictItemModalVisible(true); }; // 打开编辑字典项模态框 const handleEditDictItem = (item: any) => { setIsEditDictItem(true); setEditingDictItemData(item); setIsDictItemModalVisible(true); }; // 字典项表单提交(新增或编辑) const handleDictItemFormSubmit = async (values: any) => { try { if (isEditDictItem && editingDictItemData) { // 条件判断,存在编辑项则执行更新 await request(`/dict/item/${editingDictItemData.id}`, { method: 'PUT', data: values, }); message.success('更新成功'); } else { // 否则执行新增,绑定到当前选择的字典 await request('/dict/item', { method: 'POST', data: { ...values, dictId: selectedDict.id }, }); message.success('添加成功'); } setIsDictItemModalVisible(false); actionRef.current?.reload(); // 刷新 ProTable } catch (error) { message.error(isEditDictItem ? '更新失败' : '添加失败'); } }; // 删除字典项 const handleDeleteDictItem = async (itemId: number) => { try { const res = await request(`/dict/item/${itemId}`, { method: 'DELETE' }); const isOk = typeof res === 'boolean' ? res : res && res.code === 0 ? res.data === true || res.data === null : false; if (!isOk) { message.error('删除失败'); return; } if (selectedDict?.id) { try { const list = await request('/dict/items', { params: { dictId: selectedDict.id, }, }); // 确保list是数组再进行some操作 const dataList = Array.isArray(list) ? list : list?.data || []; const exists = dataList.some((it: any) => it.id === itemId); if (exists) { message.error('删除失败'); } else { message.success('删除成功'); actionRef.current?.reload(); } } catch (error) { console.error('验证删除结果失败:', error); message.success('删除成功'); actionRef.current?.reload(); } } else { message.success('删除成功'); actionRef.current?.reload(); } } catch (error) { message.error('删除失败'); } }; // 左侧字典列表列定义(紧凑样式) const dictColumns = [ { title: '名称', dataIndex: 'name', key: 'name' }, { title: '标题', dataIndex: 'title', key: 'title' }, ]; // 右侧字典项列表列定义(紧凑样式) const dictItemColumns: ProColumns[] = [ { title: '名称', dataIndex: 'name', key: 'name', copyable: true, sorter: true, }, { title: '标题', dataIndex: 'title', key: 'title', copyable: true, sorter: true, }, { title: '中文标题', dataIndex: 'titleCN', key: 'titleCN', copyable: true, sorter: true, }, { title: '简称', dataIndex: 'shortName', key: 'shortName', copyable: true, sorter: true, }, { title: '图片', dataIndex: 'image', key: 'image', valueType: 'image', width: 80, }, { title: '操作', key: 'action', valueType: 'option', render: (_: any, record: any) => ( ), }, ]; return ( setSearchText(e.target.value)} enterButton allowClear size="small" />
({ onClick: () => { // 条件判断,重复点击同一行则取消选择 if (selectedDict?.id === record.id) { setSelectedDict(null); } else { setSelectedDict(record); } }, })} rowClassName={(record) => selectedDict?.id === record.id ? 'ant-table-row-selected' : '' } pagination={false} /> { // 当没有选择字典时,不发起请求 if (!selectedDict?.id) { return { data: [], success: true, }; } const { name, title } = params; try { const res = await request('/dict/items', { params: { dictId: selectedDict.id, name, title, }, }); // 确保返回的是数组 const data = Array.isArray(res) ? res : res?.data || []; return { data: data, success: true, }; } catch (error) { console.error('获取字典项失败:', error); return { data: [], success: false, }; } }} rowKey="id" search={{ layout: 'vertical', }} pagination={false} options={{ reload: true, density: false, setting: { draggable: true, checkable: true, checkedReset: false, }, search: false, fullScreen: false, }} size="small" key={selectedDict?.id} headerTitle={ { // 创建 FormData 对象 const formData = new FormData(); // 添加文件到 FormData formData.append('file', file); // 添加字典 ID 到 FormData formData.append('dictId', String(dictId)); // 调用导入字典项的 API const response = await dictApi.dictcontrollerImportdictitems( formData, ); // 返回 JSON 响应 return await response.json(); }} onExport={handleExportDictItems} onAdd={handleAddDictItem} onRefreshDicts={fetchDicts} /> } /> {/* 字典项 Modal(添加或编辑) */} { setIsDictItemModalVisible(false); setEditingDictItemData(null); }} onOk={handleDictItemFormSubmit} /> ); }; export default AttributePage;