合并评查点新增代码

This commit is contained in:
2025-04-13 15:09:01 +08:00
parent 414fb8ebac
commit 60680cd4bf
11 changed files with 772 additions and 941 deletions
+71 -83
View File
@@ -9,6 +9,7 @@ import { FileProgress} from "~/components/ui/FileProgress";
import { ProcessingSteps, Step } from "~/components/ui/ProcessingSteps";
import uploadStyles from "~/styles/pages/files_upload.css?url";
import { getTodayDocuments, getDocumentTypes, getDocumentsStatus, type Document, type DocumentType, DocumentStatus } from "~/api/files/files-upload";
import { uploadFileToBinary, uploadDocumentToServer } from "~/api/files";
export function links() {
return [
@@ -109,99 +110,34 @@ interface FileUploadResponse {
error: string | null;
}
// 将文件转换为二进制数据
async function uploadFileToBinary(file: File): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
if (reader.result instanceof ArrayBuffer) {
resolve(reader.result);
} else {
reject(new Error('无法将文件转换为二进制格式'));
}
};
reader.onerror = () => {
reject(new Error('读取文件失败'));
};
// 读取文件为 ArrayBuffer (二进制格式)
reader.readAsArrayBuffer(file);
});
}
// 模拟上传文件到服务器的API
async function uploadFileToServer(
binaryData: ArrayBuffer,
fileName: string,
fileType: string,
documentType: FileType,
priority: Priority
priority: Priority,
documentNumber: string | null,
remark: string | null,
isTestDocument: boolean
): Promise<FileUploadResponse> {
// 在实际应用中,这里会使用fetch或axios发送请求到后端API
console.log(`[模拟API] 上传文件: ${fileName}, 大小: ${binaryData.byteLength} 字节`);
// 模拟网络延迟
await new Promise(resolve => setTimeout(resolve, 500));
try {
// 创建FormData对象,将文件和其他信息一起提交
const formData = new FormData();
// 使用封装的上传函数
const response = await uploadDocumentToServer(
binaryData,
fileName,
fileType,
documentType,
PRIORITY_TO_CHINESE[priority],
documentNumber,
remark,
isTestDocument
);
// 将二进制数据转换为Blob并添加到FormData
const blob = new Blob([binaryData], { type: fileType });
formData.append('file', blob, fileName);
// 将 type_id 和 priority 添加到一个JSON对象中
const uploadInfo = {
type_id: Number(documentType), // 确保 type_id 是数字值
evaluation_level: PRIORITY_TO_CHINESE[priority] // 转换为中文优先级
};
// 添加 JSON 字符串到 FormData
formData.append('upload_info', JSON.stringify(uploadInfo));
// 创建HTTP请求的参数
const requestParams = {
method: 'POST',
url: 'http://172.16.0.55:8000/admin/documents/upload',
headers: {
// FormData会自动设置Content-Type为multipart/form-data
'X-File-Name': encodeURIComponent(fileName)
},
body: formData
};
// 打印 FormData 内容的正确方式
console.log('[模拟API] 请求参数:', {
url: requestParams.url,
headers: requestParams.headers,
uploadInfo, // 直接打印原始对象更有帮助
formDataEntries: Array.from(formData.entries()).map(([key, value]) => {
if (!(value instanceof Blob)) {
return { key, value };
}
}),
fileName
});
// 实际API调用 - 在生产环境中实现
const response = await fetch(requestParams.url, {
method: requestParams.method,
headers: requestParams.headers,
body: requestParams.body
});
if (!response.ok) {
// 获取更多错误信息
const errorText = await response.text();
console.error(`上传失败 (${response.status}): ${errorText}`);
throw new Error(`上传失败: ${response.status} ${response.statusText}`);
}
const data = await response.json();
return data;
return response;
} catch (error) {
console.error('[模拟API] 上传错误:', error);
return {
@@ -318,8 +254,11 @@ export default function FilesUpload() {
const { documents, documentTypes } = useLoaderData<LoaderData>();
// 状态管理
const [isTestDocument, setIsTestDocument] = useState(false);
const [fileType, setFileType] = useState<FileType | "">("");
const [priority, setPriority] = useState<Priority>(Priority.NORMAL);
const [documentNumber, setDocumentNumber] = useState<string>("");
const [remark, setRemark] = useState<string>("");
const [currentFiles, setCurrentFiles] = useState<File[]>([]);
const [uploadProgress, setUploadProgress] = useState(0);
const [uploadSpeed, setUploadSpeed] = useState("0KB/s");
@@ -506,7 +445,10 @@ export default function FilesUpload() {
file.name,
file.type,
fileType as FileType,
priority
priority,
documentNumber || null,
remark || null,
isTestDocument
);
if (!response.success || !response.result) {
@@ -801,6 +743,8 @@ export default function FilesUpload() {
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};
// 格式化文件大小显示
const formatFileSize = (bytes: number) => {
@@ -920,7 +864,7 @@ export default function FilesUpload() {
<Form method="post" encType="multipart/form-data" ref={formRef}>
{/* 文件类型选择 */}
<Card title={<h3></h3>} className="mb-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div className="form-group">
<label htmlFor="file-type-select" className="form-label"> <span className="text-red-500">*</span></label>
<select
@@ -959,6 +903,37 @@ export default function FilesUpload() {
</select>
<div className="form-tip"></div>
</div>
<div className="form-group">
<label htmlFor="docNumber" className="form-label"></label>
<input
type="text"
id="docNumber"
name="docNumber"
className="form-input w-full"
placeholder="请输入合同编号、许可证号等"
value={documentNumber}
onChange={(e) => setDocumentNumber(e.target.value)}
disabled={uploadStage !== "idle"}
/>
<div className="form-tip"></div>
</div>
</div>
<div className="grid grid-cols-1 mt-4">
<div className="form-group">
<label className="form-label" htmlFor="docRemark">
</label>
<textarea
id="docRemark"
name="docRemark"
className="form-textarea w-full"
placeholder="可输入文档的相关描述或备注信息"
rows={2}
value={remark}
onChange={(e) => setRemark(e.target.value)}
disabled={uploadStage !== "idle"}
></textarea>
</div>
</div>
</Card>
@@ -975,6 +950,17 @@ export default function FilesUpload() {
tipText="支持单个或批量上传,文件格式:PDF、Word、Excel、图片"
shouldPreventFileSelect={!fileType}
/>
<div className="switch-container">
<label className="switch" aria-label="标记为测试文档">
<input
type="checkbox"
checked={isTestDocument}
onChange={e => setIsTestDocument(e.target.checked)}
/>
<span className="slider"></span>
</label>
<span></span>
</div>
</>
)}
@@ -1082,6 +1068,8 @@ export default function FilesUpload() {
</div>
</div>
)}
</Card>
</Form>