更新数据同步
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
// 格式化文件大小
|
||||
|
||||
Reference in New Issue
Block a user