缘起
几个管理系统做完,我回头看了一眼:登录、JWT、RBAC、操作日志、字典、Excel 导入导出,每个项目都重写了一遍,而且每一遍写得都不太一样。结果是同一个 bug 我要在三个仓库里各修一次,改一处响应格式要翻四份文档。
这套基座就是那次盘点剩下的东西。它不含任何业务,只装「每个管理系统都得有、且不该长得不一样」的那部分:协议、鉴权、权限、日志,加上把这几条钉死的护栏测试。新项目 clone 下来改个名字就能开工,业务模块从一份黄金范例生成,不用谁再凭记忆手抄一遍。
背景
管理系统之间的差异其实都在业务层,横切的那部分高度一致:controller / service / model 怎么分层,统一响应体和分页体长什么样,JWT 走哪个头,权限码按什么粒度落库,操作日志记哪些字段,菜单和字典怎么配,导入导出的模板从哪来。这些东西没有一份统一定义时,落到代码里就是四种写法,之后只能靠人去对齐。要沉淀的就是这一层:与业务无关、可复用,并且把约定写成违反即失败的检查,作为后续所有业务项目的起点。
方案
构建四端一体(Go 后端 + Web 前端 + 移动端 H5 + 微信小程序)的脚手架基座,四端共享同一套协议与工程铁律,并由架构护栏强制约束:
- 统一响应协议:
{code, message, data},分页{list, total, page, page_size} - 统一鉴权:JWT(
Authorization: Bearer <token>),401/403 由前端拦截器统一处理 - RBAC 权限:用户-角色-权限三级模型,受保护路由挂
PermissionRequired("<资源>:<动作>") - 操作日志:
OperationLogger中间件自动记录受保护路由的操作与登录日志 - 系统管理五件套:用户 / 角色 / 权限 / 字典 / 操作日志,开箱即用
- 品牌可配置:config 的
app段驱动四端登录页、标题与页脚,静态资源经/api/system/info下发 - 架构护栏:后端
internal/guard/与根eslint.config.js把铁律编译成「违反即测试 / Lint 失败」的静态检查 - 依赖登记制:
deps.yaml与各端清单双向校验,漏登记或僵尸条目即失败
新增业务模块无需手写骨架,make gen name=<模块> 从唯一范例 _example/ 生成全套骨架并自动接线。
技术架构
| 模块 | 技术选型 |
|---|---|
| 后端 | Go + Gin + GORM |
| Web 前端 | Vue3 + Element Plus + Pinia |
| 移动端 | Vue3 + Vant + Pinia |
| 小程序端 | uniapp + Vue3 + Pinia |
| 数据库 | SQLite(WAL)/ MySQL 双驱动 |
| 鉴权 | JWT + RBAC 权限码两级中间件 |
| 工程 | Makefile 统一入口 + 架构护栏测试 + 依赖登记制 |
采用 controller → service → model 三层分层,默认值 → YAML → 环境变量三层配置,一键打包为单进程可部署形态(后端自动托管 Web 与移动端产物)。
成果
从企业固定资产管理系统中提炼出与业务无关的可复用横切能力,形成可运行的四端 monorepo 骨架:clone 后 make init name=my-system 一键改名即可开发新项目,make gen name=<模块> 从黄金范例生成业务模块,make test/lint/smoke 靠护栏与冒烟证明「没改坏」。多个后续业务项目(公车管理、出租订单等)均基于此基座快速起盘,统一了协议、鉴权与工程约定。
体验
基座已部署,可在线体验(默认账号 admin / admin123):
- 在线体验:base.bennywen.xyz
