353 lines
10 KiB
TypeScript
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);
|