TeamMemberScopeDisplayHelper.cs 5.58 KB
using FoodLabeling.Application.Contracts.Dtos.TeamMember;
using FoodLabeling.Domain.Shared;
using SqlSugar;

namespace FoodLabeling.Application.Helpers;

/// <summary>
/// Team Member 列表展示:适用全部 Region/Location 时返回 All Region / All Location。
/// </summary>
public static class TeamMemberScopeDisplayHelper
{
    public static List<TeamMemberAssignedLocationDto> AllLocationDisplay { get; } =
        new()
        {
            new TeamMemberAssignedLocationDto
            {
                LocationName = FoodLabelingDisplayConsts.AllLocation
            }
        };

    /// <summary>
    /// 列表/导出用:当成员绑定范围覆盖其 Company/Region 下全部门店时,折叠为 All Location。
    /// </summary>
    public static async Task<List<TeamMemberAssignedLocationDto>> FormatAssignedLocationsForListAsync(
        ISqlSugarClient db,
        Guid? roleId,
        IReadOnlyList<string> partnerIds,
        IReadOnlyList<string> regionIds,
        IReadOnlyList<TeamMemberAssignedLocationDto> assigned)
    {
        var assignedIds = assigned
            .Select(x => x.Id)
            .Where(x => !string.IsNullOrWhiteSpace(x))
            .Select(x => x.Trim())
            .Distinct(StringComparer.Ordinal)
            .ToList();

        if (assignedIds.Count == 0)
        {
            return assigned.ToList();
        }

        if (partnerIds.Count > 0)
        {
            var allPartnerLocationIds = await LocationScopeBindingHelper.ResolveLocationIdsFromPartnerIdsAsync(
                db, partnerIds);
            if (allPartnerLocationIds.Count > 0 &&
                AllScopeBindingHelper.IsFullIdSelection(assignedIds, allPartnerLocationIds))
            {
                return AllLocationDisplay;
            }
        }

        return assigned.ToList();
    }

    /// <summary>
    /// 列表/导出用:当 Region 覆盖 Company 下全部 Region 时,返回 All Region 展示文案。
    /// </summary>
    public static async Task<string> FormatRegionTextForListAsync(
        ISqlSugarClient db,
        IReadOnlyList<string> partnerIds,
        IReadOnlyList<string> regionIds,
        IReadOnlyDictionary<string, string> regionNameMap)
    {
        if (regionIds.Count == 0)
        {
            return FoodLabelingDisplayConsts.NotAvailable;
        }

        if (partnerIds.Count > 0)
        {
            var allRegions = await LocationScopeBindingHelper.ResolveGroupIdsFromPartnerIdsAsync(db, partnerIds);
            if (allRegions.Count > 0 && AllScopeBindingHelper.IsFullIdSelection(regionIds, allRegions))
            {
                return FoodLabelingDisplayConsts.AllRegion;
            }
        }

        return string.Join("; ",
            regionIds.Select(id =>
                regionNameMap.TryGetValue(id, out var name) && !string.IsNullOrWhiteSpace(name)
                    ? name
                    : id));
    }

    /// <summary>
    /// 编辑回显:库中存展开后的 Guid;若绑定已覆盖 Company 下全部 Region/门店,则将对应 Id 列表折叠为 <c>["ALL"]</c>,供前端勾选 ALL。
    /// </summary>
    public static async Task<(List<string> RegionIds, List<string> LocationIds, List<TeamMemberAssignedLocationDto> Assigned)>
        CollapseScopeIdsToAllSentinelForEditAsync(
            ISqlSugarClient db,
            IReadOnlyList<string> partnerIds,
            IReadOnlyList<string> regionIds,
            IReadOnlyList<string> locationIds,
            IReadOnlyList<TeamMemberAssignedLocationDto> assigned)
    {
        var partners = LocationScopeBindingHelper.NormalizeIds(partnerIds);
        var regions = LocationScopeBindingHelper.NormalizeIds(regionIds);
        var locations = LocationScopeBindingHelper.NormalizeIds(locationIds);
        var assignedList = assigned?.ToList() ?? new List<TeamMemberAssignedLocationDto>();

        if (partners.Count == 0)
        {
            return (regions, locations, assignedList);
        }

        var allRegionIds = await LocationScopeBindingHelper.ResolveGroupIdsFromPartnerIdsAsync(db, partners);
        if (allRegionIds.Count > 0 && AllScopeBindingHelper.IsFullIdSelection(regions, allRegionIds))
        {
            regions = new List<string> { AllScopeBindingHelper.ScopeAll };
        }

        var allLocationIds = await LocationScopeBindingHelper.ResolveLocationIdsFromPartnerIdsAsync(db, partners);
        if (allLocationIds.Count > 0 && AllScopeBindingHelper.IsFullIdSelection(locations, allLocationIds))
        {
            locations = new List<string> { AllScopeBindingHelper.ScopeAll };
            assignedList = AllLocationDisplay;
        }

        return (regions, locations, assignedList);
    }

    public static string FormatLocationTextForList(IReadOnlyList<TeamMemberAssignedLocationDto> assigned)
    {
        if (assigned.Count == 0)
        {
            return FoodLabelingDisplayConsts.NotAvailable;
        }

        if (assigned.Count == 1 &&
            string.Equals(assigned[0].LocationName, FoodLabelingDisplayConsts.AllLocation, StringComparison.Ordinal) &&
            string.IsNullOrWhiteSpace(assigned[0].LocationCode))
        {
            return FoodLabelingDisplayConsts.AllLocation;
        }

        return string.Join("; ",
            assigned.Select(a =>
            {
                var code = a.LocationCode?.Trim() ?? string.Empty;
                var name = a.LocationName?.Trim() ?? string.Empty;
                if (!string.IsNullOrEmpty(code) && !string.IsNullOrEmpty(name))
                {
                    return $"{code} - {name}";
                }

                return !string.IsNullOrEmpty(name) ? name : code;
            }));
    }
}