Switch大气层Atmosphere完整指南:终极自定义固件免费安装教程
2026/7/13 4:39:04
作为甘肃国企上市公司项目负责人,我深度理解您对大文件传输系统的核心诉求:高稳定性、强安全性、全兼容性、信创适配。结合集团2000+项目规模与信创国产化要求,我团队基于SpringBoot+Vue2架构,研发了一套支持100G级文件传输、SM4/AES加密、断点续传、信创兼容的解决方案,现以专业视角向您汇报技术方案(附核心源码)。
localStorage+数据库双存储进度,刷新/关闭浏览器不丢失)。/父文件夹/子文件路径存储(兼容IE8与信创浏览器)。X-Request-ID关联业务流水)。storage.config动态切换(无需重启服务)。// 兼容IE8的polyfill(必须引入!) import 'es6-promise/auto'; // 补Promise import 'whatwg-fetch'; // 补fetch import Blob from 'blob-polyfill'; // 补Blob(IE8不支持slice) if (!window.console) window.console = { log: () => {}, error: () => {} }; // 补console // 依赖库(需手动安装:npm install crypto-js axios spark-md5) import CryptoJS from 'crypto-js'; import axios from 'axios'; import SparkMD5 from 'spark-md5'; export default { data() { return { uploadTasks: [], // 上传任务列表(核心数据) chunkSize: 10 * 1024 * 1024, // 10MB分片(100G文件分10000片,平衡速度与内存) aesKey: '', // AES密钥(从后端动态获取) currentTaskId: '', // 当前上传任务的ID isUploading: false // 全局上传状态锁 }; }, mounted() { this.initAesKey(); // 初始化AES密钥(首次加载时生成) this.checkResumeTasks(); // 启动时检查本地是否有未完成的任务 }, methods: { /** * 上传下一个分片(递归) * @param {Object} task 当前上传任务 */ async uploadNextChunk(task) { if (task.chunkIndex >= task.totalChunks) { // 所有分片上传完成 task.progress = 100; task.status = 'success'; task.statusText = '上传成功'; this.isUploading = false; localStorage.removeItem(`upload_${task.taskId}`); // 清除本地缓存 this.$message.success(`${task.fileName} 上传完成!`); return; } // 计算当前分片的起始和结束位置 const start = task.chunkIndex * this.chunkSize; const end = Math.min(start + this.chunkSize, task.totalSize); const chunk = task.file.slice(start, end); // IE8支持File.slice(需Blob.js补丁) // 读取分片内容并加密(原生JS实现) const reader = new FileReader(); reader.onload = (function(chunk, task) { return async function(e) { const chunkContent = e.target.result; // AES加密分片(密钥与后端一致) const encryptedChunk = CryptoJS.AES.encrypt( CryptoJS.lib.WordArray.create(chunkContent), this.aesKey, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 } ).toString(); // 构造FormData(兼容IE8) const formData = new FormData(); formData.append('taskId', task.taskId); formData.append('chunkIndex', task.chunkIndex); formData.append('totalChunks', task.totalChunks); formData.append('filePath', task.filePath); formData.append('chunk', new Blob([encryptedChunk])); try { // 调用后端上传接口(SpringBoot) const res = await axios.post('/api/upload/chunk', formData, { headers: { 'Content-Type': 'multipart/form-data' }, onUploadProgress: (e) => { if (e.lengthComputable) { // 计算实时上传速度(KB/s) const timeDiff = e.timeStamp - (task.lastTime || Date.now()); const speed = (e.loaded - task.uploadedSize) / (timeDiff || 1) / 1024; task.speed = speed.toFixed(2); task.lastTime = e.timeStamp; // 更新进度 task.uploadedSize = e.loaded; task.progress = Math.round((task.uploadedSize / task.totalSize) * 100); } } }); // 分片上传成功,更新状态 task.chunkIndex++; task.status = 'uploading'; task.statusText = `上传中(${task.chunkIndex}/${task.totalChunks})`; this.uploadNextChunk(task); // 递归上传下一个分片 } catch (err) { // 上传失败,标记状态 task.status = 'failed'; task.statusText = `上传失败:${err.response?.data?.msg || '网络错误'}`; this.isUploading = false; } }.bind(this); })(chunk, task); reader.readAsArrayBuffer(chunk); // 读取分片为ArrayBuffer(加密需要) }, } };// com.example.uploader.controller.UploadController.java@RestController@RequestMapping("/api/upload")publicclassUploadController{@Value("${upload.chunk.size}")privatelongchunkSize;// 10MB分片大小(配置文件动态调整)@Value("${upload.storage.path}")privateStringstoragePath;// 存储路径(动态配置:本地/OBS/私有云)@AutowiredprivateUploadProgressServiceprogressService;// 进度服务(数据库操作)@AutowiredprivateAesEncryptoraesEncryptor;// AES加密工具(国密SM4可选)/** * 分片上传接口 */@PostMapping("/chunk")publicResponseEntityuploadChunk(@RequestParam("taskId")StringtaskId,@RequestParam("chunkIndex")intchunkIndex,@RequestParam("totalChunks")inttotalChunks,@RequestParam("filePath")StringfilePath,@RequestParam("chunk")MultipartFilechunk){// 1. 参数校验if(chunk.getSize()>chunkSize){returnResponseEntity.badRequest().body("分片大小超过限制");}// 5. 记录进度到数据库(断点续传关键)UploadProgressprogress=newUploadProgress();progress.setTaskId(taskId);progress.setFilePath(filePath);progress.setChunkIndex(chunkIndex);progress.setTotalChunks(totalChunks);progress.setUploadedSize(chunk.getSize());progress.setStatus("uploading");progressService.saveOrUpdate(progress);// 唯一索引防重复returnResponseEntity.ok("分片上传成功");}}// com.example.uploader.service.UploadProgressService.java@ServicepublicclassUploadProgressService{@AutowiredprivateUploadProgressMapperprogressMapper;// MyBatis Plus Mapper/** * 保存或更新上传进度(唯一索引:taskId+filePath+chunkIndex) */publicvoidsaveOrUpdate(UploadProgressprogress){QueryWrapperqueryWrapper=newQueryWrapper<>();queryWrapper.eq("task_id",progress.getTaskId()).eq("file_path",progress.getFilePath()).eq("chunk_index",progress.getChunkIndex());UploadProgressexisting=progressMapper.selectOne(queryWrapper);if(existing!=null){progress.setId(existing.getId());progressMapper.updateById(progress);}else{progressMapper.insert(progress);}}}-- 通用SQL(MySQL/Oracle/达梦/人大金仓)CREATETABLEIFNOTEXISTSupload_progress(idBIGINTAUTO_INCREMENTPRIMARYKEYCOMMENT'主键ID',task_idVARCHAR(255)NOTNULLCOMMENT'任务ID(如upload_1620000000_abc123)',file_pathVARCHAR(1000)NOTNULLCOMMENT'文件存储路径(如/upload_1620000000/folder_123/file.txt)',chunk_indexINTNOTNULLCOMMENT'当前分片索引(0开始)',total_chunksINTNOTNULLCOMMENT'总分片数',uploaded_sizeBIGINTNOTNULLCOMMENT'已上传大小(字节)',statusVARCHAR(50)NOTNULLDEFAULT'pending'COMMENT'状态:pending/resuming/uploading/failed/success',create_timeTIMESTAMPDEFAULTCURRENT_TIMESTAMPCOMMENT'创建时间',update_timeTIMESTAMPDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMPCOMMENT'更新时间')ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;-- 唯一约束(防止同一任务同一分片重复记录)CREATEUNIQUEINDEXUQ_Task_File_ChunkONupload_progress(task_id,file_path,chunk_index);StorageConfig动态切换存储实现。mvn clean packageapplication.yml(数据库、存储路径、加密密钥)。java -jar uploader-service.jarnpm run builddist目录部署至Nginx/Apache(内网地址:http://internal-uploader:8080)。# application.ymlupload:aes-key:"your-32bytes-aes-key"# AES-256密钥(集团KMS动态获取)sm4-key:"your-16bytes-sm4-key"# SM4密钥(可选,用于存储加密)storage:type:"local"# 可选:obs(华为云)、minio(私有云)local-path:"/data/uploads/"# 本地存储路径obs-config:endpoint:"https://obs.cn-north-1.myhuaweicloud.com"access-key:"your-access-key"secret-key:"your-secret-key"bucket-name:"your-bucket"本方案针对集团大文件传输、信创适配、多项目复用的核心需求设计,提供从源码到部署的全链路支持。我们承诺:
期待与贵集团建立长期合作,共同推动信创产业发展!
附件:央企项目合同、软著证书、信创认证、银行回款凭证(扫描件)。
(注:以上代码为简化示例,实际交付包含完整注释、异常处理、日志监控等功能模块。)
支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传
支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。
支持文件批量下载
文件下载支持离线保存进度信息,刷新页面,关闭页面,重启系统均不会丢失进度信息。
支持下载文件夹,并保留层级结构,不打包,不占用服务器资源。
下载完整示例