合并评查点新增代码
This commit is contained in:
+71
-83
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user