我又把自己的 Go 后台管理系统升级了一遍:文件管理、2GB 上传、私有文件预览、Docker 镜像全安排上了

欢迎大家提 https://github.com/Rodert/ShiyuAdmin/issues

大家好,我是 JavaPub。

最近又抽时间折腾了一下自己的开源项目 ShiyuAdmin。

项目地址:

https://github.com/Rodert/ShiyuAdmin/

在这里插入图片描述

ShiyuAdmin 是我自己维护的一套通用后台管理系统,目前技术栈主要是:

  • Go
  • Gin
  • Gorm
  • React
  • Ant Design Pro
  • RBAC
  • PostgreSQL
  • Redis
  • Docker

最开始做它的时候,我的想法其实很简单:

以后再做管理后台,别每次都从登录、用户、角色、菜单、权限这些东西重新写一遍。

所以慢慢把用户管理、角色管理、菜单权限、部门管理、动态菜单、接口权限、操作日志、Redis 管理、系统监控、数据管理这些东西都加了进去。

但随着自己真正拿它去做项目,我越来越发现:

一个后台框架想真正“拿来就用”,光有 RBAC 还远远不够。

所以最近又集中更新了一波。

这次我重点解决了几个我自己在实际项目里经常遇到的问题。


一、终于加入了完整的文件管理

这次比较大的一个更新,就是给 ShiyuAdmin 加了一套真正的 文件管理模块。

这不是简单写一个:

POST /upload

然后把文件扔到某个目录里就结束了。

我希望从一开始就把文件当成一个独立的基础设施来设计。

所以这次新增了两个核心模型:

StorageConfig
MediaFile

也就是:

存储配置
    ↓
文件元数据
    ↓
实际存储对象

文件本身和存储后端是分开的。

目前默认提供本地存储,初始化时会自动创建:

本地存储
Driver: local
BasePath: ./data/uploads

但数据模型里已经预留了:

local
s3
oss

以及:

Endpoint
Bucket
PublicURL
AccessKey
SecretKey

这些字段。

这意味着后面要接:

AWS S3
Cloudflare R2
阿里云 OSS
腾讯云 COS
MinIO

实际上就比较顺了。

我不太喜欢那种一开始把文件上传路径硬编码死,后面要上对象存储的时候再推倒重来的做法。

既然是通用后台,就应该尽量把扩展能力提前留出来。


在这里插入图片描述

二、文件不只是上传,还要能真正“管理”

有了存储还不够。

后台里现在已经加入了完整的文件列表和管理能力。

包括:

文件列表
文件搜索
分页
上传
下载
删除
回收站
恢复

而且这里的删除并不是直接物理删除。

我用了软删除的方式,把删除后的文件放进“回收站”。

对应接口也拆开了:

GET    /files
GET    /files/recycle-bin

POST   /files/upload

GET    /files/:code/download

DELETE /files/:code

POST   /files/:code/restore

这样用户误删文件以后,还有机会恢复。

文件记录里面也不只是保存一个路径,而是记录了:

FileCode
StorageID
OriginalName
ObjectKey
MimeType
Size
SHA256
AccessLevel
UploaderCode

比如 SHA256 后面可以继续做:

文件校验
重复文件判断
内容寻址
安全扫描

这些东西。

这也是我现在做 ShiyuAdmin 一个比较明确的思路:

不只是把页面做出来,而是尽量把以后真正做业务需要的扩展空间留出来。


三、文件权限也接进了 RBAC

既然 ShiyuAdmin 本身就是一个 RBAC 后台,那么文件系统肯定不能自己另搞一套权限。

所以这次直接把文件管理接进了原来的权限体系。

目前主要拆成:

system:file:list
system:file:upload
system:file:delete

也就是说可以做到:

A 角色只能查看文件

B 角色可以查看 + 上传

C 角色拥有查看 + 上传 + 删除权限

而不是只要登录后台,就能随便上传和删除。

很多后台系统一开始文件上传只是一个辅助功能。

但随着业务越来越复杂,合同、图片、Excel、PDF、附件、视频全部往里面塞以后,文件本身其实已经变成非常重要的一类业务数据。

