feat : 优化文件上传 优化一体机体验
This commit is contained in:
@@ -62,38 +62,6 @@
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.code-card {
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
border-radius: 16px;
|
||||
padding: 20px;
|
||||
margin-bottom: 25px;
|
||||
text-align: center;
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.code-label {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.code-value {
|
||||
font-size: 22px;
|
||||
color: #2d3436;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2px;
|
||||
padding: 12px;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
margin-top: 8px;
|
||||
word-break: break-all;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.upload-section {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
@@ -131,6 +99,17 @@
|
||||
background: rgba(102, 126, 234, 0.05);
|
||||
}
|
||||
|
||||
.upload-area.disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
background: #f5f5f5;
|
||||
border-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.upload-area.disabled:active {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.upload-icon {
|
||||
font-size: 48px;
|
||||
color: #667eea;
|
||||
@@ -161,6 +140,10 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.file-input:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.selected-files {
|
||||
display: none;
|
||||
}
|
||||
@@ -516,6 +499,62 @@
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 限制提示样式 */
|
||||
.limit-info {
|
||||
background: #fff8e1;
|
||||
border: 1px solid #ffd54f;
|
||||
border-radius: 12px;
|
||||
padding: 12px 16px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 14px;
|
||||
color: #f57c00;
|
||||
display: none;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
animation: slideIn 0.3s ease;
|
||||
}
|
||||
|
||||
.limit-info.show {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.limit-icon {
|
||||
font-size: 18px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.limit-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 限制警告提示 */
|
||||
.limit-warning-info {
|
||||
background: #ffebee;
|
||||
border: 1px solid #ffcdd2;
|
||||
border-radius: 12px;
|
||||
padding: 12px 16px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 14px;
|
||||
color: #d32f2f;
|
||||
display: none;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
animation: slideIn 0.3s ease;
|
||||
}
|
||||
|
||||
.limit-warning-info.show {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.limit-warning-icon {
|
||||
font-size: 18px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.limit-warning-text {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -526,18 +565,30 @@
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<!-- 限制提示 -->
|
||||
<div class="limit-info" id="limitInfo">
|
||||
<span class="limit-icon">⚠️</span>
|
||||
<div class="limit-text" id="limitText">加载中...</div>
|
||||
</div>
|
||||
|
||||
<!-- 总数量限制警告 -->
|
||||
<div class="limit-warning-info" id="limitWarningInfo">
|
||||
<span class="limit-warning-icon">⚠️</span>
|
||||
<div class="limit-warning-text" id="limitWarningText">已超过文件上传总数限制</div>
|
||||
</div>
|
||||
|
||||
<div class="upload-section">
|
||||
<h3 class="section-title">📎 选择文件</h3>
|
||||
<div class="upload-area" id="uploadArea">
|
||||
<div class="upload-icon">📁</div>
|
||||
<div class="upload-text">点击选择文件</div>
|
||||
<div class="upload-hint">支持图片、文档、文本等格式<br />单个文件不超过10MB</div>
|
||||
<div class="upload-text" id="uploadText">点击选择文件</div>
|
||||
<div class="upload-hint" id="uploadHint">支持图片、文档、文本等格式</div>
|
||||
<input
|
||||
type="file"
|
||||
id="fileInput"
|
||||
class="file-input"
|
||||
multiple
|
||||
accept="image/*,.pdf,.doc,.docx,.xls,.xlsx,.csv,.ppt,.pptx,.txt,.md,.html"
|
||||
accept="image/*,.pdf,.doc,.docx,.xls,.xlsx,.csv,.ppt,.pptx,.txt,.md"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -566,7 +617,7 @@
|
||||
|
||||
<!-- 状态提示框 -->
|
||||
<div class="status-message" id="statusMessage">
|
||||
<span class="status-icon">✅</span>
|
||||
<span class="status-icon" id="statusIcon">✅</span>
|
||||
<h3 class="status-title" id="statusTitle">上传成功!</h3>
|
||||
<p class="status-desc" id="statusDesc">文件已成功上传到电脑端</p>
|
||||
<button class="status-btn" id="statusBtn">完成</button>
|
||||
@@ -579,15 +630,24 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 获取URL中的code参数
|
||||
// 获取URL中的参数
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const sessionId = urlParams.get('sessionId');
|
||||
const uploadApi = urlParams.get('uploadApi');
|
||||
console.log(sessionId);
|
||||
console.log(uploadApi);
|
||||
const fileCountParam = urlParams.get('fileCount');
|
||||
|
||||
// 配置常量
|
||||
const MAX_FILE_COUNT = fileCountParam ? parseInt(fileCountParam) : 2; // 从URL参数获取,默认为2
|
||||
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
|
||||
|
||||
console.log('Session ID:', sessionId);
|
||||
console.log('Upload API:', uploadApi);
|
||||
console.log('Max file count:', MAX_FILE_COUNT);
|
||||
|
||||
// DOM元素
|
||||
const uploadArea = document.getElementById('uploadArea');
|
||||
const uploadText = document.getElementById('uploadText');
|
||||
const uploadHint = document.getElementById('uploadHint');
|
||||
const fileInput = document.getElementById('fileInput');
|
||||
const fileList = document.getElementById('fileList');
|
||||
const selectedFilesContainer = document.getElementById('selectedFiles');
|
||||
@@ -596,19 +656,34 @@
|
||||
const loadingOverlay = document.getElementById('loadingOverlay');
|
||||
const loadingText = document.getElementById('loadingText');
|
||||
const statusMessage = document.getElementById('statusMessage');
|
||||
const statusIcon = document.getElementById('statusIcon');
|
||||
const statusTitle = document.getElementById('statusTitle');
|
||||
const statusDesc = document.getElementById('statusDesc');
|
||||
const statusBtn = document.getElementById('statusBtn');
|
||||
const imagePreviewModal = document.getElementById('imagePreviewModal');
|
||||
const previewImage = document.getElementById('previewImage');
|
||||
const closePreview = document.getElementById('closePreview');
|
||||
const limitInfo = document.getElementById('limitInfo');
|
||||
const limitText = document.getElementById('limitText');
|
||||
const limitWarningInfo = document.getElementById('limitWarningInfo');
|
||||
const limitWarningText = document.getElementById('limitWarningText');
|
||||
|
||||
// 状态变量
|
||||
let selectedFiles = [];
|
||||
let isUploading = false;
|
||||
let uploadedCount = 0; // 已上传的总文件数量
|
||||
|
||||
// 初始化
|
||||
function init() {
|
||||
// 更新限制提示文本
|
||||
updateLimitText();
|
||||
|
||||
// 显示限制提示
|
||||
limitInfo.classList.add('show');
|
||||
|
||||
// 检查本地存储中已上传的文件数量
|
||||
checkUploadedCount();
|
||||
|
||||
// 事件监听
|
||||
fileInput.addEventListener('change', handleFileSelect);
|
||||
clearBtn.addEventListener('click', clearAllFiles);
|
||||
@@ -632,6 +707,46 @@
|
||||
|
||||
// 防止页面滚动
|
||||
document.body.addEventListener('touchmove', preventScroll, { passive: false });
|
||||
|
||||
// 更新UI
|
||||
updateUI();
|
||||
}
|
||||
|
||||
// 更新限制提示文本
|
||||
function updateLimitText() {
|
||||
if (MAX_FILE_COUNT <= 0) {
|
||||
limitText.textContent = '未设置可上传文件数量';
|
||||
} else {
|
||||
limitText.textContent = `总共可上传 ${MAX_FILE_COUNT} 个文件,每个文件不超过10MB(已上传: ${uploadedCount})`;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查已上传的文件数量
|
||||
function checkUploadedCount() {
|
||||
// 使用sessionStorage存储当前会话的上传数量
|
||||
// 如果要永久存储,可以改用localStorage
|
||||
const storedCount = sessionStorage.getItem('uploadedFileCount');
|
||||
uploadedCount = storedCount ? parseInt(storedCount) : 0;
|
||||
|
||||
// 更新警告提示
|
||||
updateWarningText();
|
||||
}
|
||||
|
||||
// 更新警告提示
|
||||
function updateWarningText() {
|
||||
if (MAX_FILE_COUNT > 0 && uploadedCount >= MAX_FILE_COUNT) {
|
||||
limitWarningInfo.classList.add('show');
|
||||
limitWarningText.textContent = `已超过文件上传总数限制(${MAX_FILE_COUNT}个)`;
|
||||
} else {
|
||||
limitWarningInfo.classList.remove('show');
|
||||
}
|
||||
}
|
||||
|
||||
// 保存已上传的文件数量
|
||||
function saveUploadedCount() {
|
||||
sessionStorage.setItem('uploadedFileCount', uploadedCount.toString());
|
||||
updateLimitText();
|
||||
updateWarningText();
|
||||
}
|
||||
|
||||
// 处理文件选择
|
||||
@@ -646,6 +761,12 @@
|
||||
// 设置拖拽上传
|
||||
function setupDragAndDrop() {
|
||||
uploadArea.addEventListener('dragover', (e) => {
|
||||
// 如果已达总数限制,禁止拖拽
|
||||
if (MAX_FILE_COUNT > 0 && uploadedCount >= MAX_FILE_COUNT) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
uploadArea.classList.add('dragover');
|
||||
});
|
||||
@@ -659,6 +780,12 @@
|
||||
e.preventDefault();
|
||||
uploadArea.classList.remove('dragover');
|
||||
|
||||
// 如果已达总数限制,禁止拖拽上传
|
||||
if (MAX_FILE_COUNT > 0 && uploadedCount >= MAX_FILE_COUNT) {
|
||||
showError(`已超过文件上传总数限制(${MAX_FILE_COUNT}个)`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.dataTransfer.files.length) {
|
||||
handleFiles(e.dataTransfer.files);
|
||||
}
|
||||
@@ -667,12 +794,41 @@
|
||||
|
||||
// 处理文件
|
||||
function handleFiles(files) {
|
||||
const maxSize = 20 * 1024 * 1024; // 20MB
|
||||
// 检查是否已达到总文件数量上限
|
||||
if (MAX_FILE_COUNT > 0 && uploadedCount >= MAX_FILE_COUNT) {
|
||||
showError(`已超过文件上传总数限制(${MAX_FILE_COUNT}个)`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查当前选择的文件是否会导致超过总数限制
|
||||
const potentialTotalCount = uploadedCount + files.length;
|
||||
if (MAX_FILE_COUNT > 0 && potentialTotalCount > MAX_FILE_COUNT) {
|
||||
showError(`最多只能上传 ${MAX_FILE_COUNT} 个文件,已上传 ${uploadedCount} 个`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否已达到本次选择的文件数量上限
|
||||
if (selectedFiles.length >= MAX_FILE_COUNT) {
|
||||
showError(`最多只能选择 ${MAX_FILE_COUNT} 个文件`);
|
||||
return;
|
||||
}
|
||||
|
||||
for (let file of files) {
|
||||
// 检查是否已达到本次选择的文件数量上限
|
||||
if (selectedFiles.length >= MAX_FILE_COUNT) {
|
||||
showError(`最多只能选择 ${MAX_FILE_COUNT} 个文件,已忽略多余文件`);
|
||||
break;
|
||||
}
|
||||
|
||||
// 检查是否会导致超过总数限制
|
||||
if (MAX_FILE_COUNT > 0 && (uploadedCount + selectedFiles.length) >= MAX_FILE_COUNT) {
|
||||
showError(`已超过文件上传总数限制(${MAX_FILE_COUNT}个)`);
|
||||
break;
|
||||
}
|
||||
|
||||
// 检查文件大小
|
||||
if (file.size > maxSize) {
|
||||
showError(`文件 ${file.name} 超过20MB限制`);
|
||||
if (file.size > MAX_FILE_SIZE) {
|
||||
showError(`文件 ${file.name} 超过10MB限制`);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -843,18 +999,55 @@
|
||||
// 更新UI状态
|
||||
function updateUI() {
|
||||
const hasFiles = selectedFiles.length > 0;
|
||||
const isTotalLimitReached = MAX_FILE_COUNT > 0 && uploadedCount >= MAX_FILE_COUNT;
|
||||
|
||||
// 显示/隐藏文件列表
|
||||
selectedFilesContainer.classList.toggle('show', hasFiles);
|
||||
|
||||
// 更新按钮状态
|
||||
clearBtn.disabled = !hasFiles || isUploading;
|
||||
uploadBtn.disabled = !hasFiles || isUploading;
|
||||
// 检查是否已达总文件数量上限
|
||||
if (isTotalLimitReached) {
|
||||
// 禁用所有上传相关功能
|
||||
uploadArea.classList.add('disabled');
|
||||
fileInput.disabled = true;
|
||||
uploadText.textContent = '文件上传总数已达上限';
|
||||
uploadHint.innerHTML = `总共可上传 ${MAX_FILE_COUNT} 个文件<br />已上传: ${uploadedCount}`;
|
||||
|
||||
// 禁用按钮
|
||||
clearBtn.disabled = true;
|
||||
uploadBtn.disabled = true;
|
||||
|
||||
// 显示限制警告提示
|
||||
limitWarningInfo.classList.add('show');
|
||||
limitWarningText.textContent = `已超过文件上传总数限制(${MAX_FILE_COUNT}个)`;
|
||||
} else {
|
||||
// 更新上传区域状态
|
||||
uploadArea.classList.remove('disabled');
|
||||
|
||||
// 根据文件数量更新上传区域
|
||||
if (MAX_FILE_COUNT <= 0) {
|
||||
// 如果没有设置文件数量限制,始终可以上传
|
||||
uploadText.textContent = '点击选择文件';
|
||||
uploadHint.innerHTML = '支持图片、文档、文本等格式<br />文件大小不超过10MB';
|
||||
fileInput.disabled = false;
|
||||
} else if (selectedFiles.length >= MAX_FILE_COUNT) {
|
||||
uploadText.textContent = `已达到最大文件数量(${MAX_FILE_COUNT}个)`;
|
||||
uploadHint.innerHTML = `最多${MAX_FILE_COUNT}个文件,每个不超过10MB<br /><strong>已选满</strong>`;
|
||||
fileInput.disabled = true;
|
||||
} else {
|
||||
uploadText.textContent = '点击选择文件';
|
||||
uploadHint.innerHTML = `支持图片、文档、文本等格式<br />最多${MAX_FILE_COUNT}个文件,每个不超过10MB<br />已上传: ${uploadedCount}/${MAX_FILE_COUNT}`;
|
||||
fileInput.disabled = false;
|
||||
}
|
||||
|
||||
// 更新按钮状态
|
||||
clearBtn.disabled = !hasFiles || isUploading;
|
||||
uploadBtn.disabled = !hasFiles || isUploading;
|
||||
}
|
||||
|
||||
// 更新上传按钮文本
|
||||
if (hasFiles) {
|
||||
if (hasFiles && !isTotalLimitReached) {
|
||||
const totalSize = selectedFiles.reduce((sum, file) => sum + file.size, 0);
|
||||
uploadBtn.innerHTML = `<span>⬆️</span> 上传 (${selectedFiles.length}个, ${formatFileSize(
|
||||
uploadBtn.innerHTML = `<span>⬆️</span> 上传 (${selectedFiles.length}/${MAX_FILE_COUNT}, ${formatFileSize(
|
||||
totalSize
|
||||
)})`;
|
||||
} else {
|
||||
@@ -866,6 +1059,19 @@
|
||||
async function startUpload() {
|
||||
if (isUploading || selectedFiles.length === 0) return;
|
||||
|
||||
// 检查是否已达总数限制
|
||||
if (MAX_FILE_COUNT > 0 && uploadedCount >= MAX_FILE_COUNT) {
|
||||
showError(`已超过文件上传总数限制(${MAX_FILE_COUNT}个)`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否会导致超过总数限制
|
||||
const potentialTotalCount = uploadedCount + selectedFiles.length;
|
||||
if (MAX_FILE_COUNT > 0 && potentialTotalCount > MAX_FILE_COUNT) {
|
||||
showError(`最多只能上传 ${MAX_FILE_COUNT} 个文件,已上传 ${uploadedCount} 个`);
|
||||
return;
|
||||
}
|
||||
|
||||
isUploading = true;
|
||||
updateUI();
|
||||
showLoading('正在准备上传...');
|
||||
@@ -903,6 +1109,7 @@
|
||||
} catch (error) {
|
||||
console.error(`文件上传失败: ${file.name}`, error);
|
||||
failCount++;
|
||||
const progressBar = document.querySelector(`#progress-${CSS.escape(file.name)}`);
|
||||
if (progressBar) {
|
||||
progressBar.style.width = '0%';
|
||||
}
|
||||
@@ -913,9 +1120,15 @@
|
||||
hideLoading();
|
||||
|
||||
if (successCount > 0) {
|
||||
// 更新已上传的文件数量
|
||||
uploadedCount += successCount;
|
||||
saveUploadedCount();
|
||||
|
||||
showSuccess(`成功上传 ${successCount} 个文件${failCount > 0 ? `,${failCount} 个失败` : ''}`);
|
||||
// 清空文件列表
|
||||
clearAllFiles();
|
||||
// 更新UI
|
||||
updateUI();
|
||||
} else {
|
||||
showError('文件上传失败,请重试');
|
||||
}
|
||||
@@ -957,7 +1170,7 @@
|
||||
|
||||
const result = await response.json();
|
||||
return {
|
||||
success: result.code == 200 ,
|
||||
success: result.code == 200,
|
||||
data: result,
|
||||
};
|
||||
} catch (error) {
|
||||
@@ -984,6 +1197,7 @@
|
||||
// 显示成功提示
|
||||
function showSuccess(message) {
|
||||
statusMessage.className = 'status-message status-success';
|
||||
statusIcon.textContent = '✅';
|
||||
statusTitle.textContent = '上传成功!';
|
||||
statusDesc.textContent = message;
|
||||
statusMessage.style.display = 'block';
|
||||
@@ -993,6 +1207,7 @@
|
||||
// 显示错误提示
|
||||
function showError(message) {
|
||||
statusMessage.className = 'status-message status-error';
|
||||
statusIcon.textContent = '❌';
|
||||
statusTitle.textContent = '出错了';
|
||||
statusDesc.textContent = message;
|
||||
statusMessage.style.display = 'block';
|
||||
@@ -1031,4 +1246,4 @@
|
||||
document.addEventListener('drop', (e) => e.preventDefault());
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
Reference in New Issue
Block a user