diff --git a/src/Api/TakeoutSaaS.AdminApi/Controllers/UsersController.cs b/src/Api/TakeoutSaaS.AdminApi/Controllers/UsersController.cs
new file mode 100644
index 0000000..412e8e9
--- /dev/null
+++ b/src/Api/TakeoutSaaS.AdminApi/Controllers/UsersController.cs
@@ -0,0 +1,212 @@
+using MediatR;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using System.ComponentModel.DataAnnotations;
+using TakeoutSaaS.Application.Identity.Commands;
+using TakeoutSaaS.Application.Identity.Contracts;
+using TakeoutSaaS.Application.Identity.Queries;
+using TakeoutSaaS.Module.Authorization.Attributes;
+using TakeoutSaaS.Shared.Abstractions.Constants;
+using TakeoutSaaS.Shared.Abstractions.Results;
+using TakeoutSaaS.Shared.Web.Api;
+
+namespace TakeoutSaaS.AdminApi.Controllers;
+
+///
+/// 用户管理。
+///
+[ApiVersion("1.0")]
+[Authorize]
+[Route("api/admin/v{version:apiVersion}/users")]
+public sealed class UsersController(IMediator mediator) : BaseApiController
+{
+ ///
+ /// 用户分页列表。
+ ///
+ [HttpGet]
+ [PermissionAuthorize("identity:user:read")]
+ [ProducesResponseType(typeof(ApiResponse>), StatusCodes.Status200OK)]
+ public async Task>> List(
+ [FromQuery] SearchIdentityUsersQuery query,
+ CancellationToken cancellationToken)
+ {
+ // 1. 查询用户分页
+ var result = await mediator.Send(query, cancellationToken);
+
+ // 2. 返回分页数据
+ return ApiResponse>.Ok(result);
+ }
+
+ ///
+ /// 用户详情。
+ ///
+ [HttpGet("{userId:long}")]
+ [PermissionAuthorize("identity:user:read")]
+ [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status404NotFound)]
+ public async Task> Detail(long userId, [FromQuery] bool includeDeleted, CancellationToken cancellationToken)
+ {
+ // 1. 查询用户详情
+ var result = await mediator.Send(new GetIdentityUserDetailQuery
+ {
+ UserId = userId,
+ IncludeDeleted = includeDeleted
+ }, cancellationToken);
+
+ // 2. 返回详情或 404
+ return result == null
+ ? ApiResponse.Error(ErrorCodes.NotFound, "用户不存在")
+ : ApiResponse.Ok(result);
+ }
+
+ ///
+ /// 用户权限明细。
+ ///
+ [HttpGet("{userId:long}/permissions")]
+ [PermissionAuthorize("identity:user:read")]
+ [ProducesResponseType(typeof(ApiResponse>), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResponse>), StatusCodes.Status404NotFound)]
+ public async Task>> Permissions(long userId, CancellationToken cancellationToken)
+ {
+ // 1. 查询用户详情并提取权限
+ var detail = await mediator.Send(new GetIdentityUserDetailQuery { UserId = userId }, cancellationToken);
+ if (detail == null)
+ {
+ return ApiResponse>.Error(ErrorCodes.NotFound, "用户不存在");
+ }
+
+ // 2. 返回权限编码列表
+ return ApiResponse>.Ok(detail.Permissions);
+ }
+
+ ///
+ /// 创建用户。
+ ///
+ [HttpPost]
+ [PermissionAuthorize("identity:user:create")]
+ [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
+ public async Task> Create([FromBody, Required] CreateIdentityUserCommand command, CancellationToken cancellationToken)
+ {
+ // 1. 创建用户
+ var result = await mediator.Send(command, cancellationToken);
+
+ // 2. 返回创建结果
+ return ApiResponse.Ok(result);
+ }
+
+ ///
+ /// 更新用户。
+ ///
+ [HttpPut("{userId:long}")]
+ [PermissionAuthorize("identity:user:update")]
+ [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status404NotFound)]
+ public async Task> Update(long userId, [FromBody, Required] UpdateIdentityUserCommand command, CancellationToken cancellationToken)
+ {
+ // 1. 绑定用户 ID
+ if (command.UserId == 0)
+ {
+ command = command with { UserId = userId };
+ }
+
+ // 2. (空行后) 执行更新
+ var result = await mediator.Send(command, cancellationToken);
+
+ // 3. (空行后) 返回结果或 404
+ return result == null
+ ? ApiResponse.Error(ErrorCodes.NotFound, "用户不存在")
+ : ApiResponse.Ok(result);
+ }
+
+ ///
+ /// 删除用户。
+ ///
+ [HttpDelete("{userId:long}")]
+ [PermissionAuthorize("identity:user:delete")]
+ [ProducesResponseType(typeof(ApiResponse