From 7f6a291628017facf1bca211cafd457fe5474407 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sat, 22 Aug 2026 13:38:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=AA=8C=E6=94=B6=E6=8A=A5?= =?UTF-8?q?=E9=85=AC=E5=BE=85=E8=A7=A3=E5=86=BB=E9=85=8D=E7=BD=AE=E5=B9=B6?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BE=85=E8=A7=A3=E5=86=BB=E7=BB=93=E7=AE=97?= =?UTF-8?q?=E6=BC=8F=E5=85=A5=E9=98=9F=E4=B8=8E=E9=87=8D=E5=A4=8D=E9=87=8A?= =?UTF-8?q?=E6=94=BE=E6=B5=81=E6=B0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/055_reward_unfreeze_config.sql | 3 + .../work-order-settlement-repo.ts | 223 ++++++++++-------- .../worker-platform/worker-finance-repo.ts | 4 +- .../admin-work-order-acceptance-service.ts | 14 +- .../worker-acceptance-service.ts | 2 + .../worker-finance-config-service.ts | 4 + apps/frontend/src/layouts/AdminLayout.tsx | 3 +- .../pages/admin/panels/AfterSalesPanel.tsx | 2 +- .../src/pages/admin/panels/FinancePanel.tsx | 15 +- .../admin/platform/AdminPlatformShopsPage.tsx | 2 +- .../worker/WorkerProfileDesktopSections.tsx | 6 +- .../worker/WorkerProfileFinanceModals.tsx | 2 +- .../pages/worker/WorkerProfileMobileView.tsx | 2 +- .../src/pages/worker/WorkerProfileRecords.tsx | 2 +- .../worker/worker-profile-view-utils.tsx | 2 +- .../src/services/admin/worker-platform.ts | 1 + apps/frontend/src/types/worker-platform.ts | 1 + 17 files changed, 173 insertions(+), 115 deletions(-) create mode 100644 apps/backend/src/db/migrations/055_reward_unfreeze_config.sql diff --git a/apps/backend/src/db/migrations/055_reward_unfreeze_config.sql b/apps/backend/src/db/migrations/055_reward_unfreeze_config.sql new file mode 100644 index 00000000..69a9b59d --- /dev/null +++ b/apps/backend/src/db/migrations/055_reward_unfreeze_config.sql @@ -0,0 +1,3 @@ +-- 验收报酬默认进入待解冻,售后问题单成立前不能直接提现。 +COMMENT ON COLUMN worker_wallets.pending_unfreeze_amount IS '待解冻金额:验收报酬与押金按配置天数解冻到账'; +COMMENT ON TABLE worker_deposit_unfreezes IS '待解冻计划:验收报酬与押金到期自动转入可用余额'; diff --git a/apps/backend/src/repositories/worker-platform/work-order-settlement-repo.ts b/apps/backend/src/repositories/worker-platform/work-order-settlement-repo.ts index 66cc0ff7..5363d08d 100644 --- a/apps/backend/src/repositories/worker-platform/work-order-settlement-repo.ts +++ b/apps/backend/src/repositories/worker-platform/work-order-settlement-repo.ts @@ -18,6 +18,7 @@ import type { WorkOrderRow, WorkOrderShareRow } from './types.js' export async function acceptWorkOrderAndSettle(input: { workOrderId: number unfreezeDays: number + rewardUnfreezeEnabled: boolean now: string /** 操作人类型:admin / worker / system */ actorType?: string @@ -94,11 +95,13 @@ export async function acceptWorkOrderAndSettle(input: { now: input.now, }) const debtOffsetAmount = debtOffsets.reduce((total, item) => total + item.amount, 0) - const shouldDelayUnfreeze = input.unfreezeDays > 0 + const shouldDelayUnfreeze = input.rewardUnfreezeEnabled && input.unfreezeDays > 0 + const pendingUnfreezeAmount = + (shouldDelayUnfreeze ? shareReward : 0) + (input.unfreezeDays > 0 ? releaseAmount : 0) const nextAvailable = Number(wallet?.available_amount || 0) + - shareReward + - (shouldDelayUnfreeze ? 0 : releaseAmount) - + (shouldDelayUnfreeze ? 0 : shareReward) + + (input.unfreezeDays > 0 ? 0 : releaseAmount) - debtOffsetAmount const nextFrozen = Math.max(0, Number(wallet?.frozen_deposit_amount || 0) - releaseAmount) @@ -113,86 +116,87 @@ export async function acceptWorkOrderAndSettle(input: { updated_at = $5 WHERE worker_id = $6 `, - [ - nextAvailable, - nextFrozen, - shouldDelayUnfreeze ? releaseAmount : 0, - shareReward, - input.now, - shareWorkerId, - ], + [nextAvailable, nextFrozen, pendingUnfreezeAmount, shareReward, input.now, shareWorkerId], ) - if (releaseAmount > 0) { - if (shouldDelayUnfreeze) { - await enqueueDepositUnfreezeWithClient(client, { - workerId: shareWorkerId, - workOrderId: input.workOrderId, - amount: releaseAmount, - unfreezeDays: input.unfreezeDays, - now: input.now, - }) - await client.query( - ` + if (pendingUnfreezeAmount > 0) { + await enqueueDepositUnfreezeWithClient(client, { + workerId: shareWorkerId, + workOrderId: input.workOrderId, + amount: pendingUnfreezeAmount, + unfreezeDays: input.unfreezeDays, + now: input.now, + }) + } + if (releaseAmount > 0 && input.unfreezeDays > 0) { + await client.query( + ` INSERT INTO worker_wallet_ledgers ( worker_id, ledger_type, amount, balance_after, frozen_after, related_work_order_id, note, payload_json, created_at ) VALUES ($1, 'deposit_pending_unfreeze', $2, $3, $4, $5, '拼单验收押金待解冻', $6::jsonb, $7) `, - [ - shareWorkerId, - releaseAmount, - nextAvailable, - nextFrozen, - input.workOrderId, - JSON.stringify({ - workOrderId: input.workOrderId, - shareId: Number(share.id), - unfreezeDays: input.unfreezeDays, - }), - input.now, - ], - ) - } else { - await client.query( - ` - INSERT INTO worker_wallet_ledgers ( - worker_id, ledger_type, amount, balance_after, frozen_after, - related_work_order_id, note, payload_json, created_at - ) VALUES ($1, 'deposit_release', $2, $3, $4, $5, '拼单验收释放押金', $6::jsonb, $7) - `, - [ - shareWorkerId, - releaseAmount, - nextAvailable, - nextFrozen, - input.workOrderId, - JSON.stringify({ workOrderId: input.workOrderId, shareId: Number(share.id) }), - input.now, - ], - ) - } + [ + shareWorkerId, + releaseAmount, + nextAvailable, + nextFrozen, + input.workOrderId, + JSON.stringify({ + workOrderId: input.workOrderId, + shareId: Number(share.id), + unfreezeDays: input.unfreezeDays, + }), + input.now, + ], + ) } - - if (shareReward > 0) { + if (releaseAmount > 0 && input.unfreezeDays === 0) { await client.query( ` INSERT INTO worker_wallet_ledgers ( worker_id, ledger_type, amount, balance_after, frozen_after, related_work_order_id, note, payload_json, created_at - ) VALUES ($1, 'sharing_reward', $2, $3, $4, $5, $6, $7::jsonb, $8) + ) VALUES ($1, 'deposit_release', $2, $3, $4, $5, '拼单验收释放押金', $6::jsonb, $7) `, [ shareWorkerId, + releaseAmount, + nextAvailable, + nextFrozen, + input.workOrderId, + JSON.stringify({ workOrderId: input.workOrderId, shareId: Number(share.id) }), + input.now, + ], + ) + } + + if (shareReward > 0) { + const rewardLedgerType = shouldDelayUnfreeze + ? 'deposit_pending_unfreeze' + : 'reward_settlement' + await client.query( + ` + INSERT INTO worker_wallet_ledgers ( + worker_id, ledger_type, amount, balance_after, frozen_after, + related_work_order_id, note, payload_json, created_at + ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9) + `, + [ + shareWorkerId, + rewardLedgerType, shareReward, nextAvailable, nextFrozen, input.workOrderId, - `拼单结算报酬 ${share.quantity} 份`, + shouldDelayUnfreeze + ? '拼单份额验收报酬待解冻' + : `拼单份额验收结算报酬 ${share.quantity} 份`, JSON.stringify({ workOrderId: input.workOrderId, shareId: Number(share.id), quantity: share.quantity, + ...(shouldDelayUnfreeze ? { unfreezeDays: input.unfreezeDays } : {}), }), input.now, ], @@ -250,11 +254,13 @@ export async function acceptWorkOrderAndSettle(input: { now: input.now, }) const debtOffsetAmount = debtOffsets.reduce((total, item) => total + item.amount, 0) - const shouldDelayUnfreeze = input.unfreezeDays > 0 + const shouldDelayUnfreeze = input.rewardUnfreezeEnabled && input.unfreezeDays > 0 + const pendingUnfreezeAmount = + (shouldDelayUnfreeze ? rewardAmount : 0) + (input.unfreezeDays > 0 ? releaseAmount : 0) const nextAvailable = Number(wallet?.available_amount || 0) + - rewardAmount + - (shouldDelayUnfreeze ? 0 : releaseAmount) - + (shouldDelayUnfreeze ? 0 : rewardAmount) + + (input.unfreezeDays > 0 ? 0 : releaseAmount) - debtOffsetAmount const nextFrozen = Math.max(0, Number(wallet?.frozen_deposit_amount || 0) - releaseAmount) @@ -269,25 +275,21 @@ export async function acceptWorkOrderAndSettle(input: { updated_at = $5 WHERE worker_id = $6 `, - [ - nextAvailable, - nextFrozen, - shouldDelayUnfreeze ? releaseAmount : 0, - rewardAmount, - input.now, - workerId, - ], + [nextAvailable, nextFrozen, pendingUnfreezeAmount, rewardAmount, input.now, workerId], ) + if (pendingUnfreezeAmount > 0) { + await enqueueDepositUnfreezeWithClient(client, { + workerId, + workOrderId: input.workOrderId, + amount: pendingUnfreezeAmount, + unfreezeDays: input.unfreezeDays, + now: input.now, + }) + } + if (releaseAmount > 0) { - if (shouldDelayUnfreeze) { - await enqueueDepositUnfreezeWithClient(client, { - workerId, - workOrderId: input.workOrderId, - amount: releaseAmount, - unfreezeDays: input.unfreezeDays, - now: input.now, - }) + if (input.unfreezeDays > 0) { await client.query( ` INSERT INTO worker_wallet_ledgers ( @@ -322,14 +324,31 @@ export async function acceptWorkOrderAndSettle(input: { } if (rewardAmount > 0) { + const rewardLedgerType = shouldDelayUnfreeze + ? 'deposit_pending_unfreeze' + : 'reward_settlement' await client.query( ` INSERT INTO worker_wallet_ledgers ( worker_id, ledger_type, amount, balance_after, frozen_after, related_work_order_id, note, payload_json, created_at - ) VALUES ($1, 'reward_settlement', $2, $3, $4, $5, '验收通过结算报酬', '{}'::jsonb, $6) + ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9) `, - [workerId, rewardAmount, nextAvailable, nextFrozen, input.workOrderId, input.now], + [ + workerId, + rewardLedgerType, + rewardAmount, + nextAvailable, + nextFrozen, + input.workOrderId, + shouldDelayUnfreeze ? '验收通过报酬待解冻' : '验收通过结算报酬', + JSON.stringify( + shouldDelayUnfreeze + ? { workOrderId: input.workOrderId, unfreezeDays: input.unfreezeDays } + : {}, + ), + input.now, + ], ) } for (const debtOffset of debtOffsets) { @@ -383,6 +402,7 @@ export async function acceptWorkOrderShareAndSettle(input: { workOrderId: number shareId: number unfreezeDays: number + rewardUnfreezeEnabled: boolean now: string actorType?: string actorName?: string @@ -428,11 +448,13 @@ export async function acceptWorkOrderShareAndSettle(input: { now: input.now, }) const debtOffsetAmount = debtOffsets.reduce((total, item) => total + item.amount, 0) - const shouldDelayUnfreeze = input.unfreezeDays > 0 + const shouldDelayUnfreeze = input.rewardUnfreezeEnabled && input.unfreezeDays > 0 + const pendingUnfreezeAmount = + (shouldDelayUnfreeze ? shareReward : 0) + (input.unfreezeDays > 0 ? releaseAmount : 0) const nextAvailable = Number(wallet?.available_amount || 0) + - shareReward + - (shouldDelayUnfreeze ? 0 : releaseAmount) - + (shouldDelayUnfreeze ? 0 : shareReward) + + (input.unfreezeDays > 0 ? 0 : releaseAmount) - debtOffsetAmount const nextFrozen = Math.max(0, Number(wallet?.frozen_deposit_amount || 0) - releaseAmount) await client.query( @@ -441,21 +463,14 @@ export async function acceptWorkOrderShareAndSettle(input: { pending_unfreeze_amount = pending_unfreeze_amount + $3, total_settled_amount = total_settled_amount + $4, updated_at = $5 WHERE worker_id = $6`, - [ - nextAvailable, - nextFrozen, - shouldDelayUnfreeze ? releaseAmount : 0, - shareReward, - input.now, - workerId, - ], + [nextAvailable, nextFrozen, pendingUnfreezeAmount, shareReward, input.now, workerId], ) - if (releaseAmount > 0 && shouldDelayUnfreeze) { + if (pendingUnfreezeAmount > 0) { await enqueueDepositUnfreezeWithClient(client, { workerId, workOrderId: input.workOrderId, - amount: releaseAmount, + amount: pendingUnfreezeAmount, unfreezeDays: input.unfreezeDays, now: input.now, }) @@ -468,31 +483,43 @@ export async function acceptWorkOrderShareAndSettle(input: { ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9)`, [ workerId, - shouldDelayUnfreeze ? 'deposit_pending_unfreeze' : 'deposit_release', + input.unfreezeDays > 0 ? 'deposit_pending_unfreeze' : 'deposit_release', releaseAmount, nextAvailable, nextFrozen, input.workOrderId, - shouldDelayUnfreeze ? '拼单份额验收押金待解冻' : '拼单份额验收释放押金', + input.unfreezeDays > 0 ? '拼单份额验收押金待解冻' : '拼单份额验收释放押金', JSON.stringify({ workOrderId: input.workOrderId, shareId: input.shareId }), input.now, ], ) } if (shareReward > 0) { + const rewardLedgerType = shouldDelayUnfreeze ? 'deposit_pending_unfreeze' : 'sharing_reward' await client.query( `INSERT INTO worker_wallet_ledgers ( worker_id, ledger_type, amount, balance_after, frozen_after, related_work_order_id, note, payload_json, created_at - ) VALUES ($1, 'sharing_reward', $2, $3, $4, $5, $6, $7::jsonb, $8)`, + ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9)`, [ workerId, + rewardLedgerType, shareReward, nextAvailable, nextFrozen, input.workOrderId, - `拼单份额验收结算报酬 ${share.quantity} 份`, - JSON.stringify({ workOrderId: input.workOrderId, shareId: input.shareId }), + shouldDelayUnfreeze + ? '拼单份额验收报酬待解冻' + : `拼单份额验收结算报酬 ${share.quantity} 份`, + JSON.stringify( + shouldDelayUnfreeze + ? { + workOrderId: input.workOrderId, + shareId: input.shareId, + unfreezeDays: input.unfreezeDays, + } + : { workOrderId: input.workOrderId, shareId: input.shareId }, + ), input.now, ], ) diff --git a/apps/backend/src/repositories/worker-platform/worker-finance-repo.ts b/apps/backend/src/repositories/worker-platform/worker-finance-repo.ts index eb3eddcd..c0c45744 100644 --- a/apps/backend/src/repositories/worker-platform/worker-finance-repo.ts +++ b/apps/backend/src/repositories/worker-platform/worker-finance-repo.ts @@ -483,9 +483,7 @@ function buildWorkerFinanceRequestWhere({ if (createdFrom) { params.push(createdFrom) // 纯日期字符串 cast 后即当天 00:00:00;带时间则精确到秒 - filters.push( - `wfr.created_at >= ($${params.length}::timestamp) AT TIME ZONE 'Asia/Shanghai'`, - ) + filters.push(`wfr.created_at >= ($${params.length}::timestamp) AT TIME ZONE 'Asia/Shanghai'`) } if (createdTo) { params.push(createdTo) diff --git a/apps/backend/src/services/worker-platform/admin-work-order-acceptance-service.ts b/apps/backend/src/services/worker-platform/admin-work-order-acceptance-service.ts index 93c0060d..4db0dd38 100644 --- a/apps/backend/src/services/worker-platform/admin-work-order-acceptance-service.ts +++ b/apps/backend/src/services/worker-platform/admin-work-order-acceptance-service.ts @@ -8,6 +8,7 @@ import { } from '../../repositories/worker-platform/index.js' import type { JsonObject } from '../../types/json.js' import { createHttpError } from '../../utils/http.js' +import { getWorkerFinanceConfig } from './worker-finance-config-service.js' import { nowIso } from '../../utils/time.js' import { resolveAdminNotificationEntity } from '../admin/admin-notification-service.js' import { @@ -21,7 +22,6 @@ import { resolveWorkOrderOperationalStatus, } from './mappers.js' import { resolveWorkOrderRealtimeWorkerIds } from './admin-work-order-realtime-service.js' -import { getWorkerFinanceConfig } from './worker-finance-config-service.js' import { getRequiredWorkOrder } from './worker-session-context-service.js' export async function acceptAdminWorkOrder(workOrderId: number | string, actorName = '') { @@ -43,7 +43,7 @@ export async function acceptAdminWorkOrder(workOrderId: number | string, actorNa const now = nowIso() const { order: updated, failureReason } = await acceptWorkOrderAndSettle({ workOrderId: workOrder.id, - unfreezeDays: getWorkerFinanceConfig().depositUnfreezeDays, + ...resolveAcceptanceFinanceOptions(), now, actorType: 'admin', actorName, @@ -75,7 +75,7 @@ export async function acceptAdminWorkOrderShare( const result = await acceptWorkOrderShareAndSettle({ workOrderId: Number(workOrderId), shareId: Number(shareId), - unfreezeDays: getWorkerFinanceConfig().depositUnfreezeDays, + ...resolveAcceptanceFinanceOptions(), now: nowIso(), actorType: 'admin', actorName, @@ -104,6 +104,14 @@ export async function acceptAdminWorkOrderShare( return { order: mapWorkOrderAdmin(result.order), share: mapWorkOrderShare(result.share) } } +function resolveAcceptanceFinanceOptions() { + const financeConfig = getWorkerFinanceConfig() + return { + unfreezeDays: financeConfig.depositUnfreezeDays, + rewardUnfreezeEnabled: financeConfig.rewardUnfreezeEnabled, + } +} + export async function cancelAdminWorkOrderShare( workOrderId: number | string, shareId: number | string, diff --git a/apps/backend/src/services/worker-platform/worker-acceptance-service.ts b/apps/backend/src/services/worker-platform/worker-acceptance-service.ts index 4d3c4ea4..d3ba3636 100644 --- a/apps/backend/src/services/worker-platform/worker-acceptance-service.ts +++ b/apps/backend/src/services/worker-platform/worker-acceptance-service.ts @@ -173,6 +173,7 @@ export async function submitWorkerOrderAcceptance( const { order: acceptedOrder, failureReason } = await acceptWorkOrderAndSettle({ workOrderId: workOrder.id, unfreezeDays: getWorkerFinanceConfig().depositUnfreezeDays, + rewardUnfreezeEnabled: getWorkerFinanceConfig().rewardUnfreezeEnabled, now, actorType: 'worker', actorName: worker.display_name || worker.username || '', @@ -452,6 +453,7 @@ async function submitWorkerSharingAcceptance( workOrderId: Number(workOrder.id), shareId: Number(result.share.id), unfreezeDays: getWorkerFinanceConfig().depositUnfreezeDays, + rewardUnfreezeEnabled: getWorkerFinanceConfig().rewardUnfreezeEnabled, now, actorType: 'worker', actorName: worker.display_name || worker.username || '', diff --git a/apps/backend/src/services/worker-platform/worker-finance-config-service.ts b/apps/backend/src/services/worker-platform/worker-finance-config-service.ts index f245cb01..3dd2316b 100644 --- a/apps/backend/src/services/worker-platform/worker-finance-config-service.ts +++ b/apps/backend/src/services/worker-platform/worker-finance-config-service.ts @@ -9,6 +9,7 @@ import { export type WorkerFinanceConfig = { depositUnfreezeDays: number + rewardUnfreezeEnabled: boolean recharge: { enabled: boolean channelName: string @@ -56,6 +57,7 @@ export function normalizeWorkerFinanceConfig(rawValue: unknown): WorkerFinanceCo return { depositUnfreezeDays: normalizeRangeInteger(source.depositUnfreezeDays, 3, 0, 30), + rewardUnfreezeEnabled: source.rewardUnfreezeEnabled !== false, recharge: { enabled: typeof recharge.enabled === 'boolean' ? recharge.enabled : true, channelName: String(recharge.channelName || recharge.channel_name || '').trim(), @@ -80,6 +82,7 @@ export function normalizeWorkerFinanceConfig(rawValue: unknown): WorkerFinanceCo export function createDefaultWorkerFinanceConfig(): WorkerFinanceConfig { return { depositUnfreezeDays: 3, + rewardUnfreezeEnabled: true, recharge: { enabled: true, channelName: '', @@ -101,6 +104,7 @@ export function createDefaultWorkerFinanceConfig(): WorkerFinanceConfig { function refreshWorkerFinanceConfig(config: WorkerFinanceConfig): WorkerFinanceConfig { return { depositUnfreezeDays: config.depositUnfreezeDays, + rewardUnfreezeEnabled: config.rewardUnfreezeEnabled, recharge: { ...config.recharge, qrCodeImage: config.recharge.qrCodeImage diff --git a/apps/frontend/src/layouts/AdminLayout.tsx b/apps/frontend/src/layouts/AdminLayout.tsx index ffd2fe29..4c42e8ba 100644 --- a/apps/frontend/src/layouts/AdminLayout.tsx +++ b/apps/frontend/src/layouts/AdminLayout.tsx @@ -429,8 +429,7 @@ function patchAdminWorkOrderCaches( matchesWorkOrderKeyword(item, keyword) && (!workerId || workerId === Number(item.worker?.workerId || 0)) && (!targetWorkOrderId || targetWorkOrderId === Number(item.workOrderId || 0)) - const shouldInsert = - event.operation === 'upsert' && page === 1 && matches && !levelFilterActive + const shouldInsert = event.operation === 'upsert' && page === 1 && matches && !levelFilterActive const operation = event.operation === 'remove' || !matches ? 'remove' : 'upsert' queryClient.setQueryData( queryKey, diff --git a/apps/frontend/src/pages/admin/panels/AfterSalesPanel.tsx b/apps/frontend/src/pages/admin/panels/AfterSalesPanel.tsx index 492fb3a5..e2a92ff2 100644 --- a/apps/frontend/src/pages/admin/panels/AfterSalesPanel.tsx +++ b/apps/frontend/src/pages/admin/panels/AfterSalesPanel.tsx @@ -395,7 +395,7 @@ const AfterSalesPanel = forwardRef(function AfterSalesPan label="追缴金额" name="recoveryAmount" rules={[{ required: true, message: '请输入追缴金额' }]} - extra="系统依次扣减该责任打手的本单待解冻押金、可用余额;不足部分转为欠款,并从后续验收报酬自动抵扣。" + extra="系统依次扣减该责任打手的本单待解冻金额、可用余额;不足部分转为欠款,并从后续验收报酬自动抵扣。" > diff --git a/apps/frontend/src/pages/admin/panels/FinancePanel.tsx b/apps/frontend/src/pages/admin/panels/FinancePanel.tsx index efdf5c1b..4e1c5050 100644 --- a/apps/frontend/src/pages/admin/panels/FinancePanel.tsx +++ b/apps/frontend/src/pages/admin/panels/FinancePanel.tsx @@ -41,6 +41,7 @@ import { formatAdminDateTime } from '@/utils/admin-time' import { asRecord, formatMoney } from './shared' type FinanceConfigFormValues = { depositUnfreezeDays?: number + rewardUnfreezeEnabled?: boolean recharge?: { enabled?: boolean channelName?: string @@ -158,6 +159,7 @@ export default function FinancePanel() { try { await saveAdminWorkerFinanceConfig({ depositUnfreezeDays: Number(values.depositUnfreezeDays ?? 3), + rewardUnfreezeEnabled: values.rewardUnfreezeEnabled !== false, recharge: { enabled: values.recharge?.enabled !== false, channelName: String(values.recharge?.channelName || '').trim(), @@ -401,12 +403,20 @@ export default function FinancePanel() { + + + - 解冻期间如订单出现问题,可在"接单工单"中对已验收工单扣减待解冻押金(全额或部分)。 + 解冻期间如订单出现问题,可在"接单工单"或"售后问题单"中优先扣减本单待解冻金额。 @@ -636,6 +646,7 @@ export default function FinancePanel() { function mapFinanceConfigToFormValues(config?: WorkerFinanceConfig): FinanceConfigFormValues { return { depositUnfreezeDays: Number(config?.depositUnfreezeDays ?? 3), + rewardUnfreezeEnabled: config?.rewardUnfreezeEnabled !== false, recharge: { enabled: config?.recharge.enabled !== false, channelName: config?.recharge.channelName || '', diff --git a/apps/frontend/src/pages/admin/platform/AdminPlatformShopsPage.tsx b/apps/frontend/src/pages/admin/platform/AdminPlatformShopsPage.tsx index 1ee973c4..30c18eff 100644 --- a/apps/frontend/src/pages/admin/platform/AdminPlatformShopsPage.tsx +++ b/apps/frontend/src/pages/admin/platform/AdminPlatformShopsPage.tsx @@ -747,7 +747,7 @@ function ScheduledJobCard({ } > - 将有押金工单验收通过后进入待解冻的押金,在到期后自动转入可用余额(验收后 3 天到账)。 + 将验收报酬与押金一起进入待解冻,在到期后自动转入可用余额(默认验收后 3 天到账)。
diff --git a/apps/frontend/src/pages/worker/WorkerProfileMobileView.tsx b/apps/frontend/src/pages/worker/WorkerProfileMobileView.tsx index f67467d0..0b10b17f 100644 --- a/apps/frontend/src/pages/worker/WorkerProfileMobileView.tsx +++ b/apps/frontend/src/pages/worker/WorkerProfileMobileView.tsx @@ -189,7 +189,7 @@ export function WorkerProfileMobileView({
- +
diff --git a/apps/frontend/src/pages/worker/WorkerProfileRecords.tsx b/apps/frontend/src/pages/worker/WorkerProfileRecords.tsx index 28f466d2..189aff6b 100644 --- a/apps/frontend/src/pages/worker/WorkerProfileRecords.tsx +++ b/apps/frontend/src/pages/worker/WorkerProfileRecords.tsx @@ -29,7 +29,7 @@ const LEDGER_TYPE_OPTIONS = [ { value: 'withdraw_paid', label: '提现打款' }, { value: 'deposit_freeze', label: '冻结押金' }, { value: 'deposit_release', label: '释放押金' }, - { value: 'deposit_pending_unfreeze', label: '押金待解冻' }, + { value: 'deposit_pending_unfreeze', label: '待解冻金额' }, { value: 'deposit_unfreeze', label: '押金已解冻' }, { value: 'deposit_deduction', label: '扣除押金' }, { value: 'reward_settlement', label: '结算报酬' }, diff --git a/apps/frontend/src/pages/worker/worker-profile-view-utils.tsx b/apps/frontend/src/pages/worker/worker-profile-view-utils.tsx index 7a60f8c5..5d90639a 100644 --- a/apps/frontend/src/pages/worker/worker-profile-view-utils.tsx +++ b/apps/frontend/src/pages/worker/worker-profile-view-utils.tsx @@ -52,7 +52,7 @@ export function formatLedgerType(ledgerType: string) { withdraw_paid: '提现打款', deposit_freeze: '冻结押金', deposit_release: '释放押金', - deposit_pending_unfreeze: '押金待解冻', + deposit_pending_unfreeze: '待解冻金额', deposit_unfreeze: '押金已解冻', deposit_deduction: '扣除押金', reward_settlement: '结算报酬', diff --git a/apps/frontend/src/services/admin/worker-platform.ts b/apps/frontend/src/services/admin/worker-platform.ts index e82704d7..50cd5f4f 100644 --- a/apps/frontend/src/services/admin/worker-platform.ts +++ b/apps/frontend/src/services/admin/worker-platform.ts @@ -408,6 +408,7 @@ export function fetchAdminWorkerFinanceConfig() { export function saveAdminWorkerFinanceConfig(payload: { depositUnfreezeDays?: number + rewardUnfreezeEnabled?: boolean recharge?: { enabled?: boolean channelName?: string diff --git a/apps/frontend/src/types/worker-platform.ts b/apps/frontend/src/types/worker-platform.ts index 62d405e2..6ba2bbbd 100644 --- a/apps/frontend/src/types/worker-platform.ts +++ b/apps/frontend/src/types/worker-platform.ts @@ -200,6 +200,7 @@ export type WorkerAfterSalesCaseEvent = { export type WorkerFinanceConfig = { depositUnfreezeDays: number + rewardUnfreezeEnabled: boolean recharge: { enabled: boolean channelName: string