技术选型.md 17 KB

技术选型

本文引用的文件

  • my-uniapp-vue3/package.json
  • server/package.json
  • my-uniapp-vue3/tsconfig.json
  • server/tsconfig.json
  • server/prisma/schema.prisma
  • server/src/modules/book-generator/index.ts
  • server/src/modules/tts/tts.service.ts
  • server/src/services/ffmpeg.processor.ts
  • server/src/services/redis.service.ts
  • my-uniapp-vue3/vite.config.ts
  • server/src/config/index.ts
  • server/src/services/storage.service.ts
  • server/src/modules/video-generator/video-generator.service.ts
  • my-uniapp-vue3/src/main.ts

目录

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

引言

本技术选型文档面向“AI有声书生成平台”,围绕前端与后端技术栈、AI集成、媒体处理、数据库与缓存等维度进行系统化说明。重点解释以下选型理由:

  • 前端:采用 uni-app 实现跨平台兼容;Vue3 的响应式与组合式 API 提升开发效率;TypeScript 提供类型安全与工程化保障。
  • 后端:Koa.js 轻量灵活、易于扩展;TypeScript 工程化提升可维护性;Prisma ORM 提供强类型的数据库抽象与迁移能力。
  • AI 集成:LangChain 与 LangGraph 用于智能内容生成与流程编排;多模型提供商策略(阿里云、MiniMax 等)增强稳定性与弹性。
  • 媒体处理:FFmpeg 为核心引擎,fluent-ffmpeg 提供易用封装;结合统一存储与 Redis 缓存,构建高效媒体管线。
  • 数据库与缓存:MySQL 作为关系型主存储;Redis 提供高性能缓存与会话/限流等能力。

项目结构

项目采用前后端分离与模块化组织:

  • 前端:my-uniapp-vue3(uni-app + Vue3 + TypeScript + Pinia)
  • 后端:server(Koa + TypeScript + Prisma + LangChain/LangGraph + FFmpeg + Redis)

    graph TB
    FE["前端应用<br/>uni-app + Vue3 + TypeScript"] --> API["后端API<br/>Koa + TypeScript"]
    API --> DB["数据库<br/>MySQL + Prisma"]
    API --> CACHE["缓存<br/>Redis"]
    API --> MEDIA["媒体处理<br/>FFmpeg + fluent-ffmpeg"]
    API --> LLM["AI集成<br/>LangChain + LangGraph"]
    API --> STORE["存储服务<br/>OSS/本地"]
    

图示来源

  • my-uniapp-vue3/package.json:1-65
  • server/package.json:1-60
  • server/prisma/schema.prisma:1-472

章节来源

  • my-uniapp-vue3/package.json:1-65
  • server/package.json:1-60

核心组件

  • 前端框架:uni-app(一套 Vue3 生态的跨平台解决方案,支持 H5、小程序、快应用等多端)
  • 状态管理:Pinia(轻量、易用、TypeScript 友好)
  • 类型系统:TypeScript(严格类型检查,提升可维护性)
  • 后端框架:Koa(极简 Web 框架,中间件生态丰富)
  • ORM:Prisma(类型安全的数据库抽象与迁移工具)
  • AI 框架:LangChain、LangGraph(LLM 工作流编排与节点化处理)
  • 媒体处理:FFmpeg(核心编解码与转码)、fluent-ffmpeg(Node.js 封装)
  • 缓存:Redis(高性能键值存储,支持多种数据结构)
  • 存储:统一存储服务(OSS/本地无缝切换)

章节来源

  • my-uniapp-vue3/package.json:39-62
  • server/package.json:11-44

架构总览

整体架构分为三层:表现层(uni-app)、服务层(Koa + 模块化服务)、基础设施(MySQL、Redis、OSS/本地存储、FFmpeg)。

