namespace ServiceLib.Manager; public class GroupProfileManager { public static async Task HasCycle(ProfileItem item) { return await HasCycle(item.IndexId, item.GetProtocolExtra()); } public static async Task HasCycle(string? indexId, ProtocolExtraItem? extraInfo) { return await HasCycle(indexId, extraInfo, [], []); } private static async Task HasCycle(string? indexId, ProtocolExtraItem? extraInfo, HashSet visited, HashSet stack) { if (indexId.IsNullOrEmpty() || extraInfo == null) { return false; } if (stack.Contains(indexId)) { return true; } if (visited.Contains(indexId)) { return false; } visited.Add(indexId); stack.Add(indexId); try { if (extraInfo.GroupType.IsNullOrEmpty()) { return false; } if (extraInfo.ChildItems.IsNullOrEmpty()) { return false; } var childIds = Utils.String2List(extraInfo.ChildItems) ?.Where(p => !string.IsNullOrEmpty(p)) .ToList(); if (childIds == null) { return false; } var childItems = await AppManager.Instance.GetProfileItemsByIndexIds(childIds); foreach (var childItem in childItems) { if (await HasCycle(childItem.IndexId, childItem.GetProtocolExtra(), visited, stack)) { return true; } } return false; } finally { stack.Remove(indexId); } } public static async Task<(List Items, ProtocolExtraItem? Extra)> GetChildProfileItems(ProfileItem profileItem) { var protocolExtra = profileItem.GetProtocolExtra(); return (await GetChildProfileItemsByProtocolExtra(protocolExtra), protocolExtra); } public static async Task> GetChildProfileItemsByProtocolExtra(ProtocolExtraItem? protocolExtra) { if (protocolExtra == null) { return []; } var items = new List(); items.AddRange(await GetSubChildProfileItems(protocolExtra)); items.AddRange(await GetSelectedChildProfileItems(protocolExtra)); return items; } private static async Task> GetSelectedChildProfileItems(ProtocolExtraItem? extra) { if (extra == null || extra.ChildItems.IsNullOrEmpty()) { return []; } var childProfileIds = Utils.String2List(extra.ChildItems) ?.Where(p => !string.IsNullOrEmpty(p)) .ToList() ?? []; if (childProfileIds.Count == 0) { return []; } var ordered = await AppManager.Instance.GetProfileItemsOrderedByIndexIds(childProfileIds); return ordered; } private static async Task> GetSubChildProfileItems(ProtocolExtraItem? extra) { if (extra == null || extra.SubChildItems.IsNullOrEmpty()) { return []; } var childProfiles = await AppManager.Instance.ProfileItems(extra.SubChildItems ?? string.Empty); return childProfiles?.Where(p => p != null && p.IsValid() && (!p.ConfigType.IsComplexType() || p.ConfigType == EConfigType.Outbound) && (extra.Filter.IsNullOrEmpty() || Regex.IsMatch(p.Remarks, extra.Filter)) ) .ToList() ?? []; } public static async Task> GetAllChildProfileItems(ProfileItem profileItem) { var itemMap = new Dictionary(); var visited = new HashSet(); await CollectChildItems(profileItem, itemMap, visited); return itemMap; } private static async Task CollectChildItems(ProfileItem profileItem, Dictionary itemMap, HashSet visited) { var (childItems, _) = await GetChildProfileItems(profileItem); foreach (var child in childItems.Where(child => visited.Add(child.IndexId))) { itemMap[child.IndexId] = child; if (child.ConfigType.IsGroupType()) { await CollectChildItems(child, itemMap, visited); } } } }