服务层实现.md 22 KB

服务层实现

本文引用的文件

  • server/src/app.ts
  • server/src/modules/auth/auth.service.ts
  • server/src/modules/book-generator/book-generator.service.ts
  • server/src/modules/book-generator/book-queue.processor.ts
  • server/src/modules/tts/tts.service.ts
  • server/src/modules/player/player.service.ts
  • server/src/modules/subscription/subscription.service.ts
  • server/src/modules/member/member.service.ts
  • server/src/modules/payment/payment.service.ts
  • server/src/services/redis.service.ts
  • server/src/services/storage.service.ts
  • server/src/services/queue.service.ts
  • server/src/services/websocket.service.ts
  • server/src/services/oss.service.ts
  • server/src/config/index.ts
  • server/src/types/index.ts

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件面向AI有声书生成平台的服务层,系统性梳理服务层的设计原则、职责边界与实现细节,覆盖认证、书籍生成、TTS、播放器、订阅与支付、队列与缓存、存储与WebSocket等模块。文档强调业务逻辑封装、数据处理与第三方服务集成,给出异步任务处理、队列管理、缓存与存储策略,并提供依赖注入配置、生命周期管理与性能优化建议。

项目结构

服务层位于后端工程的 server/src 目录,采用按模块划分的组织方式:

  • app.ts 作为入口,装配中间件、路由与服务初始化
  • modules 下按功能拆分领域服务(auth、book-generator、tts、player、subscription、member、payment 等)
  • services 下提供基础设施服务(Redis、队列、存储、WebSocket、OSS、日志等)

    graph TB
    A["应用入口<br/>server/src/app.ts"] --> B["认证服务<br/>auth.service.ts"]
    A --> C["书籍生成服务<br/>book-generator.service.ts"]
    A --> D["TTS服务<br/>tts.service.ts"]
    A --> E["播放器服务<br/>player.service.ts"]
    A --> F["订阅服务<br/>subscription.service.ts"]
    A --> G["会员服务<br/>member.service.ts"]
    A --> H["支付服务<br/>payment.service.ts"]
    C --> I["队列服务<br/>queue.service.ts"]
    C --> J["书籍生成队列处理器<br/>book-queue.processor.ts"]
    D --> K["存储服务<br/>storage.service.ts"]
    D --> L["OSS服务<br/>oss.service.ts"]
    A --> M["WebSocket服务<br/>websocket.service.ts"]
    A --> N["Redis服务<br/>redis.service.ts"]
    A --> O["配置中心<br/>config/index.ts"]
    A --> P["类型定义<br/>types/index.ts"]
    

图示来源

  • server/src/app.ts:133-194
  • server/src/modules/book-generator/book-generator.service.ts:1-549
  • server/src/modules/tts/tts.service.ts:1-715
  • server/src/modules/player/player.service.ts:1-280
  • server/src/modules/subscription/subscription.service.ts:1-800
  • server/src/modules/member/member.service.ts:1-183
  • server/src/modules/payment/payment.service.ts:1-578
  • server/src/services/queue.service.ts:1-347
  • server/src/services/websocket.service.ts:1-136
  • server/src/services/redis.service.ts:1-274
  • server/src/services/storage.service.ts:1-278
  • server/src/services/oss.service.ts:1-256
  • server/src/config/index.ts:1-117
  • server/src/types/index.ts:1-124

章节来源

  • server/src/app.ts:133-194

核心组件

  • 认证服务:手机号验证码登录、JWT签发与用户信息查询
  • 书籍生成服务:批量生成编排器、内容/音频/视频生成与合并流程
  • TTS服务:多提供商(阿里云、MiniMax、Mock)抽象、文本分段、音频合并与上传
  • 播放器服务:播放进度持久化、章节合并音频
  • 订阅与支付:套餐配置、Token余额与使用、音频时长计费、支付回调与激活
  • 队列与缓存:Bull队列与内存队列双栈、Redis缓存
  • 存储与CDN:统一存储抽象(OSS/本地)、签名URL与批量清理
  • WebSocket:生成进度与完成事件推送

章节来源

  • server/src/modules/auth/auth.service.ts:1-115
  • server/src/modules/book-generator/book-generator.service.ts:1-549
  • server/src/modules/tts/tts.service.ts:1-715
  • server/src/modules/player/player.service.ts:1-280
  • server/src/modules/subscription/subscription.service.ts:1-800
  • server/src/modules/member/member.service.ts:1-183
  • server/src/modules/payment/payment.service.ts:1-578
  • server/src/services/queue.service.ts:1-347
  • server/src/services/websocket.service.ts:1-136
  • server/src/services/redis.service.ts:1-274
  • server/src/services/storage.service.ts:1-278
  • server/src/services/oss.service.ts:1-256

