结构调整
This commit is contained in:
107
Service/EmailServices/EmailParse/EmailParseForm95555.cs
Normal file
107
Service/EmailServices/EmailParse/EmailParseForm95555.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
namespace Service.EmailParseServices;
|
||||
|
||||
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 async 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 [];
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user