手机号显示补全国家码格式
This commit is contained in:
1 parent
cd5a07543e
commit
a71417cb32
5 files changed
+109
-11
No files matched your search
@@ -1,6 +1,7 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using TelegramPanel.Core.Interfaces;
|
||||
using TelegramPanel.Core.Utils;
|
||||
using TelegramPanel.Data.Entities;
|
||||
using TelegramPanel.Data.Repositories;
|
||||
|
||||
@@ -36,36 +37,52 @@ public class AccountManagementService
|
||||
|
||||
public async Task<Account?> GetAccountAsync(int id)
|
||||
{
|
||||
return await _accountRepository.GetByIdAsync(id);
|
||||
var account = await _accountRepository.GetByIdAsync(id);
|
||||
FormatPhoneForDisplay(account);
|
||||
return account;
|
||||
}
|
||||
|
||||
public async Task<Account?> GetAccountByPhoneAsync(string phone)
|
||||
{
|
||||
return await _accountRepository.GetByPhoneAsync(phone);
|
||||
var digits = PhoneNumberFormatter.NormalizeToDigits(phone);
|
||||
var account = await _accountRepository.GetByPhoneAsync(digits);
|
||||
FormatPhoneForDisplay(account);
|
||||
return account;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Account>> GetAllAccountsAsync()
|
||||
{
|
||||
return await _accountRepository.GetAllAsync();
|
||||
var list = (await _accountRepository.GetAllAsync()).ToList();
|
||||
foreach (var a in list)
|
||||
FormatPhoneForDisplay(a);
|
||||
return list;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Account>> GetActiveAccountsAsync()
|
||||
{
|
||||
return await _accountRepository.GetActiveAccountsAsync();
|
||||
var list = (await _accountRepository.GetActiveAccountsAsync()).ToList();
|
||||
foreach (var a in list)
|
||||
FormatPhoneForDisplay(a);
|
||||
return list;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Account>> GetAccountsByCategoryAsync(int categoryId)
|
||||
{
|
||||
return await _accountRepository.GetByCategoryAsync(categoryId);
|
||||
var list = (await _accountRepository.GetByCategoryAsync(categoryId)).ToList();
|
||||
foreach (var a in list)
|
||||
FormatPhoneForDisplay(a);
|
||||
return list;
|
||||
}
|
||||
|
||||
public async Task<Account> CreateAccountAsync(Account account)
|
||||
{
|
||||
account.Phone = PhoneNumberFormatter.NormalizeToDigits(account.Phone);
|
||||
return await _accountRepository.AddAsync(account);
|
||||
}
|
||||
|
||||
public async Task UpdateAccountAsync(Account account)
|
||||
{
|
||||
account.Phone = PhoneNumberFormatter.NormalizeToDigits(account.Phone);
|
||||
await _accountRepository.UpdateAsync(account);
|
||||
}
|
||||
|
||||
@@ -212,6 +229,14 @@ public class AccountManagementService
|
||||
return count == 0 ? string.Empty : new string(digits, 0, count);
|
||||
}
|
||||
|
||||
private static void FormatPhoneForDisplay(Account? account)
|
||||
{
|
||||
if (account == null)
|
||||
return;
|
||||
|
||||
account.Phone = PhoneNumberFormatter.FormatWithCountryCode(account.Phone);
|
||||
}
|
||||
|
||||
private static string? TryFindRepoRoot()
|
||||
{
|
||||
var current = Directory.GetCurrentDirectory();
|
||||
|
||||
@@ -3,6 +3,7 @@ using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using TelegramPanel.Core.Interfaces;
|
||||
using TelegramPanel.Core.Services;
|
||||
using TelegramPanel.Core.Utils;
|
||||
using TelegramPanel.Data.Entities;
|
||||
using System.IO.Compression;
|
||||
using WTelegram;
|
||||
@@ -63,7 +64,10 @@ public class AccountImportService
|
||||
try
|
||||
{
|
||||
// 入库策略:按手机号 upsert(方便重复导入/替换 session)
|
||||
var phone = result.Phone!;
|
||||
var phone = PhoneNumberFormatter.NormalizeToDigits(result.Phone);
|
||||
if (string.IsNullOrWhiteSpace(phone))
|
||||
throw new InvalidOperationException("导入结果缺少有效手机号");
|
||||
|
||||
var existing = await _accountManagement.GetAccountByPhoneAsync(phone);
|
||||
if (existing != null)
|
||||
{
|
||||
@@ -156,7 +160,10 @@ public class AccountImportService
|
||||
{
|
||||
try
|
||||
{
|
||||
var phone = result.Phone!;
|
||||
var phone = PhoneNumberFormatter.NormalizeToDigits(result.Phone);
|
||||
if (string.IsNullOrWhiteSpace(phone))
|
||||
throw new InvalidOperationException("导入结果缺少有效手机号");
|
||||
|
||||
var existing = await _accountManagement.GetAccountByPhoneAsync(phone);
|
||||
if (existing != null)
|
||||
{
|
||||
@@ -341,7 +348,9 @@ public class AccountImportService
|
||||
if (!TryGetString(root, out var phone, "phone", "phone_number", "phoneNumber") || string.IsNullOrWhiteSpace(phone))
|
||||
return new ImportResult(false, null, null, null, null, $"json 缺少 phone: {jsonPath}");
|
||||
|
||||
phone = phone.Trim();
|
||||
phone = PhoneNumberFormatter.NormalizeToDigits(phone);
|
||||
if (string.IsNullOrWhiteSpace(phone))
|
||||
return new ImportResult(false, null, null, null, null, $"json phone 无效: {jsonPath}");
|
||||
|
||||
_ = TryGetLong(root, out var userId, "user_id", "uid", "userId");
|
||||
_ = TryGetString(root, out var username, "username");
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="libphonenumber-csharp" Version="9.0.21" />
|
||||
<PackageReference Include="WTelegramClient" Version="4.*" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.*" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.*" />
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
using PhoneNumbers;
|
||||
|
||||
namespace TelegramPanel.Core.Utils;
|
||||
|
||||
/// <summary>
|
||||
/// 手机号格式化/规范化工具(用于展示国家码)
|
||||
/// </summary>
|
||||
public static class PhoneNumberFormatter
|
||||
{
|
||||
private static readonly PhoneNumberUtil Util = PhoneNumberUtil.GetInstance();
|
||||
|
||||
/// <summary>
|
||||
/// 仅保留数字(用于数据库存储/查询/文件名)
|
||||
/// </summary>
|
||||
public static string NormalizeToDigits(string? phone)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(phone))
|
||||
return string.Empty;
|
||||
|
||||
var digits = new char[phone.Length];
|
||||
var count = 0;
|
||||
foreach (var ch in phone)
|
||||
{
|
||||
if (ch >= '0' && ch <= '9')
|
||||
digits[count++] = ch;
|
||||
}
|
||||
|
||||
return count == 0 ? string.Empty : new string(digits, 0, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 格式化为 “+国家码 空格 本地号码” 的展示形式,如:+86 13800138000
|
||||
/// </summary>
|
||||
public static string FormatWithCountryCode(string? phone)
|
||||
{
|
||||
var digits = NormalizeToDigits(phone);
|
||||
if (digits.Length == 0)
|
||||
return (phone ?? string.Empty).Trim();
|
||||
|
||||
try
|
||||
{
|
||||
// Telegram 账号手机号通常是 E.164 数字串(无 +),这里统一按 E.164 解析
|
||||
var number = Util.Parse("+" + digits, defaultRegion: null);
|
||||
var nsn = Util.GetNationalSignificantNumber(number);
|
||||
if (string.IsNullOrWhiteSpace(nsn))
|
||||
return "+" + digits;
|
||||
|
||||
return $"+{number.CountryCode} {nsn}";
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 解析失败也至少补上 "+"
|
||||
return "+" + digits;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -342,8 +342,15 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
var phoneDigits = TelegramPanel.Core.Utils.PhoneNumberFormatter.NormalizeToDigits(accountInfo.Phone);
|
||||
if (string.IsNullOrWhiteSpace(phoneDigits))
|
||||
{
|
||||
Snackbar.Add("手机号无效,无法保存账号", Severity.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查账号是否已存在
|
||||
var existingAccount = await AccountManagement.GetAccountByPhoneAsync(accountInfo.Phone!);
|
||||
var existingAccount = await AccountManagement.GetAccountByPhoneAsync(phoneDigits);
|
||||
|
||||
if (existingAccount != null)
|
||||
{
|
||||
@@ -364,11 +371,11 @@
|
||||
// 创建新账号
|
||||
var account = new Account
|
||||
{
|
||||
Phone = accountInfo.Phone!,
|
||||
Phone = phoneDigits,
|
||||
UserId = accountInfo.TelegramUserId,
|
||||
Nickname = BuildNickname(accountInfo),
|
||||
Username = accountInfo.Username,
|
||||
SessionPath = System.IO.Path.Combine(sessionsPath, $"{accountInfo.Phone}.session"),
|
||||
SessionPath = System.IO.Path.Combine(sessionsPath, $"{phoneDigits}.session"),
|
||||
ApiId = telegramApiId,
|
||||
ApiHash = telegramApiHash,
|
||||
IsActive = true,
|
||||
|
||||
Reference in new issue
Block a user