graph TB
subgraph "表现层"
U["用户界面<br/>uni-app + Vue3 + Pinia"]
end
subgraph "服务层"
K["Koa 应用"]
M1["TTS 服务<br/>多提供商策略"]
M2["视频生成服务<br/>FFmpeg 集成"]
M3["书籍生成器<br/>LangGraph 工作流"]
CFG["配置中心<br/>模型/密钥/阈值"]
ST["存储服务<br/>OSS/本地"]
RD["Redis 缓存"]
end
subgraph "基础设施"
DB["MySQL + Prisma"]
FS["文件系统/对象存储"]
FF["FFmpeg 处理器"]
end
U --> K
K --> M1
K --> M2
K --> M3
K --> CFG
M1 --> FF
M2 --> FF
M1 --> ST
M2 --> ST
M3 --> CFG
K --> DB
K --> RD
ST --> FS

图示来源

  • server/src/modules/tts/tts.service.ts:1-715
  • server/src/modules/video-generator/video-generator.service.ts:1-556
  • server/src/modules/book-generator/index.ts:1-104
  • server/src/services/ffmpeg.processor.ts:1-379
  • server/src/services/storage.service.ts:1-278
  • server/src/services/redis.service.ts:1-274
  • server/prisma/schema.prisma:1-472

详细组件分析

前端技术栈:uni-app + Vue3 + TypeScript

  • 跨平台兼容:通过 uni-app 的编译时多端适配,一套代码同时运行在 H5、微信小程序、支付宝小程序等平台,降低维护成本。
  • 响应式与组合式 API:Vue3 的 Composition API 更适合复杂业务逻辑的模块化拆分;配合 TypeScript 提供完善的类型推断与 IDE 支持。
  • 状态管理:Pinia 提供直观的 store 定义与类型安全,与 Vue3 协同良好。
  • 开发体验:Vite 作为构建工具,提供快速热更新与良好的 DX;开发服务器代理配置便于联调后端接口。

章节来源

  • my-uniapp-vue3/package.json:39-62
  • my-uniapp-vue3/tsconfig.json:1-14
  • my-uniapp-vue3/vite.config.ts:1-24
  • my-uniapp-vue3/src/main.ts:1-32

后端技术栈:Koa + TypeScript + Prisma

  • Koa.js 轻量灵活:中间件洋葱模型清晰,便于扩展认证、日志、限流、错误处理等横切能力。
  • TypeScript 工程化:严格的类型约束减少运行时错误,提升团队协作效率;与 Prisma 结合获得类型安全的数据库操作。
  • Prisma ORM:提供强类型的查询、迁移与种子数据管理,简化数据库抽象与版本演进。

章节来源

  • server/package.json:11-44
  • server/tsconfig.json:1-24
  • server/prisma/schema.prisma:1-472

AI 集成:LangChain 与 LangGraph

  • LangGraph 工作流:通过策略门面与节点化处理,支持“串行/一步大纲并行/逐章内聚”等多种生成策略,满足不同书籍规模与质量要求。
  • LLM 调用:统一的消息构建与解析流程,结合多提供商(阿里云、MiniMax 等)的自动切换与降级策略,提升稳定性与弹性。

    sequenceDiagram
    participant C as "客户端"
    participant API as "Koa 控制器"
    participant LG as "LangGraph 生成器"
    participant LLM as "LLM 服务"
    participant DB as "Prisma"
    C->>API : "发起生成请求"
    API->>LG : "选择策略并启动生成"
    LG->>LLM : "构建消息并调用 LLM"
    LLM-->>LG : "返回大纲/内容"
    LG->>DB : "持久化章节/书籍状态"
    LG-->>API : "生成完成"
    API-->>C : "返回结果"
    

图示来源

  • server/src/modules/book-generator/index.ts:1-104

章节来源

  • server/src/modules/book-generator/index.ts:1-104

多模型提供商集成策略

  • 多提供商:支持阿里云(DashScope/Qwen)、MiniMax 等,按优先级与可用性自动切换。
  • 自动降级:当出现配额/限流/服务不可用等错误时,自动切换到下一个可用提供商,保证生成成功率。
  • 配置中心:集中管理模型列表、默认模型、默认音色与切换规则,便于运维与灰度发布。

    flowchart TD
    Start(["开始生成"]) --> Pick["选择提供商优先级"]
    Pick --> TryProv{"尝试提供商"}
    TryProv --> |成功| Done["生成完成"]
    TryProv --> |额度/限流| Next["切换到下一个提供商"]
    Next --> TryProv
    TryProv --> |全部失败| Fail["返回失败"]
    