架构总览

服务层围绕“领域服务 + 基础设施服务”的分层设计,通过统一配置中心与类型系统支撑跨模块协作。应用入口负责初始化数据库、缓存、存储、WebSocket、队列与订阅计划,并在优雅退出时关闭资源。

graph TB
subgraph "应用层"
APP["应用入口<br/>app.ts"]
end
subgraph "领域服务"
AUTH["认证服务"]
BG["书籍生成服务"]
TTS["TTS服务"]
PLAYER["播放器服务"]
SUB["订阅服务"]
PAY["支付服务"]
MEM["会员服务"]
end
subgraph "基础设施服务"
REDIS["Redis服务"]
QUEUE["队列服务"]
WS["WebSocket服务"]
STORE["存储服务"]
OSS["OSS服务"]
CFG["配置中心"]
TYPES["类型定义"]
end
APP --> AUTH
APP --> BG
APP --> TTS
APP --> PLAYER
APP --> SUB
APP --> PAY
APP --> MEM
BG --> QUEUE
TTS --> STORE
STORE --> OSS
APP --> WS
APP --> REDIS
APP --> CFG
APP --> TYPES

图示来源

  • server/src/app.ts:133-194
  • server/src/config/index.ts:1-117
  • server/src/types/index.ts:1-124

详细组件分析

认证服务

  • 职责:手机号验证码生成与校验、JWT签发、用户信息查询
  • 设计要点:验证码内存存储(生产建议Redis)、免密登录开关、用户不存在即创建
  • 错误传播:验证码错误/过期、用户不存在抛出错误由上层中间件捕获

    sequenceDiagram
    participant Client as "客户端"
    participant AuthSvc as "认证服务"
    participant DB as "数据库"
    Client->>AuthSvc : "手机号+验证码登录"
    AuthSvc->>AuthSvc : "校验验证码"
    AuthSvc->>DB : "查找/创建用户"
    DB-->>AuthSvc : "用户记录"
    AuthSvc-->>Client : "返回token与用户信息"
    

图示来源

  • server/src/modules/auth/auth.service.ts:44-97

章节来源

  • server/src/modules/auth/auth.service.ts:1-115

书籍生成服务

  • 职责:批量生成编排(内容/音频/视频/合并),进度推送,取消标志与超时控制
  • 设计要点:LangGraph内容生成、叶节点并行音频生成、按父节点分组合并、视频生成与轮询检查
  • 错误传播:步骤级错误捕获与失败回退,WebSocket推送失败事件

    sequenceDiagram
    participant Client as "客户端"
    participant Orchestrator as "批量生成编排器"
    participant BGStore as "书籍存储"
    participant LangGraph as "LangGraph生成器"
    participant PlayerSvc as "播放器服务"
    participant WS as "WebSocket服务"
    Client->>Orchestrator : "创建批量任务"
    Orchestrator->>BGStore : "检查书籍状态"
    Orchestrator->>LangGraph : "生成内容"
    LangGraph-->>Orchestrator : "内容完成"
    Orchestrator->>BGStore : "批量生成音频"
    Orchestrator->>PlayerSvc : "合并章节音频"
    Orchestrator->>WS : "推送进度/完成"
    Orchestrator-->>Client : "返回结果"
    

图示来源

  • server/src/modules/book-generator/book-generator.service.ts:45-143
  • server/src/modules/book-generator/book-generator.service.ts:149-217
  • server/src/modules/book-generator/book-generator.service.ts:222-285
  • server/src/modules/book-generator/book-generator.service.ts:289-359
  • server/src/modules/book-generator/book-generator.service.ts:364-453
  • server/src/modules/book-generator/book-generator.service.ts:458-528

章节来源

  • server/src/modules/book-generator/book-generator.service.ts:1-549

TTS服务

  • 职责:多提供商抽象(阿里云、MiniMax、Mock)、文本分段、音频合并、上传存储、LRC歌词生成、AI标题/摘要/标签
  • 设计要点:Provider工厂、优先级尝试、并发控制、云端URL降级、进度与完成事件推送
  • 错误传播:额度限制降级到下一个Provider,非额度错误直接抛出

    flowchart TD
    Start(["开始生成"]) --> Split["文本分段"]
    Split --> ChooseProvider{"选择Provider"}
    ChooseProvider --> |阿里云/HTTP| GenHTTP["HTTP合成"]
    ChooseProvider --> |MiniMax| GenAsync["异步轮询"]
    ChooseProvider --> |Mock| GenMock["模拟生成"]
    GenHTTP --> Merge["音频合并"]
    GenAsync --> Merge
    GenMock --> Merge
    Merge --> Upload["上传存储"]
    Upload --> SaveDB["保存章节/记录"]
    SaveDB --> Callback["回调/推送完成"]
    Callback --> End(["结束"])
    

