feat(m0): 后端骨架 + 账号体系(M0 验收 36/36 通过)
技术栈(已在 4.1.1 上实测跑通,非纸面选型)
Java 21 + Spring Boot 4.1.1 + MyBatis-Plus 3.5.17(boot4) + PostgreSQL 16.15
+ Redis 7 + Flyway 12.4 + springdoc 3.1.1;前端定 Vue 3 + Element Plus + uni-app
交付内容
M0-01 基础设施 deploy/docker-compose.yml(PG + Redis + MinIO,容器名与端口避让本机既有项目)
M0-02 后端骨架 xt-common + xt-server;统一响应 / 全局异常 / 58 个错误码 /
多租户拦截 / 软删除 / 字段自动填充 / AES-GCM / HMAC 索引 / RSA / JWT
M0-05 租户 开通租户(一次完成建租户 + 发 6 个内置角色 + 建首个管理员)、列表、详情
M0-06 组织 CRUD + 组织树 + ancestor_path 自动维护 + 占用校验
M0-07 PC 登录 RSA 解密 + 图形验证码 + 失败锁定 + 等时比较防账号枚举 + 审计日志
M0-08 登出/当前用户 Token 黑名单(存 SHA-256,TTL 到自然过期)
M0-01 数据库 Flyway 2 个迁移 → 26 张表(20 业务 + 5 标准 + 1 迁移记录)
安全姿态
· 租户拦截器【默认拒绝】:匿名请求触及租户表直接抛 40101,不做「不加条件放行」
· 权限码定义在代码里(PermissionDef / BuiltinRole),不建 sys_permission 表,杜绝前后端漂移
· 匿名接口只靠 @PublicApi 放行,不做路径白名单,避免两套机制各说各话
· 账号不存在时也跑一次 BCrypt(假哈希),拉平响应时间防枚举
· 登录密码 RSA 传输,防止网关/APM 把明文密码记进日志
脚本
scripts/sync-ddl.py 文档 DDL → Flyway 迁移,带 --check 防漂移
scripts/e2e-m0.py M0 验收 36 项,可进 CI
scripts/verify-docs.py 文档一致性(接口数【逐节】核对、错误码、跨文档数字、表格列数)
scripts/dev-login.py RSA 加密登录助手
scripts/dev-clean-e2e.py 清理 E2E 测试数据
文档修正(实测暴露,非人工审查)
· DDL 缺陷:sys_tenant.contact_phone / sys_user.phone / collect_roster.phone
原 varchar(20) 按明文长度建,装不下 AES-GCM 密文(约 52 字符),改 varchar(128)(PRD V2.4)
· 错误码 40007b/40007c 带字母后缀与「code 为数字」的约定冲突,规范化为 40071/40072
· 07-开发实施计划 新增 §9 版本兼容踩坑记录(10 条实录)与 §10 M0 完成情况
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
# 数据信息填报系统 · 本地开发基础设施
|
||||
#
|
||||
# 用法:
|
||||
# cd deploy
|
||||
# copy .env.example .env (首次)
|
||||
# docker compose up -d
|
||||
#
|
||||
# ⚠️ 容器名统一加 xt- 前缀,端口刻意避开 55432 / 6379
|
||||
# (本机已有其他项目的 pg-verify 与 redis-local 在跑,不要动它们)
|
||||
|
||||
name: xiaotutongxue
|
||||
|
||||
services:
|
||||
# ── PostgreSQL 16 ─────────────────────────────────
|
||||
pg:
|
||||
image: postgres:16-alpine
|
||||
container_name: xt-pg
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: ${PG_DB:-filldb}
|
||||
POSTGRES_USER: ${PG_USER:-fill}
|
||||
POSTGRES_PASSWORD: ${PG_PASSWORD:-fill_dev_pwd}
|
||||
# 中文排序与大小写:用 C 排序 + UTF8,避免 locale 差异导致索引行为不一致
|
||||
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C"
|
||||
TZ: Asia/Shanghai
|
||||
ports:
|
||||
- "${PG_PORT:-5432}:5432"
|
||||
volumes:
|
||||
- pg-data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${PG_USER:-fill} -d ${PG_DB:-filldb}"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 12
|
||||
start_period: 10s
|
||||
command:
|
||||
- postgres
|
||||
# 超大图处理是内存密集的,DB 侧保留默认即可,但把慢查询记下来
|
||||
- -c
|
||||
- log_min_duration_statement=1000
|
||||
- -c
|
||||
- timezone=Asia/Shanghai
|
||||
|
||||
# ── Redis 7 ───────────────────────────────────────
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: xt-redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${REDIS_PORT:-16379}:6379"
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
command:
|
||||
- redis-server
|
||||
- --appendonly
|
||||
- "yes"
|
||||
- --requirepass
|
||||
- "${REDIS_PASSWORD:-redis_dev_pwd}"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "redis-cli -a ${REDIS_PASSWORD:-redis_dev_pwd} ping | grep PONG"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 12
|
||||
start_period: 5s
|
||||
|
||||
# ── MinIO(对象存储,S3 兼容)─────────────────────
|
||||
# M0 阶段不写入,但先起好——本地/生产的存储层走同一套 S3 接口,
|
||||
# 换阿里云 OSS 只改配置,不改代码。
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
container_name: xt-minio
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}
|
||||
MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}
|
||||
TZ: Asia/Shanghai
|
||||
ports:
|
||||
- "${MINIO_PORT:-9000}:9000"
|
||||
- "${MINIO_CONSOLE_PORT:-9001}:9001"
|
||||
volumes:
|
||||
- minio-data:/data
|
||||
command: server /data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "mc ready local || exit 1"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 6
|
||||
start_period: 15s
|
||||
|
||||
volumes:
|
||||
pg-data:
|
||||
redis-data:
|
||||
minio-data:
|
||||
Reference in New Issue
Block a user