Merge branch 'PingChuan' into shiy-temp
This commit is contained in:
+2
-1
@@ -8,4 +8,5 @@ node_modules
|
||||
.idea
|
||||
.history
|
||||
|
||||
logs/
|
||||
logs/
|
||||
docreview-frontend-deploy.tar.gz
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* 提供三个选项卡:评查结果、AI智能分析、文件信息
|
||||
*/
|
||||
import { ReactNode, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useNavigate } from '@remix-run/react';
|
||||
import { loadingBarService } from '~/components/ui/LoadingBar';
|
||||
import { DOCUMENT_URL } from "~/api/axios-client";
|
||||
|
||||
@@ -28,19 +28,19 @@ export function ReviewTabs({ activeTab, onTabChange, children, fileInfo, onConfi
|
||||
const handleBack = () => {
|
||||
// 防抖处理 - 如果已经在导航中,不重复触发
|
||||
if (isNavigating) return;
|
||||
|
||||
|
||||
// 设置导航状态为true
|
||||
setIsNavigating(true);
|
||||
loadingBarService.show();
|
||||
|
||||
|
||||
// 根据来源页面返回
|
||||
const previousRoute = fileInfo.previousRoute || 'documents';
|
||||
const returnTo = previousRoute === 'documents'
|
||||
? "/documents"
|
||||
: previousRoute === 'filesUpload'
|
||||
const returnTo = previousRoute === 'documents'
|
||||
? "/documents"
|
||||
: previousRoute === 'filesUpload'
|
||||
? "/files/upload"
|
||||
: "/rules-files";
|
||||
|
||||
|
||||
// 立即导航返回
|
||||
navigate(returnTo);
|
||||
};
|
||||
@@ -49,19 +49,19 @@ export function ReviewTabs({ activeTab, onTabChange, children, fileInfo, onConfi
|
||||
const handleDownloadFile = async () => {
|
||||
try {
|
||||
const downloadUrl = `${DOCUMENT_URL}${fileInfo.path}`;
|
||||
|
||||
|
||||
// 使用fetch获取文件内容
|
||||
const response = await fetch(downloadUrl);
|
||||
if (!response.ok) {
|
||||
throw new Error(`下载失败: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
|
||||
// 将响应转换为Blob
|
||||
const blob = await response.blob();
|
||||
|
||||
|
||||
// 创建Blob URL
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
|
||||
|
||||
// 创建一个隐藏的a标签并点击它
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
@@ -71,7 +71,7 @@ export function ReviewTabs({ activeTab, onTabChange, children, fileInfo, onConfi
|
||||
a.download = decodeURIComponent(fileName);
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
|
||||
|
||||
// 清理
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a);
|
||||
@@ -89,7 +89,7 @@ export function ReviewTabs({ activeTab, onTabChange, children, fileInfo, onConfi
|
||||
<div className="tab-nav w-full flex justify-between">
|
||||
{/* 评查结果、AI智能分析、文件信息 */}
|
||||
<div className="flex">
|
||||
<button
|
||||
<button
|
||||
className={`tab-nav-item ${activeTab === 'preview' ? 'active' : ''}`}
|
||||
onClick={() => onTabChange('preview')}
|
||||
type="button"
|
||||
@@ -108,16 +108,16 @@ export function ReviewTabs({ activeTab, onTabChange, children, fileInfo, onConfi
|
||||
{/* {fileInfo.type === '1' && ( */}
|
||||
{/* 隐藏结构比对 */}
|
||||
{fileInfo.type === '999999' && (
|
||||
<button
|
||||
<button
|
||||
className={`tab-nav-item ${activeTab === 'filecompare' ? 'active' : ''}`}
|
||||
onClick={() => onTabChange('filecompare')}
|
||||
type="button"
|
||||
aria-pressed={activeTab === 'filecompare'}
|
||||
>
|
||||
>
|
||||
<i className="ri-flip-horizontal-line"></i> 结构比对
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
<button
|
||||
className={`tab-nav-item ${activeTab === 'fileinfo' ? 'active' : ''}`}
|
||||
onClick={() => onTabChange('fileinfo')}
|
||||
type="button"
|
||||
@@ -129,14 +129,14 @@ export function ReviewTabs({ activeTab, onTabChange, children, fileInfo, onConfi
|
||||
{/* 操作按钮 */}
|
||||
<div className="flex space-x-3">
|
||||
{/* 返回上一级 */}
|
||||
<button
|
||||
<button
|
||||
className="ant-btn ant-btn-default flex items-center my-2"
|
||||
onClick={() => handleBack()}
|
||||
disabled={isNavigating}
|
||||
>
|
||||
<i className="ri-arrow-left-line mr-1"></i> {isNavigating ? '返回中...' : '返回'}
|
||||
</button>
|
||||
<button
|
||||
<button
|
||||
className="ant-btn ant-btn-default flex items-center my-2"
|
||||
onClick={handleDownloadFile}
|
||||
>
|
||||
@@ -148,7 +148,7 @@ export function ReviewTabs({ activeTab, onTabChange, children, fileInfo, onConfi
|
||||
>
|
||||
<i className="ri-file-copy-line mr-1"></i> 导出评查报告
|
||||
</button> */}
|
||||
<button
|
||||
<button
|
||||
className={`ant-btn ant-btn-primary my-2 flex items-center ${fileInfo.auditStatus === 1 ? 'hidden' : ''}`}
|
||||
onClick={onConfirmResults}
|
||||
>
|
||||
@@ -156,7 +156,7 @@ export function ReviewTabs({ activeTab, onTabChange, children, fileInfo, onConfi
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="tab-content w-full">
|
||||
{children}
|
||||
</div>
|
||||
|
||||
@@ -33,11 +33,11 @@ const configs: Record<string, ApiConfig> = {
|
||||
// 生产环境
|
||||
production: {
|
||||
// postgrest
|
||||
baseUrl: 'http://10.79.97.16:8000',
|
||||
baseUrl: 'http://10.79.97.17:8000',
|
||||
// minio
|
||||
documentUrl: 'http://10.76.244.156:9000/docauditai/',
|
||||
// 文件上传
|
||||
uploadUrl: 'http://10.79.97.16:8000/admin/documents/upload',
|
||||
uploadUrl: 'http://10.79.97.17:8000/admin/documents/upload',
|
||||
},
|
||||
|
||||
// 备用配置 (可以根据需要添加更多环境)
|
||||
|
||||
+23
-19
@@ -28,16 +28,9 @@ const extractAppId = (appUrl: string): string => {
|
||||
return appUrl;
|
||||
};
|
||||
|
||||
// 获取配置值并添加调试日志
|
||||
const getApiUrl = () => {
|
||||
// 在Remix中,我们使用本地API路由作为代理,而不是直接访问Dify API
|
||||
if (typeof window !== 'undefined') {
|
||||
// 客户端:使用相对路径访问本地API
|
||||
return '/api';
|
||||
} else {
|
||||
// 服务端:也使用相对路径
|
||||
return '/api';
|
||||
}
|
||||
// 获取Dify API配置
|
||||
const getDifyApiUrl = () => {
|
||||
return getEnvVar('NEXT_PUBLIC_API_URL', 'https://api.dify.ai/v1');
|
||||
};
|
||||
|
||||
const getAppId = () => {
|
||||
@@ -46,22 +39,36 @@ const getAppId = () => {
|
||||
// console.log('🔧 Chat Config Debug:', {
|
||||
// rawAppId,
|
||||
// extractedAppId,
|
||||
// apiUrl: getApiUrl(),
|
||||
// difyApiUrl: getDifyApiUrl(),
|
||||
// hasApiKey: !!getEnvVar('NEXT_PUBLIC_APP_KEY', ''),
|
||||
// difyApiUrl: getEnvVar('NEXT_PUBLIC_API_URL', ''),
|
||||
// });
|
||||
return extractedAppId;
|
||||
};
|
||||
|
||||
// 生成用户ID (模拟服务端逻辑)
|
||||
const generateUserId = () => {
|
||||
const appId = getAppId();
|
||||
// 生成或获取会话ID (可以使用localStorage或其他方式)
|
||||
let sessionId = '';
|
||||
if (typeof window !== 'undefined') {
|
||||
sessionId = localStorage.getItem('dify_session_id') || '';
|
||||
if (!sessionId) {
|
||||
sessionId = 'sess_' + Math.random().toString(36).substring(2, 15);
|
||||
localStorage.setItem('dify_session_id', sessionId);
|
||||
}
|
||||
}
|
||||
return `user_${appId}:${sessionId}`;
|
||||
};
|
||||
|
||||
// 聊天应用配置
|
||||
export const CHAT_CONFIG = {
|
||||
// API相关配置 - 使用本地API路由作为代理
|
||||
API_URL: getApiUrl(),
|
||||
// API相关配置 - 直接使用Dify API
|
||||
API_URL: getDifyApiUrl(),
|
||||
APP_ID: getAppId(),
|
||||
API_KEY: getEnvVar('NEXT_PUBLIC_APP_KEY', ''),
|
||||
|
||||
// Dify API 配置(用于服务端)
|
||||
DIFY_API_URL: getEnvVar('NEXT_PUBLIC_API_URL', 'https://api.dify.ai/v1'),
|
||||
// 用户生成函数
|
||||
generateUserId,
|
||||
|
||||
// 应用信息
|
||||
APP_INFO: {
|
||||
@@ -76,9 +83,6 @@ export const CHAT_CONFIG = {
|
||||
isShowPrompt: false,
|
||||
promptTemplate: 'I want you to act as a javascript console.',
|
||||
|
||||
// API相关
|
||||
API_PREFIX: '/api',
|
||||
|
||||
// 本地化
|
||||
LOCALE_COOKIE_NAME: 'locale',
|
||||
|
||||
|
||||
@@ -113,8 +113,6 @@ export default function useConversation() {
|
||||
isSetToLocalStorage = true,
|
||||
newConversationName = ''
|
||||
) => {
|
||||
// console.log('🔄 设置当前会话ID:', { id, appId, isSetToLocalStorage });
|
||||
|
||||
doSetCurrConversationId(id);
|
||||
|
||||
if (isSetToLocalStorage && id !== '-1') {
|
||||
@@ -130,19 +128,11 @@ export default function useConversation() {
|
||||
|
||||
globalThis.localStorage?.setItem(storageConversationIdKey, JSON.stringify(conversationIdInfo));
|
||||
|
||||
// console.log('💾 会话ID已保存到localStorage:', {
|
||||
// appUrlKey,
|
||||
// conversationId: id,
|
||||
// fullStorage: conversationIdInfo
|
||||
// });
|
||||
} catch (error) {
|
||||
console.error('保存会话ID到本地存储失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 不进行URL导航,保持单页面应用模式
|
||||
// console.log('✅ 会话切换完成,当前会话ID:', id);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 重置新会话输入
|
||||
|
||||
@@ -7,6 +7,8 @@ import chatInputStyles from "~/styles/components/chat-with-llm/chat-input.css?ur
|
||||
import chatSidebarStyles from "~/styles/components/chat-with-llm/sidebar.css?url";
|
||||
import chatThoughtProcessStyles from "~/styles/components/chat-with-llm/thought-process.css?url";
|
||||
import chatMarkdownStyles from "~/styles/components/chat-with-llm/markdown.css?url";
|
||||
// 导入测试文件用于调试
|
||||
import "~/utils/dify-test.client";
|
||||
|
||||
export function links() {
|
||||
return [
|
||||
@@ -32,6 +34,11 @@ export const meta: MetaFunction = () => {
|
||||
/**
|
||||
* 聊天主页面
|
||||
* 实现单页面应用模式,所有会话切换都在同一页面内完成
|
||||
*
|
||||
* 调试说明:
|
||||
* - 打开浏览器开发者工具的控制台
|
||||
* - 输入 window.testDify() 可以测试Dify API连接
|
||||
* - 查看网络选项卡可以监控API请求
|
||||
*/
|
||||
export default function ChatWithLLMIndex() {
|
||||
return (
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { Outlet } from "react-router-dom";
|
||||
import {type MetaFunction} from "@remix-run/node";
|
||||
import { Outlet } from "@remix-run/react";
|
||||
import { type MetaFunction } from "@remix-run/node";
|
||||
|
||||
export const meta: MetaFunction = () => {
|
||||
return [
|
||||
{title: "文档列表 - 中国烟草AI合同及卷宗审核系统"},
|
||||
{name: "documents", content: "文档列表,新增,修改"}
|
||||
{ title: "文档列表 - 中国烟草AI合同及卷宗审核系统" },
|
||||
{ name: "documents", content: "文档列表,新增,修改" }
|
||||
]
|
||||
}
|
||||
|
||||
export const handle = {
|
||||
breadcrumb: "文档列表"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文档列表路由布局
|
||||
|
||||
+660
-236
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,85 @@
|
||||
import { CHAT_CONFIG } from '../config/chat';
|
||||
|
||||
/**
|
||||
* 测试Dify API连接
|
||||
* 这个文件可以用来调试和测试前端直接调用Dify API的功能
|
||||
*/
|
||||
export const testDifyConnection = async () => {
|
||||
console.log('🔧 Dify Configuration:', {
|
||||
apiUrl: CHAT_CONFIG.API_URL,
|
||||
appId: CHAT_CONFIG.APP_ID,
|
||||
hasApiKey: !!CHAT_CONFIG.API_KEY,
|
||||
apiKeyPreview: CHAT_CONFIG.API_KEY ? `${CHAT_CONFIG.API_KEY.substring(0, 10)}...` : 'No API Key',
|
||||
});
|
||||
|
||||
if (!CHAT_CONFIG.API_URL || !CHAT_CONFIG.APP_ID || !CHAT_CONFIG.API_KEY) {
|
||||
console.error('❌ Dify配置不完整,请检查环境变量');
|
||||
return false;
|
||||
}
|
||||
|
||||
const user = CHAT_CONFIG.generateUserId();
|
||||
console.log('👤 Generated User ID:', user);
|
||||
|
||||
try {
|
||||
// 测试获取应用参数
|
||||
console.log('📋 测试获取应用参数...');
|
||||
const response = await fetch(`${CHAT_CONFIG.API_URL}/parameters`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${CHAT_CONFIG.API_KEY}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
console.error('❌ 获取应用参数失败:', response.status, response.statusText);
|
||||
const errorText = await response.text();
|
||||
console.error('错误详情:', errorText);
|
||||
return false;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('✅ 成功获取应用参数:', data);
|
||||
|
||||
// 测试获取会话列表
|
||||
console.log('💬 测试获取会话列表...');
|
||||
const params = new URLSearchParams({
|
||||
user,
|
||||
limit: '10',
|
||||
first_id: '',
|
||||
});
|
||||
|
||||
const conversationsResponse = await fetch(`${CHAT_CONFIG.API_URL}/conversations?${params}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${CHAT_CONFIG.API_KEY}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (!conversationsResponse.ok) {
|
||||
console.error('❌ 获取会话列表失败:', conversationsResponse.status, conversationsResponse.statusText);
|
||||
const errorText = await conversationsResponse.text();
|
||||
console.error('错误详情:', errorText);
|
||||
return false;
|
||||
}
|
||||
|
||||
const conversationsData = await conversationsResponse.json();
|
||||
console.log('✅ 成功获取会话列表:', conversationsData);
|
||||
|
||||
return true;
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 测试Dify连接时发生错误:', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 在浏览器控制台中可以调用这个函数进行测试
|
||||
* 使用方法:
|
||||
* 1. 打开浏览器控制台
|
||||
* 2. 输入: window.testDify()
|
||||
* 3. 查看输出结果
|
||||
*/
|
||||
if (typeof window !== 'undefined') {
|
||||
(window as any).testDify = testDifyConnection;
|
||||
}
|
||||
Generated
+1
@@ -6,6 +6,7 @@
|
||||
"": {
|
||||
"name": "remix_docreview",
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.6.1",
|
||||
"@codemirror/lang-javascript": "^6.2.3",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@react-pdf-viewer/core": "^3.12.0",
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"typecheck": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.6.1",
|
||||
"@codemirror/lang-javascript": "^6.2.3",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@react-pdf-viewer/core": "^3.12.0",
|
||||
|
||||
Generated
+12337
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -42,6 +42,6 @@ export default defineConfig({
|
||||
// 防止依赖预构建时触发页面刷新导致路由中断
|
||||
force: false,
|
||||
// 预构建这些依赖,避免首次加载时出现重新构建
|
||||
include: ['react-pdf', 'pdfjs-dist', 'dayjs', '@remix-run/node', 'react-dom', 'axios', 'dayjs/plugin/utc', 'react-router-dom', 'jszip', 'ahooks', 'antd', 'immer', '@ant-design/icons', 'react-markdown', 'remark-math', 'remark-breaks', 'rehype-katex','remark-gfm'],
|
||||
include: ['react-pdf', 'pdfjs-dist', 'dayjs', '@remix-run/node', 'react-dom', 'axios', 'dayjs/plugin/utc', '@remix-run/react', 'jszip', 'ahooks', 'antd', 'immer', '@ant-design/icons', 'react-markdown', 'remark-math', 'remark-breaks', 'rehype-katex', 'remark-gfm'],
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user