# 用户基本信息
**本文引用的文件**
- [schema.prisma](file://server/prisma/schema.prisma)
- [auth.controller.ts](file://server/src/modules/auth/auth.controller.ts)
- [auth.service.ts](file://server/src/modules/auth/auth.service.ts)
- [user.ts](file://my-uniapp-vue3/src/store/user.ts)
- [index.ts](file://server/src/models/index.ts)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
## 简介
本文件面向AI有声书生成平台的“用户基本信息”模型,围绕User模型进行系统化说明,重点覆盖以下方面:
- 字段定义与数据类型、约束条件及业务含义
- 字段允许空值的原因与默认值设计考量
- 常见业务流程的实现路径,如手机号登录/注册、用户信息查询与更新、昵称与头像变更等
- 与前端状态管理与后端服务层的交互方式
## 项目结构
与用户基本信息模型直接相关的代码分布在如下位置:
- 数据库模型定义:Prisma Schema(包含User模型及其索引)
- 后端控制器与服务:认证模块的路由与业务逻辑
- 前端状态管理:Pinia Store对用户信息的读取与持久化
- 数据访问层:Prisma 客户端连接与查询
```mermaid
graph TB
subgraph "前端"
FE_Store["用户状态存储
user.ts"]
end
subgraph "后端"
BE_Router["认证路由
auth.controller.ts"]
BE_Service["认证服务
auth.service.ts"]
BE_Models["数据访问层
models/index.ts"]
end
subgraph "数据库"
DB_Schema["Prisma Schema
schema.prisma"]
end
FE_Store --> BE_Router
BE_Router --> BE_Service
BE_Service --> BE_Models
BE_Models --> DB_Schema
```
图表来源
- [auth.controller.ts:1-94](file://server/src/modules/auth/auth.controller.ts#L1-L94)
- [auth.service.ts:1-115](file://server/src/modules/auth/auth.service.ts#L1-L115)
- [index.ts:1-15](file://server/src/models/index.ts#L1-L15)
- [schema.prisma:10-38](file://server/prisma/schema.prisma#L10-L38)
章节来源
- [auth.controller.ts:1-94](file://server/src/modules/auth/auth.controller.ts#L1-L94)
- [auth.service.ts:1-115](file://server/src/modules/auth/auth.service.ts#L1-L115)
- [index.ts:1-15](file://server/src/models/index.ts#L1-L15)
- [schema.prisma:10-38](file://server/prisma/schema.prisma#L10-L38)
## 核心组件
本节聚焦User模型的核心字段,逐项说明其数据类型、约束、默认值与业务含义,并解释为何某些字段允许为空。
- id 主键自增
- 类型:整数
- 约束:主键、自动递增
- 业务含义:用户唯一标识,用于关联其他表(如订单、收藏、播放记录等)
- 设计考量:保证全局唯一且无需外部生成
- phone 手机号(唯一索引)
- 类型:字符串
- 约束:唯一、可空
- 业务含义:手机号登录/注册入口;可为空表示未绑定手机号
- 设计考量:允许空值以支持非手机号登录渠道;唯一性确保登录入口一致性
- openid 第三方登录标识(唯一索引)
- 类型:字符串
- 约束:唯一、可空
- 业务含义:微信等第三方登录的用户标识;可为空表示未绑定第三方
- 设计考量:允许空值以支持多渠道登录;唯一性避免重复绑定
- nickname 昵称(默认值)
- 类型:字符串
- 约束:非空
- 默认值:"用户"
- 业务含义:展示用名称;为空白时提供友好默认名
- 设计考量:提升首次体验与兼容性
- avatar 头像URL(默认值)
- 类型:字符串
- 约束:非空
- 默认值:空字符串
- 业务含义:用户头像地址;为空时表示未设置头像
- 设计考量:兼容未设置头像的场景
- memberLevel 会员等级(默认值)
- 类型:整数
- 约束:非空
- 默认值:0(普通用户)
- 业务含义:区分用户权益与功能限制
- 设计考量:从0级起步,便于后续扩展
- memberExpireAt 会员到期时间(可空)
- 类型:日期时间
- 约束:可空
- 业务含义:会员状态的有效截止时间
- 设计考量:允许空值表示非会员或永久会员
- dailyUsage 每日用量(默认值)
- 类型:整数
- 约束:非空
- 默认值:0
- 业务含义:当日使用量统计,配合签到奖励与限额控制
- 设计考量:从0开始,便于累计与重置
- lastUsageDate 最后使用日期(默认值)
- 类型:字符串
- 约束:非空
- 默认值:空字符串
- 业务含义:记录最近一次使用日期,用于连续签到与重置逻辑
- 设计考量:字符串格式便于快速比较与存储
- usedAudioMinutes 已用音频时长(默认值)
- 类型:整数
- 约束:非空
- 默认值:0
- 业务含义:累计使用的音频生成时长(分钟),用于配额控制
- 设计考量:与订阅/套餐结合,限制生成时长
- subscriptionResetDate 订阅重置日期(可空)
- 类型:日期时间
- 约束:可空
- 业务含义:订阅周期重置的时间点
- 设计考量:允许空值表示未订阅或未启用重置
- createdAt/updatedAt 时间戳(默认值)
- 类型:日期时间
- 约束:非空
- 默认值:创建时自动写入当前时间;更新时自动刷新
- 业务含义:审计与排序依据
索引与外键
- 对phone与openid分别建立唯一索引,确保登录入口与第三方绑定的唯一性
- User模型与其他业务实体存在一对多/一对一关系(如评论、收藏、播放记录、偏好等)
章节来源
- [schema.prisma:10-38](file://server/prisma/schema.prisma#L10-L38)
## 架构总览
用户基本信息在系统中的流转路径如下:
- 前端通过认证接口发起登录请求
- 后端服务根据手机号与验证码进行校验并创建/查询用户
- 返回JWT令牌与用户信息
- 前端Store保存令牌与用户信息,后续请求携带令牌访问受保护资源
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Router as "认证路由
auth.controller.ts"
participant Service as "认证服务
auth.service.ts"
participant DB as "数据库
schema.prisma"
Client->>Router : "POST /auth/login"
Router->>Service : "loginWithPhone(phone, code)"
Service->>DB : "查询手机号是否存在"
DB-->>Service : "返回用户或空"
Service->>DB : "不存在则创建用户含默认昵称/头像等"
Service-->>Router : "返回token与用户信息"
Router-->>Client : "登录成功响应"
```
图表来源
- [auth.controller.ts:32-52](file://server/src/modules/auth/auth.controller.ts#L32-L52)
- [auth.service.ts:43-97](file://server/src/modules/auth/auth.service.ts#L43-L97)
- [schema.prisma:10-38](file://server/prisma/schema.prisma#L10-L38)
## 详细组件分析
### 字段定义与约束详解
- 主键与自增
- id为整型主键并自动递增,保证全局唯一性与高并发下的稳定性
- 唯一索引字段
- phone与openid均为唯一索引,防止重复登录入口与重复绑定
- 可空字段
- phone与openid允许空值,体现多渠道登录策略
- memberExpireAt与subscriptionResetDate允许空值,表示非会员或未启用重置
- 默认值设计
- nickname默认"用户",avatar默认空字符串,memberLevel默认0,dailyUsage与lastUsageDate默认0/空字符串,usedAudioMinutes默认0
- 设计目标:在无显式设置时提供合理初始值,降低前端与业务层的空值判断复杂度
章节来源
- [schema.prisma:10-38](file://server/prisma/schema.prisma#L10-L38)
### 登录与注册流程(手机号)
- 前端调用发送验证码接口,随后调用登录接口
- 后端服务在开发模式下可跳过验证码校验(code为空或特定值时)
- 若用户不存在,则创建新用户并填充默认昵称与头像
- 生成JWT令牌返回给前端
```mermaid
sequenceDiagram
participant FE as "前端
user.ts"
participant API as "后端路由
auth.controller.ts"
participant SVC as "后端服务
auth.service.ts"
participant PRISMA as "Prisma
schema.prisma"
FE->>API : "POST /auth/send-code"
FE->>API : "POST /auth/login"
API->>SVC : "loginWithPhone(phone, code)"
SVC->>PRISMA : "findUnique(phone)"
alt "用户不存在"
SVC->>PRISMA : "create(user with defaults)"
end
SVC-->>API : "token + user"
API-->>FE : "登录成功"
```
图表来源
- [auth.controller.ts:10-52](file://server/src/modules/auth/auth.controller.ts#L10-L52)
- [auth.service.ts:43-97](file://server/src/modules/auth/auth.service.ts#L43-L97)
- [user.ts:32-46](file://my-uniapp-vue3/src/store/user.ts#L32-L46)
章节来源
- [auth.controller.ts:10-52](file://server/src/modules/auth/auth.controller.ts#L10-L52)
- [auth.service.ts:43-97](file://server/src/modules/auth/auth.service.ts#L43-L97)
- [user.ts:32-46](file://my-uniapp-vue3/src/store/user.ts#L32-L46)
### 用户信息查询与更新
- 查询用户信息
- 后端通过鉴权中间件获取当前用户ID,查询User表并返回必要字段
- 更新用户信息
- 支持更新昵称与头像;后端仅对传入的字段进行更新,避免覆盖其他字段
```mermaid
sequenceDiagram
participant FE as "前端
user.ts"
participant API as "后端路由
auth.controller.ts"
participant SVC as "后端服务
auth.service.ts"
participant PRISMA as "Prisma
schema.prisma"
FE->>API : "GET /auth/user-info"
API->>SVC : "getUserInfo(userId)"
SVC->>PRISMA : "findUnique(id)"
SVC-->>API : "用户信息"
API-->>FE : "返回信息"
FE->>API : "PUT /auth/user-info {nickname, avatar}"
API->>PRISMA : "update(id, {nickname?, avatar?})"
API-->>FE : "更新成功"
```
图表来源
- [auth.controller.ts:54-92](file://server/src/modules/auth/auth.controller.ts#L54-L92)
- [auth.service.ts:99-115](file://server/src/modules/auth/auth.service.ts#L99-L115)
- [schema.prisma:10-38](file://server/prisma/schema.prisma#L10-L38)
章节来源
- [auth.controller.ts:54-92](file://server/src/modules/auth/auth.controller.ts#L54-L92)
- [auth.service.ts:99-115](file://server/src/modules/auth/auth.service.ts#L99-L115)
### 字段允许空值与默认值的设计考量
- phone与openid允许空值
- 支持多种登录方式(手机号、第三方),避免强制绑定单一入口
- nickname与avatar默认值
- 提升首次体验,减少空值处理分支
- memberExpireAt与subscriptionResetDate允许空值
- 表示非会员或未启用订阅周期重置,简化业务判断
- dailyUsage与lastUsageDate默认0/空字符串
- 便于连续签到与额度重置逻辑的统一处理
章节来源
- [schema.prisma:10-38](file://server/prisma/schema.prisma#L10-L38)
### 常见业务场景实现路径
- 手机号绑定
- 当前登录流程以手机号作为登录入口;若用户已有phone字段,可视为已绑定
- 若需绑定新手机号,可在现有登录流程基础上扩展“绑定手机号”接口(当前仓库未提供独立绑定接口)
- OpenID关联
- 当前User模型包含openid字段,但认证流程未展示第三方登录入口
- 若接入第三方登录,可在登录流程中补充对openid的写入与去重逻辑
- 昵称修改
- 通过PUT /auth/user-info接口传入nickname字段即可更新
- 头像URL更新
- 通过PUT /auth/user-info接口传入avatar字段即可更新
章节来源
- [auth.controller.ts:66-92](file://server/src/modules/auth/auth.controller.ts#L66-L92)
- [auth.service.ts:43-97](file://server/src/modules/auth/auth.service.ts#L43-L97)
- [schema.prisma:10-38](file://server/prisma/schema.prisma#L10-L38)
## 依赖关系分析
- 前端依赖
- Pinia Store负责登录态与用户信息的本地持久化与状态计算
- 后端依赖
- 认证路由依赖认证服务进行业务处理
- 认证服务依赖Prisma进行数据库读写
- 数据访问层封装Prisma客户端连接与生命周期管理
```mermaid
graph LR
FE["前端 Store
user.ts"] --> API["后端路由
auth.controller.ts"]
API --> SVC["后端服务
auth.service.ts"]
SVC --> PRISMA["Prisma 客户端
models/index.ts"]
PRISMA --> SCHEMA["Schema 定义
schema.prisma"]
```
图表来源
- [user.ts:1-107](file://my-uniapp-vue3/src/store/user.ts#L1-L107)
- [auth.controller.ts:1-94](file://server/src/modules/auth/auth.controller.ts#L1-L94)
- [auth.service.ts:1-115](file://server/src/modules/auth/auth.service.ts#L1-L115)
- [index.ts:1-15](file://server/src/models/index.ts#L1-L15)
- [schema.prisma:10-38](file://server/prisma/schema.prisma#L10-L38)
章节来源
- [user.ts:1-107](file://my-uniapp-vue3/src/store/user.ts#L1-L107)
- [auth.controller.ts:1-94](file://server/src/modules/auth/auth.controller.ts#L1-L94)
- [auth.service.ts:1-115](file://server/src/modules/auth/auth.service.ts#L1-L115)
- [index.ts:1-15](file://server/src/models/index.ts#L1-L15)
- [schema.prisma:10-38](file://server/prisma/schema.prisma#L10-L38)
## 性能考量
- 索引策略
- phone与openid建立唯一索引,确保登录与绑定查询高效
- 查询优化
- 登录与查询用户信息均采用按主键或唯一键查询,避免全表扫描
- 缓存建议
- 对高频读取的用户信息可在应用层做短期缓存(如Redis),降低数据库压力
- 令牌与会话
- 使用JWT令牌承载用户标识,减少数据库会话存储开销
## 故障排查指南
- 登录失败或验证码错误
- 检查验证码生成与校验逻辑,确认过期时间与匹配规则
- 开发环境下可临时跳过验证码校验以定位问题
- 用户不存在
- 确认用户是否已通过手机号登录并创建
- 检查phone字段是否正确传入
- 更新用户信息失败
- 确认传入的nickname与avatar字段是否符合预期
- 检查鉴权中间件是否正确注入userId
- 数据库连接异常
- 检查Prisma客户端连接状态与数据库URL配置
章节来源
- [auth.controller.ts:54-92](file://server/src/modules/auth/auth.controller.ts#L54-L92)
- [auth.service.ts:21-32](file://server/src/modules/auth/auth.service.ts#L21-L32)
- [index.ts:5-13](file://server/src/models/index.ts#L5-L13)
## 结论
User模型以简洁明确的字段与合理的默认值设计,支撑起平台的多渠道登录与基础用户管理能力。通过唯一索引保障登录入口的一致性,通过可空字段与默认值兼顾灵活性与易用性。结合前端Store与后端服务层的清晰职责划分,形成了稳定可靠的用户信息流转链路。后续可在现有基础上扩展第三方登录与手机号绑定接口,进一步完善用户身份体系。