From 423672e47b6cffeedd39730110f28848a8aee325 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Wed, 9 Sep 2026 19:57:06 +0800 Subject: [PATCH] =?UTF-8?q?fix(distribution-admin):=20=E5=85=A8=E9=9D=A2?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=85=A8=E7=AB=99=E8=A1=A8=E6=A0=BC=E5=88=97?= =?UTF-8?q?=E5=AE=BD=E3=80=81=E5=8D=95=E5=8F=B7=E9=98=B2=E6=8A=98=E8=A1=8C?= =?UTF-8?q?=E3=80=81=E5=B9=B3=E5=8F=B0=E4=B8=8E=E7=8A=B6=E6=80=81=E4=B8=AD?= =?UTF-8?q?=E6=96=87=E5=8C=96=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- distribution-admin/src/pages/Accounts.tsx | 27 +++- distribution-admin/src/pages/Dashboard.tsx | 50 +++++-- distribution-admin/src/pages/Orders.tsx | 51 +++++++- distribution-admin/src/pages/Payments.tsx | 130 ++++++++++++++----- distribution-admin/src/pages/Rules.tsx | 2 + distribution-admin/src/pages/Settlements.tsx | 24 +++- distribution-admin/src/pages/Sites.tsx | 26 +++- distribution-admin/src/pages/Storefront.tsx | 26 +++- distribution-admin/src/pages/Wallet.tsx | 2 +- distribution-admin/src/style.css | 11 ++ 10 files changed, 292 insertions(+), 57 deletions(-) diff --git a/distribution-admin/src/pages/Accounts.tsx b/distribution-admin/src/pages/Accounts.tsx index da05caf..3ce7fda 100644 --- a/distribution-admin/src/pages/Accounts.tsx +++ b/distribution-admin/src/pages/Accounts.tsx @@ -94,9 +94,31 @@ function formatGameName(name?: string) { ) { return '三角洲' } + if (lower.includes('honor') || name.includes('王者')) { + return '王者荣耀' + } + if (lower.includes('genshin') || name.includes('原神')) { + return '原神' + } + if (lower.includes('cs') || lower.includes('csgo')) { + return 'CS2' + } return name } +function formatLoginPlatform(platform?: string): string { + if (!platform) return '' + const lower = platform.toLowerCase().trim() + if (lower === 'qq') return 'QQ' + if (lower === 'wechat' || lower === 'wx') return '微信' + if (lower === 'steam') return 'Steam' + if (lower === 'epic') return 'Epic' + if (lower === 'wegame') return 'WeGame' + if (lower === 'mobile') return '手游端' + if (lower === 'pc') return 'PC端' + return platform +} + export default function Accounts() { const member = useMember() const [sites, setSites] = useState([]) @@ -734,11 +756,12 @@ export default function Accounts() { {formatGameName(row.game_name)} {row.server_region && {row.server_region}} - {row.login_platform && {row.login_platform}} + {row.login_platform && {formatLoginPlatform(row.login_platform)}} ), diff --git a/distribution-admin/src/pages/Dashboard.tsx b/distribution-admin/src/pages/Dashboard.tsx index 9311d01..ba2fea9 100644 --- a/distribution-admin/src/pages/Dashboard.tsx +++ b/distribution-admin/src/pages/Dashboard.tsx @@ -47,6 +47,7 @@ const ORDER_STATUS_MAP: Record = { completed: { label: '已完成', color: 'success' }, refunded: { label: '已退款', color: 'purple' }, cancelled: { label: '已取消', color: 'default' }, + closed: { label: '已关闭', color: 'default' }, } const SETTLEMENT_STATUS_MAP: Record = { @@ -56,6 +57,8 @@ const SETTLEMENT_STATUS_MAP: Record = settling: { label: '结算中', color: 'processing' }, disputed: { label: '争议冻结', color: 'magenta' }, failed: { label: '结算异常', color: 'error' }, + arbitrated: { label: '已仲裁结算', color: 'purple' }, + closed: { label: '已关闭', color: 'default' }, } function formatGameName(gameName?: string): string { @@ -71,9 +74,31 @@ function formatGameName(gameName?: string): string { ) { return '三角洲' } + if (lower.includes('honor') || gameName.includes('王者')) { + return '王者荣耀' + } + if (lower.includes('genshin') || gameName.includes('原神')) { + return '原神' + } + if (lower.includes('cs') || lower.includes('csgo')) { + return 'CS2' + } return gameName } +function formatLoginPlatform(platform?: string): string { + if (!platform) return '' + const lower = platform.toLowerCase().trim() + if (lower === 'qq') return 'QQ' + if (lower === 'wechat' || lower === 'wx') return '微信' + if (lower === 'steam') return 'Steam' + if (lower === 'epic') return 'Epic' + if (lower === 'wegame') return 'WeGame' + if (lower === 'mobile') return '手游端' + if (lower === 'pc') return 'PC端' + return platform +} + export default function Dashboard() { const member = useMember() const [sites, setSites] = useState([]) @@ -270,26 +295,31 @@ export default function Dashboard() { rowKey="date" dataSource={analytics?.trend_days ?? []} pagination={false} + scroll={{ x: 720 }} columns={[ - { title: '日期', dataIndex: 'date', width: 140, render: (v: string) => {v} }, + { title: '日期', dataIndex: 'date', width: 130, render: (v: string) => {v} }, { title: '收号数量', dataIndex: 'received_count', + width: 120, render: (v: number) => 0 ? 'blue' : 'default'}>{v} 个, }, { title: '成交订单', dataIndex: 'order_count', + width: 120, render: (v: number) => 0 ? 'purple' : 'default'}>{v} 单, }, { title: '成交 GMV', dataIndex: 'gmv_cent', + width: 160, render: (v: number) => {formatMoney(v)}, }, { title: '预计分成收益', dataIndex: 'profit_cent', + width: 160, render: (v: number) => {formatMoney(v)}, }, ]} @@ -306,14 +336,14 @@ export default function Dashboard() { rowKey="order_id" dataSource={recentOrders} pagination={false} - scroll={{ x: 1050 }} + scroll={{ x: 1100 }} columns={[ { title: '订单与商品编号', - width: 260, + width: 280, render: (_: unknown, row: DistributionOrder) => ( -
-
+
+
{row.listing_no ? ( -
+
{row.game_name && {formatGameName(row.game_name)}} {row.server_region && {row.server_region}} - {row.login_platform && {row.login_platform}} + {row.login_platform && {formatLoginPlatform(row.login_platform)}}
), diff --git a/distribution-admin/src/pages/Orders.tsx b/distribution-admin/src/pages/Orders.tsx index 9ca39b0..99f9ca1 100644 --- a/distribution-admin/src/pages/Orders.tsx +++ b/distribution-admin/src/pages/Orders.tsx @@ -53,6 +53,7 @@ const ORDER_STATUS_MAP: Record = { completed: { label: '已完成', color: 'success' }, refunded: { label: '已退款', color: 'purple' }, cancelled: { label: '已取消', color: 'default' }, + closed: { label: '已关闭', color: 'default' }, } const SETTLEMENT_STATUS_MAP: Record = { @@ -62,10 +63,14 @@ const SETTLEMENT_STATUS_MAP: Record = settling: { label: '结算中', color: 'processing' }, disputed: { label: '争议冻结', color: 'magenta' }, failed: { label: '结算异常', color: 'error' }, + arbitrated: { label: '已仲裁结算', color: 'purple' }, + closed: { label: '已关闭', color: 'default' }, } const REFUND_STATUS_MAP: Record = { none: { label: '未退款', color: 'default' }, + pending: { label: '退款审核中', color: 'orange' }, + pending_review: { label: '待退款审核', color: 'orange' }, refunding: { label: '退款中', color: 'orange' }, refunded: { label: '已退押金/差额', color: 'blue' }, failed: { label: '退款失败', color: 'error' }, @@ -107,9 +112,31 @@ function formatGameName(gameName?: string): string { ) { return '三角洲' } + if (lower.includes('honor') || gameName.includes('王者')) { + return '王者荣耀' + } + if (lower.includes('genshin') || gameName.includes('原神')) { + return '原神' + } + if (lower.includes('cs') || lower.includes('csgo')) { + return 'CS2' + } return gameName } +function formatLoginPlatform(platform?: string): string { + if (!platform) return '' + const lower = platform.toLowerCase().trim() + if (lower === 'qq') return 'QQ' + if (lower === 'wechat' || lower === 'wx') return '微信' + if (lower === 'steam') return 'Steam' + if (lower === 'epic') return 'Epic' + if (lower === 'wegame') return 'WeGame' + if (lower === 'mobile') return '手游端' + if (lower === 'pc') return 'PC端' + return platform +} + export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) { const member = useMember() const [sites, setSites] = useState([]) @@ -337,7 +364,7 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) { {row.game_name && {formatGameName(row.game_name)}} {row.server_region && {row.server_region}} - {row.login_platform && {row.login_platform}} + {row.login_platform && {formatLoginPlatform(row.login_platform)}} {row.rent_duration_hours ? 租期: {row.rent_duration_hours}h : null}
@@ -589,7 +616,7 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) { {formatGameName(row.game_name)} {row.server_region && {row.server_region}} - {row.login_platform && {row.login_platform}} + {row.login_platform && {formatLoginPlatform(row.login_platform)}} {row.rank_level && {row.rank_level}}
@@ -865,13 +892,27 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) { { key: 'order_no', label: '订单编号', - children: {selectedOrder.order_no}, + children: ( + + {selectedOrder.order_no} + + ), }, { key: 'listing_no', label: '商品编号', children: selectedOrder.listing_no ? ( - + {selectedOrder.listing_no} ) : ( @@ -892,7 +933,7 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) { { key: 'platform', label: '登录平台', - children: selectedOrder.login_platform || '-', + children: formatLoginPlatform(selectedOrder.login_platform) || '-', }, { key: 'renter', diff --git a/distribution-admin/src/pages/Payments.tsx b/distribution-admin/src/pages/Payments.tsx index 0dc3618..2f98ab5 100644 --- a/distribution-admin/src/pages/Payments.tsx +++ b/distribution-admin/src/pages/Payments.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react' -import { Card, Table, Typography, Space, Select, Tag, InputNumber, Button, message } from 'antd' +import { Card, Table, Typography, Space, Select, Tag, InputNumber, Button, message, Modal } from 'antd' import { bindPaymentChannel, listPaymentChannels, listSites, unbindPaymentChannel, getMe, type PaymentChannel, type Site } from '../api' import { useMember } from '../MemberContext' @@ -71,49 +71,115 @@ export default function Payments() { } } - async function handleUnbind(id: number) { - try { - await unbindPaymentChannel(id) - message.success('已解绑') - if (siteID) void load(siteID) - } catch { - message.error('解绑失败') - } + async function handleUnbind(channel: PaymentChannel) { + Modal.confirm({ + title: '确认解绑该支付通道?', + content: `通道 ID: ${channel.config_id},解绑后该站点将无法继续使用此通道发起收款。`, + okText: '确认解绑', + okType: 'danger', + cancelText: '取消', + onOk: async () => { + try { + await unbindPaymentChannel(channel.id) + message.success('已成功解绑支付通道') + if (siteID) void load(siteID) + } catch { + message.error('解绑失败') + } + }, + }) } return ( - - 支付通道 - - {member?.is_superadmin && sites.length > 1 && ( - ({ label: `${site.site_name} (${site.site_code})`, value: site.id }))} + onChange={(value) => { + setSiteID(value) + void load(value) + }} + /> + )} + setConfigID(v ?? null)} /> - )} - setConfigID(v ?? null)} /> - setPriority(v ?? 0)} /> - - - + setPriority(v ?? 0)} + /> + + + + + {v === 'active' ? '正常生效' : (v || '已停用')} }, + { + title: '商户配置 ID', + dataIndex: 'config_id', + width: 160, + render: (v: number) => #{v}, + }, + { + title: '调度优先级', + dataIndex: 'priority', + width: 120, + render: (v: number) => {v}, + }, + { + title: '运行状态', + dataIndex: 'status', + width: 140, + render: (v: string) => ( + + {v === 'active' ? '正常生效' : v || '已停用'} + + ), + }, { title: '操作', - render: (_: unknown, row: PaymentChannel) => handleUnbind(row.id)}>解绑, + width: 100, + render: (_: unknown, row: PaymentChannel) => ( + + ), }, ]} /> diff --git a/distribution-admin/src/pages/Rules.tsx b/distribution-admin/src/pages/Rules.tsx index 5309845..d753de1 100644 --- a/distribution-admin/src/pages/Rules.tsx +++ b/distribution-admin/src/pages/Rules.tsx @@ -215,10 +215,12 @@ export default function Rules() { loading={loading} dataSource={rules} pagination={false} + scroll={{ x: 950 }} columns={[ { title: '业务交易模式', dataIndex: 'mode', + width: 280, render: (v: string) => (
{MODE_LABELS[v] ?? v} diff --git a/distribution-admin/src/pages/Settlements.tsx b/distribution-admin/src/pages/Settlements.tsx index 19387ad..0f5a6b6 100644 --- a/distribution-admin/src/pages/Settlements.tsx +++ b/distribution-admin/src/pages/Settlements.tsx @@ -227,8 +227,25 @@ export default function Settlements() { { title: '账单批次号', dataIndex: 'batch_no', - width: 200, - render: (v: string) => {v}, + width: 220, + render: (v: string) => ( +
+ + {v} + +
+ ), }, { title: '结算周期开始', @@ -354,11 +371,12 @@ export default function Settlements() { loading={itemsLoading} dataSource={items} pagination={false} + scroll={{ x: 550 }} columns={[ { title: '关联订单 ID', dataIndex: 'order_id', - render: (v: number) => 订单 #{v}, + render: (v: number) => 订单 #{v}, }, { title: '分润角色 / 收益类型', diff --git a/distribution-admin/src/pages/Sites.tsx b/distribution-admin/src/pages/Sites.tsx index 2cf1fd8..2615ad3 100644 --- a/distribution-admin/src/pages/Sites.tsx +++ b/distribution-admin/src/pages/Sites.tsx @@ -85,7 +85,7 @@ export default function Sites({ isSuperadmin = true }: { isSuperadmin?: boolean } return ( - +
@@ -108,10 +108,12 @@ export default function Sites({ isSuperadmin = true }: { isSuperadmin?: boolean dataSource={items} loading={loading} pagination={false} + scroll={{ x: 950 }} columns={[ { title: '站点名称', dataIndex: 'site_name', + width: 220, render: (v: string) => ( @@ -119,11 +121,26 @@ export default function Sites({ isSuperadmin = true }: { isSuperadmin?: boolean ), }, - { title: '站点标识', dataIndex: 'site_code', render: (v: string) => {v} }, - { title: '绑定域名', dataIndex: 'domain' }, + { + title: '站点标识', + dataIndex: 'site_code', + width: 140, + render: (v: string) => {v}, + }, + { + title: '绑定域名', + dataIndex: 'domain', + width: 220, + render: (v: string) => ( + + {v} + + ), + }, { title: '运行状态', dataIndex: 'status', + width: 110, render: (v: string) => ( {v === 'active' ? '正常运营' : v} @@ -133,16 +150,19 @@ export default function Sites({ isSuperadmin = true }: { isSuperadmin?: boolean { title: '账号展示', dataIndex: 'display_account_enabled', + width: 100, render: (v: boolean) => (v ? 开启 : 关闭), }, { title: '税费设定', + width: 110, render: (_: unknown, row: Site) => row.tax_enabled ? {row.tax_rate_bps / 100}% : 不征税, }, { title: '创建时间', dataIndex: 'created_at', + width: 140, render: (v: string) => (v ? new Date(v).toLocaleDateString() : '-'), }, ]} diff --git a/distribution-admin/src/pages/Storefront.tsx b/distribution-admin/src/pages/Storefront.tsx index ce3d029..5d0bf2e 100644 --- a/distribution-admin/src/pages/Storefront.tsx +++ b/distribution-admin/src/pages/Storefront.tsx @@ -48,9 +48,31 @@ function formatGameName(gameName?: string): string { ) { return '三角洲' } + if (lower.includes('honor') || gameName.includes('王者')) { + return '王者荣耀' + } + if (lower.includes('genshin') || gameName.includes('原神')) { + return '原神' + } + if (lower.includes('cs') || lower.includes('csgo')) { + return 'CS2' + } return gameName } +function formatLoginPlatform(platform?: string): string { + if (!platform) return '' + const lower = platform.toLowerCase().trim() + if (lower === 'qq') return 'QQ' + if (lower === 'wechat' || lower === 'wx') return '微信' + if (lower === 'steam') return 'Steam' + if (lower === 'epic') return 'Epic' + if (lower === 'wegame') return 'WeGame' + if (lower === 'mobile') return '手游端' + if (lower === 'pc') return 'PC端' + return platform +} + export default function Storefront() { const { siteCode = 'demo' } = useParams<{ siteCode: string }>() const [loading, setLoading] = useState(true) @@ -370,7 +392,7 @@ export default function Storefront() { )} {item.login_platform && ( - {item.login_platform} + {formatLoginPlatform(item.login_platform)} )} {item.rank_level && ( @@ -465,7 +487,7 @@ export default function Storefront() { {formatGameName(selectedListing.game_name)} {selectedListing.server_region || '全区通用'} - {selectedListing.login_platform || 'PC端'} + {formatLoginPlatform(selectedListing.login_platform) || 'PC端'} {selectedListing.rank_level || '暂未定级'} {selectedListing.haf_coin_amount > 0 diff --git a/distribution-admin/src/pages/Wallet.tsx b/distribution-admin/src/pages/Wallet.tsx index 2583af2..968390f 100644 --- a/distribution-admin/src/pages/Wallet.tsx +++ b/distribution-admin/src/pages/Wallet.tsx @@ -316,7 +316,7 @@ export default function Wallet() { }, { title: '审核 / 付款备注', - minWidth: 160, + width: 180, render: (_: unknown, row: SiteWithdrawal) => (
{row.review_remark && ( diff --git a/distribution-admin/src/style.css b/distribution-admin/src/style.css index b43437d..2b5382f 100644 --- a/distribution-admin/src/style.css +++ b/distribution-admin/src/style.css @@ -149,6 +149,17 @@ body, align-items: center !important; vertical-align: middle !important; margin-inline-start: 4px !important; + flex-shrink: 0 !important; +} + +.ant-typography { + word-break: keep-all; +} + +.mono-code { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !important; + white-space: nowrap !important; + word-break: keep-all !important; } .stats {