diff --git a/.kiro/specs/user-auth-migration/design.md b/.kiro/specs/user-auth-migration/design.md new file mode 100644 index 00000000..c3cd011e --- /dev/null +++ b/.kiro/specs/user-auth-migration/design.md @@ -0,0 +1,588 @@ +# Design Document: 用户认证系统迁移 + +## Overview + +本设计文档描述了将PHP用户认证系统迁移到.NET 8的技术方案。系统采用分层架构,包括Controller层、Service层和Repository层。迁移过程中保持与现有UniApp前端的100%兼容性,使用相同的请求/响应格式。 + +## Architecture + +``` +┌─────────────────────────────────────────────────────────────┐ +│ UniApp 前端 │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ API Gateway / Nginx │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ .NET 8 API 服务 │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ Controllers │ │ +│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ +│ │ │AuthController│ │UserController│ │HealthCheck │ │ │ +│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ Services │ │ +│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ +│ │ │ AuthService │ │ UserService │ │ JwtService │ │ │ +│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ +│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ +│ │ │WechatService│ │ SmsService │ │IpLocationSvc│ │ │ +│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ Infrastructure │ │ +│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ +│ │ │ EF Core │ │ Redis │ │ COS Upload │ │ │ +│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ +│ └─────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ + │ │ + ▼ ▼ + ┌───────────┐ ┌───────────┐ + │ MySQL │ │ Redis │ + └───────────┘ └───────────┘ +``` + +## Components and Interfaces + +### 1. AuthController + +负责处理所有认证相关的HTTP请求。 + +```csharp +[ApiController] +[Route("api")] +public class AuthController : ControllerBase +{ + // POST /login - 微信小程序登录 + [HttpPost("login")] + public async Task> WechatMiniProgramLogin(WechatLoginRequest request); + + // POST /mobileLogin - 手机号验证码登录 + [HttpPost("mobileLogin")] + public async Task> MobileLogin(MobileLoginRequest request); + + // POST /login_bind_mobile - 微信授权绑定手机号 + [HttpPost("login_bind_mobile")] + public async Task> LoginBindMobile(BindMobileRequest request); + + // POST /bindMobile - 验证码绑定手机号 + [HttpPost("bindMobile")] + public async Task> BindMobile(BindMobileWithCodeRequest request); + + // GET|POST /login_record - 记录用户登录 + [HttpPost("login_record")] + [HttpGet("login_record")] + public async Task> RecordLogin(RecordLoginRequest request); +} +``` + +### 2. UserController + +负责处理用户信息相关的HTTP请求。 + +```csharp +[ApiController] +[Route("api")] +public class UserController : ControllerBase +{ + // POST /user - 获取用户信息 + [HttpPost("user")] + public async Task> GetUserInfo(); + + // POST /update_userinfo - 更新用户信息 + [HttpPost("update_userinfo")] + public async Task UpdateUserInfo(UpdateUserInfoRequest request); + + // POST /user_log_off - 注销账号 + [HttpPost("user_log_off")] + public async Task LogOff(LogOffRequest request); +} +``` + +### 3. IAuthService + +认证服务接口。 + +```csharp +public interface IAuthService +{ + Task WechatMiniProgramLoginAsync(string code, int? pid, string clickId); + Task MobileLoginAsync(string mobile, string code, int? pid, string clickId); + Task BindMobileAsync(int userId, string mobile, string code); + Task WechatBindMobileAsync(int userId, string wechatCode); + Task RecordLoginAsync(int userId, string device, string deviceInfo); + Task LogOffAsync(int userId, int type); +} +``` + +### 4. IWechatService + +微信服务接口。 + +```csharp +public interface IWechatService +{ + Task GetOpenIdAsync(string code); + Task GetMobileAsync(string code); +} +``` + +### 5. IJwtService + +JWT服务接口。 + +```csharp +public interface IJwtService +{ + string GenerateToken(User user); + ClaimsPrincipal ValidateToken(string token); + int? GetUserIdFromToken(string token); +} +``` + +### 6. IUserService + +用户服务接口。 + +```csharp +public interface IUserService +{ + Task GetUserByIdAsync(int userId); + Task GetUserByOpenIdAsync(string openId); + Task GetUserByUnionIdAsync(string unionId); + Task GetUserByMobileAsync(string mobile); + Task CreateUserAsync(CreateUserDto dto); + Task UpdateUserAsync(int userId, UpdateUserDto dto); + Task GetUserInfoAsync(int userId); + Task CalculateVipLevelAsync(int userId, int currentVip); +} +``` + +### 7. IIpLocationService + +IP地理位置服务接口。 + +```csharp +public interface IIpLocationService +{ + Task GetLocationAsync(string ip); +} +``` + +## Data Models + +### Request Models + +```csharp +public class WechatLoginRequest +{ + public string Code { get; set; } + public int? Pid { get; set; } +} + +public class MobileLoginRequest +{ + public string Mobile { get; set; } + public string Code { get; set; } + public int? Pid { get; set; } +} + +public class BindMobileRequest +{ + public string Code { get; set; } // 微信授权code +} + +public class BindMobileWithCodeRequest +{ + public string Mobile { get; set; } + public string Code { get; set; } // 短信验证码 +} + +public class UpdateUserInfoRequest +{ + public string Nickname { get; set; } + public string Headimg { get; set; } + public string Imagebase { get; set; } // Base64图片 +} + +public class RecordLoginRequest +{ + public string Device { get; set; } + public string DeviceInfo { get; set; } +} + +public class LogOffRequest +{ + public int Type { get; set; } // 0-注销 1-取消注销 +} +``` + +### Response Models + +```csharp +public class ApiResponse +{ + public int Status { get; set; } // 1成功 0失败 -1未登录 + public string Msg { get; set; } + public T Data { get; set; } +} + +public class UserInfoResponse +{ + public UserInfoDto Userinfo { get; set; } + public OtherConfigDto Other { get; set; } + public List TaskList { get; set; } +} + +public class UserInfoDto +{ + public int Id { get; set; } + public string Uid { get; set; } + public string Nickname { get; set; } + public string Headimg { get; set; } + public string Mobile { get; set; } // 脱敏后的手机号 + public int MobileIs { get; set; } // 是否绑定手机 + public decimal Money { get; set; } + public decimal Money2 { get; set; } + public decimal Integral { get; set; } + public decimal Score { get; set; } + public int Vip { get; set; } + public string VipImgurl { get; set; } + public int Coupon { get; set; } + public int Day { get; set; } // 注册天数 +} + +public class BindMobileResponse +{ + public string Token { get; set; } // 账户合并时返回新token +} + +public class RecordLoginResponse +{ + public string Uid { get; set; } + public string Nickname { get; set; } + public string Headimg { get; set; } +} +``` + +### Internal DTOs + +```csharp +public class LoginResult +{ + public bool Success { get; set; } + public string Token { get; set; } + public int UserId { get; set; } + public string ErrorMessage { get; set; } +} + +public class WechatAuthResult +{ + public bool Success { get; set; } + public string OpenId { get; set; } + public string UnionId { get; set; } + public string ErrorMessage { get; set; } +} + +public class IpLocationResult +{ + public bool Success { get; set; } + public string Province { get; set; } + public string City { get; set; } + public string Adcode { get; set; } +} + +public class CreateUserDto +{ + public string OpenId { get; set; } + public string UnionId { get; set; } + public string Mobile { get; set; } + public string Nickname { get; set; } + public string Headimg { get; set; } + public int Pid { get; set; } + public int? ClickId { get; set; } +} +``` + +## Key Implementation Details + +### 1. 防抖机制实现 + +使用Redis实现登录防抖,防止用户频繁请求: + +```csharp +public async Task TryAcquireLoginLockAsync(string key, int expireSeconds = 3) +{ + var lockKey = $"login:debounce:{key}"; + return await _redis.StringSetAsync(lockKey, "1", TimeSpan.FromSeconds(expireSeconds), When.NotExists); +} +``` + +### 2. 用户UID生成策略 + +根据配置支持三种UID生成方式: +- 类型0: 使用真实用户ID +- 类型1: 生成指定长度的纯数字ID +- 类型2: 生成字母数字混合ID + +```csharp +public string GenerateUid(int userId, UidConfig config) +{ + return config.UidType switch + { + 0 => userId.ToString(), + 1 => GenerateNumericUid(config.UidLength), + 2 => GenerateAlphaNumericUid(config.UidLength), + _ => userId.ToString() + }; +} +``` + +### 3. 账户合并逻辑 + +当用户绑定的手机号已被其他账户使用时,需要合并账户: + +```csharp +public async Task MergeAccountsAsync(int currentUserId, int mobileUserId) +{ + // 1. 将当前用户的openid迁移到手机号用户 + // 2. 生成新的token + // 3. 删除当前用户和账户记录 + // 4. 返回新token +} +``` + +### 4. Token兼容策略 + +为保持与旧系统兼容,同时使用JWT和数据库token: + +```csharp +public async Task CreateAccountTokenAsync(int userId) +{ + var tokenNum = GenerateRandomString(10); + var time = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + var accountToken = ComputeMd5($"{userId}{tokenNum}{time}"); + + // 存储到UserAccount表 + await UpdateUserAccountAsync(userId, accountToken, tokenNum, time); + + return accountToken; +} +``` + +### 5. 默认头像生成 + +使用Identicon库生成用户默认头像: + +```csharp +public async Task<(string nickname, string headimg)> CreateDefaultAvatarAsync(string seed, string prefix) +{ + var nickname = $"{prefix}{Random.Shared.Next(1000, 9999)}"; + var identicon = new Identicon(seed + nickname); + var imageData = identicon.GetImageData(); + var url = await _cosUploader.UploadAsync(imageData, $"storage/users/icon/default/{Guid.NewGuid()}.png"); + return (nickname, url); +} +``` + + + +## Correctness Properties + +*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.* + +### Property 1: 微信登录用户查找优先级 + +*For any* 用户登录请求,如果提供了unionid,系统应优先通过unionid查找用户;只有当unionid查找失败时,才通过openid查找。 + +**Validates: Requirements 1.2** + +### Property 2: 新用户创建完整性 + +*For any* 不存在的用户(无论是微信登录还是手机号登录),系统创建的新用户记录应包含:有效的uid、非空的昵称、有效的头像URL、正确的pid(如果提供)。 + +**Validates: Requirements 1.3, 2.3** + +### Property 3: 登录成功Token生成 + +*For any* 成功的登录请求(微信或手机号),系统应返回包含用户ID的有效JWT Token,且该Token应使用配置的密钥正确签名。 + +**Validates: Requirements 1.5, 2.4, 3.1, 3.2** + +### Property 4: 登录防抖机制 + +*For any* 用户在3秒内发起的重复登录请求,第二次及之后的请求应被拒绝并返回"请勿频繁登录"错误。 + +**Validates: Requirements 1.6, 2.6** + +### Property 5: 推荐关系记录 + +*For any* 新用户注册时提供的有效推荐人ID(pid),系统应将该pid正确保存到用户记录中。 + +**Validates: Requirements 1.8, 2.7** + +### Property 6: 验证码验证与清理 + +*For any* 手机号登录请求,如果验证码正确,系统应验证通过并删除Redis中的验证码;如果验证码错误或过期,系统应返回"验证码错误"。 + +**Validates: Requirements 2.1, 2.2** + +### Property 7: Token验证与授权 + +*For any* 携带Token的API请求,如果Token有效,系统应允许访问;如果Token无效或过期,系统应返回状态码-1(未登录)。 + +**Validates: Requirements 3.3, 3.4** + +### Property 8: 数据库Token兼容存储 + +*For any* 成功的登录请求,系统应同时在UserAccount表中存储account_token,确保与旧系统兼容。 + +**Validates: Requirements 3.6** + +### Property 9: 用户信息完整性 + +*For any* 用户信息查询请求,返回的数据应包含所有必要字段(id、uid、nickname、headimg、mobile、money、integral、vip等),且手机号应进行脱敏处理(格式:138****8000)。 + +**Validates: Requirements 4.1, 4.4** + +### Property 10: 昵称更新验证 + +*For any* 昵称更新请求,如果昵称为空,系统应拒绝更新;如果昵称有效,系统应保存更新。 + +**Validates: Requirements 4.2** + +### Property 11: VIP等级计算 + +*For any* 用户信息查询,系统应根据用户的累计消费金额正确计算并返回VIP等级。 + +**Validates: Requirements 4.5** + +### Property 12: 手机号绑定验证码验证 + +*For any* 手机号绑定请求,系统应验证短信验证码;验证码错误时应返回"验证码错误"。 + +**Validates: Requirements 5.1, 5.5** + +### Property 13: 账户合并正确性 + +*For any* 手机号已被其他用户绑定的情况,系统应正确合并账户:将当前用户的openid迁移到手机号用户,删除当前用户记录,并返回新的Token。 + +**Validates: Requirements 5.2, 5.3** + +### Property 14: 直接绑定手机号 + +*For any* 手机号未被其他用户绑定的情况,系统应直接更新当前用户的手机号。 + +**Validates: Requirements 5.4** + +### Property 15: 登录日志记录 + +*For any* 成功的登录请求,系统应在UserLoginLog表中记录登录日志,并更新UserAccount表中的最后登录时间和IP信息。 + +**Validates: Requirements 6.1, 6.3** + +### Property 16: recordLogin接口返回值 + +*For any* recordLogin接口调用,系统应返回用户的uid、昵称和头像。 + +**Validates: Requirements 6.4** + +### Property 17: 账号注销类型处理 + +*For any* 账号注销请求,type=0时表示注销账号,type=1时表示取消注销,系统应记录相应的日志并返回成功消息。 + +**Validates: Requirements 7.1, 7.2, 7.3** + +## Error Handling + +### 1. 微信API错误 + +- 当微信API返回错误时,记录详细错误日志 +- 返回用户友好的错误信息:"登录失败,请稍后重试" + +### 2. 验证码错误 + +- 验证码不存在或已过期:返回"验证码错误" +- 验证码不匹配:返回"验证码错误" + +### 3. 防抖限制 + +- 用户频繁请求:返回"请勿频繁登录,请稍后再试" + +### 4. Token错误 + +- Token无效:返回status=-1,msg="未登录" +- Token过期:返回status=-1,msg="登录已过期" + +### 5. 数据库错误 + +- 事务失败时回滚 +- 记录详细错误日志 +- 返回"网络故障,请稍后再试" + +## Testing Strategy + +### 单元测试 + +使用xUnit框架编写单元测试,覆盖以下场景: + +1. **AuthService测试** + - 微信登录成功/失败场景 + - 手机号登录成功/失败场景 + - 防抖机制测试 + - 账户合并测试 + +2. **JwtService测试** + - Token生成测试 + - Token验证测试 + - Token过期测试 + +3. **UserService测试** + - 用户查找测试 + - 用户创建测试 + - 用户信息更新测试 + - VIP等级计算测试 + +### 属性测试 + +使用FsCheck库进行属性测试,每个属性测试运行至少100次迭代: + +1. **Property 1-5**: 登录相关属性测试 +2. **Property 6-8**: Token相关属性测试 +3. **Property 9-11**: 用户信息相关属性测试 +4. **Property 12-14**: 手机号绑定相关属性测试 +5. **Property 15-17**: 日志和注销相关属性测试 + +### 集成测试 + +1. **API端到端测试** + - 完整的微信登录流程 + - 完整的手机号登录流程 + - 用户信息获取和更新流程 + +2. **数据库集成测试** + - 用户创建和查询 + - 账户合并 + - 登录日志记录 + +### 测试配置 + +```csharp +// 属性测试配置示例 +[Property(MaxTest = 100)] +public Property LoginShouldGenerateValidToken() +{ + return Prop.ForAll( + Arb.From(), + request => { + var result = _authService.LoginAsync(request).Result; + return result.Success && !string.IsNullOrEmpty(result.Token); + }); +} +``` diff --git a/.kiro/specs/user-auth-migration/requirements.md b/.kiro/specs/user-auth-migration/requirements.md new file mode 100644 index 00000000..6b8f364f --- /dev/null +++ b/.kiro/specs/user-auth-migration/requirements.md @@ -0,0 +1,116 @@ +# Requirements Document + +## Introduction + +本文档定义了将PHP用户认证系统迁移到.NET 8的需求规范。迁移范围包括微信小程序登录、手机号验证码登录、JWT Token管理、用户信息管理、手机号绑定、登录记录和账号注销功能。迁移过程中需要保持与现有UniApp前端的100%兼容性。 + +## Glossary + +- **Auth_System**: 用户认证系统,负责处理用户登录、注册、Token管理等功能 +- **Wechat_Service**: 微信服务,负责与微信API交互获取openid和用户信息 +- **Sms_Service**: 短信服务,负责验证短信验证码(发送验证码暂不迁移,继续使用PHP接口) +- **Jwt_Service**: JWT服务,负责生成、验证和刷新JWT Token +- **User_Service**: 用户服务,负责用户信息的增删改查 +- **Redis_Cache**: Redis缓存服务,用于存储验证码和防抖锁 +- **IP_Location_Service**: IP地理位置服务,用于解析用户登录IP的地理位置 + +## Requirements + +### Requirement 1: 微信小程序登录 + +**User Story:** As a 用户, I want to 通过微信小程序授权登录, so that 我可以快速进入系统而无需输入账号密码 + +#### Acceptance Criteria + +1. WHEN 用户提交微信授权code, THE Auth_System SHALL 调用微信API获取openid和unionid +2. WHEN 获取到openid后, THE Auth_System SHALL 查找是否存在该用户(优先通过unionid查找,其次通过openid查找) +3. WHEN 用户不存在时, THE Auth_System SHALL 自动创建新用户并生成默认头像和昵称 +4. WHEN 用户存在时, THE Auth_System SHALL 更新用户的unionid(如果之前为空) +5. WHEN 登录成功后, THE Auth_System SHALL 生成JWT Token并返回给客户端 +6. WHEN 用户在3秒内重复请求登录, THE Auth_System SHALL 返回"请勿频繁登录"错误(防抖机制) +7. IF 微信API调用失败, THEN THE Auth_System SHALL 返回明确的错误信息 +8. WHEN 用户提供推荐人ID(pid), THE Auth_System SHALL 记录推荐关系 + +### Requirement 2: 手机号验证码登录 + +**User Story:** As a 用户, I want to 通过手机号和验证码登录, so that 我可以在没有微信的情况下也能登录系统 + +#### Acceptance Criteria + +1. WHEN 用户提交手机号和验证码登录, THE Auth_System SHALL 从Redis获取并验证验证码是否正确 +2. WHEN 验证码验证通过后, THE Auth_System SHALL 删除Redis中的验证码 +3. WHEN 手机号用户不存在时, THE Auth_System SHALL 自动创建新用户并生成默认头像和昵称 +4. WHEN 登录成功后, THE Auth_System SHALL 生成JWT Token并返回 +5. IF 验证码错误或过期, THEN THE Auth_System SHALL 返回"验证码错误" +6. WHEN 用户在3秒内重复请求登录, THE Auth_System SHALL 返回"请勿频繁登录"错误 +7. WHEN 用户提供推荐人ID(pid), THE Auth_System SHALL 记录推荐关系 + +**注意:** 发送短信验证码接口暂不迁移,继续使用PHP原有接口 + +### Requirement 3: JWT Token管理 + +**User Story:** As a 系统, I want to 使用JWT Token进行用户认证, so that 可以实现无状态的安全认证 + +#### Acceptance Criteria + +1. WHEN 用户登录成功, THE Jwt_Service SHALL 生成包含用户ID的JWT Token +2. THE Jwt_Service SHALL 使用配置的密钥对Token进行签名 +3. WHEN 请求携带Token访问受保护接口, THE Auth_System SHALL 验证Token的有效性 +4. IF Token无效或过期, THEN THE Auth_System SHALL 返回状态码-1(未登录) +5. WHEN Token即将过期时, THE Jwt_Service SHALL 支持Token刷新功能 +6. THE Auth_System SHALL 同时在数据库UserAccount表中存储account_token用于兼容旧系统 + +### Requirement 4: 用户信息管理 + +**User Story:** As a 用户, I want to 查看和修改我的个人信息, so that 我可以维护我的账户资料 + +#### Acceptance Criteria + +1. WHEN 用户请求获取个人信息, THE User_Service SHALL 返回用户的完整信息(包括余额、积分、VIP等级等) +2. WHEN 用户更新昵称, THE User_Service SHALL 验证昵称不为空并保存 +3. WHEN 用户上传新头像, THE User_Service SHALL 将Base64图片上传到腾讯云COS并更新头像URL +4. THE User_Service SHALL 对手机号进行脱敏处理(显示为138****8000格式) +5. WHEN 返回用户信息时, THE User_Service SHALL 计算并返回用户的VIP等级和相关权益 + +### Requirement 5: 手机号绑定 + +**User Story:** As a 用户, I want to 绑定我的手机号, so that 我可以使用手机号登录并接收重要通知 + +#### Acceptance Criteria + +1. WHEN 用户请求绑定手机号, THE Auth_System SHALL 验证短信验证码 +2. WHEN 手机号已被其他用户绑定, THE Auth_System SHALL 合并两个账户(保留手机号用户,迁移openid) +3. WHEN 账户合并后, THE Auth_System SHALL 返回新的Token +4. WHEN 手机号未被绑定, THE Auth_System SHALL 直接更新当前用户的手机号 +5. IF 验证码错误, THEN THE Auth_System SHALL 返回"验证码错误" + +### Requirement 6: 登录记录 + +**User Story:** As a 系统管理员, I want to 记录用户的登录信息, so that 可以进行安全审计和用户行为分析 + +#### Acceptance Criteria + +1. WHEN 用户登录成功, THE Auth_System SHALL 记录登录日志(包括用户ID、设备类型、IP地址、登录时间) +2. WHEN 记录登录时, THE IP_Location_Service SHALL 解析IP地址获取省份和城市信息 +3. THE Auth_System SHALL 更新UserAccount表中的最后登录时间和IP信息 +4. WHEN 用户调用recordLogin接口, THE Auth_System SHALL 返回用户的uid、昵称和头像 + +### Requirement 7: 账号注销 + +**User Story:** As a 用户, I want to 注销我的账号, so that 我可以删除我在系统中的所有数据 + +#### Acceptance Criteria + +1. WHEN 用户请求注销账号, THE Auth_System SHALL 记录注销请求日志 +2. THE Auth_System SHALL 返回注销成功的消息 +3. WHEN type参数为0时表示注销账号,type为1时表示取消注销 + +### Requirement 8: API接口文档更新 + +**User Story:** As a 开发者, I want to 在迁移完成后更新API接口文档, so that 可以追踪迁移进度和新接口地址 + +#### Acceptance Criteria + +1. WHEN 每个接口迁移完成后, THE 开发者 SHALL 在docs/API接口文档.md中标记该接口为"已迁移" +2. THE 文档 SHALL 记录新接口的完整地址 +3. THE 文档 SHALL 保留原接口信息以便对比 diff --git a/.kiro/specs/user-auth-migration/tasks.md b/.kiro/specs/user-auth-migration/tasks.md new file mode 100644 index 00000000..e0567fc0 --- /dev/null +++ b/.kiro/specs/user-auth-migration/tasks.md @@ -0,0 +1,190 @@ +# Implementation Plan: 用户认证系统迁移 + +## Overview + +本任务列表将PHP用户认证系统迁移到.NET 8,按照接口优先级逐个迁移,每完成一个接口都需要更新API接口文档标记迁移状态。 + +## Tasks + +- [ ] 1. 基础设施准备 + - [ ] 1.1 创建认证相关的DTO和Request/Response模型 + - 在HoneyBox.Model/Models目录下创建Auth相关的请求响应模型 + - 包括WechatLoginRequest、MobileLoginRequest、ApiResponse等 + - _Requirements: 1.1-1.8, 2.1-2.7_ + - [ ] 1.2 创建服务接口定义 + - 在HoneyBox.Core/Interfaces目录下创建IAuthService、IJwtService、IWechatService、IUserService、IIpLocationService接口 + - _Requirements: 1.1-1.8, 2.1-2.7, 3.1-3.6_ + - [ ] 1.3 配置JWT认证中间件 + - 在Program.cs中配置JWT Bearer认证 + - 添加JwtSettings配置类 + - _Requirements: 3.1-3.6_ + - [ ] 1.4 配置Redis服务 + - 添加StackExchange.Redis依赖 + - 配置Redis连接和服务注入 + - _Requirements: 1.6, 2.1, 2.2, 2.6_ + +- [ ] 2. JWT服务实现 + - [ ] 2.1 实现JwtService + - 实现Token生成、验证、刷新功能 + - 实现从Token中提取用户ID + - _Requirements: 3.1-3.5_ + - [ ] 2.2 编写JwtService单元测试 + - 测试Token生成和验证 + - **Property 3: 登录成功Token生成** + - **Validates: Requirements 3.1, 3.2** + - [ ] 2.3 编写Token验证属性测试 + - **Property 7: Token验证与授权** + - **Validates: Requirements 3.3, 3.4** + +- [ ] 3. 用户服务实现 + - [ ] 3.1 实现UserService基础功能 + - 实现用户查找(ByOpenId、ByUnionId、ByMobile) + - 实现用户创建 + - 实现UID生成策略 + - _Requirements: 1.2, 1.3, 2.3_ + - [ ] 3.2 实现用户信息获取和更新 + - 实现GetUserInfoAsync + - 实现UpdateUserAsync + - 实现VIP等级计算 + - _Requirements: 4.1-4.5_ + - [ ] 3.3 编写UserService属性测试 + - **Property 2: 新用户创建完整性** + - **Property 9: 用户信息完整性** + - **Property 10: 昵称更新验证** + - **Property 11: VIP等级计算** + - **Validates: Requirements 1.3, 2.3, 4.1, 4.2, 4.4, 4.5** + +- [ ] 4. 微信服务实现 + - [ ] 4.1 实现WechatService + - 实现GetOpenIdAsync(调用微信API获取openid/unionid) + - 实现GetMobileAsync(获取微信授权手机号) + - _Requirements: 1.1, 5.1_ + - [ ] 4.2 编写WechatService单元测试 + - Mock微信API测试 + - _Requirements: 1.1, 1.7_ + +- [ ] 5. IP地理位置服务实现 + - [ ] 5.1 实现IpLocationService + - 调用高德地图API解析IP地址 + - 返回省份、城市、区域编码 + - _Requirements: 6.2_ + +- [ ] 6. 认证服务实现 + - [ ] 6.1 实现AuthService - 微信登录 + - 实现WechatMiniProgramLoginAsync + - 包含防抖机制、用户查找/创建、Token生成 + - _Requirements: 1.1-1.8_ + - [ ] 6.2 实现AuthService - 手机号登录 + - 实现MobileLoginAsync + - 包含验证码验证、用户查找/创建、Token生成 + - _Requirements: 2.1-2.7_ + - [ ] 6.3 实现AuthService - 手机号绑定 + - 实现BindMobileAsync和WechatBindMobileAsync + - 包含账户合并逻辑 + - _Requirements: 5.1-5.5_ + - [ ] 6.4 实现AuthService - 登录记录 + - 实现RecordLoginAsync + - 记录登录日志、更新UserAccount + - _Requirements: 6.1, 6.3, 6.4_ + - [ ] 6.5 实现AuthService - 账号注销 + - 实现LogOffAsync + - _Requirements: 7.1-7.3_ + - [ ] 6.6 编写AuthService属性测试 + - **Property 1: 微信登录用户查找优先级** + - **Property 4: 登录防抖机制** + - **Property 5: 推荐关系记录** + - **Property 6: 验证码验证与清理** + - **Property 8: 数据库Token兼容存储** + - **Validates: Requirements 1.2, 1.6, 1.8, 2.1, 2.2, 2.6, 2.7, 3.6** + - [ ] 6.7 编写手机号绑定属性测试 + - **Property 12: 手机号绑定验证码验证** + - **Property 13: 账户合并正确性** + - **Property 14: 直接绑定手机号** + - **Validates: Requirements 5.1-5.5** + - [ ] 6.8 编写登录记录属性测试 + - **Property 15: 登录日志记录** + - **Property 16: recordLogin接口返回值** + - **Property 17: 账号注销类型处理** + - **Validates: Requirements 6.1, 6.3, 6.4, 7.1-7.3** + +- [ ] 7. Checkpoint - 服务层测试验证 + - 确保所有服务层单元测试通过 + - 确保所有属性测试通过 + - 如有问题请询问用户 + +- [ ] 8. 控制器实现 - AuthController + - [ ] 8.1 实现微信小程序登录接口 POST /login + - 调用AuthService.WechatMiniProgramLoginAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 1.1-1.8_ + - [ ] 8.2 实现手机号登录接口 POST /mobileLogin + - 调用AuthService.MobileLoginAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 2.1-2.7_ + - [ ] 8.3 实现微信授权绑定手机号接口 POST /login_bind_mobile + - 调用AuthService.WechatBindMobileAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 5.1-5.5_ + - [ ] 8.4 实现验证码绑定手机号接口 POST /bindMobile + - 调用AuthService.BindMobileAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 5.1-5.5_ + - [ ] 8.5 实现登录记录接口 GET|POST /login_record + - 调用AuthService.RecordLoginAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 6.1-6.4_ + +- [ ] 9. 控制器实现 - UserController + - [ ] 9.1 实现获取用户信息接口 POST /user + - 调用UserService.GetUserInfoAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 4.1-4.5_ + - [ ] 9.2 实现更新用户信息接口 POST /update_userinfo + - 调用UserService.UpdateUserAsync + - 支持Base64头像上传到腾讯云COS + - 更新API接口文档标记迁移状态 + - _Requirements: 4.2, 4.3_ + - [ ] 9.3 实现账号注销接口 POST /user_log_off + - 调用AuthService.LogOffAsync + - 更新API接口文档标记迁移状态 + - _Requirements: 7.1-7.3_ + +- [ ] 10. Checkpoint - 控制器测试验证 + - 确保所有控制器接口可正常访问 + - 使用Postman或HTTP文件测试各接口 + - 如有问题请询问用户 + +- [ ] 11. 集成测试 + - [ ] 11.1 编写微信登录集成测试 + - 测试完整的微信登录流程 + - _Requirements: 1.1-1.8_ + - [ ] 11.2 编写手机号登录集成测试 + - 测试完整的手机号登录流程 + - _Requirements: 2.1-2.7_ + - [ ] 11.3 编写用户信息接口集成测试 + - 测试用户信息获取和更新流程 + - _Requirements: 4.1-4.5_ + +- [ ] 12. 文档更新和最终验证 + - [ ] 12.1 更新API接口文档 + - 确认所有迁移接口都已标记 + - 记录新接口地址 + - _Requirements: 8.1-8.3_ + - [ ] 12.2 创建HTTP测试文件 + - 在HoneyBox.Api目录下创建auth.http测试文件 + - 包含所有认证相关接口的测试请求 + +- [ ] 13. Final Checkpoint - 完整功能验证 + - 确保所有测试通过 + - 确保API文档已更新 + - 确保与前端兼容性 + - 如有问题请询问用户 + +## Notes + +- All tasks are required for comprehensive testing from the start +- Each task references specific requirements for traceability +- Checkpoints ensure incremental validation +- Property tests validate universal correctness properties +- Unit tests validate specific examples and edge cases +- 每迁移完成一个接口,都需要在docs/API接口文档.md中标记迁移状态和新接口地址