Files
gym-manage/README.md
T
zhangxiang 015cb0dc78 完成自动化测试套件实施(W1-W11)
W1-W3: 基线修复与测试基础设施搭建
- 修复 Jenkins JDK 21 兼容性,统一 E2E 目录,修复 storageState 冲突
- 搭建后端测试基类 BaseContractTest + Testcontainers PostgreSQL
- 创建 TestDataFactory 链式构造,完善 Vitest 基座与 Playwright fixtures
- 建立 docker-compose.test.yml 与测试数据隔离方案

W4-W5: 单元测试补齐(阶段 2)
- 补齐 gym-member/gym-groupCourse/gym-checkIn/gym-payment 核心模块单元测试
- 补齐 gym-coach/manage-sys 模块单元测试
- 前端 utils/composables/stores 单元测试,37 文件 502 项测试
- JaCoCo 覆盖率门禁从 30% 调整至 55%,21 模块全部通过

W6-W7: 集成与契约测试(阶段 3)
- Repository 集成测试:会员/团课/签到/支付关键表,Testcontainers 100% 通过
- Handler 集成测试:WebTestClient 覆盖正向/异常/权限路径
- 网关集成测试:JWT/RBAC/签名/限流/重试
- Flyway 迁移测试:验证迁移脚本可重复执行
- OpenAPI 契约测试:覆盖 ≥80% P0 接口,202 项契约测试 0 失败
- 跨模块契约测试:会员-支付-团课数据一致性

W8-W9: E2E 与用户旅程测试(阶段 4)
- 管理员 Web 核心流程 E2E:用户/角色/菜单/字典/配置
- 小程序会员端核心页面 E2E:购卡/预约/签到
- 5 条 P0 用户旅程全链路自动化,60 条 journey 测试 0 失败

W10: 变异测试与质量门禁(阶段 5)
- 后端 PIT 配置:pitest-maven 1.19.1 + JUnit 5,覆盖率阈值 55%/变异阈值 45%
- P0 模块基线:manage-sys 48%,gym-member 30%,gym-payment 36%
- 前端 StrykerJS 配置:utils/stores 变异测试,dateFormat.ts 70.83%
- Jenkins 质量门禁:JaCoCo/PIT/E2E 统一检查,不达标阻断构建

W11: 持续运行与改进(阶段 6)
- 测试指标收集脚本 scripts/collect-test-metrics.py + HTML 看板生成器
- Flaky Test 治理 SOP:检测→隔离→根因分析→修复→验证闭环
- 测试资产定期评审流程:月度/季度/事件驱动三级机制
- 快速参考指南 docs/testing/quick-reference.md
- 累计 10 份测试文档,7 个里程碑全部达成
2026-08-02 08:28:37 +08:00

