代码规范.md 16 KB

代码规范

本文引用的文件

  • server/package.json
  • my-uniapp-vue3/package.json
  • server/tsconfig.json
  • my-uniapp-vue3/tsconfig.json
  • server/src/app.ts
  • server/prisma/schema.prisma
  • server/src/modules/auth/auth.controller.ts
  • server/src/modules/tts/tts.controller.ts
  • server/src/middleware/errorHandler.ts
  • server/src/services/logger.service.ts
  • my-uniapp-vue3/src/main.ts
  • my-uniapp-vue3/src/components/AudioDownload.vue
  • my-uniapp-vue3/src/store/user.ts

目录

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

简介

本规范面向AI有声书生成平台的前后端团队,统一TypeScript/JavaScript编码风格、Vue3组件开发规范、命名约定与文件组织结构,并给出数据库模型规范、代码格式化工具配置建议、Git提交信息规范以及代码审查检查清单。目标是提升代码一致性、可维护性与协作效率。

项目结构

  • 后端采用Koa + TypeScript,模块化路由与服务分层清晰;数据库使用Prisma + MySQL。
  • 前端基于UniApp + Vue3 + Pinia,组件按功能页面拆分,状态集中管理。
  • 构建与脚本在各自package.json中定义,类型检查与路径别名在tsconfig中配置。

    graph TB
    subgraph "后端"
    APP["应用入口<br/>server/src/app.ts"]
    ROUTER["路由注册<br/>各模块控制器"]
    MWARE["中间件<br/>错误处理/安全/限流/日志"]
    SRV["服务层<br/>业务逻辑封装"]
    PRISMA["数据模型<br/>server/prisma/schema.prisma"]
    end
    subgraph "前端"
    MAIN["应用入口<br/>my-uniapp-vue3/src/main.ts"]
    STORE["状态管理<br/>Pinia Store"]
    COMP["组件库<br/>my-uniapp-vue3/src/components/*.vue"]
    PAGE["页面路由<br/>my-uniapp-vue3/src/pages/*.vue"]
    end
    APP --> ROUTER --> SRV --> PRISMA
    APP --> MWARE
    MAIN --> STORE
    MAIN --> COMP
    MAIN --> PAGE
    

图表来源

  • server/src/app.ts:1-194
  • server/prisma/schema.prisma:1-472
  • my-uniapp-vue3/src/main.ts:1-32

章节来源

  • server/src/app.ts:1-194
  • my-uniapp-vue3/src/main.ts:1-32

核心组件

  • 应用入口与路由装配:后端通过Koa创建HTTP服务,挂载中间件、静态资源与路由;前端通过createSSRApp初始化应用与Pinia。
  • 数据模型:Prisma Schema定义了用户、书籍、章节、播放记录、订单、订阅等核心实体及索引策略。
  • 控制器与服务:控制器负责参数校验、权限控制与响应封装;服务层封装业务逻辑与外部调用。
  • 中间件与日志:统一错误处理、安全防护、性能监控与Winston日志记录。
  • 前端组件与状态:组件职责单一、Props明确、事件与生命周期管理规范;Pinia集中管理用户状态与派生状态。

章节来源

  • server/src/app.ts:1-194
  • server/prisma/schema.prisma:1-472
  • server/src/modules/auth/auth.controller.ts:1-94
  • server/src/modules/tts/tts.controller.ts:1-274
  • server/src/middleware/errorHandler.ts:1-67
  • server/src/services/logger.service.ts:1-114
  • my-uniapp-vue3/src/components/AudioDownload.vue:1-179
  • my-uniapp-vue3/src/store/user.ts:1-107

架构总览

后端采用“中间件 -> 路由 -> 控制器 -> 服务 -> 数据库”的分层结构;前端采用“页面/组件 -> Store -> API工具”的分层结构。日志与错误处理贯穿全链路,确保可观测性与稳定性。

