import { useState } from 'react' import { keepPreviousData, useQuery, useQueryClient } from '@tanstack/react-query' import { Alert, App, Button, Input, Select, Space, Tag, Typography, type TableColumnsType } from 'antd' import { ReloadOutlined } from '@ant-design/icons' import { cancelCrashOrder, completeCrashOrder, fetchCrashOrders, receiveCrashOrder, refundCrashOrder, } from '@/features/admin/api' import { AdminPageHeader } from '@/features/admin/components/AdminPageHeader' import { DataTable } from '@/features/admin/components/DataTable' import { FilterBar, FilterField } from '@/features/admin/components/FilterBar' import type { AdminCrashOrder } from '@/features/admin/types' import { useAdminSessionStore } from '@/stores/adminSession' import { formatDateTime, formatMoney, formatText } from '@/shared/utils/format' const statusMeta: Record = { pending_payment: { label: '待支付', color: 'gold' }, paid: { label: '已支付', color: 'blue' }, received: { label: '已接单', color: 'cyan' }, completed: { label: '已完成', color: 'green' }, cancelled: { label: '已取消', color: 'default' }, refunded: { label: '已退款', color: 'red' }, } function errorText(error: unknown) { const response = (error as { response?: { data?: { message?: string } } })?.response return response?.data?.message || (error instanceof Error ? error.message : '请求失败') } export function AdminCrashOrdersPage() { const { message, modal } = App.useApp() const queryClient = useQueryClient() const [filters, setFilters] = useState<{ keyword: string; status?: string }>({ keyword: '' }) const [applied, setApplied] = useState(filters) const [page, setPage] = useState(1) const [pageSize, setPageSize] = useState(20) const permissions = useAdminSessionStore(state => state.admin?.permissions) const canView = Boolean(permissions?.includes('*') || permissions?.includes('mohong:order_view')) const canManage = Boolean(permissions?.includes('*') || permissions?.includes('mohong:order_manage')) const query = { keyword: applied.keyword.trim() || undefined, status: applied.status, page, page_size: pageSize, } const ordersQuery = useQuery({ queryKey: ['admin-crash-orders', query], queryFn: () => fetchCrashOrders(query), enabled: canView, placeholderData: keepPreviousData, }) const invalidate = () => queryClient.invalidateQueries({ queryKey: ['admin-crash-orders'] }) const act = async (action: () => Promise, success: string) => { try { await action() message.success(success) await invalidate() } catch (error) { message.error(errorText(error)) } } const columns: TableColumnsType = [ { title: '订单', key: 'order', width: 240, render: (_, row) => (
{row.order_no} {row.product_title}
), }, { title: '买家', key: 'buyer', width: 170, render: (_, row) => (
{formatText(row.buyer_nickname)} {formatText(row.buyer_phone)}
), }, { title: '数量 / 金额', key: 'amount', width: 150, align: 'right', render: (_, row) => (
{formatMoney(row.amount_cent)} × {row.quantity}
), }, { title: '状态', dataIndex: 'status', width: 110, render: value => { const meta = statusMeta[value] ?? { label: value, color: 'default' } return ( {meta.label} ) }, }, { title: '备注', key: 'remark', render: (_, row) => formatText(row.admin_remark || row.cancel_reason), }, { title: '下单时间', dataIndex: 'created_at', width: 170, render: value => formatDateTime(value), }, { title: '操作', key: 'actions', width: 260, fixed: 'right', render: (_, row) => ( {row.status === 'paid' ? ( ) : null} {row.status === 'received' ? ( ) : null} {row.status === 'paid' || row.status === 'received' ? ( ) : null} {row.status === 'paid' || row.status === 'received' || row.status === 'completed' ? ( ) : null} ), }, ] if (!canView) { return (
) } return (
共 {ordersQuery.data?.total ?? 0} 单} extra={ } /> { setPage(1) setApplied(filters) }} onReset={() => { const empty = { keyword: '' } setFilters(empty) setApplied(empty) setPage(1) }} > setFilters(current => ({ ...current, keyword: event.target.value }))} />