图示来源

  • server/src/modules/tts/tts.service.ts:160-190
  • server/src/config/index.ts:45-67

章节来源

  • server/src/modules/tts/tts.service.ts:160-190
  • server/src/config/index.ts:45-67

媒体处理:FFmpeg 与统一存储

  • FFmpeg 处理器:提供音频合并、音视频合成、格式转换、裁剪、音量调整、时长探测等能力;自动处理远程 URL 下载与上传。
  • 统一存储服务:支持 OSS 与本地存储无缝切换,屏蔽底层差异;提供上传、下载、删除、签名 URL 等能力。
  • 视频生成:基于 FFmpeg 的视频生成服务,支持带/不带背景音乐的合成,并与章节状态联动。

    sequenceDiagram
    participant S as "存储服务"
    participant F as "FFmpeg 处理器"
    participant O as "对象存储/OSS"
    participant L as "本地文件系统"
    S->>F : "上传音频/视频"
    F->>F : "下载远程资源到本地临时目录"
    F->>F : "执行 FFmpeg 命令合并/转码/合成"
    F->>S : "上传处理结果"
    alt OSS 模式
    S->>O : "上传文件"
    O-->>S : "返回访问 URL"
    else 本地模式
    S->>L : "写入 uploads 目录"
    L-->>S : "返回本地 URL"
    end
    S-->>调用方 : "返回最终 URL"
    

图示来源

  • server/src/services/ffmpeg.processor.ts:1-379
  • server/src/services/storage.service.ts:1-278

章节来源

  • server/src/services/ffmpeg.processor.ts:1-379
  • server/src/services/storage.service.ts:1-278
  • server/src/modules/video-generator/video-generator.service.ts:1-556

