diff --git a/src/hooks/useEmail.js b/src/hooks/useEmail.js index b825ed2..de805e3 100644 --- a/src/hooks/useEmail.js +++ b/src/hooks/useEmail.js @@ -1,7 +1,9 @@ import { useState, useEffect } from 'react' import { isEmpty } from '@/utils/commons' -import { getEmailDetailAction, postResendEmailAction } from '@/actions/EmailActions' -import { App, Button, Divider, Avatar } from 'antd' +import { getEmailDetailAction, postResendEmailAction, } from '@/actions/EmailActions' +import { App } from 'antd' +import useConversationStore from '@/stores/ConversationStore'; +import { msgStatusRenderMapped } from '@/channel/bubbleMsgUtils'; /** * @param mai_sn 邮件编号ID @@ -13,6 +15,8 @@ export const useEmailDetail = (mai_sn, data) => { const [loading, setLoading] = useState(false) const [mailData, setMailData] = useState({ loading, info: {}, content: '', attachments: [] }) + const [updateMessageItem] = useConversationStore(state => [state.updateMessageItem]); + useEffect(() => { const getEmailDetail = async () => { if (isEmpty(mai_sn)) { @@ -43,7 +47,13 @@ export const useEmailDetail = (mai_sn, data) => { return false } await postResendEmailAction({ mai_sn, externalid, actionid, token: 0 }) + // 重发没有状态返回值, 此处前端处理为'待发送', todo: 刷新页面后消息仍为上一个状态'失败' + updateMessageItem({ conversationid: externalid, actionid, id: actionid, status: msgStatusRenderMapped['accepted'] }) } return { loading, mailData, postEmailResend } } + +export const EmailBuilder = ({subject, content}) => { + return `${subject}${content}`; +} diff --git a/src/utils/pagespy.js b/src/utils/pagespy.js index 13f2c98..8ded402 100644 --- a/src/utils/pagespy.js +++ b/src/utils/pagespy.js @@ -12,8 +12,9 @@ export const loadPageSpy = (title) => { ]; Promise.all(PageSpySrc.map((src) => loadScript(src))).then(() => { // 注册插件 - PageSpy.registerPlugin(new DataHarborPlugin({ maximum: 2 * 1024 * 1024 })); + PageSpy.registerPlugin(new DataHarborPlugin({ maximum: 10 * 1024 * 1024 })); + PageSpy.registerPlugin(new RRWebPlugin()); // 实例化 PageSpy - window.$pageSpy = new PageSpy({ api: 'page-spy.mycht.cn', project: 'Sales CRM', title: title + '(v' + BUILD_VERSION + ')', autoRender: false }); + window.$pageSpy = new PageSpy({ api: 'page-spy.mycht.cn', project: 'Sales CRM', title: title + '(v' + BUILD_VERSION + ')', autoRender: false, offline: false, }); }); }; diff --git a/src/views/Conversations/Online/Input/EmailEditorPopup.jsx b/src/views/Conversations/Online/Input/EmailEditorPopup.jsx index ea776dc..690a512 100644 --- a/src/views/Conversations/Online/Input/EmailEditorPopup.jsx +++ b/src/views/Conversations/Online/Input/EmailEditorPopup.jsx @@ -10,11 +10,11 @@ import useAuthStore from '@/stores/AuthStore'; import LexicalEditor from '@/components/LexicalEditor'; import { v4 as uuid } from 'uuid'; -import { cloneDeep, isEmpty } from '@/utils/commons'; +import { cloneDeep, isEmpty, } from '@/utils/commons'; import './EmailEditor.css'; import { postSendEmail } from '@/actions/EmailActions'; import { sentMsgTypeMapped, } from '@/channel/bubbleMsgUtils'; -import { useEmailDetail } from '@/hooks/useEmail'; +import { EmailBuilder, useEmailDetail } from '@/hooks/useEmail'; import useSnippetStore from '@/stores/SnippetStore' import { useOrderStore } from '@/stores/OrderStore' @@ -92,6 +92,7 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, fromOrder, oid, const [stickToProps, setStickToProps] = useState({}); + const [propsSerialize, setPropsSerialize] = useState(''); const [newFromEmail, setNewFromEmail] = useState(''); const [newToEmail, setNewToEmail] = useState(''); @@ -113,9 +114,12 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, fromOrder, oid, // 否则, 会话列表切换之后, 会话ID更新, 导致消息关联错误 const [stickToCid, setStickToCid] = useState(conversationid); useEffect(() => { + const propsObj = { open, setOpen, fromEmail, fromUser, fromOrder, oid, toEmail, conversationid, quoteid, mai: _mailData?.info?.MAI_MAT_SN, action, draft } + + // 没有引用邮件 if (isEmpty(quoteid)) { - // console.log('emailEditorPopup effect', open, '\nto', toEmail) - setStickToProps({ fromEmail, fromUser, fromOrder, oid, toEmail, conversationid, quoteid, action, draft }); + setStickToProps(propsObj) + setPropsSerialize(JSON.stringify(propsObj)) setStickToCid(conversationid) setEmailOrder(fromOrder) @@ -127,35 +131,29 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, fromOrder, oid, setEmailMat(_findMat) // if (open !== true) { - // form.resetFields() + // form.resetFields() // } } - - return () => { - stateReset() - form.resetFields() - } - }, [open]) - - // 转发/回复时, 使用详情的账户信息 - useEffect(() => { - 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); - 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) + // 转发/回复时, 使用详情的账户信息 + 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) + 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) + } } return () => {} - }, [mailData, open]) + }, [open, mailData]) const handleSwitchEmail = (labelValue) => { const { value } = labelValue @@ -195,15 +193,15 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, fromOrder, oid, // console.log('quoteid', quoteid, isEmpty(quoteid), isEmpty(mailData.info)); if (isEmpty(quoteid) && action !== 'new') { - return () => {}; + return () => {} } - const { info, } = mailData + const { info } = mailData // setShowCc(!isEmpty(mailData.info?.MAI_CS)); - const preQuoteBody = generateQuoteContent(mailData); + const preQuoteBody = generateQuoteContent(mailData) - if ( !isEmpty(mailData.info) && action !== 'edit') { - setInitialContent(preQuoteBody); + if (!isEmpty(mailData.info) && action !== 'edit') { + setInitialContent(preQuoteBody) } const _formValues = { @@ -211,36 +209,36 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, fromOrder, oid, cc: info?.MAI_CS || '', // bcc: quote.bcc || '', subject: `Re: ${info.MAI_Subject || ''}`, - }; - const forwardValues = { from: newFromEmail, subject: `Fw: ${info.MAI_Subject || ''}` }; + } + const forwardValues = { from: newFromEmail, subject: `Fw: ${info.MAI_Subject || ''}` } if (action === 'reply') { - form.setFieldsValue(_formValues); - setInitialForm(_formValues); + form.setFieldsValue(_formValues) + setInitialForm(_formValues) } else if (action === 'forward') { - setStickToCid('0'); - form.setFieldsValue(forwardValues); - setInitialForm(forwardValues); + setStickToCid('0') + form.setFieldsValue(forwardValues) + setInitialForm(forwardValues) } else if (action === 'edit') { const thisFormValues = { to: info?.MAI_To || '', cc: info?.MAI_CS || '', subject: info?.MAI_Subject || '', - }; - form.setFieldsValue(thisFormValues); - setInitialForm(thisFormValues); - const thisBody = generateMailContent(mailData); + } + form.setFieldsValue(thisFormValues) + setInitialForm(thisFormValues) + const thisBody = generateMailContent(mailData) // console.log('thisBody', thisBody); setInitialContent(thisBody) } else if (action === 'new') { const newEmail = { to: newToEmail, subject: draft?.subject || '' } - form.setFieldsValue(newEmail); - setInitialForm(newEmail); - setInitialContent(draft?.content || ''); + form.setFieldsValue(newEmail) + setInitialForm(newEmail) + setInitialContent(draft?.content || '') } - return () => {}; - }, [stickToProps, mailData.info, draft, newToEmail, newFromEmail]); + return () => {} + }, [propsSerialize, mailData.info, newToEmail, newFromEmail]); const [openPlainTextConfirm, setOpenPlainTextConfirm] = useState(false); const handlePlainTextOpenChange = ({ target }) => { @@ -385,7 +383,6 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, fromOrder, oid, // console.log('onSend callback', '\nisRichText', isRichText); // console.log(form.getFieldsValue()); const body = structuredClone(form.getFieldsValue()); - body.mailcontent = isRichText ? htmlContent : textContent; body.from = newFromEmail; body.attaList = fileList; body.opi_sn = emailOPI; @@ -393,6 +390,7 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, fromOrder, oid, body.coli_sn = emailOrder || ''; // console.log('body', body, '\n', emailOrder); const values = await form.validateFields(); + body.mailcontent = isRichText ? EmailBuilder({ subject: values.subject, content: htmlContent }) : textContent body.cc = values.cc || ''; body.bcc = values.bcc || ''; const msgObj = { @@ -408,7 +406,7 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, fromOrder, oid, subject: values.subject, content: body.mailcontent, }, - coli_id: stickToProps.oid || `{${emailOrder}}` + coli_id: stickToProps.oid || (emailOrder ? `{${emailOrder}}` : ''), } setSendLoading(true); body.externalID = stickToCid; @@ -420,6 +418,7 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, fromOrder, oid, bubbleMsg.content = undefined; // invokeEmailMessage(bubbleMsg); + // console.log('postSendEmail', body, '\n', msgObj); const result = await postSendEmail(body); const mailSavedId = result.id || ''; bubbleMsg.email.mai_sn = mailSavedId; @@ -457,6 +456,7 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, fromOrder, oid, initial={{ width: window.innerWidth-600, height: window.innerHeight-40, left: 300 + 24, top: 20 }} onCancel={() => { form.resetFields(); + stateReset() }} title={ <> @@ -485,7 +485,7 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, fromOrder, oid,
{ ? 'Enter 发送, Shift+Enter 换行' : 'Enter 换行'; - const [fromIM, setFromIM] = useState(''); + const [fromIM, setFromIM] = useState(DEFAULT_WABA); useEffect(() => { switch (channel) { case 'waba': - setFromIM(whatsAppBusiness) + setFromIM(whatsAppBusiness || DEFAULT_WABA) break case 'wa': setFromIM('') // todo: 个人WhatsApp号 break default: + setFromIM(DEFAULT_WABA) break }