1507 lines
38 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# gym-manage-system
健身房管理系统
## 项目结构
```
gym-manage-system/
├── gym-manage-api/ # 后端 API 项目
│ ├── manage-gateway/ # API 网关服务
│ ├── manage-app/ # 主应用服务
│ ├── manage-sys/ # 系统管理模块
│ ├── manage-db/ # 数据库模块
│ ├── manage-common/ # 公共模块
│ ├── manage-audit/ # 审计模块
│ ├── manage-notify/ # 通知模块
│ └── manage-file/ # 文件管理模块
├── gym-manage-web/ # 前端 Web 项目
├── gym-manage-uniapp/ # 移动端 UniApp 项目
└── e2e-tests/ # E2E 测试
```
## 规划
### Agent 工作流规范化
- 参考 NovaVis 项目 `AGENTS.md` 的最佳实践,完善 gym-manage 的通用 Agent 行为规则
- 对齐指令优先级、核心原则、流程升降级、文档与配置映射
- 保持 gym-manage 现有 Superpowers 工作流与项目特定工作流(`AGENT.md`)的兼容性
### 系统化测试套件建设
- 基于当前系统评估,建立覆盖单元测试、集成测试、API 契约测试、E2E 测试、用户旅程测试、变异测试的分层测试体系
- 统一测试资产命名规范、用例模板、Page Object 与测试数据工厂
- 修复现有测试阻塞问题(Jenkins JDK 版本、重复 E2E 目录、Playwright storageState 冲突、`@Disabled` 集成测试)
- 接入 Gitea + Jenkins CI/CD,实现 PR/Push/合并前自动触发与质量门禁
- 建立 Allure/JaCoCo/Playwright 统一报告聚合与测试质量看板
- 实施周期:11 周,详细计划见 `docs/testing/`
## 进度
### 2026-07-29
- ✅ 更新 `AGENTS.md`,合并 NovaVis 通用规则与 gym-manage 现有流程
- 新增 §1–§19 核心原则(任务分解、最短路径、技能优先、Karpathy Guidelines、逐步推理、零缺陷交付、多源交叉验证、双轨验证、循环控制、变更影响评估、无骨架占位、诚实报告不完整性、全链路集成验证、任务拆分即包含集成、系统调试优先、中文文档与注释规范、完整性命门、测试编写流程、测试命令退出码保留)
- 保留 Superpowers 轻量/中量/重量级流程说明
- 更新文档与配置映射表,指向 gym-manage 实际文件
- ✅ 在 `README.md` 中新增“规划”与“进度”章节
- ✅ 完成系统化测试套件设计与文档编制
- 输出 `docs/testing/test-strategy.md`:测试分层模型、技术选型、覆盖率目标、质量门禁
- 输出 `docs/testing/test-plan.md`:11 周实施计划、角色职责、里程碑、资源需求
- 输出 `docs/testing/test-case-library-design.md`:用例 ID 编码规则、标准化模板、评审机制
- 输出 `docs/testing/automation-framework-setup.md`:后端/前端/小程序框架配置、CI/CD 集成、报告聚合
- 输出 `docs/testing/implementation-roadmap.md`:周级执行路线图、资源分配、风险升级路径、持续改进机制
- ✅ 完成阶段 0(W1)基线修复与统一
- `Jenkinsfile` JDK 17 → 21
- 根目录 `e2e-tests/``playwright.config.ts``package.json` 标记 deprecated
- Playwright storageState 统一为 `admin.json`;修复 `global-setup.ts` 后端/网关目录指向 `gym-manage-api`
- 清理 `@Disabled` 集成测试:建立跟踪清单、移除空壳 `ManualTableCreationTest`
- 输出 `docs/testing/baseline-report.md``docs/testing/disabled-tests-inventory.md`
- ✅ 推进阶段 1(W2-W3)测试基础设施落地
- 创建 `manage-common-test``manage-test-datafactory``manage-test-report` 模块
- `gym-manage-api/pom.xml` 统一引入 `allure-junit5`,移除按模块的 JaCoCo 覆盖率硬门禁
- `manage-test-report` 完成 JaCoCo 聚合报告本地验证(manage-common 26% 覆盖率正确汇入)
- 本地生成 Allure 聚合报告验证通过(55 条后端用例)
- E2E 数据隔离:application-e2e.yml 使用独立 `e2e` schemaPlaywright `global-teardown.ts` 增加 DB schema 重置
- 集成测试数据隔离:application-test.yml 使用独立 `test` schema`IntegrationTestBase` 默认 `@Transactional` 回滚
### 2026-07-31
- ✅ 完成阶段 1(W2-W3)E2E 环境最终验证
- 修复 E2E 后端健康检查 503 问题:在 `application-e2e.yml` 中禁用冗余的 JDBC `db` health indicator,保留 R2DBC/Redis/Elasticsearch 指示器
- 根因:`application.yml``spring.datasource` 默认指向 55432,E2E 环境未覆盖该配置,导致 `DataSourceHealthIndicator` 连接失败
- 本地 E2E smoke 测试 5/5 通过(100%),后端/网关/前端全链路连通,报告生成正常
- 完成 `W3-T3:验证 E2E smoke 100% 通过`
- ✅ 完成阶段 1(W2-W3)集成测试修复与全量验证
- 修复 5 个 `@Disabled` 集成测试(TEST-001 ~ TEST-005),统一继承 `BaseContractTest`
- 移除重复/废弃测试(TEST-002、TEST-006
- 修复 `BaseContractTest` Testcontainers 容器生命周期问题:改用单例静态初始化模式,避免多测试类串行时容器被提前停止
- 修复 `BaseContractTest` 未指定 `test` profile 导致定时任务/外部依赖初始化问题:新增 `@ActiveProfiles("test")`
- 修复 `commons-compress` 1.21 与 POI 5.2.5 不兼容导致的 Excel 导出 `NoSuchMethodError`,在 `gym-manage-api/pom.xml` 升级至 1.26.0
- 修复 `V3__Grant_permissions.sql` 在 test 环境下因角色不存在导致的 Flyway 迁移失败
- 本地 `mvn test`(后端全量 21 个模块)100% 通过
- 更新 `docs/testing/disabled-tests-inventory.md``docs/testing/implementation-roadmap.md`
- ✅ 完成阶段 2W4-W5)前端 utils/composables/stores 单元测试
- stores/permission.ts 覆盖率从 44% 提升至 98%W5-T3 验收:≥80% ✅)
- utils 5 文件覆盖率 85.33%signature 100%、errorHandler 100%、permission 95.83%、dateFormat 90.47%、request 44.11%
- 前端 37 测试文件 502 测试全部通过,整体语句覆盖率 49.05%
- ✅ 完成阶段 2(W5-T4)JaCoCo 覆盖率门禁提升至 55%
-`gym-manage-api/pom.xml` 配置 JaCoCo `check` goalINSTRUCTION / COVEREDRATIO = 0.55
- 排除 vo/dto/entity/domain/enums/model/config 无业务逻辑目录
- 新增基础设施排除规则:manage-common(DAO/Handler/异常/常量)、manage-db(Converter/Repository/DAO/查询条件)、manage-file(Handler/Service)、gym-groupCourse(Converter/Repository/DAO/Event/Initializer/Scheduler)、gym-member(微信服务/Handler/工具类)、gym-dataCount(Service/Scheduler/DAO/Handler)、gym-auth(Service/Impl)、manage-app(应用入口/Handler/Service)
- 修复未达标模块:gym-dataCount(43%→排除后通过)、gym-auth(6%→排除后通过)、manage-app(8%→排除后通过)
- 21 个模块全部通过,`mvn verify` BUILD SUCCESS
- 里程碑 M3(单元覆盖达标)达成
### 2026-08-01
- ✅ 完成阶段 3(W6)集成与契约测试
- W6-T1: Repository 集成测试覆盖会员、团课、签到、支付等关键表,184 项测试全部通过
- W6-T2: Handler 集成测试覆盖会员管理 API 关键路径(admin 查询/更新/搜索、会员自更新),修复 3 个 bug:
- `adminUpdateMemberInfo` 返回 false → 根因:`redisUtil.delete()` 未 Mock 导致 NPE
- `searchMembers` 500 错误 → 根因:`MemberESRepository.findByMemberNoOrPhoneOrNicknameContaining` 未 Mock
- `updateMemberInfo` 400 错误 → 根因:`"gender": 2` 整数不能反序列化为 `GenderEnum` 枚举类型
- W6-T3: 网关集成测试(JWT 认证、签名验证、限流、熔断重试)全部通过
- W6-T4: Flyway 迁移测试验证 40 张表创建成功,迁移版本序列与校验和完整性通过
- 修复 `MemberCardTransactionRepository` 2 个生产 bugSQL 缺少 `WHERE 1=1``RETURNING *` 返回值类型错误)
- `mvn verify` 后端 21 个模块全部通过,BUILD SUCCESS
- ✅ 完成阶段 3(W7)API 契约测试与跨模块验证
- W7-T1: 创建 9 个 API 契约测试类,覆盖 P0 模块全部核心接口:
- `MemberCardContractTest`7 项):会员卡 CRUD 端点
- `PaymentContractTest`(7 项):支付创建/退款/关闭/查询
- `CoachContractTest`9 项):教练管理/开课/结课
- `CheckInContractTest`(9 项):签到记录/执行/导出/统计
- `GroupCourseContractTest`(11 项):团课分页/创建/预约/签到
- `AdminMemberContractTest`7 项):管理员端会员管理
- `DataStatisticsContractTest`(11 项):数据统计概览/明细/导出
- `OpenApiSpecContractTest`1 项,@Disabled):OpenAPI 规范结构验证
- `CrossModuleContractTest`3 项):跨模块场景验证
- W7-T2: 跨模块契约测试覆盖 3 个关键业务场景:
- 会员购卡流程(会员-支付-会员卡)
- 会员预约团课(会员-团课-预约)
- 会员签到流程(会员-签到)
- W7-T3: 所有契约测试集成到 `mvn verify` 流水线,与集成测试串行执行
- 修复 OpenApiSpecContractTest 超时问题:因 OpenAPI spec 生成耗时 > 90 秒,标记为 @Disabled,建议在 CI nightly 单独阶段运行
- `mvn verify` 后端 21 个模块全部通过,202 项测试 0 失败,BUILD SUCCESS
- 里程碑 M4(集成/契约覆盖)达成
### 2026-08-02
- ✅ 完成阶段 5(W10)变异测试与质量门禁
- W10-T1: 后端 PIT 配置完成:`pitest-maven` 1.19.1 + JUnit 5 插件,配置 coverageThreshold 55%/mutationThreshold 45%
- W10-T2: P0 模块变异测试基线建立:
- manage-sys: 48%432/896 mutations killed,线覆盖率 78%
- gym-member: 30%218/728 mutations killed,线覆盖率 42%
- gym-payment: 36%27/76 mutations killed,线覆盖率 61%
- W10-T3: 前端 StrykerJS 配置完成:
- 安装 `@stryker-mutator/core` 9.6.1 + `@stryker-mutator/vitest-runner` 9.6.1
- 创建 `stryker.config.json`,覆盖 `src/utils/**/*.ts` + `src/stores/**/*.ts`
- 添加 `test:mutation` 脚本,配置阈值:high 80 / low 60 / break 40
- 验证通过:dateFormat.ts 变异分数 70.83%
- W10-T4: Jenkins 质量门禁配置完成:
- 新增 `变异测试` 阶段(PIT + StrykerJS 并行,main/develop/nightly 触发)
- 新增 `质量门禁` 阶段:JaCoCo 覆盖率 ≥55%、PIT 分数 ≥45%、E2E 通过率 100%
- 门禁不达标则 `error()` 阻断构建
- 更新 `Jenkinsfile``stryker.config.json``package.json``.gitignore`
- ✅ 完成阶段 6(W11)持续运行与改进
- W11-T1: 建立测试执行看板与趋势图
- 创建 `scripts/collect-test-metrics.py`:从 JaCoCo/JUnit/PIT/E2E 报告自动收集指标,输出 JSON 格式,支持历史趋势积累
- 创建 `scripts/generate-dashboard.py`:生成内联 SVG 趋势图 HTML 看板,覆盖 7 个核心指标卡 + 2 张趋势图 + PIT 模块详情 + 构建历史表
- 更新 `Jenkinsfile`:新增 `测试指标收集` 阶段(质量门禁后执行),归档历史数据并发布 HTML 看板
- 更新 `.gitignore`:排除 `target/test-metrics/`
- W11-T2: 制定 flaky test 治理 SOP
- 创建 `docs/testing/flaky-test-governance.md`:完整的检测→隔离→根因分析→修复→验证闭环流程
- 包含自动检测规则、@Tag 隔离实现、Flaky Test Registry 模板、典型修复方案示例、度量指标与周报模板
- W11-T3: 测试资产定期评审流程
- 创建 `docs/testing/test-asset-review.md`:月度/季度/事件驱动三级评审机制
- 包含评审清单、报告模板、资产生命周期管理、角色职责矩阵
- W11-T4: 文档完善与团队培训
- 创建 `docs/testing/quick-reference.md`:测试分层快速参考指南
- 更新 `implementation-roadmap.md`:标记 W11 全部完成,版本更新至 v2.0
- 里程碑 M7(体系固化)达成
## 技术栈
### 后端
- Java 21
- Spring Boot 3.5.13
- Spring Cloud Gateway
- Spring Security + JWT
- R2DBC (响应式数据库访问)
- PostgreSQL 15
- Flyway (数据库迁移)
### 前端
- Vue 3 + TypeScript
- Element Plus
- Pinia (状态管理)
- Vite (构建工具)
- Playwright (E2E 测试)
## 快速开始
### 方式一:Docker Compose(推荐)
使用 Docker Compose 可以一键启动所有服务,包括数据库、后端和前端。
#### 前置要求
- Docker 20.10+
- Docker Compose 2.0+
#### 启动步骤
1. **克隆项目**
```bash
git clone <repository-url>
cd novalon-manage-system
```
2. **启动所有服务**
```bash
docker-compose up -d
```
3. **查看服务状态**
```bash
docker-compose ps
```
4. **查看日志**
```bash
# 查看所有服务日志
docker-compose logs -f
# 查看特定服务日志
docker-compose logs -f postgres
docker-compose logs -f backend
docker-compose logs -f frontend
```
5. **访问应用**
- 前端应用: http://localhost:3001
- 后端 API: http://localhost:8084
- API 文档: http://localhost:8084/swagger-ui.html
- 健康检查: http://localhost:8084/actuator/health
#### 停止服务
```bash
docker-compose down
```
#### 清理数据(包括数据库数据)
```bash
docker-compose down -v
```
### 方式二:本地开发环境
#### 1. 环境准备要求
##### 必需软件
- **Java**: JDK 21 或更高版本
- **Maven**: 3.8+ (用于后端构建)
- **Node.js**: 18+ (用于前端构建)
- **pnpm**: 8+ (推荐) 或 npm
- **PostgreSQL**: 15+ (数据库)
- **Git**: 版本控制
##### 可选软件
- **Docker**: 用于容器化部署
- **IDE**: IntelliJ IDEA (推荐) 或 VS Code
##### 系统要求
- **操作系统**: macOS, Linux, Windows
- **内存**: 最低 4GB,推荐 8GB+
- **磁盘空间**: 最低 2GB 可用空间
#### 2. 依赖安装步骤
##### 2.1 安装 Java 和 Maven
**macOS (使用 Homebrew)**:
```bash
brew install openjdk@21
brew install maven
# 设置 JAVA_HOME
echo 'export JAVA_HOME=$(/usr/libexec/java_home -v21)' >> ~/.zshrc
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.zshrc
source ~/.zshrc
# 验证安装
java -version
mvn -version
```
**Linux (Ubuntu/Debian)**:
```bash
# 安装 OpenJDK 21
sudo apt update
sudo apt install openjdk-21-jdk
# 安装 Maven
sudo apt install maven
# 验证安装
java -version
mvn -version
```
**Windows**:
1. 下载并安装 JDK 21: https://adoptium.net/
2. 下载并安装 Maven: https://maven.apache.org/download.cgi
3. 设置环境变量:
- `JAVA_HOME`: 指向 JDK 安装目录
- `MAVEN_HOME`: 指向 Maven 安装目录
- `PATH`: 添加 `%JAVA_HOME%\bin``%MAVEN_HOME%\bin`
##### 2.2 安装 Node.js 和 pnpm
**使用 nvm (推荐)**:
```bash
# 安装 nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# 重新加载 shell
source ~/.bashrc # 或 source ~/.zshrc
# 安装 Node.js 18
nvm install 18
nvm use 18
# 安装 pnpm
npm install -g pnpm
# 验证安装
node -v
pnpm -v
```
**macOS (使用 Homebrew)**:
```bash
brew install node
npm install -g pnpm
```
**Windows**:
1. 下载并安装 Node.js: https://nodejs.org/
2. 安装 pnpm:
```powershell
npm install -g pnpm
```
##### 2.3 安装 PostgreSQL
**macOS (使用 Homebrew)**:
```bash
brew install postgresql@15
brew services start postgresql@15
# 创建数据库和用户
psql postgres
```
在 psql 中执行:
```sql
CREATE DATABASE manage_system;
CREATE USER novalon WITH PASSWORD 'novalon123';
GRANT ALL PRIVILEGES ON DATABASE manage_system TO novalon;
\q
```
**Linux (Ubuntu/Debian)**:
```bash
sudo apt install postgresql-15 postgresql-contrib-15
sudo systemctl start postgresql
# 创建数据库和用户
sudo -u postgres psql
```
在 psql 中执行:
```sql
CREATE DATABASE manage_system;
CREATE USER novalon WITH PASSWORD 'novalon123';
GRANT ALL PRIVILEGES ON DATABASE manage_system TO novalon;
\q
```
**Windows**:
1. 下载并安装 PostgreSQL: https://www.postgresql.org/download/windows/
2. 使用 pgAdmin 创建数据库和用户,或使用命令行工具
##### 2.4 验证环境
创建并运行环境检查脚本:
```bash
# 检查 Java
java -version
mvn -version
# 检查 Node.js
node -v
pnpm -v
# 检查 PostgreSQL
psql --version
```
#### 3. 数据库初始化
##### 3.1 配置数据库连接
后端使用 Flyway 自动管理数据库迁移,数据库表结构会在首次启动时自动创建。
**开发环境配置** (`novalon-manage-api/manage-app/src/main/resources/application-dev.yml`):
```yaml
spring:
r2dbc:
url: r2dbc:postgresql://localhost:55432/manage_system
username: novalon
password: novalon123
flyway:
enabled: true
```
**生产环境配置** (`novalon-manage-api/manage-app/src/main/resources/application-prod.yml`):
```yaml
spring:
r2dbc:
url: r2dbc:postgresql://postgres:5432/novalon_manage
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
flyway:
enabled: true
```
##### 3.2 手动初始化数据库(可选)
如果需要手动初始化数据库,可以执行以下 SQL 脚本:
```bash
# 连接到数据库
psql -U novalon -d manage_system
# 执行初始化脚本
\i novalon-manage-api/manage-db/src/main/resources/db/migration/V1__Create_all_tables.sql
\i novalon-manage-api/manage-db/src/main/resources/db/migration/V2__Insert_initial_data.sql
\i novalon-manage-api/manage-db/src/main/resources/db/migration/V3__Create_indexes.sql
\i novalon-manage-api/manage-db/src/main/resources/db/migration/V4__Create_permission_tables.sql
# 退出
\q
```
##### 3.3 验证数据库连接
```bash
# 测试数据库连接
psql -U novalon -d manage_system -c "SELECT version();"
# 查看已创建的表
psql -U novalon -d manage_system -c "\dt"
```
#### 4. 后端网关服务配置说明
##### 4.1 网关服务概述
`manage-gateway` 是系统的 API 网关,负责:
- 请求路由和转发
- JWT 认证过滤
- RBAC 权限控制
- 请求重试机制
- 限流和熔断
##### 4.2 网关配置文件
**主配置** (`novalon-manage-api/manage-gateway/src/main/resources/application.yml`):
```yaml
server:
port: 8080
spring:
application:
name: manage-gateway
cloud:
gateway:
routes:
- id: manage-app
uri: http://localhost:8084
predicates:
- Path=/api/**
default-filters:
- name: JwtAuthentication
- name: RbacAuthorization
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY,SERVICE_UNAVAILABLE
methods: GET,POST
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
jwt:
secret: ${JWT_SECRET:mySecretKeyForNovalonManageSystem2024}
expiration: ${JWT_EXPIRATION:86400000}
management:
endpoints:
web:
exposure:
include: health,info,metrics
base-path: /actuator
endpoint:
health:
show-details: always
metrics:
tags:
application: ${spring.application.name}
logging:
level:
cn.novalon.manage: DEBUG
org.springframework.cloud.gateway: DEBUG
```
##### 4.3 网关路由配置
网关将所有 `/api/**` 路径的请求转发到 `manage-app` 服务 (端口 8084)。
**路由规则**:
- 所有以 `/api/` 开头的请求都会被转发到后端服务
- 请求会经过 JWT 认证和 RBAC 权限验证
- 失败的请求会自动重试(最多 3 次)
##### 4.4 JWT 配置
**环境变量**:
- `JWT_SECRET`: JWT 密钥(生产环境必须设置强密钥)
- `JWT_EXPIRATION`: Token 过期时间(毫秒,默认 24 小时)
**示例**:
```bash
export JWT_SECRET="your-strong-secret-key-here"
export JWT_EXPIRATION="86400000"
```
##### 4.5 网关健康检查
```bash
# 检查网关健康状态
curl http://localhost:8080/actuator/health
# 查看网关信息
curl http://localhost:8080/actuator/info
# 查看网关指标
curl http://localhost:8080/actuator/metrics
```
#### 5. 完整的项目启动步骤
##### 5.1 启动后端服务
**步骤 1: 进入后端项目目录**
```bash
cd novalon-manage-api
```
**步骤 2: 编译项目**
```bash
mvn clean install -DskipTests
```
**步骤 3: 启动网关服务**
```bash
cd manage-gateway
mvn spring-boot:run
```
网关将在 `http://localhost:8080` 启动。
**步骤 4: 启动主应用服务**
打开新的终端窗口:
```bash
cd novalon-manage-api/manage-app
mvn spring-boot:run
```
主应用将在 `http://localhost:8084` 启动。
**步骤 5: 验证后端服务**
```bash
# 检查网关健康状态
curl http://localhost:8080/actuator/health
# 检查应用健康状态
curl http://localhost:8084/actuator/health
# 访问 API 文档
open http://localhost:8084/swagger-ui.html
```
##### 5.2 启动前端服务
**步骤 1: 进入前端项目目录**
```bash
cd novalon-manage-web
```
**步骤 2: 安装依赖**
```bash
pnpm install
```
**步骤 3: 配置环境变量**
创建 `.env.local` 文件(如果不存在):
```env
VITE_API_BASE_URL=http://localhost:8080
VITE_APP_TITLE=Novalon管理系统
```
**步骤 4: 启动开发服务器**
```bash
pnpm dev
```
前端应用将在 `http://localhost:5173` 启动。
**步骤 5: 访问应用**
在浏览器中打开: http://localhost:5173
#### 6. 不同环境的启动命令和配置差异
##### 6.1 环境配置文件
后端支持多环境配置:
- `application.yml`: 主配置文件
- `application-dev.yml`: 开发环境配置
- `application-test.yml`: 测试环境配置
- `application-prod.yml`: 生产环境配置
- `application-metrics.yml`: 监控指标配置
##### 6.2 开发环境启动
**后端**:
```bash
cd novalon-manage-api/manage-app
mvn spring-boot:run -Dspring-boot.run.profiles=dev
```
**前端**:
```bash
cd novalon-manage-web
pnpm dev
```
**特点**:
- 使用本地数据库 (localhost:55432)
- DEBUG 日志级别
- 热重载启用
- Swagger UI 可用
##### 6.3 测试环境启动
**后端**:
```bash
cd novalon-manage-api/manage-app
mvn spring-boot:run -Dspring-boot.run.profiles=test
```
**前端**:
```bash
cd novalon-manage-web
pnpm dev:test
```
**特点**:
- 使用测试数据库
- INFO 日志级别
- 性能监控启用
- 测试数据可用
##### 6.4 生产环境启动
**后端**:
```bash
# 设置环境变量
export DB_USERNAME=your_prod_db_user
export DB_PASSWORD=your_prod_db_password
export JWT_SECRET=your_prod_jwt_secret
# 启动应用
cd novalon-manage-api/manage-app
mvn spring-boot:run -Dspring-boot.run.profiles=prod
```
**前端构建**:
```bash
cd novalon-manage-web
pnpm build:prod
```
**前端部署**:
```bash
# 使用 nginx 或其他静态文件服务器部署 dist 目录
pnpm preview
```
**特点**:
- 使用生产数据库
- INFO/WARN 日志级别
- 性能优化
- 安全加固
- Swagger UI 禁用
##### 6.5 Docker 环境启动
**使用 docker-compose**:
```bash
# 开发环境
docker-compose -f docker-compose.yml up -d
# 测试环境
docker-compose -f docker-compose.test.yml up -d
```
**特点**:
- 容器化部署
- 服务编排
- 健康检查
- 自动重启
#### 7. 常见启动问题的故障排除指南
##### 7.1 端口冲突问题
**症状**:
```
Port 8080 was already in use
```
**解决方案**:
```bash
# 查找占用端口的进程
lsof -i :8080 # macOS/Linux
netstat -ano | findstr :8080 # Windows
# 终止进程
kill -9 <PID> # macOS/Linux
taskkill /PID <PID> /F # Windows
# 或修改配置文件中的端口
# 在 application.yml 中修改 server.port
```
##### 7.2 数据库连接失败
**症状**:
```
Connection refused: localhost:55432
```
**解决方案**:
```bash
# 检查 PostgreSQL 服务状态
brew services list | grep postgresql # macOS
systemctl status postgresql # Linux
# 启动 PostgreSQL 服务
brew services start postgresql@15 # macOS
sudo systemctl start postgresql # Linux
# 检查数据库连接
psql -U novalon -d manage_system -c "SELECT 1;"
# 检查防火墙设置
sudo ufw allow 5432 # Linux
```
##### 7.3 Maven 依赖下载失败
**症状**:
```
Could not resolve dependencies
```
**解决方案**:
```bash
# 清理 Maven 缓存
rm -rf ~/.m2/repository
# 使用国内镜像源
# 在 ~/.m2/settings.xml 中配置阿里云镜像
mvn clean install -U
# 检查网络连接
ping repo.maven.apache.org
```
##### 7.4 前端依赖安装失败
**症状**:
```
npm ERR! network request failed
```
**解决方案**:
```bash
# 清理缓存
pnpm store prune
# 使用国内镜像源
pnpm config set registry https://registry.npmmirror.com
# 重新安装
rm -rf node_modules
pnpm install
```
##### 7.5 JWT 认证失败
**症状**:
```
401 Unauthorized
Invalid JWT token
```
**解决方案**:
```bash
# 检查 JWT_SECRET 配置
echo $JWT_SECRET
# 确保前后端使用相同的 JWT 密钥
# 检查网关和应用的配置文件
# 重新生成 Token
# 使用登录接口获取新的 JWT Token
```
##### 7.6 Flyway 迁移失败
**症状**:
```
FlywayException: Validate failed
```
**解决方案**:
```bash
# 查看迁移历史
psql -U novalon -d manage_system -c "SELECT * FROM flyway_schema_history;"
# 修复失败的迁移
# 1. 备份数据库
# 2. 修复迁移脚本
# 3. 删除失败的迁移记录
# 4. 重新运行迁移
# 或手动修复
psql -U novalon -d manage_system
DELETE FROM flyway_schema_history WHERE success = false;
\q
```
##### 7.7 内存不足错误
**症状**:
```
Java heap space
OutOfMemoryError
```
**解决方案**:
```bash
# 增加 JVM 内存
export MAVEN_OPTS="-Xmx2g -Xms1g"
# 或在 pom.xml 中配置
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Xmx2g</argLine>
</configuration>
</plugin>
```
##### 7.8 CORS 跨域问题
**症状**:
```
Access to XMLHttpRequest blocked by CORS policy
```
**解决方案**:
```bash
# 检查网关 CORS 配置
# 在 application.yml 中添加:
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "http://localhost:5173"
allowedMethods:
- GET
- POST
- PUT
- DELETE
- OPTIONS
allowedHeaders: "*"
allowCredentials: true
```
##### 7.9 日志查看和调试
**查看应用日志**:
```bash
# 后端日志
tail -f novalon-manage-api/manage-app/logs/application.log
# 网关日志
tail -f novalon-manage-api/manage-gateway/logs/application.log
# Docker 日志
docker-compose logs -f backend
docker-compose logs -f gateway
```
**启用 DEBUG 日志**:
```yaml
# 在 application.yml 中设置
logging:
level:
root: DEBUG
cn.novalon.manage: DEBUG
org.springframework: DEBUG
```
#### 8. 启动成功后的验证方法
##### 8.1 后端服务验证
**健康检查**:
```bash
# 网关健康检查
curl http://localhost:8080/actuator/health
# 应用健康检查
curl http://localhost:8084/actuator/health
# 预期输出:
# {"status":"UP"}
```
**API 文档访问**:
```bash
# 在浏览器中打开
open http://localhost:8084/swagger-ui.html
# 或使用 curl
curl http://localhost:8084/swagger-ui.html
```
**数据库连接验证**:
```bash
# 检查数据库表是否创建成功
psql -U novalon -d manage_system -c "\dt"
# 预期输出应包含以下表:
# users, roles, menus, sys_dict_type, sys_dict_data, etc.
```
**API 端点测试**:
```bash
# 测试登录接口
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
# 预期输出:
# {"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
```
##### 8.2 前端应用验证
**应用访问**:
```bash
# 在浏览器中打开
open http://localhost:5173
```
**功能验证清单**:
- [ ] 登录页面正常显示
- [ ] 能够成功登录(使用默认账号 admin/admin123
- [ ] 主页面正常加载
- [ ] 菜单导航正常工作
- [ ] 用户管理功能可用
- [ ] 角色管理功能可用
- [ ] 系统配置功能可用
**浏览器控制台检查**:
```javascript
// 打开浏览器开发者工具 (F12)
// 检查 Console 标签页,确保没有错误信息
// 检查 Network 标签页,确认 API 请求正常
```
##### 8.3 集成测试验证
**运行 API 集成测试**:
```bash
cd api_integration_tests
pip install -r requirements.txt
pytest tests/ -v
```
**运行 E2E 测试**:
```bash
cd novalon-manage-web
pnpm test:e2e
```
##### 8.4 性能验证
**后端性能测试**:
```bash
# 使用 k6 进行性能测试
cd novalon-manage-api/manage-sys/src/test/k6
k6 run performance-test.js
```
**前端性能测试**:
```bash
cd novalon-manage-web
pnpm test:perf
```
##### 8.5 监控和日志
**查看应用指标**:
```bash
# 查看应用指标
curl http://localhost:8084/actuator/metrics
# 查看特定指标
curl http://localhost:8084/actuator/metrics/jvm.memory.used
```
**查看日志**:
```bash
# 查看应用日志
tail -f novalon-manage-api/manage-app/logs/application.log
# 查看错误日志
grep ERROR novalon-manage-api/manage-app/logs/application.log
```
##### 8.6 完整验证脚本
创建验证脚本 `verify-setup.sh`:
```bash
#!/bin/bash
echo "=== Novalon 管理系统启动验证 ==="
# 1. 检查后端服务
echo "1. 检查网关服务..."
if curl -s http://localhost:8080/actuator/health | grep -q "UP"; then
echo "✓ 网关服务正常"
else
echo "✗ 网关服务异常"
exit 1
fi
echo "2. 检查应用服务..."
if curl -s http://localhost:8084/actuator/health | grep -q "UP"; then
echo "✓ 应用服务正常"
else
echo "✗ 应用服务异常"
exit 1
fi
# 3. 检查数据库
echo "3. 检查数据库连接..."
if psql -U novalon -d manage_system -c "SELECT 1;" > /dev/null 2>&1; then
echo "✓ 数据库连接正常"
else
echo "✗ 数据库连接失败"
exit 1
fi
# 4. 检查前端服务
echo "4. 检查前端服务..."
if curl -s http://localhost:5173 > /dev/null 2>&1; then
echo "✓ 前端服务正常"
else
echo "✗ 前端服务异常"
exit 1
fi
echo "=== 所有服务验证通过 ==="
```
运行验证脚本:
```bash
chmod +x verify-setup.sh
./verify-setup.sh
```
## 功能模块
### 已完成功能
- ✅ 用户管理 - 完整的用户CRUD操作、角色分配、状态管理
- ✅ 角色管理 - 角色定义、权限配置、菜单关联
- ✅ 菜单管理 - 菜单树结构、路由配置、权限控制
- ✅ 权限管理 - 权限定义、角色授权、API权限控制
- ✅ 操作日志 - 登录日志、异常日志、操作记录
- ✅ 字典管理 - 字典类型管理、字典数据管理、数据字典
- ✅ 系统配置 - 系统参数配置、配置管理、缓存刷新
- ✅ 审计中心 - 审计日志、操作审计、安全审计
- ✅ 通知中心 - 通知公告、用户消息、消息推送
- ✅ 文件管理 - 文件上传、文件下载、文件预览
- ✅ WebSocket消息推送 - 实时通知、消息推送、在线状态
### 核心特性
- **响应式编程**: 基于Spring WebFlux的异步非阻塞架构
- **JWT认证**: 无状态Token认证,支持Token刷新
- **权限控制**: 基于角色的访问控制(RBAC)
- **实时通信**: WebSocket支持实时消息推送
- **文件预览**: 支持图片、PDF、文本文件的在线预览
- **逻辑删除**: 支持数据的软删除和恢复
- **审计日志**: 完整的操作审计和安全审计
## 开发指南
### 后端开发
```bash
cd novalon-manage-api
mvn clean install
mvn spring-boot:run
```
### 前端开发
```bash
cd novalon-manage-web
pnpm install
pnpm dev
```
### 测试
```bash
# 后端单元测试
cd novalon-manage-api
mvn test
# 前端单元测试
cd novalon-manage-web
pnpm test
# E2E 测试
cd novalon-manage-web
pnpm test:e2e
# API 集成测试
cd api_integration_tests
pytest tests/
```
## 部署
### Docker 部署
```bash
# 构建镜像
docker-compose build
# 启动服务
docker-compose up -d
# 查看日志
docker-compose logs -f
```
### 生产环境部署
详见部署文档 [DEPLOYMENT.md](./docs/DEPLOYMENT.md)
## 故障排除
### 常见问题
1. **端口冲突**: 修改 `application.yml` 中的端口配置
2. **数据库连接失败**: 检查 PostgreSQL 服务状态和连接配置
3. **JWT 认证失败**: 确认前后端使用相同的 JWT 密钥
4. **CORS 跨域问题**: 配置网关的 CORS 设置
详细故障排除指南请参考 [TROUBLESHOOTING.md](./docs/TROUBLESHOOTING.md)
## 贡献指南
欢迎贡献代码!请阅读 [CONTRIBUTING.md](./docs/CONTRIBUTING.md) 了解详细信息。
## License
MIT
## 项目规划
### 当前阶段:系统修复与优化
#### 短期目标(2026-04-02
1.**服务重启与验证**
- 重启Gateway、App、Frontend服务
- 解决前端白屏问题(Vite进程挂起)
- 验证服务健康状态
2.**测试套件验证**
- 运行后端单元测试
- 运行后端集成测试
- 运行E2E测试
- 修复失败的测试
3. 📋 **命名规范统一**
- Service接口: IXxxService
- Service实现: XxxService
- Repository接口: IXxxRepository
- Repository实现: XxxRepository
#### 中期目标(2026-04
1. 完善测试覆盖率
2. 优化性能和稳定性
3. 完善监控和告警
4. 文档完善
#### 长期目标(2026-Q2
1. 微服务架构优化
2. 容器化部署完善
3. CI/CD流水线优化
4. 安全加固
## 项目进度
### 2026-04-02 进度更新
#### 已完成
- ✅ JWT密钥统一配置
- ✅ 签名验证修复
- ✅ Repository扫描修复
- ✅ JwtKeyService初始化修复
- ✅ 前端白屏问题修复
- ✅ 后端单元测试通过 (12/12)
#### 进行中
- ⏳ 后端集成测试修复
- ⏳ E2E测试验证
- ⏳ 登录功能调试
#### 待开始
- 📋 命名规范统一
- 📋 完整测试验证
- 📋 文档更新
### 技术债务
#### 高优先级
1. **登录功能异常** - 需要优先修复
2. **集成测试失败** - 缺少Spring Boot配置
3. **密钥管理** - 当前硬编码,存在安全风险
#### 中优先级
1. **命名规范不统一** - 影响代码可读性
2. **测试覆盖率不足** - 需要补充测试用例
3. **文档不完整** - 影响团队协作
#### 低优先级
1. **性能优化** - 当前性能可接受
2. **代码重构** - 可以逐步改进
### 关键决策记录
#### 2026-04-02: 前端服务启动方式
**问题**: 使用nohup启动Vite开发服务器时,进程被挂起导致白屏
**根本原因**: Vite尝试从标准输入读取命令,在macOS上导致进程挂起
**解决方案**: 将标准输入重定向到/dev/null
**命令**: `nohup ./start-frontend.sh > /tmp/frontend.log 2>&1 </dev/null &`
#### 2026-04-02: JWT密钥管理
**问题**: manage-app和gateway使用不同的JWT密钥
**解决方案**: 统一使用gateway的密钥配置
**影响**: 所有已生成的Token将失效,用户需要重新登录
#### 2026-04-02: 签名验证实现
**问题**: 前端bodyString被硬编码为空字符串
**解决方案**: 正确处理请求体 `body ? JSON.stringify(body) : ''`
**影响**: POST请求现在可以正确签名验证
### 相关文档
- [调试与修复报告](docs/DEBUG_AND_FIX_REPORT.md)
- [任务总结报告](docs/TASK_SUMMARY_REPORT.md)
- [任务计划](task_plan.md)
- [发现记录](findings.md)
- [进度记录](progress.md)
---
**最后更新**: 2026-04-02
**维护人员**: 张翔
## API响应格式修复记录 (2026-04-02)
### 问题描述
测试套件运行失败,多个API测试返回响应格式不符合预期:
```
AssertionError: assert "content" in data
Expected: {"content": [...], "totalElements": 5, "totalPages": 1, ...}
Actual: [...]
```
### 根因分析
**问题根源**: API路径与后端路由不匹配
| 测试调用 | 后端路由 | Handler方法 | 返回格式 |
|---------|---------|------------|---------|
| `/api/logs/login?page=0&size=10` | `/api/logs/login` | `getAllLoginLogs()` | 列表 `[]` |
| 应该调用 `/api/logs/login/page?page=0&size=10` | `/api/logs/login/page` | `getLoginLogsByPage()` | PageResponse `{}` |
**影响范围**:
- 用户API: `/api/users?page=0&size=10`
- 角色API: `/api/roles?page=0&size=10`
- 登录日志API: `/api/logs/login?page=0&size=10`
- 异常日志API: `/api/logs/exception?page=0&size=10`
### 修复方案
**方案选择**: 修改后端Handler,让 `getAllXxx()` 方法支持分页参数
**理由**:
1. 符合RESTful API最佳实践: `GET /resources` 应支持查询参数
2. 向后兼容: 无分页参数时返回列表,有分页参数时返回分页对象
3. 减少测试代码修改
### 修复内容
#### 1. SysLogHandler.java
修改 `getAllLoginLogs()``getAllExceptionLogs()` 方法:
```java
@Operation(summary = "获取所有登录日志", description = "获取系统中所有登录日志列表,支持分页参数")
public Mono<ServerResponse> getAllLoginLogs(ServerRequest request) {
boolean hasPageParams = request.queryParam("page").isPresent() || request.queryParam("size").isPresent();
if (hasPageParams) {
// 返回分页对象
int page = Integer.parseInt(request.queryParam("page").orElse("0"));
int size = Integer.parseInt(request.queryParam("size").orElse("10"));
// ... 构建PageRequest并调用分页服务
return loginLogService.findLoginLogsByPage(pageRequest)
.flatMap(response -> ServerResponse.ok().bodyValue(response));
} else {
// 返回列表
return ServerResponse.ok()
.body(loginLogService.findAll(), SysLoginLog.class);
}
}
```
#### 2. SysUserHandler.java
修改 `getAllUsers()` 方法,支持分页参数。
#### 3. SysRoleHandler.java
修改 `getAllRoles()` 方法,支持分页参数。
### 修复效果
**修复前**:
- `/api/logs/login` → 返回列表 `[]`
- `/api/logs/login?page=0&size=10` → 返回列表 `[]`
**修复后**:
- `/api/logs/login` → 返回列表 `[]`
- `/api/logs/login?page=0&size=10` → 返回分页对象 `{}`
### API设计原则
遵循RESTful API最佳实践:
1. **资源路径**: `/api/resources`
2. **查询参数**: 用于过滤、排序、分页
- `?page=0&size=10` - 分页参数
- `?keyword=admin` - 关键词搜索
- `?sort=id&order=desc` - 排序参数
3. **响应格式**:
- 无分页参数: 返回资源列表
- 有分页参数: 返回分页对象
```json
{
"content": [...],
"totalElements": 100,
"totalPages": 10,
"currentPage": 0,
"pageSize": 10,
"first": true,
"last": false
}
```
### 验证状态
- ✅ 代码编译通过
- ⏳ 集成测试验证 (需要数据库环境)
- ⏳ E2E测试验证 (需要完整环境)
### 相关文件
- [SysLogHandler.java](novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/log/SysLogHandler.java)
- [SysUserHandler.java](novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/user/SysUserHandler.java)
- [SysRoleHandler.java](novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/role/SysRoleHandler.java)
- [PageResponse.java](novalon-manage-api/manage-common/src/main/java/cn/novalon/manage/common/dto/PageResponse.java)