这时候权限就不能再靠前端“隐藏一个按钮”来解决了。

接口权限必须一起做。


四、单文件上传直接放到了 2 GiB

这个更新其实还有一个挺有意思的小坑。

文件模块刚做完的时候,应用层虽然支持大文件,但部署以后发现:

Nginx 先把请求拦了。

所以后面又专门提交了一次修复:

fix: allow 2GiB multipart uploads

在 Nginx 层增加了:

client_max_body_size 2050m;

为什么不是刚好 2048m?

因为 multipart/form-data 本身还有 boundary 等额外数据,需要留一点空间。

后端本身也做了大小限制:

const maxUploadSize int64 = 2 << 30

并通过 MaxBytesReader 控制请求大小。

所以现在单文件最大可以做到:

2 GiB

图片、PDF、压缩包,甚至一些视频文件都基本够用了。

这个地方也算一个挺典型的工程问题:

一个功能“代码支持”,不代表真正部署出去以后就支持。

中间可能还有:

浏览器
CDN
Cloudflare
Nginx
网关
后端框架
应用服务器
对象存储

任何一层限制都可能导致上传失败。


五、私有文件终于可以在线预览了

文件管理做好以后,我很快又遇到一个问题。

如果文件是私有的,直接把 URL 塞给浏览器并不合适。

因为它需要经过登录鉴权和 RBAC 权限校验。

于是又加了一次提交:

feat: preview private media files

后端新增:

GET /files/:code/preview

并且仍然要求:

system:file:list

权限。

前端不会直接暴露一个裸文件地址,而是带着 Bearer Token 请求文件,然后拿到 Blob,再创建临时 URL 用来展示。

目前支持的在线预览包括:

图片
PDF
文本文件

图片直接展示;

PDF 和文本可以通过 iframe 预览;

其他暂时不支持的格式则提示用户下载查看。

这个设计我个人还是比较喜欢的。

因为:

登录鉴权
    ↓
RBAC 权限验证
    ↓
读取文件
    ↓
返回 Blob
    ↓
浏览器临时预览

整个链路仍然在后台的权限控制范围内。

而不是为了图方便,把原本应该是私有的文件变成公开 URL。


在这里插入图片描述

六、另外一个小功能:主题偏好

这一波更新里还顺手完善了后台的主题偏好。

这个功能相比文件管理当然不算大,但对于一个每天都要打开的后台来说,体验还是挺重要的。

后台系统和普通网站不太一样。

很多运营、管理员、开发人员可能一天要盯着它几个小时。

所以类似:

主题
布局
界面偏好

这些东西我后面也会继续完善。

这类功能单独拿出来没什么惊艳的,但一个成熟后台往往就是由这些“小东西”一点点堆出来的。


七、这次我更在意的,其实是 Docker 部署

除了业务功能,这次我还重新整理了一遍整个项目的 Docker 部署方式。

这部分我觉得反而非常重要。

以前很多开源后台都是:

git clone

然后:

npm install
npm run build

go build

docker build

服务器自己从源码开始折腾。

这种方式开发阶段没问题。

但是部署多了以后真的很烦。

所以这次我直接做了一套 统一应用镜像。


八、前端 + 后端打成一个镜像

现在根目录增加了一个多阶段 Dockerfile。

整个构建过程大致是:

Node 20
   ↓
构建 React 前端

Go 1.23
   ↓
编译 Go Backend

Nginx Alpine
   ↓
放入前端静态文件

Supervisor
   ↓
同时管理 Nginx + Go API

也就是说:

React
+
Go API
+
Nginx
+
Supervisor

最终全部变成:

一个 Docker Image

而不是服务器上跑一堆分散的东西。

这样以后部署的时候简单很多。


九、GitHub Actions 自动构建 GHCR 镜像

这个是我这次比较喜欢的一个改动。

现在每次 Push 代码,GitHub Actions 都可以自动:

Checkout
    ↓
Docker Build
    ↓
生成镜像
    ↓
Push 到 GHCR

也就是:

GitHub Container Registry

