邮件详情; `已处理`操作

dev/ckeditor
Lei OT 1 month ago
parent 1ea4dabbc2
commit 04c71b1ff0

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M22 13.3414C21.3744 13.1203 20.7013 13 20 13C16.6863 13 14 15.6863 14 19C14 19.7013 14.1203 20.3744 14.3414 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H21C21.5523 3 22 3.44772 22 4V13.3414ZM12.0606 11.6829L5.64722 6.2377L4.35278 7.7623L12.0731 14.3171L19.6544 7.75616L18.3456 6.24384L12.0606 11.6829ZM19 22L15.4645 18.4645L16.8787 17.0503L19 19.1716L22.5355 15.636L23.9497 17.0503L19 22Z"></path></svg>

After

Width:  |  Height:  |  Size: 504 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M22 14H20V7.23792L12.0718 14.338L4 7.21594V19H14V21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H21C21.5523 3 22 3.44772 22 4V14ZM4.51146 5L12.0619 11.662L19.501 5H4.51146ZM19 22L15.4645 18.4645L16.8787 17.0503L19 19.1716L22.5355 15.636L23.9497 17.0503L19 22Z"></path></svg>

After

Width:  |  Height:  |  Size: 372 B

@ -14,6 +14,7 @@ import ResendLineSVG from '@/assets/icons/reset-left-line.svg?react';
import EditLineSVG from '@/assets/icons/quill-pen-line.svg?react'; import EditLineSVG from '@/assets/icons/quill-pen-line.svg?react';
import MailDownloadLineSVG from '@/assets/icons/mail-download-line.svg?react'; import MailDownloadLineSVG from '@/assets/icons/mail-download-line.svg?react';
import MailAddLineSVG from '@/assets/icons/mail-add-line.svg?react'; import MailAddLineSVG from '@/assets/icons/mail-add-line.svg?react';
import MailCheckSVG from '@/assets/icons/mail-check-line.svg?react';
import TextSVG from '@/assets/icons/text.svg?react'; import TextSVG from '@/assets/icons/text.svg?react';
@ -30,6 +31,7 @@ export const ResendIcon = (props) => <Icon component={ResendLineSVG} {...props}
export const EditIcon = (props) => <Icon component={EditLineSVG} {...props} />; export const EditIcon = (props) => <Icon component={EditLineSVG} {...props} />;
export const MailDownloadIcon = (props) => <Icon component={MailDownloadLineSVG} {...props} />; export const MailDownloadIcon = (props) => <Icon component={MailDownloadLineSVG} {...props} />;
export const MailAddloadIcon = (props) => <Icon component={MailAddLineSVG} {...props} />; export const MailAddloadIcon = (props) => <Icon component={MailAddLineSVG} {...props} />;
export const MailCheckIcon = (props) => <Icon component={MailCheckSVG} {...props} />;
export const TextIcon = (props) => <Icon component={TextSVG} {...props} />; export const TextIcon = (props) => <Icon component={TextSVG} {...props} />;

