关闭会话: 传参;

会话窗口刷新和获取消息记录; 引用消息
dev/mobile
Lei OT 2 years ago
parent 8166bd2112
commit d7d13108a0

@ -111,8 +111,8 @@ export const fetchTemplates = async () => {
return canUseTemplates; return canUseTemplates;
}; };
export const fetchConversationsList = async (opisn) => { export const fetchConversationsList = async (params) => {
const { result: data } = await fetchJSON(`${API_HOST}/getconversations`, { opisn }); const { result: data } = await fetchJSON(`${API_HOST}/getconversations`, params);
const list = data.map((ele) => ({ ...ele, customer_name: ele.whatsapp_name.trim() })); const list = data.map((ele) => ({ ...ele, customer_name: ele.whatsapp_name.trim() }));
return list; return list;
}; };

@ -31,9 +31,9 @@ export const sentMsgTypeMapped = {
renderId: msg.id, renderId: msg.id,
to: msg.to, to: msg.to,
msgtype: 'text', msgtype: 'text',
msgcontent: { body: msg.text, ...(msg.context ? { context: msg.context } : {}) }, msgcontent: { body: msg.text, ...(msg.context ? { context: msg.context, message_origin: msg.message_origin } : {}) },
}), }),
contentToRender: (msg) => ({ ...msg, actionId: msg.id, conversationid: msg.id.split('.')[0], ...(msg.context ? { reply: { message: msg.context.message_origin.text, title: msg.context.message_origin.senderName || 'Reference' } } : {}) }), contentToRender: (msg) => ({ ...msg, actionId: msg.id, conversationid: msg.id.split('.')[0], ...(msg.context ? { reply: { message: msg.message_origin.text, title: msg.message_origin.senderName || 'Reference' } } : {}) }),
}, },
whatsappTemplate: { whatsappTemplate: {
contentToSend: (msg) => ({ action: 'message', actionId: msg.id, renderId: msg.id, to: msg.to, msgtype: 'template', msgcontent: msg.template }), contentToSend: (msg) => ({ action: 'message', actionId: msg.id, renderId: msg.id, to: msg.to, msgtype: 'template', msgcontent: msg.template }),
@ -212,6 +212,7 @@ export const parseRenderMessageItem = (msg) => {
customer_name: msg?.customerProfile?.name || '', customer_name: msg?.customerProfile?.name || '',
whatsapp_name: msg?.customerProfile?.name || '', whatsapp_name: msg?.customerProfile?.name || '',
whatsapp_phone_number: msg.from, whatsapp_phone_number: msg.from,
whatsapp_msg_type: msg.type,
}; };
}; };
/** /**
@ -240,6 +241,7 @@ export const parseRenderMessageList = (messages, conversationid = null) => {
: {}), : {}),
// conversationid: conversationid, // conversationid: conversationid,
// title: msg.customerProfile.name, // title: msg.customerProfile.name,
whatsapp_msg_type: msgContent.type,
}; };
}); });
}; };

@ -70,10 +70,12 @@ const ConversationReducer = (state = initialState, action) => {
const message = action.payload; const message = action.payload;
const targetId = message.conversationid; const targetId = message.conversationid;
const targetMsgs = (activeConversations[String(targetId)] || []).map((ele) => { const targetMsgs = (activeConversations[String(targetId)] || []).map((ele) => {
// 更新状态
// * 已读的不再更新状态, 有时候投递结果在已读之后返回
if (ele.id === ele.actionId && ele.actionId === message.actionId) { if (ele.id === ele.actionId && ele.actionId === message.actionId) {
return { ...ele, id: message.id, status: message.status, dateString: message.dateString }; return { ...ele, id: message.id, status: ele.status === 'read' ? ele.status : message.status, dateString: message.dateString };
} else if (ele.id === message.id) { } else if (ele.id === message.id) {
return { ...ele, id: message.id, status: message.status, dateString: message.dateString }; return { ...ele, id: message.id, status: ele.status === 'read' ? ele.status : message.status, dateString: message.dateString };
} }
return ele; return ele;
}); });

@ -5,8 +5,7 @@ import { SendOutlined, MessageOutlined, SmileOutlined, PictureOutlined, CommentO
import { useAuthContext } from '@/stores/AuthContext'; import { useAuthContext } from '@/stores/AuthContext';
import { useConversationState, useConversationDispatch } from '@/stores/ConversationContext'; import { useConversationState, useConversationDispatch } from '@/stores/ConversationContext';
import { import {
fetchCustomerProfile, fetchConversationsList,
receivedCustomerProfile,
setCurrentConversation, setCurrentConversation,
addConversationList, delConversationitem, addConversationList, delConversationitem,
fetchConversationItemClose, fetchConversationItemClose,
@ -16,38 +15,31 @@ import { ChatList, } from 'react-chat-elements';
import { isEmpty, pick } from '@/utils/utils'; import { isEmpty, pick } from '@/utils/utils';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
const CDropdown = () => { const CDropdown = (props) => {
const { loginUser } = useAuthContext();
const { userId } = loginUser;
const { currentConversation } = useConversationState();
const dispatch = useConversationDispatch(); const dispatch = useConversationDispatch();
const handleConversationItemClose = async (item) => {
console.log('invoke close', {conversationid: item.sn, opisn: userId }); const handleConversationItemClose = async () => {
// await fetchConversationItemClose({ conversationid: item.sn, opisn: userId }); await fetchConversationItemClose({ conversationid: props.sn, opisn: props.opi_sn });
dispatch(delConversationitem(item)); dispatch(delConversationitem(props));
}; };
return ( return (
<Dropdown key={'more-action'} <Dropdown
key={'more-action'}
trigger={'click'} trigger={'click'}
menu={{ menu={{
items: [ items: [{ key: 'close', danger: true, label: '关闭会话' }],
{ onClick: (e) => {
key: 'close', e.domEvent.stopPropagation();
danger: true, switch (e.key) {
label: '关闭会话',
},
],
onClick: ({ key }) => {
switch (key) {
case 'close': case 'close':
return handleConversationItemClose(currentConversation); return handleConversationItemClose();
default: default:
return; return;
} }
}, },
}}> }}>
<Button key={'More'} type='text' title='More' className=' rounded-none text-gray-400' icon={<MoreOutlined />} size={'middle'} onClick={e => e.stopPropagation() } /> <Button key={'More'} type='text' title='More' className=' rounded-none text-gray-400' icon={<MoreOutlined />} size={'middle'} onClick={(e) => e.stopPropagation()} />
</Dropdown> </Dropdown>
); );
} }
@ -81,7 +73,7 @@ const Conversations = () => {
// statusColorType: 'badge', // statusColorType: 'badge',
// statusText: 'online', // statusText: 'online',
className: String(item.sn) === String(currentConversation.sn) ? '__active text-primary underline bg-whatsapp-me ' : '', className: String(item.sn) === String(currentConversation.sn) ? '__active text-primary underline bg-whatsapp-me ' : '',
customStatusComponents: [CDropdown], customStatusComponents: [() => CDropdown(item)],
})) }))
); );
@ -90,59 +82,35 @@ const Conversations = () => {
useEffect(() => { useEffect(() => {
if (order_sn) { if (order_sn) {
// getCustomerProfile(order_sn); getOrderConversationList(order_sn);
// reset chat window
dispatch(setCurrentConversation({ sn: '', customer_name: '', coli_sn: order_sn }));
} }
return () => {}; return () => {};
}, [order_sn]); }, [order_sn]);
const getCustomerProfile = async (colisn) => { const getOrderConversationList = async (colisn) => {
const data = await fetchCustomerProfile(colisn); const data = await fetchConversationsList({ opisn: userId, colisn });
dispatch(receivedCustomerProfile(data)); if (!isEmpty(data)) {
if (isEmpty(data)) { dispatch(addConversationList(data));
return false; switchConversation(data[0]);
} // dispatch(setCurrentConversation(data[0]));
if (!isEmpty(data.conversations)) {
dispatch(addConversationList(data.conversations));
dispatch(setCurrentConversation(data.conversations[0]));
} else { } else {
// reset chat window // reset chat window
if (isEmpty(data.contact?.[0]?.whatsapp_phone_number)) { dispatch(setCurrentConversation({ sn: '', customer_name: '', coli_sn: order_sn }));
dispatch(setCurrentConversation({ sn: '', customer_name: '', coli_sn: '' })); return false;
return false;
}
//
const newChat = {
'sn': uuid(),
// 'opi_sn': 354,
'coli_sn': colisn,
'whatsapp_phone_number': data.contact[0].whatsapp_phone_number,
'last_received_time': '',
'last_send_time': '',
'unread_msg_count': 0,
'whatsapp_name': data.contact[0].name,
'customer_name': data.contact[0].name,
};
dispatch(addConversationList([newChat]));
const newCurrent = pick(newChat, ['sn', 'coli_sn', 'whatsapp_phone_number', 'whatsapp_name', 'customer_name']);
dispatch(setCurrentConversation(newCurrent));
} }
}; };
const switchConversation = async (item) => { const switchConversation = async (item) => {
if (String(item.sn) === String(currentConversation.sn)) { console.log('invoke switch');
return false;
}
dispatch(setCurrentConversation(item));
const messagesList = activeConversations[`${item.sn}`] || []; const messagesList = activeConversations[`${item.sn}`] || [];
if (isEmpty(messagesList)) { if (isEmpty(messagesList)) {
const data = await fetchMessages({ opisn: userId, whatsappid: item.whatsapp_phone_number }); const data = await fetchMessages({ opisn: userId, whatsappid: item.whatsapp_phone_number });
dispatch(receivedMessageList(item.sn, data)); dispatch(receivedMessageList(item.sn, data));
} }
if (isEmpty(item.coli_sn) || item.coli_sn === '0') { if (String(item.sn) === String(currentConversation.sn)) {
dispatch(receivedCustomerProfile({})); return false;
} }
dispatch(setCurrentConversation(item));
}; };
const onSwitchConversation = (item) => { const onSwitchConversation = (item) => {

@ -44,7 +44,7 @@ const InputBox = () => {
id: `${currentConversation.sn}.${uuid()}`, // Date.now().toString(16), id: `${currentConversation.sn}.${uuid()}`, // Date.now().toString(16),
date: new Date(), date: new Date(),
status: 'waiting', status: 'waiting',
...(referenceMsg.id ? { context: { message_id: referenceMsg.id, message_origin: referenceMsg } } : {}), ...(referenceMsg.id ? { context: { message_id: referenceMsg.id, }, message_origin: referenceMsg } : {}),
}; };
invokeSendMessage(msgObj); invokeSendMessage(msgObj);
setTextContent(''); setTextContent('');
@ -77,12 +77,12 @@ const InputBox = () => {
autoSize={{ minRows: 2, maxRows: 6 }} autoSize={{ minRows: 2, maxRows: 6 }}
/> />
<Flex justify={'space-between'} className=' bg-gray-200 p-1 rounded-b'> <Flex justify={'space-between'} className=' bg-gray-200 p-1 rounded-b'>
<Flex gap={4} className='divide-y-0 divide-x divide-solid divide-gray-500 '> <Flex gap={4} className='divide-y-0 divide-x divide-solid divide-gray-500 *:text-primary *:rounded-none'>
<InputTemplate key='templates' disabled={!talkabled} invokeSendMessage={invokeSendMessage} /> <InputTemplate key='templates' disabled={!talkabled} invokeSendMessage={invokeSendMessage} />
{/* <Button type='text' className=' rounded-none text-primary' icon={<PictureOutlined />} size={'middle'} /> */} <Button key={'addPic'} type='text' disabled={!textabled} className='' icon={<PictureOutlined />} size={'middle'} />
{/* <Button type='text' className=' rounded-none text-primary' icon={<FolderAddOutlined />} size={'middle'} /> */} {/* <Button type='text' className='' icon={<FolderAddOutlined />} size={'middle'} /> */}
{/* <Button type='text' className=' rounded-none text-primary' icon={<CloudUploadOutlined />} size={'middle'} /> */} {/* <Button type='text' className='' icon={<CloudUploadOutlined />} size={'middle'} /> */}
{/* <Button type='text' className=' rounded-none text-primary' icon={<FilePdfOutlined />} size={'middle'} /> */} {/* <Button type='text' className='' icon={<FilePdfOutlined />} size={'middle'} /> */}
</Flex> </Flex>
<Button key={'send-btn'} onClick={handleSendText} type='primary' size='middle' icon={<SendOutlined />} <Button key={'send-btn'} onClick={handleSendText} type='primary' size='middle' icon={<SendOutlined />}
disabled={!textabled} disabled={!textabled}

