1. 开启交叉评查的显示/隐藏(开启生产环境的配置),优化不同端口的显示/隐藏交叉评查入口的效果。
2. 优化评查结果的AI建议修改的文本输入框的显示效果。 3. 提交17正式环境的api-config.ts,备份一个wafIP的配置api-config-wafIP.ts。
This commit is contained in:
@@ -2100,10 +2100,11 @@ export function ReviewPointsList({
|
||||
value={suggestionValue.suggested_value || ''}
|
||||
readOnly
|
||||
disabled={!hasSuggestedValue}
|
||||
rows={Math.min(Math.max(Math.ceil((suggestionValue.suggested_value || '').length / 30), 1), 5)}
|
||||
className={`flex-1 p-2 border rounded text-xs resize-none overflow-y-auto focus:outline-none ${
|
||||
hasSuggestedValue
|
||||
? 'border-gray-200 bg-gray-50 text-gray-700 cursor-not-allowed'
|
||||
: 'border-gray-200 bg-gray-100 text-gray-400 cursor-not-allowed'
|
||||
? 'border-gray-200 bg-gray-50 text-gray-700'
|
||||
: 'border-gray-200 bg-gray-100 text-gray-400'
|
||||
}`}
|
||||
aria-label={`${key}的AI建议内容`}
|
||||
placeholder={!hasSuggestedValue ? '暂无建议值' : ''}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useState, useEffect } from 'react';
|
||||
import { Link, useLocation, useNavigate } from '@remix-run/react';
|
||||
import type { UserRole } from '~/root';
|
||||
import { getUserRoutesByRole, mapUserRoleToRoleKey, type MenuItem } from '~/api/auth/user-routes';
|
||||
import { DOCUMENT_URL } from '~/config/api-config';
|
||||
import { DOCUMENT_URL, CROSS_CHECKING_ONLY_PORT, CROSS_CHECKING_ONLY_MODE } from '~/config/api-config';
|
||||
|
||||
interface SidebarProps {
|
||||
onToggle: () => void;
|
||||
@@ -95,6 +95,15 @@ export function Sidebar({ onToggle, collapsed, userRole, frontendJWT = '' }: Sid
|
||||
const [isSettingsMode, setIsSettingsMode] = useState<boolean>(false);
|
||||
const [isCrossCheckingMode, setIsCrossCheckingMode] = useState<boolean>(false);
|
||||
|
||||
// 🔒 检测当前端口,用于控制交叉评查入口的显示
|
||||
const [currentPort, setCurrentPort] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
setCurrentPort(window.location.port || '');
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 从 sessionStorage 读取当前选中的模块名称和图片路径,以及各种模式标志
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
@@ -200,6 +209,15 @@ export function Sidebar({ onToggle, collapsed, userRole, frontendJWT = '' }: Sid
|
||||
return false;
|
||||
}
|
||||
|
||||
// 🔒 交叉评查访问控制:
|
||||
// - CROSS_CHECKING_ONLY_MODE=false 时,所有端口都可访问(根据后端权限)
|
||||
// - CROSS_CHECKING_ONLY_MODE=true 时,只有 51707 端口可访问
|
||||
if (CROSS_CHECKING_ONLY_MODE && currentPort && currentPort !== CROSS_CHECKING_ONLY_PORT) {
|
||||
if (item.path === '/cross-checking' || item.path?.startsWith('/cross-checking/')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 🔑 重要:非交叉评查模式下,隐藏所有 /cross-checking 相关菜单
|
||||
if (item.path === '/cross-checking' || item.path?.startsWith('/cross-checking/')) {
|
||||
return false;
|
||||
|
||||
@@ -1760,7 +1760,7 @@ export function ReviewPointsList({
|
||||
{/* 字段名称标签 */}
|
||||
<div className="text-xs text-gray-600 mb-2 font-medium">
|
||||
<i className="ri-lightbulb-line text-yellow-500 mr-1"></i>
|
||||
AI建议修改 - {key}
|
||||
AI修改建议 - {key}
|
||||
</div>
|
||||
|
||||
{/* 原因说明 */}
|
||||
@@ -1785,10 +1785,11 @@ export function ReviewPointsList({
|
||||
value={suggestionValue.suggested_value || ''}
|
||||
readOnly
|
||||
disabled={!hasSuggestedValue}
|
||||
rows={Math.min(Math.max(Math.ceil((suggestionValue.suggested_value || '').length / 30), 1), 5)}
|
||||
className={`flex-1 p-2 border rounded text-xs resize-none overflow-y-auto focus:outline-none ${
|
||||
hasSuggestedValue
|
||||
? 'border-gray-200 bg-gray-50 text-gray-700 cursor-not-allowed'
|
||||
: 'border-gray-200 bg-gray-100 text-gray-400 cursor-not-allowed'
|
||||
? 'border-gray-200 bg-gray-50 text-gray-700'
|
||||
: 'border-gray-200 bg-gray-100 text-gray-400'
|
||||
}`}
|
||||
aria-label={`${key}的AI建议内容`}
|
||||
placeholder={!hasSuggestedValue ? '暂无建议值' : ''}
|
||||
|
||||
@@ -338,7 +338,7 @@ export function PdfPreview({
|
||||
fill="#00AA00"
|
||||
fillOpacity="0.1"
|
||||
stroke="#00684a"
|
||||
strokeWidth="1"
|
||||
strokeWidth="0.5"
|
||||
rx="2"
|
||||
>
|
||||
<title>{`高亮文本: ${highlight.text}`}</title>
|
||||
|
||||
@@ -5,24 +5,35 @@
|
||||
*/
|
||||
// 环境配置类型
|
||||
interface ApiConfig {
|
||||
// 主API基础URL
|
||||
// 主API基础URL(FastAPI后端地址,包含Dify代理)
|
||||
baseUrl: string;
|
||||
// 文档服务URL
|
||||
documentUrl: string;
|
||||
// 文档上传API URL
|
||||
uploadUrl: string;
|
||||
// Collabora Online 服务器地址
|
||||
collaboraUrl: string;
|
||||
// 应用基础URL(用于 WOPI 回调)
|
||||
appUrl: string;
|
||||
// OAuth2.0配置
|
||||
oauth: {
|
||||
// IDaaS服务器地址
|
||||
serverUrl: string;
|
||||
serverUrl?: string;
|
||||
// OAuth2应用Client ID
|
||||
clientId: string;
|
||||
clientId?: string;
|
||||
// OAuth2应用Client Secret
|
||||
clientSecret: string;
|
||||
clientSecret?: string;
|
||||
// 回调地址
|
||||
redirectUri: string;
|
||||
redirectUri?: string;
|
||||
// 应用ID(用于登出)
|
||||
appId: string;
|
||||
appId?: string;
|
||||
};
|
||||
// Dify 知识库检索配置
|
||||
dify: {
|
||||
// Reranking 模型提供商
|
||||
rerankingProviderName: string;
|
||||
// Reranking 模型名称
|
||||
rerankingModelName: string;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -30,154 +41,191 @@ interface ApiConfig {
|
||||
// 根据不同端口提供不同的API配置
|
||||
const portConfigs: Record<string, Partial<ApiConfig>> = {
|
||||
|
||||
// 测试主要服务实例
|
||||
'5173': {
|
||||
baseUrl: 'http://172.16.0.55:8000',
|
||||
documentUrl: 'http://172.16.0.55:8000/docauditai/',
|
||||
uploadUrl: 'http://172.16.0.55:8000/admin/documents'
|
||||
},
|
||||
// 测试客户端实例
|
||||
'5174': {
|
||||
baseUrl: 'http://172.16.0.55:5174',
|
||||
documentUrl: 'http://172.16.0.55:5174/docauditai/',
|
||||
uploadUrl: 'http://172.16.0.55:5174/admin/documents'
|
||||
},
|
||||
// 测试客户端实例
|
||||
'5175': {
|
||||
baseUrl: 'http://172.16.0.55:5175',
|
||||
documentUrl: 'http://172.16.0.55:5175/docauditai/',
|
||||
uploadUrl: 'http://172.16.0.55:5175/admin/documents'
|
||||
},
|
||||
// 测试客户端实例
|
||||
'5176': {
|
||||
baseUrl: 'http://172.16.0.55:5176',
|
||||
documentUrl: 'http://172.16.0.55:5176/docauditai/',
|
||||
uploadUrl: 'http://172.16.0.55:5176/admin/documents'
|
||||
},
|
||||
// 测试客户端实例
|
||||
'5177': {
|
||||
baseUrl: 'http://172.16.0.55:5177',
|
||||
documentUrl: 'http://172.16.0.55:5177/docauditai/',
|
||||
uploadUrl: 'http://172.16.0.55:5177/admin/documents'
|
||||
},
|
||||
// 测试客户端实例
|
||||
'5178': {
|
||||
baseUrl: 'http://172.16.0.55:8008',
|
||||
documentUrl: 'http://172.16.0.55:8008/docauditai/',
|
||||
uploadUrl: 'http://172.16.0.55:8008/admin/documents'
|
||||
},
|
||||
|
||||
|
||||
|
||||
// 主要
|
||||
// 梅州
|
||||
'51703': {
|
||||
baseUrl: 'http://172.16.0.55:8073',
|
||||
documentUrl: 'http://172.16.0.55:8073/docauditai/',
|
||||
uploadUrl: 'http://172.16.0.55:8073/admin/documents'
|
||||
// baseUrl: 'http://nas.7bm.co:8873',
|
||||
// documentUrl: 'http://nas.7bm.co:8873/docauditai/',
|
||||
// uploadUrl: 'http://nas.7bm.co:8873/admin/documents'
|
||||
// baseUrl: 'http://172.16.0.56:8073',
|
||||
// documentUrl: 'http://172.16.0.56:8073/docauditai/',
|
||||
// uploadUrl: 'http://172.16.0.56:8073/api/v2/documents',
|
||||
// collaboraUrl: 'http://172.16.0.81:9980',
|
||||
// appUrl: 'http://172.16.0.34:51703',
|
||||
|
||||
baseUrl: 'http://10.79.96.233:8000',
|
||||
documentUrl: 'http://10.79.96.233:8000/docauditai/',
|
||||
uploadUrl: 'http://10.79.96.233:8000/api/v2/documents',
|
||||
collaboraUrl: 'http://10.79.96.233:9980',
|
||||
appUrl: 'http://10.79.96.233:51703',
|
||||
|
||||
oauth: {
|
||||
redirectUri: 'http://10.79.96.233:51703/callback'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
// 云浮
|
||||
'51704': {
|
||||
baseUrl: 'http://10.79.97.17:8001',
|
||||
documentUrl: 'http://10.79.97.17:8001/docauditai/',
|
||||
uploadUrl: 'http://10.79.97.17:8001/admin/documents'
|
||||
// baseUrl: 'http://172.16.0.55:8001',
|
||||
// documentUrl: 'http://172.16.0.55:8001/docauditai/',
|
||||
// uploadUrl: 'http://172.16.0.55:8001/api/v2/documents',
|
||||
// collaboraUrl: 'http://172.16.0.81:9980',
|
||||
// appUrl: 'http://172.16.0.34:51704',
|
||||
|
||||
baseUrl: 'http://10.79.96.233:8001',
|
||||
documentUrl: 'http://10.79.96.233:8001/docauditai/',
|
||||
uploadUrl: 'http://10.79.96.233:8001/api/v2/documents',
|
||||
collaboraUrl: 'http://10.79.96.233:9980',
|
||||
appUrl: 'http://10.79.96.233:51704',
|
||||
oauth: {
|
||||
redirectUri: 'http://10.79.96.233:51704/callback'
|
||||
}
|
||||
},
|
||||
|
||||
// 揭阳
|
||||
'51705': {
|
||||
baseUrl: 'http://10.79.97.17:8002',
|
||||
documentUrl: 'http://10.79.97.17:8002/docauditai/',
|
||||
uploadUrl: 'http://10.79.97.17:8002/admin/documents'
|
||||
baseUrl: 'http://10.79.96.233:8002',
|
||||
documentUrl: 'http://10.79.96.233:8002/docauditai/',
|
||||
uploadUrl: 'http://10.79.96.233:8002/api/v2/documents',
|
||||
collaboraUrl: 'http://10.79.96.233:9980',
|
||||
appUrl: 'http://10.79.96.233:51705',
|
||||
oauth: {
|
||||
redirectUri: 'http://10.79.96.233:51705/callback'
|
||||
}
|
||||
},
|
||||
|
||||
// 潮州
|
||||
'51706': {
|
||||
baseUrl: 'http://10.79.97.17:8003',
|
||||
documentUrl: 'http://10.79.97.17:8003/docauditai/',
|
||||
uploadUrl: 'http://10.79.97.17:8003/admin/documents'
|
||||
baseUrl: 'http://10.79.96.233:8003',
|
||||
documentUrl: 'http://10.79.96.233:8003/docauditai/',
|
||||
uploadUrl: 'http://10.79.96.233:8003/api/v2/documents',
|
||||
collaboraUrl: 'http://10.79.96.233:9980',
|
||||
appUrl: 'http://10.79.96.233:51706',
|
||||
oauth: {
|
||||
redirectUri: 'http://10.79.96.233:51706/callback'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 省局
|
||||
'51707': {
|
||||
baseUrl: 'http://10.79.97.17:8004',
|
||||
documentUrl: 'http://10.79.97.17:8004/docauditai/',
|
||||
uploadUrl: 'http://10.79.97.17:8004/admin/documents'
|
||||
// baseUrl: 'http://172.16.0.55:8866',
|
||||
// documentUrl: 'http://172.16.0.55:8866/docauditai/',
|
||||
// uploadUrl: 'http://172.16.0.55:8866/api/v2/documents',
|
||||
// collaboraUrl: 'http://172.16.0.81:9980',
|
||||
// appUrl: 'http://172.16.0.34:51707',
|
||||
|
||||
// 正式环境
|
||||
baseUrl: 'http://10.79.96.233:8004',
|
||||
documentUrl: 'http://10.79.96.233:8004/docauditai/',
|
||||
uploadUrl: 'http://10.79.96.233:8004/api/v2/documents',
|
||||
collaboraUrl: 'http://10.79.96.233:9980',
|
||||
appUrl: 'http://10.79.96.233:51707',
|
||||
|
||||
oauth: {
|
||||
redirectUri: 'http://10.79.96.233:51707/callback'
|
||||
}
|
||||
},
|
||||
|
||||
//test
|
||||
'51708': {
|
||||
baseUrl: 'http://10.79.97.17:8005',
|
||||
documentUrl: 'http://10.79.97.17:8005/docauditai/',
|
||||
uploadUrl: 'http://10.79.97.17:8005/admin/documents'
|
||||
baseUrl: 'http://10.79.96.233:8005',
|
||||
documentUrl: 'http://10.79.96.233:8005/docauditai/',
|
||||
uploadUrl: 'http://10.79.96.233:8005/api/v2/documents',
|
||||
collaboraUrl: 'http://10.79.96.233:9980',
|
||||
appUrl: 'http://10.79.96.233:51708'
|
||||
},
|
||||
};
|
||||
|
||||
// 不同环境的默认配置
|
||||
// 由于合同模板的上传,后续的的uploadUrl都不需要/upload,直接写/admin/documents,由程序自动添加/upload或/upload_contract_template
|
||||
// 由于合同模板的上传,后续的的uploadUrl都不需要/upload,直接写/api/v2/documents,由程序自动添加/upload或/upload_contract_template
|
||||
const configs: Record<string, ApiConfig> = {
|
||||
// 开发环境
|
||||
development: {
|
||||
baseUrl: 'http://172.16.0.55:8000',
|
||||
documentUrl: 'http://172.16.0.55:8000/docauditai/',
|
||||
uploadUrl: 'http://172.16.0.55:8000/admin/documents',
|
||||
// baseUrl: 'http://172.16.0.58:8073', // FastAPI后端(包含/dify代理)
|
||||
// documentUrl: 'http://172.16.0.58:8073/docauditai/',
|
||||
// uploadUrl: 'http://172.16.0.58:8073/api/v2/documents',
|
||||
baseUrl: 'http://172.16.0.55:8073', // FastAPI后端(包含/dify代理)
|
||||
documentUrl: 'http://172.16.0.55:8073/docauditai/',
|
||||
uploadUrl: 'http://172.16.0.55:8073/api/v2/documents',
|
||||
|
||||
collaboraUrl: 'http://172.16.0.81:9980',
|
||||
appUrl: 'http://172.16.0.34:5173',
|
||||
|
||||
oauth: {
|
||||
serverUrl: 'http://10.79.112.85', // IDaaS服务器地址
|
||||
clientId: 'none',
|
||||
clientSecret: 'none', // 需要替换为实际的Client Secret
|
||||
redirectUri: 'http://10.79.97.17/', // 回调地址
|
||||
redirectUri: 'http://10.79.96.233/', // 回调地址
|
||||
appId: 'idaasoauth2' // 应用ID,用于登出
|
||||
},
|
||||
dify: {
|
||||
rerankingProviderName: 'langgenius/tongyi/tongyi',
|
||||
rerankingModelName: 'gte-rerank'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 测试环境
|
||||
testing: {
|
||||
baseUrl: 'http://nas.7bm.co:8873',
|
||||
documentUrl: 'http://nas.7bm.co:8873/docauditai/',
|
||||
uploadUrl: 'http://nas.7bm.co:8873/admin/documents',
|
||||
baseUrl: 'http://172.16.0.55:8073', // FastAPI后端(包含/dify代理)
|
||||
documentUrl: 'http://172.16.0.55:8073/docauditai/',
|
||||
uploadUrl: 'http://172.16.0.55:8073/api/v2/documents',
|
||||
collaboraUrl: 'http://172.16.0.81:9980',
|
||||
// appUrl: 'http://10.79.96.233:51703',
|
||||
appUrl: 'http://172.16.0.34:5183',
|
||||
oauth: {
|
||||
serverUrl: 'http://10.79.112.85', // IDaaS服务器地址
|
||||
clientId: '54d2a619fe5c81ae1250434c441fccccqMtKwh7H4fO',
|
||||
clientSecret: 'placeholder', // 需要替换为实际的Client Secret
|
||||
redirectUri: 'http://10.79.97.17/', // 回调地址
|
||||
redirectUri: 'http://10.79.96.233/', // 回调地址
|
||||
appId: 'idaasoauth2' // 应用ID,用于登出
|
||||
},
|
||||
dify: {
|
||||
rerankingProviderName: 'langgenius/tongyi/tongyi',
|
||||
rerankingModelName: 'gte-rerank'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 生产环境
|
||||
production: {
|
||||
// postgrest
|
||||
baseUrl: 'http://10.79.97.17:8000',
|
||||
baseUrl: 'http://10.79.96.233:8000', // FastAPI后端(包含/dify代理)
|
||||
// minio
|
||||
documentUrl: 'http://10.76.244.156:9000/docauditai/',
|
||||
// 文件上传
|
||||
uploadUrl: 'http://10.79.97.17:8000/admin/documents',
|
||||
uploadUrl: 'http://10.79.96.233:8000/api/v2/documents',
|
||||
collaboraUrl: 'http://10.79.96.233:9980',
|
||||
appUrl: 'http://10.79.96.233:51703',
|
||||
oauth: {
|
||||
serverUrl: 'http://10.79.112.85', // IDaaS服务器地址
|
||||
clientId: '54d2a619fe5c81ae1250434c441fccccqMtKwh7H4fO',
|
||||
// clientSecret: 'VYk1AC5XIJEfnEXwyq0u9JEY3fi3byCfSD58zANGeb', // 需要替换为实际的Client Secret
|
||||
serverUrl: 'http://10.79.112.85', // IDaaS服务器地址(测试)
|
||||
// serverUrl: 'http://10.79.97.252', // IDaaS服务器地址(生产)
|
||||
// ⚠️ 安全警告:clientSecret 不应该硬编码在代码中
|
||||
// 请在生产环境使用环境变量 OAUTH_CLIENT_SECRET
|
||||
clientSecret: 'placeholder', // 占位符,实际值从环境变量获取
|
||||
redirectUri: 'http://10.79.97.17/', // 回调地址
|
||||
redirectUri: 'http://10.79.96.233/', // 回调地址
|
||||
appId: 'idaasoauth2' // 应用ID,用于登出
|
||||
},
|
||||
dify: {
|
||||
rerankingProviderName: 'langgenius/tongyi/tongyi',
|
||||
rerankingModelName: 'gte-rerank'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 备用配置 (可以根据需要添加更多环境)
|
||||
staging: {
|
||||
baseUrl: 'http://172.16.0.119:9000/admin',
|
||||
baseUrl: 'http://172.16.0.119:9000/admin', // FastAPI后端(包含/dify代理)
|
||||
documentUrl: 'http://nas.7bm.co:9000/docauditai/',
|
||||
uploadUrl: 'http://172.16.0.119:8000/admin/documents/upload',
|
||||
uploadUrl: 'http://172.16.0.119:8000/api/v2/documents',
|
||||
collaboraUrl: 'http://10.79.96.233:9980',
|
||||
appUrl: 'http://172.16.0.119:3000',
|
||||
oauth: {
|
||||
serverUrl: 'http://10.79.112.85', // IDaaS服务器地址
|
||||
clientId: 'none', // 需要替换为实际的Client ID
|
||||
clientSecret: 'your_client_secret', // 需要替换为实际的Client Secret
|
||||
redirectUri: 'http://172.16.0.119:3000/callback', // 回调地址
|
||||
appId: 'idaasoauth2' // 应用ID,用于登出
|
||||
},
|
||||
dify: {
|
||||
rerankingProviderName: 'langgenius/tongyi/tongyi',
|
||||
rerankingModelName: 'gte-rerank'
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -194,18 +242,18 @@ const getCurrentEnvironment = (): string => {
|
||||
});
|
||||
return nodeEnv || 'development';
|
||||
}
|
||||
|
||||
|
||||
// 客户端:优先使用NEXT_PUBLIC_前缀的环境变量
|
||||
const nextPublicNodeEnv = process.env.NEXT_PUBLIC_NODE_ENV;
|
||||
const nodeEnv = process.env.NODE_ENV;
|
||||
const result = nextPublicNodeEnv || nodeEnv || 'development';
|
||||
|
||||
|
||||
console.log('🔧 客户端环境检测:', {
|
||||
NEXT_PUBLIC_NODE_ENV: nextPublicNodeEnv,
|
||||
NODE_ENV: nodeEnv,
|
||||
result: result
|
||||
});
|
||||
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -215,6 +263,10 @@ const getConfigFromEnv = (defaultConfig: ApiConfig): ApiConfig => {
|
||||
baseUrl: process.env.NEXT_PUBLIC_API_BASE_URL || defaultConfig.baseUrl,
|
||||
documentUrl: process.env.NEXT_PUBLIC_DOCUMENT_URL || defaultConfig.documentUrl,
|
||||
uploadUrl: process.env.NEXT_PUBLIC_UPLOAD_URL || defaultConfig.uploadUrl,
|
||||
|
||||
collaboraUrl: defaultConfig.collaboraUrl || '',
|
||||
appUrl: defaultConfig.appUrl || '',
|
||||
|
||||
oauth: {
|
||||
serverUrl: process.env.NEXT_PUBLIC_OAUTH_SERVER_URL || defaultConfig.oauth.serverUrl,
|
||||
clientId: process.env.NEXT_PUBLIC_OAUTH_CLIENT_ID || defaultConfig.oauth.clientId,
|
||||
@@ -223,7 +275,8 @@ const getConfigFromEnv = (defaultConfig: ApiConfig): ApiConfig => {
|
||||
clientSecret: process.env.OAUTH_CLIENT_SECRET || defaultConfig.oauth.clientSecret,
|
||||
redirectUri: process.env.NEXT_PUBLIC_OAUTH_REDIRECT_URI || defaultConfig.oauth.redirectUri,
|
||||
appId: process.env.NEXT_PUBLIC_OAUTH_APP_ID || defaultConfig.oauth.appId
|
||||
}
|
||||
},
|
||||
dify: defaultConfig.dify
|
||||
};
|
||||
};
|
||||
|
||||
@@ -237,7 +290,7 @@ const getCurrentPort = (): string => {
|
||||
if (typeof window !== 'undefined') {
|
||||
windowPort = window.location.port || '';
|
||||
}
|
||||
|
||||
|
||||
// 在服务器端,优先使用运行时端口检测
|
||||
if (typeof window === 'undefined') {
|
||||
const runtimePort = getRuntimePort();
|
||||
@@ -246,16 +299,16 @@ const getCurrentPort = (): string => {
|
||||
return runtimePort;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 优先使用环境变量中的端口配置
|
||||
const nextPublicApiPortConfig = process.env.NEXT_PUBLIC_API_PORT_CONFIG;
|
||||
const nextPublicPort = process.env.NEXT_PUBLIC_PORT;
|
||||
const apiPortConfig = process.env.API_PORT_CONFIG;
|
||||
const portEnv = process.env.PORT;
|
||||
|
||||
|
||||
// 优先级:windowPort > NEXT_PUBLIC_API_PORT_CONFIG > NEXT_PUBLIC_PORT > API_PORT_CONFIG > PORT环境变量
|
||||
const result = windowPort || nextPublicApiPortConfig || nextPublicPort || apiPortConfig || portEnv || '';
|
||||
|
||||
|
||||
console.log('🔧 端口检测:', {
|
||||
windowPort: windowPort,
|
||||
NEXT_PUBLIC_API_PORT_CONFIG: nextPublicApiPortConfig,
|
||||
@@ -264,7 +317,7 @@ const getCurrentPort = (): string => {
|
||||
PORT: portEnv,
|
||||
result: result
|
||||
});
|
||||
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -276,7 +329,7 @@ const getRuntimePort = (): string => {
|
||||
if (typeof window !== 'undefined') {
|
||||
return ''; // 客户端不执行此逻辑
|
||||
}
|
||||
|
||||
|
||||
// 尝试从进程参数中获取端口
|
||||
const args = process.argv;
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
@@ -287,7 +340,7 @@ const getRuntimePort = (): string => {
|
||||
return args[i].split('=')[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 从环境变量获取
|
||||
return process.env.PORT || '';
|
||||
};
|
||||
@@ -299,40 +352,44 @@ const getRuntimePort = (): string => {
|
||||
const getCurrentConfig = (): ApiConfig => {
|
||||
const env = getCurrentEnvironment();
|
||||
const port = getCurrentPort();
|
||||
|
||||
|
||||
console.log('🔧 配置调试信息:', {
|
||||
environment: env,
|
||||
port: port,
|
||||
hasPortConfig: !!(port && portConfigs[port]),
|
||||
portConfig: port ? portConfigs[port] : null
|
||||
});
|
||||
|
||||
|
||||
// 获取基础配置
|
||||
let defaultConfig = configs[env] || configs.development;
|
||||
|
||||
|
||||
// 如果有端口特定配置,则合并配置
|
||||
if (port && portConfigs[port]) {
|
||||
console.log(`🔧 使用端口特定配置: ${port}`, portConfigs[port]);
|
||||
console.log(`🔧 使用端口特定配置: ${port}`);
|
||||
const portConfig = portConfigs[port];
|
||||
defaultConfig = {
|
||||
...defaultConfig,
|
||||
...portConfigs[port],
|
||||
// 保持oauth配置不变,只覆盖API相关配置
|
||||
oauth: defaultConfig.oauth
|
||||
...defaultConfig,
|
||||
...portConfig,
|
||||
// 如果端口配置中有oauth,需要深度合并oauth配置
|
||||
oauth: portConfig.oauth
|
||||
? { ...defaultConfig.oauth, ...portConfig.oauth }
|
||||
: defaultConfig.oauth
|
||||
};
|
||||
console.log(`🔧 使用端口特定配置---深度合并后: ${JSON.stringify(defaultConfig.oauth)}`)
|
||||
} else {
|
||||
console.log(`🔧 使用环境配置: ${env}`, defaultConfig);
|
||||
}
|
||||
|
||||
|
||||
// 只有在明确设置了环境变量的情况下才覆盖配置
|
||||
const hasEnvOverrides = process.env.NEXT_PUBLIC_API_BASE_URL ||
|
||||
process.env.NEXT_PUBLIC_DOCUMENT_URL ||
|
||||
process.env.NEXT_PUBLIC_UPLOAD_URL;
|
||||
|
||||
const hasEnvOverrides = process.env.NEXT_PUBLIC_API_BASE_URL ||
|
||||
process.env.NEXT_PUBLIC_DOCUMENT_URL ||
|
||||
process.env.NEXT_PUBLIC_UPLOAD_URL;
|
||||
|
||||
if (hasEnvOverrides) {
|
||||
console.log('🔧 检测到环境变量覆盖,使用环境变量配置');
|
||||
return getConfigFromEnv(defaultConfig);
|
||||
}
|
||||
|
||||
|
||||
console.log('🔧 最终配置:', defaultConfig);
|
||||
return defaultConfig;
|
||||
};
|
||||
@@ -343,9 +400,12 @@ export const apiConfig = getCurrentConfig();
|
||||
// 导出具体的配置项,方便使用
|
||||
export const {
|
||||
baseUrl: API_BASE_URL,
|
||||
documentUrl: DOCUMENT_URL,
|
||||
documentUrl: DOCUMENT_URL,
|
||||
uploadUrl: UPLOAD_URL,
|
||||
oauth: OAUTH_CONFIG
|
||||
collaboraUrl: COLLABORA_URL,
|
||||
appUrl: APP_URL,
|
||||
oauth: OAUTH_CONFIG,
|
||||
dify: DIFY_CONFIG
|
||||
} = apiConfig;
|
||||
|
||||
/**
|
||||
@@ -353,10 +413,10 @@ export const {
|
||||
* 可以安全地在客户端代码中使用
|
||||
*/
|
||||
export const CLIENT_OAUTH_CONFIG = {
|
||||
serverUrl: OAUTH_CONFIG.serverUrl,
|
||||
clientId: OAUTH_CONFIG.clientId,
|
||||
redirectUri: OAUTH_CONFIG.redirectUri,
|
||||
appId: OAUTH_CONFIG.appId,
|
||||
serverUrl: OAUTH_CONFIG.serverUrl as string,
|
||||
clientId: OAUTH_CONFIG.clientId as string,
|
||||
redirectUri: OAUTH_CONFIG.redirectUri as string,
|
||||
appId: OAUTH_CONFIG.appId as string,
|
||||
// 客户端不需要 clientSecret
|
||||
};
|
||||
|
||||
@@ -396,4 +456,20 @@ if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'testing'
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 交叉评查专属模式配置
|
||||
* 当为 true 且端口为 51707 时,首页只显示交叉评查入口
|
||||
*/
|
||||
export const CROSS_CHECKING_ONLY_MODE = process.env.CROSS_CHECKING_ONLY_MODE === 'true';
|
||||
|
||||
/**
|
||||
* 交叉评查专属模式的目标端口
|
||||
*/
|
||||
export const CROSS_CHECKING_ONLY_PORT = '51707';
|
||||
|
||||
/**
|
||||
* 获取当前端口(服务端使用)
|
||||
*/
|
||||
export { getCurrentPort };
|
||||
+18
-12
@@ -47,14 +47,12 @@ const portConfigs: Record<string, Partial<ApiConfig>> = {
|
||||
// baseUrl: 'http://172.16.0.56:8073',
|
||||
// documentUrl: 'http://172.16.0.56:8073/docauditai/',
|
||||
// uploadUrl: 'http://172.16.0.56:8073/api/v2/documents',
|
||||
|
||||
// collaboraUrl: 'http://172.16.0.81:9980',
|
||||
// appUrl: 'http://172.16.0.34:51703',
|
||||
|
||||
baseUrl: 'http://10.79.97.17:8000',
|
||||
documentUrl: 'http://10.79.97.17:8000/docauditai/',
|
||||
uploadUrl: 'http://10.79.97.17:8000/api/v2/documents',
|
||||
|
||||
collaboraUrl: 'http://10.79.97.17:9980',
|
||||
appUrl: 'http://10.79.97.17:51703',
|
||||
|
||||
@@ -66,17 +64,17 @@ const portConfigs: Record<string, Partial<ApiConfig>> = {
|
||||
|
||||
// 云浮
|
||||
'51704': {
|
||||
baseUrl: 'http://172.16.0.55:8001',
|
||||
documentUrl: 'http://172.16.0.55:8001/docauditai/',
|
||||
uploadUrl: 'http://172.16.0.55:8001/api/v2/documents',
|
||||
collaboraUrl: 'http://172.16.0.81:9980',
|
||||
appUrl: 'http://172.16.0.34:51704',
|
||||
// baseUrl: 'http://172.16.0.55:8001',
|
||||
// documentUrl: 'http://172.16.0.55:8001/docauditai/',
|
||||
// uploadUrl: 'http://172.16.0.55:8001/api/v2/documents',
|
||||
// collaboraUrl: 'http://172.16.0.81:9980',
|
||||
// appUrl: 'http://172.16.0.34:51704',
|
||||
|
||||
// baseUrl: 'http://10.79.97.17:8001',
|
||||
// documentUrl: 'http://10.79.97.17:8001/docauditai/',
|
||||
// uploadUrl: 'http://10.79.97.17:8001/api/v2/documents',
|
||||
// collaboraUrl: 'http://10.79.97.17:9980',
|
||||
// appUrl: 'http://10.79.97.17:51704',
|
||||
baseUrl: 'http://10.79.97.17:8001',
|
||||
documentUrl: 'http://10.79.97.17:8001/docauditai/',
|
||||
uploadUrl: 'http://10.79.97.17:8001/api/v2/documents',
|
||||
collaboraUrl: 'http://10.79.97.17:9980',
|
||||
appUrl: 'http://10.79.97.17:51704',
|
||||
oauth: {
|
||||
redirectUri: 'http://10.79.97.17:51704/callback'
|
||||
}
|
||||
@@ -109,11 +107,19 @@ const portConfigs: Record<string, Partial<ApiConfig>> = {
|
||||
|
||||
// 省局
|
||||
'51707': {
|
||||
// baseUrl: 'http://172.16.0.55:8866',
|
||||
// documentUrl: 'http://172.16.0.55:8866/docauditai/',
|
||||
// uploadUrl: 'http://172.16.0.55:8866/api/v2/documents',
|
||||
// collaboraUrl: 'http://172.16.0.81:9980',
|
||||
// appUrl: 'http://172.16.0.34:51707',
|
||||
|
||||
// 正式环境
|
||||
baseUrl: 'http://10.79.97.17:8004',
|
||||
documentUrl: 'http://10.79.97.17:8004/docauditai/',
|
||||
uploadUrl: 'http://10.79.97.17:8004/api/v2/documents',
|
||||
collaboraUrl: 'http://10.79.97.17:9980',
|
||||
appUrl: 'http://10.79.97.17:51707',
|
||||
|
||||
oauth: {
|
||||
redirectUri: 'http://10.79.97.17:51707/callback'
|
||||
}
|
||||
|
||||
@@ -313,6 +313,17 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
}
|
||||
}
|
||||
|
||||
// 🔒 交叉评查访问控制:
|
||||
// - CROSS_CHECKING_ONLY_MODE=false 时,所有端口都可访问(根据后端权限)
|
||||
// - CROSS_CHECKING_ONLY_MODE=true 时,只有 51707 端口可访问
|
||||
if (CROSS_CHECKING_ONLY_MODE && !isPublicPath && currentPort !== CROSS_CHECKING_ONLY_PORT) {
|
||||
const isCrossCheckingPath = pathname === '/cross-checking' || pathname.startsWith('/cross-checking/');
|
||||
if (isCrossCheckingPath) {
|
||||
console.warn(`⚠️ [Root Loader] CROSS_CHECKING_ONLY_MODE启用,非51707端口禁止访问交叉评查:端口=${currentPort},路径=${pathname}`);
|
||||
throw new Response("当前端口无权访问交叉评查功能", { status: 403 });
|
||||
}
|
||||
}
|
||||
|
||||
// 向组件传递路径信息
|
||||
return Response.json({
|
||||
userRole, // ✅ 返回真实的用户角色
|
||||
|
||||
+13
-4
@@ -75,7 +75,15 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
}
|
||||
|
||||
// 检查是否存在顶级路由 '/cross-checking'
|
||||
hasCrossCheckingAccess = routesResult.data.some(route => route.path === '/cross-checking');
|
||||
// 🔒 交叉评查访问控制:
|
||||
// - CROSS_CHECKING_ONLY_MODE=false 时,所有端口都可访问(根据后端权限)
|
||||
// - CROSS_CHECKING_ONLY_MODE=true 时,只有 51707 端口可访问
|
||||
const currentPort = getCurrentPort();
|
||||
if (!CROSS_CHECKING_ONLY_MODE || currentPort === CROSS_CHECKING_ONLY_PORT) {
|
||||
hasCrossCheckingAccess = routesResult.data.some(route => route.path === '/cross-checking');
|
||||
} else {
|
||||
hasCrossCheckingAccess = false; // CROSS_CHECKING_ONLY_MODE=true 且非51707端口不显示交叉评查入口
|
||||
}
|
||||
|
||||
// 检查是否存在顶级路由 '/chat-with-llm'
|
||||
hasChatLLMAccess = routesResult.data.some(route => route.path === '/chat-with-llm');
|
||||
@@ -89,11 +97,12 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
|
||||
// 🔑 判断是否启用交叉评查专属模式
|
||||
// 条件:CROSS_CHECKING_ONLY_MODE=true 且 当前端口为 51707
|
||||
const currentPort = getCurrentPort();
|
||||
const isCrossCheckingOnlyMode = CROSS_CHECKING_ONLY_MODE && currentPort === CROSS_CHECKING_ONLY_PORT;
|
||||
// 注意:currentPort 已在上面的权限检查中获取,这里复用(如果在 if 块外需要则重新获取)
|
||||
const currentPortForMode = getCurrentPort();
|
||||
const isCrossCheckingOnlyMode = CROSS_CHECKING_ONLY_MODE && currentPortForMode === CROSS_CHECKING_ONLY_PORT;
|
||||
|
||||
if (isCrossCheckingOnlyMode) {
|
||||
console.log(`🔒 [Index Loader] 交叉评查专属模式已启用 (端口: ${currentPort})`);
|
||||
console.log(`🔒 [Index Loader] 交叉评查专属模式已启用 (端口: ${currentPortForMode})`);
|
||||
}
|
||||
|
||||
// 返回用户信息、入口模块和权限给客户端
|
||||
|
||||
@@ -253,20 +253,42 @@ type LoaderData = {
|
||||
// 添加 loader 函数
|
||||
export async function loader({ request }: LoaderFunctionArgs) {
|
||||
try {
|
||||
const loaderStart = Date.now();
|
||||
|
||||
// 获取用户会话信息
|
||||
const sessionStart = Date.now();
|
||||
const { getUserSession } = await import("~/api/login/auth.server");
|
||||
const { userInfo, frontendJWT } = await getUserSession(request);
|
||||
|
||||
// console.log(`[loader 耗时] getUserSession: ${Date.now() - sessionStart}ms`);
|
||||
|
||||
// console.log('loader: 开始加载数据...');
|
||||
const url = new URL(request.url);
|
||||
const mode = url.searchParams.get("mode") || "create";
|
||||
|
||||
|
||||
// 我们不能在服务器端访问 sessionStorage,所以在客户端组件中处理 documentTypeIds 过滤
|
||||
// 并行加载文档和文档类型
|
||||
// 并行加载文档和文档类型(分别计时)
|
||||
const apiStart = Date.now();
|
||||
|
||||
const documentsPromise = (async () => {
|
||||
const start = Date.now();
|
||||
const result = await getTodayDocuments(userInfo, frontendJWT);
|
||||
// console.log(`[loader 耗时] getTodayDocuments API: ${Date.now() - start}ms`);
|
||||
return result;
|
||||
})();
|
||||
|
||||
const typesPromise = (async () => {
|
||||
const start = Date.now();
|
||||
const result = await getDocumentTypes(frontendJWT);
|
||||
// console.log(`[loader 耗时] getDocumentTypes API: ${Date.now() - start}ms`);
|
||||
return result;
|
||||
})();
|
||||
|
||||
const [documentsResponse, typesResponse] = await Promise.all([
|
||||
getTodayDocuments(userInfo, frontendJWT),
|
||||
getDocumentTypes(frontendJWT)
|
||||
documentsPromise,
|
||||
typesPromise
|
||||
]);
|
||||
// console.log(`[loader 耗时] 并行API调用总耗时: ${Date.now() - apiStart}ms`);
|
||||
console.log(`[loader 耗时] loader总耗时: ${(Date.now() - loaderStart)/1000}s`);
|
||||
|
||||
// console.log('loader: 文档加载结果:', documentsResponse);
|
||||
// console.log('loader: 文档类型加载结果:', typesResponse);
|
||||
|
||||
Reference in New Issue
Block a user