sequenceDiagram
participant C as "客户端"
participant R as "路由层<br/>控制器"
participant S as "服务层"
participant D as "数据库<br/>Prisma"
C->>R : "HTTP请求"
R->>R : "参数校验/权限检查"
R->>S : "调用业务逻辑"
S->>D : "查询/写入"
D-->>S : "结果集"
S-->>R : "聚合结果"
R-->>C : "统一响应结构"

图表来源

  • server/src/app.ts:100-128
  • server/src/modules/tts/tts.controller.ts:52-127
  • server/prisma/schema.prisma:130-194

详细组件分析

后端:应用入口与中间件

  • 中间件顺序与职责:
    • 错误处理:捕获异常并返回统一结构。
    • 安全防护:XSS与SQL注入防护。
    • CORS与BodyParser:跨域与请求体解析。
    • 限流与性能监控:预留限流开关与性能指标。
    • 日志:Winston记录HTTP请求与错误。
  • 路由注册:按模块挂载子路由前缀,统一暴露REST接口。
  • 启动流程:初始化Sentry、连接数据库、测试Redis与存储、初始化WebSocket、启动队列处理器、优雅关闭。

    flowchart TD
    Start(["启动"]) --> InitSentry["初始化Sentry"]
    InitSentry --> ConnectDB["连接数据库"]
    ConnectDB --> TestRedis["测试Redis连接"]
    TestRedis --> TestStorage["测试存储连接"]
    TestStorage --> InitPlans["初始化订阅套餐"]
    InitPlans --> InitWS["初始化WebSocket"]
    InitWS --> Listen["监听端口"]
    Listen --> Queue["初始化队列处理器"]
    Queue --> Resume["恢复中断任务"]
    Resume --> Graceful["注册优雅关闭"]
    Graceful --> End(["运行中"])
    

图表来源

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

章节来源

  • server/src/app.ts:64-130
  • server/src/app.ts:133-192

后端:控制器与服务层

  • 控制器规范:
    • 使用Koa Router定义路由,参数从ctx.request.body或ctx.params读取。
    • 使用自定义错误类抛出语义化错误,便于统一处理。
    • 响应统一结构:{ code, message, data }。
  • 服务层规范:
    • 将业务逻辑封装在服务中,避免控制器臃肿。
    • 对外依赖抽象(如TTS提供商),便于替换与测试。
  • 示例:TTS控制器对文本长度、音色、配额进行严格校验,并支持异步生成与状态查询。

    sequenceDiagram
    participant Client as "客户端"
    participant Ctrl as "TTS控制器"
    participant Svc as "TTS服务"
    participant Sub as "订阅服务"
    participant DB as "Prisma"
    Client->>Ctrl : "POST /api/tts/generate"
    Ctrl->>Ctrl : "参数校验/配额检查"
    Ctrl->>Sub : "checkAudioQuota(userId, words)"
    Sub-->>Ctrl : "允许/拒绝"
    Ctrl->>Svc : "generateAudio(...)"
    Svc->>DB : "持久化记录"
    DB-->>Svc : "成功"
    Svc-->>Ctrl : "{audioId}"
    Ctrl-->>Client : "{code,message,data}"
    

图表来源

  • server/src/modules/tts/tts.controller.ts:52-127
  • server/src/middleware/errorHandler.ts:26-67

章节来源

  • server/src/modules/tts/tts.controller.ts:1-274
  • server/src/middleware/errorHandler.ts:1-67

