# 用户基本信息 **本文引用的文件** - [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与后端服务层的清晰职责划分,形成了稳定可靠的用户信息流转链路。后续可在现有基础上扩展第三方登录与手机号绑定接口,进一步完善用户身份体系。