From 92a423ab3197e45ddb3b23fb5083dd26624ff8f2 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Fri, 8 Mar 2024 19:24:12 +0800 Subject: [PATCH] =?UTF-8?q?todo:=20=E5=8E=86=E5=8F=B2=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/actions/ConversationActions.js | 15 ++- src/lib/msgUtils.js | 1 + src/views/ChatHistory.jsx | 191 +++++++++++++++++++++++++---- 3 files changed, 179 insertions(+), 28 deletions(-) diff --git a/src/actions/ConversationActions.js b/src/actions/ConversationActions.js index d8d036c..9ae3144 100644 --- a/src/actions/ConversationActions.js +++ b/src/actions/ConversationActions.js @@ -12,12 +12,20 @@ export const fetchTemplates = async () => { return canUseTemplates; }; +/** + * + * @param {object} params { opisn } + */ export const fetchConversationsList = async (params) => { 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; }; +/** + * + * @param {object} params { opisn, whatsappid, } + */ export const fetchMessages = async (params) => { const { result } = await fetchJSON(`${API_HOST}/getcusmessages`, params); return parseRenderMessageList(result || []); @@ -29,6 +37,10 @@ export const fetchCustomerProfile = async (colisn) => { return data; }; +/** + * + * @param {object} params { opisn, whatsappid, colisn } + */ export const fetchOrderConversationsList = async (params) => { const { errcode, result: data } = await fetchJSON(`${API_HOST}/getorderconversation`, params); if (errcode !== 0) return []; @@ -39,7 +51,6 @@ export const fetchOrderConversationsList = async (params) => { /** * * @param {object} body { opisn, conversationid } - * @returns */ export const fetchConversationItemClose = async (body) => { const { result } = await fetchJSON(`${API_HOST}/closeconversation`, body); diff --git a/src/lib/msgUtils.js b/src/lib/msgUtils.js index 2fcd47d..bb11fe7 100644 --- a/src/lib/msgUtils.js +++ b/src/lib/msgUtils.js @@ -451,6 +451,7 @@ export const parseRenderMessageList = (messages, conversationid = null) => { type: msgContent.type, ...(typeof whatsappMsgTypeMapped[msgType].type === 'function' ? whatsappMsgTypeMapped[msgType].type(msg) : { type: whatsappMsgTypeMapped[msgType].type || 'text' }), date: msgContent?.sendTime || msg.msgtime || '', + localDate: msg.msgtime || '', from: msgContent.from, sender: msgContent.from, senderName: msgContent?.customerProfile?.name || msgContent.from, diff --git a/src/views/ChatHistory.jsx b/src/views/ChatHistory.jsx index 9a819b4..2949910 100644 --- a/src/views/ChatHistory.jsx +++ b/src/views/ChatHistory.jsx @@ -1,13 +1,15 @@ import { useNavigate } from 'react-router-dom'; -import { memo, useCallback, useEffect, useRef, useState } from 'react'; -import { Row, Col, Divider, Table, Card, Button, Input, Flex, Layout, Space, Empty, Radio, Select, DatePicker, Form, List, Avatar } from 'antd'; +import { memo, useCallback, useEffect, useRef, useState, forwardRef } from 'react'; +import { Row, Col, Divider, Table, Card, Button, Input, Flex, Layout, Space, Empty, Radio, Select, DatePicker, Form, List, Avatar, Spin, Image } from 'antd'; import { StarFilled, ZoomInOutlined, StarOutlined, SearchOutlined } from '@ant-design/icons'; import { ChatList, ChatItem, MessageBox } from 'react-chat-elements'; +import { fetchConversationsList, fetchMessages } from '@/actions/ConversationActions'; +import { isEmpty } from '@/utils/utils'; const { Sider, Content, Header, Footer } = Layout; const { Search } = Input; const { RangePicker } = DatePicker; - +// https://media-xsp2-1.cdn.whatsapp.net/v/t61.24694-24/424735646_380563021285029_2962758854250800176_n.jpg?ccb=11-4&oh=01_AdTogiVdUE-ToI9uH-VQKTTLyDbP7bocXUQe1OETOeCgcg&oe=65F7C6AB&_nc_sid=e6ed6c&_nc_cat=104 const data = [ { title: 'Ann', @@ -82,12 +84,16 @@ const SearchForm = memo(function ({ onSubmit }) { optionFilterProp='children' filterOption={(input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase())} options={[ + { + value: '354', + label: '宁艳', + }, { value: '杨新玲', label: '杨新玲', }, { - value: '黄雪荣', + value: '495', label: '黄雪荣', }, { @@ -185,39 +191,172 @@ function ChatHistory() { setFormValues({ ...values }); }, []); + const [loading, setLoading] = useState(false); + const [conversationsList, setConversationsList] = useState([]); + const [selectedConversation, setSelectedConversation] = useState({}); + const [chatItemMessages, setChatItemMessages] = useState([]); + const getConversationsList = async () => { + setLoading(true); + setChatItemMessages([]); + const data = await fetchConversationsList({ opisn: formValues.travel }); + setLoading(false); + setConversationsList(data); + if (data.length === 1) { + setSelectedConversation(data[0]); + await getMessages(data[0]); + } + }; + const getMessages = async (chatItem) => { + setLoading(true); + setChatItemMessages([]); + const data = await fetchMessages({ opisn: chatItem.opi_sn, whatsappid: chatItem.whatsapp_phone_number }); + setLoading(false); + setChatItemMessages(data); + }; + + useEffect(() => { + if (selectedConversation.whatsapp_phone_number) { + getMessages(selectedConversation); + } + + return () => {}; + }, [selectedConversation]); + + useEffect(() => { + if (formValues.travel) { + getConversationsList(); + } + return () => {}; + }, [formValues]); + + const RenderText = memo(function renderText({ str }) { + const parts = str.split(/(https?:\/\/[^\s]+|\p{Emoji_Presentation})/gmu).filter((s) => s !== ''); + const links = str.match(/https?:\/\/[\S]+/gi) || []; + const emojis = str.match(/([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g) || []; + const extraClass = isEmpty(emojis) ? '' : 'text-base leading-5 emoji-text'; + const objArr = parts.reduce((prev, curr, index) => { + if (links.includes(curr)) { + prev.push({ type: 'link', key: curr }); + } else if (emojis.includes(curr)) { + prev.push({ type: 'emoji', key: curr }); + } else { + prev.push({ type: 'text', key: curr }); + } + return prev; + }, []); + return ( + + {(objArr || []).map((part, index) => { + if (part.type === 'link') { + return ( + + {part.key} + + ); + } else { + // if (part.type === 'emoji') + return part.key; + } + })} + + ); + }); + + const handlePreview = (msg) => { + switch (msg.whatsapp_msg_type) { + case 'image': + // eslint-disable-next-line no-fallthrough + case 'document': + window.open(msg.data.link || msg.data.uri, '_blank', 'noopener,noreferrer'); + return false; + + default: + return false; + } + }; + const messagesEndRef = useRef(null); + const messageRefs = useRef([]); + const scrollToMessage = (id, index) => { + const _i = index || chatItemMessages.findIndex((msg) => msg.id === id); + if (_i >= 0) { + messageRefs.current[_i].scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + }; + // eslint-disable-next-line react/display-name + const MessageBoxWithRef = forwardRef((props, ref) => ( +
  • + +
  • + )); return ( <> - - - + + + + {conversationsList.map((item) => ( + setSelectedConversation(item)} + /> + ))} + -
    +
    { console.log('load more'); }} - className='h-full overflow-y-auto px-2' + className='h-full overflow-y-auto px-2 relative' itemLayout='vertical' - dataSource={data} - renderItem={(item, index) => ( - - } title={item.title} description={item.msgTime} /> -
    {item.content}
    -
    + dataSource={chatItemMessages} + renderItem={(message, index) => ( + // + // } title={item.title} description={item.msgTime} /> + //
    {item.content}
    + //
    + (messageRefs.current[index] = el)} + key={message.id} + {...message} + // position={message.sender === 'me' ? 'right' : 'left'} + position={'left'} + onReplyMessageClick={() => scrollToMessage(message.reply.id)} + onOpen={() => handlePreview(message)} + onTitleClick={() => handlePreview(message)} + notch={false} + text={} + dateString={message.dateString || message.localDate} + className={['whitespace-pre-wrap', message.whatsapp_msg_type === 'sticker' ? 'bg-transparent' : '', message.sender === 'me' ? 'whatsappme-container' : ''].join( + ' ' + )} + style={{ + backgroundColor: message.sender === 'me' ? '#ccd4ae' : '#fff', + }} + {...(message.type === 'meetingLink' + ? { + actionButtons: [ + { + onClickButton: () => { + navigator.clipboard.writeText(message.text); + }, + Component: () =>
    复制
    , + }, + ], + } + : {})} + /> )} />