using System.Text.Json; using TakeoutSaaS.Application.Identity.Contracts; using TakeoutSaaS.Domain.Identity.Entities; using TakeoutSaaS.Domain.Identity.Enums; namespace TakeoutSaaS.Application.Identity.Handlers; /// /// 菜单映射辅助。 /// internal static class MenuMapper { /// /// 将菜单实体映射为 DTO。 /// /// 菜单实体。 /// 菜单定义 DTO。 public static MenuDefinitionDto ToDto(MenuDefinition entity) { // 1. 解析权限字段 var requiredPermissions = SplitCodes(entity.RequiredPermissions); var metaPermissions = SplitCodes(entity.MetaPermissions); var metaRoles = SplitCodes(entity.MetaRoles); // 2. 解析按钮权限 var authList = string.IsNullOrWhiteSpace(entity.AuthListJson) ? [] : JsonSerializer.Deserialize>(entity.AuthListJson) ?? []; // 3. 输出 DTO return new MenuDefinitionDto { Id = entity.Id, ParentId = entity.ParentId, Name = entity.Name, Path = entity.Path, Component = entity.Component, Title = entity.Title, Icon = entity.Icon, IsIframe = entity.IsIframe, Link = entity.Link, KeepAlive = entity.KeepAlive, SortOrder = entity.SortOrder, RequiredPermissions = requiredPermissions, MetaPermissions = metaPermissions, MetaRoles = metaRoles, AuthList = authList }; } /// /// 将 DTO 字段填充到实体。 /// /// 菜单实体。 /// 菜单 DTO。 public static void FillEntity(MenuDefinition entity, MenuDefinitionDto dto) { // 1. 赋值基础字段 entity.ParentId = dto.ParentId; entity.Name = dto.Name; entity.Path = dto.Path; entity.Component = dto.Component; entity.Title = dto.Title; entity.Icon = dto.Icon; entity.IsIframe = dto.IsIframe; entity.Link = dto.Link; entity.KeepAlive = dto.KeepAlive; entity.SortOrder = dto.SortOrder; // 2. 权限与按钮 entity.RequiredPermissions = JoinCodes(dto.RequiredPermissions); entity.MetaPermissions = JoinCodes(dto.MetaPermissions); entity.MetaRoles = JoinCodes(dto.MetaRoles); entity.AuthListJson = dto.AuthList.Count == 0 ? null : JsonSerializer.Serialize(dto.AuthList); } /// /// 构建或更新菜单实体并返回 DTO。 /// /// 已存在的菜单实体。 /// 门户类型。 /// 菜单 DTO 载荷。 /// 菜单定义 DTO。 public static MenuDefinitionDto FromCommand(MenuDefinition? existing, PortalType portal, MenuDefinitionDto payload) { // 1. 构造实体 var entity = existing ?? new MenuDefinition { Portal = portal, CreatedAt = DateTime.UtcNow }; // 2. 填充字段 FillEntity(entity, payload); // 3. 返回 DTO 映射 return ToDto(entity); } /// /// 将权限/角色集合合并为存储字符串。 /// /// 编码集合。 /// 逗号分隔字符串。 public static string JoinCodes(IEnumerable codes) { return string.Join(',', codes.Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()).Distinct(StringComparer.OrdinalIgnoreCase)); } /// /// 将逗号分隔编码拆分为集合。 /// /// 编码字符串。 /// 编码数组。 public static string[] SplitCodes(string? codes) { if (string.IsNullOrWhiteSpace(codes)) { return Array.Empty(); } return codes .Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) .Distinct(StringComparer.OrdinalIgnoreCase) .ToArray(); } }