feat: 1. 完善起草合同页面的逻辑交互,对接minio的接口操作

This commit is contained in:
2025-12-05 20:17:37 +08:00
parent 3d1dbb3f97
commit 91b7518c99
21 changed files with 1249 additions and 1057 deletions
+44 -59
View File
@@ -5,16 +5,14 @@
import { useState, useEffect } from 'react';
import type { PlaceholderSchema } from '~/types/contract-draft';
import { messageService } from '~/components/ui/MessageModal';
interface PlaceholderFormProps {
schema: PlaceholderSchema | null;
values: Record<string, string>;
onChange: (values: Record<string, string>) => void;
onBatchReplace: () => void;
onExportDocument: () => void; // 改名:导出文档
onComplete: () => void;
isReplacing: boolean;
isDeleting: boolean; // 改名:是否正在删除
isDeleting: boolean; // 是否正在删除
onSingleReplace?: (key: string, value: string) => void; // 单个替换
onFieldFocus?: (key: string) => void; // 字段聚焦(高亮)
}
@@ -23,10 +21,7 @@ export function PlaceholderForm({
schema,
values,
onChange,
onBatchReplace,
onExportDocument,
onComplete,
isReplacing,
isDeleting,
onSingleReplace,
onFieldFocus
@@ -81,7 +76,19 @@ export function PlaceholderForm({
const handleCompleteClick = () => {
const missing = getMissingRequiredFields();
if (missing.length > 0) {
alert(`请填写以下必填字段:\n${missing.join('\n')}`);
messageService.show({
type: 'warning',
title: '字段校验失败',
message: '请填写以下必填字段:',
children: (
<ul className="list-disc list-inside mt-2 space-y-1">
{missing.map((field, index) => (
<li key={index} className="text-gray-700">{field}</li>
))}
</ul>
),
confirmText: '确定'
});
return;
}
onComplete();
@@ -106,11 +113,36 @@ export function PlaceholderForm({
<div className="h-full flex flex-col bg-white">
{/* 表单头部 */}
<div className="px-6 py-4 border-b border-gray-200 bg-gradient-to-r from-blue-50 to-white">
<div className="flex items-center gap-3">
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-primary to-[#004d38] flex items-center justify-center shadow-sm">
<i className="ri-file-edit-line text-white text-base"></i>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-primary to-[#004d38] flex items-center justify-center shadow-sm">
<i className="ri-file-edit-line text-white text-base"></i>
</div>
<h2 className="text-lg font-bold text-gray-900"></h2>
</div>
<h2 className="text-lg font-bold text-gray-900"></h2>
{/* 完成按钮 */}
<button
onClick={handleCompleteClick}
disabled={isDeleting}
className={`flex items-center justify-center gap-1.5 px-6 py-2 text-sm font-medium rounded-lg transition-all duration-150 ${
isDeleting
? 'bg-gray-200 text-gray-400 cursor-not-allowed'
: 'bg-green-600 text-white hover:bg-green-700 hover:shadow-md active:scale-[0.98]'
}`}
>
{isDeleting ? (
<>
<i className="ri-loader-4-line animate-spin"></i>
<span></span>
</>
) : (
<>
<i className="ri-check-line"></i>
<span></span>
</>
)}
</button>
</div>
</div>
@@ -175,53 +207,6 @@ export function PlaceholderForm({
))}
</div>
</div>
{/* 操作按钮区域(固定在底部) */}
<div className="border-t border-gray-200 px-6 py-3 bg-gray-50 flex gap-2">
<button
onClick={onBatchReplace}
disabled={isReplacing || isDeleting}
className={`flex-1 flex items-center justify-center gap-1.5 px-4 py-2 text-white text-sm font-medium rounded-lg transition-all duration-150 ${
isReplacing || isDeleting
? 'bg-gray-300 cursor-not-allowed'
: 'bg-gradient-to-r from-primary to-[#004d38] hover:shadow-md active:scale-[0.98]'
}`}
>
{isReplacing ? (
<>
<i className="ri-loader-4-line animate-spin"></i>
<span></span>
</>
) : (
<>
<i className="ri-refresh-line"></i>
<span></span>
</>
)}
</button>
<button
onClick={handleCompleteClick}
disabled={isReplacing || isDeleting}
className={`flex-1 flex items-center justify-center gap-1.5 px-4 py-2 text-sm font-medium rounded-lg transition-all duration-150 ${
isReplacing || isDeleting
? 'bg-gray-200 text-gray-400 cursor-not-allowed'
: 'bg-green-600 text-white hover:bg-green-700 hover:shadow-md active:scale-[0.98]'
}`}
>
{isDeleting ? (
<>
<i className="ri-loader-4-line animate-spin"></i>
<span></span>
</>
) : (
<>
<i className="ri-check-line"></i>
<span></span>
</>
)}
</button>
</div>
</div>
);
}