Acme Harmony UI Design System
Components / Data Entry

直传 OSS 上传与附件 (AcmeUpload)

规范了基于客户端直传 OSS 的文件上传组件调用规范、大附件切片断点续传、成功回调参数落库优先原则及避免内存泄露的重置机制。

组件源文件: wwwroot/js/components/acme.upload.js 最后更新: 2026-05-28
01 / Overview

为什么采用直传 OSS?

与传统的后端服务器中转上传不同,AcmeUpload 直接在浏览器中利用生成的临时 STS 凭证向阿里云 OSS 发起分片和传输。这减轻了应用服务器的带宽压力,同时支持大文件(GB级别)的断点续传,并在完成上传后触发回调通知应用后台完成存储归档。

重置红线

在弹窗或抽屉反复打开渲染上传组件时,必须在初始化前调用 AcmeUpload.reset(selector),以清理旧的 WebUploader 实例与事件监听,杜绝按钮重复渲染产生及内存泄漏!

02 / Source Code Mapping

组件源码与标准入口

本模块的高级组件直接与仓库内核心封装挂钩,在调用前必须核对映射关系:


AcmeUpload 直传组件

基于 WebUploader 封装,无缝整合阿里云 OSS 分片与回调。

源文件路径: wwwroot/js/components/acme.upload.js 标准入口: AcmeUpload.init(selector, options, successCallback, finishCallback)
参数名 (Option) 类型 必填 默认值 详细功能与规范说明
path String - OSS 存储的相对业务目录,如 'RecruitmentDemandAttachments'。务必对齐存储规范,禁止混乱放置。
bucket String 'xy-scm1' 指定阿里云 OSS 存储桶名称。
multiple Boolean false 是否允许多文件同时上传。
fileNumLimit Number 10 多文件上传时的最大数量上限。
fileSingleSizeLimit Number 52428800 单个文件的大小限制,默认 50MB (以 Byte 为单位)。
limitExt String - 格式限制白名单,如 '.pdf,.doc,.docx,.xlsx,.png,.jpg'。禁止允许可执行文件如 .exe,.bat,.sh
showProgress Boolean true 是否展示进度条组件。

成功回调签名极其参数映射

// 成功回调方法:
function successCallback(target, realFileName, fileUrl, fileThumbUrl, response, saveUrl) { ... }
参数名 典型内容示例 存储规范与业务含义说明
target '#myUploader' 当前上传控件容器选择器。
realFileName '简历明细.pdf' 上传文件的原始文件名称。可在业务界面展示供用户核对。
fileUrl 'https://xy-scm1.oss-cn-hangzhou.aliyuncs.com/Recruitment/x.pdf' 文件的绝对完整外网访问链接。
fileThumbUrl 'https://.../x.pdf?x-oss-process=image/resize...' 针对图片生成的标准小略缩图地址,供预览。非图片文件该字段通常为空或为通用文件占位图标。
saveUrl 'Recruitment/x.pdf' 核心落库优先路径。不带协议域名的纯相对路径。业务数据库存储一律强制落库 saveUrl 字段。禁止在数据库落 fileUrl,防止未来 OSS 域名重构切换时引发海量数据死链!
03 / Layout Code

标准上传排版布局与联动

包含进度条展示、重置及多文件上传的典型布局实现,可直接全量复制修改:


将简历或表格拖拽至此区域,或 选择本地文件
支持 PDF, DOC, XLSX 格式,大小不超过 50MB
<!-- 1. Razor 结构 -->
<div class="form-group col-md-12">
    <label class="required">项目附件清单</label>
    <div id="myUploader" class="webuploader-container modern-upload">
        <div class="upload-area">
            <i class="fal fa-cloud-upload-alt"></i>
            <span class="upload-title">拖拽文件到此处或 <a class="upload-button">选择文件</a></span>
            <span class="upload-desc">支持 .pdf, .docx, .xlsx,单个文件大小不超过 50MB</span>
        </div>
        <!-- Bootstrap 动态进度条 -->
        <div class="progress d-none" id="myProgressBar" style="height: 4px; margin-top: 8px;">
            <div class="progress-bar progress-bar-striped progress-bar-animated bg-success" role="progressbar" style="width: 0%"></div>
        </div>
    </div>
    <!-- 数据库保存值输入框 (通常设为 hidden) -->
    <input type="hidden" id="attachmentPathInput" name="attachmentPath" required />
    <!-- 附件成功上传展示栏 -->
    <div class="attachment-preview-box d-none" id="attachmentPreviewBox">
        <div class="file-card d-flex align-items-center justify-content-between p-2 mt-2 border rounded">
            <span class="file-name text-dark font-weight-medium"><i class="fal fa-file-pdf mr-2"></i><span id="lblFileName">文件名.pdf</span></span>
            <button type="button" class="btn btn-xs btn-link text-danger" onclick="clearAttachment()"><i class="fal fa-trash-alt"></i></button>
        </div>
    </div>
</div>

<script>
$(function () {
    initAttachmentUploader();
});

function initAttachmentUploader() {
    // 每次重新初始化前强制重置,防止重复创建 WebUploader 造成内存泄露与多按钮错位
    AcmeUpload.reset('#myUploader');

    AcmeUpload.init('#myUploader', {
        path: 'RecruitmentDemandAttachments',
        multiple: false,
        fileSingleSizeLimit: 50 * 1024 * 1024,
        limitExt: '.pdf,.doc,.docx,.xlsx,.png,.jpg'
    }, function (target, realFileName, fileUrl, fileThumbUrl, response, saveUrl) {
        // 成功回调:必须将 saveUrl 赋值给隐藏域
        $('#attachmentPathInput').val(saveUrl);
        
        // 渲染附件卡片
        $('#lblFileName').text(realFileName);
        $('#attachmentPreviewBox').removeClass('d-none');
        $('#myProgressBar').addClass('d-none');
        Msg.Success('提示', '文件直传成功');
    }, function () {
        console.log('队列所有上传任务已处理完毕');
    });
}

function clearAttachment() {
    $('#attachmentPathInput').val('');
    $('#attachmentPreviewBox').addClass('d-none');
    // 重置上传队列,保证能够二次选取相同文件
    initAttachmentUploader();
}
</script>
04 / Do & Don't

设计红线与准则

正确设计准则 (Do)

  • 必须以 saveUrl (如 recruit/res.pdf) 格式在数据库归档,防止阿里云 Bucket 迁移时域名改变导致大面积死链。
  • 上传之前必须做文件后缀校验,并在 limitExt 明确只开放办公或图片类后缀。
  • 清除已有附件时,在清空文本框的同时必须执行初始化重置函数,以释放之前绑定的切片上传句柄。

错误设计准则 (Don't)

  • 禁止绕开前端切片直传,私自在后端写 HttpPostedFile 接收方法,以避免高并发上传卡死服务器 IIS 进程。
  • 禁止空置 path 属性,以防所有业务的附件在阿里云 Bucket 根目录混成一团。
  • 禁止对于压缩包、图片以及 PDF 统统使用千篇一律的文件图标展示,应读取后缀进行类型特异化小图标区分。
代码复制成功!已写入剪贴板