/** * 评查点列表组件 * * 功能概述: * - 展示评查结果统计信息(总计、通过、警告、错误数量) * - 提供评查点过滤功能(按状态和搜索文本) * - 显示评查点详细信息(标题、状态、内容、建议修改等) * - 支持评查点操作(一键替换、人工审核等) * * 组件结构: * - 统计区域: 显示评查点数量统计 * - 搜索区域: 提供文本搜索功能 * - 评查点列表: 展示所有评查点 * - 评查点卡片: 展示单个评查点详情 * - 评查点头部: 显示标题和状态 * - 评查点内容: 显示当前内容和问题 * - 建议修改区域: 显示建议的修改内容 * - 操作按钮: 提供一键替换和人工审核功能 */ import { useState, useEffect } from 'react'; /** * 评查点类型定义 * 用于展示单个评查结果 */ export interface ReviewPoint { id: string; title: string; groupName: string; status: string; content: string | Record; suggestion: string; needsHumanReview?: boolean; humanReviewNote?: string; humanReviewBy?: string; humanReviewTime?: string; position?: { section: string; index: number; }; result?: boolean; } // 统计数据类型 interface Statistics { total: number; success: number; warning: number; error: number; score: number; } interface ReviewPointsListProps { reviewPoints: ReviewPoint[]; statistics: Statistics; activeReviewPointId: string | null; onReviewPointSelect: (id: string) => void; onStatusChange: (id: string, status: string) => void; } export function ReviewPointsList({ reviewPoints, statistics, activeReviewPointId, onReviewPointSelect, onStatusChange }: ReviewPointsListProps) { // 状态管理 const [editingReviewPoint, setEditingReviewPoint] = useState(null); // 当前正在编辑的评查点ID const [userInputText, setUserInputText] = useState(''); // 用户输入的审核意见文本 const [searchText, setSearchText] = useState(''); // 搜索文本 const [statusFilter, setStatusFilter] = useState(null); // 状态过滤 const [suggestionTexts, setSuggestionTexts] = useState>({}); // 存储每个评查点的建议文本 // 初始化建议文本 useEffect(() => { // 将所有评查点的建议文本存储到状态中 const suggestions: Record = {}; reviewPoints.forEach(point => { suggestions[point.id] = point.suggestion || ''; }); setSuggestionTexts(suggestions); }, [reviewPoints]); // 处理建议文本变更 const handleSuggestionChange = (reviewPointId: string, text: string) => { setSuggestionTexts(prev => ({ ...prev, [reviewPointId]: text })); }; /** * 过滤评查点 * 根据搜索文本和状态过滤条件筛选评查点 */ const filteredReviewPoints = reviewPoints.filter(point => { // 匹配搜索文本 const matchesSearch = searchText === '' || point.title.toLowerCase().includes(searchText.toLowerCase()) || point.groupName.toLowerCase().includes(searchText.toLowerCase()) || (typeof point.content === 'string' && point.content.toLowerCase().includes(searchText.toLowerCase())) || (typeof point.content === 'object' && point.content !== null && Object.values(point.content).some(value => typeof value === 'string' && value.toLowerCase().includes(searchText.toLowerCase()) )); // 处理状态过滤 let matchesStatus = false; if (statusFilter === null) { // 未选择过滤条件时显示所有 matchesStatus = true; } else if (statusFilter === 'success') { // 过滤"通过"状态 matchesStatus = point.result === true || (point.result === undefined && point.status === 'success'); } else if (statusFilter === 'warning') { // 过滤"警告"状态 matchesStatus = point.result === false && point.status === 'warning'; } else if (statusFilter === 'error') { // 过滤"错误"状态 matchesStatus = point.result === false && point.status === 'error'; } return matchesSearch && matchesStatus; }); /** * 处理一键替换操作 * @param reviewPointId 评查点ID */ const handleReplace = (reviewPointId: string) => { // 在实际应用中,这里应该调用API进行内容替换 // 模拟替换操作 alert(`将为评查点 ${reviewPointId} 执行一键替换操作`); // 更新评查点状态为成功 onStatusChange(reviewPointId, 'success'); }; /** * 处理评查点审核操作 * @param reviewPointId 评查点ID * @param action 操作类型: 'approve' 通过 / 'reject' 不通过 */ const handleReviewAction = (reviewPointId: string, action: 'approve' | 'reject') => { // 更新评查点状态 onStatusChange(reviewPointId, action === 'approve' ? 'success' : 'error'); // 清除编辑状态 setEditingReviewPoint(null); setUserInputText(''); alert(`${action === 'approve' ? '通过' : '不通过'}了评查点 ${reviewPointId}`); }; /** * 显示评查点详情编辑界面 * @param reviewPointId 评查点ID */ const handleEditReviewPoint = (reviewPointId: string) => { setEditingReviewPoint(reviewPointId); // 获取评查点的建议内容作为初始值 const reviewPoint = reviewPoints.find(point => point.id === reviewPointId); if (reviewPoint) { setUserInputText(reviewPoint.suggestion || ''); } }; /** * 渲染评查统计信息 * 显示总计、通过、警告、错误数量 */ const renderStatistics = () => { // 确保传入的statistics存在,否则使用计算值 const statsToUse = statistics || { total: reviewPoints.length, success: 0, warning: 0, error: 0, score: 0 }; // 计算各个状态的评查点数量 const successCount = reviewPoints.filter( point => point.result === true || (point.result === undefined && point.status === 'success') ).length; const warningCount = reviewPoints.filter( point => point.result === false && point.status === 'warning' ).length; const errorCount = reviewPoints.filter( point => point.result === false && point.status === 'error' ).length; // 如果没有计算值,则使用传入的统计值 const totalToShow = statsToUse.total === 0 ? reviewPoints.length : statsToUse.total; const successToShow = successCount || statsToUse.success; const warningToShow = warningCount || statsToUse.warning; const errorToShow = errorCount || statsToUse.error; return (
{/* 总计数量 */}
{totalToShow}
总计
{/* 通过数量 */}
通过
{/* 警告数量 */}
警告
{/* 错误数量 */}
错误
); }; /** * 渲染搜索框 * 用于按文本搜索评查点 */ const renderSearchBar = () => { return (
setSearchText(e.target.value)} /> {searchText && ( )}
); }; /** * 渲染评查点状态标签 * @param status 状态文本 * @param result 评查结果 * @returns 状态标签组件 */ const renderStatusBadge = (status: string, result?: boolean) => { // 优先根据result判断是否通过 if (result === true) { return ( 通过 ); } // 当result为false时,根据status决定显示警告还是错误 if (result === false) { if (status === 'warning') { return ( 警告 ); } else if (status === 'error') { return ( 不通过 ); } } // 兼容旧版逻辑,当没有result时,仍按status判断 switch (status) { case 'success': return ( 通过 ); case 'warning': return ( 警告 ); case 'error': return ( 不通过 ); case 'processing': return ( 处理中 ); default: return ( 警告 ); } }; /** * 渲染人工审核标记 * @param reviewPoint 评查点 * @returns 人工审核标记组件 */ const renderHumanReviewBadge = (reviewPoint: ReviewPoint) => { if (reviewPoint.needsHumanReview) { return ( 需人工 ); } return null; }; /** * 渲染人工审核注释 * @param reviewPoint 评查点 * @returns 人工审核注释组件 */ const renderHumanReviewNote = (reviewPoint: ReviewPoint) => { if (reviewPoint.needsHumanReview && reviewPoint.humanReviewNote) { return (
{reviewPoint.humanReviewNote} {reviewPoint.humanReviewBy && reviewPoint.humanReviewTime && (
审核人:{reviewPoint.humanReviewBy} | 时间:{reviewPoint.humanReviewTime}
)}
); } return null; }; /** * 渲染评查点内容与建议 * @param reviewPoint 评查点 * @returns 评查点内容组件 */ const renderReviewPointContent = (reviewPoint: ReviewPoint) => { // 如果当前评查点不处于编辑状态,只显示简单信息 if (editingReviewPoint !== reviewPoint.id) { // 根据result和status决定渲染哪种样式 if (reviewPoint.result === true || (reviewPoint.result === undefined && reviewPoint.status === 'success')) { // 已通过的评查点只显示基本信息和人工审核注释 if (reviewPoint.needsHumanReview && reviewPoint.humanReviewNote) { return (

已处理

{reviewPoint.suggestion && (

{reviewPoint.suggestion}

)}
); } return null; } // 非通过状态,显示内容和修改建议 const isErrorStatus = reviewPoint.result === false && reviewPoint.status === 'error'; return (
{/* 内容显示区域 */}
{/* 移除顶部的"当前值"标题,在每个内容项中显示 */} {typeof reviewPoint.content === 'object' && reviewPoint.content !== null ? ( // 当 content 是对象时的渲染方式
{Object.entries(reviewPoint.content).map(([key, value], index) => (
{/* 使用flex布局使key和状态标签左右对齐 */}
{key} {isErrorStatus ? '不符合规范' : '需优化'}

{value || '(内容为空)'}

))}
) : ( // 当 content 是字符串时的渲染方式 <> {/* 为字符串内容也添加标题和状态 */}
当前值 {isErrorStatus ? '不符合规范' : '需优化'}

{reviewPoint.content || '(内容为空)'}

)}
{/* 建议修改区域 */}
建议修改为: 符合规范
); }; /** * 渲染无匹配结果提示 * 当过滤后没有评查点时显示 */ const renderEmptyState = () => { return (

没有找到匹配的评查点

请尝试不同的搜索词或清除筛选条件

{(searchText || statusFilter) && ( )}
); }; // 组件主渲染函数 return (
{/* 面板头部 */}
评查结果
{/* 评查统计 */} {renderStatistics()} {/* 搜索框 */} {renderSearchBar()} {/* 评查点列表 */}
{filteredReviewPoints.length > 0 ? ( filteredReviewPoints.map(reviewPoint => ( )) ) : ( renderEmptyState() )}
); }