1.同步包版本。

2.交叉评查的任务中上传文件。
3.添加dify库名解决保存配置失败的问题。
This commit is contained in:
2026-01-20 17:29:55 +08:00
parent 1fca1a2e2e
commit 9951f16e50
11 changed files with 394 additions and 82 deletions
+1
View File
@@ -14,6 +14,7 @@ docreview-frontend-deploy.tar.gz
.claude/
.doc/
.messages/
.database/
.auth_doc/
typecheck_result.txt
+73 -2
View File
@@ -362,10 +362,81 @@ export function generateFileId(): string {
*/
export function formatFileSize(bytes: number): string {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
/**
* 向已有任务上传新文档
*
* POST /api/v2/cross_review/tasks/{task_id}/upload_documents
*
* @param params 上传参数
* @returns 上传结果
*/
export async function uploadDocumentToTask(params: {
taskId: number;
file: File;
jwtToken?: string | null;
}): Promise<{
success: boolean;
data?: unknown;
error?: string;
}> {
const { taskId, file, jwtToken } = params;
try {
console.log('[上传文档到任务] 开始上传:', { taskId, fileName: file.name });
const formData = new FormData();
// 添加文件(使用 files 字段名)
formData.append('files', file, file.name);
const uploadEndpoint = `/api/v2/cross_review/tasks/${taskId}/upload_documents`;
const uploadUrl = API_BASE_URL + uploadEndpoint;
const headers: Record<string, string> = {};
if (jwtToken) {
headers['Authorization'] = `Bearer ${jwtToken}`;
}
const response = await axios.post(uploadUrl, formData, { headers });
const result = response.data;
// 新接口响应格式: { code: 0, success: true, message: "...", data: {...} }
if (result && (result.success || result.code === 0)) {
console.log('[上传文档到任务] 上传成功:', result.message);
return { success: true, data: result.data };
} else {
console.error('[上传文档到任务] 上传失败:', result.detail || result.message);
return { success: false, error: result.detail || result.message || '上传失败' };
}
} catch (error) {
console.error('[上传文档到任务] 请求失败:', error);
let errorMessage = '上传文档失败';
if (axios.isAxiosError(error)) {
// 新接口错误格式: { detail: "错误信息" }
if (error.response?.data?.detail) {
errorMessage = error.response.data.detail;
} else if (error.response?.data?.message) {
errorMessage = error.response.data.message;
} else if (error.response?.status === 403) {
errorMessage = '无权操作:只有任务创建者或主要负责人可以上传文档';
} else if (error.response?.status === 400) {
errorMessage = '请求参数错误';
}
} else if (error instanceof Error) {
errorMessage = error.message || errorMessage;
}
return {
success: false,
error: errorMessage
};
}
}
+1
View File
@@ -1,6 +1,7 @@
import { API_BASE_URL } from '../../config/api-config';
import { postgrestPut, postgrestGet } from '../postgrest-client';
import axios from 'axios';
export { uploadDocumentToTask } from './cross-files-upload';
// 交叉评查任务状态枚举
export enum CrossCheckingTaskStatus {
@@ -8,13 +8,16 @@ import { ResultStats } from '../ui/ResultStats';
import { toastService } from '../ui/Toast';
import { AttachmentUploadModal } from '../ui/AttachmentUploadModal';
import { TemplateUploadModal } from '../ui/TemplateUploadModal';
import { UploadArea, type UploadAreaRef } from '../ui/UploadArea';
import { formatDate } from '~/utils';
import {
type CrossReviewDocumentWithVersion,
type CrossReviewHistoryVersion,
appendTaskDocumentAttachments,
uploadCrossReviewDocumentTemplate,
uploadDocumentToTask,
} from '~/api/cross-checking/cross-files';
import { formatFileSize } from '~/api/cross-checking/cross-files-upload';
// 导出样式链接
export const links = () => [];
@@ -69,15 +72,6 @@ const crossReviewAuditStatusMapping: Record<string, { label: string; color: stri
"1": { label: "已评查", color: "green", icon: "ri-check-line" },
};
// 格式化文件大小
const formatFileSize = (bytes: number) => {
if (bytes === 0) return "0 Bytes";
const k = 1024;
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};
export function DocumentListModal({
isOpen,
onClose,
@@ -124,6 +118,12 @@ export function DocumentListModal({
const [showTemplateUpload, setShowTemplateUpload] = useState(false);
const [templateUploading, setTemplateUploading] = useState(false);
// 上传文件模态框状态
const [showUploadModal, setShowUploadModal] = useState(false);
const [uploadedFile, setUploadedFile] = useState<File | null>(null);
const [isFileUploading, setIsFileUploading] = useState(false);
const uploadAreaRef = useRef<UploadAreaRef>(null);
// 同步外部文档数据到本地
useEffect(() => {
setLocalDocuments(documents.map(doc => ({ ...doc, isExpanded: expandedRows.has(doc.id) })));
@@ -217,6 +217,78 @@ export function DocumentListModal({
setSelectedDocumentPath(null);
};
// 打开上传文件模态框
const handleOpenUploadModal = () => {
setShowUploadModal(true);
setUploadedFile(null);
};
// 关闭上传文件模态框
const handleCloseUploadModal = () => {
setShowUploadModal(false);
setUploadedFile(null);
uploadAreaRef.current?.resetFileInput();
};
// 处理文件选择
const handleFileSelected = (files: FileList) => {
if (files.length === 0) return;
const file = files[0];
const fileName = file.name.toLowerCase();
const isValidType = file.type === 'application/pdf' || fileName.endsWith('.pdf') ||
file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' || fileName.endsWith('.docx') ||
file.type === 'application/zip' || fileName.endsWith('.zip') ||
file.type === 'application/x-zip-compressed';
// || file.type === 'application/x-7z-compressed' || fileName.endsWith('.7z');
if (!isValidType) {
// toastService.error('只能上传 PDF、DOCX 文件或 ZIP、7Z 压缩包');
toastService.error('只能上传 PDF、DOCX 文件或 ZIP 压缩包');
return;
}
setUploadedFile(file);
};
// 删除选中的文件
const handleRemoveFile = () => {
setUploadedFile(null);
uploadAreaRef.current?.resetFileInput();
};
// 确认上传文件
const handleUploadFile = async () => {
if (!uploadedFile || !taskId) {
toastService.error('缺少必要参数');
return;
}
setIsFileUploading(true);
try {
const result = await uploadDocumentToTask({
taskId,
file: uploadedFile,
jwtToken: frontendJWT
});
if (!result.success || result.error) {
throw new Error(result.error || '上传文件失败');
}
toastService.success('文件上传成功!正在后台处理中');
handleCloseUploadModal();
// 刷新文档列表
if (onSearch) {
onSearch(searchKeyword);
}
} catch (error) {
console.error('上传文件失败:', error);
toastService.error(error instanceof Error ? error.message : '上传文件失败');
} finally {
setIsFileUploading(false);
}
};
// 处理追加附件上传
const handleAttachmentUpload = async (files: File[], _mergeMode: 'overwrite' | 'new', remark: string) => {
if (!taskId || !selectedDocumentId) {
@@ -642,30 +714,43 @@ export function DocumentListModal({
</div>
</div>
{/* 右侧:搜索框 */}
{onSearch && (
<div className="flex items-center">
<div className="relative">
<input
type="text"
placeholder="搜索文件名称或文档编号"
value={searchKeyword}
onChange={(e) => handleSearchChange(e.target.value)}
className="pl-9 pr-4 py-2 border border-gray-300 rounded-md text-sm w-64 focus:outline-none focus:ring-0"
/>
<i className="ri-search-line absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"></i>
{searchKeyword && (
<button
type="button"
className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600"
onClick={() => handleSearchChange('')}
>
<i className="ri-close-line"></i>
</button>
)}
{/* 右侧:搜索框 + 上传按钮 */}
<div className="flex items-center gap-3">
{/* 上传文件按钮 - 仅负责人可见 */}
{isProposer && (
<button
type="button"
className="flex items-center gap-2 px-4 py-2 bg-green-800 text-white rounded-md text-sm hover:bg-green-700 transition-colors"
onClick={handleOpenUploadModal}
>
<i className="ri-upload-cloud-2-line"></i>
</button>
)}
{onSearch && (
<div className="flex items-center">
<div className="relative">
<input
type="text"
placeholder="搜索文件名称或文档编号"
value={searchKeyword}
onChange={(e) => handleSearchChange(e.target.value)}
className="pl-9 pr-4 py-2 border border-gray-300 rounded-md text-sm w-64 focus:outline-none focus:ring-0"
/>
<i className="ri-search-line absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"></i>
{searchKeyword && (
<button
type="button"
className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600"
onClick={() => handleSearchChange('')}
>
<i className="ri-close-line"></i>
</button>
)}
</div>
</div>
</div>
)}
)}
</div>
</div>
{loading ? (
@@ -780,6 +865,150 @@ export function DocumentListModal({
title="上传合同模板"
supportedFormatsDesc="支持.pdf、.docx格式,用于与合同文档进行结构对比"
/>
{/* 上传文件模态框 */}
<Modal
isOpen={showUploadModal}
onClose={handleCloseUploadModal}
title="上传文档到任务"
size="medium"
>
<div className="p-6">
<div className="flex gap-6">
{/* 左侧:上传区域 */}
<div className="flex-1">
<div className="text-sm font-medium text-gray-700 mb-3"></div>
<UploadArea
ref={uploadAreaRef}
onFilesSelected={handleFileSelected}
className="custom-upload-area"
// accept=".pdf,.docx,.zip,.7z"
accept=".pdf,.docx,.zip"
multiple={false}
icon="ri-upload-cloud-2-line"
buttonText="选择文件"
mainText="点击或拖拽文件到此区域上传"
tipText={
<div className="text-gray-500 text-xs mt-2">
<div></div>
<div className="flex flex-wrap gap-2 mt-1 justify-center">
<span className="inline-flex items-center px-2 py-0.5 rounded bg-red-50 text-red-600">
<i className="ri-file-pdf-line mr-1"></i>PDF
</span>
<span className="inline-flex items-center px-2 py-0.5 rounded bg-blue-50 text-blue-600">
<i className="ri-file-word-2-line mr-1"></i>DOCX
</span>
<span className="inline-flex items-center px-2 py-0.5 rounded bg-orange-50 text-orange-600">
<i className="ri-folder-zip-line mr-1"></i>ZIP
</span>
</div>
</div>
}
disabled={isFileUploading || uploadedFile !== null}
/>
</div>
{/* 右侧:文件信息展示 */}
<div className="flex-1">
<div className="text-sm font-medium text-gray-700 mb-3"></div>
<div className="border border-gray-200 rounded-lg bg-gray-50 min-h-[200px] p-4">
{uploadedFile ? (
<div className="h-full flex flex-col">
{/* 文件图标和类型 */}
<div className="flex items-center justify-center mb-4">
{(() => {
const fileName = uploadedFile.name.toLowerCase();
if (fileName.endsWith('.pdf')) return <i className="ri-file-pdf-line text-5xl text-red-500"></i>;
if (fileName.endsWith('.docx')) return <i className="ri-file-word-2-line text-5xl text-blue-500"></i>;
if (fileName.endsWith('.zip') || fileName.endsWith('.7z')) return <i className="ri-folder-zip-line text-5xl text-orange-500"></i>;
return <i className="ri-file-line text-5xl text-gray-500"></i>;
})()}
</div>
{/* 文件详情 */}
<div className="flex-1 space-y-3">
<div className="bg-white rounded-md p-3 border border-gray-200">
<div className="text-xs text-gray-500 mb-1"></div>
<div className="text-sm font-medium text-gray-800 truncate" title={uploadedFile.name}>
{uploadedFile.name}
</div>
</div>
<div className="bg-white rounded-md p-3 border border-gray-200">
<div className="text-xs text-gray-500 mb-1"></div>
<div className="text-sm font-medium text-gray-800">
{formatFileSize(uploadedFile.size)}
</div>
</div>
</div>
{/* 删除按钮 */}
<div className="mt-4 pt-3 border-t border-gray-200">
<button
type="button"
onClick={handleRemoveFile}
disabled={isFileUploading}
className="w-full flex items-center justify-center gap-2 px-4 py-2 text-sm text-red-600 bg-red-50 hover:bg-red-100 rounded-md transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
>
<i className="ri-delete-bin-line"></i>
</button>
</div>
</div>
) : (
<div className="h-full flex flex-col items-center justify-center text-gray-400">
<i className="ri-file-line text-4xl mb-2"></i>
<span className="text-sm"></span>
<span className="text-xs mt-1"></span>
</div>
)}
</div>
</div>
</div>
{/* 按钮区域 */}
<div className="flex justify-end gap-3 mt-6 pt-4 border-t border-gray-200">
<button
type="button"
onClick={handleCloseUploadModal}
disabled={isFileUploading}
className="px-4 py-2 text-sm text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
>
</button>
<button
type="button"
onClick={handleUploadFile}
disabled={!uploadedFile || isFileUploading}
className="px-4 py-2 text-sm text-white bg-green-800 rounded-md hover:bg-green-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
>
{isFileUploading ? (
<>
<i className="ri-loader-4-line animate-spin"></i>
...
</>
) : (
<>
<i className="ri-upload-line"></i>
</>
)}
</button>
</div>
{/* 上传进度提示 */}
{isFileUploading && (
<div className="mt-4">
<div className="bg-blue-50 p-4 rounded-md border border-blue-100">
<div className="flex items-center justify-center text-blue-800">
<i className="ri-loader-4-line animate-spin text-xl mr-2"></i>
<span className="font-medium">...</span>
</div>
</div>
</div>
)}
</div>
</Modal>
</Modal>
);
}
+4 -2
View File
@@ -220,8 +220,10 @@ const configs: Record<string, ApiConfig> = {
appId: 'idaasoauth2' // 应用ID,用于登出
},
dify: {
rerankingProviderName: 'langgenius/tongyi/tongyi',
rerankingModelName: 'gte-rerank'
// rerankingProviderName: 'langgenius/tongyi/tongyi',
rerankingProviderName: 'langgenius/xinference/xinference',
// rerankingModelName: 'gte-rerank'
rerankingModelName: 'bge-reranker-v2-m3'
}
},
@@ -149,6 +149,7 @@ export function useDatasetSettings(
// 仅更新检索设置
await updateDatasetSettings(dataset.id, {
name: dataset.name,
retrieval_model: formValuesToRetrievalModel(retrievalSettings),
});
@@ -25,7 +25,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
);
}
console.log('[API] Dataset Detail:', { datasetId });
// console.log('[API] Dataset Detail:', { datasetId });
// 转发请求到 FastAPI -> Dify API
const apiUrl = `${API_BASE_URL}/dify_dataset/datasets/${datasetId}`;
@@ -96,6 +96,8 @@ export async function action({ request, params }: ActionFunctionArgs) {
if (method === 'PATCH') {
const body = await request.json();
// console.log('[API] body:', body);
// name 是必填字段
if (!body.name || typeof body.name !== 'string') {
return new Response(
@@ -121,6 +123,8 @@ export async function action({ request, params }: ActionFunctionArgs) {
if (body.retrieval_model && typeof body.retrieval_model === 'object') {
const rm = body.retrieval_model;
const name = body.name || '';
// 验证 search_method
const validSearchMethods = ['keyword_search', 'semantic_search', 'full_text_search', 'hybrid_search'];
if (rm.search_method && !validSearchMethods.includes(rm.search_method)) {
@@ -130,6 +134,8 @@ export async function action({ request, params }: ActionFunctionArgs) {
);
}
allowedBody.name = name;
allowedBody.retrieval_model = {
search_method: rm.search_method,
reranking_enable: rm.reranking_enable ?? false,
@@ -145,7 +151,7 @@ export async function action({ request, params }: ActionFunctionArgs) {
};
}
console.log('[API] Update Dataset Settings:', { datasetId, body: allowedBody });
// console.log('[API] Update Dataset Settings:', { datasetId, body: allowedBody });
const apiUrl = `${API_BASE_URL}/dify_dataset/datasets/${datasetId}`;
const response = await fetch(apiUrl, {
+3 -3
View File
@@ -749,11 +749,11 @@ export default function CrossCheckingIndex() {
<span className="text-sm text-gray-600"></span>
<span className="stat-value">{stats.totalTasks}</span>
</div>
<div className="stat-item">
{/* <div className="stat-item">
<i className="ri-time-line stat-icon"></i>
<span className="text-sm text-gray-600">待开始:</span>
<span className="stat-value">{stats.pendingTasks}</span>
</div>
</div> */}
<div className="stat-item">
<i className="ri-play-circle-line stat-icon"></i>
<span className="text-sm text-gray-600"></span>
@@ -806,7 +806,7 @@ export default function CrossCheckingIndex() {
name="status"
value={searchParams.get('status') || ''}
options={[
{ value: CrossCheckingTaskStatus.PENDING, label: "未开始" },
// { value: CrossCheckingTaskStatus.PENDING, label: "未开始" },
{ value: CrossCheckingTaskStatus.IN_PROGRESS, label: "进行中" },
{ value: CrossCheckingTaskStatus.COMPLETED, label: "已完成" }
]}
+1
View File
@@ -404,6 +404,7 @@ export default function Login() {
</div>
{/* 管理员登录链接 */}
{/* <div className="admin-login-link hidden"> */}
<div className="admin-login-link">
<button
onClick={handleAdminLogin}
+5 -5
View File
@@ -34,6 +34,7 @@
"axios": "^1.9.0",
"chalk": "^5.3.0",
"compression": "^1.7.5",
"cross-env": "^7.0.3",
"dayjs": "^1.11.13",
"diff": "^7.0.0",
"docx-preview": "^0.3.5",
@@ -66,16 +67,15 @@
"remark-math": "^6.0.0",
"remixicon": "^4.6.0",
"tslib": "^2.8.1",
"uuid": "^11.1.0",
"cross-env": "^7.0.3"
"uuid": "^11.1.0"
},
"devDependencies": {
"@remix-run/dev": "^2.16.2",
"@types/compression": "^1.7.5",
"@types/express": "^4.17.21",
"@types/morgan": "^1.9.9",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react-pdf": "^7.0.0",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
@@ -89,7 +89,7 @@
"eslint-plugin-react-hooks": "^4.6.0",
"postcss": "^8.5.3",
"tailwindcss": "^3.4.17",
"typescript": "^5.1.6",
"typescript": "^5.8.3",
"vite": "^6.0.0",
"vite-tsconfig-paths": "^4.2.1"
},
+36 -36
View File
@@ -16,7 +16,7 @@ importers:
version: 2.0.0(antd@6.0.1(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@ant-design/x-markdown':
specifier: ^2.0.0
version: 2.0.0(@types/react@18.3.23)(antd@6.0.1(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
version: 2.0.0(@types/react@18.3.27)(antd@6.0.1(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@codemirror/lang-javascript':
specifier: ^6.2.3
version: 6.2.4
@@ -59,6 +59,9 @@ importers:
compression:
specifier: ^1.7.5
version: 1.8.0
cross-env:
specifier: ^7.0.3
version: 7.0.3
dayjs:
specifier: ^1.11.13
version: 1.11.13
@@ -133,10 +136,10 @@ importers:
version: 18.3.1(react@18.3.1)
react-markdown:
specifier: ^10.1.0
version: 10.1.0(@types/react@18.3.23)(react@18.3.1)
version: 10.1.0(@types/react@18.3.27)(react@18.3.1)
react-pdf:
specifier: ^9.2.1
version: 9.2.1(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
version: 9.2.1(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
rehype-katex:
specifier: ^7.0.1
version: 7.0.1
@@ -172,14 +175,14 @@ importers:
specifier: ^1.9.9
version: 1.9.10
'@types/react':
specifier: ^18.2.20
version: 18.3.23
specifier: ^18.3.12
version: 18.3.27
'@types/react-dom':
specifier: ^18.2.7
version: 18.3.7(@types/react@18.3.23)
specifier: ^18.3.1
version: 18.3.7(@types/react@18.3.27)
'@types/react-pdf':
specifier: ^7.0.0
version: 7.0.0(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
version: 7.0.0(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@typescript-eslint/eslint-plugin':
specifier: ^6.7.4
version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)
@@ -189,9 +192,6 @@ importers:
autoprefixer:
specifier: ^10.4.21
version: 10.4.21(postcss@8.5.6)
cross-env:
specifier: ^7.0.3
version: 7.0.3
esbuild:
specifier: ^0.25.1
version: 0.25.5
@@ -220,7 +220,7 @@ importers:
specifier: ^3.4.17
version: 3.4.17
typescript:
specifier: ^5.1.6
specifier: ^5.8.3
version: 5.8.3
vite:
specifier: ^6.0.0
@@ -1744,8 +1744,8 @@ packages:
resolution: {integrity: sha512-G0a+5UiKk3AvEauBP/Js7r9kGZNW3iBbS6kXkH0foGSaKWR6K3ElTe7Y4tlolc2VKbM9udmMxpkbxh/dtR2wXA==}
deprecated: This is a stub types definition. react-pdf provides its own type definitions, so you do not need this installed.
'@types/react@18.3.23':
resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==}
'@types/react@18.3.27':
resolution: {integrity: sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==}
'@types/semver@7.7.0':
resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==}
@@ -2471,8 +2471,8 @@ packages:
engines: {node: '>=4'}
hasBin: true
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
culvert@0.1.2:
resolution: {integrity: sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==}
@@ -6191,7 +6191,7 @@ snapshots:
'@emotion/unitless': 0.7.5
'@rc-component/util': 1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
clsx: 2.1.1
csstype: 3.1.3
csstype: 3.2.3
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
stylis: 4.3.6
@@ -6232,7 +6232,7 @@ snapshots:
resize-observer-polyfill: 1.5.1
throttle-debounce: 5.0.2
'@ant-design/x-markdown@2.0.0(@types/react@18.3.23)(antd@6.0.1(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
'@ant-design/x-markdown@2.0.0(@types/react@18.3.27)(antd@6.0.1(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@ant-design/cssinjs': 2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@ant-design/cssinjs-utils': 2.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -6242,7 +6242,7 @@ snapshots:
antd: 6.0.1(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
classnames: 2.5.1
dompurify: 3.2.7
html-react-parser: 5.2.10(@types/react@18.3.23)(react@18.3.1)
html-react-parser: 5.2.10(@types/react@18.3.27)(react@18.3.1)
katex: 0.16.22
lodash.throttle: 4.1.1
marked: 15.0.12
@@ -7808,22 +7808,22 @@ snapshots:
'@types/range-parser@1.2.7': {}
'@types/react-dom@18.3.7(@types/react@18.3.23)':
'@types/react-dom@18.3.7(@types/react@18.3.27)':
dependencies:
'@types/react': 18.3.23
'@types/react': 18.3.27
'@types/react-pdf@7.0.0(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
'@types/react-pdf@7.0.0(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
react-pdf: 9.2.1(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-pdf: 9.2.1(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
transitivePeerDependencies:
- '@types/react'
- react
- react-dom
'@types/react@18.3.23':
'@types/react@18.3.27':
dependencies:
'@types/prop-types': 15.7.15
csstype: 3.1.3
csstype: 3.2.3
'@types/semver@7.7.0': {}
@@ -8035,7 +8035,7 @@ snapshots:
'@vanilla-extract/private': 1.0.9
css-what: 6.2.2
cssesc: 3.0.0
csstype: 3.1.3
csstype: 3.2.3
dedent: 1.6.0(babel-plugin-macros@3.1.0)
deep-object-diff: 1.1.9
deepmerge: 4.3.1
@@ -8660,7 +8660,7 @@ snapshots:
cssesc@3.0.0: {}
csstype@3.1.3: {}
csstype@3.2.3: {}
culvert@0.1.2: {}
@@ -9974,7 +9974,7 @@ snapshots:
domhandler: 5.0.3
htmlparser2: 10.0.0
html-react-parser@5.2.10(@types/react@18.3.23)(react@18.3.1):
html-react-parser@5.2.10(@types/react@18.3.27)(react@18.3.1):
dependencies:
domhandler: 5.0.3
html-dom-parser: 5.1.2
@@ -9982,7 +9982,7 @@ snapshots:
react-property: 2.0.2
style-to-js: 1.1.21
optionalDependencies:
'@types/react': 18.3.23
'@types/react': 18.3.27
html-url-attributes@3.0.1: {}
@@ -10878,9 +10878,9 @@ snapshots:
merge-descriptors@1.0.3: {}
merge-refs@1.3.0(@types/react@18.3.23):
merge-refs@1.3.0(@types/react@18.3.27):
optionalDependencies:
'@types/react': 18.3.23
'@types/react': 18.3.27
merge-stream@2.0.0: {}
@@ -12186,11 +12186,11 @@ snapshots:
react-is@18.3.1: {}
react-markdown@10.1.0(@types/react@18.3.23)(react@18.3.1):
react-markdown@10.1.0(@types/react@18.3.27)(react@18.3.1):
dependencies:
'@types/hast': 3.0.4
'@types/mdast': 4.0.4
'@types/react': 18.3.23
'@types/react': 18.3.27
devlop: 1.1.0
hast-util-to-jsx-runtime: 2.3.6
html-url-attributes: 3.0.1
@@ -12204,20 +12204,20 @@ snapshots:
transitivePeerDependencies:
- supports-color
react-pdf@9.2.1(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
react-pdf@9.2.1(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
clsx: 2.1.1
dequal: 2.0.3
make-cancellable-promise: 1.3.2
make-event-props: 1.6.2
merge-refs: 1.3.0(@types/react@18.3.23)
merge-refs: 1.3.0(@types/react@18.3.27)
pdfjs-dist: 4.8.69
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
tiny-invariant: 1.3.3
warning: 4.0.3
optionalDependencies:
'@types/react': 18.3.23
'@types/react': 18.3.27
react-property@2.0.2: {}