控制器层设计
本文引用的文件
- server/src/app.ts
- server/src/modules/auth/auth.controller.ts
- server/src/modules/tts/tts.controller.ts
- server/src/modules/player/player.controller.ts
- server/src/modules/audioedit/audioedit.controller.ts
- server/src/modules/member/member.controller.ts
- server/src/modules/favorites/favorites.controller.ts
- server/src/modules/preferences/preferences.controller.ts
- server/src/modules/book-generator/book-generator.controller.ts
目录
- 引言
- 项目结构
- 核心组件
- 架构总览
- 详细组件分析
- 依赖关系分析
- 性能考量
- 故障排查指南
- 结论
- 附录
引言
本文件面向AI有声书生成平台的控制器层,系统性梳理控制器的设计模式与职责分离原则,阐释RESTful API设计规范、HTTP方法映射与路由组织策略,并结合用户认证、书籍生成、TTS服务、播放器等模块控制器的实现细节,说明控制器与服务层的交互模式、参数验证机制与统一响应格式化策略。同时给出最佳实践与常见问题排查建议,帮助开发者在保持高内聚低耦合的同时,构建可维护、可观测、可扩展的后端API体系。
项目结构
控制器层位于后端应用入口之下,采用按功能域分组的模块化组织方式,每个业务域拥有独立的控制器与服务层,通过统一的Koa应用注册路由,形成清晰的层次边界与职责划分。
- 应用入口负责中间件装配、静态资源挂载、全局健康检查与指标暴露,并集中注册各模块控制器路由。
- 控制器层专注于请求解析、参数校验、鉴权与限流、调用服务层、统一响应封装与错误处理。
- 服务层负责业务逻辑编排、第三方集成与持久化操作。
数据模型与中间件贯穿于控制器与服务之间,确保一致性与安全性。
graph TB
subgraph "应用入口"
APP["server/src/app.ts"]
end
subgraph "控制器层"
AUTH["auth.controller.ts"]
TTS["tts.controller.ts"]
PLAYER["player.controller.ts"]
AUDIOEDIT["audioedit.controller.ts"]
MEMBER["member.controller.ts"]
FAVORITES["favorites.controller.ts"]
PREFS["preferences.controller.ts"]
BOOKGEN["book-generator.controller.ts"]
end
subgraph "服务层"
SRV_AUTH["auth.service.ts"]
SRV_TTS["tts.service.ts"]
SRV_PLAYER["player.service.ts"]
SRV_AUDIOEDIT["audioedit.service.ts"]
SRV_MEMBER["member.service.ts"]
SRV_FAVORITES["favorites.service.ts"]
SRV_PREFS["preferences.service.ts"]
SRV_BOOKGEN["book-generator.service.ts"]
end
APP --> AUTH
APP --> TTS
APP --> PLAYER
APP --> AUDIOEDIT
APP --> MEMBER
APP --> FAVORITES
APP --> PREFS
APP --> BOOKGEN
AUTH --> SRV_AUTH
TTS --> SRV_TTS
PLAYER --> SRV_PLAYER
AUDIOEDIT --> SRV_AUDIOEDIT
MEMBER --> SRV_MEMBER
FAVORITES --> SRV_FAVORITES
PREFS --> SRV_PREFS
BOOKGEN --> SRV_BOOKGEN
图表来源
- server/src/app.ts:100-128
- server/src/modules/auth/auth.controller.ts:1-94
- server/src/modules/tts/tts.controller.ts:1-274
- server/src/modules/player/player.controller.ts:1-344
- server/src/modules/audioedit/audioedit.controller.ts:1-103
- server/src/modules/member/member.controller.ts:1-90
- server/src/modules/favorites/favorites.controller.ts:1-76
- server/src/modules/preferences/preferences.controller.ts:1-50
- server/src/modules/book-generator/book-generator.controller.ts:1-199
章节来源
- server/src/app.ts:100-128
核心组件
- 用户认证控制器:提供短信验证码发送、手机号登录、用户信息获取与更新等接口,内置参数校验与鉴权中间件保护。
- TTS服务控制器:提供音色列表、服务商列表、异步音频生成、状态查询、预览音色、单/批量下载等能力,集成配额与用量限制。
- 播放器控制器:提供播放进度管理、最近播放、公开状态控制、章节音频列表与详情等接口,支持公开与私有内容访问控制。
- 音频编辑控制器:提供音频裁剪、合并与信息查询等基础编辑能力。
- 会员与偏好控制器:提供会员权益、状态、订单、模拟支付以及用户偏好设置等接口。
- 书籍生成控制器:提供一键批量生成书籍(内容、音频、合并、视频生成与合并)的调度与状态查询,支持取消与并发控制。
章节来源
- server/src/modules/auth/auth.controller.ts:1-94
- server/src/modules/tts/tts.controller.ts:1-274
- server/src/modules/player/player.controller.ts:1-344
- server/src/modules/audioedit/audioedit.controller.ts:1-103
- server/src/modules/member/member.controller.ts:1-90
- server/src/modules/preferences/preferences.controller.ts:1-50
- server/src/modules/book-generator/book-generator.controller.ts:1-199
架构总览
控制器层遵循“薄控制器、厚服务”的设计原则,将业务逻辑下沉至服务层,控制器仅承担:
图表来源
- server/src/app.ts:64-83
- server/src/modules/auth/auth.controller.ts:11-52
- server/src/modules/tts/tts.controller.ts:53-127
- server/src/modules/player/player.controller.ts:14-53
详细组件分析
用户认证控制器
- 设计要点
- 使用Koa Router进行路由声明,区分匿名与受保护接口。
- 对手机号格式进行即时校验,避免无效请求进入服务层。
- 在受保护接口中注入鉴权中间件,从上下文提取用户标识。
- HTTP方法与路由
- POST /api/auth/send-code:发送验证码(开发环境直接返回验证码便于联调)
- POST /api/auth/login:手机号登录(当前版本跳过验证码校验)
- GET /api/auth/user-info:获取用户信息(需鉴权)
- PUT /api/auth/user-info:更新用户信息(昵称/头像)
- 参数验证与错误处理
- 使用自定义错误类型抛出语义化错误,便于统一处理。
- 对缺失或非法参数返回明确提示,避免服务层重复校验。
响应格式
统一采用 { code, message, data } 结构,code为0表示成功,非0为业务错误码。
flowchart TD
Start(["请求进入"]) --> Parse["解析请求体<br/>校验手机号格式"]
Parse --> Valid{"格式有效?"}
Valid -- 否 --> Err["抛出参数错误"]
Valid -- 是 --> SendCode["生成验证码并返回"]
SendCode --> End(["结束"])
Err --> End
图表来源
- server/src/modules/auth/auth.controller.ts:11-30
章节来源
- server/src/modules/auth/auth.controller.ts:11-92
TTS服务控制器
- 设计要点
- 提供音色与服务商查询、异步生成、状态查询、预览音色、下载与批量下载等能力。
- 集成可选鉴权与用量配额检查,保障资源合理使用。
- 对外部依赖(数据库、存储)进行健壮性处理,避免上游异常影响响应。
- HTTP方法与路由
- GET /api/tts/voices:获取可用音色列表
- GET /api/tts/providers:获取可用TTS服务商列表
- GET /api/tts/test-db:测试数据库连通性
- POST /api/tts/generate:异步生成音频(支持bookId/章节标题关联)
- GET /api/tts/status/:audioId:查询生成状态
- POST /api/tts/preview:预览音色(固定短文本)
- GET /api/tts/download/:audioId:获取下载信息
- POST /api/tts/download/batch:批量下载音频
- 参数验证与错误处理
- 文本长度、音色选择、书籍存在性等前置校验。
- 使用统一错误类型与状态码,保证前后端一致的错误语义。
响应格式
统一结构,data中包含具体业务数据;下载类接口直接返回可下载URL。
sequenceDiagram
participant Client as "客户端"
participant Ctrl as "TTS控制器"
participant Svc as "TTS服务"
participant Sub as "订阅服务"
participant DB as "数据库"
Client->>Ctrl : "POST /api/tts/generate"
Ctrl->>Ctrl : "校验文本/音色/可选书籍"
Ctrl->>Sub : "检查配额/估算分钟数"
Ctrl->>Svc : "异步生成音频"
Svc->>DB : "持久化任务/状态"
DB-->>Svc : "确认"
Svc-->>Ctrl : "返回任务信息"
Ctrl-->>Client : "{code,message,data}"
图表来源
- server/src/modules/tts/tts.controller.ts:53-127
- server/src/modules/tts/tts.controller.ts:183-221
章节来源
- server/src/modules/tts/tts.controller.ts:13-274
播放器控制器
- 设计要点
- 提供播放进度的增删改查与批量操作,支持公开与私有内容访问控制。
- 为开发环境提供测试用户ID,便于前端联调。
- 章节级音频适配:对章节(level=1)自动合并小节音频,提升播放体验。
- HTTP方法与路由
- GET /api/player/progress:获取播放进度列表(可按audioId过滤)
- POST /api/player/progress:保存播放进度
- PUT /api/player/progress/:audioId:更新播放进度
- DELETE /api/player/progress/:audioId:删除单条记录
- DELETE /api/player/progress/batch:批量删除
- GET /api/player/recent:获取用户最近播放记录(未登录返回空列表)
- GET /api/player/audio/list:获取章节音频列表(公开+个人)
- GET /api/player/audio/:id:获取章节音频详情(公开/所有者/匿名)
- PUT /api/player/audio/:id/public:更新章节公开状态
- 参数验证与错误处理
- 对必需参数进行类型与范围校验,非法参数抛出语义化错误。
- 访问控制严格:非公开内容且非所有者拒绝访问。
响应格式
图表来源
- server/src/modules/player/player.controller.ts:230-294
章节来源
- server/src/modules/player/player.controller.ts:14-344
音频编辑控制器
- 设计要点
- 提供音频裁剪、合并与信息查询的基础能力,参数校验与错误处理集中在控制器层。
- HTTP方法与路由
- POST /api/audio/trim:裁剪音频(起止时间校验)
- POST /api/audio/merge:合并音频(最少两张,顺序可选)
- GET /api/audio/:audioId/info:获取音频信息
- 响应格式
- 成功时返回 { code: 0, message: "success", data };失败时返回 { code: 400, message }。
章节来源
- server/src/modules/audioedit/audioedit.controller.ts:10-103
会员与偏好控制器
- 设计要点
- 会员控制器:权益查询、状态查询、订单创建、模拟支付(仅开发)、订单列表。
- 偏好控制器:获取与更新用户偏好(播放速度、音质、主题、默认音色、音量、自动播放、仅WiFi下载等)。
- HTTP方法与路由
- 会员:GET /api/member/benefits、GET /api/member/status、POST /api/member/order、POST /api/member/pay/mock、GET /api/member/orders
- 偏好:GET /api/user/preferences/、PUT /api/user/preferences/
- 参数验证与错误处理
- 对产品类型、订单号等关键参数进行校验,非法输入抛出语义化错误。
章节来源
- server/src/modules/member/member.controller.ts:9-90
- server/src/modules/preferences/preferences.controller.ts:12-47
书籍生成控制器
- 设计要点
- 提供一键批量生成书籍的调度与状态查询,支持取消与并发控制。
- 通过Map维护运行中的任务,避免重复触发。
- HTTP方法与路由
- POST /api/book-generator/books/:id/batch-generate:启动批量生成(可指定步骤)
- POST /api/book-generator/books/:id/batch-generate/cancel:取消任务
- GET /api/book-generator/books/:id/batch-generate/status:查询状态
参数验证与错误处理
- 书籍存在性、步骤合法性、并发冲突等前置校验。
异常捕获与清理,确保任务状态一致性。
sequenceDiagram
participant Client as "客户端"
participant Ctrl as "书籍生成控制器"
participant Svc as "书籍生成服务"
participant WS as "WebSocket服务"
Client->>Ctrl : "POST /batch-generate"
Ctrl->>Ctrl : "校验书籍/步骤/并发"
Ctrl->>Svc : "创建并启动任务"
Svc-->>Ctrl : "返回taskId/orchestrator"
Ctrl->>WS : "推送进度"
Ctrl-->>Client : "{code,message,data}"
Client->>Ctrl : "POST /cancel"
Ctrl->>Ctrl : "查找任务并设置取消标志"
Ctrl-->>Client : "{code,message,data}"
图表来源
- server/src/modules/book-generator/book-generator.controller.ts:24-119
- server/src/modules/book-generator/book-generator.controller.ts:125-156
章节来源
- server/src/modules/book-generator/book-generator.controller.ts:24-199
收藏控制器
- 设计要点
- 提供收藏列表、添加、取消、检查是否已收藏等能力,支持可选鉴权。
- HTTP方法与路由
- GET /api/favorites/:获取收藏列表
- POST /api/favorites/:添加收藏
- DELETE /api/favorites/:audioId:取消收藏
- GET /api/favorites/check/:audioId:检查是否已收藏
章节来源
- server/src/modules/favorites/favorites.controller.ts:12-76
依赖关系分析
- 控制器与中间件
- 统一错误处理、性能监控、安全防护、CORS、限流等中间件在应用入口装配,控制器无需重复实现。
- 鉴权中间件(如authMiddleware、optionalAuth)在控制器中按需启用。
- 控制器与服务层
- 控制器仅负责编排与编解码,业务逻辑下沉至服务层,降低控制器复杂度。
- 服务层内部可能进一步拆分领域服务,控制器不感知具体实现细节。
控制器与数据层
通过Prisma等ORM进行数据访问,控制器仅传递必要参数,避免直接操作底层SQL。
graph LR
CTRL_AUTH["auth.controller.ts"] --> MWARE_AUTH["auth.ts(鉴权)"]
CTRL_TTS["tts.controller.ts"] --> MWARE_USAGE["usageLimit.ts(用量)"]
CTRL_PLAYER["player.controller.ts"] --> MWARE_OPTAUTH["auth.ts(可选鉴权)"]
CTRL_BOOKGEN["book-generator.controller.ts"] --> SVC_BOOKGEN["book-generator.service.ts"]
CTRL_TTS --> SVC_TTS["tts.service.ts"]
CTRL_PLAYER --> SVC_PLAYER["player.service.ts"]
图表来源
- server/src/app.ts:64-83
- server/src/modules/tts/tts.controller.ts:5-8
- server/src/modules/player/player.controller.ts:4-6
- server/src/modules/book-generator/book-generator.controller.ts:8-13
章节来源
性能考量
- 异步与后台任务
- TTS与书籍生成等耗时操作采用异步任务与队列处理,控制器快速返回,避免阻塞请求线程。
- 并发控制
- 书籍生成控制器通过Map记录运行中的任务,防止重复触发与资源竞争。
- 限流与配额
- TTS控制器集成用量配额检查,避免超支;应用层可启用全局限流中间件(当前已注释)。
- 缓存与存储
- Redis用于缓存热点数据;OSS/本地存储用于音视频文件,控制器仅返回URL,减少响应体大小。
故障排查指南
- 统一错误处理
- 控制器抛出自定义错误类型(如BadRequestError、NotFoundError),由全局中间件捕获并格式化输出。
- 常见问题定位
- 参数错误:检查控制器参数校验分支与错误码。
- 权限不足:确认鉴权中间件是否正确配置,用户身份是否正确注入。
- 资源不存在:检查服务层查询条件与数据库状态。
- 外部依赖异常:查看数据库/存储/第三方服务连通性测试接口。
- 日志与监控
- 应用层集成Winston日志与Sentry错误监控,配合性能中间件与指标接口定位瓶颈。
章节来源
- server/src/app.ts:64-83
- server/src/modules/tts/tts.controller.ts:35-50
结论
控制器层通过清晰的RESTful路由设计、严格的参数与鉴权校验、统一的响应与错误处理机制,实现了与服务层的高内聚低耦合协作。结合异步任务、并发控制与限流配额策略,平台在保证用户体验的同时,兼顾了系统的稳定性与可维护性。建议后续持续完善API文档生成与契约校验,进一步提升团队协作效率与系统演进能力。
附录
- API路由组织策略
- 按模块前缀分组:/api/auth、/api/tts、/api/player、/api/book-generator 等。
- 子资源与动作组合:如 /api/player/audio/:id/public 表达更新公开状态的动作。
- 最佳实践清单
- 控制器只做“薄薄一层”,业务逻辑下沉至服务层。
- 统一响应结构与错误码,便于前端一致处理。
- 对外暴露的接口尽量幂等,必要时引入请求去重与状态查询。
- 对敏感操作(如公开状态变更、支付模拟)严格鉴权与环境限制。