From 8e13c4042c2bc2c26b6d36e30d353f0ca8799c5d Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 26 Feb 2025 13:49:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=89=8D=E7=AB=AF):=20=E6=94=BE=E5=A4=A7?= =?UTF-8?q?=E4=BE=9B=E5=BA=94=E5=95=86=E9=82=AE=E4=BB=B6=E5=8C=BA=E5=9F=9F?= =?UTF-8?q?,=20+=E6=90=9C=E7=B4=A2,=20=E4=B8=8A=E4=B8=8B=E5=88=86=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Icons.jsx | 4 + .../Online/Components/EmailDetail.jsx | 2 + .../Online/Components/EmailDetailInline.jsx | 197 ++++++++++++++++++ .../Online/Components/SupplierEmailDrawer.jsx | 113 ++++++++++ .../Online/order/CustomerProfile.jsx | 9 +- 5 files changed, 322 insertions(+), 3 deletions(-) create mode 100644 src/views/Conversations/Online/Components/EmailDetailInline.jsx create mode 100644 src/views/Conversations/Online/Components/SupplierEmailDrawer.jsx diff --git a/src/components/Icons.jsx b/src/components/Icons.jsx index d352efe..b861015 100644 --- a/src/components/Icons.jsx +++ b/src/components/Icons.jsx @@ -61,3 +61,7 @@ const Filter = () => ( ) export const FilterIcon = (props) => ; + +const Expand = () => (); + +export const ExpandIcon = (props) => ; diff --git a/src/views/Conversations/Online/Components/EmailDetail.jsx b/src/views/Conversations/Online/Components/EmailDetail.jsx index 830bb00..05b4b6a 100644 --- a/src/views/Conversations/Online/Components/EmailDetail.jsx +++ b/src/views/Conversations/Online/Components/EmailDetail.jsx @@ -9,6 +9,7 @@ import useStyleStore from '@/stores/StyleStore' import { useEmailDetail, } from '@/hooks/useEmail'; import { EMAIL_ATTA_HOST } from '@/config'; import EmailBindFormModal from './EmailBind'; +import EmailDetailInline from './EmailDetailInline'; /** * @property {*} emailMsg - 邮件数据. { conversationid, actionId, order_opi, coli_sn, msgOrigin: { from, to, id, email: { subject, mai_sn, } } } @@ -144,6 +145,7 @@ const EmailDetail = ({ open, setOpen, emailMsg={}, disabled=false, ...props }) = onMove={onHandleMove} onResize={onHandleResize} footer={}> + {/* */}
{mailData.info?.MAI_Subject || emailMsg?.msgOrigin?.subject}
diff --git a/src/views/Conversations/Online/Components/EmailDetailInline.jsx b/src/views/Conversations/Online/Components/EmailDetailInline.jsx new file mode 100644 index 0000000..8e7c605 --- /dev/null +++ b/src/views/Conversations/Online/Components/EmailDetailInline.jsx @@ -0,0 +1,197 @@ +import { useState, useEffect } from 'react' +import { App, Button, Divider, Avatar } from 'antd' +import { LoadingOutlined, ApiOutlined } from '@ant-design/icons'; +import { EditIcon, ReplyIcon, ResendIcon, ShareForwardIcon } from '@/components/Icons' +import { isEmpty, TagColorStyle } from '@/utils/commons' +import EmailEditorPopup from '../Input/EmailEditorPopup' +import DnDModal from '@/components/DndModal' +import useStyleStore from '@/stores/StyleStore' +import { useEmailDetail, } from '@/hooks/useEmail'; +import { EMAIL_ATTA_HOST } from '@/config'; +import EmailBindFormModal from './EmailBind'; + +/** + * @property {*} emailMsg - 邮件数据. { conversationid, actionId, order_opi, coli_sn, msgOrigin: { from, to, id, email: { subject, mai_sn, } } } + */ +const EmailDetailInline = ({ mailID, open, setOpen = () => {}, emailMsg={}, disabled=false, ...props }) => { + + // console.log('emailDetail', emailMsg); + + const {notification, message} = App.useApp() + + const { conversationid, actionId, order_opi, coli_sn } = emailMsg + const { mai_sn, id } = emailMsg.msgOrigin?.email || emailMsg.msgOrigin || {} + // const mailID = mai_sn || id + + const [action, setAction] = useState('') + + const [openEmailEditor, setOpenEmailEditor] = useState(false) + const [fromEmail, setFromEmail] = useState('') + useEffect(() => { + setOpenEmailEditor(false) + + return () => {} + }, [mailID]) + + const onOpenEditor = (msgOrigin, action) => { + const { from, to } = msgOrigin + setOpenEmailEditor(true) + setFromEmail(action === 'edit' ? from : to) + setAction(action) + // setOpen(false) + } + + const { loading, mailData, orderDetail, postEmailResend } = useEmailDetail(mailID) + const [showBindBtn, setShowBindBtn] = useState(false); + useEffect(() => { + setShowBindBtn(isEmpty(mailData.info?.MAI_COLI_SN)) + return () => {} + }, [mailData.info?.MAI_COLI_SN]) + + const handleResend = async () => { + if (isEmpty(mai_sn)) { + return false + } + try { + await postEmailResend({ mai_sn, conversationid, actionId }) + // setOpen(false) + } catch (err) { + notification.error({ + message: "请求失败", + description: err.message, + placement: "top", + duration: 3, + }); + } + } + + /** + * 根据状态, 显示操作 + * * 已保存: [] + * * 已发送: 回复, 转发 + * * 失败: 重发 + * todo: disabled 不显示 + */ + const ActionBtns = ({className, ...props}) => { + const { status } = mailData.info + + let btns = [] + + // 没有关联订单的邮件`绑定订单` + if (showBindBtn) { + btns.push( setShowBindBtn(false)} {...{conversationid, mai_sn, showBindBtn}} />) + btns.push(); + } + + switch (status) { + case 'accepted': + break + case 'sent': + case '': // 接收的邮件没有发送状态 + btns.push( + + ) + btns.push( + + ) + break + case 'failed': + btns.push( + + ) + btns.push( + + ) + break + default: + break + } + + return ( +
+ {btns} +
+ ) + } + + return ( + <> +
+
{loading ? : null}{mailData.info?.MAI_Subject || emailMsg?.msgOrigin?.subject}
+ +
+
+
+ + {(mailData.info?.MAI_From || '').substring(0, 1)} + +
+ {/* {mailData.info?.fromName} */} + {mailData.info?.MAI_From} +
+
+
+ +
{mailData.info?.MAI_SendDate || emailMsg.localDate}
+
+
+
+ 收件人 + {mailData.info?.MAI_To} +
+ {mailData.info?.MAI_CS && ( +
+ 抄送 + {mailData.info.MAI_CS} +
+ )} + {mailData.info?.bcc && ( +
+ 密送 + {mailData.info.bcc} +
+ )} + {mailData.attachments.length > 0 && ( +
+ 共{mailData.attachments.length}个附件 +
+ {mailData.attachments.map((atta) => ( + + {atta.ATI_Name} + + ))} +
+
+ )} + +
+
+
+ + + ) +} +export default EmailDetailInline diff --git a/src/views/Conversations/Online/Components/SupplierEmailDrawer.jsx b/src/views/Conversations/Online/Components/SupplierEmailDrawer.jsx new file mode 100644 index 0000000..b7cbb38 --- /dev/null +++ b/src/views/Conversations/Online/Components/SupplierEmailDrawer.jsx @@ -0,0 +1,113 @@ +import { createContext, useEffect, useState, useRef, useMemo } from 'react' +import { App, Button, Card, Empty, Flex, Select, Spin, Typography, Divider, Modal, List, Row, Col, Tag, Drawer, Input, Tooltip } from 'antd' +import dayjs from 'dayjs' +import { InboxIcon, SendPlaneFillIcon, ExpandIcon } from '@/components/Icons' +import EmailDetailInline from '../Components/EmailDetailInline' +import { debounce, isEmpty } from '@/utils/commons' + +const SupplierEmailDrawer = ({ list: otherEmailList, currentConversationID, opi_sn, oid, ...props }) => { + const [open, setOpen] = useState(false) + const [selectedEmail, setSelectedEmail] = useState({}) + const searchInputRef = useRef(null) + const [dataSource, setDataSource] = useState([]) + useEffect(() => { + setOpen(false); + setDataSource(otherEmailList) + // setSelectedEmail({ MAI_SN: -1000 }); + + return () => {} + }, [otherEmailList]) + const onClearSearch = () => { + setDataSource(otherEmailList) + } + const handleSearch = (value) => { + if (isEmpty(value)) onClearSearch() + const res = otherEmailList.filter((ele) => `${ele.MAI_Subject}${ele.SenderReceiver}`.toLowerCase().includes(value.toLowerCase())) + setDataSource(res) + } + return ( + <> +