数据库与缓存:MySQL + Redis

  • MySQL:使用 Prisma 管理实体关系与迁移,覆盖用户、书籍、章节、订单、播放记录、订阅、素材等核心领域模型。
  • Redis:提供键值缓存、JSON 缓存、Hash、计数器、过期控制等能力;内置重连策略与连接状态监控,保障高并发下的稳定性。

    erDiagram
    USER {
    int id PK
    string phone
    string openid
    string nickname
    string avatar
    int memberLevel
    datetime memberExpireAt
    int dailyUsage
    string lastUsageDate
    datetime createdAt
    datetime updatedAt
    }
    BOOK {
    int id PK
    int userId
    string title
    string subtitle
    text description
    string coverUrl
    string targetAudience
    string style
    string bookScale
    int totalChapters
    int estimatedWords
    int progress
    boolean isPublished
    text outlineJson
    text foreword
    text afterword
    text errorMsg
    datetime createdAt
    datetime updatedAt
    string failedStage
    string genStage
    string status
    text bookAnalysis
    }
    BOOKCHAPTER {
    int id PK
    int bookId
    int parentId
    int level
    int number
    string title
    text summary
    text keyPoints
    int estimatedWords
    text content
    int wordCount
    text contentError
    datetime generatedAt
    text audioUrl
    int audioDuration
    text videoUrl
    int videoDuration
    boolean isPublic
    string genStage
    string status
    text lrcLyrics
    }
    ORDER {
    int id PK
    int userId
    string orderNo
    int planId
    string productType
    decimal amount
    string status
    string paymentMethod
    string paymentId
    datetime paidAt
    datetime createdAt
    datetime updatedAt
    }
    SUBSCRIPTIONPLAN {
    int id PK
    string name
    int level
    decimal priceMonthly
    decimal priceYearly
    text description
    text features
    boolean isRecommended
    boolean isActive
    int sortOrder
    int dailyGenerations
    int perGenerationLimit
    int monthlyTokens
    int monthlyMinutes
    int yearlyTokens
    int voiceOptions
    string audioQuality
    boolean apiAccess
    boolean batchProcessing
    boolean teamManagement
    boolean overageEnabled
    decimal overagePrice
    datetime createdAt
    datetime updatedAt
    }
    USER ||--o{ BOOK : "拥有"
    BOOK ||--o{ BOOKCHAPTER : "包含"
    USER ||--o{ ORDER : "下单"
    SUBSCRIPTIONPLAN ||--o{ ORDER : "被购买"
    

图示来源

  • server/prisma/schema.prisma:10-472

章节来源

  • server/prisma/schema.prisma:1-472
  • server/src/services/redis.service.ts:1-274

依赖关系分析

  • 前端依赖:@dcloudio/uni-app、vue、pinia、typescript、vite 等;通过脚本命令实现多端构建与开发。
  • 后端依赖:koa、@koa/router、@koa/bodyparser、@prisma/client、langchain、@langchain/langgraph、fluent-ffmpeg、ioredis、axios、bull 等;通过 tsx/tsc 实现开发与构建。
  • 配置与类型:前后端均使用 tsconfig 管理编译选项;后端通过 dotenv 与 models.json 管理环境变量与模型配置。

    graph LR
    subgraph "前端依赖"
    U["@dcloudio/uni-app"]
    V["vue"]
    P["pinia"]
    TS["typescript"]
    VT["vite"]
    end
    subgraph "后端依赖"
    K["koa"]
    PR["prisma"]
    LC["langchain"]
    LG["langgraph"]
    FF["fluent-ffmpeg"]
    RD["ioredis"]
    AX["axios"]
    end
    U --> V
    V --> P
    V --> TS
    VT --> U
    K --> PR
    K --> LC
    K --> LG
    K --> FF
    K --> RD
    K --> AX
    

图示来源

  • my-uniapp-vue3/package.json:39-62
  • server/package.json:11-44

章节来源

  • my-uniapp-vue3/package.json:1-65
  • server/package.json:1-60

性能考虑

  • 媒体处理并发:FFmpeg 处理器对音频分段与并发执行进行合理控制,避免资源争用;对长文本与实时模式采取降级策略,确保稳定性。
  • 存储与网络:统一存储服务在 OSS 与本地之间切换,减少网络抖动影响;对远程 URL 下载设置超时与重试策略。
  • 缓存策略:Redis 提供热点数据缓存与限流控制;对频繁读取的配置与用户偏好进行 TTL 管理。
  • 数据库优化:Prisma 提供索引与查询优化建议;对高频字段建立索引,避免 N+1 查询。

故障排查指南

  • TTS 生成失败:检查提供商可用性与配额;查看失败标记文件与数据库状态;确认回调与 WebSocket 推送是否正常。
  • FFmpeg 处理异常:确认临时目录权限与磁盘空间;检查命令参数与超时设置;核对输入 URL 与下载链路。
  • Redis 连接问题:检查主机、端口、密码与 DB 选择;关注重连策略与连接状态日志。
  • 存储异常:区分 OSS 与本地模式,核对对象键与签名 URL;确认权限与桶配置。

章节来源

  • server/src/modules/tts/tts.service.ts:257-280
  • server/src/services/ffmpeg.processor.ts:1-379
  • server/src/services/redis.service.ts:1-274
  • server/src/services/storage.service.ts:1-278

结论

本技术选型以“跨平台、可扩展、稳定可靠”为目标:

  • 前端采用 uni-app + Vue3 + TypeScript,兼顾多端一致性与开发效率;
  • 后端采用 Koa + TypeScript + Prisma,具备良好的工程化与可维护性;
  • AI 集成通过 LangChain/LangGraph 与多提供商策略,提升生成质量与稳定性;
  • 媒体处理以 FFmpeg 为核心,结合统一存储与缓存,形成高效的媒体管线;
  • 数据库与缓存分别承担关系型数据与高性能缓存职责,支撑业务高并发场景。

附录

  • 开发与构建:前端通过 npm scripts 调用 uni 与 vite;后端通过 tsx 开发、tsc 构建。
  • 代理配置:前端开发服务器对 /api、/uploads、/videos 进行代理,便于联调后端服务。

章节来源

  • my-uniapp-vue3/package.json:4-37
  • server/package.json:6-9
  • my-uniapp-vue3/vite.config.ts:7-21