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();
}
}