mldong 快速开发框架分片上传模块设计与实现

180 阅读4分钟

在现代 Web 开发中,文件上传是常见的需求。对于大文件上传场景(如视频、日志、镜像等),传统单次上传方式存在性能瓶颈和失败风险。为了解决这一问题,mldong 快速开发框架 引入了 分片上传(Multipart Upload) 模块,通过将大文件拆分成多个小块进行上传,提升稳定性和用户体验。

本文将从整体架构、接口设计、前端组件实现、后端服务支撑等多个维度,全面解析 mldong 分片上传模块的设计与实现。


一、分片上传的整体流程

分片上传的核心思想是:将一个大文件分割成多个小片段分别上传,最后在服务器上合并所有片段,形成完整的文件。其核心步骤如下:

  1. 初始化分片上传任务
  2. 依次上传每个分片
  3. 完成上传并合并文件
  4. 取消上传或失败处理

我们可以使用 PlantUML 绘制流程图来清晰表达整个交互过程:


二、接口设计(后端)

1. 初始化分片上传

@PostMapping("/sys/fileInfo/initiateMultipartUpload")
public CommonResult<Dict> initiateMultipartUpload(@RequestBody FileInfoParam param);
  • 功能说明:创建一个上传会话,返回 uploadId fileInfoId
  • 请求参数
    • originalFilename: 原始文件名
    • objectType: 文件类型标识
    • contentType: MIME 类型
    • size: 文件总大小
  • 响应示例
{
    "code": 0,
    "msg": "成功",
    "data": {
        "fileInfoId": "1938914498327797762",
        "uploadId": "685fca7635f9b439503acdb2"
    }
}

2. 上传单个分片

@PostMapping("/sys/fileInfo/uploadPart")
public CommonResult<?> uploadPart(MultipartFile file, @RequestParam Integer partNumber, @RequestParam Long fileInfoId);
  • 功能说明:上传指定序号的分片
  • 请求参数
    • partNumber: 分片序号(从 1 开始)
    • fileInfoId: 文件 ID,在第一步中返回
    • file: 当前分片数据
  • 响应示例
{
    "code": 0,
    "msg": "成功",
    "data": null
}

3. 完成分片上传

@PostMapping("/sys/fileInfo/completeMultipartUpload")
public CommonResult<Dict> completeMultipartUpload(@RequestBody FileInfoParam param);
  • 功能说明:通知服务端合并所有分片
  • 请求参数
    • fileInfoId: 文件 ID,在第一步中返回
  • 响应示例
{
    "code": 0,
    "msg": "成功",
    "data": {
        "fullUrl": "/api/uploadfiles/mldong/202506/1938914498327797762.pdf",
        "url": "mldong/202506/1938914498327797762.pdf",
        "fileInfoId": "1938914498327797762"
    }
}

4. 取消分片上传

@PostMapping("/sys/fileInfo/abortMultipartUpload")
public CommonResult<?> abortMultipartUpload(@RequestBody FileInfoParam param);
  • 功能说明:中断当前上传过程,清理服务器上的临时文件
  • 请求参数
    • fileInfoId: 文件 ID,在第一步中返回
  • 响应示例
{
    "code": 0,
    "msg": "成功",
    "data": null
}

三、前端组件实现(Vue + Ant Design Vue)

在前端,我们基于 Ant Design Vue 的 Upload 组件 进行封装,实现了对分片上传的支持,并提供了良好的交互体验。

1. 核心组件结构

<template>
  <Upload
    v-model:file-list="fileList"
    :action="action"
    :before-upload="beforeUpload"
    @change="handleChange"
    @remove="handleRemove"
  >
    <!-- 自定义按钮 -->
    <Button :loading="isUploading">上传文件</Button>
  </Upload>
  <!-- 分片进度条 -->
  <div v-if="isUploading" class="upload-progress">
    <div class="progress-bar" :style="{ width: `${uploadProgress}%` }"></div>
    <div class="chunk-item" v-for="i in totalChunks" :key="i" :class="{ completed: i <= currentChunk }"></div>
  </div>
</template>


2. 分片上传逻辑封装

(1) 初始化上传会话

const initializeChunk = async (file: File) => {
  const initData = {
    contentType: file.type,
    originalFilename: file.name,
    objectType: props.objectType,
    size: file.size.toString(),
  };
  return await initiateMultipartUpload(initData);
};

(2) 切分文件为多个分片

const createFileChunks = (file: File) => {
  const chunks = [];
  let start = 0;
  let index = 0;
  totalChunks.value = Math.ceil(file.size / props.chunkSize);

  while (start < file.size) {
    chunks.push({
      chunk: file.slice(start, start + props.chunkSize),
      index,
    });
    start += props.chunkSize;
    index++;
  }
  return chunks;
};

(3) 上传每个分片

const uploadChunk = async (chunk: Blob, filename: string, uploadId: string, fileInfoId: string, index: number) => {
  await uploadPart({
    partNumber: index + 1,
    uploadId,
    fileInfoId,
    file: new File([chunk], filename),
  });
  currentChunk.value = index + 1;
  uploadProgress.value = Math.round(((index + 1) / totalChunks.value) * 100);
};

(4) 完成上传并合并文件

const completeRes = await completeMultipartUpload({
  uploadId: uploadId.value,
  fileInfoId,
});

3. 组件使用样例

样例是在vben5框架下的,这里简单的配置

主要是:multipart设置为true,则启用分片上传。

{
      fieldName: 'attachment1',
      label: '附件',
      component: 'Upload',
      help: '分片上传',
      componentProps: {
        listType: 'text',
        multipart: true,
      },
      formItemClass: 'col-span-12',
      detailSpan: 12,
}

四、优势总结

特性描述
✅ 支持大文件上传突破浏览器上传限制,支持 GB 级文件
⚙️ 断点续传基础支持分片机制天然支持断点续传扩展
📈 实时进度展示提供分片级和总体进度条可视化
🔄 失败自动中断上传异常自动调用 abortMultipartUpload 清理资源
📦 易于集成基于 Vue + Ant Design Vue 封装,开箱即用

五、结语

随着企业数字化转型的加速,文件上传作为系统交互的重要环节,其稳定性与效率至关重要。mldong 快速开发框架 中的分片上传模块,不仅解决了大文件上传的技术难题,还通过前后端协同设计,实现了良好的用户体验与可维护性。

未来,我们将继续优化该模块,计划引入以下特性:

  • ✅ 分片缓存与断点续传
  • ✅ 多线程并发上传
  • ✅ 秒传支持(MD5校验)
  • ✅ 跨域支持与安全控制

如果你正在寻找一套高效、易用、可扩展的文件上传解决方案,欢迎尝试 mldong!


📌 项目地址

后端源码:gitee.com/mldong/mldo…

前端源码:gitee.com/mldong/mldo…

组件地址:gitee.com/mldong/mldo…

演示站:antd-vben5.mldong.com/

目前放在【系统管理】->【岗位管理】的第一个【附件】字段上。

注:演示站非只是apifox的模拟接口,非真实上传,如要完整体验,需要下载前端端工程体验。