diff --git a/src/views/Conversations/Online/ConversationBind.jsx b/src/views/Conversations/Online/ConversationBind.jsx new file mode 100644 index 0000000..89b029d --- /dev/null +++ b/src/views/Conversations/Online/ConversationBind.jsx @@ -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) => ( + + ), + }, + ]; + return ( + <> + {currentConversationID && } + { + setOpen(false); + }} + destroyOnClose> + + + + + ); +}; +export default ConversationBindFormModal; diff --git a/src/views/Conversations/Online/order/CustomerProfile.jsx b/src/views/Conversations/Online/order/CustomerProfile.jsx index cef8de0..8c53ef3 100644 --- a/src/views/Conversations/Online/order/CustomerProfile.jsx +++ b/src/views/Conversations/Online/order/CustomerProfile.jsx @@ -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 = (() => { 暂无相关订单} > - + updateCurrentConversation({coli_sn})} /> ) } diff --git a/src/views/orders/AdvanceSearchForm.jsx b/src/views/orders/AdvanceSearchForm.jsx new file mode 100644 index 0000000..b535e50 --- /dev/null +++ b/src/views/orders/AdvanceSearchForm.jsx @@ -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 ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +