Files
tashow-manager/src/pages/trade/order/list.tsx
2026-01-21 15:07:11 +08:00

353 lines
10 KiB
TypeScript

import {
type ActionType,
ProCard,
type ProColumns,
} from '@ant-design/pro-components';
import {
Avatar,
Badge,
Button,
Divider,
Input,
message,
Space,
Statistic,
} from 'antd';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import ConfigurableDrawerForm, {
type ConfigurableDrawerFormRef,
} from '@/components/DrawerForm';
import EnhancedProTable from '@/components/EnhancedProTable';
import { baseOrderColumns } from './config';
const { Search } = Input;
import { DownOutlined, UpOutlined, UserOutlined } from '@ant-design/icons';
import PopconfirmForm, {
type PopconfirmFormRef,
} from '@/components/PopconfirmForm';
import {
mapOrderStatusToBadgeStatus,
OrderStatus,
OrderStatusLabels,
} from '@/constants/trade';
import {
getTradeOrderPage,
getTradeSummary,
type TradeOrderPageRespVO,
type TradeReq,
type TradeSummaryRespVO,
updateOrderRemark,
} from '@/services/trade/order';
import CancleOrderModal from './components/cancleOrderModal';
import DetailCom from './detail';
const OrderListItem: React.FC<{ orderStatus: number }> = (props) => {
const { orderStatus } = props;
const tableRef = useRef<ActionType>(null);
const configurableDrawerRef = useRef<ConfigurableDrawerFormRef>(null);
const [modalData, setModalData] = useState<TradeOrderPageRespVO>();
const [isShowTotal, setIsShowTotal] = useState<boolean>(false);
const popconfirmFormRef = useRef<PopconfirmFormRef>(null);
const [summary, setSummary] = useState<TradeSummaryRespVO>();
const [cancleOrderVisible, setCancleOrderVisible] = useState<boolean>(false);
const fetchSummary = async () => {
const res = await getTradeSummary();
setSummary(res);
};
useEffect(() => {
fetchSummary();
}, []);
const onFetch = async (
params: TradeReq & {
pageSize: number;
current: number;
},
) => {
const data = await getTradeOrderPage({
...params,
orderStatus: props?.orderStatus ? props?.orderStatus : undefined,
pageNo: params.current,
pageSize: params.pageSize,
});
return {
data: data.list,
success: true,
total: data.total,
};
};
const handleDetail = useCallback(
(record: TradeOrderPageRespVO) => {
setModalData(record);
configurableDrawerRef.current?.open(record);
},
[modalData],
);
const handleOrder = useCallback(
(type: string, record?: TradeOrderPageRespVO) => {
setModalData(record);
if (type === 'order') {
setCancleOrderVisible(true);
}
if (type === 'order') {
setCancleOrderVisible(true);
}
// await updateTradeOrder(values.id);
},
[],
);
const handleUpdate = async (values: TradeOrderPageRespVO, id?: number) => {
try {
await updateOrderRemark({ remark: values.userRemark || '', id: id });
tableRef.current?.reload();
return true;
} finally {
message.success('更新成功');
}
// await updateTradeOrder(values.id);
};
const actionColumns: ProColumns<TradeOrderPageRespVO> = {
title: '操作',
dataIndex: 'option',
valueType: 'option',
fixed: 'right',
width: 100,
render: (_text: React.ReactNode, record: TradeOrderPageRespVO) => [
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: 4,
justifyContent: 'center',
}}
key={record.id}
>
{record.orderStatus !== OrderStatus.Cancelled && (
<a key="cancel" onClick={() => handleOrder('order', record)}>
</a>
)}
{record.orderStatus === OrderStatus.PendingService && (
<a key="order" onClick={() => handleOrder('service', record)}>
</a>
)}
{record.orderStatus === OrderStatus.PendingConfirmation && (
<a key="order" onClick={() => handleOrder('service', record)}>
</a>
)}
{(record.orderStatus as number) > OrderStatus.PendingPayment &&
record.orderStatus !== OrderStatus.Cancelled && (
<a key="sale" onClick={() => handleOrder('sales', record)}>
</a>
)}
{record.orderStatus === OrderStatus.PendingAcceptance && (
<a key="sale" onClick={() => handleOrder('sales', record)}>
</a>
)}
<a key="detail" onClick={() => handleDetail(record)}>
</a>
{record.orderStatus === OrderStatus.PendingPayment && (
<PopconfirmForm
ref={popconfirmFormRef}
columns={[
{
title: '备注',
name: 'merchantRemark',
valueType: 'textarea',
fieldProps: { rows: 4, autoFocus: false },
},
]}
onSubmit={(value) => handleUpdate(value, record.id)}
>
<a
key="remark"
onClick={() => popconfirmFormRef.current?.open(record)}
>
</a>
</PopconfirmForm>
)}
</div>,
],
};
const onClose = useCallback(() => {
configurableDrawerRef.current?.close();
}, []);
const handleRow = (record: TradeOrderPageRespVO) => {
return {
'data-record': JSON.stringify(record),
className: 'order-row-with-info',
};
};
const components = {
body: {
row: (props: any) => {
const { children, ...restProps } = props;
const record = props['data-record']
? JSON.parse(props['data-record'])
: undefined;
return (
<>
{record && (
<tr style={{ background: 'rgba(0, 0, 0, 0.06)' }}>
<td
colSpan={columns.length}
style={{
padding: '0px 8px',
borderBottom: '1px solid #f0f0f0',
color: '#666',
}}
>
<Space>
<Badge
status={mapOrderStatusToBadgeStatus(
OrderStatusLabels[record.orderStatus as OrderStatus]
.color,
)}
text={
OrderStatusLabels[record.orderStatus as OrderStatus]
.label
}
size="small"
/>
<Divider />
<span> {record.orderCategoryName}</span>
<span> {record.createTime}</span>
<span>{record.orderNum}</span>
<span> {record.payType}</span>
<Space>
<Avatar icon={<UserOutlined />} src={record.shopLogo} />
{/* <Image src={record.picUrl} width={64} /> */}
{record.shopName || '-'}
</Space>
<Space>
{record.userAvatar ? (
<Avatar src={record.userAvatar} />
) : (
<Avatar icon={<UserOutlined />} />
)}
{record.userNickName || record.userName}
<span>{record.userMobile} </span>
</Space>
</Space>
</td>
</tr>
)}
<tr {...restProps}>{children}</tr>
</>
);
},
},
header: {
cell: (props: any) => {
const { children, ...restProps } = props;
return <th {...restProps}>{children}</th>;
},
},
};
const columns = [...baseOrderColumns, actionColumns];
const handleIsTotal = useCallback(() => {
setIsShowTotal(!isShowTotal);
}, [isShowTotal]);
const handleSearch = useCallback((value: string) => {
console.log('搜索', value);
tableRef.current?.reload();
}, []);
return (
<>
<Space
style={{
padding: '18px',
background: '#fff',
width: '100%',
marginBottom: 16,
}}
>
<Search
placeholder="商品名称/商品ID/订单号"
enterButton
onSearch={handleSearch}
/>
<Button
icon={isShowTotal ? <DownOutlined /> : <UpOutlined />}
onClick={handleIsTotal}
>
</Button>
</Space>
{isShowTotal && (
<ProCard.Group direction="row" style={{ marginBottom: 18 }}>
<ProCard layout="center" style={{ background: '#f5f5f5' }}>
<Statistic
title="订单数量"
value={summary?.orderCount}
precision={2}
/>
</ProCard>
<ProCard layout="center" style={{ background: '#f5f5f5' }}>
<Statistic
title="实付金额"
value={summary?.payPrice}
precision={2}
/>
</ProCard>
<ProCard layout="center" style={{ background: '#f5f5f5' }}>
<Statistic
title="实收金额"
value={summary?.livePrice}
precision={2}
/>
</ProCard>
</ProCard.Group>
)}
<EnhancedProTable<TradeOrderPageRespVO>
ref={tableRef}
columns={columns}
request={onFetch}
headerTitle="销售管理"
showIndex={false}
showSelection={false}
search={{ defaultCollapsed: true }}
onRow={handleRow}
components={components}
/>
<ConfigurableDrawerForm
ref={configurableDrawerRef}
width="80vw"
title={`订单:${modalData?.orderNum}`}
bodyStyle={{
background: '#f5f5f5',
paddingTop: 8,
}}
footer={<Button onClick={onClose}></Button>}
>
<DetailCom data={modalData} />
</ConfigurableDrawerForm>
<CancleOrderModal
open={cancleOrderVisible}
onClose={() => setCancleOrderVisible(false)}
id={modalData?.id}
/>
</>
);
};
export default React.memo(OrderListItem);