企业网站制作流程携程网站的会计工作怎么做
- 作者: 五速梦信息网
- 时间: 2026年03月21日 09:58
当前位置: 首页 > news >正文
企业网站制作流程,携程网站的会计工作怎么做,郑州网络营销外包顾问,备案时如何关闭网站springbootvue大文件断点续传 后端代码代码说明1.上传分片接口2. 查询已上传分片接口3. 合并分片接口4.后端流程 前端组件前端流程 后端代码
RestController
RequestMapping(/api/commonFileUtil)
public class CommonFileController {Autowiredprivate FilePathC… springbootvue大文件断点续传 后端代码代码说明1.上传分片接口2. 查询已上传分片接口3. 合并分片接口4.后端流程 前端组件前端流程 后端代码
RestController
RequestMapping(/api/commonFileUtil)
public class CommonFileController {Autowiredprivate FilePathConfig filePathConfig;/*** 上传分片/PostMapping(commonUploadByModule/{module})public ActionResult? commonUploadByModule(PathVariable(module) String folder,RequestPart(file) MultipartFile multipartFile,RequestParam(fileHash) String fileHash,RequestParam(chunkIndex) int chunkIndex,RequestParam(totalChunks) int totalChunks,RequestParam(fileName) String originalFileName) throws IOException {String baseFolder filePathConfig.getUploadByModule() (StrUtil.isEmpty(folder) ? default : folder);String tempFolder baseFolder /temp/ fileHash;FileUtil.checkAndCreateFolder(tempFolder);File chunkFile new File(tempFolder, chunkIndex .part);IoUtil.write(new FileOutputStream(chunkFile), true, multipartFile.getBytes());return ActionResult.success(分片上传成功);}/* 查询自己的分片/GetMapping(commonUploadByModule/{module}/status)public ActionResult? uploadedChunks(PathVariable(module) String folder,RequestParam(fileHash) String fileHash) {String baseFolder filePathConfig.getUploadByModule() (StrUtil.isEmpty(folder) ? default : folder);String tempFolder baseFolder /temp/ fileHash;ListInteger uploaded new ArrayList();File folderFile new File(tempFolder);if (folderFile.exists()) {File[] files folderFile.listFiles((dir, name) - name.endsWith(.part));if (files ! null) {for (File file : files) {String name file.getName().replace(.part, );uploaded.add(Integer.parseInt(name));}}}MapObject, Object map new HashMap();map.put(uploaded, uploaded);return ActionResult.success(map);}/* 分片合并**/PostMapping(commonUploadByModule/{module}/merge)public ActionResult? mergeChunks(PathVariable(module) String folder,RequestBody MapString, String params) throws IOException {String fileHash params.get(fileHash);String originalFileName params.get(fileName);String baseFolder filePathConfig.getUploadByModule() (StrUtil.isEmpty(folder) ? default : folder);String tempFolder baseFolder /temp/ fileHash;File[] chunks new File(tempFolder).listFiles((dir, name) - name.endsWith(.part));if (chunks null || chunks.length 0) {return ActionResult.fail(未找到分片文件);}Arrays.sort(chunks, Comparator.comparingInt(f - Integer.parseInt(f.getName().replace(.part, ))));String mergedFileName FileUtil.addPrefix(Paths.get(originalFileName).getFileName().toString());String mergedFilePath baseFolder / mergedFileName;FileUtil.checkAndCreateFolder(baseFolder);try (FileOutputStream fos new FileOutputStream(mergedFilePath)) {for (File chunk : chunks) {Files.copy(chunk.toPath(), fos);}}// 清理临时文件夹for (File chunk : chunks) chunk.delete();new File(tempFolder).delete();MapString, String map new HashMap();map.put(fileName, mergedFileName);map.put(fileOriginName, originalFileName);map.put(fileSize, String.format(%.2fMB, new File(mergedFilePath).length() / 1024 / 1024f));map.put(filePath, mergedFilePath);return ActionResult.success(map);}
}代码说明
1.上传分片接口
PostMapping({module})
public ActionResult? uploadChunk(PathVariable(module) String folder,RequestPart(file) MultipartFile multipartFile,RequestParam(fileHash) String fileHash,RequestParam(chunkIndex) int chunkIndex,RequestParam(totalChunks) int totalChunks,RequestParam(fileName) String originalFileName
) throws IOException { PostMapping(“{module}”): 表示 POST 请求路径为 /uploadByModule/{module}例如/uploadByModule/video。 PathVariable(“module”) String folder: 获取路径变量 module如 “video”表示上传分类。 RequestPart(“file”) MultipartFile multipartFile: 接收上传的文件分片。 其余参数为前端额外上传的信息 fileHash: 前端根据文件内容生成的唯一标识 chunkIndex: 当前是第几个分片 totalChunks: 总共有多少个分片 fileName: 文件原始名。
String baseFolder filePathConfig.getUploadByModule() (StrUtil.isEmpty(folder) ? default : folder); 构造出完整的基础目录路径比如/mnt/upload/video。 如果路径为空则用默认目录 /mnt/upload/default。
String tempFolder baseFolder /temp/ fileHash;
FileUtil.checkAndCreateFolder(tempFolder);构造当前文件的临时目录如 /mnt/upload/video/temp/abc123。 checkAndCreateFolder() 是你自己定义的工具方法用于确保目录存在不存在则创建。
File chunkFile new File(tempFolder, chunkIndex .part);
IoUtil.write(new FileOutputStream(chunkFile), true, multipartFile.getBytes());创建当前分片的目标文件对象例如 /mnt/upload/video/temp/abc123/0.part。 使用 IoUtil.write() 将上传的分片写入本地文件。
- 查询已上传分片接口
GetMapping({module}/status)
public ActionResult? uploadedChunks(PathVariable(module) String folder,RequestParam(fileHash) String fileHash
) {GET 请求路径为/uploadByModule/video/status?fileHashabc123 返回指定文件通过 fileHash 唯一标识的 已上传分片编号。
String baseFolder filePathConfig.getUploadByModule() (StrUtil.isEmpty(folder) ? default : folder); String tempFolder baseFolder /temp/ fileHash; 计算临时分片文件夹路径。 ListInteger uploaded new ArrayList(); File folderFile new File(tempFolder); 准备存储已上传的分片编号。 if (folderFile.exists()) {File[] files folderFile.listFiles((dir, name) - name.endsWith(.part));判断该文件夹是否存在如果存在则读取里面所有以 .part 结尾的文件即分片。 for (File f : files) {String name f.getName().replace(.part, );uploaded.add(Integer.parseInt(name));} }去除每个文件名的 .part 后缀并转为数字分片编号存入列表中。 - 合并分片接口
PostMapping({module}/merge)
public ActionResult? mergeChunks(PathVariable(module) String folder,RequestBody MapString, String params
) throws IOException { POST /uploadByModule/video/merge RequestBody 参数为 JSON 对象包含两个 key fileHash: 文件唯一标识 fileName: 原始文件名。
String fileHash params.get(fileHash); String originalFileName params.get(fileName); 从请求体中提取参数。 String baseFolder filePathConfig.getUploadByModule() (StrUtil.isEmpty(folder) ? default : folder); String tempFolder baseFolder /temp/ fileHash;组装临时目录。 File[] chunks new File(tempFolder).listFiles((dir, name) - name.endsWith(.part)); if (chunks null || chunks.length 0) {return ActionResult.error(未找到分片文件); } Arrays.sort(chunks, Comparator.comparingInt(f - Integer.parseInt(f.getName().replace(.part, ))));对所有分片文件按编号升序排序确保按顺序合并。 String mergedFileName FileUtil.addPrefix(Paths.get(originalFileName).getFileName().toString()); String mergedFilePath baseFolder / mergedFileName; FileUtil.checkAndCreateFolder(baseFolder);使用你的 addPrefix() 工具方法给原始文件名加上唯一前缀 最终合并后文件路径如 /mnt/upload/video/1651283761234_myfile.mp4
try (FileOutputStream fos new FileOutputStream(mergedFilePath)) {for (File chunk : chunks) {Files.copy(chunk.toPath(), fos);} } 创建输出流 fos逐个读取 .part 文件并写入合并目标文件。 for (File chunk : chunks) chunk.delete(); new File(tempFolder).delete();合并完成后删除所有分片及临时文件夹。 MapString, String map new HashMap(); map.put(fileName, mergedFileName); map.put(fileOriginName, originalFileName); map.put(fileSize, String.format(%.2fMB, new File(mergedFilePath).length() / 1024f / 1024f)); map.put(filePath, mergedFilePath); return ActionResult.success(map); 返回完整信息给前端包括 实际文件名带前缀 原始名称 文件大小 路径。
4.后端流程 [后端] 每个分片保存在 temp/{fileHash}/chunkIndex.part合并时按照顺序将所有 part 合成文件 前端组件 templatediv classupload-wrapperinput typefile changehandleFileChange /button :disabled!file || uploading clickuploadFile{{ uploading ? 上传中… : 上传文件 }}/buttondiv v-ifuploading上传进度{{ progress.toFixed(2) }}%/div/div /templatescript import Vue from vue import SparkMD5 from spark-md5 import request from /utils/request;export default {data () {return {file: null,chunkSize: 5 * 1024 * 1024, // 每片 5MBuploading: false,progress: 0,module: video // 上传模块路径如 default、video、image…}},methods: {handleFileChange (e) {this.file e.target.files[0]},async uploadFile () {if (!this.file) returnthis.uploading trueconst fileHash await this.calculateFileHash(this.file)const totalChunks Math.ceil(this.file.size / this.chunkSize)const uploadedChunkIndexes await this.getUploadedChunkIndexes(fileHash)for (let index 0; index totalChunks; index) {if (uploadedChunkIndexes.includes(index)) {this.updateProgress(index 1, totalChunks)continue}const start index * this.chunkSizeconst end Math.min(start this.chunkSize, this.file.size)const chunk this.file.slice(start, end)await this.uploadChunk({chunk,fileHash,chunkIndex: index,totalChunks,fileName: this.file.name})this.updateProgress(index 1, totalChunks)}await this.mergeChunks(fileHash, this.file.name)this.uploading falsealert(上传成功)},updateProgress (uploadedChunks, totalChunks) {this.progress (uploadedChunks / totalChunks) * 100},async calculateFileHash (file) {return new Promise(resolve {const spark new SparkMD5.ArrayBuffer()const reader new FileReader()const chunkSize this.chunkSizeconst chunks Math.ceil(file.size / chunkSize)let currentChunk 0const loadNext () {const start currentChunk * chunkSizeconst end Math.min(start chunkSize, file.size)reader.readAsArrayBuffer(file.slice(start, end))}reader.onload e {spark.append(e.target.result)currentChunkif (currentChunk chunks) {loadNext()} else {resolve(spark.end())}}loadNext()})},async getUploadedChunkIndexes (fileHash) {// try {// const res await axios.get(/api/commonFileUtil/commonUploadByModule/\({this.module}/status, {// params: { fileHash }// })// return res.data.data.uploaded || []// } catch (e) {// return []// }return new Promise((resolve, reject) {request({url: /api/commonFileUtil/commonUploadByModule/\){this.module}/status?fileHash\({fileHash},method: GET}).then((res) {if (res res.data Array.isArray(res.data.uploaded)) {resolve(res.data.uploaded)} else {// 兜底避免不是数组时报错resolve([])}}).catch((err) {reject([])})})},async uploadChunk ({ chunk, fileHash, chunkIndex, totalChunks, fileName }) {const formData new FormData()formData.append(file, chunk)formData.append(fileHash, fileHash)formData.append(chunkIndex, chunkIndex)formData.append(totalChunks, totalChunks)formData.append(fileName, fileName)return new Promise((resolve, reject) {request({url: /api/commonFileUtil/commonUploadByModule/\){this.module},method: post,data: formData,}).then((res) {resolve(res.data)}).catch((err) {reject(err)})})},async mergeChunks (fileHash, fileName) {return new Promise((resolve, reject) {request({url: /api/commonFileUtil/commonUploadByModule/${this.module}/merge,method: post,data: {fileHash,fileName},}).then((res) {resolve(res.data)}).catch((err) {reject(err)})})}} } /scriptstyle scoped .upload-wrapper {padding: 20px;border: 1px dashed #999;border-radius: 10px;width: 400px; } /style 前端流程 [前端] → 1. 计算 fileHash → 2. 查询 status 接口获取已上传分片 → 3. 上传分片附带 index/hash/total → 4. 上传完成后调用 merge 接口
- 上一篇: 企业网站制作费做分录中国制造网
- 下一篇: 企业网站制作哪家好logo商标设计
相关文章
-
企业网站制作费做分录中国制造网
企业网站制作费做分录中国制造网
- 技术栈
- 2026年03月21日
-
企业网站诊断做wordpress 主题下载站
企业网站诊断做wordpress 主题下载站
- 技术栈
- 2026年03月21日
-
企业网站怎做如何做网站淘宝客
企业网站怎做如何做网站淘宝客
- 技术栈
- 2026年03月21日
-
企业网站制作哪家好logo商标设计
企业网站制作哪家好logo商标设计
- 技术栈
- 2026年03月21日
-
企业网站制作排名wordpress 数据库填写
企业网站制作排名wordpress 数据库填写
- 技术栈
- 2026年03月21日
-
企业网站制作设网站开发定制模板网站建设
企业网站制作设网站开发定制模板网站建设
- 技术栈
- 2026年03月21日






