diff --git a/src/actions/ConversationActions.js b/src/actions/ConversationActions.js index ffd7c78..dc79094 100644 --- a/src/actions/ConversationActions.js +++ b/src/actions/ConversationActions.js @@ -57,9 +57,9 @@ export const fetchConversationsList = async (params) => { /** * - * @param {object} params { opisn, whatsappid, colisn } + * @param {object} params { opisn, whatsappid, colisn, email } * * opisn, colisn : 用于查询 - * * whatsappid: 用于创建会话 + * * whatsappid, email: 用于创建会话 */ export const fetchOrderConversationsList = async (params) => { const { errcode, result: data } = await fetchJSON(`${API_HOST}/getorderconversation`, params); diff --git a/src/channel/bubbleMsgUtils.js b/src/channel/bubbleMsgUtils.js index c23303f..e894074 100644 --- a/src/channel/bubbleMsgUtils.js +++ b/src/channel/bubbleMsgUtils.js @@ -43,8 +43,6 @@ export const WABAccounts = [ } ]; export const WABAccountsMapped = WABAccounts.reduce((a, c) => ({ ...a, [removeFirstPlus(c.phoneNumber)]: c, [c.phoneNumber]: c }), {}) -console.log(WABAccountsMapped); - export const replaceTemplateString = (str, replacements) => { let result = str; diff --git a/src/components/LexicalEditor/plugins/InlineImagePlugin/index.tsx b/src/components/LexicalEditor/plugins/InlineImagePlugin/index.tsx index 17c924d..31ff3dd 100644 --- a/src/components/LexicalEditor/plugins/InlineImagePlugin/index.tsx +++ b/src/components/LexicalEditor/plugins/InlineImagePlugin/index.tsx @@ -170,7 +170,7 @@ export function InsertInlineImageDialog({ data-test-id="image-modal-file-upload-btn" disabled={isDisabled} onClick={() => handleOnClick()}> - Confirm + {uploading ? 'Uploading, Pls wait...' : 'Confirm'} > diff --git a/src/stores/ConversationStore.js b/src/stores/ConversationStore.js index 598fd1c..b257ec2 100644 --- a/src/stores/ConversationStore.js +++ b/src/stores/ConversationStore.js @@ -339,7 +339,7 @@ const messageSlice = (set, get) => ({ // msgUpdate // console.log('UPDATE_SENT_MESSAGE_ITEM-----------------------------------------------------------------', message); // 更新会话中的消息 - const { activeConversations, conversationsList, currentConversation } = get(); + const { activeConversations, conversationsList, currentConversation, setFilter } = get(); const targetId = message.conversationid; const targetMsgs = (activeConversations[String(targetId)] || []).map((ele) => { // 更新状态 @@ -395,6 +395,7 @@ const messageSlice = (set, get) => ({ } const mergedList = [...newConversations, ...conversationsList] const mergedListMapped = groupBy(mergedList, 'top_state'); + setFilter({ loadNextPage: true }); return set({ topList: mergedListMapped['1'] || [], @@ -405,7 +406,7 @@ const messageSlice = (set, get) => ({ }, sentOrReceivedNewMessage: (targetId, message) => { // msgRender: - const { activeConversations, conversationsList, currentConversation, totalNotify } = get(); + const { activeConversations, conversationsList, currentConversation, totalNotify, setFilter } = get(); const targetMsgs = activeConversations[String(targetId)] || []; const targetIndex = conversationsList.findIndex((ele) => Number(ele.sn) === Number(targetId)); const lastReceivedTime = (message.type !== 'system' && message.sender !== 'me') ? dayjs(message.date).add(8, 'hours').format(DATETIME_FORMAT) : null; @@ -444,6 +445,7 @@ const messageSlice = (set, get) => ({ // console.log('find in list, chat updated and Top: \n', JSON.stringify(newConversation, null, 2)); // console.log('list updated : \n', JSON.stringify(conversationsList, null, 2)); const mergedListMapped = groupBy(conversationsList, 'top_state'); + setFilter({ loadNextPage: true }); const isCurrent = Number(targetId) === Number(currentConversation.sn); const updatedCurrent = isCurrent @@ -483,8 +485,11 @@ export const useConversationStore = create( setInitial: (v) => set({ initialState: v }), // side effects - fetchInitialData: async ({userId, userIds, whatsAppBusiness, ...loginUser}) => { - const { setTemplates, setInitial, setTags } = get(); + fetchInitialData: async ({userId, whatsAppBusiness, ...loginUser}) => { + const { addToConversationList, setTemplates, setInitial, setTags } = get(); + + const conversationsList = await fetchConversationsList({ opisn: userId }); + addToConversationList(conversationsList); const templates = await fetchTemplates({ waba: whatsAppBusiness }); setTemplates(templates); diff --git a/src/views/Conversations/Online/Components/ChatListFilter.jsx b/src/views/Conversations/Online/Components/ChatListFilter.jsx index 7ae955f..12578f0 100644 --- a/src/views/Conversations/Online/Components/ChatListFilter.jsx +++ b/src/views/Conversations/Online/Components/ChatListFilter.jsx @@ -1,9 +1,8 @@ import React, { useState, useEffect } from 'react'; -import { Button, Tag, Radio, Popover, Form, Divider } from 'antd'; -import { FilterOutlined, FilterTwoTone } from '@ant-design/icons'; -import { debounce, isEmpty, isNotEmpty, objectMapper, stringToColour } from '@/utils/commons'; +import { Button, Tag, Radio, Popover, Form } from 'antd'; +import { isEmpty, objectMapper, stringToColour } from '@/utils/commons'; import useConversationStore from '@/stores/ConversationStore'; -import { OrderLabelDefaultOptions, OrderStatusDefaultOptions } from '@/stores/OrderStore'; +import { OrderLabelDefaultOptions } from '@/stores/OrderStore'; import { FilterIcon } from '@/components/Icons'; const otypes = [ diff --git a/src/views/Conversations/Online/Components/ChatListItem.jsx b/src/views/Conversations/Online/Components/ChatListItem.jsx index b3291f1..3f10316 100644 --- a/src/views/Conversations/Online/Components/ChatListItem.jsx +++ b/src/views/Conversations/Online/Components/ChatListItem.jsx @@ -64,7 +64,7 @@ const NewTagForm = ({onSubmit,...props}) => { ); }; -const ChatListItem = (({item, refreshConversationList,setListUpdateFlag,onSwitchConversation,tabSelectedConversation, setNewChatModalVisible,setEditingChat,...props}) => { +const ChatListItem = (({item, refreshConversationList,setListUpdateFlag,onSwitchConversation, setNewChatModalVisible,setEditingChat,...props}) => { const [mobile] = useStyleStore((state) => [state.mobile]); const routerReplace = mobile === false ? true : false; // : true; @@ -243,8 +243,6 @@ const ChatListItem = (({item, refreshConversationList,setListUpdateFlag,onSwitch // item.top_state === 1 ? 'bg-stone-100' : '', String(item.sn) === String(currentConversation.sn) ? '__active text-primary bg-whatsapp-bg' - : String(item.sn) === String(tabSelectedConversation?.sn) - ? ' bg-neutral-200' : item.top_state === 1 ? 'bg-stone-100' : '', diff --git a/src/views/Conversations/Online/Components/EmailDetail.jsx b/src/views/Conversations/Online/Components/EmailDetail.jsx index 619892a..7146299 100644 --- a/src/views/Conversations/Online/Components/EmailDetail.jsx +++ b/src/views/Conversations/Online/Components/EmailDetail.jsx @@ -24,7 +24,7 @@ const EmailDetail = ({ open, setOpen, emailMsg, ...props }) => { const {notification, message} = App.useApp() - const { conversationid, actionId, order_opi } = emailMsg + const { conversationid, actionId, order_opi, coli_sn } = emailMsg const { mai_sn, id } = emailMsg.msgOrigin?.email || emailMsg.msgOrigin || {} const mailID = mai_sn || id const [initialPosition, setInitialPosition] = useState({}) @@ -163,7 +163,7 @@ const EmailDetail = ({ open, setOpen, emailMsg, ...props }) => {
${mailData.content} @@ -65,52 +65,89 @@ const generateMailContent = (mailData) => ` ${mailData.content}
` -const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, toEmail, conversationid, quoteid, initial = {}, mailData: _mailData, action = 'reply', ...props }) => { +/** + * @property {string} fromEmail - 发件人邮箱 + * @property {string} fromUser - 发件人用户 + * @property {string} fromOrder - 发件人订单 + * @property {string} toEmail - 收件人邮箱 + * @property {string} conversationid - 会话ID + * @property {string} quoteid - 引用邮件ID + */ +const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, fromOrder, toEmail, conversationid, quoteid, initial = {}, mailData: _mailData, action = 'reply', ...props }) => { + const { notification, message } = App.useApp(); + const [form] = Form.useForm(); + const [mobile] = useStyleStore((state) => [state.mobile]); const [userId, username, emailList] = useAuthStore((state) => [state.loginUser.userId, state.loginUser.username, state.loginUser.emailList]); const emailListOption = emailList?.map(ele => ({ ...ele, label: ele.email, key: ele.email, value: ele.email })) || []; - const emailListMapped = emailListOption?.reduce((r, v) => ({ ...r, [v.opi_sn]: v }), {}); + // const emailListMapped = emailListOption?.reduce((r, v) => ({ ...r, [v.opi_sn]: v }), {}); const emailListAddrMapped = emailListOption?.reduce((r, v) => ({ ...r, [v.email]: v }), {}); const emailListMatMapped = emailListOption?.reduce((r, v) => ({ ...r, [v.mat_sn]: v }), {}); // console.log('emailListMapped', emailListOption, emailListAddrMapped); const mai_sn = quoteid; - const { loading, mailData } = useEmailDetail(mai_sn, _mailData) + const { loading: getLoading, mailData } = useEmailDetail(mai_sn, _mailData) - const [newFromEmail, setNewFromEmail] = useState(fromEmail); - const [newToEmail, setNewToEmail] = useState(toEmail); - const [emailOPI, setEmailOPI] = useState(fromUser); + const [stickToProps, setStickToProps] = useState({}); + + const [newFromEmail, setNewFromEmail] = useState(''); + const [newToEmail, setNewToEmail] = useState(''); + const [emailOPI, setEmailOPI] = useState(''); + const [emailOrder, setEmailOrder] = useState(''); const [emailMat, setEmailMat] = useState(''); - useEffect(() => { - const emailUser = mailData.info?.MAI_OPI_SN || fromUser // quote.order_opi - const emailUserMat = mailData.info?.MAI_MAT_SN - // const _default = - // emailListOption?.find((ele) => ele.opi_sn === emailUser && ele.default === true) || - // emailListOption?.find((ele) => ele.opi_sn === emailUser && ele.backup === true) || - // emailListOption?.find((ele) => ele.opi_sn === emailUser) || - // emailListOption?.find((ele) => ele.default === true) || - // emailListOption?.find((ele) => ele.backup === true) + // 存储: 会话ID, + // 这个窗口没有模态, 即使不是focus, 还是需要保持会话ID + // 否则, 会话列表切换之后, 会话ID更新, 导致消息关联错误 + const [stickToCid, setStickToCid] = useState(conversationid); + useEffect(() => { + // console.log('emailEditorPopup effect', open, '\nto', toEmail) + setStickToProps({ fromEmail, fromUser, fromOrder, toEmail, conversationid, quoteid, action }); - setNewFromEmail(fromEmail); - setEmailOPI(emailUser); - setNewToEmail(toEmail); + setStickToCid(conversationid) + setEmailOrder(fromOrder) + setEmailOPI(fromUser) + setNewFromEmail(fromEmail) + setNewToEmail(toEmail) const _findMat = emailListAddrMapped?.[fromEmail]?.mat_sn - setEmailMat(emailUserMat || _findMat) + setEmailMat(_findMat) - // 转发/回复时, 从发出的邮件操作, 获取原来的发件人邮箱 - const _findMatOld = emailListMatMapped?.[emailUserMat] - if (isEmpty(_findMat) && _findMatOld) { + if (open !== true) { + form.resetFields() + } + + return () => { + setStickToProps({}) + setStickToCid('') + setEmailOrder('') + setEmailOPI('') + setNewFromEmail('') + setNewToEmail('') + } + }, [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) } return () => {} - }, [open, fromEmail, fromUser, toEmail, mailData]) + }, [mailData]) const handleSwitchEmail = (labelValue) => { const { value } = labelValue @@ -120,24 +157,6 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, toEmail, convers setEmailOPI(_findMat?.opi_sn) }; - - const { notification, message } = App.useApp(); - const [form] = Form.useForm(); - - // 存储会话ID, - // 这个窗口没有模态, 即使不是focus, 还是需要保持会话ID - // 否则, 会话列表切换之后, 会话ID更新, 导致消息关联错误 - const [stickToCid, setStickToCid] = useState(conversationid); - useEffect(() => { - setStickToCid(conversationid) - if (open !== true) { - form.resetFields(); - } - - return () => {} - }, [open]) - - const [isRichText, setIsRichText] = useState(mobile === false); // const [isRichText, setIsRichText] = useState(false); // 默认纯文本 const [htmlContent, setHtmlContent] = useState(''); @@ -164,9 +183,6 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, toEmail, convers const [initialForm, setInitialForm] = useState({}); const [initialContent, setInitialContent] = useState(''); - /** - * 加载邮件数据 - */ useEffect(() => { // console.log('quoteid', quoteid, isEmpty(quoteid), isEmpty(mailData.info)); @@ -184,12 +200,12 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, toEmail, convers } const _formValues = { - to: info?.MAI_From || fromEmail, + to: info?.MAI_From || newFromEmail, cc: info?.MAI_CS || '', // bcc: quote.bcc || '', subject: `Re: ${info.MAI_Subject || ''}`, }; - const forwardValues = { subject: `Fw: ${info.subject || ''}` }; + const forwardValues = { subject: `Fw: ${info.MAI_Subject || ''}` }; if (action === 'reply') { form.setFieldsValue(_formValues); setInitialForm(_formValues); @@ -209,13 +225,13 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, toEmail, convers setInitialContent(thisBody) } else if (action === 'new') { - const newEmail = { to: toEmail, } + const newEmail = { to: newToEmail, } form.setFieldsValue(newEmail); setInitialForm(newEmail); } return () => {}; - }, [open, action, mailData.info]); + }, [stickToProps, mailData.info, newToEmail, newFromEmail]); const [openPlainTextConfirm, setOpenPlainTextConfirm] = useState(false); const handlePlainTextOpenChange = ({ target }) => { @@ -306,15 +322,16 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, toEmail, convers const [sendLoading, setSendLoading] = useState(false); const onHandleSend = async () => { - console.log('onSend callback', '\nisRichText', isRichText); + // console.log('onSend callback', '\nisRichText', isRichText); // console.log(form.getFieldsValue()); const body = structuredClone(form.getFieldsValue()); body.mailcontent = isRichText ? htmlContent : textContent; - body.from = newFromEmail || fromEmail; + body.from = newFromEmail; body.attaList = fileList; body.opi_sn = emailOPI; body.mat_sn = emailMat; - console.log('body', body); + body.coli_sn = emailOrder || ''; + // console.log('body', body, '\n', emailOrder); const values = await form.validateFields(); body.cc = values.cc || ''; body.bcc = values.bcc || ''; @@ -338,14 +355,14 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, toEmail, convers try { const bubbleMsg = cloneDeep(msgObj); bubbleMsg.id = `${stickToCid}.${msgObj.id}`; - bubbleMsg.email.mai_sn = ''; + // bubbleMsg.email.mai_sn = ''; bubbleMsg.content = undefined; - invokeEmailMessage(bubbleMsg); + // invokeEmailMessage(bubbleMsg); const result = await postSendEmail(body); - // const mailSavedId = result.id || ''; - // bubbleMsg.email.mai_sn = mailSavedId; - // invokeEmailMessage(bubbleMsg); + const mailSavedId = result.id || ''; + bubbleMsg.email.mai_sn = mailSavedId; + invokeEmailMessage(bubbleMsg); // setSendLoading(false); @@ -358,8 +375,9 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, toEmail, convers duration: 3, }); + } finally { + setSendLoading(false); } - setSendLoading(false); }; @@ -382,8 +400,8 @@ const EmailEditorPopup = ({ open, setOpen, fromEmail, fromUser, toEmail, convers }} title={ <> - {loading ?