图示来源

  • server/src/modules/tts/tts.service.ts:201-280
  • server/src/modules/tts/tts.service.ts:285-542
  • server/src/modules/tts/tts.service.ts:547-597

章节来源

  • server/src/modules/tts/tts.service.ts:1-715

播放器服务

  • 职责:播放进度持久化(upsert)、章节合并音频(MP3合并)、最近播放记录
  • 设计要点:按章合并小节音频,自动转换相对URL为绝对路径,失败回退

    flowchart TD
    Req["请求章节音频URL"] --> CheckLevel{"是否为章(level=1)"}
    CheckLevel --> |否| ReturnURL["返回原音频URL"]
    CheckLevel --> |是| FindSubs["查找子节/小节音频"]
    FindSubs --> Merge["合并音频"]
    Merge --> SaveURL["更新章节音频URL"]
    SaveURL --> Done["返回合并后URL"]
    

图示来源

  • server/src/modules/player/player.service.ts:147-234

章节来源

  • server/src/modules/player/player.service.ts:1-280

订阅与支付服务

  • 订阅服务:套餐配置、Token余额与使用、音频时长配额与计费、书籍生成配额预估
  • 支付服务:支付宝/微信支付SDK懒加载、订单创建、支付链接/二维码生成、回调处理与订阅激活

    sequenceDiagram
    participant Client as "客户端"
    participant PaySvc as "支付服务"
    participant DB as "数据库"
    participant SubSvc as "订阅服务"
    Client->>PaySvc : "创建支付订单"
    PaySvc->>DB : "写入订单记录"
    PaySvc-->>Client : "返回支付链接/二维码"
    Client->>PaySvc : "支付回调"
    PaySvc->>DB : "更新订单状态"
    PaySvc->>SubSvc : "激活订阅/更新Token"
    SubSvc-->>Client : "返回成功"
    

图示来源

  • server/src/modules/payment/payment.service.ts:122-191
  • server/src/modules/payment/payment.service.ts:359-406
  • server/src/modules/subscription/subscription.service.ts:299-309

章节来源

  • server/src/modules/subscription/subscription.service.ts:1-800
  • server/src/modules/member/member.service.ts:1-183
  • server/src/modules/payment/payment.service.ts:1-578

队列与缓存

  • 队列服务:Bull队列(Redis)与内存队列双栈,任务状态查询、进度回调、统计与暂停/恢复
  • 书籍生成队列处理器:并发3,任务失败状态回写,服务器启动时恢复中断任务

    sequenceDiagram
    participant App as "应用入口"
    participant QSvc as "队列服务"
    participant BGProc as "书籍生成处理器"
    participant BGStore as "书籍存储"
    App->>QSvc : "初始化队列"
    App->>QSvc : "添加书籍生成任务"
    QSvc-->>BGProc : "分发任务"
    BGProc->>BGStore : "更新生成中状态"
    BGProc-->>QSvc : "完成/失败"
    App->>QSvc : "恢复中断任务"
    

图示来源

  • server/src/services/queue.service.ts:48-160
  • server/src/modules/book-generator/book-queue.processor.ts:48-83
  • server/src/modules/book-generator/book-queue.processor.ts:88-124

章节来源

  • server/src/services/queue.service.ts:1-347
  • server/src/modules/book-generator/book-queue.processor.ts:1-124

存储与CDN

  • 存储服务:统一抽象(OSS/本地),上传/下载/删除/签名URL,目录清理
  • OSS服务:文件/Buffer上传、签名URL、批量删除、内容类型推断

    classDiagram
    class StorageService {
    +setStorageType(type)
    +getStorageType()
    +uploadAudio(localPath, audioId)
    +uploadVideo(localPath, videoId)
    +uploadCover(localPath, bookId)
    +uploadFile(localPath, category, id)
    +uploadBuffer(buffer, objectKey, contentType)
    +deleteFile(url)
    +deleteDirectory(prefix, id)
    +downloadFile(url)
    +getSignedUrl(url, expires)
    +testConnection()
    }
    class OSSService {
    +uploadFile(localPath, objectKey)
    +uploadBuffer(buffer, objectKey, contentType)
    +uploadAudio(localPath, audioId)
    +uploadVideo(localPath, videoId)
    +uploadCover(localPath, bookId)
    +deleteFile(objectKey)
    +deleteDirectory(prefix)
    +getSignedUrl(objectKey, expires)
    +downloadFile(objectKey)
    +getFileUrl(objectKey)
    +testConnection()
    }
    StorageService --> OSSService : "委托"
    

