From 33f10896a071c9e8b43d20f19d0ca43af03e6c7d Mon Sep 17 00:00:00 2001 From: yorn <1057707203@qq.com> Date: Fri, 5 Dec 2025 00:04:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=201.=E6=8E=A5=E5=85=A5ai=5Fsuggestion.=202?= =?UTF-8?q?.=20=E6=8E=A5=E5=85=A5=E5=90=88=E5=90=8C=E8=B5=B7=E8=8D=89?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/contract-template/templates.ts | 1 + app/api/home/home.ts | 6 +- app/api/prompts/prompts.ts | 2 + app/api/role-permissions/role-permissions.ts | 2 +- app/components/collabora/CollaboraViewer.tsx | 4 +- app/components/collabora/hooks.ts | 21 +- .../collabora/lib/Highlightselecttext.ts | 6 +- app/components/collabora/types.ts | 3 + app/components/cross-checking/FileInfo.tsx | 4 +- app/components/cross-checking/FilePreview.tsx | 4 +- .../cross-checking/ReviewPointsList.tsx | 77 +- app/components/layout/Sidebar.tsx | 12 +- app/components/reviews/FilePreview.tsx | 196 +- app/components/reviews/ReviewPointsList.tsx | 190 +- app/components/reviews/ReviewTabs.tsx | 4 +- .../previewComponents/ComparePreview.tsx | 31 +- .../reviews/previewComponents/PdfPreview.tsx | 33 +- app/root.tsx | 10 +- app/routes/_index.tsx | 20 +- app/routes/contract-template.detail.$id.tsx | 148 +- app/routes/documents.list.tsx | 175 +- app/routes/files.upload.tsx | 42 +- app/routes/prompts._index.tsx | 22 +- app/routes/role-permissions._index.tsx | 15 +- app/services/collabora.wopi.server.ts | 2 +- .../components/file-preview-isolation.css | 22 +- app/styles/pages/role-permissions.css | 42 +- package-lock.json | 3069 +++++++++++++---- package.json | 2 + 29 files changed, 3184 insertions(+), 981 deletions(-) diff --git a/app/api/contract-template/templates.ts b/app/api/contract-template/templates.ts index 8ffe97d..aa02704 100644 --- a/app/api/contract-template/templates.ts +++ b/app/api/contract-template/templates.ts @@ -44,6 +44,7 @@ export interface ContractTemplate { created_at: string; updated_at: string; pdf_file_path?: string; + placeholder_schema?: Record; // 占位符配置 (JSONB) // 关联的分类信息 category?: ContractCategory; } diff --git a/app/api/home/home.ts b/app/api/home/home.ts index ca0c860..e2be60b 100644 --- a/app/api/home/home.ts +++ b/app/api/home/home.ts @@ -317,11 +317,11 @@ export async function getEntryModules(userRole: string | null | undefined, userA // console.log('✅ [getEntryModules] 入口模块数据(含文档类型):', JSON.stringify(modulesWithTypes)); - // 默认会多加一个 智慧法务大模型 入口 默认所有人都可以用,看到 + // 默认会多加一个 智慧法务助手 入口 默认所有人都可以用,看到 modulesWithTypes.push({ "id": 0, - "name": "智慧法务大模型", - "description": "智慧法务大模型", + "name": "智慧法务助手", + "description": "智慧法务助手", "path": "entryModule/assistant", "areas": [], "created_at": "2025-11-18T21:33:33.857417+08:00", diff --git a/app/api/prompts/prompts.ts b/app/api/prompts/prompts.ts index b03706f..9e2779d 100644 --- a/app/api/prompts/prompts.ts +++ b/app/api/prompts/prompts.ts @@ -14,6 +14,7 @@ export interface PromptTemplate { status: number; version: string; created_by: number | null; + created_by_username?: string; // 创建者用户名 created_at: string; updated_at: string; is_active?: boolean; @@ -151,6 +152,7 @@ export function convertToUITemplate(template: PromptTemplate): PromptTemplateUI status: mapStatusToUI(template.status), version: template.version, created_by: template.created_by || 0, + created_by_username: template.created_by_username, created_at: formatDate(template.created_at), updated_at: formatDate(template.updated_at), template_code: template.template_code || undefined, diff --git a/app/api/role-permissions/role-permissions.ts b/app/api/role-permissions/role-permissions.ts index 165de95..403657c 100644 --- a/app/api/role-permissions/role-permissions.ts +++ b/app/api/role-permissions/role-permissions.ts @@ -196,7 +196,7 @@ export async function getRoles(params?: { description: role.description || '', parent_role_id: role.parent_role_id || null, priority: role.priority || 0, - is_system_role: role.is_system || false, + is_system_role: (role.role_key == 'admin' || role.role_key == 'common') ? true : role.is_system || false, created_at: role.created_at, updated_at: role.updated_at })); diff --git a/app/components/collabora/CollaboraViewer.tsx b/app/components/collabora/CollaboraViewer.tsx index a387e75..8e7ae14 100644 --- a/app/components/collabora/CollaboraViewer.tsx +++ b/app/components/collabora/CollaboraViewer.tsx @@ -279,8 +279,8 @@ export const CollaboraViewer = forwardRef
-

{error || '加载配置失败'}

-

请刷新页面重试或联系管理员

+

{error}

+ {/*

请刷新页面重试或联系管理员

*/}
); diff --git a/app/components/collabora/hooks.ts b/app/components/collabora/hooks.ts index 1b14347..aedae0d 100644 --- a/app/components/collabora/hooks.ts +++ b/app/components/collabora/hooks.ts @@ -15,6 +15,7 @@ import { COLLABORA_URL } from '~/config/api-config'; import { toastService } from '../ui/Toast'; import { unoScrollToTop, + unoReplaceAll } from './lib'; import type { CollaboraConfig } from './types'; @@ -131,14 +132,30 @@ export function useCollaboraUnoCommands(iframeRef: RefObject) await new Promise((resolve) => setTimeout(resolve, 100)); }, [iframeRef]); + /** + * 替换所有匹配项 + * @param searchText 要搜索的文本 + * @param replaceText 替换后的文本 + */ + const replaceAll = useCallback(async (searchText: string, replaceText: string) => { + if (!iframeRef.current?.contentWindow) { + console.warn('[UNO] iframe 不可用'); + return; + } + console.log('[UNO] 替换全部:', searchText, '->', replaceText); + await unoReplaceAll(iframeRef.current.contentWindow, searchText, replaceText); + await new Promise((resolve) => setTimeout(resolve, 100)); + }, [iframeRef]); return useMemo( () => ({ - scrollToTop + scrollToTop, + replaceAll }), [ - scrollToTop + scrollToTop, + replaceAll ] ); } diff --git a/app/components/collabora/lib/Highlightselecttext.ts b/app/components/collabora/lib/Highlightselecttext.ts index de12bb0..b9ccab8 100644 --- a/app/components/collabora/lib/Highlightselecttext.ts +++ b/app/components/collabora/lib/Highlightselecttext.ts @@ -22,7 +22,7 @@ export interface HighlightOptions { /** 高亮颜色 (LibreOffice Decimal 格式), 默认 16776960 = 黄色 */ color?: number; /** 目标页码 (从1开始), 默认第1页 */ - page?: number; + page?: number | null; } /** @@ -32,7 +32,7 @@ export interface HighlightResponse { success: boolean; message: string; highlightedCount?: number; - page?: number; + page?: number | null; timestamp: number; } @@ -70,7 +70,7 @@ export async function highlightText( options?: HighlightOptions ): Promise { const color = options?.color ?? 16776960; // 默认黄色 - const page = options?.page ?? 1; // 默认第1页 + const page = options?.page ?? null; // 默认第1页 console.log('[HighlightSelectText] 调用 Python 脚本高亮文本:', { text, diff --git a/app/components/collabora/types.ts b/app/components/collabora/types.ts index fef0336..550eafe 100644 --- a/app/components/collabora/types.ts +++ b/app/components/collabora/types.ts @@ -53,6 +53,9 @@ export interface CollaboraViewerHandle { /** UNO 命令方法集合 */ unoCommands: { scrollToTop: () => Promise; + replaceAll?: (searchText: string, replaceText: string) => Promise; + find?: (searchText: string) => Promise; + search?: (searchText: string) => Promise; }; /** 文档是否已加载完成 */ isReady: boolean; diff --git a/app/components/cross-checking/FileInfo.tsx b/app/components/cross-checking/FileInfo.tsx index 2eb488d..29f050f 100644 --- a/app/components/cross-checking/FileInfo.tsx +++ b/app/components/cross-checking/FileInfo.tsx @@ -71,13 +71,13 @@ export function FileInfo({ fileInfo, onConfirmResults }: FileInfoProps) { {/* 操作按钮区域 */}
- {/* 下载原文件按钮 */} + {/* 下载文件按钮 */} {/* 导出评查报告按钮 */} diff --git a/app/components/cross-checking/FilePreview.tsx b/app/components/cross-checking/FilePreview.tsx index c2711ec..14a7ada 100644 --- a/app/components/cross-checking/FilePreview.tsx +++ b/app/components/cross-checking/FilePreview.tsx @@ -527,7 +527,7 @@ export function FilePreview({ fileContent, activeReviewPointResultId, targetPage 比例:{zoomLevel}% - + */}
; + ai_suggestion?: { + summary?: string; + analysis?: { + failure_reason?: string; + solution_approach?: string; + rule_understanding?: string; + }; + suggestions?: Record; + generated_at?: string; + }; message?: string; res?: boolean; } | undefined; @@ -1934,10 +1954,10 @@ export function ReviewPointsList({ // 渲染AI模型返回的评估消息 if (config.message) { // 检查message是否为对象,如果是则转换为字符串 - const messageContent = typeof config.message === 'object' - ? JSON.stringify(config.message) + const messageContent = typeof config.message === 'object' + ? JSON.stringify(config.message) : String(config.message); - + // 添加模型评估消息区域,使用蓝色背景突出显示 fieldElements.push(
@@ -1949,6 +1969,57 @@ export function ReviewPointsList({ ); } + // 渲染AI建议(ai_suggestion) + if (config.ai_suggestion?.suggestions && Object.keys(config.ai_suggestion.suggestions).length > 0) { + // 遍历suggestions对象的key-value对 + Object.entries(config.ai_suggestion.suggestions).forEach(([key, suggestionValue], index) => { + // 检查建议值是否存在(null 或有值都要渲染) + const hasSuggestedValue = suggestionValue.suggested_value !== null && suggestionValue.suggested_value.trim() !== ''; + + fieldElements.push( +
+ {/* 字段名称标签 */} +
+ + AI建议修改 - {key} +
+ + {/* 原因说明 */} +
+
+ +
+ {suggestionValue.reason} + {suggestionValue.source.page !== null && ( + + (来源页码: {suggestionValue.source.page}) + + )} +
+
+
+ + {/* 建议内容显示 */} +
+ {/* 文本输入框 */} +