Java 接单脚手架模板工程(Spring Boot 3.5 / JDK 17 / MyBatis-Plus / Sa-Token / MySQL 8 / Redis)。
一条 cookiecutter 命令生成带 RBAC、文件上传、监控等完整底座的新项目;模板仓自身即合法
Maven 项目(117 项单测),make all 一键完成纪律检查 + 编译 + 冒烟 + 防漂移。
pip install cookiecutter # 一次性
cookiecutter /path/to/cookiecutter-java-scaffold # 交互式(或 gh:<you>/cookiecutter-java-scaffold)生成时回答项目名(如 demo app)即得 demo_app/(包名 com.example.demo_app 由 post_gen 钩子确定性
重写)。生成后四步(详见生成项目内 README):
- 建库并执行
sql/schema.sql+sql/data.sql - 复制
src/main/resources/application-local.yml.example→application-local.yml,填写真实凭证(已 gitignore) mvn spring-boot:run- 打开
http://localhost:8080/swagger-ui/index.html(默认账号admin / admin123)
| 模块 | 内容 | 可裁剪 |
|---|---|---|
| common | 统一响应 R/TableDataInfo、全局异常、@Log 注解、LogEvent、工具类 | 否(地基) |
| framework | Sa-Token / MyBatis-Plus / Redis / springdoc / Druid / CORS / 异步线程池配置,@Log 切面,示例定时任务 | 否(地基) |
| modules/system | 用户/角色/菜单/部门/字典/参数/登录日志/操作日志、StpInterfaceImpl(RuoYi-Vue3 v3.9.2 契约) | 否(核心) |
| modules/member | C 端接口模板(StpMemberUtil 双账号体系 + TODO 语义接单指南) | 部分(SaTokenConfig 引用其 StpMemberUtil,需连配置同改) |
| modules/file | 文件上传(Storage 接口 + 本地实现 + OSS 预留) | 是 |
| modules/tool | Excel 导入导出示例 | 是(M10 实证:整删后 mvn compile 通过) |
| modules/monitor | 服务器监控(CPU/内存/JVM,oshi) | 是 |
| modules/demo | DemoArticle/DemoOrder 示例业务模块(接单参照) | 是(M10 实证;删时同步删 data.sql 示例菜单 menu_id=5 与对应测试) |
cookiecutter-java-scaffold/
├── cookiecutter.json # 生成参数(project_name/project_slug/package_name/db_name/server_port)
├── hooks/post_gen_project.py # 生成后确定性重写:包目录移动 + 全树整词替换 + 坐标/主类名 + git init
├── Makefile # 纪律三件套:占位符检查 / 冒烟 / 防漂移(CI 等价物)
├── scripts/dev-local.yml # 开发工作区凭证(gitignored,绝不入库)
├── .github/workflows/template-ci.yml # GitHub Actions:与本地 make all + 生成项目 mvn test 等价
└── {{cookiecutter.project_slug}}/ # 模板本体(固定基础包 com.scaffoldseed,自身可编译可测试)
├── pom.xml / Dockerfile / docker-compose.yml / README.md
├── sql/schema.sql / sql/data.sql # 15 表结构 + 种子(幂等)
├── docs/member-integration.md # C 端接单指南
└── src/{main,test}/java/com/scaffoldseed/... # 上述八模块 + 117 项单测
- 模板树内零真实地址、零真实凭证:所有地址类配置一律
${SCAFFOLD_*:默认}环境变量兜底(默认 localhost/root),make check-placeholders+ 代码评审双重把关 - 开发者个人凭证:生成项目
application-local.yml(gitignore,模板仅提供.example) - 模板维护者工作区凭证:
scripts/dev-local.yml(gitignored,用于联调真库真缓存,复制到.smoke/<项目>) - 生产凭证:只经环境变量注入(docker run
-e/ compose${SCAFFOLD_*}),见生成项目 README「Docker 部署」
| 命令 | 作用 |
|---|---|
make all |
全部检查(CI 等价物):占位符纪律 + 模板自编译 + 冒烟 + 防漂移 |
make check-placeholders |
Jinja2 语句/注释界定符全树零容忍;双花括号仅白名单文件且必须以 cookiecutter. 前缀(详见 Makefile) |
make template-compile |
模板仓自身 mvn compile(固定基础包使其为合法 Maven 项目) |
make smoke |
cookiecutter 生成到 .smoke/(基线)并编译生成项目 |
make check-drift |
二次生成与 .smoke/ 基线 diff,防模板/重写脚本漂移 |
- 模板内 Dockerfile:单阶段(宿主机
mvn -DskipTests package出 jar)+ eclipse-temurin:17-jre,TZ=Asia/Shanghai,ENTRYPOINT java -Xms256m -Xmx512m,内置 HEALTHCHECK(curl 探 /actuator/health, 基底镜像实测自带 curl;精简基底可退回 bash /dev/tcp 方案,见 Dockerfile 注释),exec 形式使 java 为 PID 1 直收 SIGTERM 优雅停机 - docker-compose.yml 三形态:
up -d仅 app(外部 DB/Redis,depends_on对未启用 profile 的服务按required: false忽略);--profile localdb up -d附带 MySQL8.4+Redis7(app 等健康后启动,首次初始化 自动导 schema/data);up -d --no-deps app显式跳过依赖。compose v2.27 实测三种形态均有效 - CI(.github/workflows/template-ci.yml):ubuntu-latest + Temurin 17 + cookiecutter →
make check-placeholders→make template-compile→make smoke→ 生成项目mvn test(无需外部 DB/Redis,117 项全绿)→make check-drift。工作流文件不含 Jinja2 界定符(不使用 GitHub 表达式语法)
| 限制 | 现状 | 回归条件 |
|---|---|---|
| knife4j 4.5.0 与 springdoc 2.5+ 二进制不兼容、springdoc 2.3- 不支持 Boot 3.5 | 文档内核用 springdoc-openapi 2.9.1(/swagger-ui/index.html),皮肤暂缺 | knife4j 发布适配 Boot 3.5 的版本后替换 starter 并回归 /doc.html(详见 progress.txt M9 记录与模板 pom 注释) |
| Spring Boot 4(SB4) | 未跟进(3.5.x LTS 线) | SB4 GA 且依赖链(Sa-Token/MP/Druid)齐适配后升 parent 并全量回归 |
| easyexcel 已归档转 cn.idev.excel:fastexcel | 锁定 easyexcel 4.0.3(最后一个稳定版) | fastexcel 功能对齐(含注解导出/样式)后切换 modules/tool 依赖 |
| 生成项目强绑 RuoYi-Vue3 前端契约 | 后端契约按 v3.9.2 锚定 | 前端大版本升级时同步契约矩阵(progress.txt M3 附录 A) |
各里程碑决策与实测证据见
progress.txt(gitignored,本地维护)。