topfans/backend/services/userService/service/README.md
2026-05-16 02:42:32 +08:00

440 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Service层实现文档
## 一、认证ServiceAuthService
### 1.1 功能概述
实现了用户认证相关的核心功能,包括:
- 用户注册
- 用户登录
- 用户登出
- Token刷新
- Token验证
### 1.2 接口定义
```go
type AuthService interface {
// Register 注册
Register(req *pb.RegisterRequest) (*pb.RegisterResponse, error)
// Login 登录
Login(req *pb.LoginRequest) (*pb.LoginResponse, error)
// Logout 登出
Logout(req *pb.LogoutRequest) (*pb.LogoutResponse, error)
// RefreshToken 刷新Token
RefreshToken(req *pb.RefreshTokenRequest) (*pb.RefreshTokenResponse, error)
// ValidateToken 验证Token用于中间件
ValidateToken(req *pb.ValidateTokenRequest) (*pb.ValidateTokenResponse, error)
}
```
### 1.3 实现流程
#### 1.3.1 注册流程
1. 参数验证手机号、密码、昵称、star_id
2. 验证手机号是否已存在
3. 验证明星是否存在
4. 使用事务创建用户和粉丝档案
- 创建用户(加密密码)
- 创建第一个粉丝档案
- 生成JWT Token
- 更新用户Token
5. 返回Token和用户信息
#### 1.3.2 登录流程
1. 参数验证(手机号、密码)
2. 根据手机号查询用户
3. 验证密码bcrypt比对
4. 验证用户是否激活
5. 获取用户的粉丝档案列表
6. 生成JWT Token包含user_id和当前star_id
7. 更新用户Token
8. 返回Token和用户信息
#### 1.3.3 Token刷新流程
1. 解析旧Token即使过期也要解析
2. 查询用户
3. 验证旧Token是否匹配数据库中的Token
4. 验证updated_at是否匹配如果用户信息更新Token失效
5. 生成新Token
6. 更新数据库中的Token
7. 返回新Token
#### 1.3.4 Token验证流程
1. 解析和验证Token检查签名和过期时间
2. 查询用户验证Token是否匹配
3. 验证用户是否激活
4. 验证Token是否匹配数据库中的Token
5. 验证updated_at是否匹配
6. 返回验证结果
#### 1.3.5 登出流程
1. 从Token中提取user_id
2. 清除用户Token
### 1.4 依赖
- `UserRepository` - 用户数据访问
- `FanProfileRepository` - 粉丝档案数据访问
- `StarRepository` - 明星信息数据访问
- `JWT工具` - Token生成和解析
- `Logger` - 日志记录
- `Validator` - 参数验证
### 1.5 使用示例
```go
// 创建Service实例
userRepo := repository.NewUserRepository()
fanProfileRepo := repository.NewFanProfileRepository()
starRepo := repository.NewStarRepository()
db := database.GetDB()
authService := NewAuthService(userRepo, fanProfileRepo, starRepo, db)
// 用户注册
registerReq := &pb.RegisterRequest{
Mobile: "13800138000",
Password: "123456",
StarId: 1,
Nickname: "粉丝昵称",
}
registerResp, err := authService.Register(registerReq)
// 用户登录
loginReq := &pb.LoginRequest{
Mobile: "13800138000",
Password: "123456",
}
loginResp, err := authService.Login(loginReq)
// 刷新Token
refreshReq := &pb.RefreshTokenRequest{
AccessToken: "old_token_here",
}
refreshResp, err := authService.RefreshToken(refreshReq)
// 验证Token
validateReq := &pb.ValidateTokenRequest{
AccessToken: "token_here",
}
validateResp, err := authService.ValidateToken(validateReq)
// 登出
logoutReq := &pb.LogoutRequest{
AccessToken: "token_here",
}
logoutResp, err := authService.Logout(logoutReq)
```
### 1.6 错误处理
Service层返回的错误类型
- `ErrUserNotFound` - 用户不存在
- `ErrUserAlreadyExists` - 用户已存在
- `ErrInvalidPassword` - 密码错误
- `ErrInvalidToken` - Token无效
- `ErrTokenExpired` - Token过期
- `ErrTokenMismatch` - Token不匹配
- `ErrUserInactive` - 用户未激活
- `ErrInvalidMobile` - 手机号格式错误
- `ErrPasswordTooShort` - 密码太短
- `ErrInvalidStarID` - 明星ID无效
- `ErrStarNotFound` - 明星不存在
所有错误都会被记录到日志中,便于调试和监控。
### 1.7 注意事项
1. **事务处理**:注册流程使用数据库事务,确保用户和粉丝档案的创建原子性
2. **密码安全**密码使用bcrypt加密存储不存储明文
3. **Token管理**Token存储在数据库中支持单设备登录
4. **Token失效**当用户信息更新updated_at改变旧Token会自动失效
5. **日志记录**:所有关键操作都会记录日志,包括成功和失败场景
### 1.8 测试要点
- 注册成功和失败场景
- 登录成功和失败场景
- Token生成和验证
- Token刷新
- 修改密码后Token失效
- 用户信息更新后Token失效
---
## 二、用户信息ServiceUserService
### 2.1 功能概述
实现了用户信息相关的核心功能,包括:
- 获取用户信息
- 获取粉丝档案
- 获取个人信息页数据
- 修改昵称
- 修改密码
### 2.2 接口定义
```go
type UserService interface {
// GetUser 获取用户信息
GetUser(req *pb.GetUserRequest) (*pb.GetUserResponse, error)
// GetFanProfile 获取粉丝档案
GetFanProfile(req *pb.GetFanProfileRequest) (*pb.GetFanProfileResponse, error)
// GetMyProfile 获取个人信息页
GetMyProfile(req *pb.GetMyProfileRequest, userID, starID int64) (*pb.GetMyProfileResponse, error)
// UpdateNickname 修改昵称
UpdateNickname(req *pb.UpdateNicknameRequest, userID, starID int64) (*pb.UpdateNicknameResponse, error)
// UpdatePassword 修改密码
UpdatePassword(req *pb.UpdatePasswordRequest, userID int64) (*pb.UpdatePasswordResponse, error)
}
```
### 2.3 实现流程
#### 2.3.1 获取用户信息流程
1. 参数验证user_id
2. 查询用户
3. 返回用户信息
#### 2.3.2 获取粉丝档案流程
1. 参数验证user_id, star_id
2. 查询粉丝档案
3. 返回粉丝档案信息
#### 2.3.3 获取个人信息页流程
1. 参数验证user_id, star_id
2. 查询用户信息
3. 查询当前粉丝档案
4. 查询用户的所有粉丝身份
5. 聚合返回完整信息
#### 2.3.4 修改昵称流程
1. 参数验证user_id, star_id, nickname
2. 验证粉丝档案是否存在
3. 更新昵称
4. 查询更新后的粉丝档案
5. 返回更新后的信息
#### 2.3.5 修改密码流程
1. 参数验证user_id, old_password, new_password
2. 查询用户
3. 验证旧密码
4. 加密新密码
5. 使用事务更新密码和updated_at清除Token
6. 返回成功响应
**重要**:修改密码时,会更新`updated_at`并清除Token导致旧Token失效需要重新登录。
### 2.4 依赖
- `UserRepository` - 用户数据访问
- `FanProfileRepository` - 粉丝档案数据访问
### 2.5 使用示例
```go
// 创建Service实例
userRepo := repository.NewUserRepository()
fanProfileRepo := repository.NewFanProfileRepository()
db := database.GetDB()
userService := NewUserService(userRepo, fanProfileRepo, db)
// 获取用户信息
getUserReq := &pb.GetUserRequest{
UserId: 10000001,
}
getUserResp, err := userService.GetUser(getUserReq)
// 获取粉丝档案
getFanProfileReq := &pb.GetFanProfileRequest{
UserId: 10000001,
StarId: 1,
}
getFanProfileResp, err := userService.GetFanProfile(getFanProfileReq)
// 获取个人信息页
getMyProfileReq := &pb.GetMyProfileRequest{}
getMyProfileResp, err := userService.GetMyProfile(getMyProfileReq, 10000001, 1)
// 修改昵称
updateNicknameReq := &pb.UpdateNicknameRequest{
Nickname: "新昵称",
}
updateNicknameResp, err := userService.UpdateNickname(updateNicknameReq, 10000001, 1)
// 修改密码
updatePasswordReq := &pb.UpdatePasswordRequest{
OldPassword: "旧密码",
NewPassword: "新密码",
}
updatePasswordResp, err := userService.UpdatePassword(updatePasswordReq, 10000001)
```
### 2.6 错误处理
Service层返回的错误类型
- `ErrUserNotFound` - 用户不存在
- `ErrFanProfileNotFound` - 粉丝档案不存在
- `ErrInvalidPassword` - 密码错误
- `ErrInvalidUserID` - 用户ID无效
- `ErrInvalidStarID` - 明星ID无效
- `ErrPasswordTooShort` - 密码太短
所有错误都会被记录到日志中,便于调试和监控。
### 2.7 注意事项
1. **密码安全**修改密码时使用bcrypt加密存储新密码
2. **Token失效**:修改密码后,`updated_at`会更新旧Token会自动失效
3. **事务处理**修改密码使用数据库事务确保密码更新和Token清除的原子性
4. **数据聚合**:获取个人信息页需要聚合用户信息、当前粉丝档案和所有粉丝身份
5. **日志记录**:所有关键操作都会记录日志,包括成功和失败场景
### 2.8 测试要点
- 获取用户信息成功和失败场景
- 获取粉丝档案成功和失败场景
- 获取个人信息页(数据聚合)
- 修改昵称成功和失败场景
- 修改密码成功和失败场景
- 修改密码后Token失效验证
---
## 三、粉丝身份ServiceIdentityService
### 3.1 功能概述
实现了粉丝身份相关的核心功能,包括:
- 获取可选粉丝身份列表(支持搜索)
- 新增粉丝身份最多2个
- 切换粉丝身份生成新Token
### 3.2 接口定义
```go
type IdentityService interface {
// GetFanIdentities 获取可选粉丝身份列表
GetFanIdentities(req *pb.GetFanIdentitiesRequest) (*pb.GetFanIdentitiesResponse, error)
// AddIdentity 新增粉丝身份
AddIdentity(req *pb.AddIdentityRequest, userID int64) (*pb.AddIdentityResponse, error)
// SwitchIdentity 切换粉丝身份
SwitchIdentity(req *pb.SwitchIdentityRequest, userID int64, currentStarID int64) (*pb.SwitchIdentityResponse, error)
}
```
### 3.3 实现流程
#### 3.3.1 获取可选粉丝身份列表流程
1. 如果有关键词调用Search搜索否则调用GetAllActive获取所有可用明星
2. 转换为proto类型
3. 返回明星列表
#### 3.3.2 新增粉丝身份流程
1. 参数验证user_id, star_id, nickname
2. 检查用户已有的粉丝身份数量最多2个
3. 验证明星是否存在
4. 检查该用户是否已有该明星的身份
5. 创建新的粉丝档案
6. 返回新创建的粉丝档案
#### 3.3.3 切换粉丝身份流程
1. 参数验证user_id, new_star_id
2. 检查是否切换到相同的身份
3. 查询用户
4. 验证新身份是否存在
5. 生成新Token包含新的star_id
6. 更新用户Token
7. 返回新Token和粉丝档案
### 3.4 依赖
- `FanProfileRepository` - 粉丝档案数据访问
- `StarRepository` - 明星信息数据访问
- `UserRepository` - 用户数据访问用于切换身份时更新Token
- `JWT工具` - Token生成切换身份时
### 3.5 使用示例
```go
// 创建Service实例
fanProfileRepo := repository.NewFanProfileRepository()
starRepo := repository.NewStarRepository()
userRepo := repository.NewUserRepository()
db := database.GetDB()
identityService := NewIdentityService(fanProfileRepo, starRepo, userRepo, db)
// 获取可选粉丝身份列表
getFanIdentitiesReq := &pb.GetFanIdentitiesRequest{
Keyword: "明星", // 可选,为空则返回所有
}
getFanIdentitiesResp, err := identityService.GetFanIdentities(getFanIdentitiesReq)
// 新增粉丝身份
addIdentityReq := &pb.AddIdentityRequest{
StarId: 2,
Nickname: "新身份昵称",
}
addIdentityResp, err := identityService.AddIdentity(addIdentityReq, 10000001)
// 切换粉丝身份
switchIdentityReq := &pb.SwitchIdentityRequest{
NewStarId: 2,
}
switchIdentityResp, err := identityService.SwitchIdentity(switchIdentityReq, 10000001, 1)
```
### 3.6 错误处理
Service层返回的错误类型
- `ErrFanProfileNotFound` - 粉丝档案不存在
- `ErrStarNotFound` - 明星不存在
- `ErrInvalidStarID` - 明星ID无效
- `ErrMaxIdentitiesReached` - 已达到最大身份数量最多2个
所有错误都会被记录到日志中,便于调试和监控。
### 3.7 注意事项
1. **身份数量限制**一个用户最多可以拥有2个粉丝身份新增时会检查
2. **Token更新**切换身份时会生成新的JWT Token包含新的star_id
3. **重复检查**:新增身份时会检查用户是否已有该明星的身份
4. **日志记录**:所有关键操作都会记录日志,包括成功和失败场景
### 3.8 测试要点
- 获取可选粉丝身份列表(带关键词和不带关键词)
- 新增粉丝身份成功和失败场景
- 新增身份时数量限制检查最多2个
- 切换粉丝身份成功和失败场景
- 切换到相同身份的处理
- 切换身份后Token更新验证