Files
EmailBill/Service/EmailServices/EmailParse/EmailParseForm95555.cs

109 lines
3.8 KiB
C#
Raw Normal View History

2026-02-10 17:49:19 +08:00
using Service.AI;
namespace Service.EmailServices.EmailParse;
2025-12-25 11:20:56 +08:00
public class EmailParseForm95555(
ILogger<EmailParseForm95555> logger,
2026-02-10 17:49:19 +08:00
ISmartHandleService smartHandleService
) : EmailParseServicesBase(logger, smartHandleService)
2025-12-25 11:20:56 +08:00
{
public override bool CanParse(string from, string subject, string body)
2025-12-25 11:20:56 +08:00
{
if (!from.Contains("95555@message.cmbchina.com"))
{
return false;
}
if (!subject.Contains("账户变动通知"))
{
return false;
}
2025-12-25 11:20:56 +08:00
// 不能包含HTML标签
if (Regex.IsMatch(body, "<.*?>"))
{
return false;
}
return true;
}
2026-01-18 22:25:59 +08:00
public override Task<(
2025-12-25 11:20:56 +08:00
string card,
string reason,
decimal amount,
decimal balance,
TransactionType type,
DateTime? occurredAt
)[]> ParseEmailContentAsync(string emailContent)
{
// 示例1您账户8826于12月31日09:34在财付通-微信支付-这有电快捷支付1.00元余额30.21
// 示例2: 您账户8826于12月31日10:47入账款项人民币1000.00余额人民币1030.21。
2025-12-31 11:10:10 +08:00
var pattern =
"您账户(?<card>\\d+)" + // 卡号
"于(?<time>\\d{1,2}月\\d{1,2}日\\d{1,2}:\\d{2})" + // 交易时间
"(?:(?<type>收入|支出|消费|转入|转出|入账款项))?" + // 交易类型(可选)
"(?:在(?<reason>[^\\d。]*?))?" + // 交易原因(可选)
"?(?:人民币)?(?<amount>\\d+\\.\\d{1,2})(?:元)?" + // 金额,“元” 可有可无
",余额(?:人民币)?(?<balance>\\d+\\.\\d{1,2})" + // 余额
"。?"; // 句号可有可无
2025-12-25 11:20:56 +08:00
var matches = Regex.Matches(emailContent, pattern);
if (matches.Count <= 0)
{
logger.LogWarning("未能从招商银行邮件内容中解析出交易信息");
2026-01-18 22:25:59 +08:00
return Task.FromResult<(string card, string reason, decimal amount, decimal balance, TransactionType type, DateTime? occurredAt)[]>([]);
2025-12-25 11:20:56 +08:00
}
var results = new List<(
string card,
string reason,
decimal amount,
decimal balance,
TransactionType type,
DateTime? occurredAt
)>();
foreach (Match match in matches)
{
var card = match.Groups["card"].Value;
var amountStr = match.Groups["amount"].Value;
var balanceStr = match.Groups["balance"].Value;
var typeStr = match.Groups["type"].Value;
var reason = match.Groups["reason"].Value;
2026-01-30 10:41:19 +08:00
if (string.IsNullOrEmpty(reason))
{
reason = typeStr;
}
2025-12-25 11:20:56 +08:00
if (!string.IsNullOrEmpty(card) &&
!string.IsNullOrEmpty(reason) &&
decimal.TryParse(amountStr, out var amount) &&
decimal.TryParse(balanceStr, out var balance))
{
var type = DetermineTransactionType(typeStr, reason, amount);
var occurredAt = ParseOccurredAt(match.Groups["time"].Value);
results.Add((card, reason, amount, balance, type, occurredAt));
2025-12-25 11:20:56 +08:00
}
}
2026-01-18 22:25:59 +08:00
return Task.FromResult(results.ToArray());
2025-12-25 11:20:56 +08:00
}
private DateTime? ParseOccurredAt(string value)
{
// "12月31日09:34"
var now = DateTime.Now;
var dateTimeStr = $"{now.Year}年{value}";
if (DateTime.TryParse(dateTimeStr, out var occurredAt))
{
// 如果解析结果在未来,说明是上一年的交易
if (occurredAt > now)
{
occurredAt = occurredAt.AddYears(-1);
}
return occurredAt;
}
return null;
}
2025-12-25 11:20:56 +08:00
}