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

352 lines
13 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { LinkOutlined, MailOutlined, PhoneOutlined, UserOutlined, WhatsAppOutlined, FieldNumberOutlined } 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 { useShallow } from 'zustand/react/shallow';
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';
import { postEditConversationItemColiAction } from "@/actions/ConversationActions";
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(useShallow(state => state.currentConversation?.coli_sn || ""));
const currentConversationID = useConversationStore(useShallow(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 [resetOrderStore] = useOrderStore(state => [state.resetOrderStore])
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 = result.customerDetail.whatsapp_phone_number || result.customerDetail.phone || 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,
});
});
} else {
resetOrderStore();
}
return () => resetOrderStore()
}, [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();
}, [])
const handleOrderSwitch = async (coli_sn) => {
await postEditConversationItemColiAction({conversationid: currentConversationID, coli_sn });
setChatOrder(coli_sn);
updateCurrentConversation({ coli_sn });
};
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={handleOrderSwitch}
onChange={handleOrderSwitch}
/>}
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>
<FieldNumberOutlined className="pr-1" />
{orderDetail.order_no}
</Typography.Text>
<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>
<Typography.Text>
<span>特殊要求</span>
{orderDetail.customer_request}
</Typography.Text>
<Typography.Text>
<span>外联备注</span>
{orderDetail.wl_memo}
</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;