using FoodLabeling.Application.Contracts.Dtos.TeamMember; using FoodLabeling.Domain.Shared; using SqlSugar; namespace FoodLabeling.Application.Helpers; /// /// Team Member 列表展示:适用全部 Region/Location 时返回 All Region / All Location。 /// public static class TeamMemberScopeDisplayHelper { public static List AllLocationDisplay { get; } = new() { new TeamMemberAssignedLocationDto { LocationName = FoodLabelingDisplayConsts.AllLocation } }; /// /// 列表/导出用:当成员绑定范围覆盖其 Company/Region 下全部门店时,折叠为 All Location。 /// public static async Task> FormatAssignedLocationsForListAsync( ISqlSugarClient db, Guid? roleId, IReadOnlyList partnerIds, IReadOnlyList regionIds, IReadOnlyList assigned, string? appliedLocationType = null) { var assignedIds = assigned .Select(x => x.Id) .Where(x => !string.IsNullOrWhiteSpace(x)) .Select(x => x.Trim()) .Distinct(StringComparer.Ordinal) .ToList(); if (AllScopeBindingHelper.IsDeclaredAll(appliedLocationType)) { if (partnerIds.Count > 0) { var concreteRegions = LocationScopeBindingHelper.FilterConcreteScopeIds(regionIds); var universe = concreteRegions.Count > 0 ? await AllScopeBindingHelper.ResolveAllLocationIdsAsync(db, partnerIds, concreteRegions) : await LocationScopeBindingHelper.ResolveLocationIdsFromPartnerIdsAsync(db, partnerIds); if (universe.Count > 0 && !AllScopeBindingHelper.IsFullIdSelection(assignedIds, universe)) { return assigned.ToList(); } } return AllLocationDisplay; } if (assignedIds.Count == 0) { return assigned.ToList(); } if (partnerIds.Count > 0) { // 有具体 Region 时按 Region 范围内全选判断;否则按 Company 全部门店 var concreteRegions = LocationScopeBindingHelper.FilterConcreteScopeIds(regionIds); var universe = concreteRegions.Count > 0 ? await AllScopeBindingHelper.ResolveAllLocationIdsAsync(db, partnerIds, concreteRegions) : await LocationScopeBindingHelper.ResolveLocationIdsFromPartnerIdsAsync(db, partnerIds); if (universe.Count > 0 && AllScopeBindingHelper.IsFullIdSelection(assignedIds, universe)) { return AllLocationDisplay; } } return assigned.ToList(); } /// /// 列表/导出用:当 Region 覆盖 Company 下全部 Region 时,返回 All Region 展示文案。 /// public static async Task FormatRegionTextForListAsync( ISqlSugarClient db, IReadOnlyList partnerIds, IReadOnlyList regionIds, IReadOnlyDictionary regionNameMap, string? appliedRegionType = null) { if (AllScopeBindingHelper.IsDeclaredAll(appliedRegionType) || (regionIds.Count == 1 && AllScopeBindingHelper.IsDeclaredAll(regionIds[0]))) { return FoodLabelingDisplayConsts.AllRegion; } 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)); } /// /// 编辑回显:库中存展开后的 Guid;结合 AppliedRegionType/AppliedLocationType 折叠为 ["ALL"]。 /// public static async Task<(List RegionIds, List LocationIds, List Assigned)> CollapseScopeIdsToAllSentinelForEditAsync( ISqlSugarClient db, IReadOnlyList partnerIds, IReadOnlyList regionIds, IReadOnlyList locationIds, IReadOnlyList assigned, string? appliedRegionType = null, string? appliedLocationType = null) { var partners = LocationScopeBindingHelper.NormalizeIds(partnerIds); var regions = LocationScopeBindingHelper.NormalizeIds(regionIds); var locations = LocationScopeBindingHelper.NormalizeIds(locationIds); var assignedList = assigned?.ToList() ?? new List(); if (AllScopeBindingHelper.IsDeclaredAll(appliedRegionType)) { regions = new List { AllScopeBindingHelper.ScopeAll }; } if (AllScopeBindingHelper.IsDeclaredAll(appliedLocationType)) { // 误标 ALL 但库中仅为部分门店时,回显具体 Id(与新增传参对称) if (locations.Count > 0 && partners.Count > 0) { var scopedRegions = LocationScopeBindingHelper.FilterConcreteScopeIds(regions); var universe = scopedRegions.Count > 0 ? await AllScopeBindingHelper.ResolveAllLocationIdsAsync(db, partners, scopedRegions) : await LocationScopeBindingHelper.ResolveLocationIdsFromPartnerIdsAsync(db, partners); if (!AllScopeBindingHelper.IsFullIdSelection(locations, universe)) { return (regions, locations, assignedList); } } locations = new List { AllScopeBindingHelper.ScopeAll }; assignedList = AllLocationDisplay; return (regions, locations, assignedList); } // 落库为 SPECIFIED(显式选店):禁止再按「区内恰好全选」折叠成 ALL if (AllScopeBindingHelper.IsDeclaredSpecified(appliedLocationType)) { if (partners.Count == 0) { return (regions, locations, assignedList); } if (!AllScopeBindingHelper.IsDeclaredAll(appliedRegionType)) { var allRegionIds = await LocationScopeBindingHelper.ResolveGroupIdsFromPartnerIdsAsync(db, partners); if (allRegionIds.Count > 0 && AllScopeBindingHelper.IsFullIdSelection(regions, allRegionIds)) { regions = new List { AllScopeBindingHelper.ScopeAll }; } } return (regions, locations, assignedList); } if (partners.Count == 0) { return (regions, locations, assignedList); } if (!AllScopeBindingHelper.IsDeclaredAll(appliedRegionType)) { var allRegionIds = await LocationScopeBindingHelper.ResolveGroupIdsFromPartnerIdsAsync(db, partners); if (allRegionIds.Count > 0 && AllScopeBindingHelper.IsFullIdSelection(regions, allRegionIds)) { regions = new List { AllScopeBindingHelper.ScopeAll }; } } // Region=ALL + 具体门店:禁止再按「派生单 Region 区内全选」把 Location 折成 ALL if (AllScopeBindingHelper.IsDeclaredAll(appliedRegionType) || (regions.Count == 1 && AllScopeBindingHelper.IsDeclaredAll(regions[0]))) { var partnerUniverse = await LocationScopeBindingHelper.ResolveLocationIdsFromPartnerIdsAsync( db, partners); if (partnerUniverse.Count > 1 && locations.Count > 1 && AllScopeBindingHelper.IsFullIdSelection(locations, partnerUniverse)) { locations = new List { AllScopeBindingHelper.ScopeAll }; assignedList = AllLocationDisplay; } return (regions, locations, assignedList); } // 具体 Region:按区内门店全集判断是否折叠 locationIds var concreteRegions = LocationScopeBindingHelper.FilterConcreteScopeIds(regions); var allLocationIds = concreteRegions.Count > 0 ? await AllScopeBindingHelper.ResolveAllLocationIdsAsync(db, partners, concreteRegions) : await LocationScopeBindingHelper.ResolveLocationIdsFromPartnerIdsAsync(db, partners); if (allLocationIds.Count > 0 && AllScopeBindingHelper.IsFullIdSelection(locations, allLocationIds)) { var hasConcreteRegions = concreteRegions.Count > 0; if (hasConcreteRegions || locations.Count > 1 || allLocationIds.Count > 1) { locations = new List { AllScopeBindingHelper.ScopeAll }; assignedList = AllLocationDisplay; } } return (regions, locations, assignedList); } public static string FormatLocationTextForList(IReadOnlyList 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; })); } }