feat(M08-B): 补结算批量同步

This commit is contained in:
Codex
2026-07-02 08:10:37 +08:00
parent 2ce59eee3b
commit 9f6e267d43
7 changed files with 71 additions and 11 deletions
+10
View File
@@ -131,6 +131,7 @@
@confirm="handleConfirmSettlement"
@transfer="handleTransfer"
@sync-transfer="handleSyncTransfer"
@sync-transfer-many="handleSyncTransferMany"
@failure="handleFailure"
/>
</el-tab-pane>
@@ -478,6 +479,15 @@ async function handleSyncTransfer(input: { settlementId: string; note?: string }
}, '已同步微信状态');
}
async function handleSyncTransferMany(input: { settlementIds: string[]; note?: string }) {
await runAction(async () => {
for (const settlementId of input.settlementIds) {
await syncWechatTransfer(session.value, settlementId, input.note);
}
await Promise.all([loadSettlements(), loadStatistics()]);
}, `已批量同步 ${input.settlementIds.length} 个结算单`);
}
async function handleFailure(
input: { settlementId: string; error: string; payoutReference?: string; note?: string }
) {
@@ -34,6 +34,13 @@
<el-button :icon="Search" @click="submitFilters">筛选</el-button>
</div>
<div class="toolbar-actions">
<el-button
:icon="RefreshCw"
:disabled="selectedSyncableCount === 0"
@click="submitBatchSync"
>
批量同步
</el-button>
<el-button :icon="Download" :disabled="items.length === 0" @click="exportSettlements">
导出
</el-button>
@@ -49,7 +56,14 @@
</div>
</div>
<el-table :data="items" :loading="loading" class="data-table" row-key="id">
<el-table
:data="items"
:loading="loading"
class="data-table"
row-key="id"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="44" :selectable="canSelectSettlement" />
<el-table-column prop="settlementNo" label="结算单" min-width="190" fixed>
<template #default="{ row }">
<div class="stack">
@@ -347,7 +361,7 @@
</template>
<script setup lang="ts">
import { computed, reactive, watch } from 'vue';
import { computed, reactive, ref, watch } from 'vue';
import {
BadgeCheck,
CircleAlert,
@@ -398,6 +412,7 @@ const emit = defineEmits<{
confirm: [{ settlementId: string; note?: string }];
transfer: [{ settlementId: string; mode: TransferMode; note?: string }];
'sync-transfer': [{ settlementId: string; note?: string }];
'sync-transfer-many': [{ settlementIds: string[]; note?: string }];
failure: [{ settlementId: string; error: string; payoutReference?: string; note?: string }];
}>();
@@ -409,6 +424,7 @@ const statusOptions = [
{ label: '取消', value: 'CANCELLED' }
];
const filterDraft = reactive({ storeId: props.filters.storeId, cleanerUserId: props.filters.cleanerUserId });
const selectedSettlements = ref<CleaningSettlement[]>([]);
const generateDialog = reactive({ open: false, cleanerUserId: '', storeId: '', note: '' });
const transferDialog = reactive({
open: false,
@@ -462,6 +478,9 @@ const candidateDialog = reactive<{
});
const candidatePageRewardCents = computed(() => candidateDialog.items
.reduce((sum, item) => sum + item.rewardCents, 0));
const selectedSyncableSettlements = computed(() => selectedSettlements.value
.filter((settlement) => settlement.status === 'CONFIRMED'));
const selectedSyncableCount = computed(() => selectedSyncableSettlements.value.length);
function settlementTag(status: SettlementStatus) {
if (status === 'PAID') return 'success';
@@ -476,6 +495,14 @@ function preflightTag(status: string) {
return 'danger';
}
function canSelectSettlement(row: CleaningSettlement) {
return row.status === 'CONFIRMED';
}
function handleSelectionChange(rows: CleaningSettlement[]) {
selectedSettlements.value = rows;
}
function cleanerLabel(cleaner: ManagedUser) {
const name = cleaner.nickname || `ID ${cleaner.id}`;
const phone = cleaner.maskedPhone ? ` · ${cleaner.maskedPhone}` : '';
@@ -519,6 +546,18 @@ function submitTransfer() {
transferDialog.open = false;
}
function submitBatchSync() {
const settlementIds = selectedSyncableSettlements.value.map((settlement) => settlement.id);
if (!settlementIds.length) {
ElMessage.warning('请选择待发放结算单');
return;
}
emit('sync-transfer-many', {
settlementIds,
note: '后台批量同步微信转账状态'
});
}
async function openPreflight(row: CleaningSettlement) {
try {
preflightDialog.result = await preflightWechatTransfer(props.session, row.id);