fix: 1.接入ai_suggestion.

2. 接入合同起草功能。
This commit is contained in:
2025-12-05 00:04:45 +08:00
parent eca98fc540
commit 33f10896a0
29 changed files with 3184 additions and 981 deletions
+151 -24
View File
@@ -223,9 +223,11 @@ export default function DocumentsIndex() {
const [showAttachmentUpload, setShowAttachmentUpload] = useState<boolean>(false);
const [showTemplateUpload, setShowTemplateUpload] = useState<boolean>(false);
const [selectedDocumentId, setSelectedDocumentId] = useState<number | null>(null);
const [selectedDocumentName, setSelectedDocumentName] = useState<string | null>(null);
const [selectedDocumentVersion, setSelectedDocumentVersion] = useState<number | null>(null);
const [attachmentFiles, setAttachmentFiles] = useState<File[]>([]);
const [templateFile, setTemplateFile] = useState<File | null>(null);
const [attachmentMergeMode, setAttachmentMergeMode] = useState<'overwrite' | 'new'>('overwrite');
const [attachmentMergeMode, setAttachmentMergeMode] = useState<'overwrite' | 'new'>('new');
const [attachmentRemark, setAttachmentRemark] = useState<string>("");
const [attachmentUploading, setAttachmentUploading] = useState<boolean>(false);
const [templateUploading, setTemplateUploading] = useState<boolean>(false);
@@ -356,6 +358,38 @@ export default function DocumentsIndex() {
}
}, [searchParams, fetchData, documentTypeIds]);
// 监听 documents 数据变化,自动修正不一致的展开状态
useEffect(() => {
if (documents.length === 0) return;
const newExpandedRows = new Set(expandedRows);
let hasChanges = false;
// 检查每个展开的行
expandedRows.forEach(docId => {
const doc = documents.find(d => d.id === docId);
// 如果文档不存在或没有历史版本数据,自动折叠
if (!doc || !doc.historyVersions || doc.historyVersions.length === 0) {
console.warn(`自动折叠文档 ${docId}:数据不完整`);
newExpandedRows.delete(docId);
hasChanges = true;
}
});
// 如果有变化,更新状态
if (hasChanges) {
setExpandedRows(newExpandedRows);
// 同时更新 documents 中的 isExpanded 状态
setDocuments(prevDocs =>
prevDocs.map(d =>
newExpandedRows.has(d.id) ? { ...d, isExpanded: true } : { ...d, isExpanded: false }
)
);
}
}, [documents, expandedRows]);
// 使用并更新缓存数据
useEffect(() => {
// 如果有缓存数据,先显示缓存,再在后台加载新数据
@@ -881,6 +915,8 @@ export default function DocumentsIndex() {
setAttachmentRemark("");
setShowAttachmentUpload(false);
setSelectedDocumentId(null);
setSelectedDocumentName(null);
setSelectedDocumentVersion(null);
// 刷新文档列表
if (documentTypeIds && documentTypeIds.length > 0) {
@@ -951,6 +987,8 @@ export default function DocumentsIndex() {
setTemplateFile(null);
setShowTemplateUpload(false);
setSelectedDocumentId(null);
setSelectedDocumentName(null);
setSelectedDocumentVersion(null);
// 刷新文档列表
if (documentTypeIds && documentTypeIds.length > 0) {
@@ -981,11 +1019,28 @@ export default function DocumentsIndex() {
)
);
} else {
// 展开前检查是否有历史版本数据
const hasHistoryData = doc.historyVersions && doc.historyVersions.length > 0;
const hasHistoryCount = doc.historyCount && doc.historyCount > 0;
// 如果有历史版本计数但没有数据,可能是数据加载失败
if (hasHistoryCount && !hasHistoryData) {
console.warn(`文档 ${doc.id}${doc.historyCount} 个历史版本,但数据为空`);
toastService.warning('历史版本数据加载失败,请刷新页面重试');
return;
}
// 如果没有历史版本,不允许展开
if (!hasHistoryCount) {
console.log(`文档 ${doc.id} 没有历史版本`);
return;
}
// 展开:显示历史版本
newExpanded.add(doc.id);
setExpandedRows(newExpanded);
// 更新展开状态(历史版本数据已经在主数据中了)
// 更新展开状态
setDocuments(prevDocs =>
prevDocs.map(d =>
d.id === doc.id ? { ...d, isExpanded: true } : d
@@ -1077,6 +1132,36 @@ export default function DocumentsIndex() {
<i className="ri-download-line"></i>
</button>
{parentDoc.type === '1' && historyDoc.fileStatus === 'Processed' && (
<>
<button
type="button"
className="text-xs px-2 py-1 h-7 mr-1 hover:underline hover:text-primary"
onClick={() => {
setSelectedDocumentId(historyDoc.id);
setSelectedDocumentName(historyDoc.name);
setSelectedDocumentVersion(historyDoc.versionNumber || null);
setShowAttachmentUpload(true);
}}
>
<i className="ri-attachment-line"></i>
</button>
<button
type="button"
className="text-xs px-2 py-1 h-7 mr-1 text-gray-500 hover:underline hover:text-gray-700"
onClick={() => {
setSelectedDocumentId(historyDoc.id);
setSelectedDocumentName(historyDoc.name);
setSelectedDocumentVersion(historyDoc.versionNumber || null);
setShowTemplateUpload(true);
}}
>
<i className="ri-file-copy-line"></i>
</button>
</>
)}
<button
type="button"
className="text-xs px-2 py-1 h-7 text-error hover:underline hover:text-red-700"
@@ -1294,22 +1379,26 @@ export default function DocumentsIndex() {
</button>
{record.type === '1' && record.fileStatus === 'Processed' && (
<>
<button
<button
type="button"
className="text-xs px-2 py-1 h-7 mr-1 hover:underline hover:text-primary"
onClick={() => {
setSelectedDocumentId(record.id);
setSelectedDocumentName(record.name);
setSelectedDocumentVersion(record.historyCount !== undefined && record.historyCount > 0 ? record.historyCount + 1 : null);
setShowAttachmentUpload(true);
}}
>
<i className="ri-attachment-line"></i>
</button>
<button
<button
type="button"
className="text-xs px-2 py-1 h-7 mr-1 text-gray-500 hover:underline hover:text-gray-700"
onClick={() => {
setSelectedDocumentId(record.id);
setSelectedDocumentName(record.name);
setSelectedDocumentVersion(record.historyCount !== undefined && record.historyCount > 0 ? record.historyCount + 1 : null);
setShowTemplateUpload(true);
}}
>
@@ -1531,22 +1620,34 @@ export default function DocumentsIndex() {
))}
</tr>
{/* 历史版本行 */}
{doc.isExpanded && doc.historyVersions && doc.historyVersions.length > 0 && (
{doc.isExpanded && (
<>
{doc.historyVersions.map((historyDoc) => renderHistoryRow(historyDoc, doc))}
{/* 正在加载历史版本 */}
{loadingHistory.has(doc.id) ? (
<tr key={`loading-${doc.id}`} className="history-row">
<td colSpan={columns.length} className="px-4 py-3">
<div className="version-loading">
<i className="ri-loader-4-line"></i>
...
</div>
</td>
</tr>
) : doc.historyVersions && doc.historyVersions.length > 0 ? (
/* 显示历史版本数据 */
doc.historyVersions.map((historyDoc) => renderHistoryRow(historyDoc, doc))
) : (
/* 数据为空时的提示 */
<tr key={`empty-${doc.id}`} className="history-row">
<td colSpan={columns.length} className="px-4 py-3">
<div className="text-center text-gray-500 text-sm py-2">
<i className="ri-information-line mr-1"></i>
</div>
</td>
</tr>
)}
</>
)}
{/* 正在加载历史版本 */}
{doc.isExpanded && loadingHistory.has(doc.id) && (
<tr key={`loading-${doc.id}`} className="history-row">
<td colSpan={columns.length} className="px-4 py-3">
<div className="version-loading">
<i className="ri-loader-4-line"></i>
...
</div>
</td>
</tr>
)}
</>
))}
</tbody>
@@ -1573,6 +1674,8 @@ export default function DocumentsIndex() {
onClick={() => {
setShowAttachmentUpload(false);
setSelectedDocumentId(null);
setSelectedDocumentName(null);
setSelectedDocumentVersion(null);
setAttachmentFiles([]);
setAttachmentRemark("");
}}
@@ -1587,6 +1690,8 @@ export default function DocumentsIndex() {
onClick={() => {
setShowAttachmentUpload(false);
setSelectedDocumentId(null);
setSelectedDocumentName(null);
setSelectedDocumentVersion(null);
setAttachmentFiles([]);
setAttachmentRemark("");
}}
@@ -1600,10 +1705,18 @@ export default function DocumentsIndex() {
{/* 文档信息 */}
<div className="bg-gray-50 p-3 rounded">
<p className="text-sm text-gray-600">
ID: <span className="font-medium">{selectedDocumentId}</span>
{/* 目标文档ID: <span className="font-medium">{selectedDocumentId}</span> */}
: <span className="font-medium">{selectedDocumentName}</span>
{selectedDocumentVersion && (
<span className="ml-2 text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded">
v{selectedDocumentVersion}
</span>
)}
</p>
<p className="text-xs text-gray-500 mt-1">
.pdf.docxZIPRAR格式ZIP/RAR内需要保证文件格式一致
.pdf.docxZIPRAR格式
<i className="ri-information-line mr-1"></i>
ZIP/RAR内需要保证文件格式一致
</p>
</div>
@@ -1624,7 +1737,7 @@ export default function DocumentsIndex() {
<label htmlFor="attachment-file-input" className="cursor-pointer">
<i className="ri-attachment-line text-3xl text-gray-400 mb-2 block"></i>
<p className="text-sm text-gray-600"></p>
<p className="text-xs text-gray-500 mt-1">PDFWordZIPRAR格式</p>
<p className="text-xs text-gray-500 mt-1">.pdf.docx.zip.rar格式</p>
</label>
</div>
{attachmentFiles.length > 0 && (
@@ -1650,7 +1763,7 @@ export default function DocumentsIndex() {
</label>
<div className="space-y-2">
<label className="flex items-center">
{/* <label className="flex items-center">
<input
type="radio"
name="mergeMode"
@@ -1660,7 +1773,7 @@ export default function DocumentsIndex() {
className="mr-2"
/>
<span className="text-sm">覆盖原文档(推荐)</span>
</label>
</label> */}
<label className="flex items-center">
<input
type="radio"
@@ -1696,6 +1809,8 @@ export default function DocumentsIndex() {
onClick={() => {
setShowAttachmentUpload(false);
setSelectedDocumentId(null);
setSelectedDocumentName(null);
setSelectedDocumentVersion(null);
setAttachmentFiles([]);
setAttachmentRemark("");
}}
@@ -1723,11 +1838,13 @@ export default function DocumentsIndex() {
onClick={() => {
setShowTemplateUpload(false);
setSelectedDocumentId(null);
setSelectedDocumentName(null);
setSelectedDocumentVersion(null);
setTemplateFile(null);
}}
>
<div
className="bg-white rounded-lg p-6 w-full max-w-lg mx-4"
className="bg-white rounded-lg p-6 w-full max-w-xl mx-4"
onClick={(e) => e.stopPropagation()}
>
<div className="flex justify-between items-center mb-4">
@@ -1736,6 +1853,8 @@ export default function DocumentsIndex() {
onClick={() => {
setShowTemplateUpload(false);
setSelectedDocumentId(null);
setSelectedDocumentName(null);
setSelectedDocumentVersion(null);
setTemplateFile(null);
}}
className="text-gray-400 hover:text-gray-600"
@@ -1748,7 +1867,13 @@ export default function DocumentsIndex() {
{/* 文档信息 */}
<div className="bg-gray-50 p-3 rounded">
<p className="text-sm text-gray-600">
ID: <span className="font-medium">{selectedDocumentId}</span>
{/* 目标文档ID: <span className="font-medium">{selectedDocumentId}</span> */}
: <span className="font-medium">{selectedDocumentName}</span>
{selectedDocumentVersion && (
<span className="ml-2 text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded">
v{selectedDocumentVersion}
</span>
)}
</p>
<p className="text-xs text-gray-500 mt-1">
.pdf.docx格式
@@ -1794,6 +1919,8 @@ export default function DocumentsIndex() {
onClick={() => {
setShowTemplateUpload(false);
setSelectedDocumentId(null);
setSelectedDocumentName(null);
setSelectedDocumentVersion(null);
setTemplateFile(null);
}}
disabled={templateUploading}