79 lines
3.1 KiB
TypeScript
79 lines
3.1 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import { Table, Tag, Select, Space, Input, Button } from 'antd';
|
|
import type { ColumnsType } from 'antd/es/table';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { getOrderList } from '@/api/admin';
|
|
import dayjs from 'dayjs';
|
|
|
|
const { Option } = Select;
|
|
|
|
const statusMap: Record<string, { color: string; label: string }> = {
|
|
pending_pay: { color: 'gold', label: '待支付' },
|
|
pending_confirm: { color: 'blue', label: '待确认' },
|
|
pending_checkin: { color: 'cyan', label: '待入住' },
|
|
checked_in: { color: 'orange', label: '已入住' },
|
|
completed: { color: 'green', label: '已完成' },
|
|
cancelled: { color: 'default', label: '已取消' },
|
|
refunding: { color: 'red', label: '退款中' },
|
|
refunded: { color: 'purple', label: '已退款' },
|
|
};
|
|
|
|
const OrderList: React.FC = () => {
|
|
const navigate = useNavigate();
|
|
const [data, setData] = useState<any[]>([]);
|
|
const [total, setTotal] = useState(0);
|
|
const [page, setPage] = useState(1);
|
|
const [status, setStatus] = useState<string>('');
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const fetchData = async () => {
|
|
setLoading(true);
|
|
try {
|
|
const res: any = await getOrderList({ page, pageSize: 10, status: status || undefined });
|
|
setData(res.data?.list || []);
|
|
setTotal(res.data?.total || 0);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => { fetchData(); }, [page, status]);
|
|
|
|
const columns: ColumnsType<any> = [
|
|
{ title: '订单号', dataIndex: 'orderNo', width: 200 },
|
|
{ title: '用户', dataIndex: ['user', 'nickname'], width: 100 },
|
|
{ title: '商家', dataIndex: ['merchant', 'shopName'], width: 140, ellipsis: true },
|
|
{ title: '房源', dataIndex: ['room', 'name'], width: 140, ellipsis: true },
|
|
{ title: '入住', dataIndex: 'checkInDate', width: 110 },
|
|
{ title: '离店', dataIndex: 'checkOutDate', width: 110 },
|
|
{ title: '金额', dataIndex: 'payAmount', width: 100, render: (v) => `¥${v}` },
|
|
{
|
|
title: '状态', dataIndex: 'status', width: 100,
|
|
render: (s) => <Tag color={statusMap[s]?.color}>{statusMap[s]?.label || s}</Tag>,
|
|
},
|
|
{ title: '下单时间', dataIndex: 'createdAt', width: 180, render: (v: string) => v ? dayjs(v).format('YYYY-MM-DD HH:mm') : '-' },
|
|
{
|
|
title: '操作', key: 'action', width: 100, fixed: 'right',
|
|
render: (_, record) => (
|
|
<Button type="link" onClick={() => navigate(`/orders/${record.id}`)}>
|
|
详情
|
|
</Button>
|
|
),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div>
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}>
|
|
<h2>订单管理</h2>
|
|
<Select value={status || undefined} placeholder="订单状态" style={{ width: 150 }} allowClear onChange={(v) => { setStatus(v || ''); setPage(1); }}>
|
|
{Object.entries(statusMap).map(([k, v]) => <Option key={k} value={k}>{v.label}</Option>)}
|
|
</Select>
|
|
</div>
|
|
<Table rowKey="id" columns={columns} dataSource={data} loading={loading} scroll={{ x: 1300 }} pagination={{ current: page, total, pageSize: 10, onChange: setPage }} />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default OrderList;
|