// apps/web/src/components/models/term/term-manager.tsx import { Button, Input, Modal, Space, Table, TreeSelect, Select, Card, Row, Col, Typography, Divider, } from "antd"; import { api } from "@nice/client"; import { useState, useEffect } from "react"; import { PlusOutlined, EditOutlined, DeleteOutlined, SearchOutlined, FileTextOutlined, } from "@ant-design/icons"; import { ObjectType } from "@nice/common"; const { Title } = Typography; interface TermManagerProps { title: string; } export default function DeviceManager({ title }: TermManagerProps) { const [isModalVisible, setIsModalVisible] = useState(false); const [editingTerm, setEditingTerm] = useState(null); const [termName, setTermName] = useState(""); const [parentId, setParentId] = useState(null); const [taxonomyId, setTaxonomyId] = useState(null); const [searchValue, setSearchValue] = useState(""); const [treeData, setTreeData] = useState([]); const [taxonomySelectDisabled, setTaxonomySelectDisabled] = useState(false); const [pageSize, setPageSize] = useState(10); const [currentPage, setCurrentPage] = useState(1); // ... 保持原有的 API 调用和逻辑 ... // 获取所有taxonomy const { data: taxonomies } = api.taxonomy.getAll.useQuery({ type: ObjectType.DEVICE, }); // 获取所有故障类型taxonomy // 故障网系类别taxonomy const { data: systemTypeTaxonomy } = api.taxonomy.findBySlug.useQuery({ slug: "system_type", }); // 故障类型taxonomy const { data: deviceTypeTaxonomy } = api.taxonomy.findBySlug.useQuery({ slug: "device_type", }); // 获取所有网系类别条目 const { data: systemTypeTerms, refetch: refetchSystemType } = api.term.findMany.useQuery({ where: { taxonomy: { slug: "system_type" }, deletedAt: null, }, include: { children: true, }, orderBy: { order: "asc" }, }); // 获取所有故障类型条目 const { data: deviceTypeTerms, refetch: refetchDeviceType } = api.term.findMany.useQuery({ where: { taxonomy: { slug: "device_type" }, deletedAt: null, }, include: { children: true, }, orderBy: { order: "asc" }, }); const handlePageChange = (page: number, size: number) => { setCurrentPage(page); setPageSize(size); }; const handlePageSizeChange = (current: number, size: number) => { setCurrentPage(1); // 重置到第一页 setPageSize(size); }; // 构建包含两种分类的树形数据 useEffect(() => { if (systemTypeTerms && deviceTypeTerms) { // 先获取顶级网系类别 const rootTerms = systemTypeTerms.filter((term) => !term.parentId); // 构建树形数据 const buildTreeData = (items: any[]): any[] => { return items.map((item) => { // 找到与此网系类别关联的故障类型 const deviceChildren = deviceTypeTerms.filter( (t) => t.parentId === item.id ); // 为每个故障类型找到其子故障 const processedDeviceChildren = deviceChildren.map((deviceType) => { const deviceItems = deviceTypeTerms.filter( (t) => t.parentId === deviceType.id ); return { ...deviceType, key: deviceType.id, children: deviceItems.map((device) => ({ ...device, key: device.id, })), }; }); return { ...item, key: item.id, children: processedDeviceChildren, }; }); }; setTreeData(buildTreeData(rootTerms)); } }, [systemTypeTerms, deviceTypeTerms]); // 搜索过滤逻辑 useEffect(() => { if (systemTypeTerms && deviceTypeTerms) { if (!searchValue) { // 重新构建完整的树形结构 const rootTerms = systemTypeTerms.filter((term) => !term.parentId); const buildTreeData = (items: any[]): any[] => { return items.map((item) => { const deviceChildren = deviceTypeTerms.filter( (t) => t.parentId === item.id ); const processedDeviceChildren = deviceChildren.map((deviceType) => { const deviceItems = deviceTypeTerms.filter( (t) => t.parentId === deviceType.id ); return { ...deviceType, key: deviceType.id, children: deviceItems.map((device) => ({ ...device, key: device.id, })), }; }); return { ...item, key: item.id, children: processedDeviceChildren, }; }); }; setTreeData(buildTreeData(rootTerms)); } else { // 搜索匹配所有项 const allTerms = [...systemTypeTerms, ...deviceTypeTerms]; const filtered = allTerms.filter((term) => term.name.toLowerCase().includes(searchValue.toLowerCase()) ); setTreeData(filtered.map((item) => ({ ...item, key: item.id }))); } } }, [systemTypeTerms, deviceTypeTerms, searchValue]); const handleSearch = (value: string) => { setSearchValue(value); }; // API调用 const { mutate: createTerm } = api.term.create.useMutation({ onSuccess: () => { refetchSystemType(); refetchDeviceType(); setIsModalVisible(false); setTermName(""); setParentId(null); setTaxonomyId(null); }, }); const { mutate: updateTerm } = api.term.update.useMutation({ onSuccess: () => { refetchSystemType(); refetchDeviceType(); setIsModalVisible(false); setEditingTerm(null); setTermName(""); setParentId(null); setTaxonomyId(null); }, }); const { mutate: softDeleteByIds } = api.term.softDeleteByIds.useMutation({ onSuccess: () => { refetchSystemType(); refetchDeviceType(); }, }); // 操作处理函数 const handleAdd = (parentRecord?: any) => { setEditingTerm(null); setTermName(""); setParentId(parentRecord?.id || null); refetchSystemType(); refetchDeviceType(); // 根据父记录类型自动选择taxonomy if (parentRecord) { // 如果父类是网系类别,则自动设置为故障类型 if (parentRecord.taxonomyId === systemTypeTaxonomy?.id) { setTaxonomyId(deviceTypeTaxonomy?.id); // 可以设置状态来禁用Select组件 setTaxonomySelectDisabled(true); } else { setTaxonomyId(parentRecord.taxonomyId); setTaxonomySelectDisabled(false); } } else { // 如果是顶级项,默认设为网系类别 setTaxonomyId(systemTypeTaxonomy?.id || null); setTaxonomySelectDisabled(false); } setIsModalVisible(true); }; const handleEdit = (term: any) => { setEditingTerm(term); setTermName(term.name); setParentId(term.parentId); setTaxonomyId(term.taxonomyId); setIsModalVisible(true); refetchSystemType(); refetchDeviceType(); }; const handleDelete = (term: any) => { Modal.confirm({ title: "确认删除", content: `确定要删除"${term.name}"吗?这将同时删除其下所有子项!`, onOk: () => softDeleteByIds({ ids: [term.id] }), }); refetchSystemType(); refetchDeviceType(); }; const handleSave = () => { if (!termName.trim() || !taxonomyId) return; if (editingTerm) { updateTerm({ where: { id: editingTerm.id }, data: { name: termName, parentId: parentId, hasChildren: editingTerm.hasChildren, }, }); } else { createTerm({ data: { name: termName, taxonomyId: taxonomyId, parentId: parentId, }, }); } refetchSystemType(); refetchDeviceType(); }; // 构建父级选择器的选项 const getParentOptions = () => { if (!systemTypeTerms || !deviceTypeTerms) return []; const allTerms = [...systemTypeTerms, ...deviceTypeTerms]; // 根据编辑对象和当前选择的taxonomy过滤有效的父级选项 let validParents = allTerms; // 如果是编辑现有项 if (editingTerm) { // 递归查找所有子孙节点ID,避免循环引用 const findAllDescendantIds = (itemId: string): string[] => { const directChildren = allTerms.filter((t) => t.parentId === itemId); const descendantIds = directChildren.map((c) => c.id); directChildren.forEach((child) => { const childDescendants = findAllDescendantIds(child.id); descendantIds.push(...childDescendants); }); return descendantIds; }; const invalidIds = [ editingTerm.id, ...findAllDescendantIds(editingTerm.id), ]; validParents = allTerms.filter((t) => !invalidIds.includes(t.id)); } // 如果是添加故障类型,只能选择网系类别作为父级 if (!editingTerm && taxonomyId === deviceTypeTaxonomy?.id) { validParents = systemTypeTerms; } // 如果是添加具体故障,只能选择故障类型作为父级 if ( !editingTerm && taxonomyId && taxonomyId !== systemTypeTaxonomy?.id && taxonomyId !== deviceTypeTaxonomy?.id ) { validParents = deviceTypeTerms; } // 转换为TreeSelect需要的格式 const buildTreeOptions = (items: any[], depth = 0): any[] => { return items .filter((item) => (depth === 0 ? !item.parentId : true)) .map((item) => { const children = allTerms.filter((t) => t.parentId === item.id); return { title: "—".repeat(depth) + (depth > 0 ? " " : "") + item.name, value: item.id, children: children.length > 0 ? buildTreeOptions(children, depth + 1) : undefined, }; }); }; return buildTreeOptions(validParents); }; return (
{/* 主要内容卡片 */} {/* 统计信息区域 */}
{systemTypeTerms?.length || 0}
网系类别
{deviceTypeTerms?.filter((term) => systemTypeTerms?.some( (sysType) => sysType.id === term.parentId ) ).length || 0}
故障类型
{/* */} {/*
*/} {/*
{deviceTypeTerms?.filter(term => !systemTypeTerms?.some(sysType => sysType.id === term.parentId) && deviceTypeTerms?.some(devType => devType.id === term.parentId) ).length || 0}
具体故障
*/} {/*
*/}
{/* 工具栏区域 */}
handleSearch(e.target.value)} value={searchValue} allowClear prefix={} className="w-full" size="middle" />
{/* 表格区域 */}
(
{/* 根据层级添加不同的图标 */} {record.taxonomyId === systemTypeTaxonomy?.id ? ( 📁 ) : record.taxonomyId === deviceTypeTaxonomy?.id ? ( 📂 ) : ( 📄 )} {text}
), }, { title: "分类类型", key: "taxonomyType", width: "25%", render: (_, record) => { if (record.taxonomyId === systemTypeTaxonomy?.id) { return ( 网系类别 ); } else if (record.taxonomyId === deviceTypeTaxonomy?.id) { return ( 故障类型 ); } else { return ( 具体故障 ); } }, }, { title: "操作", key: "action", width: "25%", render: (_, record: any) => (
), }, ]} rowKey="id" pagination={{ pageSize: pageSize, // 每页显示数量 current: currentPage, showSizeChanger: true, showQuickJumper: true, showTotal: (total) => `共 ${total} 条记录`, pageSizeOptions: [ "10", "15", "20"], onChange: handlePageChange, onShowSizeChange: handlePageSizeChange, }} rowClassName={(record, index) => `hover:bg-blue-50 transition-colors duration-200 ${ record.taxonomyId === systemTypeTaxonomy?.id ? "bg-blue-25" : record.taxonomyId === deviceTypeTaxonomy?.id ? "bg-green-25" : "bg-orange-25" }` } onHeaderRow={() => ({ style: { backgroundColor: "#f8fafc", fontWeight: "600", borderBottom: "2px solid #e2e8f0", }, })} bordered={true} // 改为有边框 size="middle" locale={{ emptyText: "暂无数据" }} className="rounded-lg overflow-hidden shadow-sm" showHeader={true} scroll={{ x: 800 }} // 添加横向滚动 /> {/* 编辑/添加模态框 */} {editingTerm ? : } {editingTerm ? `编辑${title}` : `添加${title}`} } open={isModalVisible} onOk={handleSave} onCancel={() => setIsModalVisible(false)} okText="保存" cancelText="取消" width={600} destroyOnClose >
setTermName(e.target.value)} size="large" />
{!editingTerm && (