Merge branch 'main' of github.com:hainatravel/global-sales
commit
1fd2a13a40
@ -0,0 +1,104 @@
|
|||||||
|
import { create } from "zustand";
|
||||||
|
import { VonageClient } from "@vonage/client-sdk";
|
||||||
|
import { fetchJSON } from "@/utils/request";
|
||||||
|
import { prepareUrl, isNotEmpty } from "@/utils/commons";
|
||||||
|
import { VONAGE_URL, DATETIME_FORMAT } from "@/config";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
const callCenterStore = create((set, get) => ({
|
||||||
|
client: new VonageClient({ apiUrl: "https://api-ap-3.vonage.com", websocketUrl: "wss://ws-ap-3.vonage.com" }),
|
||||||
|
call_id: 0,
|
||||||
|
loading: false,
|
||||||
|
logs: "",
|
||||||
|
|
||||||
|
//初始化 Vonage
|
||||||
|
init_vonage: user_id => {
|
||||||
|
const { client, log } = get();
|
||||||
|
set({ loading: true });
|
||||||
|
const fetchUrl = prepareUrl(VONAGE_URL + "/jwt")
|
||||||
|
.append("user_id", user_id)
|
||||||
|
.build();
|
||||||
|
return fetchJSON(fetchUrl).then(json => {
|
||||||
|
if (json.status === 200) {
|
||||||
|
let jwt = json.token;
|
||||||
|
|
||||||
|
client
|
||||||
|
.createSession(jwt)
|
||||||
|
.then(sessionId => {
|
||||||
|
log("Id of created session: ", sessionId);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
log("Error creating session: ", error);
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("sessionError", reason => {
|
||||||
|
// After creating a session
|
||||||
|
log("Session error reason: ", reason);
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("legStatusUpdate", (callId, legId, status) => {
|
||||||
|
// After creating a session
|
||||||
|
log({ callId, legId, status });
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("callInvite", (callId, from, channelType) => {
|
||||||
|
log({ callId, from, channelType }); // Answer / Reject Call
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("callHangup", (callId, callQuality, reason) => {
|
||||||
|
log(`Call ${callId} has hung up, callQuality:${callQuality}, reason:${reason}`);
|
||||||
|
set({ call_id: 0 });
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("sessionError", error => {
|
||||||
|
log({ error });
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw new Error("请求jwt失败");
|
||||||
|
}
|
||||||
|
set({ loading: false });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
log: (...message) => {
|
||||||
|
const { logs } = get();
|
||||||
|
console.log(message);
|
||||||
|
set({ logs: [...logs, dayjs().format(DATETIME_FORMAT) + " : " + JSON.stringify(message)] });
|
||||||
|
},
|
||||||
|
|
||||||
|
// 创建一个语音通话
|
||||||
|
make_call: phone_number => {
|
||||||
|
const { client, log } = get();
|
||||||
|
if (!isNotEmpty(phone_number)) {
|
||||||
|
log("请输入电话号码");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log("开始拨号:" + phone_number);
|
||||||
|
if (client) {
|
||||||
|
set({ loading: true });
|
||||||
|
client
|
||||||
|
.serverCall({ to: phone_number })
|
||||||
|
.then(callId => {
|
||||||
|
log("Id of created call: ", callId);
|
||||||
|
set({ call_id: callId });
|
||||||
|
set({ loading: false });
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
log("Error making call: ", error);
|
||||||
|
set({ loading: false });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 挂断语音通话
|
||||||
|
hang_up: () => {
|
||||||
|
const { client, call_id, log } = get();
|
||||||
|
log("挂断电话");
|
||||||
|
if (call_id) {
|
||||||
|
client.hangup(call_id);
|
||||||
|
set({ call_id: 0 });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
export default callCenterStore;
|
@ -0,0 +1,61 @@
|
|||||||
|
import { useCallback, useState, useEffect } from "react";
|
||||||
|
import { Grid, Divider, Layout, Flex, Spin, Input, Col, Row, List, Typography } from "antd";
|
||||||
|
import { PhoneOutlined, CustomerServiceOutlined, AudioOutlined } from "@ant-design/icons";
|
||||||
|
import { useParams, useHref, useNavigate } from "react-router-dom";
|
||||||
|
import { isEmpty } from "@/utils/commons";
|
||||||
|
|
||||||
|
import callCenterStore from "@/stores/CallCenterStore";
|
||||||
|
import useAuthStore from "@/stores/AuthStore";
|
||||||
|
|
||||||
|
const CallCenter = props => {
|
||||||
|
const href = useHref();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { phonenumber } = useParams();
|
||||||
|
const [init_vonage, make_call, hang_up, logs, call_id, loading] = callCenterStore(state => [state.init_vonage, state.make_call, state.hang_up, state.logs, state.call_id, state.loading]);
|
||||||
|
const [loginUser] = useAuthStore(state => [state.loginUser]);
|
||||||
|
const [phone_number, setPhone_number] = useState(phonenumber);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (loginUser.userId === -1 && href.indexOf("/p/") === -1) {
|
||||||
|
navigate("/p/dingding/login?origin_url=" + href);
|
||||||
|
} else {
|
||||||
|
init_vonage(loginUser.userId);
|
||||||
|
}
|
||||||
|
}, [href, navigate, init_vonage, loginUser]);
|
||||||
|
|
||||||
|
const oncall = () => {
|
||||||
|
if (isEmpty(call_id)) {
|
||||||
|
make_call(phone_number);
|
||||||
|
} else {
|
||||||
|
hang_up();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col md={24} lg={8} xxl={9}></Col>
|
||||||
|
<Col md={24} lg={8} xxl={6}>
|
||||||
|
<Input.Search
|
||||||
|
type="tel"
|
||||||
|
size="large"
|
||||||
|
defaultValue={phone_number}
|
||||||
|
placeholder="电话号码"
|
||||||
|
prefix={<AudioOutlined />}
|
||||||
|
suffix={loading ? <Spin /> : ""}
|
||||||
|
enterButton={call_id ? "挂断" : "拨号"}
|
||||||
|
onSearch={oncall}
|
||||||
|
onChange={e => {
|
||||||
|
setPhone_number(e.target.value);
|
||||||
|
}}></Input.Search>
|
||||||
|
</Col>
|
||||||
|
<Col md={24} lg={8} xxl={9}></Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Divider plain orientation="left" className="mb-0"></Divider>
|
||||||
|
<List header={<Typography.Text strong>Console Logs</Typography.Text>} bordered dataSource={logs} renderItem={item => <List.Item>{item}</List.Item>} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default CallCenter;
|
@ -1,190 +1,231 @@
|
|||||||
import { LinkOutlined, MailOutlined, PhoneOutlined, UserOutlined, WhatsAppOutlined } from '@ant-design/icons'
|
import { LinkOutlined, MailOutlined, PhoneOutlined, UserOutlined, WhatsAppOutlined } from "@ant-design/icons";
|
||||||
import { App, Button, Card, Empty, Flex, Select, Spin, Typography, Divider, Modal } from 'antd'
|
import { App, Button, Card, Empty, Flex, Select, Spin, Typography, Divider, Modal } from "antd";
|
||||||
import { useEffect, useState, useRef } from 'react'
|
import { useEffect, useState, useRef } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { copy, isEmpty } from '@/utils/commons'
|
import { copy, isEmpty } from "@/utils/commons";
|
||||||
import { Conditional } from '@/components/Conditional'
|
import { Conditional } from "@/components/Conditional";
|
||||||
import useConversationStore from '@/stores/ConversationStore'
|
import useConversationStore from "@/stores/ConversationStore";
|
||||||
import { useOrderStore, OrderLabelDefaultOptions, OrderStatusDefaultOptions } from '@/stores/OrderStore'
|
import { useOrderStore, OrderLabelDefaultOptions, OrderStatusDefaultOptions } from "@/stores/OrderStore";
|
||||||
import useAuthStore from '@/stores/AuthStore'
|
import useAuthStore from "@/stores/AuthStore";
|
||||||
import QuotesHistory from './QuotesHistory'
|
import QuotesHistory from "./QuotesHistory";
|
||||||
import ConversationBind from './../ConversationBind';
|
import ConversationBind from "./../ConversationBind";
|
||||||
import ConversationsNewItem from './../ConversationsNewItem';
|
import ConversationsNewItem from "./../ConversationsNewItem";
|
||||||
import { useConversationNewItem } from '@/hooks/useConversation';
|
import { useConversationNewItem } from "@/hooks/useConversation";
|
||||||
|
|
||||||
const CustomerProfile = (() => {
|
const CustomerProfile = () => {
|
||||||
const { notification, message } = App.useApp()
|
const { notification, message } = App.useApp();
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false);
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false)
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
const orderCommentRef = useRef(null)
|
const orderCommentRef = useRef(null);
|
||||||
const currentOrder = useConversationStore((state) => state.currentConversation?.coli_sn || '')
|
const currentOrder = useConversationStore(state => state.currentConversation?.coli_sn || "");
|
||||||
const currentConversationID = useConversationStore((state) => state.currentConversation?.sn || '')
|
const currentConversationID = useConversationStore(state => state.currentConversation?.sn || "");
|
||||||
const [updateCurrentConversation] = useConversationStore(((state) => [state.updateCurrentConversation]));
|
const [updateCurrentConversation] = useConversationStore(state => [state.updateCurrentConversation]);
|
||||||
const loginUser = useAuthStore((state) => state.loginUser)
|
const loginUser = useAuthStore(state => state.loginUser);
|
||||||
const { orderDetail, customerDetail, lastQuotation, quotationList,
|
const { orderDetail, customerDetail, lastQuotation, quotationList, fetchOrderDetail, setOrderPropValue, appendOrderComment } = useOrderStore();
|
||||||
fetchOrderDetail, setOrderPropValue, appendOrderComment
|
|
||||||
} = useOrderStore()
|
|
||||||
|
|
||||||
const orderLabelOptions = copy(OrderLabelDefaultOptions)
|
const navigate = useNavigate();
|
||||||
orderLabelOptions.unshift({ value: 0, label: '未设置', disabled: true, })
|
const orderLabelOptions = copy(OrderLabelDefaultOptions);
|
||||||
|
orderLabelOptions.unshift({ value: 0, label: "未设置", disabled: true });
|
||||||
|
|
||||||
const orderStatusOptions = copy(OrderStatusDefaultOptions)
|
const orderStatusOptions = copy(OrderStatusDefaultOptions);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (currentOrder) {
|
if (currentOrder) {
|
||||||
setLoading(true)
|
setLoading(true);
|
||||||
fetchOrderDetail(currentOrder)
|
fetchOrderDetail(currentOrder)
|
||||||
.finally(() => setLoading(false))
|
.finally(() => setLoading(false))
|
||||||
.catch(reason => {
|
.catch(reason => {
|
||||||
notification.error({
|
notification.error({
|
||||||
message: '查询出错',
|
message: "查询出错",
|
||||||
description: reason.message,
|
description: reason.message,
|
||||||
placement: 'top',
|
placement: "top",
|
||||||
duration: 60,
|
duration: 60,
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}, [currentOrder])
|
}, [currentOrder]);
|
||||||
|
|
||||||
let regularText = ''
|
let regularText = "";
|
||||||
if (orderDetail.buytime > 0) regularText = '(R' + orderDetail.buytime + ')'
|
if (orderDetail.buytime > 0) regularText = "(R" + orderDetail.buytime + ")";
|
||||||
|
|
||||||
const { openOrderContactConversation } = useConversationNewItem();
|
const { openOrderContactConversation } = useConversationNewItem();
|
||||||
const [newChatModalVisible, setNewChatModalVisible] = useState(false);
|
const [newChatModalVisible, setNewChatModalVisible] = useState(false);
|
||||||
const [newChatFormValues, setNewChatFormValues] = useState({});
|
const [newChatFormValues, setNewChatFormValues] = useState({});
|
||||||
const handleNewChat = async (values) => {
|
const handleNewChat = async values => {
|
||||||
const newContact = { wa_id: values.wa_id };
|
const newContact = { wa_id: values.wa_id };
|
||||||
openOrderContactConversation(newContact.wa_id);
|
openOrderContactConversation(newContact.wa_id);
|
||||||
setNewChatModalVisible(false);
|
setNewChatModalVisible(false);
|
||||||
}
|
};
|
||||||
|
|
||||||
if (currentOrder) {
|
if (currentOrder) {
|
||||||
return (
|
return (
|
||||||
<div className='divide-x-0 divide-y divide-dashed divide-gray-300'>
|
<div className="divide-x-0 divide-y divide-dashed divide-gray-300">
|
||||||
<Spin spinning={loading}>
|
<Spin spinning={loading}>
|
||||||
<Card className='p-2 '
|
<Card
|
||||||
|
className="p-2 "
|
||||||
bordered={false}
|
bordered={false}
|
||||||
title={orderDetail.order_no}
|
title={orderDetail.order_no}
|
||||||
actions={[
|
actions={[
|
||||||
<Select key={'orderlabel'} size='small'
|
<Select
|
||||||
|
key={"orderlabel"}
|
||||||
|
size="small"
|
||||||
style={{
|
style={{
|
||||||
width: '100%'
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
variant='borderless'
|
variant="borderless"
|
||||||
onSelect={(value) => {
|
onSelect={value => {
|
||||||
setOrderPropValue(currentOrder, 'orderlabel', value)
|
setOrderPropValue(currentOrder, "orderlabel", value)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
message.success('设置成功')
|
message.success("设置成功");
|
||||||
})
|
})
|
||||||
.catch(reason => {
|
.catch(reason => {
|
||||||
notification.error({
|
notification.error({
|
||||||
message: '设置出错',
|
message: "设置出错",
|
||||||
description: reason.message,
|
description: reason.message,
|
||||||
placement: 'top',
|
placement: "top",
|
||||||
duration: 60,
|
duration: 60,
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
}}
|
}}
|
||||||
value={orderDetail.tags}
|
value={orderDetail.tags}
|
||||||
options={orderLabelOptions}
|
options={orderLabelOptions}
|
||||||
/>,
|
/>,
|
||||||
<Select key={'orderstatus'} size='small'
|
<Select
|
||||||
|
key={"orderstatus"}
|
||||||
|
size="small"
|
||||||
style={{
|
style={{
|
||||||
width: '100%'
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
variant='borderless'
|
variant="borderless"
|
||||||
onSelect={(value) => {
|
onSelect={value => {
|
||||||
setOrderPropValue(currentOrder,'orderstatus', value)
|
setOrderPropValue(currentOrder, "orderstatus", value)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
message.success('设置成功')
|
message.success("设置成功");
|
||||||
})
|
})
|
||||||
.catch(reason => {
|
.catch(reason => {
|
||||||
notification.error({
|
notification.error({
|
||||||
message: '设置出错',
|
message: "设置出错",
|
||||||
description: reason.message,
|
description: reason.message,
|
||||||
placement: 'top',
|
placement: "top",
|
||||||
duration: 60,
|
duration: 60,
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
}}
|
}}
|
||||||
value={orderDetail.states}
|
value={orderDetail.states}
|
||||||
options={orderStatusOptions}
|
options={orderStatusOptions}
|
||||||
/>
|
/>,
|
||||||
]}
|
]}>
|
||||||
>
|
|
||||||
<Flex gap={10}>
|
<Flex gap={10}>
|
||||||
<Flex vertical={true} justify='space-between'>
|
<Flex vertical={true} justify="space-between">
|
||||||
<Typography.Text ><UserOutlined className=' pr-1' />{customerDetail.name + regularText}</Typography.Text>
|
<Typography.Text>
|
||||||
<Typography.Text ><PhoneOutlined className=' pr-1' />{customerDetail.phone}</Typography.Text>
|
<UserOutlined className=" pr-1" />
|
||||||
<Typography.Text ><MailOutlined className=' pr-1' />{customerDetail.email}</Typography.Text>
|
{customerDetail.name + regularText}
|
||||||
|
</Typography.Text>
|
||||||
|
<Typography.Text>
|
||||||
|
<PhoneOutlined className=" pr-1" />
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
size={"small"}
|
||||||
|
onClick={() => {
|
||||||
|
navigate(`/callcenter/call/` + customerDetail.phone);
|
||||||
|
}}>
|
||||||
|
{customerDetail.phone}
|
||||||
|
</Button>
|
||||||
|
</Typography.Text>
|
||||||
|
<Typography.Text>
|
||||||
|
<MailOutlined className=" pr-1" />
|
||||||
|
{customerDetail.email}
|
||||||
|
</Typography.Text>
|
||||||
<Typography.Text>
|
<Typography.Text>
|
||||||
<WhatsAppOutlined className='pr-1' />
|
<WhatsAppOutlined className="pr-1" />
|
||||||
<Button type='link' size={'small'} onClick={() => {
|
<Button
|
||||||
|
type="link"
|
||||||
|
size={"small"}
|
||||||
|
onClick={() => {
|
||||||
setNewChatModalVisible(true);
|
setNewChatModalVisible(true);
|
||||||
setNewChatFormValues(prev => ({...prev, phone_number: customerDetail.whatsapp_phone_number, is_current_order: true, }))
|
setNewChatFormValues(prev => ({ ...prev, phone_number: customerDetail.whatsapp_phone_number, is_current_order: true }));
|
||||||
}} >{customerDetail.whatsapp_phone_number}</Button>
|
}}>
|
||||||
|
{customerDetail.whatsapp_phone_number}
|
||||||
|
</Button>
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Card>
|
</Card>
|
||||||
<Divider orientation='left'><Typography.Text strong>最新报价</Typography.Text></Divider>
|
<Divider orientation="left">
|
||||||
<Flex vertical={true} className='p-2 '>
|
<Typography.Text strong>最新报价</Typography.Text>
|
||||||
|
</Divider>
|
||||||
|
<Flex vertical={true} className="p-2 ">
|
||||||
<Conditional
|
<Conditional
|
||||||
condition={quotationList.length > 0}
|
condition={quotationList.length > 0}
|
||||||
whenFalse={<Empty description={<span>暂无报价</span>}></Empty>}
|
whenFalse={<Empty description={<span>暂无报价</span>}></Empty>}
|
||||||
whenTrue={
|
whenTrue={
|
||||||
<>
|
<>
|
||||||
<p className='m-0 py-2 line-clamp-2 '><a target='_blank' href={lastQuotation.letterurl}><LinkOutlined /> {lastQuotation.lettertitle}</a></p>
|
<p className="m-0 py-2 line-clamp-2 ">
|
||||||
<Flex justify={'space-between'} >
|
<a target="_blank" href={lastQuotation.letterurl}>
|
||||||
|
<LinkOutlined />
|
||||||
|
{lastQuotation.lettertitle}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<Flex justify={"space-between"}>
|
||||||
<QuotesHistory dataSource={quotationList} />
|
<QuotesHistory dataSource={quotationList} />
|
||||||
</Flex>
|
</Flex>
|
||||||
</>
|
</>
|
||||||
}/>
|
}
|
||||||
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Divider orientation='left'><Typography.Text strong>表单信息</Typography.Text></Divider>
|
<Divider orientation="left">
|
||||||
<p className='p-2 overflow-auto m-0 break-words whitespace-pre-wrap' dangerouslySetInnerHTML={{__html: orderDetail.order_detail}}></p>
|
<Typography.Text strong>表单信息</Typography.Text>
|
||||||
<Modal title='添加备注' open={isModalOpen}
|
</Divider>
|
||||||
|
<p className="p-2 overflow-auto m-0 break-words whitespace-pre-wrap" dangerouslySetInnerHTML={{ __html: orderDetail.order_detail }}></p>
|
||||||
|
<Modal
|
||||||
|
title="添加备注"
|
||||||
|
open={isModalOpen}
|
||||||
onOk={() => {
|
onOk={() => {
|
||||||
const orderCommnet = orderCommentRef.current.value
|
const orderCommnet = orderCommentRef.current.value;
|
||||||
if (isEmpty(orderCommnet)) {
|
if (isEmpty(orderCommnet)) {
|
||||||
message.warning('请输入备注后再提交。')
|
message.warning("请输入备注后再提交。");
|
||||||
} else {
|
} else {
|
||||||
appendOrderComment(loginUser.userId, currentOrder, orderCommnet)
|
appendOrderComment(loginUser.userId, currentOrder, orderCommnet)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
message.success('添加成功')
|
message.success("添加成功");
|
||||||
setIsModalOpen(false)
|
setIsModalOpen(false);
|
||||||
})
|
})
|
||||||
.catch(reason => {
|
.catch(reason => {
|
||||||
notification.error({
|
notification.error({
|
||||||
message: '添加出错',
|
message: "添加出错",
|
||||||
description: reason.message,
|
description: reason.message,
|
||||||
placement: 'top',
|
placement: "top",
|
||||||
duration: 60,
|
duration: 60,
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
orderCommentRef.current.value = ''
|
orderCommentRef.current.value = "";
|
||||||
}}
|
}}
|
||||||
onCancel={() => {setIsModalOpen(false)}}>
|
onCancel={() => {
|
||||||
<textarea ref={orderCommentRef} className='w-full' rows={4}></textarea>
|
setIsModalOpen(false);
|
||||||
|
}}>
|
||||||
|
<textarea ref={orderCommentRef} className="w-full" rows={4}></textarea>
|
||||||
</Modal>
|
</Modal>
|
||||||
<Button size={'small'} onClick={() => {
|
<Button
|
||||||
setIsModalOpen(true)
|
size={"small"}
|
||||||
}}>添加备注</Button>
|
onClick={() => {
|
||||||
|
setIsModalOpen(true);
|
||||||
|
}}>
|
||||||
|
添加备注
|
||||||
|
</Button>
|
||||||
</Spin>
|
</Spin>
|
||||||
<ConversationsNewItem initialValues={newChatFormValues} open={newChatModalVisible} onCreate={handleNewChat} onCancel={() => setNewChatModalVisible(false)} />
|
<ConversationsNewItem initialValues={newChatFormValues} open={newChatModalVisible} onCreate={handleNewChat} onCancel={() => setNewChatModalVisible(false)} />
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Empty
|
<Empty description={<span>暂无相关订单</span>}>
|
||||||
description={<span>暂无相关订单</span>}
|
<ConversationBind currentConversationID={currentConversationID} onBoundSuccess={coli_sn => updateCurrentConversation({ coli_sn })} />
|
||||||
>
|
|
||||||
<ConversationBind currentConversationID={currentConversationID} onBoundSuccess={(coli_sn) => updateCurrentConversation({coli_sn})} />
|
|
||||||
</Empty>
|
</Empty>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
})
|
};
|
||||||
|
|
||||||
export default CustomerProfile
|
export default CustomerProfile;
|
||||||
|
Loading…
Reference in New Issue