From 1f1071501f4954ad0440d79c2a38e7210393e928 Mon Sep 17 00:00:00 2001 From: Codex Date: Tue, 11 Aug 2026 02:07:59 +0800 Subject: [PATCH] feat(cleaning): close settlement integrity and reconciliation --- admin/src/api.ts | 48 ++ .../components/CleaningSettlementsPanel.vue | 216 +++++- .../components/CleaningStatisticsPanel.vue | 40 +- admin/src/components/CleaningTasksPanel.vue | 12 +- admin/src/components/CleaningWorkspace.vue | 34 +- admin/src/types.ts | 31 + .../src/cleaning/cleaning-payout-service.ts | 90 ++- .../src/cleaning/cleaning-task-repository.ts | 619 +++++++++++++++--- backend/src/db/migration-runner.ts | 11 +- backend/src/routes/cleaning.ts | 38 +- .../tests/cleaning-payout-service.test.mjs | 55 +- backend/tests/cleaning-route.test.mjs | 42 +- backend/tests/migration-contract.test.mjs | 28 +- backend/tests/migration-runner.test.mjs | 13 +- .../tests/mysql-migration-roundtrip.test.mjs | 183 +++++- ...62627_m08b_cleaning_collaboration.down.sql | 7 + ...627_m08b_cleaning_collaboration.verify.sql | 1 + ...09c_cleaning_settlement_integrity.down.sql | 43 ++ ..._m09c_cleaning_settlement_integrity.up.sql | 136 ++++ ...c_cleaning_settlement_integrity.verify.sql | 39 ++ scripts/check-m09-c-settlement-integrity.mjs | 78 +++ scripts/dev/windows/test-all.ps1 | 2 + scripts/dev/wsl/mysql-migration-roundtrip.sh | 4 +- 23 files changed, 1562 insertions(+), 208 deletions(-) create mode 100644 database/migrations/2026081006_m09c_cleaning_settlement_integrity.down.sql create mode 100644 database/migrations/2026081006_m09c_cleaning_settlement_integrity.up.sql create mode 100644 database/migrations/2026081006_m09c_cleaning_settlement_integrity.verify.sql create mode 100644 scripts/check-m09-c-settlement-integrity.mjs diff --git a/admin/src/api.ts b/admin/src/api.ts index bfe2bf6..7d0a451 100644 --- a/admin/src/api.ts +++ b/admin/src/api.ts @@ -826,6 +826,28 @@ export function listCleaningSettlements( return request>(session, `/cleaning/settlements?${params}`); } +export function exportCleaningSettlements( + session: ApiSession, + input: { + status?: SettlementStatus; + payoutState?: PayoutStateFilter; + storeId?: string; + cleanerUserId?: string; + } +) { + const params = new URLSearchParams(); + if (input.status) params.set('status', input.status); + if (input.payoutState) params.set('payoutState', input.payoutState); + if (input.storeId) params.set('storeId', input.storeId); + if (input.cleanerUserId) params.set('cleanerUserId', input.cleanerUserId); + return request<{ + items: CleaningSettlement[]; + total: number; + exported: number; + truncated: boolean; + }>(session, `/cleaning/settlements/export?${params}`); +} + export function listCleaningSettlementCandidates( session: ApiSession, input: { page: number; pageSize: number; storeId?: string; cleanerUserId?: string } @@ -867,6 +889,32 @@ export function confirmCleaningSettlement(session: ApiSession, settlementId: str ); } +export function cancelCleaningSettlement(session: ApiSession, settlementId: string, reason: string) { + return request( + session, + `/cleaning/settlements/${encodeURIComponent(settlementId)}/cancel`, + { + method: 'POST', + body: JSON.stringify({ reason }) + } + ); +} + +export function markCleaningSettlementPaid( + session: ApiSession, + settlementId: string, + input: { payoutChannel: string; payoutReference: string; note?: string } +) { + return request( + session, + `/cleaning/settlements/${encodeURIComponent(settlementId)}/paid`, + { + method: 'POST', + body: JSON.stringify(input) + } + ); +} + export function executeWechatTransfer( session: ApiSession, settlementId: string, diff --git a/admin/src/components/CleaningSettlementsPanel.vue b/admin/src/components/CleaningSettlementsPanel.vue index d0b6b49..71013f3 100644 --- a/admin/src/components/CleaningSettlementsPanel.vue +++ b/admin/src/components/CleaningSettlementsPanel.vue @@ -56,7 +56,12 @@ > 批量同步 - + 导出 @@ -108,7 +113,7 @@ - + @@ -390,7 +413,7 @@ - +
单号{{ detailDialog.detail.settlement.settlementNo }} @@ -416,6 +439,9 @@ + + + @@ -427,6 +453,9 @@ {{ compactText(detailDialog.detail.settlement.payoutReference) }} + + {{ compactText(detailDialog.detail.settlement.payoutRequestNo) }} + {{ compactText(detailDialog.detail.settlement.payoutPackageInfo) }} @@ -436,7 +465,45 @@ {{ compactText(detailDialog.detail.settlement.note) }} + + {{ compactText(detailDialog.detail.settlement.cancelledBy) }} + + + {{ shortDate(detailDialog.detail.settlement.cancelledAt) }} + +
+

反向记录

+ + + + + + + + + + + +
+
+

状态历史

+ + + + + + + + + + + + + +