feat(M08-B): 补结算候选导出

This commit is contained in:
Codex
2026-06-30 18:19:57 +08:00
parent 67e7796652
commit 957a29b11e
6 changed files with 76 additions and 9 deletions
@@ -34,6 +34,9 @@
<el-button :icon="Search" @click="submitFilters">筛选</el-button>
</div>
<div class="toolbar-actions">
<el-button :icon="Download" :disabled="items.length === 0" @click="exportSettlements">
导出
</el-button>
<el-button :icon="ListChecks" @click="openCandidates">
候选
</el-button>
@@ -220,6 +223,9 @@
</div>
</div>
<template #footer>
<el-button :icon="Download" :disabled="candidateDialog.items.length === 0" @click="exportCandidates">
导出候选
</el-button>
<el-button @click="candidateDialog.open = false">关闭</el-button>
<el-button type="primary" @click="useCandidateFilters">用当前筛选生成</el-button>
</template>
@@ -346,6 +352,7 @@ import {
BadgeCheck,
CircleAlert,
ClipboardCheck,
Download,
FilePlus2,
ListChecks,
RefreshCw,
@@ -586,4 +593,53 @@ function useCandidateFilters() {
generateDialog.cleanerUserId = filterDraft.cleanerUserId;
candidateDialog.open = false;
}
function exportSettlements() {
downloadCsv(`cleaning-settlements-${Date.now()}.csv`, [
['结算单', '状态', '保洁员', '门店', '任务数', '金额', '转账状态', '外部流水', '失败原因', '创建时间'],
...props.items.map((item) => [
item.settlementNo,
item.status,
item.cleanerName,
item.storeName || '',
String(item.taskCount),
money(item.totalRewardCents),
item.payoutState,
item.payoutReference,
item.payoutError,
shortDate(item.createdAt)
])
]);
}
function exportCandidates() {
downloadCsv(`cleaning-settlement-candidates-${Date.now()}.csv`, [
['任务号', '订单号', '门店', '房间', '保洁员ID', '金额', '完成时间'],
...candidateDialog.items.map((item) => [
item.taskNo,
item.orderNo || '',
item.storeName,
item.roomName || item.roomNo,
item.cleanerUserId || '',
money(item.rewardCents),
shortDate(item.completedAt)
])
]);
}
function downloadCsv(filename: string, rows: string[][]) {
const content = rows.map((row) => row.map(csvCell).join(',')).join('\r\n');
const blob = new Blob([`\uFEFF${content}`], { type: 'text/csv;charset=utf-8' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.click();
URL.revokeObjectURL(url);
}
function csvCell(value: string) {
const normalized = value.replace(/\r?\n/g, ' ');
return /[",\r\n]/.test(normalized) ? `"${normalized.replace(/"/g, '""')}"` : normalized;
}
</script>