图示来源

  • server/src/services/storage.service.ts:13-278
  • server/src/services/oss.service.ts:13-256

章节来源

  • server/src/services/storage.service.ts:1-278
  • server/src/services/oss.service.ts:1-256

WebSocket

  • 职责:客户端连接管理、事件广播、生成完成与进度推送
  • 应用:TTS/视频生成完成事件、批量生成进度

    sequenceDiagram
    participant Srv as "WebSocket服务"
    participant Client as "客户端"
    Srv->>Client : "连接成功"
    Srv-->>Client : "广播事件(生成完成/进度)"
    Client-->>Srv : "断开连接"
    Srv->>Srv : "移除客户端"
    

图示来源

  • server/src/services/websocket.service.ts:102-136
  • server/src/services/websocket.service.ts:67-95

章节来源

  • server/src/services/websocket.service.ts:1-136

依赖关系分析

  • 服务层耦合:领域服务依赖基础设施服务(队列、存储、缓存、WebSocket),通过单例注入
  • 外部依赖:Redis/Bull队列、OSS、第三方TTS提供商、支付SDK
  • 错误传播:服务层抛出业务错误,由全局中间件统一处理

    graph LR
    AUTH --> DB["Prisma"]
    BG --> QUEUE
    BG --> WS
    TTS --> STORE
    STORE --> OSS
    PLAYER --> DB
    SUB --> DB
    PAY --> DB
    MEM --> DB
    APP --> REDIS
    APP --> WS
    APP --> QUEUE
    APP --> STORE
    

图示来源

  • server/src/app.ts:133-194
  • server/src/modules/book-generator/book-generator.service.ts:1-549
  • server/src/modules/tts/tts.service.ts:1-715
  • server/src/modules/player/player.service.ts:1-280
  • server/src/modules/subscription/subscription.service.ts:1-800
  • server/src/modules/payment/payment.service.ts:1-578
  • server/src/modules/member/member.service.ts:1-183

章节来源

  • server/src/app.ts:133-194

性能考量

  • 并发与限流:队列默认并发3,TTS对MiniMax限制并发1,其他并发2;根据Provider能力动态调整
  • 超时与重试:队列任务超时配置(音频/视频/书籍),失败重试交由容错层处理
  • 缓存策略:Redis缓存键值与Hash,支持过期与批量删除;存储层统一抽象,减少分支判断
  • I/O优化:音频合并与存储上传分离,避免阻塞主线程;WebSocket仅广播必要事件
  • 成本控制:订阅服务内置Token与音频时长计费策略,前端预估显示

故障排查指南

  • 队列不可用:Redis连接失败时自动降级内存队列,检查Redis可用性与网络
  • TTS额度限制:Provider额度不足自动切换下一个,确认API Key配置与配额
  • 存储异常:OSS/本地存储失败时降级或报错,检查环境变量与权限
  • WebSocket断连:客户端离线或异常断开,服务端自动清理连接
  • 书籍生成中断:服务器重启后自动恢复生成中任务,检查数据库状态

章节来源

  • server/src/services/queue.service.ts:54-59
  • server/src/modules/tts/tts.service.ts:518-542
  • server/src/services/storage.service.ts:252-272
  • server/src/services/websocket.service.ts:118-125
  • server/src/modules/book-generator/book-queue.processor.ts:88-124

结论

服务层以清晰的职责边界与模块化设计支撑AI有声书生成平台的核心业务,通过统一配置与类型系统提升可维护性,借助队列、缓存与存储抽象实现高可用与可扩展性。建议持续完善监控与告警、优化并发策略与成本模型,并加强单元测试覆盖关键路径。

附录

  • 依赖注入与生命周期
    • 单例服务:redisService、storageService、ossService、queueService、websocket服务
    • 应用启动时初始化数据库连接、缓存与存储连通性、订阅计划、WebSocket、书籍生成队列与中断任务恢复
    • 优雅退出:关闭队列与Redis连接
  • 配置与类型
    • 配置中心集中管理端口、JWT、模型与上传参数
    • 类型系统约束请求/响应与领域模型字段

章节来源

  • server/src/app.ts:133-194
  • server/src/config/index.ts:1-117
  • server/src/types/index.ts:1-124