放大供应商邮件区域, +搜索, 上下分栏
parent
ac8f12e216
commit
0bac2eae7c
@ -0,0 +1,192 @@
|
||||
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('')
|
||||
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(<EmailBindFormModal key={'bind'} onBoundSuccess={() => setShowBindBtn(false)} {...{conversationid, mai_sn, showBindBtn}} />)
|
||||
btns.push(<Divider key='divider1' type='vertical' />);
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case 'accepted':
|
||||
break
|
||||
case 'sent':
|
||||
case '': // 接收的邮件没有发送状态
|
||||
btns.push(
|
||||
<Button key={'reply'} onClick={() => onOpenEditor(emailMsg.msgOrigin, 'reply')} size='small' type='text' icon={<ReplyIcon className='text-indigo-500' />}>
|
||||
回复
|
||||
</Button>
|
||||
)
|
||||
btns.push(
|
||||
<Button key={'forward'} onClick={() => onOpenEditor(emailMsg.msgOrigin, 'forward')} size='small' type='text' icon={<ShareForwardIcon className='text-primary' />}>
|
||||
转发
|
||||
</Button>
|
||||
)
|
||||
break
|
||||
case 'failed':
|
||||
btns.push(
|
||||
<Button key={'resend'} onClick={() => handleResend()} size='small' type='text' icon={<ResendIcon className='text-orange-500' />}>
|
||||
重发
|
||||
</Button>
|
||||
)
|
||||
btns.push(
|
||||
<Button key={'edit'} onClick={() => onOpenEditor({...(emailMsg.msgOrigin || {}), content: mailData.content}, 'edit')} size='small' type='text' icon={<EditIcon className='text-indigo-500' />}>
|
||||
编辑
|
||||
</Button>
|
||||
)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`flex justify-end items-center w-full ${className || ''}`}>
|
||||
{btns}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='email-container flex flex-col gap-2 *:p-2 *:rounded-sm *:border-b *:border-gray-200 *:shadow-1md'>
|
||||
<div className=' font-bold'>{loading ? <LoadingOutlined className='mr-1' /> : null}{mailData.info?.MAI_Subject || emailMsg?.msgOrigin?.subject}</div>
|
||||
|
||||
<div>
|
||||
<div className={['flex flex-wrap justify-end', window.innerWidth < 600 ? 'flex-col' : 'flex-row '].join(' ')}>
|
||||
<div className=' grow shrink basis-0 flex flex-wrap gap-2 mb-2 items-center'>
|
||||
<Avatar className='' style={TagColorStyle(mailData.info?.MAI_From, true)}>
|
||||
{(mailData.info?.MAI_From || '').substring(0, 1)}
|
||||
</Avatar>
|
||||
<div className=' flex flex-col '>
|
||||
{/* <span className=' font-bold text-base'>{mailData.info?.fromName}</span> */}
|
||||
<span className='text-neutral-500 text-wrap break-words break-all '>{mailData.info?.MAI_From}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className=' shrink-0 flex flex-col justify-start gap-1 items-end'>
|
||||
<ActionBtns />
|
||||
<div className='text-xs '>{mailData.info?.MAI_SendDate || emailMsg.localDate}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='text-sm'>
|
||||
<span className='text-neutral-500 pr-2 w-12 inline-block text-justify' style={{textAlignLast: 'justify'}}>收件人</span>
|
||||
{mailData.info?.MAI_To}
|
||||
</div>
|
||||
{mailData.info?.MAI_CS && (
|
||||
<div className='text-sm'>
|
||||
<span className='text-neutral-500 pr-2 w-12 inline-block text-justify' style={{textAlignLast: 'justify'}}>抄送</span>
|
||||
{mailData.info.MAI_CS}
|
||||
</div>
|
||||
)}
|
||||
{mailData.info?.bcc && (
|
||||
<div className='text-sm'>
|
||||
<span className='text-neutral-500 pr-2 w-12 inline-block text-justify' style={{textAlignLast: 'justify'}}>密送</span>
|
||||
{mailData.info.bcc}
|
||||
</div>
|
||||
)}
|
||||
{mailData.attachments.length > 0 && (
|
||||
<div className='mt-2 *:ml-2'>
|
||||
<span>共{mailData.attachments.length}个附件</span>
|
||||
<div className='flex flex-wrap gap-2'>
|
||||
{mailData.attachments.map((atta) => (
|
||||
<a href={`${EMAIL_ATTA_HOST}${atta.ATI_ServerFile}`} key={atta.ATI_SN} target='_blank' rel='noreferrer'>
|
||||
{atta.ATI_Name}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<Divider className='my-2' />
|
||||
<div className='mt-2 whitespace-pre-wrap' dangerouslySetInnerHTML={{ __html: mailData.content }}></div>
|
||||
</div>
|
||||
</div>
|
||||
{/* todo: */}
|
||||
{/* <EmailEditorPopup
|
||||
open={openEmailEditor}
|
||||
setOpen={setOpenEmailEditor}
|
||||
fromEmail={fromEmail}
|
||||
fromUser={mailData.info?.MAI_OPI_SN || order_opi}
|
||||
fromOrder={mailData.info?.MAI_COLI_SN || coli_sn}
|
||||
conversationid={conversationid}
|
||||
oid={orderDetail.order_no}
|
||||
customerDetail={orderDetail.customerDetail}
|
||||
// emailMsg={ReferEmailMsg}
|
||||
quoteid={mailID}
|
||||
initial={{ ...initialPosition, ...initialSize }}
|
||||
mailData={mailData}
|
||||
action={action}
|
||||
key={`email-detail-inner-${action}-popup_${mailID}`}
|
||||
/> */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default EmailDetailInline
|
@ -0,0 +1,98 @@
|
||||
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, ...props }) => {
|
||||
const [open, setOpen] = useState(false)
|
||||
const [selectedEmail, setSelectedEmail] = useState({})
|
||||
const searchInputRef = useRef(null)
|
||||
const [dataSource, setDataSource] = useState([])
|
||||
useEffect(() => {
|
||||
setDataSource(otherEmailList)
|
||||
|
||||
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 (
|
||||
<>
|
||||
<Button
|
||||
icon={<ExpandIcon />}
|
||||
type={'primary'}
|
||||
className='ml-2'
|
||||
ghost
|
||||
size='small'
|
||||
onClick={() => {
|
||||
setOpen(true)
|
||||
}}
|
||||
/>
|
||||
<Drawer
|
||||
zIndex={3}
|
||||
mask={false}
|
||||
width={600}
|
||||
styles={{ header: {} }}
|
||||
title={`供应商邮件`}
|
||||
classNames={{ header: '!py-1 !px-2', body: '!p-1' }}
|
||||
placement='right'
|
||||
onClose={() => {
|
||||
setOpen(false)
|
||||
}}
|
||||
open={open}>
|
||||
<Input.Search
|
||||
className=''
|
||||
ref={searchInputRef}
|
||||
allowClear
|
||||
onClear={onClearSearch}
|
||||
onPressEnter={(e) => {
|
||||
handleSearch(e.target.value)
|
||||
return false
|
||||
}}
|
||||
onSearch={(v, e, { source }) => handleSearch(v)}
|
||||
placeholder={`输入: 标题/发件人, 回车搜索`}
|
||||
/>
|
||||
<List
|
||||
dataSource={dataSource}
|
||||
pagination={{
|
||||
pageSize: 5,
|
||||
// showLessItems: true,
|
||||
showSizeChanger: false,
|
||||
size: 'small',
|
||||
}}
|
||||
renderItem={(email) => (
|
||||
<List.Item
|
||||
className={`hover:bg-stone-50 cursor-pointer !py-1 ${selectedEmail.MAI_SN === email.MAI_SN ? 'bg-blue-100 font-bold ' : ''}`}
|
||||
onClick={() => {
|
||||
setSelectedEmail(email)
|
||||
}}>
|
||||
<Flex vertical={false} wrap={false} className='w-full'>
|
||||
<div className='flex-auto ml-auto min-w-40 line-clamp-1'>
|
||||
{email.Direction === '收' ? <InboxIcon className='text-indigo-500' /> : <SendPlaneFillIcon className='text-primary' />}
|
||||
{/* <Tooltip title={email.MAI_Subject}> */}
|
||||
<Typography.Text >{email.MAI_Subject}</Typography.Text>
|
||||
{/* </Tooltip> */}
|
||||
</div>
|
||||
<div className='max-w-40'>
|
||||
<Typography.Text ellipsis={{ tooltip: email.SenderReceiver }}>{email.SenderReceiver}</Typography.Text>
|
||||
</div>
|
||||
<div className='max-w-20'>
|
||||
<Typography.Text ellipsis={{ tooltip: email.MAI_SendDate }}>{dayjs(email.MAI_SendDate).format('MM-DD HH:mm')}</Typography.Text>
|
||||
</div>
|
||||
</Flex>
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
<EmailDetailInline {...{ mailID: selectedEmail.MAI_SN }} />
|
||||
</Drawer>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default SupplierEmailDrawer
|
Loading…
Reference in New Issue