优化邮件解析正则表达式,增强交易信息提取能力;调整界面样式,增加删除功能
This commit is contained in:
@@ -35,13 +35,16 @@ public class EmailParseForm95555(
|
||||
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+)" +
|
||||
"于.*?" + // 时间等信息统统吞掉
|
||||
"(?:(?<type>收入|支出|消费|转入|转出).*?)?" + // 可选 type
|
||||
"(?:在(?<reason>.*?))?" + // 可选 reason(“财付通-微信支付-这有电快捷支付”)
|
||||
"(?<amount>\\d+\\.\\d{1,2})元,余额" +
|
||||
"(?<balance>\\d+\\.\\d{1,2})";
|
||||
"您账户(?<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);
|
||||
|
||||
@@ -63,10 +66,14 @@ public class EmailParseForm95555(
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
var card = match.Groups["card"].Value;
|
||||
var reason = match.Groups["reason"].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) &&
|
||||
@@ -74,9 +81,27 @@ public class EmailParseForm95555(
|
||||
decimal.TryParse(balanceStr, out var balance))
|
||||
{
|
||||
var type = DetermineTransactionType(typeStr, reason, amount);
|
||||
results.Add((card, reason, amount, balance, type, null));
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -71,8 +71,18 @@ public abstract class EmailParseServicesBase(
|
||||
DateTime? occurredAt
|
||||
)[]?> ParseByAiAsync(string body)
|
||||
{
|
||||
var systemPrompt = "你是一个信息抽取助手。仅输出严格的JSON数组,不要包含任何多余文本。每个交易记录包含字段: card(字符串), reason(字符串), amount(数字), balance(数字), type(字符串,值为'收入'或'支出'), occurredAt(字符串,yyyy-MM-dd HH:mm:ss格式日期时间)。如果缺失,请推断或置空。";
|
||||
var userPrompt = $"从下面这封银行账单相关邮件正文中提取所有交易记录,返回JSON数组格式,每个元素包含: card, reason, amount, balance, type(收入或支出), occurredAt(非必要)。正文如下:\n\n{body}";
|
||||
var systemPrompt = $"""
|
||||
你是一个信息抽取助手。
|
||||
仅输出严格的JSON数组,不要包含任何多余文本。
|
||||
每个交易记录包含字段: card(字符串), reason(字符串), amount(数字), balance(数字), type(字符串,值为'收入'或'支出'), occurredAt(字符串,yyyy-MM-dd HH:mm:ss格式日期时间)。
|
||||
如果缺失,请推断或置空。
|
||||
[重要] 当前时间为{DateTime.Now:yyyy-MM-dd HH:mm:ss},请根据当前时间推断交易发生的时间。
|
||||
""";
|
||||
var userPrompt = $"""
|
||||
从下面这封银行账单相关邮件正文中提取所有交易记录,返回JSON数组格式,
|
||||
每个元素包含: card, reason, amount, balance, type(收入或支出), occurredAt(非必要)。
|
||||
正文如下:\n\n{body}
|
||||
""";
|
||||
|
||||
var contentText = await openAiService.ChatAsync(systemPrompt, userPrompt);
|
||||
if (string.IsNullOrWhiteSpace(contentText))
|
||||
@@ -190,12 +200,76 @@ public abstract class EmailParseServicesBase(
|
||||
var lowerReason = reason.ToLower();
|
||||
|
||||
// 收入关键词
|
||||
string[] incomeKeywords = { "工资", "奖金", "退款", "返现", "收入", "转入", "存入", "利息", "分红" };
|
||||
string[] incomeKeywords =
|
||||
{
|
||||
"工资", "奖金", "退款",
|
||||
"返现", "收入", "转入",
|
||||
"存入", "利息", "分红",
|
||||
"入账", "收款",
|
||||
|
||||
// 常见扩展
|
||||
"实发工资", "薪资", "薪水", "薪酬",
|
||||
"提成", "佣金", "劳务费",
|
||||
"报销入账", "报销款", "补贴", "补助",
|
||||
|
||||
"退款成功", "退回", "退货退款",
|
||||
"返现入账", "返利", "返佣",
|
||||
|
||||
"到账", "已到账", "入账成功",
|
||||
"收款成功", "收到款项", "到账金额",
|
||||
"资金转入", "资金收入",
|
||||
|
||||
"转账收入", "转账入账", "他行来账",
|
||||
"工资代发", "代发工资", "单位打款",
|
||||
|
||||
"利息收入", "收益", "收益发放", "理财收益",
|
||||
"分红收入", "股息", "红利",
|
||||
|
||||
// 平台常用词
|
||||
"红包", "红包收入", "红包入账",
|
||||
"奖励金", "活动奖励", "补贴金",
|
||||
"现金奖励", "推广奖励", "返现奖励",
|
||||
|
||||
// 存取类
|
||||
"现金存入", "柜台存入", "ATM存入",
|
||||
"他人转入", "他人汇入"
|
||||
};
|
||||
if (incomeKeywords.Any(k => lowerReason.Contains(k)))
|
||||
return TransactionType.Income;
|
||||
|
||||
// 支出关键词
|
||||
string[] expenseKeywords = { "消费", "支付", "购买", "转出", "取款", "支出", "扣款", "缴费" };
|
||||
string[] expenseKeywords =
|
||||
{
|
||||
"消费", "支付", "购买",
|
||||
"转出", "取款", "支出",
|
||||
"扣款", "缴费", "付款",
|
||||
"刷卡",
|
||||
|
||||
// 常见扩展
|
||||
"支出金额", "支出人民币", "已支出",
|
||||
"已消费", "消费支出", "消费人民币",
|
||||
"已支付", "成功支付", "支付成功", "交易支付",
|
||||
"已扣款", "扣款成功", "扣费", "扣费成功",
|
||||
"转账", "转账支出", "向外转账", "已转出",
|
||||
"提现", "现金支出", "现金取款",
|
||||
"扣除", "扣除金额", "记账支出",
|
||||
|
||||
// 账单/通知类用语
|
||||
"本期应还", "本期应还金额", "本期账单金额",
|
||||
"本期应还人民币", "最低还款额",
|
||||
"本期欠款", "欠款金额",
|
||||
|
||||
// 线上平台常见用语
|
||||
"订单支付", "订单扣款", "订单消费",
|
||||
"交易支出", "交易扣款", "交易成功支出",
|
||||
"话费充值", "流量充值", "水费", "电费", "燃气费",
|
||||
"物业费", "服务费", "手续费", "年费", "会费",
|
||||
"利息支出", "还款支出", "代扣", "代缴",
|
||||
|
||||
// 信用卡/花呗等场景
|
||||
"信用卡还款", "花呗还款", "白条还款",
|
||||
"分期还款", "账单还款", "自动还款"
|
||||
};
|
||||
if (expenseKeywords.Any(k => lowerReason.Contains(k)))
|
||||
return TransactionType.Expense;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</div>
|
||||
|
||||
<div class="popup-scroll-content">
|
||||
<van-form @submit="onSubmit">
|
||||
<van-form @submit="onSubmit" style="margin-top: 12px;">
|
||||
<van-cell-group inset>
|
||||
<van-cell title="卡号" :value="transaction.card" />
|
||||
<van-cell title="交易时间" :value="formatDate(transaction.occurredAt)" />
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
<h3>{{ currentEmail.Subject || currentEmail.subject || '(无主题)' }}</h3>
|
||||
</div>
|
||||
<div class="popup-scroll-content">
|
||||
<van-cell-group inset>
|
||||
<van-cell-group inset style="margin-top: 12px;">
|
||||
<van-cell title="发件人" :value="currentEmail.From || currentEmail.from || '未知'" />
|
||||
<van-cell title="接收时间" :value="formatDate(currentEmail.ReceivedDate || currentEmail.receivedDate)" />
|
||||
<van-cell title="记录时间" :value="formatDate(currentEmail.CreateTime || currentEmail.createTime)" />
|
||||
@@ -127,7 +127,7 @@
|
||||
:transactions="transactionList"
|
||||
:loading="false"
|
||||
:finished="true"
|
||||
:show-delete="false"
|
||||
:show-delete="true"
|
||||
@click="handleTransactionClick"
|
||||
/>
|
||||
</PopupContainer>
|
||||
|
||||
@@ -298,7 +298,7 @@
|
||||
:transactions="categoryBills"
|
||||
:loading="billListLoading"
|
||||
:finished="billListFinished"
|
||||
:show-delete="false"
|
||||
:show-delete="true"
|
||||
@load="loadCategoryBills"
|
||||
@click="viewBillDetail"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user