feat: 关联订单

dev/timezone
Lei OT 1 year ago
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;

@ -8,6 +8,7 @@ import useConversationStore from '@/stores/ConversationStore'
import { useOrderStore, OrderLabelDefaultOptions, OrderStatusDefaultOptions } from '@/stores/OrderStore'
import useAuthStore from '@/stores/AuthStore'
import QuotesHistory from './QuotesHistory'
import ConversationBind from './../ConversationBind';
const CustomerProfile = (() => {
const { notification, message } = App.useApp()
@ -15,6 +16,8 @@ const CustomerProfile = (() => {
const [isModalOpen, setIsModalOpen] = useState(false)
const orderCommentRef = useRef(null)
const currentOrder = useConversationStore((state) => state.currentConversation?.coli_sn || '')
const currentConversationID = useConversationStore((state) => state.currentConversation?.sn || '')
const [updateCurrentConversation] = useConversationStore(((state) => [state.updateCurrentConversation]));
const loginUser = useAuthStore((state) => state.loginUser)
const { orderDetail, customerDetail, lastQuotation, quotationList,
fetchOrderDetail, setOrderPropValue, appendOrderComment
@ -160,14 +163,7 @@ const CustomerProfile = (() => {
<Empty
description={<span>暂无相关订单</span>}
>
<Button type='primary' onClick={() => {
notification.info({
message: '温馨提示',
description: '功能还在开发中,敬请期待',
placement: 'top',
duration: 60,
})
}}>现在关联</Button>
<ConversationBind currentConversationID={currentConversationID} onBoundSuccess={(coli_sn) => updateCurrentConversation({coli_sn})} />
</Empty>
)
}

@ -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…
Cancel
Save