fix(distribution-admin): 全面优化全站表格列宽、单号防折行、平台与状态中文化体验
This commit is contained in:
@@ -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<Site[]>([])
|
||||
@@ -734,11 +756,12 @@ export default function Accounts() {
|
||||
<Typography.Text
|
||||
copyable={{ text: v || String(row.listing_id), tooltips: ['复制商品编号', '已复制'] }}
|
||||
strong
|
||||
className="mono-code"
|
||||
style={{
|
||||
fontSize: 13,
|
||||
color: '#1677ff',
|
||||
fontFamily: 'monospace',
|
||||
whiteSpace: 'nowrap',
|
||||
wordBreak: 'keep-all',
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
@@ -801,7 +824,7 @@ export default function Accounts() {
|
||||
<Space size={4} style={{ marginTop: 4 }} wrap>
|
||||
<Tag color="blue">{formatGameName(row.game_name)}</Tag>
|
||||
{row.server_region && <Tag>{row.server_region}</Tag>}
|
||||
{row.login_platform && <Tag color="cyan">{row.login_platform}</Tag>}
|
||||
{row.login_platform && <Tag color="cyan">{formatLoginPlatform(row.login_platform)}</Tag>}
|
||||
</Space>
|
||||
</div>
|
||||
),
|
||||
|
||||
@@ -47,6 +47,7 @@ const ORDER_STATUS_MAP: Record<string, { label: string; color: string }> = {
|
||||
completed: { label: '已完成', color: 'success' },
|
||||
refunded: { label: '已退款', color: 'purple' },
|
||||
cancelled: { label: '已取消', color: 'default' },
|
||||
closed: { label: '已关闭', color: 'default' },
|
||||
}
|
||||
|
||||
const SETTLEMENT_STATUS_MAP: Record<string, { label: string; color: string }> = {
|
||||
@@ -56,6 +57,8 @@ const SETTLEMENT_STATUS_MAP: Record<string, { label: string; color: string }> =
|
||||
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<Site[]>([])
|
||||
@@ -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) => <strong>{v}</strong> },
|
||||
{ title: '日期', dataIndex: 'date', width: 130, render: (v: string) => <strong>{v}</strong> },
|
||||
{
|
||||
title: '收号数量',
|
||||
dataIndex: 'received_count',
|
||||
width: 120,
|
||||
render: (v: number) => <Tag color={v > 0 ? 'blue' : 'default'}>{v} 个</Tag>,
|
||||
},
|
||||
{
|
||||
title: '成交订单',
|
||||
dataIndex: 'order_count',
|
||||
width: 120,
|
||||
render: (v: number) => <Tag color={v > 0 ? 'purple' : 'default'}>{v} 单</Tag>,
|
||||
},
|
||||
{
|
||||
title: '成交 GMV',
|
||||
dataIndex: 'gmv_cent',
|
||||
width: 160,
|
||||
render: (v: number) => <span style={{ color: '#cf1322', fontWeight: 'bold' }}>{formatMoney(v)}</span>,
|
||||
},
|
||||
{
|
||||
title: '预计分成收益',
|
||||
dataIndex: 'profit_cent',
|
||||
width: 160,
|
||||
render: (v: number) => <span style={{ color: '#52c41a', fontWeight: 'bold' }}>{formatMoney(v)}</span>,
|
||||
},
|
||||
]}
|
||||
@@ -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) => (
|
||||
<div style={{ whiteSpace: 'nowrap' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', whiteSpace: 'nowrap', marginBottom: 4 }}>
|
||||
<div style={{ whiteSpace: 'nowrap', display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
<div style={{ display: 'inline-flex', alignItems: 'center', whiteSpace: 'nowrap' }}>
|
||||
<Tag
|
||||
color="default"
|
||||
style={{
|
||||
@@ -330,10 +360,11 @@ export default function Dashboard() {
|
||||
<Typography.Text
|
||||
copyable={{ text: row.order_no, tooltips: ['复制订单号', '已复制'] }}
|
||||
strong
|
||||
className="mono-code"
|
||||
style={{
|
||||
fontSize: 13,
|
||||
fontFamily: 'monospace',
|
||||
whiteSpace: 'nowrap',
|
||||
wordBreak: 'keep-all',
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
@@ -342,7 +373,7 @@ export default function Dashboard() {
|
||||
</Typography.Text>
|
||||
</div>
|
||||
{row.listing_no ? (
|
||||
<div style={{ display: 'flex', alignItems: 'center', whiteSpace: 'nowrap' }}>
|
||||
<div style={{ display: 'inline-flex', alignItems: 'center', whiteSpace: 'nowrap' }}>
|
||||
<Tag
|
||||
color="blue"
|
||||
style={{
|
||||
@@ -358,12 +389,13 @@ export default function Dashboard() {
|
||||
</Tag>
|
||||
<Typography.Text
|
||||
copyable={{ text: row.listing_no, tooltips: ['复制商品编号', '已复制'] }}
|
||||
className="mono-code"
|
||||
style={{
|
||||
fontSize: 13,
|
||||
color: '#1677ff',
|
||||
fontWeight: 600,
|
||||
fontFamily: 'monospace',
|
||||
whiteSpace: 'nowrap',
|
||||
wordBreak: 'keep-all',
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
@@ -390,7 +422,7 @@ export default function Dashboard() {
|
||||
<Space size={4} style={{ marginTop: 4 }} wrap>
|
||||
{row.game_name && <Tag color="blue">{formatGameName(row.game_name)}</Tag>}
|
||||
{row.server_region && <Tag>{row.server_region}</Tag>}
|
||||
{row.login_platform && <Tag color="cyan">{row.login_platform}</Tag>}
|
||||
{row.login_platform && <Tag color="cyan">{formatLoginPlatform(row.login_platform)}</Tag>}
|
||||
</Space>
|
||||
</div>
|
||||
),
|
||||
|
||||
@@ -53,6 +53,7 @@ const ORDER_STATUS_MAP: Record<string, { label: string; color: string }> = {
|
||||
completed: { label: '已完成', color: 'success' },
|
||||
refunded: { label: '已退款', color: 'purple' },
|
||||
cancelled: { label: '已取消', color: 'default' },
|
||||
closed: { label: '已关闭', color: 'default' },
|
||||
}
|
||||
|
||||
const SETTLEMENT_STATUS_MAP: Record<string, { label: string; color: string }> = {
|
||||
@@ -62,10 +63,14 @@ const SETTLEMENT_STATUS_MAP: Record<string, { label: string; color: string }> =
|
||||
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<string, { label: string; color: string }> = {
|
||||
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<Site[]>([])
|
||||
@@ -337,7 +364,7 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) {
|
||||
<Space size={4} style={{ marginTop: 4 }} wrap>
|
||||
{row.game_name && <Tag color="blue">{formatGameName(row.game_name)}</Tag>}
|
||||
{row.server_region && <Tag>{row.server_region}</Tag>}
|
||||
{row.login_platform && <Tag color="cyan">{row.login_platform}</Tag>}
|
||||
{row.login_platform && <Tag color="cyan">{formatLoginPlatform(row.login_platform)}</Tag>}
|
||||
{row.rent_duration_hours ? <Tag color="purple">租期: {row.rent_duration_hours}h</Tag> : null}
|
||||
</Space>
|
||||
</div>
|
||||
@@ -589,7 +616,7 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) {
|
||||
<Space size={4} style={{ marginTop: 4 }} wrap>
|
||||
<Tag color="blue">{formatGameName(row.game_name)}</Tag>
|
||||
{row.server_region && <Tag>{row.server_region}</Tag>}
|
||||
{row.login_platform && <Tag color="cyan">{row.login_platform}</Tag>}
|
||||
{row.login_platform && <Tag color="cyan">{formatLoginPlatform(row.login_platform)}</Tag>}
|
||||
{row.rank_level && <Tag color="purple">{row.rank_level}</Tag>}
|
||||
</Space>
|
||||
</div>
|
||||
@@ -865,13 +892,27 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) {
|
||||
{
|
||||
key: 'order_no',
|
||||
label: '订单编号',
|
||||
children: <Typography.Text copyable>{selectedOrder.order_no}</Typography.Text>,
|
||||
children: (
|
||||
<Typography.Text
|
||||
copyable={{ text: selectedOrder.order_no, tooltips: ['复制订单号', '已复制'] }}
|
||||
strong
|
||||
className="mono-code"
|
||||
style={{ fontSize: 13, whiteSpace: 'nowrap', wordBreak: 'keep-all', display: 'inline-flex', alignItems: 'center' }}
|
||||
>
|
||||
{selectedOrder.order_no}
|
||||
</Typography.Text>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'listing_no',
|
||||
label: '商品编号',
|
||||
children: selectedOrder.listing_no ? (
|
||||
<Typography.Text copyable={{ text: selectedOrder.listing_no }} strong style={{ color: '#1677ff' }}>
|
||||
<Typography.Text
|
||||
copyable={{ text: selectedOrder.listing_no, tooltips: ['复制商品编号', '已复制'] }}
|
||||
strong
|
||||
className="mono-code"
|
||||
style={{ color: '#1677ff', fontSize: 13, whiteSpace: 'nowrap', wordBreak: 'keep-all', display: 'inline-flex', alignItems: 'center' }}
|
||||
>
|
||||
{selectedOrder.listing_no}
|
||||
</Typography.Text>
|
||||
) : (
|
||||
@@ -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',
|
||||
|
||||
@@ -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 (
|
||||
<Space direction="vertical" className="page">
|
||||
<Typography.Title level={3}>支付通道</Typography.Title>
|
||||
<Space>
|
||||
{member?.is_superadmin && sites.length > 1 && (
|
||||
<Select
|
||||
placeholder="分销网站"
|
||||
style={{ width: 200 }}
|
||||
value={siteID}
|
||||
options={sites.map((site) => ({ label: site.site_name, value: site.id }))}
|
||||
onChange={(value) => {
|
||||
setSiteID(value)
|
||||
void load(value)
|
||||
}}
|
||||
<Space direction="vertical" className="page" style={{ width: '100%' }} size="middle">
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div>
|
||||
<Typography.Title level={3} style={{ marginBottom: 4 }}>
|
||||
支付通道配置
|
||||
</Typography.Title>
|
||||
<Typography.Text type="secondary">
|
||||
为分销独立站绑定专属收单商户号与收银台支付通道,支持设置多通道优先级调度。
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card size="small" style={{ background: '#f8fafc' }}>
|
||||
<Space wrap>
|
||||
{member?.is_superadmin && sites.length > 1 && (
|
||||
<Select
|
||||
placeholder="切换分销网站"
|
||||
style={{ width: 220 }}
|
||||
value={siteID}
|
||||
options={sites.map((site) => ({ label: `${site.site_name} (${site.site_code})`, value: site.id }))}
|
||||
onChange={(value) => {
|
||||
setSiteID(value)
|
||||
void load(value)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<InputNumber
|
||||
min={1}
|
||||
placeholder="商户配置 ID"
|
||||
style={{ width: 160 }}
|
||||
value={configID ?? undefined}
|
||||
onChange={(v) => setConfigID(v ?? null)}
|
||||
/>
|
||||
)}
|
||||
<InputNumber min={1} placeholder="商户配置 ID" value={configID ?? undefined} onChange={(v) => setConfigID(v ?? null)} />
|
||||
<InputNumber min={0} placeholder="优先级" value={priority} onChange={(v) => setPriority(v ?? 0)} />
|
||||
<Button type="primary" onClick={handleBind}>绑定</Button>
|
||||
</Space>
|
||||
<Card>
|
||||
<InputNumber
|
||||
min={0}
|
||||
placeholder="调度优先级"
|
||||
style={{ width: 140 }}
|
||||
value={priority}
|
||||
onChange={(v) => setPriority(v ?? 0)}
|
||||
/>
|
||||
<Button type="primary" onClick={handleBind}>
|
||||
绑定支付通道
|
||||
</Button>
|
||||
</Space>
|
||||
</Card>
|
||||
|
||||
<Card title="已绑定的支付通道列表">
|
||||
<Table
|
||||
rowKey="id"
|
||||
loading={loading}
|
||||
dataSource={channels}
|
||||
pagination={false}
|
||||
scroll={{ x: 650 }}
|
||||
columns={[
|
||||
{ title: '商户配置 ID', dataIndex: 'config_id' },
|
||||
{ title: '优先级', dataIndex: 'priority' },
|
||||
{ title: '状态', dataIndex: 'status', render: (v: string) => <Tag color={v === 'active' ? 'green' : 'default'}>{v === 'active' ? '正常生效' : (v || '已停用')}</Tag> },
|
||||
{
|
||||
title: '商户配置 ID',
|
||||
dataIndex: 'config_id',
|
||||
width: 160,
|
||||
render: (v: number) => <strong>#{v}</strong>,
|
||||
},
|
||||
{
|
||||
title: '调度优先级',
|
||||
dataIndex: 'priority',
|
||||
width: 120,
|
||||
render: (v: number) => <Tag color="blue">{v}</Tag>,
|
||||
},
|
||||
{
|
||||
title: '运行状态',
|
||||
dataIndex: 'status',
|
||||
width: 140,
|
||||
render: (v: string) => (
|
||||
<Tag color={v === 'active' ? 'green' : 'default'}>
|
||||
{v === 'active' ? '正常生效' : v || '已停用'}
|
||||
</Tag>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
render: (_: unknown, row: PaymentChannel) => <a onClick={() => handleUnbind(row.id)}>解绑</a>,
|
||||
width: 100,
|
||||
render: (_: unknown, row: PaymentChannel) => (
|
||||
<Button
|
||||
type="link"
|
||||
danger
|
||||
size="small"
|
||||
onClick={() => void handleUnbind(row)}
|
||||
>
|
||||
解绑通道
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
@@ -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) => (
|
||||
<div>
|
||||
<strong>{MODE_LABELS[v] ?? v}</strong>
|
||||
|
||||
@@ -227,8 +227,25 @@ export default function Settlements() {
|
||||
{
|
||||
title: '账单批次号',
|
||||
dataIndex: 'batch_no',
|
||||
width: 200,
|
||||
render: (v: string) => <Typography.Text strong copyable>{v}</Typography.Text>,
|
||||
width: 220,
|
||||
render: (v: string) => (
|
||||
<div style={{ whiteSpace: 'nowrap' }}>
|
||||
<Typography.Text
|
||||
strong
|
||||
copyable={{ text: v, tooltips: ['复制批次号', '已复制'] }}
|
||||
className="mono-code"
|
||||
style={{
|
||||
fontSize: 13,
|
||||
whiteSpace: 'nowrap',
|
||||
wordBreak: 'keep-all',
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
{v}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
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) => <Typography.Text strong>订单 #{v}</Typography.Text>,
|
||||
render: (v: number) => <Typography.Text strong className="mono-code">订单 #{v}</Typography.Text>,
|
||||
},
|
||||
{
|
||||
title: '分润角色 / 收益类型',
|
||||
|
||||
@@ -85,7 +85,7 @@ export default function Sites({ isSuperadmin = true }: { isSuperadmin?: boolean
|
||||
}
|
||||
|
||||
return (
|
||||
<Space direction="vertical" className="page" size="large">
|
||||
<Space direction="vertical" className="page" size="large" style={{ width: '100%' }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div>
|
||||
<Typography.Title level={3} style={{ margin: 0 }}>
|
||||
@@ -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) => (
|
||||
<Space>
|
||||
<ShopOutlined style={{ color: '#1677ff' }} />
|
||||
@@ -119,11 +121,26 @@ export default function Sites({ isSuperadmin = true }: { isSuperadmin?: boolean
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{ title: '站点标识', dataIndex: 'site_code', render: (v: string) => <Tag>{v}</Tag> },
|
||||
{ title: '绑定域名', dataIndex: 'domain' },
|
||||
{
|
||||
title: '站点标识',
|
||||
dataIndex: 'site_code',
|
||||
width: 140,
|
||||
render: (v: string) => <Tag color="blue">{v}</Tag>,
|
||||
},
|
||||
{
|
||||
title: '绑定域名',
|
||||
dataIndex: 'domain',
|
||||
width: 220,
|
||||
render: (v: string) => (
|
||||
<Typography.Text copyable={{ text: v }} className="mono-code" style={{ fontSize: 13 }}>
|
||||
{v}
|
||||
</Typography.Text>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '运行状态',
|
||||
dataIndex: 'status',
|
||||
width: 110,
|
||||
render: (v: string) => (
|
||||
<Tag color={v === 'active' ? 'green' : 'default'}>
|
||||
{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 ? <Tag color="green">开启</Tag> : <Tag>关闭</Tag>),
|
||||
},
|
||||
{
|
||||
title: '税费设定',
|
||||
width: 110,
|
||||
render: (_: unknown, row: Site) =>
|
||||
row.tax_enabled ? <Tag color="orange">{row.tax_rate_bps / 100}%</Tag> : <Tag>不征税</Tag>,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'created_at',
|
||||
width: 140,
|
||||
render: (v: string) => (v ? new Date(v).toLocaleDateString() : '-'),
|
||||
},
|
||||
]}
|
||||
|
||||
@@ -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 && (
|
||||
<Tag style={{ margin: 0, background: 'rgba(255,255,255,0.06)', color: '#cbd5e1', border: 'none' }}>
|
||||
{item.login_platform}
|
||||
{formatLoginPlatform(item.login_platform)}
|
||||
</Tag>
|
||||
)}
|
||||
{item.rank_level && (
|
||||
@@ -465,7 +487,7 @@ export default function Storefront() {
|
||||
{formatGameName(selectedListing.game_name)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="游戏大区">{selectedListing.server_region || '全区通用'}</Descriptions.Item>
|
||||
<Descriptions.Item label="登录平台">{selectedListing.login_platform || 'PC端'}</Descriptions.Item>
|
||||
<Descriptions.Item label="登录平台">{formatLoginPlatform(selectedListing.login_platform) || 'PC端'}</Descriptions.Item>
|
||||
<Descriptions.Item label="段位天梯">{selectedListing.rank_level || '暂未定级'}</Descriptions.Item>
|
||||
<Descriptions.Item label="哈夫币资产">
|
||||
{selectedListing.haf_coin_amount > 0
|
||||
|
||||
@@ -316,7 +316,7 @@ export default function Wallet() {
|
||||
},
|
||||
{
|
||||
title: '审核 / 付款备注',
|
||||
minWidth: 160,
|
||||
width: 180,
|
||||
render: (_: unknown, row: SiteWithdrawal) => (
|
||||
<div>
|
||||
{row.review_remark && (
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user