fix: 无邮箱注册改用占位邮箱,避免空串撞 uk_user_email

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zzh 2026-07-29 18:28:33 +08:00
parent 0d578059ec
commit f2f4cbf35b
4 changed files with 53 additions and 1 deletions

View File

@ -0,0 +1,12 @@
-- 修复:微信注册无邮箱时曾写入 user.Email='',撞 uk_user_email 导致后续注册提示「邮箱已被占用」
-- 将空邮箱改为「客户编号@noemail.local」占位(与 CustomerContactHelper.ResolveRbacEmailOrPlaceholder 一致)
UPDATE `user` u
INNER JOIN `t_customer` c ON c.`UserId` = u.`userid`
SET u.`Email` = CONCAT(LOWER(TRIM(c.`CustomerCode`)), '@noemail.local')
WHERE u.`Email` IS NULL OR TRIM(u.`Email`) = '';
-- 无客户关联的残留空邮箱
UPDATE `user`
SET `Email` = CONCAT('u', `userid`, '@noemail.local')
WHERE `Email` IS NULL OR TRIM(`Email`) = '';

View File

@ -193,6 +193,17 @@ public class CustomerService : ApplicationService
customer.Phone = phone; customer.Phone = phone;
customer.Email = email; customer.Email = email;
await CustomerRepository.UpdateAsync(customer); await CustomerRepository.UpdateAsync(customer);
// 同步 RBAC 登录邮箱,覆盖注册时的 @noemail.local 占位
try
{
await RbacDbContext.Database.ExecuteSqlInterpolatedAsync(
$"UPDATE `user` SET `Email` = {email} WHERE `userid` = {customer.UserId} AND `IsDeleted` = 0");
}
catch
{
// 客户资料已更新;RBAC 同步失败不阻断补全
}
} }
/// <summary> /// <summary>

View File

@ -37,4 +37,32 @@ public static class CustomerContactHelper
if (trimmed.Equals("undefined", StringComparison.OrdinalIgnoreCase)) return null; if (trimmed.Equals("undefined", StringComparison.OrdinalIgnoreCase)) return null;
return trimmed; return trimmed;
} }
/// <summary>
/// RBAC <c>user.Email</c> 有唯一索引,空串会撞库。
/// 无真实邮箱时用客户编号生成占位,禁止写入 <c>''</c>。
/// </summary>
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);
}
} }

View File

@ -130,7 +130,8 @@ public class WeChatCustomerService(
Name = customerName, Name = customerName,
Account = customerCode, Account = customerCode,
Password = password, Password = password,
Email = email ?? string.Empty, // 禁止 Email='':uk_user_email 会把第二条空邮箱当成占用
Email = CustomerContactHelper.ResolveRbacEmailOrPlaceholder(email, customerCode),
RoleIds = [customerRoleId] RoleIds = [customerRoleId]
}); });