import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { format } from 'date-fns'; import { toast } from 'sonner'; import { Search, Edit, Eye } from 'lucide-react'; // 使用共享UI组件包的具体路径导入 import { Button } from '@d8d/shared-ui-components/components/ui/button'; import { Input } from '@d8d/shared-ui-components/components/ui/input'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@d8d/shared-ui-components/components/ui/card'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@d8d/shared-ui-components/components/ui/table'; import { Badge } from '@d8d/shared-ui-components/components/ui/badge'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@d8d/shared-ui-components/components/ui/dialog'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@d8d/shared-ui-components/components/ui/form'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@d8d/shared-ui-components/components/ui/select'; import { Textarea } from '@d8d/shared-ui-components/components/ui/textarea'; import { Skeleton } from '@d8d/shared-ui-components/components/ui/skeleton'; // 简单分页组件 const DataTablePagination = ({ currentPage, pageSize, totalCount, onPageChange }: { currentPage: number; pageSize: number; totalCount: number; onPageChange: (page: number, limit: number) => void; }) => { const totalPages = Math.ceil(totalCount / pageSize); return (
共 {totalCount} 条记录
第 {currentPage} 页,共 {totalPages} 页
); }; import { adminOrderClient } from '../api'; import type { InferRequestType, InferResponseType } from 'hono/client'; import { UpdateOrderDto } from '@d8d/orders-module/schemas'; // 类型定义 type OrderResponse = InferResponseType['data'][0]; type UpdateRequest = InferRequestType['json']; // 状态映射 const orderStatusMap = { 0: { label: '未发货', color: 'warning' }, 1: { label: '已发货', color: 'info' }, 2: { label: '收货成功', color: 'success' }, 3: { label: '已退货', color: 'destructive' }, } as const; const payStatusMap = { 0: { label: '未支付', color: 'warning' }, 1: { label: '支付中', color: 'info' }, 2: { label: '支付成功', color: 'success' }, 3: { label: '已退款', color: 'secondary' }, 4: { label: '支付失败', color: 'destructive' }, 5: { label: '订单关闭', color: 'destructive' }, } as const; const orderTypeMap = { 1: { label: '实物订单', color: 'default' }, 2: { label: '虚拟订单', color: 'secondary' }, } as const; export const OrderManagement = () => { const [searchParams, setSearchParams] = useState({ page: 1, limit: 10, search: '', status: 'all', payStatus: 'all', }); const [isModalOpen, setIsModalOpen] = useState(false); const [editingOrder, setEditingOrder] = useState(null); const [detailModalOpen, setDetailModalOpen] = useState(false); const [selectedOrder, setSelectedOrder] = useState(null); // 表单实例 const updateForm = useForm({ resolver: zodResolver(UpdateOrderDto), defaultValues: {}, }); // 数据查询 const { data, isLoading, refetch } = useQuery({ queryKey: ['orders', searchParams], queryFn: async () => { const filters: any = {}; if (searchParams.status !== 'all') { filters.state = parseInt(searchParams.status); } if (searchParams.payStatus !== 'all') { filters.payState = parseInt(searchParams.payStatus); } const res = await adminOrderClient.$get({ query: { page: searchParams.page, pageSize: searchParams.limit, keyword: searchParams.search, ...(Object.keys(filters).length > 0 && { filters: JSON.stringify(filters) }), } }); if (res.status !== 200) throw new Error('获取订单列表失败'); return await res.json(); } }); // 处理搜索 const handleSearch = () => { setSearchParams(prev => ({ ...prev, page: 1 })); }; // 处理编辑订单 const handleEditOrder = (order: OrderResponse) => { setEditingOrder(order); updateForm.reset({ state: order.state, payState: order.payState, remark: order.remark || '', }); setIsModalOpen(true); }; // 处理查看详情 const handleViewDetails = (order: OrderResponse) => { setSelectedOrder(order); setDetailModalOpen(true); }; // 处理更新订单 const handleUpdateSubmit = async (data: UpdateRequest) => { if (!editingOrder) return; try { const res = await adminOrderClient[':id']['$put']({ param: { id: editingOrder.id.toString() }, json: data, }); if (res.status === 200) { toast.success('订单更新成功'); setIsModalOpen(false); refetch(); } else { const error = await res.json(); toast.error(error.message || '更新失败'); } } catch (error) { console.error('更新订单失败:', error); toast.error('更新失败,请重试'); } }; // 格式化金额 const formatAmount = (amount: number) => { return `¥${amount.toFixed(2)}`; }; // 获取状态颜色 const getStatusBadge = (status: number, type: 'order' | 'pay') => { const map = type === 'order' ? orderStatusMap : payStatusMap; const config = map[status as keyof typeof map] || { label: '未知', color: 'default' }; return {config.label}; }; // 骨架屏 - 只覆盖表格区域,搜索区域保持可用 if (isLoading) { return (
{/* 页面标题 */}

订单管理

管理所有订单信息

{/* 搜索区域 - 保持可用 */} 订单列表 查看和管理所有订单
setSearchParams(prev => ({ ...prev, search: e.target.value }))} className="pl-8" data-testid="order-search-input" />
{/* 表格骨架屏 */}
订单号 用户信息 收货人 金额 订单状态 支付状态 创建时间 操作 {[...Array(5)].map((_, i) => (
))}
{/* 分页骨架屏 */}
); } return (
{/* 页面标题 */}

订单管理

管理所有订单信息

{/* 搜索区域 */} 订单列表 查看和管理所有订单
setSearchParams(prev => ({ ...prev, search: e.target.value }))} className="pl-8" data-testid="order-search-input" />
{/* 数据表格 */}
订单号 用户信息 收货人 金额 订单状态 支付状态 创建时间 操作 {data?.data.map((order) => (

{order.orderNo}

{orderTypeMap[order.orderType as keyof typeof orderTypeMap]?.label}

{order.user?.username || '-'}

{order.userPhone}

{order.recevierName || '-'}

{order.receiverMobile}

{formatAmount(order.payAmount)}

{formatAmount(order.amount)}

{getStatusBadge(order.state, 'order')} {getStatusBadge(order.payState, 'pay')} {format(new Date(order.createdAt), 'yyyy-MM-dd HH:mm')}
))}
{data?.data.length === 0 && !isLoading && (

暂无订单数据

)} setSearchParams(prev => ({ ...prev, page, limit }))} />
{/* 编辑订单模态框 */} 编辑订单 更新订单状态和备注信息
( 订单状态 )} /> ( 支付状态 )} /> ( 管理员备注