feat(M08-B): 补任务列表导出

This commit is contained in:
Codex
2026-07-05 15:39:02 +08:00
parent d6bb9ccb1e
commit a50c6afdbe
6 changed files with 64 additions and 11 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="exportTasks">
导出
</el-button>
<el-button
type="success"
:icon="BadgeCheck"
@@ -401,6 +404,7 @@ import { computed, reactive, ref, watch } from 'vue';
import {
BadgeCheck,
Check,
Download,
Image,
ListChecks,
RefreshCw,
@@ -672,4 +676,40 @@ async function removeMember(cleanerUserId: string) {
ElMessage.error(error instanceof Error ? error.message : '协作者移除失败');
}
}
function exportTasks() {
downloadCsv(`cleaning-tasks-${Date.now()}.csv`, [
['任务号', '状态', '门店', '房间', '订单号', '保洁员ID', '协作人数', '奖励金额', '照片数', '提交时间', '完成时间', '驳回原因'],
...props.items.map((item) => [
item.taskNo,
item.status,
item.storeName,
item.roomName || item.roomNo,
item.orderNo || '',
item.cleanerUserId || '',
String(item.memberCount || 0),
money(item.rewardCents),
String(item.photoUrls?.length || 0),
shortDate(item.submittedAt),
shortDate(item.completedAt),
item.rejectReason || ''
])
]);
}
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>