diff --git a/apps/backend/src/services/cost-center/platform-credit-service.ts b/apps/backend/src/services/cost-center/platform-credit-service.ts index 0a90c3ae..2278c679 100644 --- a/apps/backend/src/services/cost-center/platform-credit-service.ts +++ b/apps/backend/src/services/cost-center/platform-credit-service.ts @@ -90,6 +90,11 @@ export async function listPlatformCreditAccounts(session: AdminSession) { clauses.push(`pca.owner_admin_user_id = $${params.length}`) } + // 客服第一次进来时补建三个空账户,保证四个钱包始终并列展示。 + if (!isPrivileged(session)) { + await ensurePlatformCreditAccounts(session.userId) + } + const where = clauses.length > 0 ? `AND ${clauses.join(' AND ')}` : '' const result = await query( ` diff --git a/apps/frontend/src/layouts/AdminLayout.tsx b/apps/frontend/src/layouts/AdminLayout.tsx index baf0ced4..a041b7c3 100644 --- a/apps/frontend/src/layouts/AdminLayout.tsx +++ b/apps/frontend/src/layouts/AdminLayout.tsx @@ -145,7 +145,7 @@ export default function AdminLayout() { { key: '/admin/fund', icon: , - label: role === 'support' ? '我的备用金' : '备用金', + label: role === 'support' ? '我的钱包' : '备用金', }, ...(role === 'support' ? [] diff --git a/apps/frontend/src/pages/admin/fund/FundSupportView.tsx b/apps/frontend/src/pages/admin/fund/FundSupportView.tsx index 952a62ef..25576884 100644 --- a/apps/frontend/src/pages/admin/fund/FundSupportView.tsx +++ b/apps/frontend/src/pages/admin/fund/FundSupportView.tsx @@ -34,16 +34,18 @@ import { createAdminFundExpense, createAdminFundReturn, fetchAdminFundMyAccount, + fetchAdminPlatformCreditAccounts, + fetchAdminPlatformCreditEntries, } from '@/services/admin' import type { AdminFundEntry, AdminFundExpense, AdminFundExpenseCategory, AdminFundPayeeType, + PlatformCreditEntry, } from '@/types/admin' import type { UploadedFile } from '@/types/worker-platform' import { formatAdminDateTime } from '@/utils/admin-time' -import { PlatformCreditPanel } from './PlatformCreditPanel' import { FUND_ACCOUNT_STATUS_LABELS, FUND_CATEGORY_LABELS, @@ -94,11 +96,36 @@ export default function FundSupportView() { const entries = data?.entries || [] const expenses = data?.expenses || [] + const creditAccountsQuery = useQuery({ + queryKey: ['admin-platform-credit-accounts'], + queryFn: fetchAdminPlatformCreditAccounts, + }) + const creditEntriesQuery = useQuery({ + queryKey: ['admin-platform-credit-entries', 'mine'], + queryFn: () => fetchAdminPlatformCreditEntries({ pageSize: 50 }), + }) + const creditAccounts = creditAccountsQuery.data?.data.items || [] + const creditEntries = creditEntriesQuery.data?.data.items || [] + const creditPlatforms = creditAccountsQuery.data?.data.platforms || [] + + /** 客服自己的三个积分钱包,按平台顺序排好。 */ + const myCreditWallets = creditPlatforms.map((platform) => { + const found = creditAccounts.find((item) => item.platformKey === platform.key) + return { + platform, + balanceQuantity: found?.balanceQuantity ?? 0, + balanceAmountFen: found?.balanceAmountFen ?? 0, + unitName: found?.unitName ?? '积分', + } + }) + function refresh() { void queryClient.invalidateQueries({ queryKey: ['admin-fund-my'] }) void queryClient.invalidateQueries({ queryKey: ['admin-fund-overview'] }) void queryClient.invalidateQueries({ queryKey: ['admin-fund-accounts'] }) void queryClient.invalidateQueries({ queryKey: ['admin-fund-expenses'] }) + void queryClient.invalidateQueries({ queryKey: ['admin-platform-credit-accounts'] }) + void queryClient.invalidateQueries({ queryKey: ['admin-platform-credit-entries'] }) } function openExpense() { @@ -216,6 +243,71 @@ export default function FundSupportView() { }, ] + const creditEntryColumns: TableColumnsType = [ + { + title: '平台', + dataIndex: 'platformKey', + width: 100, + render: (value: string, row) => ( + + {row.platformLabel} + + ), + }, + { + title: '类型', + dataIndex: 'entryType', + width: 80, + render: (value: string) => ( + + {value === 'grant' + ? '充值' + : value === 'consume' + ? '消耗' + : value === 'return' + ? '退回' + : '调整'} + + ), + }, + { + title: '变动', + dataIndex: 'quantityDelta', + width: 100, + align: 'right', + render: (value: number) => + value > 0 ? ( + +{value} + ) : ( + {value} + ), + }, + { + title: '余额', + dataIndex: 'balanceAfter', + width: 100, + align: 'right', + }, + { + title: '折合金额', + dataIndex: 'amountFen', + width: 110, + align: 'right', + render: (value: number) => `¥${(Number(value || 0) / 100).toFixed(2)}`, + }, + { + title: '备注', + dataIndex: 'note', + render: (value: string) => value || '-', + }, + { + title: '时间', + dataIndex: 'createdAt', + width: 150, + render: (value: string) => formatAdminDateTime(value), + }, + ] + const expenseColumns: TableColumnsType = [ { title: '付款时间', @@ -281,10 +373,14 @@ export default function FundSupportView() { return (
} loading={myQuery.isFetching} onClick={refresh}> + } @@ -303,124 +399,135 @@ export default function FundSupportView() { type="warning" showIcon message="还没有备用金账户" - description="请联系主管或管理员为你开通客服备用金账户。" + description="请联系主管或管理员为你开通客服备用金账户。平台积分钱包不受影响,可直接使用。" /> ) : null} - {account ? ( - <> - - - - - - - - - - - - - - - - - - - - - - - + + {myCreditWallets.map((wallet) => ( + + + + {wallet.platform.label} + = 100 ? 'cyan' : 'blue'}> + 1积分= + {wallet.platform.creditUnitPriceFen >= 100 ? '1元' : '1分'} + + + } + value={wallet.balanceQuantity} + suffix="积分" + valueStyle={{ + color: wallet.balanceQuantity > 0 ? undefined : '#999', + }} + /> + + 折合 ¥{(wallet.balanceAmountFen / 100).toFixed(2)} + + + + ))} + - - {account.accountNo} - - {account.responsibleSupervisorName || '-'} - - - {FUND_ACCOUNT_STATUS_LABELS[account.status] || account.status} - - - {account.lastEntryAt ? formatAdminDateTime(account.lastEntryAt) : '-'} - - - - - - - - - - - - rowKey="id" - size="small" - columns={entryColumns} - dataSource={entries} - pagination={false} - scroll={{ x: 900 }} - /> - ), - }, - { - key: 'expenses', - label: '我的支出', - children: ( - - rowKey="id" - size="small" - columns={expenseColumns} - dataSource={expenses} - pagination={false} - scroll={{ x: 1100 }} - /> - ), - }, - { - key: 'platform-credits', - label: '平台积分', - children: , - }, - ]} + 0 ? undefined : '#999', + }} /> + + {account + ? `本月发放 ¥${(account.monthInFen / 100).toFixed(2)} · 支出/缴回 ¥${(account.monthOutFen / 100).toFixed(2)}` + : '尚未开通备用金账户'} + - + + + + {account ? ( + + + {account.accountNo} + + {account.responsibleSupervisorName || '-'} + + + {FUND_ACCOUNT_STATUS_LABELS[account.status] || account.status} + + + {account.lastEntryAt ? formatAdminDateTime(account.lastEntryAt) : '-'} + + + + + + + + ) : null} + + + rowKey="id" + size="small" + columns={creditEntryColumns} + dataSource={creditEntries} + loading={creditEntriesQuery.isLoading} + pagination={false} + scroll={{ x: 900 }} + locale={{ emptyText: '还没有积分流水' }} + /> + ), + }, + { + key: 'entries', + label: '备用金流水', + children: ( + + rowKey="id" + size="small" + columns={entryColumns} + dataSource={entries} + pagination={false} + scroll={{ x: 900 }} + locale={{ emptyText: '还没有备用金流水' }} + /> + ), + }, + { + key: 'expenses', + label: '我的支出', + children: ( + + rowKey="id" + size="small" + columns={expenseColumns} + dataSource={expenses} + pagination={false} + scroll={{ x: 1100 }} + locale={{ emptyText: '还没有支出记录' }} + /> + ), + }, + ]} + /> + +