From da43347ac26d85beba2c384c394668887ab806a8 Mon Sep 17 00:00:00 2001 From: root <295172551@qq.com> Date: Sat, 5 Jul 2025 12:57:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=90=8C=E6=AD=A5=E6=9C=80=E6=96=B0?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=92=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/X1.Domain/Common/OperationResult.cs | 7 +- .../Controllers/AuthController.cs | 68 +++--- .../Controllers/DevicesController.cs | 35 ++- .../Controllers/PermissionsController.cs | 7 +- .../Controllers/RolePermissionController.cs | 21 +- .../Controllers/RolesController.cs | 37 ++- .../Controllers/UsersController.cs | 67 +++-- .../src/components/auth/LoginForm.tsx | 31 ++- .../src/components/auth/RegisterForm.tsx | 44 +++- src/X1.WebUI/src/constants/auth.ts | 3 +- .../src/pages/auth/ForgotPasswordPage.tsx | 45 +++- src/X1.WebUI/src/services/apiService.ts | 231 ++++++------------ src/X1.WebUI/src/services/authService.ts | 31 ++- src/X1.WebUI/src/types/auth.ts | 18 +- 14 files changed, 316 insertions(+), 329 deletions(-) diff --git a/src/X1.Domain/Common/OperationResult.cs b/src/X1.Domain/Common/OperationResult.cs index 42af19c..74304be 100644 --- a/src/X1.Domain/Common/OperationResult.cs +++ b/src/X1.Domain/Common/OperationResult.cs @@ -28,6 +28,11 @@ public sealed record OperationResult( /// public bool IsSuccess => ErrorMessages == null || !ErrorMessages.Any(); + /// + /// 获取成功消息(如果为空则返回默认消息) + /// + public string GetSuccessMessage() => SuccessMessage ?? "操作成功"; + /// /// 创建成功结果(仅包含数据) /// @@ -35,7 +40,7 @@ public sealed record OperationResult( /// 成功结果 public static OperationResult CreateSuccess(T data) { - return new OperationResult(null, null, data); + return new OperationResult("操作成功", null, data); } /// diff --git a/src/X1.Presentation/Controllers/AuthController.cs b/src/X1.Presentation/Controllers/AuthController.cs index 631e653..c47b9be 100644 --- a/src/X1.Presentation/Controllers/AuthController.cs +++ b/src/X1.Presentation/Controllers/AuthController.cs @@ -81,7 +81,7 @@ public class AuthController : ApiController [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status429TooManyRequests)] - public async Task>> Login([FromBody] AuthenticateUserCommand command) + public async Task> Login([FromBody] AuthenticateUserCommand command) { try { @@ -92,8 +92,7 @@ public class AuthController : ApiController if (attempts >= _authConfig.MaxLoginAttempts) { _logger.LogWarning("账号 {UserName} 登录尝试次数过多", command.UserName); - return StatusCode(StatusCodes.Status429TooManyRequests, - OperationResult.CreateFailure("登录尝试次数过多,请稍后再试")); + return OperationResult.CreateFailure("登录尝试次数过多,请稍后再试"); } // 执行登录 @@ -123,13 +122,12 @@ public class AuthController : ApiController _logger.LogWarning($"Bearer {result.Data.AccessToken}"); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "账号 {UserName} 登录时发生异常", command.UserName); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -156,10 +154,10 @@ public class AuthController : ApiController /// 登录失败,返回错误信息 /// 登录尝试次数过多 [HttpPost("email")] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status429TooManyRequests)] - public async Task>> LoginWithEmail([FromBody] EmailLoginCommand command) + [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(OperationResult), StatusCodes.Status429TooManyRequests)] + public async Task> LoginWithEmail([FromBody] EmailLoginCommand command) { try { @@ -170,8 +168,7 @@ public class AuthController : ApiController if (attempts >= _authConfig.MaxLoginAttempts) { _logger.LogWarning("邮箱 {Email} 登录尝试次数过多", command.Email); - return StatusCode(StatusCodes.Status429TooManyRequests, - OperationResult.CreateFailure("登录尝试次数过多,请稍后再试")); + return OperationResult.CreateFailure("登录尝试次数过多,请稍后再试"); } // 执行登录 @@ -201,13 +198,12 @@ public class AuthController : ApiController _logger.LogWarning($"Bearer {result.Data.AccessToken}"); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "邮箱 {Email} 登录时发生异常", command.Email); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -238,7 +234,7 @@ public class AuthController : ApiController [HttpPost("register")] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> Register([FromBody] RegisterUserCommand command) + public async Task> Register([FromBody] RegisterUserCommand command) { try { @@ -256,13 +252,12 @@ public class AuthController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "用户 {UserName} 注册时发生异常", command.UserName); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -289,7 +284,7 @@ public class AuthController : ApiController [HttpPost("refresh-token")] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> RefreshToken([FromBody] RefreshTokenCommand command) + public async Task> RefreshToken([FromBody] RefreshTokenCommand command) { try { @@ -305,13 +300,12 @@ public class AuthController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "刷新令牌时发生异常"); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -338,7 +332,7 @@ public class AuthController : ApiController [HttpPost("verification-codes")] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> SendVerificationCode( + public async Task> SendVerificationCode( [FromBody] SendVerificationCodeCommand command) { try @@ -357,13 +351,12 @@ public class AuthController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "向邮箱 {Email} 发送验证码时发生异常", command.Email); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -391,7 +384,7 @@ public class AuthController : ApiController [HttpPost("verification-codes/verify")] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> VerifyCode( + public async Task> VerifyCode( [FromBody] VerifyCodeCommand command) { try @@ -410,13 +403,12 @@ public class AuthController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "验证邮箱 {Email} 的验证码时发生异常", command.Email); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -432,7 +424,7 @@ public class AuthController : ApiController [HttpGet("captcha")] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status500InternalServerError)] - public async Task>> GetCaptcha() + public async Task> GetCaptcha() { try { @@ -455,13 +447,12 @@ public class AuthController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "生成图形验证码时发生异常"); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -488,7 +479,7 @@ public class AuthController : ApiController [HttpPost("logout")] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> Logout([FromBody] LogoutCommand command) + public async Task> Logout([FromBody] LogoutCommand command) { try { @@ -504,13 +495,12 @@ public class AuthController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "用户登出时发生异常"); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } } \ No newline at end of file diff --git a/src/X1.Presentation/Controllers/DevicesController.cs b/src/X1.Presentation/Controllers/DevicesController.cs index cfc6fab..1995c98 100644 --- a/src/X1.Presentation/Controllers/DevicesController.cs +++ b/src/X1.Presentation/Controllers/DevicesController.cs @@ -38,7 +38,7 @@ namespace CellularManagement.Presentation.Controllers /// 获取设备列表 /// [HttpGet] - public async Task>> GetAll([FromQuery] GetDevicesQuery query) + public async Task> GetAll([FromQuery] GetDevicesQuery query) { _logger.LogInformation("开始获取设备列表,页码: {PageNumber}, 每页数量: {PageSize}, 搜索关键词: {SearchTerm}", query.PageNumber, query.PageSize, query.SearchTerm); @@ -47,18 +47,18 @@ namespace CellularManagement.Presentation.Controllers if (!result.IsSuccess) { _logger.LogWarning("获取设备列表失败: {Message}", result.ErrorMessages); - return BadRequest(result); + return result; } _logger.LogInformation("成功获取设备列表,共 {Count} 条记录", result.Data?.TotalCount ?? 0); - return Ok(result); + return result; } /// /// 获取设备详情 /// [HttpGet("{id}")] - public async Task>> GetById(string id) + public async Task> GetById(string id) { _logger.LogInformation("开始获取设备详情,设备ID: {DeviceId}", id); @@ -66,18 +66,18 @@ namespace CellularManagement.Presentation.Controllers if (!result.IsSuccess) { _logger.LogWarning("获取设备详情失败: {Message}", result.ErrorMessages); - return NotFound(result); + return result; } _logger.LogInformation("成功获取设备详情,设备ID: {DeviceId}", id); - return Ok(result); + return result; } /// /// 创建设备 /// [HttpPost] - public async Task>> Create([FromBody] CreateDeviceCommand command) + public async Task> Create([FromBody] CreateDeviceCommand command) { _logger.LogInformation("开始创建设备,设备名称: {DeviceName}", command.DeviceName); @@ -85,46 +85,43 @@ namespace CellularManagement.Presentation.Controllers if (!result.IsSuccess) { _logger.LogWarning("创建设备失败: {Message}", result.ErrorMessages); - return BadRequest(result); + return result; } _logger.LogInformation("成功创建设备,设备ID: {DeviceId}", result.Data.DeviceId); - return CreatedAtAction( - nameof(GetById), - new { id = result.Data.DeviceId }, - result); + return result; } /// /// 更新设备 /// [HttpPut("{id}")] - public async Task>> Update(string id, [FromBody] UpdateDeviceCommand command) + public async Task> Update(string id, [FromBody] UpdateDeviceCommand command) { _logger.LogInformation("开始更新设备,设备ID: {DeviceId}", id); if (id != command.DeviceId) { _logger.LogWarning("设备ID不匹配,路径ID: {PathId}, 命令ID: {CommandId}", id, command.DeviceName); - return BadRequest(OperationResult.CreateFailure("设备ID不匹配")); + return OperationResult.CreateFailure("设备ID不匹配"); } var result = await mediator.Send(command); if (!result.IsSuccess) { _logger.LogWarning("更新设备失败: {Message}", result.ErrorMessages); - return NotFound(result); + return result; } _logger.LogInformation("成功更新设备,设备ID: {DeviceId}", id); - return Ok(result); + return result; } /// /// 删除设备 /// [HttpDelete("{id}")] - public async Task>> Delete(string id) + public async Task> Delete(string id) { _logger.LogInformation("开始删除设备,设备ID: {DeviceId}", id); @@ -132,11 +129,11 @@ namespace CellularManagement.Presentation.Controllers if (!result.IsSuccess) { _logger.LogWarning("删除设备失败: {Message}", result.ErrorMessages); - return NotFound(result); + return result; } _logger.LogInformation("成功删除设备,设备ID: {DeviceId}", id); - return Ok(result); + return result; } } } \ No newline at end of file diff --git a/src/X1.Presentation/Controllers/PermissionsController.cs b/src/X1.Presentation/Controllers/PermissionsController.cs index 2b1e248..0ecf380 100644 --- a/src/X1.Presentation/Controllers/PermissionsController.cs +++ b/src/X1.Presentation/Controllers/PermissionsController.cs @@ -57,7 +57,7 @@ public class PermissionsController : ApiController [HttpPost] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> CreatePermission([FromBody] CreatePermissionCommand command) + public async Task> CreatePermission([FromBody] CreatePermissionCommand command) { try { @@ -74,13 +74,12 @@ public class PermissionsController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "创建权限 {PermissionName} 时发生异常", command.Name); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } } \ No newline at end of file diff --git a/src/X1.Presentation/Controllers/RolePermissionController.cs b/src/X1.Presentation/Controllers/RolePermissionController.cs index 9365d87..ce0a326 100644 --- a/src/X1.Presentation/Controllers/RolePermissionController.cs +++ b/src/X1.Presentation/Controllers/RolePermissionController.cs @@ -54,7 +54,7 @@ public class RolePermissionController : ApiController [HttpGet("{roleId}")] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> GetRolePermissions( + public async Task> GetRolePermissions( string roleId, [FromQuery] bool includeDetails = true) { @@ -83,13 +83,12 @@ public class RolePermissionController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "获取角色 {RoleId} 的权限信息时发生异常", roleId); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -117,7 +116,7 @@ public class RolePermissionController : ApiController [HttpPost] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> AddRolePermissions( + public async Task> AddRolePermissions( [FromBody] AddRolePermissionsCommand command) { try @@ -140,13 +139,12 @@ public class RolePermissionController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "为角色 {RoleId} 添加权限时发生异常", command.RoleId); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -174,7 +172,7 @@ public class RolePermissionController : ApiController [HttpDelete] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> DeleteRolePermissions( + public async Task> DeleteRolePermissions( [FromBody] DeleteRolePermissionsCommand command) { try @@ -197,13 +195,12 @@ public class RolePermissionController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "从角色 {RoleId} 删除权限时发生异常", command.RoleId); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } } \ No newline at end of file diff --git a/src/X1.Presentation/Controllers/RolesController.cs b/src/X1.Presentation/Controllers/RolesController.cs index cd7f000..ffc662c 100644 --- a/src/X1.Presentation/Controllers/RolesController.cs +++ b/src/X1.Presentation/Controllers/RolesController.cs @@ -78,7 +78,7 @@ public class RolesController : ApiController [HttpPost] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> CreateRole([FromBody] CreateRoleCommand command) + public async Task> CreateRole([FromBody] CreateRoleCommand command) { try { @@ -95,13 +95,12 @@ public class RolesController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "创建角色 {RoleName} 时发生异常", command.Name); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -127,7 +126,7 @@ public class RolesController : ApiController [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status404NotFound)] - public async Task>> DeleteRole(string roleId) + public async Task> DeleteRole(string roleId) { try { @@ -145,13 +144,12 @@ public class RolesController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "删除角色 {RoleId} 时发生异常", roleId); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -175,7 +173,7 @@ public class RolesController : ApiController [HttpGet("{roleId}")] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status404NotFound)] - public async Task>> GetRole(string roleId) + public async Task> GetRole(string roleId) { try { @@ -193,13 +191,12 @@ public class RolesController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "获取角色 {RoleId} 信息时发生异常", roleId); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -223,7 +220,7 @@ public class RolesController : ApiController [HttpGet] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> GetAllRoles([FromQuery] GetAllRolesQuery query) + public async Task> GetAllRoles([FromQuery] GetAllRolesQuery query) { try { @@ -231,23 +228,21 @@ public class RolesController : ApiController if (result.IsSuccess) { - _logger.LogInformation("获取角色列表成功,共 {TotalCount} 条记录,当前第 {PageNumber} 页", - result.Data?.TotalCount, - result.Data?.PageNumber); + _logger.LogInformation("获取所有角色成功,共 {Count} 个角色", + result.Data?.Roles.Count()); } else { - _logger.LogWarning("获取角色列表失败: {Error}", + _logger.LogWarning("获取所有角色失败: {Error}", result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { - _logger.LogError(ex, "获取角色列表时发生异常"); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + _logger.LogError(ex, "获取所有角色时发生异常"); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } } \ No newline at end of file diff --git a/src/X1.Presentation/Controllers/UsersController.cs b/src/X1.Presentation/Controllers/UsersController.cs index 5bf5b18..bdd8d26 100644 --- a/src/X1.Presentation/Controllers/UsersController.cs +++ b/src/X1.Presentation/Controllers/UsersController.cs @@ -64,7 +64,7 @@ public class UsersController : ApiController [HttpPost] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status201Created)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> CreateUser([FromBody] CreateUserCommand command) + public async Task> CreateUser([FromBody] CreateUserCommand command) { try { @@ -73,20 +73,19 @@ public class UsersController : ApiController if (result.IsSuccess) { _logger.LogInformation("创建用户成功,用户ID: {UserId}", result.Data?.UserId); - return CreatedAtAction(nameof(GetUserById), new { id = result.Data?.UserId }, result); } else { _logger.LogWarning("创建用户失败: {Error}", result.ErrorMessages?.FirstOrDefault()); - return BadRequest(result); } + + return result; } catch (Exception ex) { _logger.LogError(ex, "创建用户时发生异常"); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -117,7 +116,7 @@ public class UsersController : ApiController [HttpGet] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - public async Task>> GetUsers([FromQuery] GetAllUsersQuery query) + public async Task> GetUsers([FromQuery] GetAllUsersQuery query) { try { @@ -135,13 +134,12 @@ public class UsersController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "获取用户列表时发生异常"); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -167,7 +165,7 @@ public class UsersController : ApiController [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status404NotFound)] - public async Task>> GetUserById([FromRoute] string id) + public async Task> GetUserById([FromRoute] string id) { try { @@ -185,13 +183,12 @@ public class UsersController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "获取用户 {UserId} 信息时发生异常", id); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -223,13 +220,18 @@ public class UsersController : ApiController [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status404NotFound)] - public async Task>> UpdateUser( + public async Task> UpdateUser( [FromRoute] string id, [FromBody] UpdateUserCommand command) { try { - command = command with { UserId = id }; + if (id != command.UserId) + { + _logger.LogWarning("用户ID不匹配,路径ID: {PathId}, 命令ID: {CommandId}", id, command.UserId); + return OperationResult.CreateFailure("用户ID不匹配"); + } + var result = await mediator.Send(command); if (result.IsSuccess) @@ -243,13 +245,12 @@ public class UsersController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "更新用户 {UserId} 信息时发生异常", id); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -272,10 +273,10 @@ public class UsersController : ApiController /// 删除失败,返回错误信息 /// 用户不存在 [HttpDelete("{id}")] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(OperationResult), StatusCodes.Status404NotFound)] - public async Task>> DeleteUser([FromRoute] string id) + [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(OperationResult), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(OperationResult), StatusCodes.Status404NotFound)] + public async Task> DeleteUser([FromRoute] string id) { try { @@ -293,13 +294,12 @@ public class UsersController : ApiController result.ErrorMessages?.FirstOrDefault()); } - return Ok(result); + return result; } catch (Exception ex) { _logger.LogError(ex, "删除用户 {UserId} 时发生异常", id); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } @@ -324,15 +324,15 @@ public class UsersController : ApiController [ProducesResponseType(typeof(OperationResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status401Unauthorized)] [ProducesResponseType(typeof(OperationResult), StatusCodes.Status404NotFound)] - public async Task>> CurrentUser() + public async Task> CurrentUser() { try { - var userId = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value; + var userId = User.FindFirst("sub")?.Value; if (string.IsNullOrEmpty(userId)) { - _logger.LogWarning("获取当前用户信息失败:未找到用户ID"); - return Unauthorized(OperationResult.CreateFailure("未授权,请先登录")); + _logger.LogWarning("无法获取当前用户ID"); + return OperationResult.CreateFailure("无法获取当前用户信息"); } var query = new GetUserByIdQuery(userId); @@ -340,21 +340,20 @@ public class UsersController : ApiController if (result.IsSuccess) { - _logger.LogInformation("获取当前用户信息成功,用户ID: {UserId}", userId); - return Ok(result); + _logger.LogInformation("获取当前用户信息成功"); } else { _logger.LogWarning("获取当前用户信息失败: {Error}", result.ErrorMessages?.FirstOrDefault()); - return NotFound(result); } + + return result; } catch (Exception ex) { _logger.LogError(ex, "获取当前用户信息时发生异常"); - return StatusCode(StatusCodes.Status500InternalServerError, - OperationResult.CreateFailure("系统错误,请稍后重试")); + return OperationResult.CreateFailure("系统错误,请稍后重试"); } } } \ No newline at end of file diff --git a/src/X1.WebUI/src/components/auth/LoginForm.tsx b/src/X1.WebUI/src/components/auth/LoginForm.tsx index b377e25..95f9aeb 100644 --- a/src/X1.WebUI/src/components/auth/LoginForm.tsx +++ b/src/X1.WebUI/src/components/auth/LoginForm.tsx @@ -4,6 +4,7 @@ import { useAuth } from '@/contexts/AuthContext'; import { useNavigate } from 'react-router-dom'; import { apiService } from '@/services/apiService'; import { toast } from '@/components/ui/use-toast'; +import { getErrorMessage } from '@/types/auth'; interface LoginFormProps { onSubmit: (username: string, password: string, rememberMe: boolean, loginType: 'account' | 'email', verificationCode?: string, captchaId?: string, captchaCode?: string) => Promise; @@ -44,28 +45,36 @@ export function LoginForm({ onSubmit }: LoginFormProps) { try { setCaptchaAvailable(false); const result = await apiService.getCaptcha(); - if (result.success && result.data) { + + // 业务逻辑判断 + if (result.isSuccess && result.data) { setCaptchaImage(result.data.imageBase64); setCaptchaId(result.data.captchaId); setCaptchaAvailable(true); + console.log('验证码获取成功:', result.successMessage); } else { + // 业务操作失败 setCaptchaImage(''); setCaptchaId(''); setCaptchaAvailable(false); + const errorMessage = getErrorMessage(result); + console.warn('验证码获取业务操作失败:', errorMessage); toast({ title: '获取验证码失败', - description: result.message || '请点击验证码图片重试', + description: errorMessage || '请点击验证码图片重试', variant: 'destructive', duration: 3000, }); } } catch (error) { + // HTTP 错误处理 setCaptchaImage(''); setCaptchaId(''); setCaptchaAvailable(false); + console.error('验证码获取HTTP错误:', error); toast({ title: '获取验证码失败', - description: '请点击验证码图片重试', + description: '网络错误,请点击验证码图片重试', variant: 'destructive', duration: 3000, }); @@ -123,31 +132,37 @@ export function LoginForm({ onSubmit }: LoginFormProps) { } try { - const response = await apiService.sendVerificationCode({ + const result = await apiService.sendVerificationCode({ email: `${email}@qq.com`, captchaId, captchaCode }); - if (response.success) { + // 业务逻辑判断 + if (result.isSuccess) { setCountdown(120); // 设置120秒倒计时 toast({ title: '验证码已发送', - description: '请查收您的QQ邮箱', + description: result.successMessage || '请查收您的QQ邮箱', duration: 3000, }); } else { + // 业务操作失败 + const errorMessage = getErrorMessage(result); + console.warn('发送验证码业务操作失败:', errorMessage); toast({ title: '发送失败', - description: response.message || '请稍后重试', + description: errorMessage || '请稍后重试', variant: 'destructive', duration: 3000, }); } } catch (error) { + // HTTP 错误处理 + console.error('发送验证码HTTP错误:', error); toast({ title: '发送失败', - description: '请稍后重试', + description: '网络错误,请稍后重试', variant: 'destructive', duration: 3000, }); diff --git a/src/X1.WebUI/src/components/auth/RegisterForm.tsx b/src/X1.WebUI/src/components/auth/RegisterForm.tsx index d7cac96..1eda526 100644 --- a/src/X1.WebUI/src/components/auth/RegisterForm.tsx +++ b/src/X1.WebUI/src/components/auth/RegisterForm.tsx @@ -2,6 +2,7 @@ import { useState, useEffect } from 'react'; import { z } from 'zod'; import { toast } from '@/components/ui/use-toast'; import { apiService } from '@/services/apiService'; +import { getErrorMessage } from '@/types/auth'; // 定义表单验证规则 const registerSchema = z.object({ @@ -70,40 +71,53 @@ export function RegisterForm({ onSubmit }: RegisterFormProps) { // 获取验证码 const fetchCaptcha = async () => { + console.log('fetchCaptcha 被调用'); // 添加调试日志 try { - setCaptchaAvailable(false); + setCaptchaAvailable(false); // 开始获取时设置为不可用 const result = await apiService.getCaptcha(); - if (result.success && result.data) { + + // 业务逻辑判断 + if (result.isSuccess && result.data) { setCaptchaImage(result.data.imageBase64); setCaptchaId(result.data.captchaId); - setCaptchaAvailable(true); + setCaptchaAvailable(true); // 成功时设置为可用 setError(null); + console.log('验证码获取成功:', result.successMessage); } else { - setCaptchaImage(''); - setCaptchaId(''); - setCaptchaAvailable(false); + // 业务操作失败 - 保持图片但重置状态 + setCaptchaAvailable(false); // 失败时重置为不可用 + const errorMessage = getErrorMessage(result); setError('获取验证码失败,请重试'); + console.warn('验证码获取业务操作失败:', errorMessage); toast({ title: '获取验证码失败', - description: result.message || '请点击验证码图片重试', + description: errorMessage || '请点击验证码图片重试', variant: 'destructive', duration: 3000, }); } } catch (error) { - setCaptchaImage(''); - setCaptchaId(''); - setCaptchaAvailable(false); + // HTTP 错误处理 - 保持图片但重置状态 + setCaptchaAvailable(false); // 失败时重置为不可用 setError('获取验证码失败,请重试'); + console.error('验证码获取HTTP错误:', error); toast({ title: '获取验证码失败', - description: '请点击验证码图片重试', + description: '网络错误,请点击验证码图片重试', variant: 'destructive', duration: 3000, }); } }; + // 添加专门的点击处理函数 + const handleCaptchaClick = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + console.log('验证码图片被点击'); // 添加调试日志 + fetchCaptcha(); + }; + // 组件加载时获取验证码 useEffect(() => { fetchCaptcha(); @@ -424,10 +438,14 @@ export function RegisterForm({ onSubmit }: RegisterFormProps) { src={`data:image/png;base64,${captchaImage}`} alt="验证码" className="h-[42px] min-w-[100px] max-w-full cursor-pointer rounded-lg shadow-sm hover:shadow transition-all duration-200" - onClick={fetchCaptcha} + onClick={handleCaptchaClick} // 使用新的处理函数 title="点击刷新验证码" + style={{ pointerEvents: 'auto' }} // 确保可以点击 /> -
+
diff --git a/src/X1.WebUI/src/constants/auth.ts b/src/X1.WebUI/src/constants/auth.ts index dca177f..fc2ae40 100644 --- a/src/X1.WebUI/src/constants/auth.ts +++ b/src/X1.WebUI/src/constants/auth.ts @@ -41,7 +41,8 @@ export const AUTH_CONSTANTS = { RESET_PASSWORD_EMAIL_SENT: '验证码已发送到您的邮箱', RESET_PASSWORD_EMAIL_FAILED: '验证码发送失败,请稍后重试', PASSWORD_RESET_SUCCESS: '密码重置成功', - PASSWORD_RESET_FAILED: '密码重置失败,请稍后重试' + PASSWORD_RESET_FAILED: '密码重置失败,请稍后重试', + ACCOUNT_LOCKED: '账号已被锁定,请稍后再试' } } as const; diff --git a/src/X1.WebUI/src/pages/auth/ForgotPasswordPage.tsx b/src/X1.WebUI/src/pages/auth/ForgotPasswordPage.tsx index 3f49e22..603024d 100644 --- a/src/X1.WebUI/src/pages/auth/ForgotPasswordPage.tsx +++ b/src/X1.WebUI/src/pages/auth/ForgotPasswordPage.tsx @@ -2,6 +2,7 @@ import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { apiService } from '@/services/apiService'; import { toast } from '@/components/ui/use-toast'; +import { getErrorMessage } from '@/types/auth'; export function ForgotPasswordPage() { const navigate = useNavigate(); @@ -20,28 +21,36 @@ export function ForgotPasswordPage() { try { setCaptchaAvailable(false); const result = await apiService.getCaptcha(); - if (result.success && result.data) { + + // 业务逻辑判断:检查业务操作是否成功 + if (result.isSuccess && result.data) { setCaptchaImage(result.data.imageBase64); setCaptchaId(result.data.captchaId); setCaptchaAvailable(true); + console.log('验证码获取成功:', result.successMessage); } else { + // 业务操作失败 setCaptchaImage(''); setCaptchaId(''); setCaptchaAvailable(false); + const errorMessage = getErrorMessage(result); + console.warn('验证码获取业务操作失败:', errorMessage); toast({ title: '获取验证码失败', - description: result.message || '请点击验证码图片重试', + description: errorMessage || '请点击验证码图片重试', variant: 'destructive', duration: 3000, }); } } catch (error) { + // HTTP 错误处理 setCaptchaImage(''); setCaptchaId(''); setCaptchaAvailable(false); + console.error('验证码获取HTTP错误:', error); toast({ title: '获取验证码失败', - description: '请点击验证码图片重试', + description: '网络错误,请点击验证码图片重试', variant: 'destructive', duration: 3000, }); @@ -77,24 +86,31 @@ export function ForgotPasswordPage() { try { setIsLoading(true); const result = await apiService.sendResetPasswordEmail(email, captchaId, captchaCode); - if (result.success) { + + // 业务逻辑判断 + if (result.isSuccess) { toast({ title: '验证码已发送', - description: '请查收您的邮箱', + description: result.successMessage || '请查收您的邮箱', duration: 3000, }); } else { + // 业务操作失败 + const errorMessage = getErrorMessage(result); + console.warn('发送验证码业务操作失败:', errorMessage); toast({ title: '发送失败', - description: result.message || '请稍后重试', + description: errorMessage || '请稍后重试', variant: 'destructive', duration: 3000, }); } } catch (error) { + // HTTP 错误处理 + console.error('发送验证码HTTP错误:', error); toast({ title: '发送失败', - description: '请稍后重试', + description: '网络错误,请稍后重试', variant: 'destructive', duration: 3000, }); @@ -129,25 +145,32 @@ export function ForgotPasswordPage() { try { setIsLoading(true); const result = await apiService.resetPassword(email, verificationCode, newPassword); - if (result.success) { + + // 业务逻辑判断 + if (result.isSuccess) { toast({ title: '密码重置成功', - description: '请使用新密码登录', + description: result.successMessage || '请使用新密码登录', duration: 3000, }); navigate('/login'); } else { + // 业务操作失败 + const errorMessage = getErrorMessage(result); + console.warn('密码重置业务操作失败:', errorMessage); toast({ title: '重置失败', - description: result.message || '请稍后重试', + description: errorMessage || '请稍后重试', variant: 'destructive', duration: 3000, }); } } catch (error) { + // HTTP 错误处理 + console.error('密码重置HTTP错误:', error); toast({ title: '重置失败', - description: '请稍后重试', + description: '网络错误,请稍后重试', variant: 'destructive', duration: 3000, }); diff --git a/src/X1.WebUI/src/services/apiService.ts b/src/X1.WebUI/src/services/apiService.ts index 2c08493..c65039e 100644 --- a/src/X1.WebUI/src/services/apiService.ts +++ b/src/X1.WebUI/src/services/apiService.ts @@ -1,4 +1,4 @@ -import { LoginRequest, RegisterRequest, LoginResponse, User, OperationResult } from '@/types/auth'; +import { LoginRequest, RegisterRequest, LoginResponse, User, OperationResult, getSuccessMessage, getErrorMessage } from '@/types/auth'; import { httpClient } from '@/lib/http-client'; import { AUTH_CONSTANTS } from '@/constants/auth'; @@ -7,13 +7,6 @@ interface CaptchaResponse { imageBase64: string; } -interface ApiResponse { - successMessage: string | null; - errorMessages: string[] | null; - data: T; - isSuccess: boolean; -} - export interface ApiService { login: (request: LoginRequest) => Promise>; emailLogin: (request: { email: string; verificationCode: string }) => Promise>; @@ -27,243 +20,181 @@ export interface ApiService { sendVerificationCode: (request: { email: string; captchaId: string; captchaCode: string }) => Promise>; } -class ApiError extends Error { - constructor(message: string, public statusCode?: number) { - super(message); - this.name = 'ApiError'; - } -} - export const apiService: ApiService = { login: async (request: LoginRequest): Promise> => { try { - const response = await httpClient.post>('/auth/login', request); - if (response.isSuccess) { - return { - success: true, - data: response.data, - message: response.successMessage || AUTH_CONSTANTS.MESSAGES.LOGIN_SUCCESS - }; - } else { - return { - success: false, - message: response?.errorMessages?.join(', ') || AUTH_CONSTANTS.MESSAGES.LOGIN_FAILED - }; + const result = await httpClient.post('/auth/login', request); + if (!result.isSuccess) { + console.warn('登录业务操作失败:', getErrorMessage(result)); } + return result; } catch (error: any) { return { - success: false, - message: error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.LOGIN_FAILED + successMessage: null, + errorMessages: [error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.LOGIN_FAILED], + data: null, + isSuccess: false }; } }, emailLogin: async (request: { email: string; verificationCode: string }): Promise> => { try { - const response = await httpClient.post>('/auth/email', request); - if (response.isSuccess) { - return { - success: true, - data: response.data, - message: response.successMessage || AUTH_CONSTANTS.MESSAGES.LOGIN_SUCCESS - }; - } else { - return { - success: false, - message: response?.errorMessages?.join(', ') || AUTH_CONSTANTS.MESSAGES.LOGIN_FAILED - }; + const result = await httpClient.post('/auth/email', request); + if (!result.isSuccess) { + console.warn('邮箱登录业务操作失败:', getErrorMessage(result)); } + return result; } catch (error: any) { return { - success: false, - message: error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.LOGIN_FAILED + successMessage: null, + errorMessages: [error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.LOGIN_FAILED], + data: null, + isSuccess: false }; } }, register: async (request: RegisterRequest): Promise> => { try { - const response = await httpClient.post>('/auth/register', request); - if (response.isSuccess) { - return { - success: true, - message: response.successMessage || AUTH_CONSTANTS.MESSAGES.REGISTER_SUCCESS - }; - } else { - return { - success: false, - message: response?.errorMessages?.join(', ') || AUTH_CONSTANTS.MESSAGES.REGISTER_FAILED - }; + const result = await httpClient.post('/auth/register', request); + if (!result.isSuccess) { + console.warn('注册业务操作失败:', getErrorMessage(result)); } + return result; } catch (error: any) { return { - success: false, - message: error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.REGISTER_FAILED + successMessage: null, + errorMessages: [error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.REGISTER_FAILED], + data: null, + isSuccess: false }; } }, refreshToken: async (refreshToken: string): Promise> => { try { - const response = await httpClient.post>('/auth/refresh-token', { refreshToken }); - if (response.isSuccess) { - return { - success: true, - data: response.data, - message: response.successMessage || AUTH_CONSTANTS.MESSAGES.TOKEN_REFRESHED - }; - } else { - return { - success: false, - message: response?.errorMessages?.join(', ') || AUTH_CONSTANTS.MESSAGES.TOKEN_REFRESH_FAILED - }; + const result = await httpClient.post('/auth/refresh-token', { refreshToken }); + if (!result.isSuccess) { + console.warn('刷新令牌业务操作失败:', getErrorMessage(result)); } + return result; } catch (error: any) { return { - success: false, - message: error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.TOKEN_REFRESH_FAILED + successMessage: null, + errorMessages: [error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.TOKEN_REFRESH_FAILED], + data: null, + isSuccess: false }; } }, logout: async (): Promise> => { try { - const response = await httpClient.post>('/auth/logout'); - if (response.isSuccess) { - return { - success: true, - message: response.successMessage || AUTH_CONSTANTS.MESSAGES.LOGOUT_SUCCESS - }; - } else { - return { - success: false, - message: response?.errorMessages?.join(', ') || AUTH_CONSTANTS.MESSAGES.LOGOUT_FAILED - }; + const result = await httpClient.post('/auth/logout'); + if (!result.isSuccess) { + console.warn('登出业务操作失败:', getErrorMessage(result)); } + return result; } catch (error: any) { return { - success: false, - message: error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.LOGOUT_FAILED + successMessage: null, + errorMessages: [error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.LOGOUT_FAILED], + data: null, + isSuccess: false }; } }, getCurrentUser: async (): Promise> => { try { - const response = await httpClient.get>('/users/current'); - if (response.isSuccess) { - return { - success: true, - data: response.data, - message: response.successMessage || AUTH_CONSTANTS.MESSAGES.USER_FETCHED - }; - } else { - return { - success: false, - message: response?.errorMessages?.join(', ') || AUTH_CONSTANTS.MESSAGES.USER_FETCH_FAILED - }; + const result = await httpClient.get('/users/current'); + if (!result.isSuccess) { + console.warn('获取当前用户业务操作失败:', getErrorMessage(result)); } + return result; } catch (error: any) { return { - success: false, - message: error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.USER_FETCH_FAILED + successMessage: null, + errorMessages: [error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.USER_INFO_FAILED], + data: null, + isSuccess: false }; } }, getCaptcha: async (): Promise> => { try { - const response = await httpClient.get>('/auth/captcha'); - if (response.isSuccess) { - return { - success: true, - data: response.data, - message: response.successMessage || '验证码获取成功' - }; - } else { - return { - success: false, - message: response?.errorMessages?.join(', ') || '验证码获取失败' - }; + const result = await httpClient.get('/auth/captcha'); + if (!result.isSuccess) { + console.warn('获取验证码业务操作失败:', getErrorMessage(result)); } + return result; } catch (error: any) { return { - success: false, - message: error.response?.data?.message || '验证码获取失败' + successMessage: null, + errorMessages: [error.response?.data?.message || '验证码获取失败'], + data: null, + isSuccess: false }; } }, sendResetPasswordEmail: async (email: string, captchaId: string, captchaCode: string): Promise> => { try { - const response = await httpClient.post>('/auth/reset-password/email', { + const result = await httpClient.post('/auth/reset-password/email', { email: `${email}@qq.com`, captchaId, captchaCode }); - if (response.isSuccess) { - return { - success: true, - message: response.successMessage || AUTH_CONSTANTS.MESSAGES.RESET_PASSWORD_EMAIL_SENT - }; - } else { - return { - success: false, - message: response?.errorMessages?.join(', ') || AUTH_CONSTANTS.MESSAGES.RESET_PASSWORD_EMAIL_FAILED - }; + if (!result.isSuccess) { + console.warn('发送重置密码邮件业务操作失败:', getErrorMessage(result)); } + return result; } catch (error: any) { return { - success: false, - message: error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.RESET_PASSWORD_EMAIL_FAILED + successMessage: null, + errorMessages: [error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.RESET_PASSWORD_EMAIL_FAILED], + data: null, + isSuccess: false }; } }, resetPassword: async (email: string, verificationCode: string, newPassword: string): Promise> => { try { - const response = await httpClient.post>('/auth/reset-password', { + const result = await httpClient.post('/auth/reset-password', { email: `${email}@qq.com`, verificationCode, newPassword }); - if (response.isSuccess) { - return { - success: true, - message: response.successMessage || AUTH_CONSTANTS.MESSAGES.PASSWORD_RESET_SUCCESS - }; - } else { - return { - success: false, - message: response?.errorMessages?.join(', ') || AUTH_CONSTANTS.MESSAGES.PASSWORD_RESET_FAILED - }; + if (!result.isSuccess) { + console.warn('重置密码业务操作失败:', getErrorMessage(result)); } + return result; } catch (error: any) { return { - success: false, - message: error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.PASSWORD_RESET_FAILED + successMessage: null, + errorMessages: [error.response?.data?.message || AUTH_CONSTANTS.MESSAGES.PASSWORD_RESET_FAILED], + data: null, + isSuccess: false }; } }, sendVerificationCode: async (request: { email: string; captchaId: string; captchaCode: string }): Promise> => { try { - const response = await httpClient.post>('/auth/verification-codes', request); - if (response.isSuccess) { - return { - success: true, - message: response.successMessage || '验证码发送成功' - }; - } else { - return { - success: false, - message: response?.errorMessages?.join(', ') || '验证码发送失败' - }; + const result = await httpClient.post('/auth/verification-codes', request); + if (!result.isSuccess) { + console.warn('发送验证码业务操作失败:', getErrorMessage(result)); } + return result; } catch (error: any) { return { - success: false, - message: error.response?.data?.message || '验证码发送失败' + successMessage: null, + errorMessages: [error.response?.data?.message || '验证码发送失败'], + data: null, + isSuccess: false }; } } diff --git a/src/X1.WebUI/src/services/authService.ts b/src/X1.WebUI/src/services/authService.ts index 345bc94..6669e76 100644 --- a/src/X1.WebUI/src/services/authService.ts +++ b/src/X1.WebUI/src/services/authService.ts @@ -2,6 +2,7 @@ import { LoginRequest, RegisterRequest, User, OperationResult, AuthAction } from import { storageService } from './storageService'; import { apiService } from '@/services/apiService'; import { AUTH_CONSTANTS } from '@/constants/auth'; +import { getErrorMessage } from '@/types/auth'; export interface AuthService { isTokenExpired: () => boolean; @@ -70,9 +71,11 @@ export const authService: AuthService = { } console.log('[authService] login result', result); - if (!result.success) { - throw new AuthError(result.message || AUTH_CONSTANTS.MESSAGES.LOGIN_FAILED); + + if (!result.isSuccess) { + throw new AuthError(getErrorMessage(result)); } + const { accessToken, refreshToken, user } = result.data!; const expiryTime = Date.now() + AUTH_CONSTANTS.AUTH_CONFIG.TOKEN_EXPIRY_TIME; storageService.setAccessToken(accessToken); @@ -100,9 +103,11 @@ export const authService: AuthService = { dispatch({ type: 'REGISTER_START' }); const result = await apiService.register(request); console.log('[authService] register result', result); - if (!result.success) { - throw new AuthError(result.message || AUTH_CONSTANTS.MESSAGES.REGISTER_FAILED); + + if (!result.isSuccess) { + throw new AuthError(getErrorMessage(result)); } + dispatch({ type: 'REGISTER_SUCCESS' }); } catch (error: any) { console.error('[authService] handleRegister error', error); @@ -119,9 +124,11 @@ export const authService: AuthService = { console.log('[authService] handleLogout start'); const result = await apiService.logout(); console.log('[authService] logout result', result); - if (!result.success) { - throw new AuthError(result.message || AUTH_CONSTANTS.MESSAGES.LOGOUT_FAILED); + + if (!result.isSuccess) { + throw new AuthError(getErrorMessage(result)); } + storageService.clearAuth(); console.log('[authService] tokens cleared'); dispatch({ type: 'LOGOUT' }); @@ -144,9 +151,11 @@ export const authService: AuthService = { } const result = await apiService.refreshToken(refreshToken); console.log('[authService] refreshToken result', result); - if (!result.success || !result.data) { - throw new AuthError(result.message || AUTH_CONSTANTS.MESSAGES.TOKEN_REFRESH_FAILED); + + if (!result.isSuccess || !result.data) { + throw new AuthError(getErrorMessage(result)); } + const { accessToken, refreshToken: newRefreshToken, user } = result.data; const expiryTime = Date.now() + AUTH_CONSTANTS.AUTH_CONFIG.TOKEN_EXPIRY_TIME; storageService.setAccessToken(accessToken); @@ -204,13 +213,13 @@ export const authService: AuthService = { console.log('[authService] 开始获取当前用户信息'); const result = await apiService.getCurrentUser(); console.log('[authService] getCurrentUser 结果', { - success: result.success, - message: result.message, + isSuccess: result.isSuccess, + errorMessage: getErrorMessage(result), hasData: !!result.data, data: result.data }); - if (!result.success || !result.data) { + if (!result.isSuccess || !result.data) { console.log('[authService] 获取用户信息失败,返回初始状态'); dispatch({ type: 'LOGOUT' }); return; diff --git a/src/X1.WebUI/src/types/auth.ts b/src/X1.WebUI/src/types/auth.ts index 3852751..284352f 100644 --- a/src/X1.WebUI/src/types/auth.ts +++ b/src/X1.WebUI/src/types/auth.ts @@ -58,8 +58,16 @@ export interface AuthContextType extends AuthState { } export interface OperationResult { - success: boolean; - data?: T; - message?: string; - errorMessages?: string[]; -} \ No newline at end of file + successMessage: string | null; + errorMessages: string[] | null; + data: T | null; + isSuccess: boolean; +} + +export const getSuccessMessage = (result: OperationResult): string => { + return result.successMessage || '操作成功'; +}; + +export const getErrorMessage = (result: OperationResult): string => { + return result.errorMessages?.join(', ') || '操作失败'; +}; \ No newline at end of file