using Fake.Application; using Oms.Domain.CustomersAggregate.Entities; namespace Oms.Application.Shared; /// /// 客户联系方式完整度(下单/揽收前必填手机+邮箱)。 /// public static class CustomerContactHelper { public const string ContactRequiredMessage = "请先完善手机号和邮箱后再下单"; public static bool HasPhone(Customer? customer) => !string.IsNullOrWhiteSpace(customer?.Phone); public static bool HasEmail(Customer? customer) => !string.IsNullOrWhiteSpace(customer?.Email); public static bool NeedsContact(Customer? customer) => customer == null || !HasPhone(customer) || !HasEmail(customer); public static void EnsureContactComplete(Customer? customer) { if (NeedsContact(customer)) { throw new BusinessException(ContactRequiredMessage); } } public static string? NormalizeOptionalContact(string? value) { var trimmed = value?.Trim(); if (string.IsNullOrWhiteSpace(trimmed)) return null; // 前端/第三方有时会把缺失值以字符串形式传过来(如 "null" / "undefined") // 这类值应按“未填写”处理,否则会误触发“已被占用”校验。 if (trimmed.Equals("null", StringComparison.OrdinalIgnoreCase)) return null; if (trimmed.Equals("undefined", StringComparison.OrdinalIgnoreCase)) return null; return trimmed; } /// /// RBAC user.Email 有唯一索引,空串会撞库。 /// 无真实邮箱时用客户编号生成占位,禁止写入 ''。 /// public static string ResolveRbacEmailOrPlaceholder(string? email, string customerCode) { var normalized = NormalizeOptionalContact(email); if (normalized != null) { return normalized; } var code = (customerCode ?? string.Empty).Trim().ToLowerInvariant(); if (string.IsNullOrEmpty(code)) { code = Guid.NewGuid().ToString("N")[..12]; } return $"{code}@noemail.local"; } public static bool IsPlaceholderRbacEmail(string? email) { var value = email?.Trim(); return !string.IsNullOrEmpty(value) && value.EndsWith("@noemail.local", StringComparison.OrdinalIgnoreCase); } }