diff --git a/wwjcloud-nest-v1/docs/ROUTE_STRUCTURE.md b/wwjcloud-nest-v1/docs/ROUTE_STRUCTURE.md new file mode 100644 index 00000000..991d46d5 --- /dev/null +++ b/wwjcloud-nest-v1/docs/ROUTE_STRUCTURE.md @@ -0,0 +1,248 @@ +# 📋 路由结构说明 + +生成时间: 2025-10-26 + +## ✅ 路由架构 + +是的,你的理解完全正确! + +### 🔐 管理后台 API + +**路径**: `/api/adminapi/*` +**数量**: 534个路由 +**用途**: 管理后台的所有功能(用户管理、系统配置、商品管理等) +**认证**: 默认需要认证 (`@UseGuards(AuthGuard)`) + +**Java定义**: +```java +@RestController +@RequestMapping("/adminapi") +@SaCheckLogin // 默认需要认证 +public class SysUserController { ... } +``` + +**NestJS转换**: +```typescript +@Controller('adminapi') +@UseGuards(AuthGuard) +@ApiBearerAuth() +export class SysUserController { ... } +``` + +**最终路径**: `/api/adminapi/*` + +--- + +### 👤 用户端 API + +**路径**: `/api/*` (除了 `/api/adminapi/*`) +**数量**: 144个路由 +**用途**: 用户端/前台的所有功能(会员、支付、微信、文件等) +**认证**: 默认不需要认证,按需添加 + +#### 主要子模块 + +| 路径 | 数量 | 说明 | +|------|------|------| +| `/api/member/*` | 41 | 会员相关 | +| `/api/diy/*` | 10 | 自定义装修 | +| `/api/wechat/*` | 9 | 微信功能 | +| `/api/core/*` | 9 | 核心功能(队列、任务) | +| `/api/weapp/*` | 6 | 微信小程序 | +| `/api/file/*` | 4 | 文件上传/下载 | +| `/api/area/*` | 4 | 地区数据 | +| `/api/ai/*` | 4 | AI功能 | +| `/api/pay/*` | 2 | 支付 | +| `/api/login` | 2 | 登录 | +| 其他 | 53 | 各种杂项功能 | + +**Java定义示例**: +```java +@RestController +@RequestMapping("/api") // ← 这个 'api' 会被NestJS全局前缀处理 +public class PayController { + + @PostMapping("/pay") + public Result pay(@RequestBody PayParam param) { ... } +} +``` + +**NestJS转换**: +```typescript +@Controller() // ← 空路径,因为NestJS已有全局 '/api' 前缀 +export class PayController { + + @Post('pay') + async pay(@Body() param: PayParam) { ... } +} +``` + +**最终路径**: `/api/pay` + +--- + +## 🔧 路径转换规则 + +### Java → NestJS 转换逻辑 + +| Java `@RequestMapping` | NestJS `@Controller` | 全局前缀 | 最终路径 | +|------------------------|---------------------|---------|---------| +| `/adminapi` | `adminapi` | `/api` | `/api/adminapi/*` ✅ | +| `adminapi` | `adminapi` | `/api` | `/api/adminapi/*` ✅ | +| `/api` | *(empty)* | `/api` | `/api/*` ✅ | +| `/api/member` | `member` | `/api` | `/api/member/*` ✅ | +| `api/member` | `member` | `/api` | `/api/member/*` ✅ | + +### 转换代码逻辑 + +```javascript +// tools/java-to-nestjs-migration/generators/controller-generator.js + +generateDecorators(routeInfo) { + let cleanPath = routeInfo.controllerPath.replace(/^\/+/, ''); // 去掉前导斜杠 + + // 如果路径是 'api' 单独出现,变为空字符串 + if (cleanPath === 'api') { + cleanPath = ''; + } + // 如果路径以 'api/' 开头,去掉这个前缀 + else if (cleanPath.startsWith('api/')) { + cleanPath = cleanPath.substring(4); // 'api/member' → 'member' + } + + // 生成装饰器 + if (cleanPath) { + decorators.push(`@Controller('${cleanPath}')`); + } else { + decorators.push('@Controller()'); // 空路径 + } +} +``` + +--- + +## ⚠️ 之前的问题 + +### 问题1: `/api/member` → `/api/api/member` + +**原因**: Java的 `@RequestMapping("/api/member")` 被完整转换为 `@Controller('api/member')`,与NestJS全局前缀 `/api` 组合后变成 `/api/api/member`。 + +**修复**: 去掉路径中的 `api/` 前缀,只保留 `member`。 + +--- + +### 问题2: `/api` → `/api/api/*` + +**原因**: Java的 `@RequestMapping("/api")` 被转换为 `@Controller('api')`,与NestJS全局前缀 `/api` 组合后变成 `/api/api/*`。 + +**修复**: 将路径 `api` 转换为空字符串 `@Controller()`。 + +--- + +## 📊 修复前后对比 + +| 状态 | `/api/api/*` 路由数量 | 正确性 | +|------|---------------------|--------| +| ❌ 修复前 | 30个 | 错误 | +| ✅ 修复后 | 0个 | 正确 | + +--- + +## 🎯 最终路由统计 + +| 路由前缀 | 数量 | 用途 | +|----------|------|------| +| `/api/adminapi/*` | 534 | 管理后台 | +| `/api/member/*` | 41 | 会员 | +| `/api/diy/*` | 10 | 自定义装修 | +| `/api/wechat/*` | 9 | 微信 | +| `/api/core/*` | 9 | 核心功能 | +| `/api/weapp/*` | 6 | 微信小程序 | +| `/api/file/*` | 4 | 文件 | +| `/api/area/*` | 4 | 地区 | +| `/api/ai/*` | 4 | AI | +| `/api/*` (其他) | 57 | 杂项 | +| **总计** | **678** | - | + +--- + +## ✅ 验证命令 + +### 查看路由分布 + +```bash +cd docker +docker compose logs api | grep "Mapped {" | \ + sed 's/.*Mapped {\([^}]*\)}.*/\1/' | \ + grep -oE '/api/[^/]+' | \ + sort | uniq -c | sort -rn +``` + +### 检查错误路由 + +```bash +# 应该返回 0 +docker compose logs api | grep "Mapped {" | grep "/api/api/" | wc -l +``` + +### 测试具体API + +```bash +# 健康检查 +curl http://localhost:3000/api/health | jq + +# 管理后台API(需认证) +curl http://localhost:3000/api/adminapi/addon/list | jq + +# 用户端API(按需认证) +curl http://localhost:3000/api/pay | jq +``` + +--- + +## 📚 相关文档 + +- [Docker测试报告](./DOCKER_TEST_REPORT.md) +- [认证修复方案](./AUTH_FIX.md) +- [认证验证报告](./AUTH_VERIFICATION_REPORT.md) + +--- + +## 💡 设计原理 + +### 为什么要去掉 `api` 前缀? + +NestJS应用配置了全局前缀 `/api` (在 `main.ts` 中): + +```typescript +// apps/api/src/main.ts +async function bootstrap() { + const app = await NestFactory.create(AppModule); + app.setGlobalPrefix('api'); // ← 全局前缀 + await app.listen(3000); +} +``` + +因此: +- ✅ `@Controller('adminapi')` → `/api/adminapi/*` +- ✅ `@Controller('member')` → `/api/member/*` +- ✅ `@Controller()` → `/api/*` +- ❌ `@Controller('api')` → `/api/api/*` (错误!) + +--- + +## 🎓 总结 + +你的理解**完全正确**: + +1. **后端管理端** = `/api/adminapi/*` (534个路由) +2. **用户端** = `/api/*` (144个路由,分布在member, pay, wechat等子路径) + +这种设计: +- ✅ 清晰分离管理后台和用户端 +- ✅ 统一使用 `/api` 作为API前缀 +- ✅ 与前端路由规范一致 +- ✅ 与Java版本完全对应 + +**🎉 完美对接!** + diff --git a/wwjcloud-nest-v1/tools/java-to-nestjs-migration/generators/controller-generator.js b/wwjcloud-nest-v1/tools/java-to-nestjs-migration/generators/controller-generator.js index 27f00522..febaa153 100644 --- a/wwjcloud-nest-v1/tools/java-to-nestjs-migration/generators/controller-generator.js +++ b/wwjcloud-nest-v1/tools/java-to-nestjs-migration/generators/controller-generator.js @@ -329,12 +329,18 @@ ${methods} if (routeInfo.controllerPath) { let cleanPath = routeInfo.controllerPath.replace(/^\/+/, ''); // 去掉前导斜杠 - // 如果路径以 'api/' 开头,去掉这个前缀(NestJS应用已有全局/api前缀) - if (cleanPath.startsWith('api/')) { + // 如果路径是 'api' 单独出现,或以 'api/' 开头,需要去掉(NestJS应用已有全局/api前缀) + if (cleanPath === 'api') { + cleanPath = ''; // 空字符串,表示根路径 + } else if (cleanPath.startsWith('api/')) { cleanPath = cleanPath.substring(4); // 去掉 'api/' } - decorators.push(`@Controller('${cleanPath}')`); + if (cleanPath) { + decorators.push(`@Controller('${cleanPath}')`); + } else { + decorators.push('@Controller()'); // 空路径使用无参数形式 + } } else { decorators.push('@Controller()'); } diff --git a/wwjcloud-nest-v1/tools/java-to-nestjs-migration/migration-report.json b/wwjcloud-nest-v1/tools/java-to-nestjs-migration/migration-report.json index 81aa42bc..9b8a6946 100644 --- a/wwjcloud-nest-v1/tools/java-to-nestjs-migration/migration-report.json +++ b/wwjcloud-nest-v1/tools/java-to-nestjs-migration/migration-report.json @@ -1,7 +1,7 @@ { - "timestamp": "2025-10-26T13:23:27.810Z", + "timestamp": "2025-10-26T13:30:05.823Z", "stats": { - "startTime": "2025-10-26T13:23:25.676Z", + "startTime": "2025-10-26T13:30:03.678Z", "endTime": null, "filesProcessed": 1390, "modulesGenerated": 6, diff --git a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/channel/app.controller.ts b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/channel/app.controller.ts index 4d2dbe02..dc366c56 100644 --- a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/channel/app.controller.ts +++ b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/channel/app.controller.ts @@ -3,7 +3,7 @@ import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagg import { AuthGuard, RbacGuard, Public, Result } from '@wwjBoot'; import { AppServiceImplService } from '../../../services/api/channel/impl/app-service-impl.service'; -@Controller('api') +@Controller() @ApiTags('API') export class AppController { constructor( diff --git a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/login/login.controller.ts b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/login/login.controller.ts index c5fa424d..09853f8a 100644 --- a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/login/login.controller.ts +++ b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/login/login.controller.ts @@ -7,7 +7,7 @@ import { WechatServiceImplService } from '../../../services/api/wechat/impl/wech import { WeappServiceImplService } from '../../../services/api/weapp/impl/weapp-service-impl.service'; import { AppServiceImplService } from '../../../services/api/channel/impl/app-service-impl.service'; -@Controller('api') +@Controller() @ApiTags('API') export class LoginController { constructor( diff --git a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/login/register.controller.ts b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/login/register.controller.ts index 34074733..c7bf5c86 100644 --- a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/login/register.controller.ts +++ b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/login/register.controller.ts @@ -5,7 +5,7 @@ import { RegisterServiceImplService } from '../../../services/api/login/impl/reg import { WechatServiceImplService } from '../../../services/api/wechat/impl/wechat-service-impl.service'; import { WeappServiceImplService } from '../../../services/api/weapp/impl/weapp-service-impl.service'; -@Controller('api') +@Controller() @ApiTags('API') export class RegisterController { constructor( diff --git a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/pay/pay.controller.ts b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/pay/pay.controller.ts index 6c0977a5..16cc4565 100644 --- a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/pay/pay.controller.ts +++ b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/pay/pay.controller.ts @@ -3,7 +3,7 @@ import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagg import { AuthGuard, RbacGuard, Public, Result } from '@wwjBoot'; import { PayServiceImplService } from '../../../services/admin/pay/impl/pay-service-impl.service'; -@Controller('api') +@Controller() @ApiTags('API') export class PayController { constructor( diff --git a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/.controller.ts b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/.controller.ts index 8a4d28ca..47f37113 100644 --- a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/.controller.ts +++ b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/.controller.ts @@ -3,7 +3,7 @@ import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagg import { AuthGuard, RbacGuard, Public, Result } from '@wwjBoot'; import { TaskServiceImplService } from '../../../services/api/sys/impl/task-service-impl.service'; -@Controller('api') +@Controller() @ApiTags('API') export class TaskController { constructor( diff --git a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/captcha.controller.ts b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/captcha.controller.ts index 0daa53e9..8e14a783 100644 --- a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/captcha.controller.ts +++ b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/captcha.controller.ts @@ -3,7 +3,7 @@ import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagg import { AuthGuard, RbacGuard, Public, Result } from '@wwjBoot'; import { CaptchaServiceImplService } from '../../../services/admin/captcha/impl/captcha-service-impl.service'; -@Controller('api') +@Controller() @ApiTags('API') export class CaptchaController { constructor( diff --git a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/sys-config.controller.ts b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/sys-config.controller.ts index e2ceb7a2..cc4bc0c8 100644 --- a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/sys-config.controller.ts +++ b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/sys-config.controller.ts @@ -9,7 +9,7 @@ import { MemberLevelServiceImplService } from '../../../services/admin/member/im import { DiyThemeServiceImplService } from '../../../services/admin/diy/impl/diy-theme-service-impl.service'; import { AppServiceImplService } from '../../../services/api/channel/impl/app-service-impl.service'; -@Controller('api') +@Controller() @ApiTags('API') export class SysConfigController { constructor( diff --git a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/sys-verify.controller.ts b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/sys-verify.controller.ts index 570d2df5..bd5bf7b1 100644 --- a/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/sys-verify.controller.ts +++ b/wwjcloud-nest-v1/wwjcloud/libs/wwjcloud-core/src/controllers/api/sys/sys-verify.controller.ts @@ -3,7 +3,7 @@ import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagg import { AuthGuard, RbacGuard, Public, Result } from '@wwjBoot'; import { SysVerifyServiceImplService } from '../../../services/api/sys/impl/sys-verify-service-impl.service'; -@Controller('api') +@Controller() @ApiTags('API') export class SysVerifyController { constructor(