更新数据同步

This commit is contained in:
2025-11-20 12:39:11 +08:00
parent 304d88541a
commit 8de93d9882
3 changed files with 100 additions and 50 deletions

View File

@@ -12,6 +12,7 @@ import com.mini.capi.model.info.TodoHandleDTO;
import com.mini.capi.utils.FileUtils;
import com.mini.capi.utils.vId;
import jakarta.annotation.Resource;
import org.apache.commons.io.FilenameUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -37,7 +38,7 @@ public class workController {
@Resource
private BizFilesService bizFilesService;
private static String UPLOAD_PATH = "/ogsapp/files/";
private static final String UPLOAD_PATH = "/ogsapp/files/";
/**
@@ -69,7 +70,7 @@ public class workController {
/**
* 创建文件夹
*/
@PostMapping("/CreateFolder")
@PostMapping("/createFolder")
public ApiResult<?> CreateFolder(@Validated @RequestBody CreateFolder request) {
try {
String dirId = vId.getCid();
@@ -104,6 +105,7 @@ public class workController {
try {
// 1. 获取原始文件名和后缀
String originalFilename = file.getOriginalFilename();
String fileType = FilenameUtils.getExtension(originalFilename);
String fileSuffix = originalFilename.substring(originalFilename.lastIndexOf("."));
// 2. 生成唯一文件名(避免文件名冲突)
String uniqueFileName = vId.getCid() + fileSuffix;
@@ -114,7 +116,7 @@ public class workController {
bizFiles.setFileName(originalFilename);
bizFiles.setFolderId(folderId);
bizFiles.setFileSize(file.getSize());
bizFiles.setFileType(fileSuffix);
bizFiles.setFileType(fileType);
bizFiles.setFilePath(filePath.toString());
bizFiles.setCreatorId(0);
bizFiles.setIsDeleted(0);

View File

@@ -6,6 +6,10 @@ server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javasc
server.tomcat.max-connections=200
server.tomcat.threads.max=100
server.tomcat.threads.min-spare=10
spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=200MB
spring.servlet.multipart.max-request-size=1000MB
spring.servlet.multipart.file-size-threshold=10MB
## Token
security.default-token=3774e79ac55aff6d1afc0f94bfaf131d
## MySQL

View File

@@ -468,7 +468,7 @@
setTimeout(() => {
// 实际项目中这里应该调用后端API创建文件夹
// 例如:
fetch('CreateFolder', {
fetch('createFolder', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -582,74 +582,118 @@
showMessage('请先选择要上传的文件', 'error');
return;
}
// 前端文件大小校验和后端max-file-size一致可选
const MAX_FILE_SIZE = 200 * 1024 * 1024; // 200MB字节
const overSizeFile = uploadFiles.find(file => file.size > MAX_FILE_SIZE);
if (overSizeFile) {
showMessage(`文件 ${overSizeFile.name} 超过 200MB 限制,请压缩后上传`, 'error');
return;
}
const uploadFolder = document.getElementById('uploadFolder').value;
showMessage(`正在上传 ${uploadFiles.length} 个文件...`);
// 禁用上传按钮
const uploadBtn = document.getElementById('startUploadBtn');
uploadBtn.disabled = true;
uploadBtn.innerHTML = '<i class="fa fa-spinner fa-spin mr-2"></i> 上传中...';
// 显示进度条
const progressBars = document.querySelectorAll('.upload-progress');
progressBars.forEach(bar => {
bar.classList.remove('hidden');
});
// 模拟上传进度
let completedFiles = 0;
let processedFiles = 0; // 统计「已处理完成」的文件数(成功+失败)
let successCount = 0; // 统计成功数
const failedFiles = []; // 记录失败文件名
uploadFiles.forEach((file, index) => {
simulateUploadProgress(index, file, () => {
completedFiles++;
// 检查是否所有文件都上传完成
if (completedFiles === uploadFiles.length) {
setTimeout(() => {
// 启用上传按钮
uploadSingleFile(file, index, uploadFolder,
// 单个文件处理完成后的回调(无论成功/失败)
(isSuccess) => {
processedFiles++;
if (isSuccess) successCount++;
else failedFiles.push(file.name);
// 关键:所有文件都处理完成后,再关闭模态框
if (processedFiles === uploadFiles.length) {
uploadBtn.disabled = false;
uploadBtn.innerHTML = '开始上传';
// 实际项目中这里应该调用后端API上传文件
// 例如:
const formData = new FormData();
uploadFiles.forEach(file => {
formData.append('files', file);
});
formData.append('folderId', uploadFolder);
fetch('uploadFiles', {
method: 'POST',
body: formData,
})
.then(response => response.json())
.then(data => {
// 处理上传成功
closeUploadFileModal();
// 显示成功消息
showMessage(`${completedFiles} 个文件上传成功`);
window.location.href = 'dataDoc'
})
.catch(error => {
// 处理上传失败
showMessage('上传文件失败', 'error');
});
}, 500);
// 关闭模态框(核心位置:所有文件处理完后)
closeUploadFileModal();
// 显示最终结果
let message = '';
if (successCount === uploadFiles.length) {
message = `全部 ${successCount} 个文件上传成功`;
window.location.href = 'dataDoc'; // 全部成功才跳转
} else if (successCount > 0) {
message = `上传完成:成功 ${successCount} 个,失败 ${failedFiles.length} 个(失败:${failedFiles.join('、')}`;
} else {
message = `全部 ${failedFiles.length} 个文件上传失败(${failedFiles.join('、')}`;
}
showMessage(message, failedFiles.length > 0 ? 'error' : 'success');
}
}
});
);
});
}
// 模拟上传进度
function simulateUploadProgress(index, file, callback) {
// 单个文件上传补充回调参数isSuccess标记是否成功
function uploadSingleFile(file, index, folderId, callback) {
const progressBar = document.querySelectorAll('.upload-progress-bar')[index];
let progress = 0;
const formData = new FormData();
formData.append('files', file);
formData.append('folderId', folderId);
const interval = setInterval(() => {
progress += Math.random() * 20;
if (progress >= 100) {
progress = 100;
clearInterval(interval);
setTimeout(callback, 500);
const xhr = new XMLHttpRequest();
xhr.open('POST', 'uploadFiles', true);
xhr.withCredentials = true;
xhr.timeout = 300000; // 5分钟超时
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) {
const progress = (e.loaded / e.total) * 100;
progressBar.style.width = `${progress.toFixed(2)}%`;
}
progressBar.style.width = `${progress}%`;
}, 200);
};
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
let data;
try {
data = JSON.parse(xhr.responseText);
} catch (err) {
showMessage(`文件 ${file.name} 上传成功,但后端返回格式错误`, 'warning');
progressBar.style.width = '100%';
callback(true); // 格式错误仍算上传成功(可根据需求调整)
return;
}
if (data.success) {
progressBar.style.width = '100%';
callback(true); // 成功回调传true
} else {
showMessage(`文件 ${file.name} 上传失败:${data.message}`, 'error');
callback(false); // 失败回调传false
}
} else {
showMessage(`文件 ${file.name} 上传失败:状态码 ${xhr.status}`, 'error');
callback(false);
}
};
xhr.onerror = () => {
showMessage(`文件 ${file.name} 网络错误`, 'error');
callback(false);
};
xhr.ontimeout = () => {
showMessage(`文件 ${file.name} 上传超时`, 'error');
callback(false);
};
xhr.send(formData);
}
// 格式化文件大小