对应镜像:

ghcr.io/<owner>/<repo>

Action 会自动生成多种标签,包括:

branch
tag
sha-xxx
YYYYMMDD-HHmmss
latest

其中默认分支会额外维护 latest。

这样服务器以后根本不用再编译项目。

只需要:

docker compose pull
docker compose up -d --no-build

就行了。

整个发布流程变成:

我 Push GitHub
        ↓
GitHub Actions
        ↓
构建 ShiyuAdmin Image
        ↓
GHCR
        ↓
服务器 docker pull
        ↓
启动

这才是我比较喜欢的开源项目部署方式。


在这里插入图片描述

十、为什么我要把本地 Compose 和线上部署拆开?

另外我还专门做了一次:

chore: separate local compose and disable auto fly deploy

把:

docker-compose.local.yml

和正式部署配置区分开。

同时 Fly.io 不再跟着每次 main push 自动部署,而是改成手动触发。

原因也很简单。

以前一个仓库同时承担:

开发环境
测试环境
演示环境
线上环境
镜像发布

很容易越做越乱。

现在我的思路逐渐变成:

源码
    ↓
CI Build
    ↓
标准 Docker Image
    ↓
不同环境自己决定怎么运行

GHCR 负责“发布镜像”。

Fly.io、自己的服务器、云服务器等则只是不同的“运行环境”。

这样两件事情就解耦了。

我认为这比“GitHub 一 Push 就自动把某台服务器更新掉”更加适合作为一个公共开源项目的默认方案。


十一、现在的 ShiyuAdmin 到什么程度了?

如果把最近几个月加进去的东西放到一起,现在基本已经有:

用户管理
角色管理
菜单管理
部门管理

RBAC 权限
动态菜单
接口权限
数据权限

个人中心
登录日志
操作日志

Redis 缓存管理
数据管理
系统监控

Dashboard
访问态势
可视化图表

文件管理
文件上传
文件下载
文件预览
文件回收站
存储配置

Docker Compose
统一应用镜像
GitHub Actions
GHCR 自动发布

项目本身采用前后端分离架构,后端是 Go + Gin + Gorm,前端是 React + Umi Max + Ant Design Pro;README 目前也已经把它定位成适合快速搭建中后台、学习 RBAC 或作为新业务基础脚手架的通用后台系统。

所以现在我自己也不太愿意把它单纯定义成一个:

“Go 后台管理系统 Demo”。

我更希望它慢慢变成一个:

真正能拿来作为新项目基础工程的后台底座。


十二、接下来还会继续加什么?

文件系统现在只是第一版。

从目前的数据结构其实已经能看出来,我后面比较想继续做:

Cloudflare R2
AWS S3
MinIO
阿里云 OSS
腾讯云 COS

这类对象存储。

然后继续完善:

文件分类
目录
批量操作
图片缩略图
视频预览
文件引用关系
存储空间统计
上传进度
分片上传
断点续传

另外还有一个方向,是继续降低部署成本。

理想状态就是:

docker compose up -d

甚至:

docker run ...

就能得到一整套可以直接开发业务的后台。


最后

我一直觉得:

自己维护一个开源项目,最有意思的地方其实并不是一次性写出多少代码。

而是你真的拿它去做项目以后,会不断发现:

这里还不够方便
那里不够安全
这个地方不好部署
那个功能缺了一块

然后一点一点补上。

ShiyuAdmin 也是这样。

它不是某一天突然写出来的,而是在我自己的实际开发过程中,一点点长出来的。

如果你最近正好在学:

Go
Gin
Gorm
React
Ant Design Pro
RBAC
Docker
GitHub Actions

或者正准备做一个自己的后台管理系统,可以拿去参考或者直接改。

项目完全开源。

GitHub:

https://github.com/Rodert/ShiyuAdmin/

觉得项目还不错的话,也欢迎给个 Star。

有 Bug、功能建议,也欢迎直接提 Issue。

我还会继续更新。

一起成为勇猛精进的人类。

posted @ 2026-08-11 21:04  JavaPub  阅读(10)  评论(0)    收藏  举报