|
|
|
@ -10,16 +10,16 @@ import useAuthStore from '@/stores/AuthStore'
|
|
|
|
|
import LexicalEditor from '@/components/LexicalEditor'
|
|
|
|
|
|
|
|
|
|
import { v4 as uuid } from 'uuid'
|
|
|
|
|
import { cloneDeep, debounce, isEmpty, writeIndexDB, readIndexDB, deleteIndexDBbyKey, olog } from '@/utils/commons'
|
|
|
|
|
import { cloneDeep, debounce, isEmpty, writeIndexDB, readIndexDB, deleteIndexDBbyKey, olog, omitEmpty } from '@/utils/commons'
|
|
|
|
|
import '@/views/Conversations/Online/Input/EmailEditor.css'
|
|
|
|
|
import { parseHTMLString, postSendEmail, saveEmailDraftOrSendAction } from '@/actions/EmailActions'
|
|
|
|
|
import { deleteEmailAttachmentAction, parseHTMLString, postSendEmail, saveEmailDraftOrSendAction } from '@/actions/EmailActions'
|
|
|
|
|
import { sentMsgTypeMapped } from '@/channel/bubbleMsgUtils'
|
|
|
|
|
import { EmailBuilder, useEmailDetail, useEmailSignature, useEmailTemplate } from '@/hooks/useEmail'
|
|
|
|
|
import { EmailBuilder, openPopup, useEmailDetail, useEmailSignature, useEmailTemplate } from '@/hooks/useEmail'
|
|
|
|
|
import useSnippetStore from '@/stores/SnippetStore'
|
|
|
|
|
// import { useOrderStore } from '@/stores/OrderStore'
|
|
|
|
|
import PaymentlinkBtn from '@/views/Conversations/Online/Input/PaymentlinkBtn'
|
|
|
|
|
import { TextIcon } from '@/components/Icons';
|
|
|
|
|
import { POPUP_FEATURES } from '@/config';
|
|
|
|
|
import { EMAIL_ATTA_HOST, POPUP_FEATURES } from '@/config';
|
|
|
|
|
|
|
|
|
|
// 禁止上传的附件类型
|
|
|
|
|
// .application, .exe, .app
|
|
|
|
@ -92,23 +92,16 @@ const NewEmail = () => {
|
|
|
|
|
// console.log('emailListMapped', emailListOption, emailListAddrMapped);
|
|
|
|
|
|
|
|
|
|
const mai_sn = pageParam.quoteid // activeEdit.quoteid
|
|
|
|
|
const { loading: quoteLoading, mailData, orderDetail } = useEmailDetail(mai_sn, null, pageParam.oid)
|
|
|
|
|
const { loading: quoteLoading, mailData, orderDetail, postEmailSaveOrSend } = useEmailDetail(mai_sn, null, pageParam.oid)
|
|
|
|
|
const { loading: loadingTamplate, templateContent } = useEmailTemplate(templateKey, {coli_sn: pageParam.oid, opi_sn: orderDetail.opi_sn || mailData.info?.MAI_OPI_SN || 0, lgc: 1});
|
|
|
|
|
const { signature } = useEmailSignature(orderDetail.opi_sn || mailData.info?.MAI_OPI_SN || 0)
|
|
|
|
|
|
|
|
|
|
const [newFromEmail, setNewFromEmail] = useState('')
|
|
|
|
|
const [newToEmail, setNewToEmail] = useState('')
|
|
|
|
|
const [emailOPI, setEmailOPI] = useState('')
|
|
|
|
|
const [emailOrder, setEmailOrder] = useState('')
|
|
|
|
|
const [emailOrderSN, setEmailOrderSN] = useState('')
|
|
|
|
|
const [emailMat, setEmailMat] = useState('')
|
|
|
|
|
|
|
|
|
|
const stateReset = () => {
|
|
|
|
|
setEmailOrder('')
|
|
|
|
|
setEmailOPI('')
|
|
|
|
|
setNewFromEmail('')
|
|
|
|
|
setNewToEmail('')
|
|
|
|
|
}
|
|
|
|
|
// const [newFromEmail, setNewFromEmail] = useState('')
|
|
|
|
|
// const [newToEmail, setNewToEmail] = useState('')
|
|
|
|
|
// const [emailOPI, setEmailOPI] = useState('')
|
|
|
|
|
// const [emailOrder, setEmailOrder] = useState('')
|
|
|
|
|
// const [emailOrderSN, setEmailOrderSN] = useState('')
|
|
|
|
|
// const [emailMat, setEmailMat] = useState('')
|
|
|
|
|
|
|
|
|
|
const [contentPrefix, setContentPrefix] = useState('')
|
|
|
|
|
const [localDraft, setLocalDraft] = useState();
|
|
|
|
@ -165,13 +158,16 @@ const NewEmail = () => {
|
|
|
|
|
// - 从原邮件内容
|
|
|
|
|
// - 从订单
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
console.log('useEffect 1---- \nform.setFieldsValue ');
|
|
|
|
|
// console.log('useEffect 1---- \nform.setFieldsValue ');
|
|
|
|
|
if (isEmpty(mailData.content) && isEmpty(orderDetail.order_no)) {
|
|
|
|
|
return () => {}
|
|
|
|
|
}
|
|
|
|
|
const docTitle = mailData.info?.MAI_Subject || 'New Email-';
|
|
|
|
|
document.title = docTitle
|
|
|
|
|
|
|
|
|
|
const { order_no } = orderDetail
|
|
|
|
|
setContentPrefix(order_no ? `<p>Dear Mr./Ms. ${orderDetail.contact?.[0]?.name || ''}</p><p>Reference Number: ${order_no}</p>` : '')
|
|
|
|
|
|
|
|
|
|
const { info } = mailData
|
|
|
|
|
const { ...templateFormValues } = templateContent;
|
|
|
|
|
|
|
|
|
@ -183,13 +179,12 @@ const NewEmail = () => {
|
|
|
|
|
const _findMatOldE = emailListMatMapped?.[info.MAI_MAT_SN]
|
|
|
|
|
const quotedMailSender = _findMatOldE?.email || ''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const sender = quotedMailSender || orderSender
|
|
|
|
|
const quotedMailSenderObj = sender; // { key: sender, label: sender, value: sender }
|
|
|
|
|
const defaultMAT = emailListAddrMapped?.[sender]?.mat_sn || ''
|
|
|
|
|
|
|
|
|
|
const _form2 = {
|
|
|
|
|
coli_sn: pageParam.oid || info?.coli_sn || '',
|
|
|
|
|
coli_sn: Number(pageParam.oid) || info?.MAI_COLI_SN || '',
|
|
|
|
|
mat_sn: info?.MAI_MAT_SN || defaultMAT,
|
|
|
|
|
opi_sn: info?.MAI_OPI_SN || orderDetail.opi_sn || '',
|
|
|
|
|
}
|
|
|
|
@ -248,21 +243,24 @@ const NewEmail = () => {
|
|
|
|
|
..._form2
|
|
|
|
|
}
|
|
|
|
|
readyToInitialContent = generateMailContent(mailData)
|
|
|
|
|
setFileList(mailData.attachments.map(ele => ({ uid: ele.ATI_SN, name: ele.ATI_Name, url: ele.ATI_ServerFile, fullPath: `${EMAIL_ATTA_HOST}${ele.ATI_ServerFile}` })))
|
|
|
|
|
break
|
|
|
|
|
case 'new':
|
|
|
|
|
_formValues = {
|
|
|
|
|
...templateFormValues,
|
|
|
|
|
from: quotedMailSenderObj,
|
|
|
|
|
to: orderReceiver,
|
|
|
|
|
..._form2
|
|
|
|
|
to: orderReceiver || info?.MAI_To || '',
|
|
|
|
|
subject: `${info.MAI_Subject || ''}`,
|
|
|
|
|
..._form2,
|
|
|
|
|
}
|
|
|
|
|
readyToInitialContent = generateMailContent({ content: templateContent.bodycontent })
|
|
|
|
|
readyToInitialContent = generateMailContent({ content: templateContent.bodycontent || '' })
|
|
|
|
|
setFileList(mailData.attachments.map(ele => ({ uid: ele.ATI_SN, name: ele.ATI_Name, url: ele.ATI_ServerFile, fullPath: `${EMAIL_ATTA_HOST}${ele.ATI_ServerFile}` })))
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
olog('222', _formValues, pageParam.action)
|
|
|
|
|
// olog('222', _formValues, pageParam.action)
|
|
|
|
|
form.setFieldsValue(_formValues) // todo: from
|
|
|
|
|
setInitialContent(readyToInitialContent);
|
|
|
|
|
|
|
|
|
@ -306,27 +304,13 @@ const NewEmail = () => {
|
|
|
|
|
return () => {}
|
|
|
|
|
}, [loadingTamplate])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
console.log('useeffect\n', orderDetail.order_no);
|
|
|
|
|
|
|
|
|
|
setContentPrefix(orderDetail.order_no ? `<p>Dear Mr./Ms. ${orderDetail.contact?.[0]?.name || ''}</p><p>Reference Number: ${orderDetail.order_no}</p>` : '')
|
|
|
|
|
// form.setFieldsValue({ to: orderDetail.contact?.[0]?.email || '' })
|
|
|
|
|
setNewToEmail(orderDetail.contact?.[0]?.email || '')
|
|
|
|
|
|
|
|
|
|
return () => {}
|
|
|
|
|
}, [orderDetail.order_no, editorKey])
|
|
|
|
|
|
|
|
|
|
const handleSwitchEmail = (labelValue) => {
|
|
|
|
|
const { value } = labelValue
|
|
|
|
|
setNewFromEmail(value)
|
|
|
|
|
const handleSwitchEmail = (value) => {
|
|
|
|
|
// const { value } = labelValue
|
|
|
|
|
// setNewFromEmail(value)
|
|
|
|
|
const _findMat = emailListAddrMapped?.[value]
|
|
|
|
|
setEmailMat(_findMat?.mat_sn)
|
|
|
|
|
setEmailOPI(_findMat?.opi_sn)
|
|
|
|
|
form.setFieldsValue({ mat_sn: _findMat?.mat_sn, opi_sn: _findMat?.opi_sn })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const [isRichText, setIsRichText] = useState(mobile === false)
|
|
|
|
|
// const [isRichText, setIsRichText] = useState(false); // 默认纯文本
|
|
|
|
|
const [htmlContent, setHtmlContent] = useState('')
|
|
|
|
@ -348,125 +332,17 @@ const NewEmail = () => {
|
|
|
|
|
setTextContent(textContent)
|
|
|
|
|
form.setFieldValue('content', htmlContent)
|
|
|
|
|
const { bodyText: abstract } = parseHTMLString(htmlContent, true);
|
|
|
|
|
const body = {
|
|
|
|
|
// from: newFromEmail,
|
|
|
|
|
// attaList: fileList,
|
|
|
|
|
// opi_sn: emailOPI,
|
|
|
|
|
// mat_sn: emailMat,
|
|
|
|
|
// coli_sn: emailOrder || '',
|
|
|
|
|
}
|
|
|
|
|
// form.setFieldValue('abstract', getAbstract(textContent))
|
|
|
|
|
debouncedSave({ ...form.getFieldsValue(), ...body, htmlContent, abstract, })
|
|
|
|
|
const formValues = omitEmpty(form.getFieldsValue());
|
|
|
|
|
if (!isEmpty(formValues)) {
|
|
|
|
|
debouncedSave({ ...form.getFieldsValue(), htmlContent, abstract, })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const [initialContent, setInitialContent] = useState('')
|
|
|
|
|
const [showQuoteContent, setShowQuoteContent] = useState(false)
|
|
|
|
|
// const [mergeQuote, setMergeQuote] = useState(true)
|
|
|
|
|
const [quoteContent, setQuoteContent] = useState('')
|
|
|
|
|
|
|
|
|
|
// const setPreFillInProperty = () => { };
|
|
|
|
|
|
|
|
|
|
// useEffect(() => {
|
|
|
|
|
// console.log('useEffect 2---- \nform.setFieldsValue ');
|
|
|
|
|
// const docTitle = localDraft?.subject || mailData.info?.MAI_Subject || 'New Email-';
|
|
|
|
|
// setTimeout(() => {
|
|
|
|
|
// document.title = docTitle
|
|
|
|
|
// }, 1500);
|
|
|
|
|
|
|
|
|
|
// // 没有引用邮件
|
|
|
|
|
// if (isEmpty(pageParam.quoteid)) {
|
|
|
|
|
|
|
|
|
|
// // setEmailOrder(orderDetail.order_no)
|
|
|
|
|
// // setEmailOPI(orderDetail.opi_sn)
|
|
|
|
|
// // setNewFromEmail(activeEdit.fromEmail)
|
|
|
|
|
// // setNewToEmail(activeEdit.toEmail)
|
|
|
|
|
|
|
|
|
|
// // const _findMat = emailListAddrMapped?.[activeEdit.fromEmail]?.mat_sn
|
|
|
|
|
// // setEmailMat(_findMat)
|
|
|
|
|
|
|
|
|
|
// // if (open !== true) {
|
|
|
|
|
// // form.resetFields()
|
|
|
|
|
// // }
|
|
|
|
|
// }
|
|
|
|
|
// // 转发/回复时, 使用详情的账户信息
|
|
|
|
|
// if (mailData.info?.MAI_MAT_SN) {
|
|
|
|
|
// const reEmailO = mailData.info?.MAI_COLI_SN
|
|
|
|
|
// const reEmailUser = mailData.info?.MAI_OPI_SN
|
|
|
|
|
// const reEmailUserMat = mailData.info?.MAI_MAT_SN
|
|
|
|
|
|
|
|
|
|
// setEmailOrder((prev) => reEmailO || prev ) // activeEdit.fromOrder
|
|
|
|
|
// setEmailOPI((prev) => reEmailUser || prev)
|
|
|
|
|
// setEmailMat((prev) => reEmailUserMat || prev)
|
|
|
|
|
|
|
|
|
|
// const _findMatOld = emailListMatMapped?.[reEmailUserMat]
|
|
|
|
|
// if (_findMatOld) {
|
|
|
|
|
// setNewFromEmail(_findMatOld.email)
|
|
|
|
|
// setEmailOPI(_findMatOld.opi_sn)
|
|
|
|
|
// setEmailMat(_findMatOld.mat_sn)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// setShowQuoteContent(false)
|
|
|
|
|
// // setMergeQuote(true)
|
|
|
|
|
// setQuoteContent('')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (isEmpty(pageParam.quoteid) && pageParam.action !== 'new') {
|
|
|
|
|
// return () => {}
|
|
|
|
|
// }
|
|
|
|
|
// const { info } = mailData
|
|
|
|
|
// // setShowCc(!isEmpty(mailData.info?.MAI_CS));
|
|
|
|
|
|
|
|
|
|
// const signatureBody = generateMailContent({ content: signature })
|
|
|
|
|
|
|
|
|
|
// // const preQuoteBody = generateQuoteContent(mailData)
|
|
|
|
|
|
|
|
|
|
// // const _initialContent = isEmpty(mailData.info) ? signatureBody : signatureBody+preQuoteBody
|
|
|
|
|
|
|
|
|
|
// if (!isEmpty(mailData.info) && pageParam.action !== 'edit') {
|
|
|
|
|
// setInitialContent(contentPrefix + signatureBody)
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// const forwardValues = { from: newFromEmail, subject: `Fw: ${info.MAI_Subject || ''}` }
|
|
|
|
|
// if (pageParam.action === 'reply') {
|
|
|
|
|
// const _formValues = {
|
|
|
|
|
// to: info?.replyTo || newFromEmail,
|
|
|
|
|
// cc: info?.MAI_CS || '',
|
|
|
|
|
// // bcc: quote.bcc || '',
|
|
|
|
|
// subject: `Re: ${info.MAI_Subject || ''}`,
|
|
|
|
|
// }
|
|
|
|
|
// form.setFieldsValue(_formValues)
|
|
|
|
|
// } else if (pageParam.action === 'replyall') {
|
|
|
|
|
// const _formValues = {
|
|
|
|
|
// to: info?.replyToAll || newFromEmail,
|
|
|
|
|
// cc: info?.MAI_CS || '',
|
|
|
|
|
// // bcc: quote.bcc || '',
|
|
|
|
|
// subject: `Re: ${info.MAI_Subject || ''}`,
|
|
|
|
|
// }
|
|
|
|
|
// form.setFieldsValue(_formValues)
|
|
|
|
|
// } else if (pageParam.action === 'forward') {
|
|
|
|
|
// form.setFieldsValue(forwardValues)
|
|
|
|
|
// } else if (pageParam.action === 'edit') {
|
|
|
|
|
// const thisFormValues = {
|
|
|
|
|
// to: info?.MAI_To || '',
|
|
|
|
|
// cc: info?.MAI_CS || '',
|
|
|
|
|
// subject: info?.MAI_Subject || '',
|
|
|
|
|
// id: pageParam.quoteid,
|
|
|
|
|
// }
|
|
|
|
|
// form.setFieldsValue(thisFormValues)
|
|
|
|
|
// const thisBody = generateMailContent(mailData)
|
|
|
|
|
// // console.log('thisBody', thisBody);
|
|
|
|
|
|
|
|
|
|
// setInitialContent(thisBody)
|
|
|
|
|
// } else if (pageParam.action === 'new') {
|
|
|
|
|
// // todo: 附件
|
|
|
|
|
// const newEmail = { to: newToEmail, subject: '' }
|
|
|
|
|
// // form.setFieldsValue(newEmail)
|
|
|
|
|
// // setInitialContent((contentPrefix || '') + signatureBody)
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// return () => {}
|
|
|
|
|
// }, [ mailData.info, signature, newToEmail, contentPrefix])
|
|
|
|
|
|
|
|
|
|
const [openPlainTextConfirm, setOpenPlainTextConfirm] = useState(false)
|
|
|
|
|
const handlePlainTextOpenChange = ({ target }) => {
|
|
|
|
|
const { value: newChecked } = target
|
|
|
|
@ -486,18 +362,18 @@ const NewEmail = () => {
|
|
|
|
|
// 1. ~直接上传返回地址~
|
|
|
|
|
// 2. 发送文件信息
|
|
|
|
|
const [fileList, setFileList] = useState([])
|
|
|
|
|
const handleChange = (info) => {
|
|
|
|
|
let newFileList = [...info.fileList]
|
|
|
|
|
// 2. Read from response and show file link
|
|
|
|
|
newFileList = newFileList.map((file) => {
|
|
|
|
|
if (file.response) {
|
|
|
|
|
// Component will show file.url as link
|
|
|
|
|
file.url = file.response.url
|
|
|
|
|
}
|
|
|
|
|
return file
|
|
|
|
|
})
|
|
|
|
|
setFileList(newFileList)
|
|
|
|
|
}
|
|
|
|
|
// const handleChange = (info) => {
|
|
|
|
|
// let newFileList = [...info.fileList]
|
|
|
|
|
// // 2. Read from response and show file link
|
|
|
|
|
// newFileList = newFileList.map((file) => {
|
|
|
|
|
// if (file.response) {
|
|
|
|
|
// // Component will show file.url as link
|
|
|
|
|
// file.url = file.response.url
|
|
|
|
|
// }
|
|
|
|
|
// return file
|
|
|
|
|
// })
|
|
|
|
|
// setFileList(newFileList)
|
|
|
|
|
// }
|
|
|
|
|
const normFile = (e) => {
|
|
|
|
|
// console.log('Upload event:', e);
|
|
|
|
|
if (Array.isArray(e)) {
|
|
|
|
@ -522,7 +398,24 @@ const NewEmail = () => {
|
|
|
|
|
setFileList((prev) => [...prev, file])
|
|
|
|
|
return false // 阻止默认上传, 附件不上传阿里云
|
|
|
|
|
},
|
|
|
|
|
onRemove: (file) => {
|
|
|
|
|
onRemove: async (file) => {
|
|
|
|
|
console.log('onRomove', file)
|
|
|
|
|
if (file.fullPath) {
|
|
|
|
|
try {
|
|
|
|
|
const x = await deleteEmailAttachmentAction([file.uid]);
|
|
|
|
|
message.success(`已删除 ${file.name}`, 2)
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(error)
|
|
|
|
|
notification.error({
|
|
|
|
|
key: editorKey,
|
|
|
|
|
message: '删除失败',
|
|
|
|
|
description: error.message,
|
|
|
|
|
placement: 'top',
|
|
|
|
|
duration: 3,
|
|
|
|
|
})
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const index = fileList.indexOf(file)
|
|
|
|
|
const newFileList = fileList.slice()
|
|
|
|
|
newFileList.splice(index, 1)
|
|
|
|
@ -569,7 +462,10 @@ const NewEmail = () => {
|
|
|
|
|
// win.document.write("<iframe src='" + dataURL + "' width='100%' height='100%' style=\"border:none\"></iframe>");
|
|
|
|
|
resolve(reader.result)
|
|
|
|
|
}
|
|
|
|
|
if (file.type.startsWith('text/') || file.type === 'application/html' || file.type === 'application/xhtml+xml') {
|
|
|
|
|
if (file.fullPath) {
|
|
|
|
|
openPopup(file.fullPath, file.uid)
|
|
|
|
|
}
|
|
|
|
|
else if (file.type.startsWith('text/') || file.type === 'application/html' || file.type === 'application/xhtml+xml') {
|
|
|
|
|
reader.readAsText(file)
|
|
|
|
|
} else {
|
|
|
|
|
reader.readAsDataURL(file)
|
|
|
|
@ -580,102 +476,65 @@ const NewEmail = () => {
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 保存成功, 推一个气泡
|
|
|
|
|
* 再从异步通知更新消息发送状态
|
|
|
|
|
*/
|
|
|
|
|
// const sentOrReceivedNewMessage = useConversationStore((state) => state.sentOrReceivedNewMessage)
|
|
|
|
|
const invokeEmailMessage = (msgObj) => {
|
|
|
|
|
const msgObjMerge = {
|
|
|
|
|
sender: 'me',
|
|
|
|
|
senderName: 'me',
|
|
|
|
|
// to: currentConversation.whatsapp_phone_number,
|
|
|
|
|
date: new Date(),
|
|
|
|
|
status: 'waiting', // accepted
|
|
|
|
|
...msgObj,
|
|
|
|
|
// id: `${currentConversation.sn}.${msgObj.id}`,
|
|
|
|
|
// id: `${stickToCid}.${msgObj.id}`,
|
|
|
|
|
// conversationid: stickToCid,
|
|
|
|
|
msg_source: 'email',
|
|
|
|
|
}
|
|
|
|
|
// olog('invoke upload', msgObjMerge)
|
|
|
|
|
const contentToRender = sentMsgTypeMapped[msgObjMerge.type].contentToRender(msgObjMerge)
|
|
|
|
|
// console.log(contentToRender, 'contentToRender sendMessage------------------');
|
|
|
|
|
// sentOrReceivedNewMessage(contentToRender.conversationid, contentToRender)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const [sendLoading, setSendLoading] = useState(false)
|
|
|
|
|
|
|
|
|
|
const onHandleSaveOrSend = async (isDraft = false) => {
|
|
|
|
|
// console.log('onSend callback', '\nisRichText', isRichText);
|
|
|
|
|
console.log(form.getFieldsValue());
|
|
|
|
|
// console.log(form.getFieldsValue());
|
|
|
|
|
const body = structuredClone(form.getFieldsValue())
|
|
|
|
|
// body.mailtype = ''; // todo: 邮件类型
|
|
|
|
|
// body.id = ''; // todo: 已保存的草稿
|
|
|
|
|
// body.from = newFromEmail // todo:
|
|
|
|
|
body.attaList = fileList
|
|
|
|
|
body.opi_sn = emailOPI
|
|
|
|
|
body.mat_sn = emailMat
|
|
|
|
|
body.coli_sn = emailOrder || ''
|
|
|
|
|
// console.log('body', body, '\n', emailOrder);
|
|
|
|
|
body.attaList = fileList;
|
|
|
|
|
// console.log('body', body, '\n', fileList);
|
|
|
|
|
const values = await form.validateFields()
|
|
|
|
|
const preQuoteBody = pageParam.quoteid ? (quoteContent ? quoteContent : generateQuoteContent(mailData, isRichText)) : ''
|
|
|
|
|
body.mailcontent = isRichText ? EmailBuilder({ subject: values.subject, content: htmlContent + preQuoteBody }) : textContent + preQuoteBody
|
|
|
|
|
body.cc = values.cc || ''
|
|
|
|
|
body.bcc = values.bcc || ''
|
|
|
|
|
const msgObj = {
|
|
|
|
|
type: 'email',
|
|
|
|
|
id: uuid(),
|
|
|
|
|
from: body.from,
|
|
|
|
|
to: values.to,
|
|
|
|
|
cc: values.cc || '',
|
|
|
|
|
bcc: values.bcc || '',
|
|
|
|
|
subject: values.subject,
|
|
|
|
|
content: body.mailcontent,
|
|
|
|
|
email: {
|
|
|
|
|
subject: values.subject,
|
|
|
|
|
content: body.mailcontent,
|
|
|
|
|
},
|
|
|
|
|
coli_id: orderDetail.order_no || (emailOrder ? `{${emailOrder}}` : ''),
|
|
|
|
|
}
|
|
|
|
|
setSendLoading(true)
|
|
|
|
|
body.bcc = values.mailtype || ''
|
|
|
|
|
setSendLoading(!isDraft)
|
|
|
|
|
notification.open({
|
|
|
|
|
key: editorKey,
|
|
|
|
|
placement: 'top',
|
|
|
|
|
// message: '提示',
|
|
|
|
|
description: '正在保存...',
|
|
|
|
|
duration: 0,
|
|
|
|
|
icon: <LoadingOutlined className='text-primary' />,
|
|
|
|
|
closable: false,
|
|
|
|
|
})
|
|
|
|
|
// body.externalID = stickToCid
|
|
|
|
|
// body.actionID = `${stickToCid}.${msgObj.id}`
|
|
|
|
|
body.contenttype = isRichText ? 'text/html' : 'text/plain'
|
|
|
|
|
try {
|
|
|
|
|
const bubbleMsg = cloneDeep(msgObj)
|
|
|
|
|
// bubbleMsg.id = `${stickToCid}.${msgObj.id}`
|
|
|
|
|
// bubbleMsg.email.mai_sn = '';
|
|
|
|
|
bubbleMsg.content = undefined
|
|
|
|
|
// invokeEmailMessage(bubbleMsg);
|
|
|
|
|
|
|
|
|
|
// console.log('postSendEmail', body, '\n', msgObj);
|
|
|
|
|
// return;
|
|
|
|
|
// todo: 保存后不在草稿箱, 在待发目录; 传了ID但每次都新增
|
|
|
|
|
const result = await saveEmailDraftOrSendAction(body, isDraft)
|
|
|
|
|
const mailSavedId = result.id || ''
|
|
|
|
|
bubbleMsg.email.mai_sn = mailSavedId
|
|
|
|
|
// console.log('invokeEmailMessage', bubbleMsg);
|
|
|
|
|
|
|
|
|
|
// invokeEmailMessage(bubbleMsg)
|
|
|
|
|
const mailSavedId = await postEmailSaveOrSend(body, isDraft)
|
|
|
|
|
form.setFieldsValue({
|
|
|
|
|
mai_sn: mailSavedId,
|
|
|
|
|
id: mailSavedId,
|
|
|
|
|
})
|
|
|
|
|
// bubbleMsg.email.mai_sn = mailSavedId
|
|
|
|
|
|
|
|
|
|
// setSendLoading(false);
|
|
|
|
|
|
|
|
|
|
notification.success({
|
|
|
|
|
key: editorKey,
|
|
|
|
|
message: '成功',
|
|
|
|
|
// description: error.message,
|
|
|
|
|
placement: 'top',
|
|
|
|
|
duration: 2,
|
|
|
|
|
showProgress: true,
|
|
|
|
|
pauseOnHover: true,
|
|
|
|
|
onClose: () => {
|
|
|
|
|
deleteIndexDBbyKey(editorKey, 'draft', 'mailbox');
|
|
|
|
|
window.close();
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
if (!isDraft) {
|
|
|
|
|
notification.success({
|
|
|
|
|
key: editorKey,
|
|
|
|
|
message: '成功',
|
|
|
|
|
description: isDraft ? '' : '窗口将自动关闭...',
|
|
|
|
|
placement: 'top',
|
|
|
|
|
duration: 2,
|
|
|
|
|
showProgress: true,
|
|
|
|
|
pauseOnHover: true,
|
|
|
|
|
onClose: () => {
|
|
|
|
|
deleteIndexDBbyKey(editorKey, 'draft', 'mailbox');
|
|
|
|
|
isDraft ? false : window.close();
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
} else { notification.destroy(editorKey) }
|
|
|
|
|
// setOpen(false)
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(error)
|
|
|
|
|
notification.error({
|
|
|
|
|
key: editorKey,
|
|
|
|
|
message: '邮件保存失败',
|
|
|
|
@ -689,9 +548,7 @@ const NewEmail = () => {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const [openDrawerSnippet] = useSnippetStore((state) => [state.openDrawer])
|
|
|
|
|
// const [openPaymentDrawer] = useOrderStore((state) => [state.openDrawer])
|
|
|
|
|
|
|
|
|
|
const [bakData, setBakData] = useState({})
|
|
|
|
|
const idleCallbackId = useRef(null)
|
|
|
|
|
const debouncedSave = useCallback(
|
|
|
|
|
debounce((data) => {
|
|
|
|
@ -702,13 +559,6 @@ const NewEmail = () => {
|
|
|
|
|
}, 1500), // 1.5s
|
|
|
|
|
[],
|
|
|
|
|
)
|
|
|
|
|
const onEditChange = (changedValues, allValues) => {
|
|
|
|
|
console.log('onEditChange', changedValues, '\n', allValues)
|
|
|
|
|
// const { name, value } = e.target;
|
|
|
|
|
// setBakData(prevData => ({ ...prevData, [name]: value }));
|
|
|
|
|
// debouncedSave(bakData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
return () => {
|
|
|
|
|
if (idleCallbackId.current && window.cancelIdleCallback) {
|
|
|
|
@ -716,6 +566,13 @@ const NewEmail = () => {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, [debouncedSave])
|
|
|
|
|
const onEditChange = (changedValues, allValues) => {
|
|
|
|
|
// console.log('onEditChange', changedValues, '\n', allValues)
|
|
|
|
|
if ('from' in changedValues) {
|
|
|
|
|
handleSwitchEmail(allValues.from);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
@ -735,14 +592,14 @@ const NewEmail = () => {
|
|
|
|
|
requiredMark={false}
|
|
|
|
|
// labelCol={{ span: 3 }}
|
|
|
|
|
>
|
|
|
|
|
<div className='w-full flex gap-4 justify-start items-center text-indigo-600 pb-1 mb-2 border-x-0 border-t-0 border-b border-solid border-neutral-200'>
|
|
|
|
|
<div className='w-full flex flex-wrap gap-2 justify-start items-center text-indigo-600 pb-1 mb-2 border-x-0 border-t-0 border-b border-solid border-neutral-200'>
|
|
|
|
|
<Button type='primary' size='middle' onClick={onHandleSaveOrSend} loading={sendLoading} icon={<SendOutlined />}>
|
|
|
|
|
发送
|
|
|
|
|
</Button>
|
|
|
|
|
<Form.Item noStyle name={'from'} rules={[{ required: true, message: '请选择发件地址' }]}>
|
|
|
|
|
<Select labelInValue={false} options={emailListOption} labelRender={item => `发件人: ${item?.label || '选择'}`} variant={'borderless'} placeholder='发件人: 选择' className='[&_.ant-select-selection-item]:font-bold [&_.ant-select-selection-placeholder]:font-bold [&_.ant-select-selection-placeholder]:text-black' classNames={{popup: {root:'min-w-60'}}} />
|
|
|
|
|
<div className="ant-form-item-explain-error text-red-500" >请选择发件地址</div>
|
|
|
|
|
<Form.Item name={'from'} rules={[{ required: true, message: '请选择发件地址' }]} >
|
|
|
|
|
<Select labelInValue={false} options={emailListOption} labelRender={item => `发件人: ${item?.label || '选择'}`} variant={'borderless'} placeholder='发件人: 选择' className='[&_.ant-select-selection-item]:font-bold [&_.ant-select-selection-placeholder]:font-bold [&_.ant-select-selection-placeholder]:text-black' classNames={{popup: {root:'min-w-60'}}} />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
{/* <div className="ant-form-item-explain-error text-red-500" >请选择发件地址</div> */}
|
|
|
|
|
<div className='ml-auto'></div>
|
|
|
|
|
<span>{orderDetail.order_no}</span>
|
|
|
|
|
<span>{templateContent.mailtypeName}</span>
|
|
|
|
@ -789,7 +646,7 @@ const NewEmail = () => {
|
|
|
|
|
</Form.Item>
|
|
|
|
|
<Form.Item name='atta' label='' className='w-full py-1 border-b-0' valuePropName='fileList' getValueFromEvent={normFile}>
|
|
|
|
|
<Flex justify='space-between'>
|
|
|
|
|
<Upload {...uploadProps} name='file' className='w-full'>
|
|
|
|
|
<Upload {...uploadProps} name='file' className='w-full [&_.ant-upload-list-item-name]:cursor-pointer'>
|
|
|
|
|
<Button icon={<UploadOutlined />}>附件</Button>
|
|
|
|
|
</Upload>
|
|
|
|
|
<Flex align={'center'} className='absolute right-0'>
|
|
|
|
|