Account模块
开发中账号模块实现。包含账号相关功能(不包括认证,但与认证紧密联系,认证应该在 authentication 模块):注册、登录、注销
#tech / dev / pm
#type / concept
#status / growing
Account模块
[!info] related notes
- 相关业务: Authentication模块, 认证业务
- 认证与登录: Token认证的实现流程, Cookie、Session、Token
- 关联实现: 账号信息记录功能实现, express实现登录
Overview
账号模块应该有:
- 用于用户 user 相关,管理用户实体数据 注册、获取当前用户信息、注销、个人信息管理、账户状态管理
快速登录应该是提供可快速登录的账户,点击后直接登录进入,不需要输入用户密码。
要实现快速登录、自动登录的话,应该是要保存一些登录信息的,比如登录凭证、账号信息等。
所以再引入 loginSession 相关功能:
- 用于登录会话 loginsession 相关,在本地保存用户的登录信息,如账号、token、remember等信息 查询记录获取需要快速登录的账号及凭证,为快速登录提供服务
服务
基础信息服务 (Base Profile Service)
这是最高频的读取服务,甚至可能需要缓存(Redis)。
- 查询用户详情: 获取昵称、头像、简介、注册时间。
- 批量查询: 供其他模块调用(例如:评论模块需要显示 10 个用户的头像)。
- 更新资料: 修改非敏感信息(如生日、地区、个人简介)。
安全与状态服务 (Security & State Service)
- 状态变更: 管理员封禁/解封用户、用户注销(软删除)。
- 敏感操作记录: 记录“修改密码”、“更换手机号”等操作日志(Audit Log)。
数据库设计(Database Schema)
这是 Account 模块的灵魂。推荐采用 “用户实体 + 授权凭证 + 扩展信息” 的三层表结构设计。
用户主表 (users / user_base)
这是系统的“身份证”,只存最核心、改动频率最低的数据。
CREATE TABLE users (
id BIGINT PRIMARY KEY, -- 用户全局唯一ID (推荐 Snowflake 算法,不要自增)
username VARCHAR(64) UNIQUE, -- 唯一用户名 (可选)
status TINYINT DEFAULT 1, -- 状态: 1-正常, 2-锁定, 3-注销, 0-未激活
created_at DATETIME, -- 注册时间
updated_at DATETIME -- 最后更新时间
);
用户扩展信息表 (user_profiles)
把非核心、展示型的数据拆分出来,避免主表过大,提升查询效率。
CREATE TABLE user_profiles (
user_id BIGINT PRIMARY KEY,
nickname VARCHAR(64), -- 昵称 (可以重复)
avatar_url VARCHAR(255), -- 头像链接
gender TINYINT, -- 性别
bio VARCHAR(500), -- 个人简介
preferences JSON -- 用户偏好设置 (夜间模式、语言等,用JSON存更灵活)
);
领域对象 (Domain Objects)
在代码实现(Java/Go/Node.ts)中,需要定义以下对象来承载数据:
1. 实体对象 (Entities/PO)
直接对应数据库表的对象,通常由 ORM (如 TypeORM, Prisma, MyBatis) 管理。
UserEntityUserIdentityEntityUserProfileEntity
2. 数据传输对象 (DTO - Data Transfer Object)
用于接口输入输出,严禁把 Entity 直接返回给前端(会泄露密码 Hash 或内部 ID)。
- 输入对象 (Request DTOs):
UpdateProfileRequest:{ nickname: string, bio: string }BindIdentityRequest:{ type: 'github', code: string }
- 输出对象 (Response DTOs):
UserCardVO:{ id, nickname, avatar }(轻量级,用于列表展示)UserDetailVO:{ id, username, email, phone, profile: {...}, settings: {...} }(全量级,用于“个人中心”)
Account 模块的关键业务流转
举个**“绑定新手机号”**的例子,看看 Account 模块内部怎么运作:
-
用户请求: 前端发起
POST /account/bind/phone,携带phoneNumber和verifyCode。 -
校验: Account 服务先检查
user_identities表,确认该phoneNumber没有被其他user_id占用。 -
验证: 调用验证码服务,确认验证码正确。
-
写入: 在
user_identities表中插入一行:user_id: 当前登录用户type: ‘phone’identifier: +86138xxxxcredential: null (如果是免密登录) 或 初始密码Hash
-
反馈: 返回绑定成功,前端刷新页面显示“手机号:已绑定”。
总结
Account 模块的核心在于解耦:
- 存储解耦: 身份(Identity)与档案(Profile)分开存。
- 逻辑解耦: Account 模块只负责“管理数据”,不负责“颁发 Token”(那是 Auth 的事)。