feat(M08-B): 补后台协作与结算详情

This commit is contained in:
Codex
2026-06-30 10:02:17 +08:00
parent 9506021b29
commit f59beb0e75
15 changed files with 529 additions and 23 deletions
@@ -49,6 +49,7 @@
<el-table-column label="操作" width="320" fixed="right">
<template #default="{ row }">
<div class="row-actions">
<el-button size="small" :icon="ListChecks" @click="openDetail(row)">详情</el-button>
<el-button
size="small"
:icon="BadgeCheck"
@@ -188,6 +189,56 @@
<el-button type="danger" @click="submitFailure">记录</el-button>
</template>
</el-dialog>
<el-dialog v-model="detailDialog.open" title="结算单详情" width="720px">
<div v-if="detailDialog.detail" class="dialog-stack">
<div class="detail-grid">
<span>单号<strong>{{ detailDialog.detail.settlement.settlementNo }}</strong></span>
<span>保洁员<strong>{{ detailDialog.detail.settlement.cleanerName }}</strong></span>
<span>金额<strong>{{ money(detailDialog.detail.settlement.totalRewardCents) }}</strong></span>
<span>状态<strong>{{ detailDialog.detail.settlement.status }}</strong></span>
</div>
<el-table :data="detailDialog.detail.items" size="small" v-loading="detailDialog.loading">
<el-table-column prop="taskNo" label="任务" min-width="170">
<template #default="{ row }">
<div class="stack">
<strong>{{ row.taskNo }}</strong>
<span>{{ compactText(row.orderNo) }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="房间" min-width="150">
<template #default="{ row }">
{{ row.storeName }} · {{ row.roomName || row.roomNo }}
</template>
</el-table-column>
<el-table-column prop="cleanerName" label="成员" width="130" />
<el-table-column prop="rewardCents" label="金额" width="110">
<template #default="{ row }">{{ money(row.rewardCents) }}</template>
</el-table-column>
<el-table-column prop="completedAt" label="完成" width="130">
<template #default="{ row }">{{ shortDate(row.completedAt) }}</template>
</el-table-column>
</el-table>
<el-descriptions :column="2" size="small" border>
<el-descriptions-item label="转账状态">
{{ compactText(detailDialog.detail.settlement.payoutState) }}
</el-descriptions-item>
<el-descriptions-item label="外部流水">
{{ compactText(detailDialog.detail.settlement.payoutReference) }}
</el-descriptions-item>
<el-descriptions-item label="失败原因" :span="2">
{{ compactText(detailDialog.detail.settlement.payoutError) }}
</el-descriptions-item>
<el-descriptions-item label="备注" :span="2">
{{ compactText(detailDialog.detail.settlement.note) }}
</el-descriptions-item>
</el-descriptions>
</div>
<template #footer>
<el-button @click="detailDialog.open = false">关闭</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
@@ -197,14 +248,16 @@ import {
CircleAlert,
ClipboardCheck,
FilePlus2,
ListChecks,
RefreshCw,
Send
} from '@lucide/vue';
import { ElMessage } from 'element-plus';
import { preflightWechatTransfer } from '../api';
import { getCleaningSettlementDetail, preflightWechatTransfer } from '../api';
import { compactText, money, shortDate } from '../format';
import type {
CleaningSettlement,
CleaningSettlementDetail,
PageResult,
SettlementStatus,
TransferMode,
@@ -260,6 +313,15 @@ const failureDialog = reactive({
payoutReference: '',
note: ''
});
const detailDialog = reactive<{
open: boolean;
loading: boolean;
detail: CleaningSettlementDetail | null;
}>({
open: false,
loading: false,
detail: null
});
function settlementTag(status: SettlementStatus) {
if (status === 'PAID') return 'success';
@@ -325,4 +387,16 @@ function submitFailure() {
});
failureDialog.open = false;
}
async function openDetail(row: CleaningSettlement) {
detailDialog.open = true;
detailDialog.loading = true;
try {
detailDialog.detail = await getCleaningSettlementDetail(props.session, row.id);
} catch (error) {
ElMessage.error(error instanceof Error ? error.message : '结算详情加载失败');
} finally {
detailDialog.loading = false;
}
}
</script>