Files
leaudit-platform-frontend/html/文档-新增.html
T

1101 lines
47 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>中国烟草AI合同及卷宗审核系统 - 上传文档</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/remixicon/2.5.0/remixicon.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
<!-- <link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"> -->
<!-- 引入外部CSS文件 -->
<link href="main.css" rel="stylesheet">
<style>
.upload-area {
border: 2px dashed #e0e0e0;
border-radius: 8px;
padding: 40px;
text-align: center;
background-color: #fafafa;
transition: all 0.3s;
cursor: pointer;
}
.upload-area:hover, .upload-area.drag-over {
border-color: var(--primary-color);
background-color: rgba(0, 104, 74, 0.05);
}
.upload-icon {
font-size: 48px;
color: #bdbdbd;
margin-bottom: 16px;
}
.upload-area:hover .upload-icon, .upload-area.drag-over .upload-icon {
color: var(--primary-color);
}
.file-list {
margin-top: 24px;
}
.file-item {
display: flex;
align-items: center;
padding: 12px;
border: 1px solid #f0f0f0;
border-radius: 4px;
margin-bottom: 12px;
background-color: white;
}
.file-item:hover {
background-color: #f9f9f9;
}
.file-icon {
font-size: 24px;
margin-right: 12px;
}
.file-info {
flex: 1;
}
.file-name {
font-weight: 500;
margin-bottom: 4px;
}
.file-meta {
font-size: 12px;
color: #666;
}
.file-size {
margin-right: 16px;
}
.progress-bar {
height: 4px;
background-color: #f0f0f0;
border-radius: 2px;
margin-top: 8px;
overflow: hidden;
}
.progress-bar-inner {
height: 100%;
background-color: var(--primary-color);
border-radius: 2px;
transition: width 0.3s;
}
.file-actions {
display: flex;
align-items: center;
}
.file-actions button {
margin-left: 8px;
}
.test-document-switch {
display: flex;
align-items: center;
margin-top: 10px;
}
.switch {
position: relative;
display: inline-block;
width: 40px;
height: 20px;
margin-right: 8px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
border-radius: 20px;
transition: .3s;
}
.slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 2px;
bottom: 2px;
background-color: white;
border-radius: 50%;
transition: .3s;
}
input:checked + .slider {
background-color: var(--primary-color);
}
input:checked + .slider:before {
transform: translateX(20px);
}
/* 文件预览功能样式 */
.preview-modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
z-index: 1000;
justify-content: center;
align-items: center;
}
.preview-content {
background-color: white;
border-radius: 8px;
width: 90%;
max-width: 1000px;
height: 85%;
overflow: hidden;
display: flex;
flex-direction: column;
}
.preview-header {
padding: 16px;
border-bottom: 1px solid #f0f0f0;
display: flex;
justify-content: space-between;
align-items: center;
}
.preview-body {
flex: 1;
overflow: auto;
padding: 0;
}
.preview-iframe {
width: 100%;
height: 100%;
border: none;
}
.preview-footer {
padding: 12px 16px;
border-top: 1px solid #f0f0f0;
text-align: right;
}
/* 文件编辑按钮样式 */
.edit-filename {
cursor: pointer;
color: var(--primary-color);
margin-left: 8px;
font-size: 14px;
}
.edit-filename:hover {
text-decoration: underline;
}
/* 批量操作样式 */
.batch-actions {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
padding: 8px 12px;
background-color: #f8f9fa;
border-radius: 4px;
border: 1px solid #f0f0f0;
}
/* 更多上传设置 */
.advanced-options {
margin-top: 16px;
}
.advanced-options-toggle {
cursor: pointer;
color: var(--primary-color);
font-size: 14px;
display: inline-flex;
align-items: center;
}
.advanced-options-toggle i {
transition: transform 0.3s;
}
.advanced-options-toggle.open i {
transform: rotate(180deg);
}
.advanced-options-content {
display: none;
margin-top: 12px;
padding: 12px;
border: 1px solid #f0f0f0;
border-radius: 4px;
background-color: #f9f9f9;
}
/* 上传失败状态样式 */
.file-status.error {
color: #f5222d;
}
.retry-btn {
color: var(--primary-color);
cursor: pointer;
}
.retry-btn:hover {
text-decoration: underline;
}
/* 上传完成操作按钮组 */
.upload-complete-actions {
display: none;
margin-top: 20px;
text-align: center;
}
/* 提示框样式 */
.alert {
padding: 12px 16px;
border-radius: 4px;
margin-bottom: 16px;
display: flex;
align-items: center;
}
.alert-success {
background-color: #f6ffed;
border: 1px solid #b7eb8f;
color: #52c41a;
}
.alert-info {
background-color: #e6f7ff;
border: 1px solid #91d5ff;
color: #1890ff;
}
.alert-warning {
background-color: #fffbe6;
border: 1px solid #ffe58f;
color: #faad14;
}
.alert-error {
background-color: #fff2f0;
border: 1px solid #ffccc7;
color: #ff4d4f;
}
</style>
</head>
<body>
<div class="layout-container">
<!-- 侧边栏 -->
<div class="sidebar">
<div class="py-6 px-4 border-b border-gray-100">
<div class="flex items-center">
<i class="ri-file-search-line text-primary text-xl mr-2"></i>
<h2 class="text-lg font-medium">AI审核系统</h2>
</div>
</div>
<div class="py-4">
<div class="sidebar-menu-item">
<a href="#" class="flex items-center text-sm font-medium">
<i class="ri-dashboard-line mr-3"></i>
<span>首页</span>
</a>
</div>
<div class="sidebar-menu-item active">
<a href="#" class="flex items-center text-sm font-medium">
<i class="ri-file-upload-line mr-3"></i>
<span>文件管理</span>
</a>
</div>
<div class="sidebar-menu-item">
<a href="#" class="flex items-center text-sm font-medium">
<i class="ri-list-check-2 mr-3"></i>
<span>评查规则库</span>
</a>
</div>
<div class="sidebar-menu-item">
<a href="#" class="flex items-center text-sm font-medium">
<i class="ri-history-line mr-3"></i>
<span>审核历史</span>
</a>
</div>
<div class="sidebar-menu-item">
<a href="#" class="flex items-center text-sm font-medium">
<i class="ri-settings-3-line mr-3"></i>
<span>系统设置</span>
</a>
</div>
</div>
</div>
<!-- 主内容区 -->
<div class="main-content">
<!-- 面包屑导航 -->
<div class="breadcrumb">
<span class="breadcrumb-item">首页</span>
<span class="breadcrumb-item">文件管理</span>
<span class="breadcrumb-item">上传文档</span>
</div>
<!-- 页面头部 -->
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-medium">上传文档</h2>
<div>
<button class="ant-btn ant-btn-default mr-2" onclick="window.location.href='文档-列表.html'">
<i class="ri-arrow-left-line"></i> 返回
</button>
<button class="ant-btn ant-btn-primary" id="start-upload-btn" disabled>
<i class="ri-upload-2-line"></i> 开始上传
</button>
</div>
</div>
<!-- 上传表单 -->
<div class="ant-card">
<div class="ant-card-body">
<form id="upload-form">
<div class="grid grid-cols-2 gap-6 mb-6">
<div class="form-group">
<label class="form-label">文档类型 <span class="text-red-500">*</span></label>
<select class="form-select" id="doc-type" required>
<option value="">请选择文档类型</option>
<option value="1">销售合同</option>
<option value="2">采购合同</option>
<option value="3">专卖许可证</option>
<option value="4">行政处罚决定书</option>
<option value="5">承包协议</option>
</select>
<div class="text-sm text-secondary mt-1">不同文档类型应用不同的评查规则</div>
</div>
<div class="form-group">
<label class="form-label">文档编号</label>
<input type="text" class="form-input" id="doc-number" placeholder="请输入合同编号、许可证号等">
<div class="text-sm text-secondary mt-1">如无编号可留空,系统将自动识别</div>
</div>
</div>
<div class="form-group mb-4">
<label class="form-label">备注信息</label>
<textarea class="form-textarea" id="doc-remark" placeholder="可输入文档的相关描述或备注信息" rows="2"></textarea>
</div>
<div class="form-group">
<label class="form-label">上传文档 <span class="text-red-500">*</span></label>
<div class="upload-area" id="upload-area">
<input type="file" id="file-input" style="display: none;" multiple>
<i class="ri-upload-cloud-line upload-icon"></i>
<div class="upload-text">
<p class="text-lg mb-2">拖拽文件到此处或点击上传</p>
<p class="text-sm text-secondary">支持 PDF、DOC、DOCX、TXT 格式文档,单个文件大小不超过50MB</p>
</div>
<div class="test-document-switch">
<label class="switch">
<input type="checkbox" id="test-document-toggle">
<span class="slider"></span>
</label>
<span>标记为测试文档(不计入正式统计)</span>
</div>
</div>
<!-- 批量操作栏 -->
<div class="batch-actions" id="batch-actions" style="display: none;">
<div>
<span class="text-sm">已选择 <span id="selected-count">0</span> 个文件</span>
</div>
<div>
<button type="button" class="ant-btn ant-btn-default ant-btn-sm mr-2" id="batch-delete-btn">
<i class="ri-delete-bin-line"></i> 删除选中
</button>
<button type="button" class="ant-btn ant-btn-default ant-btn-sm" id="clear-all-btn">
<i class="ri-close-circle-line"></i> 清空列表
</button>
</div>
</div>
<div class="file-list" id="file-list"></div>
<!-- 高级选项区域 -->
<div class="advanced-options">
<div class="advanced-options-toggle" id="advanced-toggle">
<span>高级上传设置</span>
<i class="ri-arrow-down-s-line ml-1"></i>
</div>
<div class="advanced-options-content" id="advanced-content">
<div class="grid grid-cols-2 gap-4">
<div class="form-group">
<label class="form-label">存储方式</label>
<select class="form-select" id="storage-type">
<option value="minio">MinIO对象存储</option>
<option value="local">本地文件系统</option>
<option value="s3">Amazon S3</option>
</select>
<div class="text-sm text-secondary mt-1">选择文档的存储位置</div>
</div>
<div class="form-group">
<label class="form-label">上传后操作</label>
<select class="form-select" id="after-upload">
<option value="list">返回文档列表</option>
<option value="stay">留在当前页面</option>
<option value="audit">立即开始审核</option>
</select>
<div class="text-sm text-secondary mt-1">上传完成后自动执行的操作</div>
</div>
</div>
</div>
</div>
</div>
</form>
<!-- 上传完成后的操作区域 -->
<div class="upload-complete-actions" id="upload-complete-actions">
<div class="alert alert-success mb-4">
<i class="ri-checkbox-circle-line mr-2"></i> 所有文件上传成功!
</div>
<div>
<button class="ant-btn ant-btn-default mr-2" id="upload-more-btn">
<i class="ri-add-line"></i> 继续上传
</button>
<button class="ant-btn ant-btn-default mr-2" id="view-list-btn">
<i class="ri-list-check-line"></i> 查看文档列表
</button>
<button class="ant-btn ant-btn-primary" id="start-audit-btn">
<i class="ri-play-circle-line"></i> 开始审核
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 文件预览模态框 -->
<div class="preview-modal" id="preview-modal">
<div class="preview-content">
<div class="preview-header">
<h3 class="text-lg font-medium" id="preview-title">文件预览</h3>
<button class="ant-btn ant-btn-text" id="close-preview">
<i class="ri-close-line"></i>
</button>
</div>
<div class="preview-body">
<iframe id="preview-iframe" class="preview-iframe"></iframe>
</div>
<div class="preview-footer">
<button class="ant-btn ant-btn-default" id="close-preview-btn">关闭</button>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const uploadArea = document.getElementById('upload-area');
const fileInput = document.getElementById('file-input');
const fileList = document.getElementById('file-list');
const startUploadBtn = document.getElementById('start-upload-btn');
const testDocumentToggle = document.getElementById('test-document-toggle');
const previewModal = document.getElementById('preview-modal');
const previewTitle = document.getElementById('preview-title');
const previewIframe = document.getElementById('preview-iframe');
const closePreviewBtn = document.getElementById('close-preview');
const closePreviewFooterBtn = document.getElementById('close-preview-btn');
let files = [];
// 更新上传按钮状态
function updateUploadButtonState() {
startUploadBtn.disabled = files.length === 0 || !document.getElementById('doc-type').value;
}
// 点击上传区域触发文件选择
uploadArea.addEventListener('click', function() {
fileInput.click();
});
// 拖拽文件
uploadArea.addEventListener('dragover', function(e) {
e.preventDefault();
this.classList.add('drag-over');
});
uploadArea.addEventListener('dragleave', function() {
this.classList.remove('drag-over');
});
uploadArea.addEventListener('drop', function(e) {
e.preventDefault();
this.classList.remove('drag-over');
const droppedFiles = e.dataTransfer.files;
handleFiles(droppedFiles);
});
// 文件选择
fileInput.addEventListener('change', function() {
handleFiles(this.files);
this.value = ''; // 清空文件选择器,允许重复选择同一文件
});
// 文档类型选择
document.getElementById('doc-type').addEventListener('change', updateUploadButtonState);
// 处理选择的文件
function handleFiles(selectedFiles) {
if (!selectedFiles || selectedFiles.length === 0) return;
for (let i = 0; i < selectedFiles.length; i++) {
const file = selectedFiles[i];
// 检查文件类型
const fileType = file.type;
const validTypes = ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'text/plain'];
if (!validTypes.includes(fileType) &&
!file.name.toLowerCase().endsWith('.pdf') &&
!file.name.toLowerCase().endsWith('.doc') &&
!file.name.toLowerCase().endsWith('.docx') &&
!file.name.toLowerCase().endsWith('.txt')) {
alert(`不支持的文件类型: ${file.name}\n请上传PDF、DOC、DOCX或TXT格式文件`);
continue;
}
// 检查文件大小
if (file.size > 50 * 1024 * 1024) { // 50MB
alert(`文件过大: ${file.name}\n文件大小不能超过50MB`);
continue;
}
// 检查是否已添加
const isDuplicate = files.some(f => f.name === file.name && f.size === file.size);
if (isDuplicate) {
alert(`文件已添加: ${file.name}`);
continue;
}
files.push(file);
createFileListItem(file);
}
updateUploadButtonState();
updateBatchActionsVisibility();
}
// 创建文件列表项
function createFileListItem(file) {
const fileItem = document.createElement('div');
fileItem.className = 'file-item';
// 生成唯一ID供后续操作
const fileId = 'file-' + Math.random().toString(36).substr(2, 9);
fileItem.setAttribute('data-file-id', fileId);
// 根据文件类型选择图标
let fileIconClass = 'ri-file-text-line';
let fileIconColor = 'text-primary';
let canPreview = false;
if (file.name.toLowerCase().endsWith('.pdf')) {
fileIconClass = 'ri-file-pdf-line';
fileIconColor = 'text-red-500';
canPreview = true;
} else if (file.name.toLowerCase().endsWith('.doc') || file.name.toLowerCase().endsWith('.docx')) {
fileIconClass = 'ri-file-word-line';
fileIconColor = 'text-blue-500';
} else if (file.name.toLowerCase().endsWith('.txt')) {
fileIconClass = 'ri-file-text-line';
fileIconColor = 'text-gray-500';
canPreview = true;
}
// 格式化文件大小
const fileSize = formatFileSize(file.size);
// 允许编辑文件名
const fileName = file.name;
const fileNameWithoutExt = fileName.substring(0, fileName.lastIndexOf('.'));
const fileExt = fileName.substring(fileName.lastIndexOf('.'));
fileItem.innerHTML = `
<div class="flex items-center mr-3">
<input type="checkbox" class="file-checkbox" data-file-id="${fileId}">
</div>
<i class="${fileIconClass} file-icon ${fileIconColor}"></i>
<div class="file-info">
<div class="file-name">
<span class="filename-text">${fileName}</span>
<span class="edit-filename" title="编辑文件名"><i class="ri-edit-line"></i></span>
</div>
<div class="file-meta">
<span class="file-size">${fileSize}</span>
<span class="file-status">待上传</span>
</div>
<div class="progress-bar">
<div class="progress-bar-inner" style="width: 0%"></div>
</div>
</div>
<div class="file-actions">
${canPreview ? `
<button type="button" class="ant-btn ant-btn-text ant-btn-sm text-primary preview-file-btn" title="预览文件">
<i class="ri-eye-line"></i>
</button>
` : ''}
<button type="button" class="ant-btn ant-btn-text ant-btn-sm text-error delete-file-btn" title="删除文件">
<i class="ri-delete-bin-line"></i>
</button>
</div>
`;
// 预览按钮
if (canPreview) {
const previewBtn = fileItem.querySelector('.preview-file-btn');
previewBtn.addEventListener('click', function() {
previewFile(file);
});
}
// 删除按钮
const deleteBtn = fileItem.querySelector('.delete-file-btn');
deleteBtn.addEventListener('click', function() {
removeFile(fileId);
});
// 编辑文件名
const editNameBtn = fileItem.querySelector('.edit-filename');
const filenameText = fileItem.querySelector('.filename-text');
editNameBtn.addEventListener('click', function() {
const currentName = filenameText.textContent;
const nameWithoutExt = currentName.substring(0, currentName.lastIndexOf('.'));
const ext = currentName.substring(currentName.lastIndexOf('.'));
// 创建输入框
const input = document.createElement('input');
input.type = 'text';
input.value = nameWithoutExt;
input.className = 'form-input py-0 px-1';
input.style.width = '70%';
// 替换文本为输入框
filenameText.innerHTML = '';
filenameText.appendChild(input);
input.focus();
// 处理完成编辑
const finishEditing = () => {
let newName = input.value.trim();
if (newName) {
// 只更新文件名,保留扩展名
filenameText.textContent = newName + ext;
// 更新文件对象的名称
const fileIndex = files.findIndex(f =>
fileItem.getAttribute('data-file-id') === fileId
);
if (fileIndex !== -1) {
// 在这里,我们只是更新UI显示,实际上传时再处理文件名
// 因为File对象的name属性不能直接修改,我们将使用FormData时设置新名称
fileItem.setAttribute('data-new-name', newName + ext);
}
} else {
// 如果用户删除了所有内容,还原原始文件名
filenameText.textContent = currentName;
}
};
// 失去焦点或按回车时完成编辑
input.addEventListener('blur', finishEditing);
input.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
finishEditing();
}
});
});
// 复选框事件
const checkbox = fileItem.querySelector('.file-checkbox');
checkbox.addEventListener('change', updateBatchActionsVisibility);
fileList.appendChild(fileItem);
return fileItem;
}
// 格式化文件大小
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
// 预览文件
function previewFile(file) {
if (file.type === 'application/pdf' || file.name.toLowerCase().endsWith('.pdf')) {
// 对于PDF文件,使用对象URL直接在iframe中显示
const objectUrl = URL.createObjectURL(file);
previewTitle.textContent = file.name;
previewIframe.src = objectUrl;
previewModal.style.display = 'flex';
} else if (file.type === 'text/plain' || file.name.toLowerCase().endsWith('.txt')) {
// 对于文本文件,读取内容并在iframe中显示
const reader = new FileReader();
reader.onload = function(e) {
const content = e.target.result;
previewTitle.textContent = file.name;
// 创建一个HTML文档来显示文本内容
const html = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
padding: 20px;
white-space: pre-wrap;
}
</style>
</head>
<body>${content}</body>
</html>
`;
previewIframe.src = 'data:text/html;charset=utf-8,' + encodeURIComponent(html);
previewModal.style.display = 'flex';
};
reader.readAsText(file);
}
}
// 关闭预览
function closePreview() {
previewModal.style.display = 'none';
previewIframe.src = '';
}
closePreviewBtn.addEventListener('click', closePreview);
closePreviewFooterBtn.addEventListener('click', closePreview);
// 点击模态框背景时关闭预览
previewModal.addEventListener('click', function(e) {
if (e.target === previewModal) {
closePreview();
}
});
// 移除文件
function removeFile(fileId) {
const fileItem = document.querySelector(`.file-item[data-file-id="${fileId}"]`);
if (!fileItem) return;
// 从文件列表中移除
const fileIndex = files.findIndex((_, index) =>
document.querySelectorAll('.file-item')[index].getAttribute('data-file-id') === fileId
);
if (fileIndex !== -1) {
files.splice(fileIndex, 1);
}
fileItem.remove();
updateUploadButtonState();
updateBatchActionsVisibility();
}
// 更新批量操作按钮可见性
function updateBatchActionsVisibility() {
const checkboxes = document.querySelectorAll('.file-checkbox:checked');
const batchActions = document.getElementById('batch-actions');
const selectedCount = document.getElementById('selected-count');
if (files.length > 0) {
batchActions.style.display = 'flex';
selectedCount.textContent = checkboxes.length;
} else {
batchActions.style.display = 'none';
}
}
// 批量删除按钮
document.getElementById('batch-delete-btn').addEventListener('click', function() {
const checkedBoxes = document.querySelectorAll('.file-checkbox:checked');
const fileIds = Array.from(checkedBoxes).map(checkbox => checkbox.getAttribute('data-file-id'));
if (fileIds.length === 0) return;
if (confirm(`确定要删除选中的 ${fileIds.length} 个文件吗?`)) {
fileIds.forEach(id => removeFile(id));
}
});
// 清空列表按钮
document.getElementById('clear-all-btn').addEventListener('click', function() {
if (files.length === 0) return;
if (confirm('确定要清空文件列表吗?')) {
files = [];
fileList.innerHTML = '';
updateUploadButtonState();
updateBatchActionsVisibility();
}
});
// 高级选项切换
const advancedToggle = document.getElementById('advanced-toggle');
const advancedContent = document.getElementById('advanced-content');
advancedToggle.addEventListener('click', function() {
const isOpen = advancedContent.style.display === 'block';
if (isOpen) {
advancedContent.style.display = 'none';
this.classList.remove('open');
} else {
advancedContent.style.display = 'block';
this.classList.add('open');
}
});
// 开始上传按钮
startUploadBtn.addEventListener('click', function() {
const docType = document.getElementById('doc-type').value;
const docNumber = document.getElementById('doc-number').value;
const docRemark = document.getElementById('doc-remark').value;
const isTestDocument = testDocumentToggle.checked;
const storageType = document.getElementById('storage-type').value;
const afterUpload = document.getElementById('after-upload').value;
if (!docType) {
alert('请选择文档类型');
return;
}
if (files.length === 0) {
alert('请至少上传一个文档');
return;
}
// 模拟上传过程
const fileItems = document.querySelectorAll('.file-item');
files.forEach((file, index) => {
uploadFile(file, fileItems[index], {
type_id: docType,
document_number: docNumber,
remark: docRemark,
is_test_document: isTestDocument,
storage_type: storageType
});
});
});
// 上传文件
function uploadFile(file, fileItem, metadata) {
const progressBar = fileItem.querySelector('.progress-bar-inner');
const statusText = fileItem.querySelector('.file-status');
// 获取可能被修改的文件名
const newName = fileItem.getAttribute('data-new-name');
const fileName = newName || file.name;
statusText.textContent = '上传中...';
// 假设文件ID,实际应由服务器返回
const uploadId = 'upload-' + Math.random().toString(36).substr(2, 9);
fileItem.setAttribute('data-upload-id', uploadId);
// 模拟上传进度
let progress = 0;
const interval = setInterval(() => {
progress += Math.random() * 10;
if (progress >= 100) {
progress = 100;
clearInterval(interval);
// 上传完成
setTimeout(() => {
// 根据概率模拟偶尔的上传失败情况
const success = Math.random() > 0.1; // 90%概率成功
if (success) {
statusText.textContent = '上传成功';
// 实际应用中应该使用AJAX请求上传文件
// console.log('文件上传成功:', fileName, metadata);
// 检查是否所有文件都已上传
const allUploaded = Array.from(document.querySelectorAll('.file-status')).every(
status => status.textContent === '上传成功'
);
if (allUploaded) {
setTimeout(() => {
handleUploadComplete();
}, 1000);
}
} else {
statusText.textContent = '上传失败';
statusText.classList.add('error');
// 添加重试按钮
const retryButton = document.createElement('span');
retryButton.className = 'retry-btn ml-2';
retryButton.innerHTML = '<i class="ri-refresh-line"></i> 重试';
statusText.parentNode.appendChild(retryButton);
retryButton.addEventListener('click', function() {
statusText.textContent = '准备重新上传...';
statusText.classList.remove('error');
retryButton.remove();
// 延迟一下再开始上传,让用户感知状态变化
setTimeout(() => {
progressBar.style.width = '0%';
uploadFile(file, fileItem, metadata);
}, 500);
});
}
}, 500);
}
progressBar.style.width = `${progress}%`;
}, 200);
// 实际应用中应该使用FormData和fetch/XMLHttpRequest上传文件
// const formData = new FormData();
// formData.append('file', file);
// formData.append('type_id', metadata.type_id);
// formData.append('document_number', metadata.document_number);
// formData.append('remark', metadata.remark);
// formData.append('is_test_document', metadata.is_test_document);
// formData.append('storage_type', metadata.storage_type);
// fetch('/api/documents', {
// method: 'POST',
// body: formData
// })
// .then(response => response.json())
// .then(data => {
// // console.log('上传成功:', data);
// statusText.textContent = '上传成功';
// progressBar.style.width = '100%';
//
// // 检查是否所有文件都已上传
// const allUploaded = Array.from(document.querySelectorAll('.file-status')).every(
// status => status.textContent === '上传成功'
// );
//
// if (allUploaded) {
// handleUploadComplete();
// }
// })
// .catch(error => {
// console.error('上传失败:', error);
// statusText.textContent = '上传失败';
// statusText.classList.add('error');
//
// // 添加重试按钮
// const retryButton = document.createElement('span');
// retryButton.className = 'retry-btn ml-2';
// retryButton.innerHTML = '<i class="ri-refresh-line"></i> 重试';
// statusText.parentNode.appendChild(retryButton);
//
// retryButton.addEventListener('click', function() {
// statusText.textContent = '准备重新上传...';
// statusText.classList.remove('error');
// retryButton.remove();
//
// // 延迟一下再开始上传,让用户感知状态变化
// setTimeout(() => {
// progressBar.style.width = '0%';
// uploadFile(file, fileItem, metadata);
// }, 500);
// });
// });
}
// 上传完成后的处理
function handleUploadComplete() {
// 隐藏上传区域和文件列表
document.getElementById('upload-form').style.display = 'none';
// 显示上传完成操作区域
const uploadCompleteActions = document.getElementById('upload-complete-actions');
uploadCompleteActions.style.display = 'block';
// 滚动到操作区域
uploadCompleteActions.scrollIntoView({ behavior: 'smooth' });
// 根据选择的上传后操作决定行为
const afterUpload = document.getElementById('after-upload').value;
if (afterUpload === 'list') {
setTimeout(() => {
window.location.href = '文档-列表.html';
}, 2000);
} else if (afterUpload === 'audit') {
setTimeout(() => {
window.location.href = '文档-详情.html?id=1&action=audit';
}, 2000);
}
}
// 上传完成后的操作按钮事件
document.getElementById('upload-more-btn').addEventListener('click', function() {
// 重置表单,允许继续上传
document.getElementById('upload-form').style.display = 'block';
document.getElementById('upload-complete-actions').style.display = 'none';
// 清空文件列表
files = [];
fileList.innerHTML = '';
updateUploadButtonState();
updateBatchActionsVisibility();
});
document.getElementById('view-list-btn').addEventListener('click', function() {
window.location.href = '文档-列表.html';
});
document.getElementById('start-audit-btn').addEventListener('click', function() {
// 假设最后一个上传的文档ID是1
window.location.href = '文档-详情.html?id=1&action=audit';
});
});
</script>
</body>
</html>