后端:数据库模型与索引

  • 实体关系:
    • 用户与书籍、章节、播放记录、收藏、评论、订单、订阅、播放列表等强关联。
    • 订单与订阅计划多对一,章节与书籍一对多。
  • 索引策略:
    • 多数查询条件建立复合索引或单列索引,如用户+时间、状态、唯一组合等。
    • 外键关系显式映射,保证引用完整性。
  • 字段约束:

    • 时间戳、金额、枚举字符串状态、长文本字段使用合适类型与长度。

      erDiagram
      USER {
      int id PK
      string phone UK
      string openid UK
      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 status
      string genStage
      datetime createdAt
      datetime updatedAt
      }
      BOOKCHAPTER {
      int id PK
      int bookId FK
      int parentId
      int level
      int number
      string title
      string status
      string genStage
      datetime updatedAt
      }
      ORDER {
      int id PK
      int userId FK
      string orderNo UK
      int planId FK
      string productType
      decimal amount
      string status
      datetime paidAt
      datetime createdAt
      datetime updatedAt
      }
      SUBSCRIPTIONPLAN {
      int id PK
      string name
      int level
      decimal priceMonthly
      boolean isRecommended
      int dailyGenerations
      int monthlyMinutes
      datetime createdAt
      datetime updatedAt
      }
      PLAYRECORD {
      int id PK
      int userId FK
      int chapterId FK
      float progress
      float duration
      datetime updatedAt
      }
      FAVORITE {
      int id PK
      int userId FK
      int bookId FK
      datetime createdAt
      }
      COMMENT {
      int id PK
      int userId FK
      int chapterId FK
      string content
      int rating
      datetime createdAt
      }
      USERPREFERENCE {
      int id PK
      int userId UK
      float playSpeed
      string quality
      string theme
      string defaultVoiceId
      int defaultVolume
      boolean autoPlayNext
      boolean wifiOnlyDownload
      datetime createdAt
      datetime updatedAt
      }
      AUDIORECORD {
      int id PK
      int userId
      string audioId UK
      string title
      int wordCount
      string voiceId
      string audioUrl
      int audioDuration
      int audioSize
      string status
      datetime createdAt
      datetime updatedAt
      }
      USER ||--o{ BOOK : "拥有"
      BOOK ||--o{ BOOKCHAPTER : "包含"
      USER ||--o{ ORDER : "下单"
      SUBSCRIPTIONPLAN ||--o{ ORDER : "被购买"
      USER ||--o{ PLAYRECORD : "播放"
      BOOKCHAPTER ||--o{ PLAYRECORD : "被记录"
      USER ||--o{ FAVORITE : "收藏"
      BOOK ||--o{ FAVORITE : "被收藏"
      USER ||--o{ COMMENT : "发表"
      BOOKCHAPTER ||--o{ COMMENT : "被评论"
      USER ||--o{ AUDIORECORD : "生成"
      

图表来源

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

章节来源

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

前端:应用入口与状态管理

  • 应用入口:创建SSR应用、安装Pinia,初始化用户状态。
  • 状态管理:使用Pinia Store集中管理token、用户信息、会员状态;提供派生状态与方法。
  • 组件规范:Props明确、默认值合理、事件与生命周期管理清晰;组件职责单一、可复用性强。

    classDiagram
    class UserStore {
    +token : string|null
    +userInfo : UserInfo|null
    +memberStatus : MemberStatus|null
    +isLoggedIn : computed
    +isMember : computed
    +initUser()
    +login(phone, code)
    +sendCode(phone)
    +fetchUserInfo()
    +fetchMemberStatus()
    +logout()
    +updateUserInfo(info)
    }
    

图表来源

  • my-uniapp-vue3/src/store/user.ts:7-107

章节来源

  • my-uniapp-vue3/src/main.ts:1-32
  • my-uniapp-vue3/src/store/user.ts:1-107

前端:组件开发规范示例

  • 组件职责:单一功能、可插槽扩展、具备重试与进度反馈。
  • Props定义:明确必填与可选字段,提供默认值。
  • 生命周期:在setup中声明响应式状态,避免副作用在模板中直接执行。
  • 事件处理:对外暴露事件,内部通过Promise封装异步操作。

    flowchart TD
    Click["点击下载"] --> Check["检查下载状态"]
    Check --> |已下载| End["结束"]
    Check --> |未下载| RetryLoop["重试循环(最多N次)"]
    RetryLoop --> Exec["执行下载"]
    Exec --> Save["保存到本地"]
    Save --> Success["成功提示"]
    Exec --> Fail["失败处理"]
    Fail --> RetryLoop
    

图表来源

  • my-uniapp-vue3/src/components/AudioDownload.vue:34-129

章节来源

  • my-uniapp-vue3/src/components/AudioDownload.vue:1-179

依赖关系分析

  • 后端依赖:Koa生态、Prisma、LangChain/LangGraph、队列与缓存、对象存储、Sentry、Winston等。
  • 前端依赖:UniApp、Vue3、Pinia、类型与构建工具等。

    graph LR
    subgraph "后端依赖"
    Koa["@koa/*"]
    Prisma["@prisma/client"]
    Lang["@langchain/*"]
    Bull["bull"]
    Redis["ioredis"]
    Axios["axios"]
    Winston["winston"]
    Sentry["@sentry/*"]
    end
    subgraph "前端依赖"
    UniApp["@dcloudio/uni-app*"]
    Vue["vue"]
    Pinia["pinia"]
    Types["@dcloudio/types"]
    end
    

图表来源

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

章节来源

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

性能考虑

  • 后端:
    • 合理使用索引与查询条件,避免全表扫描;对高频查询建立复合索引。
    • 限制请求体大小与文件上传大小,防止资源滥用。
    • 使用队列异步处理耗时任务(如TTS生成),控制器快速返回。
    • 性能监控与指标导出,结合日志定位瓶颈。
  • 前端:
    • 组件懒加载与按需引入,减少首屏体积。
    • 下载组件增加重试与进度反馈,改善用户体验。
    • Pinia状态粒度适中,避免过度响应式导致的渲染抖动。

故障排查指南

  • 统一错误处理:
    • 自定义错误类覆盖常见场景(未授权、禁止、不存在、参数错误、配额超限)。
    • 中间件捕获异常并返回统一结构,开发环境附加堆栈信息。
  • 日志体系:
    • Winston记录HTTP请求与错误,区分级别与文件滚动策略。
    • 结合Sentry进行错误采样与性能追踪。
  • 常见问题定位:
    • 接口报错:查看统一响应中的code/message,结合日志定位具体请求。
    • 数据库异常:检查Prisma生成的客户端与索引是否匹配查询条件。
    • 前端下载失败:检查URL有效性、网络状态与重试机制。

章节来源

  • server/src/middleware/errorHandler.ts:1-67
  • server/src/services/logger.service.ts:1-114

结论

通过统一的编码规范、清晰的分层架构与完善的日志/错误处理体系,本项目能够在复杂业务场景下保持高可维护性与高可靠性。建议在后续迭代中持续完善代码审查与自动化质量门禁,保障交付质量。

附录

代码格式化与类型检查

  • TypeScript编译配置:
    • 后端:NodeNext模块解析、ES2022目标、严格模式关闭以便过渡期兼容。
    • 前端:继承官方tsconfig、启用sourceMap、配置路径别名@/*。
  • 类型检查脚本:
    • 前端提供type-check脚本用于编译期类型校验。

章节来源

  • server/tsconfig.json:1-24
  • my-uniapp-vue3/tsconfig.json:1-14
  • my-uniapp-vue3/package.json:37-37

Git提交信息规范(建议)

  • 类型前缀:feat、fix、docs、style、refactor、perf、test、build、ci、chore、revert
  • 提交格式:type(scope): subject
  • 示例:feat(tts): 添加音色预览接口

代码审查检查清单(建议)

  • 代码风格:命名一致、缩进统一、注释清晰、无魔法数字
  • 安全性:输入校验、权限控制、敏感信息脱敏
  • 可靠性:错误处理、边界条件、幂等性、降级策略
  • 性能:索引使用、查询优化、缓存策略、队列异步化
  • 可测试性:可注入依赖、单元测试覆盖关键分支
  • 文档:接口文档、变更说明、部署与回滚预案