@ -1,7 +1,7 @@
import React, { useState, useEffect, useRef } from 'react' import React, { useState, useEffect, useRef } from 'react'
const EmailContent = ({ id, content: MailContent, className='', ...props }) => { const EmailContent = ({ id, content: MailContent, className='', ...props }) => {
const [iframeHeight, setIframeHeight] = useState(800) // Initial height const [iframeHeight, setIframeHeight] = useState(5000) // Initial height
const [content, setContent] = useState(MailContent) const [content, setContent] = useState(MailContent)
const iframeRef = useRef(null) const iframeRef = useRef(null)
const containerRef = useRef(null) const containerRef = useRef(null)
@ -29,6 +29,7 @@ const EmailContent = ({ id, content: MailContent, className='', ...props }) => {
padding: 0; padding: 0;
/*overflow-y: hidden;*/ /*overflow-y: hidden;*/
width: 900px; width: 900px;
max-width: 100%;
} }
img { img {
max-width: 90%; max-width: 90%;

@ -1,7 +1,7 @@
import { useState, useEffect } from 'react' import { useState, useEffect, useRef } from 'react'
import { App, Button, Divider, Avatar, List, Flex, Typography } from 'antd' import { App, Button, Divider, Avatar, List, Flex, Typography, Tooltip } from 'antd'
import { LoadingOutlined, ApiOutlined, FilePdfOutlined, FileOutlined, FileWordOutlined, FileExcelOutlined, FileJpgOutlined, FileImageOutlined, FileTextOutlined, FileGifOutlined, GlobalOutlined, FileZipOutlined } from '@ant-design/icons' import { LoadingOutlined, ApiOutlined, FilePdfOutlined, FileOutlined, FileWordOutlined, FileExcelOutlined, FileJpgOutlined, FileImageOutlined, FileTextOutlined, FileGifOutlined, GlobalOutlined, FileZipOutlined } from '@ant-design/icons'
import { EditIcon, ReplyAllIcon, ReplyIcon, ResendIcon, ShareForwardIcon } from '@/components/Icons' import { EditIcon, MailCheckIcon, ReplyAllIcon, ReplyIcon, ResendIcon, ShareForwardIcon } from '@/components/Icons'
import { isEmpty, TagColorStyle } from '@/utils/commons' import { isEmpty, TagColorStyle } from '@/utils/commons'
import EmailEditorPopup from '../Input/EmailEditorPopup' import EmailEditorPopup from '../Input/EmailEditorPopup'
import DnDModal from '@/components/DnDModal' import DnDModal from '@/components/DnDModal'
@ -30,8 +30,19 @@ const extTypeMapped = {
/** /**
* @property {*} emailMsg - 邮件数据. { conversationid, actionId, order_opi, coli_sn, msgOrigin: { from, to, id, email: { subject, mai_sn, } } } * @property {*} emailMsg - 邮件数据. { conversationid, actionId, order_opi, coli_sn, msgOrigin: { from, to, id, email: { subject, mai_sn, } } }
*/ */
const EmailDetailInline = ({ mailID, emailMsg = {}, disabled = false, ...props }) => { const EmailDetailInline = ({ mailID, emailMsg = {}, disabled = false, variant, size, ...props }) => {
// console.log('emailDetail', emailMsg); // console.log('emailDetail', emailMsg);
const componentRef = useRef(null);
const [compactBtn, setCompactBtn] = useState(size==='small');
useEffect(() => {
if (componentRef.current) {
// console.log(componentRef.current.getBoundingClientRect().width);
setCompactBtn(componentRef.current.offsetWidth < 769);
}
return () => {}
}, [])
const { notification, message } = App.useApp() const { notification, message } = App.useApp()
@ -50,7 +61,7 @@ const EmailDetailInline = ({ mailID, emailMsg = {}, disabled = false, ...props }
}, [mailID]) }, [mailID])
const onOpenEditor = (msgOrigin, action='reply') => { const onOpenEditor = (msgOrigin, action='reply') => {
window.open(`/email/${action}/${msgOrigin.email.mai_sn || 0}`, `${action}-${msgOrigin.email.mai_sn || 0}`,POPUP_FEATURES) window.open(`/email/${action}/${mailID || 0}`, `${action}-${mailID || 0}`,POPUP_FEATURES)
console.log('first000', emailMsg) console.log('first000', emailMsg)
console.log('first', msgOrigin) console.log('first', msgOrigin)
if (typeof props.onOpenEditor === 'function') { if (typeof props.onOpenEditor === 'function') {
@ -106,10 +117,11 @@ const EmailDetailInline = ({ mailID, emailMsg = {}, disabled = false, ...props }
let btns = [] let btns = []
btns.push(<Button type='text' onClick={() => { alert('todo')}} icon={<MailCheckIcon className={'text-yellow-600'} />} size='small'>已处理</Button>)
// `` // ``
if (showBindBtn) { if (showBindBtn) {
btns.push(<EmailBindFormModal key={'bind'} onBoundSuccess={() => setShowBindBtn(false)} {...{ conversationid, mai_sn, showBindBtn }} />) btns.push(<EmailBindFormModal key={'bind'} onBoundSuccess={() => setShowBindBtn(false)} {...{ conversationid, mai_sn, showBindBtn }} />)
btns.push(<Divider key='divider1' type='vertical' />) btns.push(<Divider key='divider1' type='vertical' className='mx-0' />)
} }
switch (status) { switch (status) {
@ -118,51 +130,62 @@ const EmailDetailInline = ({ mailID, emailMsg = {}, disabled = false, ...props }
case 'sent': case 'sent':
case '': // case '': //
btns.push( btns.push(
<Tooltip key='reply-t' title='回复'>
<Button key={'reply'} onClick={() => onOpenEditor(emailMsg.msgOrigin, 'reply')} size='small' type='text' icon={<ReplyIcon className='text-indigo-500' />}> <Button key={'reply'} onClick={() => onOpenEditor(emailMsg.msgOrigin, 'reply')} size='small' type='text' icon={<ReplyIcon className='text-indigo-500' />}>
回复 {compactBtn ? '' : '回复'}
</Button>, </Button>
</Tooltip>,
) )
btns.push( btns.push(
<Button key={'replyall'} onClick={() => onOpenEditor(emailMsg.msgOrigin, 'replyall')} size='small' type='text' icon={<ReplyAllIcon className='text-indigo-500' />}> <Tooltip key='replyall-t' title='回复全部'>
回复全部 <Button key={'replyall'} onClick={() => onOpenEditor(emailMsg.msgOrigin, 'replyall')} size='small' type='text' icon={<ReplyAllIcon className='text-indigo-500' />} >{compactBtn ? '' : '回复全部'}</Button>
</Button>, </Tooltip>,
) )
btns.push( btns.push(
<Button key={'forward'} onClick={() => onOpenEditor(emailMsg.msgOrigin, 'forward')} size='small' type='text' icon={<ShareForwardIcon className='text-primary' />}> <Tooltip key='forward-t' title='转发'>
转发 <Button key={'forward'} onClick={() => onOpenEditor(emailMsg.msgOrigin, 'forward')} size='small' type='text' icon={<ShareForwardIcon className='text-primary' />}>{compactBtn ? '' : '转发'}</Button></Tooltip>,
</Button>,
) )
break break
case 'failed': case 'failed':
btns.push( btns.push(
<Button key={'resend'} onClick={() => handleResend()} size='small' type='text' icon={<ResendIcon className='text-orange-500' />}> <Tooltip key='resend-t' title='重发'>
重发 <Button key={'resend'} onClick={() => handleResend()} size='small' type='text' icon={<ResendIcon className='text-orange-500' />}>{compactBtn ? '' : '重发'}</Button></Tooltip>,
</Button>,
) )
btns.push( btns.push(
<Tooltip key='edit-t' title='编辑'>
<Button <Button
key={'edit'} key={'edit'}
onClick={() => onOpenEditor({ ...(emailMsg.msgOrigin || {}), content: mailData.content }, 'edit')} onClick={() => onOpenEditor({ ...(emailMsg.msgOrigin || {}), content: mailData.content }, 'edit')}
size='small' size='small'
type='text' type='text'
icon={<EditIcon className='text-indigo-500' />}> icon={<EditIcon className='text-indigo-500' />}>{compactBtn ? '' : '编辑'}</Button></Tooltip>,
编辑
</Button>,
) )
break break
default: default:
break break
} }
return <div className={`flex justify-end items-center gap-1 w-full ${className || ''}`}>{btns}</div> return <div className={`flex justify-end items-center gap-1 ${className || ''}`}>{btns}</div>
}
const variantCls = (variant) => {
switch (variant) {
case 'outline':
return 'border-y-0 border-x border-solid border-neutral-200'
}
} }
return ( return (
<> <>
<div className='email-container h-full flex flex-col gap-0 divide-y divide-neutral-200 divide-solid *:p-2 *:border-0'> <div ref={componentRef} className={`email-container h-full flex flex-col gap-0 divide-y divide-neutral-200 divide-solid *:p-2 *:border-0 bg-white ${variantCls(variant)}`} >
<div className=''> <div className=''>
{loading ? <LoadingOutlined className='mr-1' /> : null} <div className='flex flex-wrap justify-between'>
<span className=' font-bold '>{mailData.info?.MAI_Subject || emailMsg?.msgOrigin?.subject}</span> <span className=' font-bold '>
{loading ? <LoadingOutlined className='mr-1' /> : null}
{mailData.info?.MAI_Subject || emailMsg?.msgOrigin?.subject}
</span>
<ActionBtns className={'ml-auto'}/>
</div>
<Divider className='my-2' /> <Divider className='my-2' />
<div className={['flex flex-wrap justify-end', window.innerWidth < 600 ? 'flex-col' : 'flex-row '].join(' ')}> <div className={['flex flex-wrap justify-end', window.innerWidth < 600 ? 'flex-col' : 'flex-row '].join(' ')}>
<div className=' flex-auto basis-0 flex flex-wrap gap-2 mb-2 items-center'> <div className=' flex-auto basis-0 flex flex-wrap gap-2 mb-2 items-center'>
@ -175,12 +198,12 @@ const EmailDetailInline = ({ mailID, emailMsg = {}, disabled = false, ...props }
</div> </div>
</div> </div>
<div className=' ml-auto flex flex-col justify-start gap-1 items-end'> <div className=' ml-auto flex flex-col justify-start gap-1 items-end'>
<ActionBtns /> {/* <ActionBtns /> */}
<div className='text-xs '>{mailData.info?.MAI_SendDate || emailMsg.localDate}</div> <div className='text-xs '>{mailData.info?.MAI_SendDate || emailMsg.localDate}</div>
</div> </div>
</div> </div>
<div className='text-sm'> <div className='text-sm'>
<span className='text-neutral-500 pr-2 w-12 inline-block text-justify' style={{ textAlignLast: 'justify' }}> <span className='text-neutral-500 pr-2 w-14 inline-block text-justify' style={{ textAlignLast: 'justify' }}>
收件人 收件人
</span> </span>
{mailData.info?.MAI_To} {mailData.info?.MAI_To}
@ -203,14 +226,14 @@ const EmailDetailInline = ({ mailID, emailMsg = {}, disabled = false, ...props }
)} )}
</div> </div>
<div className='overflow-auto'> <div className='overflow-auto'>
<Flex className=' divide-y-0 divide-x divide-gray-200 divide-solid gap-0'> <Flex className={` divide-gray-200 divide-solid gap-0 ${compactBtn === false ? 'divide-y-0 divide-x' : 'flex-col-reverse divide-x-0 '}`}>
{mailData.info?.mailType === 'text/html' ? ( {mailData.info?.mailType === 'text/html' ? (
<EmailContent content={mailData.content} id={mailID} key={mailID} /> <EmailContent content={mailData.content} id={mailID} key={mailID} />
) : ( ) : (
<div className='mt-2 whitespace-pre-wrap' dangerouslySetInnerHTML={{ __html: mailData.content }}></div> <div className='mt-2 whitespace-pre-wrap' dangerouslySetInnerHTML={{ __html: mailData.content }}></div>
)} )}
{mailData.attachments.length > 0 && ( {mailData.attachments.length > 0 && (
<div className='w-48 overflow-hidden'> <div className={`${compactBtn === false ? 'w-48' : 'border-b border-t-0'} overflow-hidden`}>
<span>&nbsp;附件 ({mailData.attachments.length})</span> <span>&nbsp;附件 ({mailData.attachments.length})</span>
<List <List
dataSource={mailData.attachments || []} dataSource={mailData.attachments || []}

Loading…
Cancel
Save