feat: 关联订单
parent
6a251436fd
commit
ec52917c94
@ -0,0 +1,142 @@
|
||||
import { useState } from 'react';
|
||||
import { App, Modal, Button, Table } from 'antd';
|
||||
import { isEmpty, cloneDeep } from '@/utils/commons';
|
||||
import { fetchJSON } from '@/utils/request';
|
||||
import AdvanceSearchForm from './../../orders/AdvanceSearchForm';
|
||||
import { API_HOST } from '@/config';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const fetchOrderList = async (params) => {
|
||||
const { errcode, result } = await fetchJSON(`${API_HOST}/getdvancedwlorder`, params);
|
||||
return errcode !== 0 ? [] : result;
|
||||
};
|
||||
|
||||
const fetchBindOrder = async (params) => {
|
||||
const { errcode, result } = await fetchJSON(`${API_HOST}/bound_order`, params);
|
||||
return errcode === 0 ? true : false;
|
||||
// return errcode !== 0 ? {} : result;
|
||||
};
|
||||
|
||||
export const ConversationBindFormModal = ({ mobile, currentConversationID, onBoundSuccess }) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const [loading, setLoading] = useState(false); // bind loading
|
||||
const [searchLoading, setSearchLoading] = useState(false);
|
||||
const [searchResult, setSearchResult] = useState([]);
|
||||
|
||||
const { notification, message } = App.useApp();
|
||||
const onSearchOrder = async (values) => {
|
||||
const copyObject = cloneDeep(values);
|
||||
delete copyObject.type;
|
||||
const allEmpty = Object.values(copyObject).every((val) => {
|
||||
return val === null || val === '' || val === undefined;
|
||||
});
|
||||
if (allEmpty) {
|
||||
notification.warning({
|
||||
message: '温馨提示',
|
||||
description: '请输入至少一个条件',
|
||||
placement: 'top',
|
||||
duration: 60,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
values.opisn = 404;
|
||||
setLoading(false);
|
||||
setSearchLoading(true);
|
||||
setSearchResult([]);
|
||||
const result = await fetchOrderList(values);
|
||||
setSearchResult(result);
|
||||
setSearchLoading(false);
|
||||
};
|
||||
const handleBindOrder = async (coli_sn) => {
|
||||
setLoading(true);
|
||||
const success = await fetchBindOrder({ coli_sn, conversationid: currentConversationID });
|
||||
setLoading(false);
|
||||
success ? message.success('绑定成功') : message.error('绑定失败');
|
||||
setOpen(false);
|
||||
if (typeof onBoundSuccess === 'function') {
|
||||
onBoundSuccess(coli_sn);
|
||||
}
|
||||
};
|
||||
const paginationProps = {
|
||||
showQuickJumper: true,
|
||||
showLessItems: true,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => {
|
||||
return `总数:${total}`;
|
||||
},
|
||||
};
|
||||
const searchResultColumns = [
|
||||
{
|
||||
title: '订单号',
|
||||
key: 'COLI_ID',
|
||||
dataIndex: 'COLI_ID',
|
||||
width: 222,
|
||||
},
|
||||
{
|
||||
title: '客人姓名',
|
||||
key: 'coli_guest',
|
||||
dataIndex: 'coli_guest',
|
||||
render: (text, record) => {
|
||||
let regularText = '';
|
||||
if (record.buytime > 0) regularText = '(R' + record.buytime + ')';
|
||||
return text + regularText;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '出发日期',
|
||||
key: 'COLI_OrderStartDate',
|
||||
dataIndex: 'COLI_OrderStartDate',
|
||||
width: 120,
|
||||
hidden: false,
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: (a, b) => {
|
||||
const datejsA = isEmpty(a.COLI_OrderStartDate) ? 0 : new dayjs(a.COLI_OrderStartDate).valueOf();
|
||||
const datejsB = isEmpty(b.COLI_OrderStartDate) ? 0 : new dayjs(b.COLI_OrderStartDate).valueOf();
|
||||
return datejsA - datejsB;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '附加信息',
|
||||
ellipsis: true,
|
||||
key: 'COLI_Introduction',
|
||||
dataIndex: 'COLI_Introduction',
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
key: 'action',
|
||||
width: 150,
|
||||
render: (_, record) => (
|
||||
<Button type={'text'} className='text-primary' onClick={() => handleBindOrder(record.COLI_SN)}>
|
||||
关联此订单
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
return (
|
||||
<>
|
||||
{currentConversationID && <Button type='primary' onClick={() => setOpen(true)} >
|
||||
现在关联
|
||||
</Button>}
|
||||
<Modal
|
||||
width={mobile === undefined ? '95%' : '100%'}
|
||||
open={open}
|
||||
title={'关联订单'}
|
||||
footer={false}
|
||||
onCancel={() => {
|
||||
setOpen(false);
|
||||
}}
|
||||
destroyOnClose>
|
||||
<AdvanceSearchForm onSubmit={onSearchOrder} loading={searchLoading} />
|
||||
<Table
|
||||
key={'advanceOrderTable'}
|
||||
loading={loading}
|
||||
dataSource={searchResult}
|
||||
columns={searchResultColumns}
|
||||
pagination={searchResult.length <= 10 ? false : paginationProps}
|
||||
/>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default ConversationBindFormModal;
|
@ -0,0 +1,155 @@
|
||||
import { OrderLabelDefaultOptions, OrderStatusDefaultOptions, RemindStateDefaultOptions } from '@/stores/OrderStore';
|
||||
import { copy, objectMapper } from '@/utils/commons';
|
||||
import { Button, Col, DatePicker, Form, Input, Row, Select } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import { memo } from 'react';
|
||||
import { DATE_FORMAT, } from '@/config';
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
const formValuesMapper = (values) => {
|
||||
const destinationObject = {
|
||||
'orderNumber': { key: 'coli_id' },
|
||||
'emailOrPhone': { key: 'emailphone' },
|
||||
'firstName': { key: 'firstName' },
|
||||
'lastName': { key: 'lastName' },
|
||||
'orderLabel': { key: 'tag' },
|
||||
'orderStatus': { key: 'orderstate' },
|
||||
'remindState': { key: 'remindstate' },
|
||||
'startDateRange': [
|
||||
{ key: 'startdate', transform: (arrVal) => arrVal ? arrVal[0].format(DATE_FORMAT) : '' },
|
||||
{ key: 'enddate', transform: (arrVal) => arrVal ? arrVal[1].format(DATE_FORMAT) : '' },
|
||||
],
|
||||
'confirmDateRange': [
|
||||
{ key: 'ConfirmDateStart', transform: (arrVal) => arrVal ? arrVal[0].format(DATE_FORMAT): '' },
|
||||
{ key: 'ConfirmDateEnd', transform: (arrVal) => arrVal ? arrVal[1].format(DATE_FORMAT) : ''},
|
||||
],
|
||||
};
|
||||
let dest = {};
|
||||
const { startDateRange, confirmDateRange, ...omittedValue } = values;
|
||||
dest = { ...objectMapper(values, destinationObject) };
|
||||
for (const key in dest) {
|
||||
if (Object.prototype.hasOwnProperty.call(dest, key)) {
|
||||
dest[key] = typeof dest[key] === 'string' ? (dest[key] || '').trim() : dest[key];
|
||||
}
|
||||
}
|
||||
// omit empty
|
||||
Object.keys(dest).forEach((key) => (dest[key] == null || dest[key] === '' || dest[key].length === 0) && delete dest[key]);
|
||||
return dest;
|
||||
}
|
||||
|
||||
const AdvanceSearchForm = memo(function noName({ initialValues, onSubmit, loading }) {
|
||||
const DATE_RANGE_PRESETS = [
|
||||
{
|
||||
label: '本周',
|
||||
value: [dayjs().startOf('w'), dayjs().endOf('w')],
|
||||
},
|
||||
{
|
||||
label: '上周',
|
||||
value: [dayjs().startOf('w').subtract(7, 'days'), dayjs().endOf('w').subtract(7, 'days')],
|
||||
},
|
||||
{
|
||||
label: '本月',
|
||||
value: [dayjs().startOf('M'), dayjs().endOf('M')],
|
||||
},
|
||||
{
|
||||
label: '上月',
|
||||
value: [dayjs().subtract(1, 'M').startOf('M'), dayjs().subtract(1, 'M').endOf('M')],
|
||||
},
|
||||
{
|
||||
label: '前三月',
|
||||
value: [dayjs().subtract(2, 'M').startOf('M'), dayjs().endOf('M')],
|
||||
},
|
||||
{
|
||||
label: '本年',
|
||||
value: [dayjs().startOf('y'), dayjs().endOf('y')],
|
||||
},
|
||||
];
|
||||
|
||||
const orderLabelOptions = copy(OrderLabelDefaultOptions);
|
||||
orderLabelOptions.unshift({ value: '', label: '全部' });
|
||||
|
||||
const orderStatusOptions = copy(OrderStatusDefaultOptions);
|
||||
orderStatusOptions.unshift({ value: '', label: '全部' });
|
||||
|
||||
const remindStateOptions = copy(RemindStateDefaultOptions);
|
||||
remindStateOptions.unshift({ value: '', label: '全部' });
|
||||
|
||||
const [form] = Form.useForm();
|
||||
|
||||
function handleSubmit(values) {
|
||||
console.log('Received values of form, origin form value: ', values);
|
||||
const dest = formValuesMapper(values);
|
||||
console.log('form value send to onSubmit:', dest);
|
||||
onSubmit?.(dest);
|
||||
}
|
||||
|
||||
return (
|
||||
<Form
|
||||
layout={'vertical'}
|
||||
form={form}
|
||||
initialValues={{
|
||||
orderLabel: '',
|
||||
orderStatus: '',
|
||||
remindState: '',
|
||||
...initialValues,
|
||||
}}
|
||||
onFinish={handleSubmit}>
|
||||
<Row justify='start' gutter={16}>
|
||||
<Col span={4}>
|
||||
<Form.Item label='订单号' name='orderNumber'>
|
||||
<Input placeholder='订单号' allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Item label='邮件/电话' name='emailOrPhone'>
|
||||
<Input placeholder='邮件地址/客人电话' allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Item label='First name' name='firstName'>
|
||||
<Input placeholder='First name' allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Item label='Last name' name='lastName'>
|
||||
<Input placeholder='Last name' allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row justify='start' align='middle' gutter={16}>
|
||||
<Col span={2}>
|
||||
<Form.Item label='标签' name='orderLabel'>
|
||||
<Select options={orderLabelOptions} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={2}>
|
||||
<Form.Item label='状态' name='orderStatus'>
|
||||
<Select options={orderStatusOptions} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={2}>
|
||||
<Form.Item label='催信' name='remindState'>
|
||||
<Select options={remindStateOptions} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Item label='出发日期' name='startDateRange'>
|
||||
<RangePicker allowClear={true} inputReadOnly={true} presets={DATE_RANGE_PRESETS} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Item label='确认日期' name='confirmDateRange'>
|
||||
<RangePicker allowClear={true} inputReadOnly={true} presets={DATE_RANGE_PRESETS} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={1} offset={1}>
|
||||
<Button type='primary' htmlType='submit' loading={loading}>
|
||||
搜索
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
);
|
||||
});
|
||||
export default AdvanceSearchForm;
|
Loading…
Reference in New Issue