feat: 招商银行 PDF 账单导入、跨格式去重与导入性能优化
- 新增招商银行「交易流水」PDF 解析(PDFBox 坐标还原,支持多页与折行),CSV/PDF 去重标识统一,支持跨格式去重 - 账单导入改为批量插入,MyBatis 日志改 Slf4j,导入接口超时放宽至 120s - 交易导出 Excel 增加样式、冻结表头与自动筛选,导出前二次确认 - 交易列表展示不计入统计金额,导入预览支持设置「计入统计」
This commit is contained in:
@@ -66,7 +66,7 @@ const allowedExtensions: Record<BillType, string[]> = {
|
||||
ALIPAY: ['.csv', '.zip'],
|
||||
WECHAT: ['.xlsx', '.zip'],
|
||||
MEITUAN: ['.csv', '.zip'],
|
||||
CMB: ['.csv', '.zip'],
|
||||
CMB: ['.csv', '.pdf', '.zip'],
|
||||
BOCOM: ['.xls', '.zip'],
|
||||
}
|
||||
|
||||
@@ -221,6 +221,18 @@ const columns = computed<DataTableColumns<ParsedBillRow>>(() => [
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('import.column.includeInStats'),
|
||||
key: 'includeInStats',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
render: (row) =>
|
||||
h(NCheckbox, {
|
||||
checked: !!row.includeInStats,
|
||||
disabled: !row.importable,
|
||||
onUpdateChecked: (v: boolean) => toggleIncludeInStats(row, v),
|
||||
}),
|
||||
},
|
||||
{
|
||||
title: t('import.column.amount'),
|
||||
key: 'amount',
|
||||
@@ -389,6 +401,22 @@ function toggleAll(checked: boolean) {
|
||||
checkedRowNos.value = checked ? selectableRows.value.map((r) => r.rowNo) : []
|
||||
}
|
||||
|
||||
/** 切换单行是否计入统计 */
|
||||
function toggleIncludeInStats(row: ParsedBillRow, value: boolean) {
|
||||
row.includeInStats = value
|
||||
}
|
||||
|
||||
/** 批量设置已勾选行的计入统计标记 */
|
||||
function setCheckedIncludeInStats(value: boolean) {
|
||||
if (checkedRows.value.length === 0) {
|
||||
message.warning(t('import.selectAtLeastOne'))
|
||||
return
|
||||
}
|
||||
checkedRows.value.forEach((row) => {
|
||||
row.includeInStats = value
|
||||
})
|
||||
}
|
||||
|
||||
/** 确认导入 */
|
||||
async function handleConfirm() {
|
||||
if (checkedRows.value.length === 0) {
|
||||
@@ -544,6 +572,12 @@ onMounted(() => {
|
||||
>
|
||||
{{ t('import.selectAll') }}
|
||||
</NCheckbox>
|
||||
<NButton size="small" :disabled="checkedRows.length === 0" @click="setCheckedIncludeInStats(true)">
|
||||
{{ t('import.setIncluded') }}
|
||||
</NButton>
|
||||
<NButton size="small" :disabled="checkedRows.length === 0" @click="setCheckedIncludeInStats(false)">
|
||||
{{ t('import.setExcluded') }}
|
||||
</NButton>
|
||||
<NText depth="3">{{ t('import.previewSummary', { total: rows.length, filtered: filteredRows.length, checked: checkedRows.length }) }}</NText>
|
||||
</NSpace>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user