using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Tiku.Application.Security; using Tiku.Domain.Tenancy; using Tiku.Infrastructure.Persistence; namespace Tiku.Api.Controllers; [ApiController] [Authorize(Policy = TikuPolicies.AuthenticatedUser)] [Route("api/me")] public sealed class MeController( ICurrentUser currentUser, TikuDbContext dbContext) : ControllerBase { [HttpGet] [EndpointSummary("获取当前登录用户")] [EndpointDescription("根据 Bearer Token 返回当前用户基础信息和活跃租户成员摘要。")] public async Task> Get(CancellationToken cancellationToken) { if (currentUser.UserId is null) { return Unauthorized(); } var user = await dbContext.Users.FindAsync([currentUser.UserId.Value], cancellationToken); if (user is null) { return Unauthorized(); } var memberships = await dbContext.TenantMemberships .Where(membership => membership.UserId == user.Id && membership.Status == MembershipStatus.Active) .Join( dbContext.Tenants, membership => membership.TenantId, tenant => tenant.Id, (membership, tenant) => new TenantMembershipResponse( tenant.Id, tenant.Name, tenant.Slug, membership.Role, membership.Status)) .ToArrayAsync(cancellationToken); return Ok(new MeResponse( user.Id, user.Phone, user.Email, user.Name, memberships)); } } /// /// 当前用户基础信息和租户成员摘要。 /// /// 用户 ID。 /// 手机号。 /// 邮箱。 /// 用户显示名称。 /// 当前用户拥有的活跃租户成员列表。 public sealed record MeResponse( Guid UserId, string? Phone, string? Email, string? Name, IReadOnlyCollection Tenants); /// /// 用户在某个租户内的成员摘要。 /// /// 租户 ID。 /// 租户名称。 /// 租户编码。 /// 当前用户在该租户内的角色。 /// 租户成员状态。 public sealed record TenantMembershipResponse( Guid TenantId, string TenantName, string TenantSlug, TenantRole Role, MembershipStatus Status);