Files
EmailBill/Service/EmailServices/EmailParse/EmailParseForm95555.cs
SunCheng 435efbcb90
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Failing after 38s
Docker Build & Deploy / Deploy to Production (push) Has been skipped
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 2s
Docker Build & Deploy / WeChat Notification (push) Successful in 2s
大量的代码格式化
2026-01-18 22:25:59 +08:00

107 lines
3.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace Service.EmailServices.EmailParse;
public class EmailParseForm95555(
ILogger<EmailParseForm95555> logger,
IOpenAiService openAiService
) : EmailParseServicesBase(logger, openAiService)
{
public override bool CanParse(string from, string subject, string body)
{
if (!from.Contains("95555@message.cmbchina.com"))
{
return false;
}
if (!subject.Contains("账户变动通知"))
{
return false;
}
// 不能包含HTML标签
if (Regex.IsMatch(body, "<.*?>"))
{
return false;
}
return true;
}
public override Task<(
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。
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})" + // 余额
"。?"; // 句号可有可无
var matches = Regex.Matches(emailContent, pattern);
if (matches.Count <= 0)
{
logger.LogWarning("未能从招商银行邮件内容中解析出交易信息");
return Task.FromResult<(string card, string reason, decimal amount, decimal balance, TransactionType type, DateTime? occurredAt)[]>([]);
}
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;
if(string.IsNullOrEmpty(reason))
{
reason = typeStr;
}
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));
}
}
return Task.FromResult(results.ToArray());
}
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;
}
}