using System.Text.Json; using FoodLabeling.Application.Services.DbModels; using FoodLabeling.Domain.Entities; using SqlSugar; namespace FoodLabeling.Application.Helpers; /// /// Company 自动生成元素:按门店解析 fl_partner 并格式化为多行展示文本。 /// public static class PartnerCompanyDisplayHelper { /// /// 模板元素是否属于 Company 自动生成(auto_Company 或 AUTO_DB + typeAdd 含 Company)。 /// public static bool IsCompanyAutoElement(string? valueSourceType, string? typeAdd, string? elementType = null) { var ta = typeAdd?.Trim(); if (string.IsNullOrWhiteSpace(ta)) { return false; } if (string.Equals(ta, "auto_Company", StringComparison.OrdinalIgnoreCase)) { return true; } return string.Equals(valueSourceType, "AUTO_DB", StringComparison.OrdinalIgnoreCase) && ta.StartsWith("auto_", StringComparison.OrdinalIgnoreCase) && ta.Contains("Company", StringComparison.OrdinalIgnoreCase); } /// /// 模板元素是否属于 Company 自动生成。 /// public static bool IsCompanyAutoElement(FlLabelTemplateElementDbEntity el) => IsCompanyAutoElement(el.ValueSourceType, el.TypeAdd, el.ElementType); /// /// Company 展示字段勾选结果。 /// public sealed class CompanyIncludeFields { public bool IncludeAddress { get; set; } public bool IncludeCity { get; set; } public bool IncludeState { get; set; } public bool IncludeZip { get; set; } public bool IncludeEmail { get; set; } } /// /// 从元素 config 解析需展示的 Company 字段(companyIncludeFields 或布尔开关)。 /// public static CompanyIncludeFields ParseIncludeFields(IReadOnlyDictionary config) { var result = new CompanyIncludeFields(); if (config.TryGetValue("companyIncludeFields", out var arrVal)) { foreach (var item in EnumerateStringArray(arrVal)) { if (string.Equals(item, "address", StringComparison.OrdinalIgnoreCase)) { result.IncludeAddress = true; } else if (string.Equals(item, "city", StringComparison.OrdinalIgnoreCase)) { result.IncludeCity = true; } else if (string.Equals(item, "state", StringComparison.OrdinalIgnoreCase)) { result.IncludeState = true; } else if (string.Equals(item, "zip", StringComparison.OrdinalIgnoreCase)) { result.IncludeZip = true; } else if (string.Equals(item, "email", StringComparison.OrdinalIgnoreCase)) { result.IncludeEmail = true; } } } if (TryGetBool(config, "includeAddress", out var includeAddress) && includeAddress) { result.IncludeAddress = true; } if (TryGetBool(config, "includeCity", out var includeCity) && includeCity) { result.IncludeCity = true; } if (TryGetBool(config, "includeState", out var includeState) && includeState) { result.IncludeState = true; } if (TryGetBool(config, "includeZip", out var includeZip) && includeZip) { result.IncludeZip = true; } if (TryGetBool(config, "includeEmail", out var includeEmail) && includeEmail) { result.IncludeEmail = true; } return result; } /// /// 将合作伙伴信息格式化为多行文本:公司名、地址、城市州邮编、邮箱。 /// public static string FormatDisplayText(FlPartnerDbEntity partner, CompanyIncludeFields includes) { var lines = new List(); var partnerName = partner.PartnerName?.Trim(); if (!string.IsNullOrWhiteSpace(partnerName)) { lines.Add(partnerName); } if (includes.IncludeAddress) { var street = partner.Street?.Trim(); if (!string.IsNullOrWhiteSpace(street)) { lines.Add(street); } } if (includes.IncludeCity || includes.IncludeState || includes.IncludeZip) { var cityStateZipParts = new List(); if (includes.IncludeCity) { var city = partner.City?.Trim(); if (!string.IsNullOrWhiteSpace(city)) { cityStateZipParts.Add(city); } } if (includes.IncludeState) { var state = partner.StateCode?.Trim(); if (!string.IsNullOrWhiteSpace(state)) { cityStateZipParts.Add(state); } } if (includes.IncludeZip) { var zip = partner.ZipCode?.Trim(); if (!string.IsNullOrWhiteSpace(zip)) { cityStateZipParts.Add(zip); } } if (cityStateZipParts.Count > 0) { lines.Add(string.Join(", ", cityStateZipParts)); } } if (includes.IncludeEmail) { var email = partner.ContactEmail?.Trim(); if (!string.IsNullOrWhiteSpace(email)) { lines.Add(email); } } return string.Join("\n", lines); } /// /// 门店 Guid → location.Partner → 匹配 fl_partner(按 PartnerName 或 Id)。 /// public static async Task ResolvePartnerByLocationIdAsync( ISqlSugarClient db, string? locationId) { var id = locationId?.Trim(); if (string.IsNullOrWhiteSpace(id) || !Guid.TryParse(id, out var locationGuid)) { return null; } var loc = await db.Queryable() .Where(x => !x.IsDeleted && x.Id == locationGuid) .FirstAsync(); if (loc is null) { return null; } var partnerKey = loc.Partner?.Trim(); if (string.IsNullOrWhiteSpace(partnerKey)) { return null; } var candidates = await db.Queryable() .Where(x => !x.IsDeleted) .Where(x => x.Id == partnerKey || x.PartnerName == partnerKey) .ToListAsync(); return candidates.FirstOrDefault(p => string.Equals(p.Id, partnerKey, StringComparison.OrdinalIgnoreCase) || string.Equals(p.PartnerName?.Trim(), partnerKey, StringComparison.OrdinalIgnoreCase)); } private static IEnumerable EnumerateStringArray(object? value) { if (value is null) { yield break; } if (value is string s) { if (!string.IsNullOrWhiteSpace(s)) { yield return s.Trim(); } yield break; } if (value is JsonElement je) { if (je.ValueKind == JsonValueKind.Array) { foreach (var item in je.EnumerateArray()) { var text = item.ValueKind == JsonValueKind.String ? item.GetString() : item.ToString(); if (!string.IsNullOrWhiteSpace(text)) { yield return text.Trim(); } } } else if (je.ValueKind == JsonValueKind.String) { var text = je.GetString(); if (!string.IsNullOrWhiteSpace(text)) { yield return text.Trim(); } } yield break; } if (value is IEnumerable enumerable) { foreach (var item in enumerable) { var text = item?.ToString(); if (!string.IsNullOrWhiteSpace(text)) { yield return text.Trim(); } } } } private static bool TryGetBool(IReadOnlyDictionary config, string key, out bool result) { result = false; if (!config.TryGetValue(key, out var value) || value is null) { return false; } switch (value) { case bool b: result = b; return true; case JsonElement je when je.ValueKind is JsonValueKind.True or JsonValueKind.False: result = je.GetBoolean(); return true; case JsonElement je when je.ValueKind == JsonValueKind.String && bool.TryParse(je.GetString(), out var parsed): result = parsed; return true; case string s when bool.TryParse(s, out var parsedStr): result = parsedStr; return true; default: return false; } } }