展示打手提现统计

This commit is contained in:
yml2213
2026-08-21 00:05:04 +08:00
parent 361b84931f
commit 2fbfaa0143
7 changed files with 63 additions and 2 deletions
@@ -0,0 +1,4 @@
-- 支持资金申请列表按打手快速统计提现次数和已提现金额。
CREATE INDEX IF NOT EXISTS idx_worker_finance_requests_worker_withdraw_stats
ON worker_finance_requests(worker_id, request_type)
INCLUDE (status, amount);
@@ -154,6 +154,11 @@ export type WorkerFinanceRequestRow = {
worker_username?: string
worker_display_name?: string
worker_phone?: string
worker_type?: string
worker_level_key?: string
worker_level_name?: string
worker_withdraw_request_count?: number
worker_total_withdraw_amount?: number
}
export type WorkerWithdrawalAccountRow = {
@@ -39,9 +39,23 @@ const WORKER_FINANCE_REQUEST_SELECT = `
wfr.*,
wu.username AS worker_username,
wu.display_name AS worker_display_name,
wu.phone AS worker_phone
wu.phone AS worker_phone,
wu.worker_type,
wl.level_key AS worker_level_key,
wl.name AS worker_level_name,
withdraw_stats.withdraw_request_count AS worker_withdraw_request_count,
withdraw_stats.total_withdraw_amount AS worker_total_withdraw_amount
FROM worker_finance_requests wfr
LEFT JOIN worker_users wu ON wu.id = wfr.worker_id
LEFT JOIN worker_levels wl ON wl.id = wu.level_id
LEFT JOIN LATERAL (
SELECT
COUNT(*)::int AS withdraw_request_count,
COALESCE(SUM(amount) FILTER (WHERE status = 'approved'), 0)::bigint AS total_withdraw_amount
FROM worker_finance_requests history_request
WHERE history_request.worker_id = wfr.worker_id
AND history_request.request_type = 'withdraw'
) withdraw_stats ON TRUE
`
export type CreateWorkerSessionInput = {
@@ -392,6 +392,11 @@ export function mapFinanceRequest(request: WorkerFinanceRequestRow | null | unde
username: request.worker_username || '',
displayName: request.worker_display_name || request.worker_username || '',
phone: request.worker_phone || '',
workerType: normalizeWorkerType(request.worker_type),
levelKey: request.worker_level_key || '',
levelName: request.worker_level_name || '',
withdrawRequestCount: Number(request.worker_withdraw_request_count || 0),
totalWithdrawAmount: Number(request.worker_total_withdraw_amount || 0),
}
: null,
}
@@ -525,6 +525,11 @@ test('支付宝提现申请保留收款二维码快照', () => {
created_at: '2026-08-20T00:00:00.000Z',
updated_at: '2026-08-20T00:00:00.000Z',
reviewed_at: null,
worker_type: 'internal',
worker_level_key: 'vip5',
worker_level_name: 'VIP5',
worker_withdraw_request_count: 3,
worker_total_withdraw_amount: 28_800,
}
const mapped = mapFinanceRequest(request)
@@ -532,6 +537,17 @@ test('支付宝提现申请保留收款二维码快照', () => {
(mapped?.payload.alipayQrCodeImage as { url?: string }).url,
'https://example.com/alipay-qr.png',
)
assert.deepEqual(mapped?.worker, {
workerId: 1,
username: '',
displayName: '',
phone: '',
workerType: 'internal',
levelKey: 'vip5',
levelName: 'VIP5',
withdrawRequestCount: 3,
totalWithdrawAmount: 28_800,
})
})
test('提现渠道仅支持支付宝和微信', () => {
@@ -201,13 +201,25 @@ export default function FinancePanel() {
const requestColumns: TableColumnsType<WorkerFinanceRequest> = [
{
title: '打手',
minWidth: 180,
minWidth: 250,
render: (_, row) => (
<div className="cell-stack">
<Typography.Text strong>
{row.worker?.displayName || row.worker?.username || '-'}
</Typography.Text>
<Typography.Text type="secondary">{row.worker?.username || '-'}</Typography.Text>
{row.worker ? (
<Space size={[4, 4]} wrap>
<Tag color={row.worker.workerType === 'internal' ? 'blue' : 'default'}>
{row.worker.workerType === 'internal' ? '内部打手' : '外部打手'}
</Tag>
<Tag>{row.worker.levelName || row.worker.levelKey || '未分级'}</Tag>
<Typography.Text type="secondary">
{row.worker.withdrawRequestCount}
{formatMoney(row.worker.totalWithdrawAmount)}
</Typography.Text>
</Space>
) : null}
</div>
),
},
@@ -99,6 +99,11 @@ export type WorkerFinanceRequest = {
username: string
displayName: string
phone: string
workerType: 'internal' | 'external'
levelKey: string
levelName: string
withdrawRequestCount: number
totalWithdrawAmount: number
}
}