You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Global-sales/src/views/Conversations/Online/order/CustomerProfile.jsx

330 lines
12 KiB
React

import { LinkOutlined, MailOutlined, PhoneOutlined, UserOutlined, WhatsAppOutlined } from "@ant-design/icons";
import { App, Button, Card, Empty, Flex, Select, Spin, Typography, Divider, Modal, List, Row, Col, Tag } from "antd";
import { useEffect, useState, useRef, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { copy, isEmpty } from "@/utils/commons";
import { Conditional } from "@/components/Conditional";
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";
import ConversationsNewItem from "./../ConversationsNewItem";
import { useConversationNewItem } from "@/hooks/useConversation";
import EmailDetail from './../Components/EmailDetail';
const CustomerProfile = () => {
const { notification, message } = App.useApp();
const [loading, setLoading] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false);
const [currentOrderNumber, setOrderNumber] = useState(false);
const [orderList, setOrderList] = useState([]);
const orderCommentRef = useRef(null);
const currentOrder = useConversationStore(state => state.currentConversation?.coli_sn || "");
const currentConversationID = useConversationStore(state => state.currentConversation?.sn || "");
const channels = useConversationStore(state => state.currentConversation?.channels);
const [updateCurrentConversation] = useConversationStore(state => [state.updateCurrentConversation]);
const [emailMsg, setEmailMsg, detailPopupOpen, setDetailOpen, openDetail] = useConversationStore(state => [state.emailMsg, state.setEmailMsg, state.detailPopupOpen, state.setDetailOpen, state.openDetail]);
const loginUser = useAuthStore(state => state.loginUser);
const [
orderDetail, customerDetail, lastQuotation, quotationList, fetchOrderDetail, setOrderPropValue, appendOrderComment, fetchOtherEmail, otherEmailList, fetchHistoryOrder
] = useOrderStore(s => [
s.orderDetail, s.customerDetail, s.lastQuotation, s.quotationList, s.fetchOrderDetail, s.setOrderPropValue, s.appendOrderComment, s.fetchOtherEmail, s.otherEmailList, s.fetchHistoryOrder
]);
const [chatOrder, setChatOrder] = useState(currentOrder);
const orderLabelOptions = copy(OrderLabelDefaultOptions);
orderLabelOptions.unshift({ value: 0, label: "未设置", disabled: true });
const orderStatusOptions = copy(OrderStatusDefaultOptions);
const getHistoryOrder = (email, whatsappid='') => {
return fetchHistoryOrder(loginUser.userId, email, whatsappid)
.then(orderList => {
const mapOrderList = orderList.map(o => {
return { value: o.coli_sn, label: o.coli_id }
})
setOrderList(mapOrderList)
if (!isEmpty(orderList)) {
setChatOrder(currentOrder)
}
})
}
useEffect(() => {
setChatOrder(currentOrder)
if (currentOrder) {
setLoading(true);
fetchOrderDetail(currentOrder)
.then(result => {
setOrderNumber(result.orderDetail.order_no)
setChatOrder(result.orderDetail.order_no)
const queryEmail = result.customerDetail.email || channels?.email || '';
const queryWA = channels?.whatsapp_phone_number || ''
getHistoryOrder(queryEmail, queryWA)
})
.finally(() => setLoading(false))
.catch(reason => {
notification.error({
message: "查询出错",
description: reason.message,
placement: "top",
duration: 60,
});
});
fetchOtherEmail(currentOrder)
.then(result => {
// console.info(result)
})
.finally(() => setLoading(false))
.catch(reason => {
notification.error({
message: "查询供应商邮件出错",
description: reason.message,
placement: "top",
duration: 60,
});
});
}
}, [currentOrder]);
let regularText = "";
if (orderDetail.buytime > 0) regularText = "(R" + orderDetail.buytime + ")";
const { openOrderContactConversation } = useConversationNewItem();
const [newChatModalVisible, setNewChatModalVisible] = useState(false);
const [newChatFormValues, setNewChatFormValues] = useState({});
const handleNewChat = async values => {
const newContact = { wa_id: values.wa_id };
openOrderContactConversation(newContact.wa_id);
setNewChatModalVisible(false);
};
const handleEmailClick = useCallback((emailItem) => {
const emailMsg = {
conversationid: currentConversationID,
order_opi: orderDetail.opi_sn,
coli_sn: currentOrder,
id: emailItem.MAI_SN,
msgOrigin: {
from: '',
to: '',
id: emailItem.MAI_SN,
email: { mai_sn: emailItem.MAI_SN, subject: emailItem.MAI_Subject, id: emailItem.MAI_SN },
},
}
setEmailMsg(emailMsg);
openDetail();
}, [])
if (currentOrder) {
return (
<div className="divide-x-0 divide-y divide-dashed divide-gray-300">
<Spin spinning={loading}>
<Card
className="p-2 "
bordered={false}
title={<Select
style={{
width: "100%",
}}
variant="borderless"
value={chatOrder}
options={orderList}
onSelect={(x) => {
setChatOrder(x);
updateCurrentConversation({ coli_sn: x });
}}
/>}
actions={[
<Select
key={"orderlabel"}
size="small"
style={{
width: "100%",
}}
variant="borderless"
onSelect={value => {
setOrderPropValue(currentOrder, "orderlabel", value)
.then(() => {
message.success("设置成功");
})
.catch(reason => {
notification.error({
message: "设置出错",
description: reason.message,
placement: "top",
duration: 60,
});
});
}}
value={orderDetail.tags}
options={orderLabelOptions}
/>,
<Select
key={"orderstatus"}
size="small"
style={{
width: "100%",
}}
variant="borderless"
onSelect={value => {
setOrderPropValue(currentOrder, "orderstatus", value)
.then(() => {
message.success("设置成功");
})
.catch(reason => {
notification.error({
message: "设置出错",
description: reason.message,
placement: "top",
duration: 60,
});
});
}}
value={orderDetail.states}
options={orderStatusOptions}
/>,
]}>
<Flex gap={10}>
<Flex vertical={true} justify="space-between">
<Typography.Text>
<UserOutlined className=" pr-1" />
{customerDetail.name + regularText}
</Typography.Text>
<Typography.Text>
<PhoneOutlined className=" pr-1" />
{customerDetail.phone}
</Typography.Text>
<Typography.Text>
<MailOutlined className=" pr-1" />
{customerDetail.email}
</Typography.Text>
<Typography.Text>
<WhatsAppOutlined className="pr-1" />
<Button
type="link"
size={"small"}
onClick={() => {
setNewChatModalVisible(true);
setNewChatFormValues((prev) => ({ ...prev, phone_number: customerDetail.whatsapp_phone_number, name: customerDetail.name, email: customerDetail.email, is_current_order: true }))
}}>
{customerDetail.whatsapp_phone_number}
</Button>
</Typography.Text>
</Flex>
</Flex>
</Card>
<Divider orientation="left">
<Typography.Text strong>最新报价</Typography.Text>
</Divider>
<Flex vertical={true} className="p-2 ">
<Conditional
condition={quotationList.length > 0}
whenFalse={<Empty description={<span>暂无报价</span>}></Empty>}
whenTrue={
<>
<p className="m-0 py-2 line-clamp-2 ">
<a target="_blank" href={lastQuotation.letterurl} rel="noreferrer">
<LinkOutlined />
&nbsp;{lastQuotation.lettertitle}
</a>
</p>
<Flex justify={"space-between"}>
<QuotesHistory dataSource={quotationList} />
</Flex>
</>
}
/>
</Flex>
<Divider orientation="left">
<Typography.Text strong>供应商邮件</Typography.Text>
</Divider>
<List
dataSource={otherEmailList}
pagination={
{
pageSize: 2,
showLessItems: true,
size: 'small'
}
}
renderItem={(email) => (
<List.Item
className='hover:bg-stone-50 cursor-pointer'
onClick={() => {
handleEmailClick(email)
}}>
<Flex
vertical
>
<div><Typography.Text ellipsis={{tooltip: email.SenderReceiver}} style={{width: 280}}><b>From: </b>{email.SenderReceiver}</Typography.Text></div>
<div><Typography.Text ellipsis={{tooltip: email.MAI_Subject}} style={{width: 280}}><b>Subject: </b>{email.MAI_Subject}</Typography.Text></div>
</Flex>
</List.Item>
)}
/>
<Divider orientation="left">
<Typography.Text strong>表单信息</Typography.Text>
</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={() => {
const orderCommnet = orderCommentRef.current.value;
if (isEmpty(orderCommnet)) {
message.warning("请输入备注后再提交。");
} else {
appendOrderComment(loginUser.userId, currentOrder, orderCommnet)
.then(() => {
message.success("添加成功");
setIsModalOpen(false);
})
.catch(reason => {
notification.error({
message: "添加出错",
description: reason.message,
placement: "top",
duration: 60,
});
});
}
orderCommentRef.current.value = "";
}}
onCancel={() => {
setIsModalOpen(false);
}}>
<textarea ref={orderCommentRef} className="w-full" rows={4}></textarea>
</Modal>
<Button
size={"small"}
onClick={() => {
setIsModalOpen(true);
}}>
添加备注
</Button>
</Spin>
<ConversationsNewItem initialValues={newChatFormValues} open={newChatModalVisible} onCreate={handleNewChat} onCancel={() => setNewChatModalVisible(false)} />
<EmailDetail open={detailPopupOpen} setOpen={setDetailOpen} emailMsg={emailMsg} key={`supplier-email-detail-1-${emailMsg?.id}`} />
</div>
);
} else {
return (
<Empty description={<span>暂无相关订单</span>}>
<ConversationBind currentConversationID={currentConversationID} userId={loginUser.userId} onBoundSuccess={coli_sn => updateCurrentConversation({ coli_sn })} />
</Empty>
);
}
};
export default CustomerProfile;