
Wipi 文件上传与 OSS 存储实战阿里云 OSS 客户端抽象封装的设计思路【免费下载链接】wipiA blog system written by next.js, nest.js and MySQL.项目地址: https://gitcode.com/gh_mirrors/wi/wipiWipi 是一个基于 next.js、nest.js 和 MySQL 的开源博客 CMS 系统内置完整的文件上传与阿里云 OSS 对象存储能力。这篇文章面向新手带你拆解 Wipi 文件上传的设计思路它如何用一层很薄的抽象封装把 OSS 存储配置得干净、可扩展让你快速看懂一个博客系统里对象存储是怎么集成起来的。为什么博客系统要把文件上传到 OSS 写博客时几乎离不开插图。如果把图片都存在服务器本地会遇到两个问题扩容困难服务器磁盘容量有限图片多了就得换机器没有 CDN 加速图片直接走源站访问速度慢。对象存储OSSObject Storage Service解决了这些问题文件存在云上通过 URL 直接访问还能配合 CDN 加速。Wipi 选择了阿里云 OSS 作为默认存储并在后台管理端提供了专门的文件管理页面支持上传、检索和删除文件。Wipi 文件上传链路从后台界面到云端存储 整个上传链路可以分为四层每层各司其职后台上传组件Upload.tsx 提供拖拽上传界面调用接口把文件发出去文件控制器file.controller.ts 定义upload接口并限制单文件最大 50MB文件服务file.service.ts 负责生成存储路径、调用 OSS 上传、把文件元信息写入数据库OSS 工具层oss.util.ts 读取配置、选择具体存储客户端真正执行上传和删除。新手只需要记住一句话界面和数据库都不直接碰 OSS一切都经过统一的工具层这就是后面抽象封装发挥作用的地方。核心设计用抽象类统一所有存储接口 打开 oss-client.ts你会看到一个只有几行的抽象类OssClient它声明了两个抽象方法putFile(filepath, buffer)上传文件返回文件的访问 URLdeleteFile(url)删除云端文件。这就是经典的依赖倒置思路上层代码比如文件服务只依赖OssClient这个接口约定而不关心底层到底是阿里云、腾讯云还是别的对象存储。好处非常直接可替换换存储厂商业务代码一行不用改可测试测试时可以轻松塞入一个假的客户端实现可读性强新人读代码时一眼就能看出这里要存文件而不用被具体 SDK 的细节干扰。阿里云 OSS 客户端的实现要点 ☁️aliyun-oss-client.ts 是唯一的具体实现它继承OssClient做三件事按需构建客户端buildClient()从配置中取出region、accessKeyId、accessKeySecret、bucket等参数创建ali-oss实例。每次操作都重新构建意味着后台改了配置立刻生效无需重启服务上传putFile调用client.put()把 OSS 返回的 URL 透传给上层删除deleteFile根据 URL 删除云端文件。整个文件不到 30 行这就是薄封装的价值——复杂的事情交给官方 SDK自己只负责把参数接好。配置驱动OSS 参数从哪里来 ⚙️oss.util.ts 中的getConfig()从系统设置表读取oss字段一段 JSON再根据其中的type字段做分发目前是aliyun类型就返回AliyunOssClient实例如果配置缺失直接抛出OSS 配置不完善的友好错误。对应的后台界面是 OSSSetting管理员用 JSON 编辑器填写如下结构即可{ type: aliyun, accessKeyId: 你的 AccessKeyId, accessKeySecret: 你的 AccessKeySecret, bucket: 你的 Bucket 名, region: oss-cn-shanghai, https: true }这种配置存在数据库、运行时读取的设计让部署环境和运行参数解耦同一份代码可以部署到任意环境OSS 参数在后台页面随时修改。文件命名策略日期 唯一 ID永不重名 ️file.service.ts 中有一段很实用的路径设计上传路径形如/2021-06-12/3402/image.png以日期做一级目录方便按时间归档开启unique参数时再插入一个由 uniqueid.util.ts基于nuid生成提供的唯一 ID 目录彻底避免同名文件互相覆盖上传成功后文件原名、存储路径、URL、MIME 类型、大小都会记录到 file.entity.ts 定义的file表中删除文件时deleteById会同时清理 OSS 云端文件和数据库记录不留垃圾。新手上手最快跑起 Wipi 并配置阿里云 OSS 克隆仓库git clone --depth1 https://gitcode.com/gh_mirrors/wi/wipi wipi按 README 用 docker 启动 MySQL 并创建wipi数据库配置.env中的数据库连接执行pnpm install和pnpm run dev访问http://localhost:3002进入管理后台默认账号 admin / admin在「系统设置」中填入上面的 OSS JSON 配置并保存打开「文件管理」页面拖入一张图片成功后复制 URL即可在文章编辑器中插入。想换成其他云厂商只需两步 ✨得益于这套抽象封装扩展存储厂商的成本极低第一步参照 aliyun-oss-client.ts 新建一个类继承OssClient并实现putFile与deleteFile第二步在 oss.util.ts 的switch中加一个case让新的type值返回你的新客户端。配置 JSON 里加上对应的密钥字段即可业务层和后台界面无需任何改动。小结Wipi 的文件上传方案虽然代码量很小却把工程上的关键点都占全了抽象类统一接口、配置驱动运行时选择实现、按日期归档的文件命名、云端与数据库的同步删除。对于刚学习 nest.js 或对象存储集成的同学来说这 5 个文件oss-client.ts、aliyun-oss-client.ts、oss.util.ts、file.controller.ts、file.service.ts就是一份非常干净的教学示例值得照着理解也值得照着重构自己的项目。【免费下载链接】wipiA blog system written by next.js, nest.js and MySQL.项目地址: https://gitcode.com/gh_mirrors/wi/wipi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考