import { useCallback, useEffect, useState } from 'react' import { Card, Table, Typography, Space, Select, Tag, message, Tabs, Input, Button, Modal, } from 'antd' import { SearchOutlined, CheckCircleOutlined, StopOutlined } from '@ant-design/icons' import { formatMoney, listOrders, listSites, fetchReceivedListings, updateReceivedListingStatus, type DistributionOrder, type ReceivedListing, type Site, } from '../api' const ORDER_STATUSES = [ 'pending_payment', 'pending_handoff', 'renting', 'overdue', 'pending_checkout_confirm', 'pending_checkout_accept', 'checkout_disputing', 'disputing', 'abnormal', 'completed', 'refunded', 'cancelled', ] const REVIEW_STATUS_LABELS: Record = { pending: { label: '待审核', color: 'orange' }, approved: { label: '审核通过', color: 'success' }, rejected: { label: '审核未通过', color: 'error' }, none: { label: '免审', color: 'default' }, } const LISTING_STATUS_LABELS: Record = { published: { label: '上架在售', color: 'green' }, inactive: { label: '已下架', color: 'default' }, closed: { label: '已关闭', color: 'error' }, draft: { label: '草稿', color: 'warning' }, } export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) { const [sites, setSites] = useState([]) const [siteID, setSiteID] = useState() const [activeTab, setActiveTab] = useState<'received_listings' | 'orders'>('received_listings') // Orders Tab State const [status, setStatus] = useState('') const [orders, setOrders] = useState([]) const [orderTotal, setOrderTotal] = useState(0) const [orderPage, setOrderPage] = useState(1) const [orderLoading, setOrderLoading] = useState(false) // Received Listings Tab State const [receivedListings, setReceivedListings] = useState([]) const [recvTotal, setRecvTotal] = useState(0) const [recvPage, setRecvPage] = useState(1) const [recvLoading, setRecvLoading] = useState(false) const [recvStatus, setRecvStatus] = useState('') const [recvReviewStatus, setRecvReviewStatus] = useState('') const [recvKeyword, setRecvKeyword] = useState('') const pageSize = 20 const loadOrders = useCallback(async (targetPage: number) => { setOrderLoading(true) try { const result = await listOrders({ kind, status, siteID, page: targetPage, pageSize }) setOrders(result.items) setOrderTotal(result.total) setOrderPage(result.page) } catch { message.error('订单加载失败') } finally { setOrderLoading(false) } }, [kind, status, siteID]) const loadReceivedListings = useCallback(async (targetPage: number) => { if (!siteID) return setRecvLoading(true) try { const result = await fetchReceivedListings({ siteID, page: targetPage, pageSize, status: recvStatus, reviewStatus: recvReviewStatus, keyword: recvKeyword, }) setReceivedListings(result.items) setRecvTotal(result.total) setRecvPage(result.page) } catch { message.error('分销收号资产加载失败') } finally { setRecvLoading(false) } }, [siteID, recvStatus, recvReviewStatus, recvKeyword]) useEffect(() => { listSites() .then((rows) => { setSites(rows) if (rows.length > 0) setSiteID(rows[0].id) }) .catch(() => message.error('站点加载失败')) }, []) useEffect(() => { if (kind === 'receive') { if (activeTab === 'received_listings') { void loadReceivedListings(1) } else { void loadOrders(1) } } else { void loadOrders(1) } }, [kind, activeTab, loadOrders, loadReceivedListings]) async function handleToggleListingStatus(item: ReceivedListing) { const nextStatus = item.status === 'published' ? 'inactive' : 'published' const actionName = nextStatus === 'published' ? '重新上架' : '下架' Modal.confirm({ title: `确认${actionName}该账号?`, content: `账号编号:${item.listing_no} (${item.title})`, onOk: async () => { try { await updateReceivedListingStatus(item.listing_id, nextStatus) message.success(`已${actionName}`) void loadReceivedListings(recvPage) } catch (error: unknown) { const respMessage = (error as { response?: { data?: { message?: string } } })?.response?.data?.message message.error(respMessage || `${actionName}操作失败`) } }, }) } const title = kind === 'sold' ? '售出账号订单' : kind === 'receive' ? '分销收号管理' : '全部分销订单' return (
{title} {kind === 'receive' ? '查看由当前分销网站上传的号源资产及审核流转状态,并跟踪对应的收号分成订单' : '查看分销订单交易及财务明细'}
({ label: v.label, value: k }))} onChange={(val) => { setRecvReviewStatus(val ?? '') }} /> } style={{ width: 260 }} allowClear value={recvKeyword} onChange={(e) => setRecvKeyword(e.target.value)} onPressEnter={() => void loadReceivedListings(1)} /> `共 ${tot} 个分销收号商品`, onChange: (p) => void loadReceivedListings(p), }} columns={[ { title: '商品编号', dataIndex: 'listing_no', width: 140, render: (v: string) => {v}, }, { title: '账号标题与游戏', dataIndex: 'title', minWidth: 220, render: (_: unknown, row: ReceivedListing) => (
{row.title || '无标题'} {row.game_name} {row.server_region && {row.server_region}} {row.login_platform && {row.login_platform}} {row.rank_level && {row.rank_level}}
), }, { title: '上传卖家', dataIndex: 'owner_phone', width: 150, render: (_: unknown, row: ReceivedListing) => (
{row.owner_nickname || '匿名卖家'}
{row.owner_phone || '-'}
), }, { title: '价格 / 押金', width: 140, render: (_: unknown, row: ReceivedListing) => (
{formatMoney(row.price_cent)}/时
押金: {formatMoney(row.deposit_amount_cent)}
), }, { title: '主站审核', dataIndex: 'review_status', width: 120, render: (v: string, row: ReceivedListing) => { const conf = REVIEW_STATUS_LABELS[v] || { label: v, color: 'default' } return (
{conf.label} {row.review_reason && ( {row.review_reason} )}
) }, }, { title: '货架状态', dataIndex: 'status', width: 110, render: (v: string) => { const conf = LISTING_STATUS_LABELS[v] || { label: v, color: 'default' } return {conf.label} }, }, { title: '上传时间', dataIndex: 'created_at', width: 160, render: (v: string) => {v}, }, { title: '操作', width: 110, render: (_: unknown, row: ReceivedListing) => ( ), }, ]} /> ), }, { key: 'orders', label: `收号分成订单 (${orderTotal})`, children: (
void loadOrders(p), }} columns={[ { title: '订单号', dataIndex: 'order_no' }, { title: '订单状态', dataIndex: 'status', render: (v: string) => {v} }, { title: '退款状态', dataIndex: 'refund_status' }, { title: '净支付', dataIndex: 'net_paid_amount_cent', render: (v: number) => formatMoney(v) }, { title: '手续费', dataIndex: 'payment_fee_cent', render: (v: number) => formatMoney(v) }, { title: '服务费', dataIndex: 'service_fee_cent', render: (v: number) => formatMoney(v) }, { title: '分成基数', dataIndex: 'split_base_amount_cent', render: (v: number) => formatMoney(v) }, { title: '尾差', dataIndex: 'rounding_adjustment_cent', render: (v: number) => formatMoney(v) }, { title: '结算', dataIndex: 'settlement_status' }, { title: '创建时间', dataIndex: 'created_at' }, ]} /> ), }, ]} /> ) : (
void loadOrders(p) }} columns={[ { title: '订单号', dataIndex: 'order_no' }, { title: '订单状态', dataIndex: 'status', render: (v: string) => {v} }, { title: '退款状态', dataIndex: 'refund_status' }, { title: '净支付', dataIndex: 'net_paid_amount_cent', render: (v: number) => formatMoney(v) }, { title: '手续费', dataIndex: 'payment_fee_cent', render: (v: number) => formatMoney(v) }, { title: '服务费', dataIndex: 'service_fee_cent', render: (v: number) => formatMoney(v) }, { title: '分成基数', dataIndex: 'split_base_amount_cent', render: (v: number) => formatMoney(v) }, { title: '尾差', dataIndex: 'rounding_adjustment_cent', render: (v: number) => formatMoney(v) }, { title: '结算', dataIndex: 'settlement_status' }, { title: '创建时间', dataIndex: 'created_at' }, ]} /> )} ) }