@ -179,7 +179,7 @@ const InputTemplate = ({ disabled = false, invokeSendMessage }) => {
trigger='click' trigger='click'
open={openTemplates} open={openTemplates}
onOpenChange={setOpenTemplates}> onOpenChange={setOpenTemplates}>
<Button type='text' className=' rounded-none text-primary' icon={<MessageOutlined />} size={'middle'} disabled={disabled} /> <Button type='text' className='' icon={<MessageOutlined />} size={'middle'} disabled={disabled} />
</Popover> </Popover>
</> </>
); );

@ -48,12 +48,12 @@ const Messages = () => {
notchStyle: { fill: '#ccd5ae' }, notchStyle: { fill: '#ccd5ae' },
// forwarded: false, // forwarded: false,
// todo: reaction: emoji // todo: reaction: emoji
replyButton: message.type === 'text' && message.status !== 'failed' ? true : false, replyButton: ['text'].includes(message.whatsapp_msg_type) && message.status !== 'failed' ? true : false,
onReplyClick: () => dispatch(setReplyTo(message)), onReplyClick: () => dispatch(setReplyTo(message)),
className: 'whatsappme-container whitespace-pre-wrap', className: 'whatsappme-container whitespace-pre-wrap',
} }
: { : {
replyButton: message.type === 'text' ? true : false, replyButton: ['text'].includes(message.whatsapp_msg_type) ? true : false,
onReplyClick: () => dispatch(setReplyTo(message)), onReplyClick: () => dispatch(setReplyTo(message)),
})} })}
// notchStyle={{fill: '#ccd5ae'}} // notchStyle={{fill: '#ccd5ae'}}

@ -56,10 +56,9 @@ const ConversationProvider = ({ children }) => {
}, []); }, []);
useEffect(() => { useEffect(() => {
fetchConversationsList(userId).then((data) => { fetchConversationsList({ opisn: userId }).then((data) => {
console.log(data, 'llllllllllllllllllllllll');
dispatch(receivedConversationList(data)); dispatch(receivedConversationList(data));
}); // todo: });
fetchTemplates().then((data) => dispatch(receivedTemplates(data))); fetchTemplates().then((data) => dispatch(receivedTemplates(data)));

Loading…
Cancel
Save