import { json, type MetaFunction } from "@remix-run/node"; import { useLoaderData, Link, useNavigate, useSearchParams } from "@remix-run/react"; import { useState, useEffect } from "react"; import indexStyles from "~/styles/pages/rule-groups_index.css?url"; import { Card } from "~/components/ui/Card"; import { Button } from "~/components/ui/Button"; import { StatusDot } from "~/components/ui/StatusDot"; import { Table } from "~/components/ui/Table"; import { FilterPanel, FilterSelect, SearchFilter } from "~/components/ui/FilterPanel"; import { Pagination } from "~/components/ui/Pagination"; import { getRuleGroups, getChildGroups, type RuleGroup } from "~/api/evaluation_points/rule-groups"; export function links() { return [{ rel: "stylesheet", href: indexStyles }]; } export const meta: MetaFunction = () => { return [ { title: "评查点分组 - 中国烟草AI合同及卷宗审核系统" }, { name: "description", content: "管理评查点分组,包括创建、编辑和删除分组" }, ]; }; export async function loader() { try { const response = await getRuleGroups(); if (response.error) { throw new Error(response.error); } return json({ groups: response.data }); } catch (error) { console.error('加载评查点分组失败:', error); return json({ groups: [] }); } } export default function RuleGroupsIndex() { const { groups: initialGroups } = useLoaderData(); const navigate = useNavigate(); const [searchParams, setSearchParams] = useSearchParams(); const [expandedGroups, setExpandedGroups] = useState([]); const [groups, setGroups] = useState(initialGroups); const [loading, setLoading] = useState>({}); // 处理展开/收起 const toggleGroup = async (groupId: string) => { if (expandedGroups.includes(groupId)) { // 收起分组 setExpandedGroups(prev => prev.filter(id => id !== groupId)); return; } // 展开分组 setLoading(prev => ({ ...prev, [groupId]: true })); try { const response = await getChildGroups(groupId); if (response.error) { throw new Error(response.error); } // 更新分组数据 setGroups(prev => prev.map(group => { if (group.id === groupId) { return { ...group, children: response.data }; } return group; })); setExpandedGroups(prev => [...prev, groupId]); } catch (error) { console.error('加载子分组失败:', error); } finally { setLoading(prev => ({ ...prev, [groupId]: false })); } }; // 展开/收起全部 const toggleAll = async (expand: boolean) => { if (expand) { // 展开所有分组 const expandedIds = groups.map(g => g.id); setExpandedGroups(expandedIds); // 加载所有子分组 for (const group of groups) { if (!group.children || group.children.length === 0) { await toggleGroup(group.id); } } } else { setExpandedGroups([]); } }; // 处理删除分组 const handleDeleteGroup = (groupId: string) => { if (confirm("确定要删除该分组吗?此操作将同时删除该分组下的所有评查点,且不可恢复。")) { console.log('删除分组ID:', groupId); // TODO: 实现删除分组的API调用 } }; // 处理搜索名称 const handleNameSearch = (value: string) => { const newParams = new URLSearchParams(searchParams); if (value) { newParams.set('name', value); } else { newParams.delete('name'); } newParams.set('page', '1'); setSearchParams(newParams); }; // 处理搜索编码 const handleCodeSearch = (value: string) => { const newParams = new URLSearchParams(searchParams); if (value) { newParams.set('code', value); } else { newParams.delete('code'); } newParams.set('page', '1'); setSearchParams(newParams); }; // 处理状态筛选变更 const handleStatusChange = (e: React.ChangeEvent) => { const { value } = e.target; const newParams = new URLSearchParams(searchParams); if (value) { newParams.set('status', value); } else { newParams.delete('status'); } newParams.set('page', '1'); setSearchParams(newParams); }; // 处理重置筛选 const handleReset = () => { setSearchParams(new URLSearchParams()); }; // 处理表格数据,包括父子级关系 const processedData = groups.flatMap(group => { // 先添加父级分组 const result: (RuleGroup & { isParent?: boolean, parentId?: string })[] = [ { ...group, isParent: true } ]; // 如果有子级分组并且当前已展开,则添加子级分组 if (group.children && expandedGroups.includes(group.id)) { group.children.forEach(child => { result.push({ ...child, parentId: group.id }); }); } return result; }); // 定义表格列配置 const columns = [ { title: "分组名称", key: "name", width: "400px", render: (_: unknown, record: RuleGroup & { isParent?: boolean, parentId?: string }) => (
{record.isParent && ( toggleGroup(record.id)} role="button" tabIndex={0} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggleGroup(record.id); } }} > {loading[record.id] ? ( ) : ( )} )} {record.name} {record.isParent ? '一级分组' : '二级分组'}
) }, { title: "分组编码", key: "code", render: (_: unknown, record: RuleGroup) => record.code }, { title: "评查点数量", key: "ruleCount", render: (_: unknown, record: RuleGroup) => ( {record.ruleCount || 0} ) }, { title: "状态", key: "status", render: (_: unknown, record: RuleGroup) => ( ) }, { title: "创建时间", key: "createdAt", render: (_: unknown, record: RuleGroup) => record.createdAt }, { title: "操作", key: "operation", width: "180px", render: (_: unknown, record: RuleGroup) => (
) } ]; return (
{/* 页面头部 */}

评查点分组管理

{/* 搜索栏 - 使用FilterPanel */} } noActionDivider={true} > {/* 数据表格 - 使用Table组件 */} {/* 分页 - 使用Pagination组件 */} {}} showTotal={true} /> ); }