feat: order list
parent
5a885942f2
commit
fc52444bd4
|
@ -32,6 +32,12 @@ export default defineConfig({
|
|||
redirect: '/home',
|
||||
routes: [],
|
||||
},
|
||||
{
|
||||
name: '订单详情',
|
||||
path: '/OrderDetails/:id',
|
||||
component: 'Order/OrderDetails',
|
||||
hideInMenu: true,
|
||||
},
|
||||
],
|
||||
npmClient: 'pnpm',
|
||||
});
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
import { getOrderByIdAPI } from '@/services/system/order';
|
||||
import { OrderPayType, OrderPayTypeStr, OrderStatus, UxOrderStatus, UxOrderStatusTag } from '@/utils/const';
|
||||
import { AlipayCircleOutlined, ArrowLeftOutlined, WechatOutlined } from '@ant-design/icons';
|
||||
import { history, useParams } from '@umijs/max';
|
||||
import { Button, Card, Descriptions, Skeleton } from 'antd';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const OrderDetails = () => {
|
||||
const { id } = useParams();
|
||||
const [orderInfo, seatOrderInfo] = useState<EditRow<Order.OrderItem>>();
|
||||
|
||||
useEffect(() => {
|
||||
getOrderByIdAPI(id!).then((result) => {
|
||||
if (result.code === 200) {
|
||||
seatOrderInfo(result.data);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card
|
||||
className="m-4"
|
||||
title={'订单号: ' + `${orderInfo ? orderInfo.orderNo : ''}`}
|
||||
extra={
|
||||
<>
|
||||
<Button
|
||||
type="link"
|
||||
key={'back'}
|
||||
onClick={() => {
|
||||
history.push('/order');
|
||||
}}
|
||||
>
|
||||
<ArrowLeftOutlined />
|
||||
返回
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{orderInfo ? (
|
||||
<Descriptions size="small" column={{ xs: 1, sm: 2, md: 3, lg: 3 }} bordered>
|
||||
<Descriptions.Item label="用户">{orderInfo?.userEmail}</Descriptions.Item>
|
||||
<Descriptions.Item label="订单单号">{orderInfo.orderNo}</Descriptions.Item>
|
||||
<Descriptions.Item label="试用套餐">{orderInfo.isApply ? '是' : '否'}</Descriptions.Item>
|
||||
<Descriptions.Item label="套餐名称">{orderInfo.goodsName}</Descriptions.Item>
|
||||
<Descriptions.Item label="支付类型">
|
||||
{orderInfo.payType === OrderPayType.WX && <WechatOutlined color="green" style={{ fontSize: '18px' }} />}
|
||||
{orderInfo.payType === OrderPayType.ZFB && (
|
||||
<AlipayCircleOutlined color="blue" style={{ fontSize: '18px' }} />
|
||||
)}
|
||||
|
||||
<span className="ml-2"> {Reflect.get(OrderPayTypeStr, orderInfo.payType)}</span>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="订单状态">
|
||||
<div style={{ color: Reflect.get(UxOrderStatusTag, orderInfo.orderStatus) }} className="font-bold">
|
||||
{Reflect.get(UxOrderStatus, orderInfo.orderStatus as number)}
|
||||
</div>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="单价">{orderInfo.price}</Descriptions.Item>
|
||||
<Descriptions.Item label="数量">{orderInfo.quantity}</Descriptions.Item>
|
||||
<Descriptions.Item label="支付总金额">{orderInfo?.totalPrice}</Descriptions.Item>
|
||||
<Descriptions.Item label="订单过期时间">
|
||||
{orderInfo?.orderStatus === OrderStatus.NO_PAY ? orderInfo.payCodeExpired : '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="第三方订单单号">{orderInfo.platformNo}</Descriptions.Item>
|
||||
<Descriptions.Item label="第三方订单状态">{orderInfo.platformOrderStatus}</Descriptions.Item>
|
||||
<Descriptions.Item label="订单创建时间">{orderInfo.createdDateTime}</Descriptions.Item>
|
||||
<Descriptions.Item label="订单修改时间">{orderInfo.lastUpdateDateTime}</Descriptions.Item>
|
||||
<Descriptions.Item label="备注">{orderInfo.comment}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
) : (
|
||||
<Skeleton active />
|
||||
)}
|
||||
</Card>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default OrderDetails;
|
|
@ -1,5 +1,297 @@
|
|||
const page = () => {
|
||||
return <>待开发</>;
|
||||
import { getOrderListAPI } from '@/services/system/order';
|
||||
import { getPackageAPI } from '@/services/system/package';
|
||||
import { OrderPayType, OrderPayTypeStr, OrderStatus, UxOrderStatus, UxOrderStatusTag } from '@/utils/const';
|
||||
import { AlipayCircleOutlined, WechatOutlined } from '@ant-design/icons';
|
||||
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
|
||||
import { history } from '@umijs/max';
|
||||
import { Button, Select, TableProps } from 'antd';
|
||||
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
const Page = () => {
|
||||
const tableRef = useRef<ActionType>();
|
||||
|
||||
const [pkgOptions, setPkg] = useState<Package.PackageItem[]>([]);
|
||||
|
||||
const [tableParams, setTableParams] = useState<TableParams>({
|
||||
pagination: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
});
|
||||
|
||||
const handleTableChange: TableProps['onChange'] = (pagination, filters, sorter) => {
|
||||
setTableParams({
|
||||
pagination,
|
||||
filters,
|
||||
...sorter,
|
||||
});
|
||||
};
|
||||
|
||||
export default page;
|
||||
useEffect(() => {
|
||||
getPackageAPI().then((result) => {
|
||||
setPkg(result.data);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleOrderDetails = (record: Order.OrderItem) => {
|
||||
history.push('/orderDetails/' + `${record.id}`);
|
||||
};
|
||||
|
||||
const searchForm: ProColumns[] = [
|
||||
{
|
||||
title: '订单号',
|
||||
hideInTable: true,
|
||||
align: 'center',
|
||||
formItemProps: {
|
||||
name: 'orderNo',
|
||||
},
|
||||
valueType: 'text',
|
||||
},
|
||||
{
|
||||
title: '套餐',
|
||||
hideInTable: true,
|
||||
align: 'center',
|
||||
formItemProps: {
|
||||
name: 'packageId',
|
||||
},
|
||||
renderFormItem: () => {
|
||||
return (
|
||||
<Select
|
||||
showSearch
|
||||
allowClear
|
||||
filterOption={false}
|
||||
options={pkgOptions.map((item) => {
|
||||
return {
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
};
|
||||
})}
|
||||
></Select>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '用户',
|
||||
hideInTable: true,
|
||||
align: 'center',
|
||||
formItemProps: {
|
||||
name: 'userEmail',
|
||||
},
|
||||
valueType: 'text',
|
||||
},
|
||||
{
|
||||
title: '订单状态',
|
||||
hideInTable: true,
|
||||
align: 'center',
|
||||
formItemProps: {
|
||||
name: 'orderStatus',
|
||||
},
|
||||
renderFormItem: () => {
|
||||
return (
|
||||
<Select
|
||||
showSearch
|
||||
allowClear
|
||||
filterOption={false}
|
||||
mode="multiple"
|
||||
maxTagCount={1}
|
||||
options={Object.keys(UxOrderStatus).map((key) => {
|
||||
return {
|
||||
label: UxOrderStatus[key as unknown as number],
|
||||
value: key,
|
||||
};
|
||||
})}
|
||||
></Select>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '支付类型',
|
||||
hideInTable: true,
|
||||
align: 'center',
|
||||
formItemProps: {
|
||||
name: 'payType',
|
||||
},
|
||||
renderFormItem: () => {
|
||||
return (
|
||||
<Select
|
||||
showSearch
|
||||
allowClear
|
||||
filterOption={false}
|
||||
mode="multiple"
|
||||
maxTagCount={1}
|
||||
options={Object.keys(OrderPayTypeStr).map((key) => {
|
||||
return {
|
||||
// @ts-ignore
|
||||
label: OrderPayTypeStr[key as unknown as any],
|
||||
value: key,
|
||||
};
|
||||
})}
|
||||
></Select>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const columns: ProColumns[] = [
|
||||
...searchForm,
|
||||
{
|
||||
title: '订单号',
|
||||
dataIndex: 'orderNo',
|
||||
align: 'center',
|
||||
fixed: 'left',
|
||||
hideInSearch: true,
|
||||
width: 230,
|
||||
render: (_, record: Order.OrderItem) => {
|
||||
if (record.isApply === true) {
|
||||
return record.orderNo + '(试用)';
|
||||
}
|
||||
return record.orderNo;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '订单状态',
|
||||
dataIndex: 'orderStatus',
|
||||
fixed: 'left',
|
||||
width: 140,
|
||||
align: 'center',
|
||||
hideInSearch: true,
|
||||
render: (_, record: Order.OrderItem) => {
|
||||
const color = Reflect.get(UxOrderStatusTag, record.orderStatus);
|
||||
return (
|
||||
<div className="flex items-center justify-start">
|
||||
<div className="w-[10px] h-[10px] mr-2" style={{ background: color }}></div>
|
||||
{Reflect.get(UxOrderStatus, record.orderStatus)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '支付总金额',
|
||||
dataIndex: 'totalPrice',
|
||||
width: 120,
|
||||
hideInSearch: true,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '支付类型',
|
||||
dataIndex: 'payType',
|
||||
hideInSearch: true,
|
||||
width: 100,
|
||||
align: 'center',
|
||||
render: (_, record: Order.OrderItem) => {
|
||||
// 支付类型 1. 微信 2. 支付宝 3. paypal -1: 后台创建
|
||||
if ([OrderPayType.WX, OrderPayType.ZFB].includes(record.payType)) {
|
||||
return (
|
||||
<div className="flex justify-center items-center">
|
||||
{record.payType === OrderPayType.WX ? (
|
||||
<WechatOutlined color="green" style={{ fontSize: '18px' }} />
|
||||
) : (
|
||||
<AlipayCircleOutlined color="blue" style={{ fontSize: '18px' }} />
|
||||
)}
|
||||
<span className="ml-1">{Reflect.get(OrderPayTypeStr, record.payType)}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (record.payType === OrderPayType.PAYPAL) {
|
||||
return Reflect.get(OrderPayTypeStr, OrderPayType.PAYPAL);
|
||||
}
|
||||
return record.isApply ? '试用' : '-';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '第三方订单号',
|
||||
dataIndex: 'platformNo',
|
||||
hideInSearch: true,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '第三方订单状态',
|
||||
dataIndex: 'platformOrderStatus',
|
||||
hideInSearch: true,
|
||||
|
||||
width: 150,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '套餐',
|
||||
dataIndex: 'goodsName',
|
||||
hideInSearch: true,
|
||||
width: 80,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '订单创建时间',
|
||||
hideInSearch: true,
|
||||
dataIndex: 'createdDateTime',
|
||||
width: 200,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '订单完成时间',
|
||||
hideInSearch: true,
|
||||
dataIndex: 'lastUpdateDateTime',
|
||||
width: 200,
|
||||
align: 'center',
|
||||
render: (_, record: Order.OrderItem) => {
|
||||
if (record.orderStatus === OrderStatus.HAVE_PAY) {
|
||||
return record.lastUpdateDateTime;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'option',
|
||||
valueType: 'option',
|
||||
align: 'center',
|
||||
render: (_: React.ReactNode, record: Order.OrderItem) => {
|
||||
return (
|
||||
<Button
|
||||
key={'order-details'}
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
handleOrderDetails(record);
|
||||
}}
|
||||
>
|
||||
订单详情
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<ProTable
|
||||
actionRef={tableRef}
|
||||
columns={columns}
|
||||
rowKey={'id'}
|
||||
pagination={tableParams.pagination}
|
||||
onChange={handleTableChange}
|
||||
search={{
|
||||
labelWidth: 75,
|
||||
span: { xs: 24, sm: 24, md: 12, lg: 12, xl: 4, xxl: 4 },
|
||||
}}
|
||||
request={async (params) => {
|
||||
const { current, pageSize, ...other } = params;
|
||||
const query = {
|
||||
current,
|
||||
pageSize,
|
||||
orderNo: other.orderNo,
|
||||
packageId: other.packageId,
|
||||
orderStatus: other.orderStatus ? other.orderStatus.join(',') : [],
|
||||
payType: other.payType ? other.payType.join(',') : [],
|
||||
};
|
||||
const { meta, code, data } = await getOrderListAPI(query);
|
||||
return {
|
||||
data: data ?? [],
|
||||
total: meta.total,
|
||||
success: code === 200,
|
||||
};
|
||||
}}
|
||||
></ProTable>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Page;
|
||||
|
|
|
@ -143,7 +143,7 @@ const UserDetailsModal = (props: PropTypes) => {
|
|||
render: (_, record: Order.OrderItem) => {
|
||||
const color = Reflect.get(UxOrderStatusTag, record.orderStatus);
|
||||
return (
|
||||
<div className="flex items-center justify-center">
|
||||
<div className="flex items-center justify-start">
|
||||
<div className="w-[10px] h-[10px] mr-2" style={{ background: color }}></div>
|
||||
{Reflect.get(UxOrderStatus, record.orderStatus)}
|
||||
</div>
|
||||
|
@ -279,17 +279,18 @@ const UserDetailsModal = (props: PropTypes) => {
|
|||
onCancel={handleOnCancel}
|
||||
>
|
||||
<Spin spinning={loading}>
|
||||
<Tabs activeKey={tabType} onChange={(activeKey) => setTabType(activeKey)}>
|
||||
<Tabs.TabPane key={'details'} tab={'用户详情'}>
|
||||
<RenderUserDetails />
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane key={'handleLogs'} tab={'扩容记录'}>
|
||||
<RenderDilatationLogs />
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane key={'orderInfo'} tab={'订单信息'}>
|
||||
<RenderUserOrders />
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
<Tabs
|
||||
activeKey={tabType}
|
||||
onChange={(activeKey) => setTabType(activeKey)}
|
||||
items={[
|
||||
{ label: '用户详情', key: 'details' },
|
||||
{ label: '扩容记录', key: 'handleLogs' },
|
||||
{ label: '订单信息', key: 'orderInfo' },
|
||||
]}
|
||||
></Tabs>
|
||||
{tabType === 'details' && <RenderUserDetails />}
|
||||
{tabType === 'handleLogs' && <RenderDilatationLogs />}
|
||||
{tabType === 'orderInfo' && <RenderUserOrders />}
|
||||
</Spin>
|
||||
</Modal>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import request from '@/utils/request';
|
||||
import qs from 'qs';
|
||||
|
||||
export const getOrderListAPI = (params: Record<string, any>): Promise<API.ResponstList<Order.OrderItem[]>> => {
|
||||
return request.get(`/system/order?` + qs.stringify(params));
|
||||
};
|
||||
|
||||
export const getOrderByIdAPI = (id: string): Promise<API.ResponstList<Order.OrderItem>> => {
|
||||
return request.get(`/system/order/` + id);
|
||||
};
|
|
@ -27,5 +27,6 @@ declare namespace Order {
|
|||
lastUpdateDateTime?: string;
|
||||
comment?: string;
|
||||
isApply: boolean;
|
||||
totalPrice?: number;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@ export const UxOrderStatus: Record<number, string> = {
|
|||
2: '已支付',
|
||||
3: '订单取消',
|
||||
4: '支付失败',
|
||||
5: '订单超时支付(二维码过期)',
|
||||
5: '订单超时支付',
|
||||
999: '超时支付失败',
|
||||
};
|
||||
|
||||
export const UxOrderStatusTag: Record<number, string> = {
|
||||
|
@ -12,7 +13,8 @@ export const UxOrderStatusTag: Record<number, string> = {
|
|||
2: '#27ae60', // 绿色
|
||||
3: '#c8d6e5', // 灰色
|
||||
4: '#e74c3c', // 红色
|
||||
5: '订单超时支付(二维码过期)', //
|
||||
5: '#c0392b', //
|
||||
999: '#c0392b',
|
||||
};
|
||||
|
||||
// 1: 待支付 2. 已支付 3. 订单取消 4. 支付失败 5. 订单超时支付(二维码过期)
|
||||
|
@ -28,10 +30,13 @@ export enum OrderPayType {
|
|||
WX = 1,
|
||||
ZFB = 2,
|
||||
PAYPAL = 3,
|
||||
BACK = -1,
|
||||
}
|
||||
|
||||
export const OrderPayTypeStr = {
|
||||
1: '微信',
|
||||
2: '支付宝',
|
||||
3: 'PayPal',
|
||||
[-1]: '管理员创建',
|
||||
[-2]: '前端创建',
|
||||
};
|
||||
|
|
|
@ -38,16 +38,6 @@ export const routes: any[] = [
|
|||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// name: '权限演示',
|
||||
// path: '/access',
|
||||
// component: '/Access',
|
||||
// },
|
||||
// {
|
||||
// name: ' CRUD 示例',
|
||||
// path: '/table',
|
||||
// component: '/Table',
|
||||
// },
|
||||
];
|
||||
|
||||
export type MenuItem = {
|
||||
|
|
Loading…
Reference in New Issue