diff --git a/app/api/document-types/document-types.ts b/app/api/document-types/document-types.ts index ed2fd1c..4145c79 100644 --- a/app/api/document-types/document-types.ts +++ b/app/api/document-types/document-types.ts @@ -60,7 +60,8 @@ export interface DocumentTypeGroup { // 搜索参数 export interface DocumentTypeSearchParams { name?: string; - group_id?: string; + ruleType?: string; + groupId?: string; page?: number; pageSize?: number; } @@ -239,13 +240,18 @@ export async function getDocumentTypes(searchParams: DocumentTypeSearchParams = } // 如果有分组ID筛选条件 - if (searchParams.group_id) { - filter['evaluation_point_groups_ids'] = `cs.{${searchParams.group_id}}`; + if (searchParams.ruleType) { + filter['evaluation_point_groups_ids'] = `cs.[${searchParams.ruleType}]`; + } + + if (searchParams.groupId) { + // 如果groupId存在,则将groupId作为子级评查点分组ID + filter['evaluation_point_groups_ids'] = `cs.[${searchParams.groupId}]`; } params.filter = filter; - // console.log('获取文档类型列表,参数:', params); + console.log('获取文档类型列表,参数:', params); const response = await postgrestGet('document_types', params); if (response.error) { @@ -529,8 +535,8 @@ export async function createDocumentType(documentType: DocumentTypeCreateDTO): P if (!groupId || isNaN(parseInt(groupId, 10))) { return { error: '无效的评查点分组ID', status: 400 }; } - const groupIds = parseInt(groupId, 10); // 修改为数组形式 - // const groupIds = [parseInt(groupId, 10)]; // 修改为数组形式 + // const groupIds = parseInt(groupId, 10); // 修改为数组形式 + const groupIds = [parseInt(groupId, 10)]; // 修改为数组形式 // 构建提示词配置 - 确保所有字段都有明确的设置 const promptConfig: Record = { @@ -580,13 +586,13 @@ export async function createDocumentType(documentType: DocumentTypeCreateDTO): P description: documentType.description || '', evaluation_point_groups_ids: groupIds, prompt_config: promptConfig, - code: documentType.code || null + // code: documentType.code || null }; // console.log('创建文档类型请求数据:', JSON.stringify(apiDocumentType, null, 2)); // console.log('创建文档类型请求数据:', apiDocumentType); // if(apiDocumentType){ - // throw new Error('测试错误'); + // throw new Error('测试错误'); // } // 发送创建请求 @@ -660,7 +666,7 @@ export async function updateDocumentType(id: string, documentType: DocumentTypeU const promptConfig: Record = { llm_extract_template: null, vlm_extract_template: null, - evaluation_template: null, + // evaluation_template: null, execution_template: null, summary_template: null }; @@ -707,7 +713,7 @@ export async function updateDocumentType(id: string, documentType: DocumentTypeU }; console.log('更新文档类型请求数据:', JSON.stringify(apiDocumentType, null, 2)); - + // throw new Error('测试错误'); // 发送更新请求 const response = await postgrestPut( 'document_types', diff --git a/app/api/evaluation_points/reviews.ts b/app/api/evaluation_points/reviews.ts index 84bfed3..ebbc26d 100644 --- a/app/api/evaluation_points/reviews.ts +++ b/app/api/evaluation_points/reviews.ts @@ -121,17 +121,17 @@ export async function getReviewPoints(fileId: string) { return { error: evaluationResultsResponse.error, status: evaluationResultsResponse.status }; } - const evaluationResultsData = extractApiData(evaluationResultsResponse.data); + const evaluationResultsData = extractApiData(evaluationResultsResponse.data) || []; - if (!evaluationResultsData || !Array.isArray(evaluationResultsData)) { - return { data: [], stats: { total: 0, success: 0, warning: 0, error: 0, score: 0 } }; + if (Array.isArray(evaluationResultsData) && evaluationResultsData.length <= 0) { + return { data: [], stats: { total: 0, success: 0, warning: 0, error: 0, score: 0 },error: '获取评查结果数据失败' }; } // 收集所有评查点ID,用于查询评查点详情 const evaluationPointIds = evaluationResultsData.map(item => item.evaluation_point_id).filter(Boolean); if (evaluationPointIds.length === 0) { - return { data: [], stats: { total: 0, success: 0, warning: 0, error: 0, score: 0 } }; + return { data: [], stats: { total: 0, success: 0, warning: 0, error: 0, score: 0 },error: '获取评查点ID失败' }; } // 步骤2:根据evaluation_point_id查询evaluation_points表 diff --git a/app/components/reviews/FileInfo.tsx b/app/components/reviews/FileInfo.tsx index 2bed241..03c9172 100644 --- a/app/components/reviews/FileInfo.tsx +++ b/app/components/reviews/FileInfo.tsx @@ -1,4 +1,5 @@ import { useNavigate } from "@remix-run/react"; +import { toastService } from "~/components/ui/Toast"; interface FileInfoProps { fileInfo: { fileName: string; @@ -54,6 +55,10 @@ export function FileInfo({ fileInfo, onConfirmResults }: FileInfoProps) { } }; + const handleBack = () => { + navigate(-1); + }; + const handleExportReport = () => { alert('导出评查报告功能'); }; @@ -83,7 +88,7 @@ export function FileInfo({ fileInfo, onConfirmResults }: FileInfoProps) { {/* 返回上一级 */} diff --git a/app/components/ui/MessageModal.tsx b/app/components/ui/MessageModal.tsx index ed7106e..463082c 100644 --- a/app/components/ui/MessageModal.tsx +++ b/app/components/ui/MessageModal.tsx @@ -146,16 +146,18 @@ export function MessageModal({ onClick={handleClose} onKeyDown={handleKeyDown} tabIndex={0} - role="button" + role="presentation" aria-label="关闭对话框" > -
e.stopPropagation()} role="dialog" aria-modal="true" aria-labelledby="message-modal-title" aria-describedby="message-modal-content" + onClick={(e) => e.stopPropagation()} + onKeyDown={(e) => e.stopPropagation()} + tabIndex={-1} > {showCloseButton && ( - + {cancelText && ( + + )} )} diff --git a/app/components/ui/SearchBox.tsx b/app/components/ui/SearchBox.tsx index 6e1aa08..173236d 100644 --- a/app/components/ui/SearchBox.tsx +++ b/app/components/ui/SearchBox.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useRef } from 'react'; interface SearchBoxProps { placeholder?: string; @@ -17,6 +17,11 @@ export function SearchBox({ className = '', name = 'keyword' }: SearchBoxProps) { + const [inputValue, setInputValue] = useState(defaultValue); + const [isHovering, setIsHovering] = useState(false); + const inputRef = useRef(null); + const containerRef = useRef(null); + const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const formData = new FormData(e.currentTarget); @@ -25,28 +30,67 @@ export function SearchBox({ }; const handleChange = (e: React.ChangeEvent) => { + const value = e.target.value; + setInputValue(value); + // 对于没有按钮的输入框,我们希望在输入时就触发搜索 if (className.includes('form-input-only')) { - onSearch(e.target.value); + onSearch(value); } }; + const handleClear = () => { + setInputValue(''); + if (inputRef.current) { + inputRef.current.value = ''; + inputRef.current.focus(); + } + onSearch(''); + }; + + const handleMouseEnter = () => { + setIsHovering(true); + }; + + const handleMouseLeave = () => { + setIsHovering(false); + }; + const isIconOnly = buttonText === ''; const isFilterControl = className.includes('filter-control'); + const hasButton = !className.includes('form-input-only'); const searchBoxClass = `search-box ${className} ${isFilterControl ? 'search-box-row' : ''}`; + const showClearButton = inputValue && isHovering; return (
- - {!className.includes('form-input-only') && ( +
+ + {showClearButton && ( + + )} +
+ {hasButton && (