From 48fcdbff077f5989df62ba265df42d58d478f1a1 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Tue, 1 Sep 2026 14:44:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=89=93=E6=89=8B=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E4=BF=A1=E6=81=AF=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/admin/panels/WorkerDetailDrawer.tsx | 19 +- worker-detail-artifacts/DIFF_FILE.patch | 65 +++ worker-detail-artifacts/MODIFIED_FILE.tsx | 438 ++++++++++++++++++ worker-detail-artifacts/ROLLBACK.sh | 8 + worker-detail-artifacts/VERIFICATION.txt | 31 ++ 5 files changed, 558 insertions(+), 3 deletions(-) create mode 100644 worker-detail-artifacts/DIFF_FILE.patch create mode 100644 worker-detail-artifacts/MODIFIED_FILE.tsx create mode 100755 worker-detail-artifacts/ROLLBACK.sh create mode 100644 worker-detail-artifacts/VERIFICATION.txt diff --git a/apps/frontend/src/pages/admin/panels/WorkerDetailDrawer.tsx b/apps/frontend/src/pages/admin/panels/WorkerDetailDrawer.tsx index c184b61a..c3074a6a 100644 --- a/apps/frontend/src/pages/admin/panels/WorkerDetailDrawer.tsx +++ b/apps/frontend/src/pages/admin/panels/WorkerDetailDrawer.tsx @@ -95,7 +95,7 @@ export default function WorkerDetailDrawer({ return ( row.relatedPlatformOrderId || row.relatedWorkOrderId || '-', + render: (_, row) => { + const orderNo = String(row.relatedPlatformOrderId || row.relatedWorkOrderId || '-').trim() + return ( + + {orderNo} + + ) + }, }, { title: '说明', @@ -353,6 +361,7 @@ function LedgersSection({ workerId }: { workerId: number }) { columns={columns} dataSource={data?.items || []} loading={ledgersQuery.isFetching} + scroll={{ x: 1020 }} pagination={buildAdminTablePagination({ page, pageSize: ADMIN_DEFAULT_PAGE_SIZE, @@ -377,7 +386,10 @@ function OrdersSection({ workerId }: { workerId: number }) { title: '平台单号', width: 160, ellipsis: true, - render: (_, row) => row.platformOrderId || row.workOrderNo || row.workOrderId, + render: (_, row) => { + const orderNo = String(row.platformOrderId || row.workOrderNo || row.workOrderId).trim() + return {orderNo} + }, }, { title: '商品', @@ -414,6 +426,7 @@ function OrdersSection({ workerId }: { workerId: number }) { columns={columns} dataSource={data?.items || []} loading={ordersQuery.isFetching} + scroll={{ x: 900 }} pagination={buildAdminTablePagination({ page, pageSize: ADMIN_DEFAULT_PAGE_SIZE, diff --git a/worker-detail-artifacts/DIFF_FILE.patch b/worker-detail-artifacts/DIFF_FILE.patch new file mode 100644 index 00000000..eaf8f380 --- /dev/null +++ b/worker-detail-artifacts/DIFF_FILE.patch @@ -0,0 +1,65 @@ +diff --git a/apps/frontend/src/pages/admin/panels/WorkerDetailDrawer.tsx b/apps/frontend/src/pages/admin/panels/WorkerDetailDrawer.tsx +index c184b61a..c3074a6a 100644 +--- a/apps/frontend/src/pages/admin/panels/WorkerDetailDrawer.tsx ++++ b/apps/frontend/src/pages/admin/panels/WorkerDetailDrawer.tsx +@@ -95,7 +95,7 @@ export default function WorkerDetailDrawer({ + return ( + row.relatedPlatformOrderId || row.relatedWorkOrderId || '-', ++ render: (_, row) => { ++ const orderNo = String(row.relatedPlatformOrderId || row.relatedWorkOrderId || '-').trim() ++ return ( ++ ++ {orderNo} ++ ++ ) ++ }, + }, + { + title: '说明', +@@ -353,6 +361,7 @@ function LedgersSection({ workerId }: { workerId: number }) { + columns={columns} + dataSource={data?.items || []} + loading={ledgersQuery.isFetching} ++ scroll={{ x: 1020 }} + pagination={buildAdminTablePagination({ + page, + pageSize: ADMIN_DEFAULT_PAGE_SIZE, +@@ -377,7 +386,10 @@ function OrdersSection({ workerId }: { workerId: number }) { + title: '平台单号', + width: 160, + ellipsis: true, +- render: (_, row) => row.platformOrderId || row.workOrderNo || row.workOrderId, ++ render: (_, row) => { ++ const orderNo = String(row.platformOrderId || row.workOrderNo || row.workOrderId).trim() ++ return {orderNo} ++ }, + }, + { + title: '商品', +@@ -414,6 +426,7 @@ function OrdersSection({ workerId }: { workerId: number }) { + columns={columns} + dataSource={data?.items || []} + loading={ordersQuery.isFetching} ++ scroll={{ x: 900 }} + pagination={buildAdminTablePagination({ + page, + pageSize: ADMIN_DEFAULT_PAGE_SIZE, diff --git a/worker-detail-artifacts/MODIFIED_FILE.tsx b/worker-detail-artifacts/MODIFIED_FILE.tsx new file mode 100644 index 00000000..c3074a6a --- /dev/null +++ b/worker-detail-artifacts/MODIFIED_FILE.tsx @@ -0,0 +1,438 @@ +import { useState } from 'react' +import { Card, Descriptions, Drawer, Select, Space, Table, Tabs, Tag, Typography } from 'antd' +import type { TableColumnsType } from 'antd' +import { useQuery } from '@tanstack/react-query' + +import { + fetchAdminWorkOrders, + fetchAdminWorkerDetail, + fetchAdminWorkerDepositUnfreezes, + fetchAdminWorkerWalletLedgers, +} from '@/services/admin' +import { ADMIN_DEFAULT_PAGE_SIZE, buildAdminTablePagination } from '@/utils/admin-pagination' +import { formatAdminDateTime } from '@/utils/admin-time' +import type { + WorkOrder, + WorkerDepositUnfreeze, + WorkerUser, + WorkerWalletLedger, +} from '@/types/worker-platform' +import { formatMoney, formatStatus, formatWorkerStatus, resolveStatusColor } from './shared' + +/** 与打手端 worker-profile-view-utils 的流水文案保持一致;未知类型原样展示。 */ +const LEDGER_TYPE_LABELS: Record = { + manual_credit: '人工充值', + withdraw_freeze: '提现冻结', + withdraw_paid: '提现打款', + withdraw_release: '提现退回', + deposit_freeze: '冻结押金', + deposit_release: '释放押金', + deposit_pending_unfreeze: '待解冻金额', + reward_pending_unfreeze: '报酬待解冻', + deposit_unfreeze: '押金已解冻', + reward_unfreeze: '报酬已解冻', + deposit_deduction: '扣除押金', + reward_settlement: '结算报酬', + sharing_reward: '拼单报酬', + after_sales_deposit_deduction: '售后扣减押金', + after_sales_balance_deduction: '售后扣减余额', + after_sales_debt_offset: '抵扣售后欠款', + after_sales_refund: '售后追缴退还', +} + +function formatLedgerType(ledgerType: string) { + return LEDGER_TYPE_LABELS[ledgerType] || ledgerType || '-' +} + +function resolveLedgerTagColor(ledgerType: string) { + if ( + [ + 'deposit_freeze', + 'deposit_pending_unfreeze', + 'reward_pending_unfreeze', + 'after_sales_debt_offset', + ].includes(ledgerType) + ) + return 'gold' + if ( + ['deposit_release', 'deposit_unfreeze', 'reward_unfreeze', 'after_sales_refund'].includes( + ledgerType, + ) + ) + return 'green' + if ( + [ + 'deposit_deduction', + 'after_sales_deposit_deduction', + 'after_sales_balance_deduction', + ].includes(ledgerType) + ) + return 'red' + if (['reward_settlement', 'sharing_reward'].includes(ledgerType)) return 'cyan' + if (ledgerType === 'manual_credit') return 'blue' + if (ledgerType === 'withdraw_freeze') return 'orange' + if (ledgerType === 'withdraw_paid') return 'purple' + if (ledgerType === 'withdraw_release') return 'green' + return 'default' +} + +function formatUnfreezeStatus(status: string) { + if (status === 'pending') return { label: '待解冻', color: 'orange' } + if (status === 'released') return { label: '已到账', color: 'green' } + if (status === 'deducted') return { label: '已扣减', color: 'red' } + return { label: status || '-', color: 'default' } +} + +export default function WorkerDetailDrawer({ + worker, + onClose, +}: { + worker: WorkerUser | null + onClose: () => void +}) { + const workerId = worker?.workerId || 0 + + return ( + + {worker.displayName || worker.username} + + {worker.workerType === 'internal' ? '内部' : '外部'} + + + {formatWorkerStatus(worker.status)} + + + ) : null + } + > + }, + { + key: 'unfreezes', + label: '待解冻', + children: , + }, + { + key: 'ledgers', + label: '资金流水', + children: , + }, + { key: 'orders', label: '他的订单', children: }, + ]} + /> + + ) +} + +function OverviewSection({ workerId }: { workerId: number }) { + const detailQuery = useQuery({ + queryKey: ['admin-worker-detail', workerId], + queryFn: () => fetchAdminWorkerDetail(workerId), + enabled: workerId > 0, + }) + const detail = detailQuery.data?.data + if (!workerId) return null + if (!detail) { + return 加载中… + } + const { worker, summary, orderOverview } = detail + return ( +
+ + + {worker.displayName || '-'} + {worker.username} + {worker.phone || '-'} + {worker.level?.name || '-'} + + {worker.inviter ? `${worker.inviter.displayName || worker.inviter.username}` : '-'} + + + {formatAdminDateTime(worker.createdAt)} + + + + + + + {formatMoney(worker.wallet.availableAmount)} + + + {formatMoney(worker.wallet.frozenDepositAmount)} + + + {formatMoney(worker.wallet.pendingUnfreezeAmount)} + + + {formatMoney(worker.wallet.totalCreditedAmount)} + + + {formatMoney(worker.wallet.totalSettledAmount)} + + + + + + {summary.activeOrderCount} + {summary.acceptedOrderCount} + + {summary.timeoutOrderCount > 0 ? {summary.timeoutOrderCount} : 0} + + + + + {orderOverview.length === 0 ? ( + 暂无订单 + ) : ( + + {orderOverview.map((item) => ( + + {formatStatus(item.status)} {item.orderCount} 单 /{' '} + {formatMoney(item.settlementAmount)} + + ))} + + )} + +
+ ) +} + +function UnfreezesSection({ workerId }: { workerId: number }) { + const [page, setPage] = useState(1) + const unfreezesQuery = useQuery({ + queryKey: ['admin-worker-detail-unfreezes', workerId, page], + queryFn: () => + fetchAdminWorkerDepositUnfreezes(workerId, { page, pageSize: ADMIN_DEFAULT_PAGE_SIZE }), + enabled: workerId > 0, + }) + const data = unfreezesQuery.data?.data + const columns: TableColumnsType = [ + { + title: '资金类型', + width: 110, + render: (_, row) => { + const labels: Record = { + deposit: '押金', + reward: '报酬', + legacy_combined: '历史合并', + } + return {labels[row.fundType] || row.fundType} + }, + }, + { + title: '金额', + width: 110, + render: (_, row) => formatMoney(row.amount), + }, + { + title: '状态', + width: 100, + render: (_, row) => { + const status = formatUnfreezeStatus(row.status) + return {status.label} + }, + }, + { + title: '到期时间', + width: 170, + render: (_, row) => formatAdminDateTime(row.unfreezeAt), + }, + { + title: '到账时间', + width: 170, + render: (_, row) => (row.releasedAt ? formatAdminDateTime(row.releasedAt) : '-'), + }, + { title: '关联工单', dataIndex: 'workOrderId', width: 100 }, + { + title: '创建时间', + width: 170, + render: (_, row) => formatAdminDateTime(row.createdAt), + }, + ] + return ( + + rowKey="id" + size="small" + columns={columns} + dataSource={data?.items || []} + loading={unfreezesQuery.isFetching} + scroll={{ x: 930 }} + pagination={buildAdminTablePagination({ + page, + pageSize: ADMIN_DEFAULT_PAGE_SIZE, + total: data?.pagination.total || 0, + onChange: setPage, + })} + /> + ) +} + +function LedgersSection({ workerId }: { workerId: number }) { + const [page, setPage] = useState(1) + const [ledgerType, setLedgerType] = useState('') + const ledgersQuery = useQuery({ + queryKey: ['admin-worker-detail-ledgers', workerId, page, ledgerType], + queryFn: () => + fetchAdminWorkerWalletLedgers(workerId, { + page, + pageSize: ADMIN_DEFAULT_PAGE_SIZE, + ledgerType: ledgerType || undefined, + }), + enabled: workerId > 0, + }) + const data = ledgersQuery.data?.data + const columns: TableColumnsType = [ + { + title: '类型', + width: 130, + render: (_, row) => ( + {formatLedgerType(row.ledgerType)} + ), + }, + { + title: '金额', + width: 110, + render: (_, row) => ( + = 0 ? 'success' : 'danger'}> + {row.amount >= 0 ? '+' : '-'} + {formatMoney(Math.abs(row.amount))} + + ), + }, + { + title: '变动后余额', + width: 110, + render: (_, row) => formatMoney(row.balanceAfter), + }, + { + title: '冻结金额', + width: 110, + render: (_, row) => formatMoney(row.frozenAfter), + }, + { + title: '关联订单', + width: 150, + render: (_, row) => { + const orderNo = String(row.relatedPlatformOrderId || row.relatedWorkOrderId || '-').trim() + return ( + + {orderNo} + + ) + }, + }, + { + title: '说明', + ellipsis: true, + render: (_, row) => row.note || '-', + }, + { + title: '时间', + width: 170, + render: (_, row) => formatAdminDateTime(row.createdAt), + }, + ] + return ( +
+