diff --git a/src/stores/FormStore.js b/src/stores/FormStore.js index d79605b..fff6a4b 100644 --- a/src/stores/FormStore.js +++ b/src/stores/FormStore.js @@ -12,6 +12,10 @@ export const useFormStore = create( setMsgHistorySelectMatch: (msgHistorySelectMatch) => set({ msgHistorySelectMatch }), msgListParams: {}, setMsgListParams: (msgListParams) => set(state => ({ msgListParams: {...state.msgListParams, ...msgListParams} })), + ImageAlbum: [], + setImageAlbum: (ImageAlbum) => set({ ImageAlbum }), + ImagePreviewSrc: '', + setImagePreviewSrc: (ImagePreviewSrc) => set({ ImagePreviewSrc }), // 订单跟踪页面 orderFollowForm: { diff --git a/src/views/ChatHistory.jsx b/src/views/ChatHistory.jsx index 0209307..caa2ced 100644 --- a/src/views/ChatHistory.jsx +++ b/src/views/ChatHistory.jsx @@ -1,429 +1,38 @@ -import { memo, useCallback, useEffect, useRef, useState, forwardRef } from 'react'; -import { App, Divider, Button, Input, Layout, DatePicker, Form, List, Spin, Flex, Image } from 'antd'; -import { LoadingOutlined } from '@ant-design/icons'; -import { ChatItem, MessageBox } from 'react-chat-elements'; -import { MESSAGE_PAGE_SIZE, fetchConversationsSearch, fetchMessagesHistory } from '@/actions/ConversationActions'; -import { cloneDeep, flush, isEmpty, pick, stringToColour } from '@/utils/utils'; +import { useCallback, useState } from 'react'; +import { Divider, Layout, Flex, Image } from 'antd'; import useFormStore from '@/stores/FormStore'; +import SearchForm from './Conversations/History/SearchForm'; +import ConversationsList from './Conversations/History/ConversationsList'; +import MessagesMatchList from './Conversations/History/MessagesMatchList'; +import MessagesList from './Conversations/History/MessagesList'; +import ImageAlbumPreview from './Conversations/History/ImageAlumPreview'; -import { fetchSalesAgent, fetchCustomerList } from '@/actions/CommonActions'; -import SearchInput from '@/components/SearchInput'; -import { isNotEmpty } from '@/utils/commons'; +const { Sider, Content } = Layout; -const { Sider, Content, Header, Footer } = Layout; -const { Search } = Input; -const { RangePicker } = DatePicker; - -const BIG_PAGE_SIZE = MESSAGE_PAGE_SIZE * 100; - -// 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 - -// eslint-disable-next-line react/display-name -const SearchForm = memo(function ({ initialValues, onSubmit }) { - const [form] = Form.useForm(); - function handleSubmit(values) { - const multiAgents = (values?.agent || []).map(ele => ele.value).join(','); - const multiCustomers = (values?.customer || []).map(ele => ele.value).join(','); - onSubmit?.({ - ...values, - opisn: multiAgents, - whatsapp_id: multiCustomers, - ...(isNotEmpty(values.msgDateRange) ? { - from_date: values.msgDateRange[0].format('YYYY-MM-DD'), - end_date: values.msgDateRange[1].format('YYYY-MM-DD'), - } : {}), - }); - } - return ( -
- - - - - - - - - - - - - - - - - - -
- - -
-
-
- ); -}); - -function ChatHistory() { - - const { message: appMessage } = App.useApp() - - // const [formValues, setFormValues] = useState({}); - const [formValues, setFormValues] = useFormStore(((state) => [state.chatHistoryForm, state.setChatHistoryForm])); - const [selectedConversation, setSelectedConversation] = useFormStore(((state) => [state.chatHistorySelectChat, state.setChatHistorySelectChat])); - const [selectMatch, setSelectedMatch] = useFormStore(((state) => [state.msgHistorySelectMatch, state.setMsgHistorySelectMatch])); - const [paramsForMsgList, setParamsForMsgList] = useFormStore(((state) => [state.msgListParams, state.setMsgListParams])); - // { opisn, whatsappid, lasttime, pagesize, pagedir } +const Index = (props) => { + const [formValues, setFormValues] = useFormStore((state) => [state.chatHistoryForm, state.setChatHistoryForm]); const handleSubmit = useCallback((values) => { setFormValues({ ...values }); }, []); - const [conversationsListLoading, setConversationsListLoading] = useState(false); - const [messageListPreLoading, setMessageListPreLoading] = useState(false); - const [messageListLoading, setMessageListLoading] = useState(false); - const [conversationsList, setConversationsList] = useState([]); - const [chatItemMessages, setChatItemMessages] = useState([]); - const [imageAlbum, setImageAlbum] = useState([]); - // const [paramsForMsgList, setParamsForMsgList] = useState({ loadNextPage: true, loadPrePage: true, }); // { opisn, whatsappid, lasttime, pagesize, pagedir } - // const [selectMatch, setSelectedMatch] = useState({}); - - const getConversationsList = async () => { - // const allEmpty = Object.values(cloneDeep(formValues)).every((val) => { - // return val === null || val === '' || val === undefined; - // }); - // if (allEmpty) return; - setConversationsListLoading(true); - setChatItemMessages([]); - setParamsForMsgList({}); - setSelectedMatch({}); - const params = flush(pick(formValues, ['opisn', 'whatsapp_id', 'search', 'from_date', 'end_date', 'coli_id'])); - const data = await fetchConversationsSearch(params); - setConversationsListLoading(false); - setConversationsList(data); - if (data.length === 1) { - setSelectedConversation(data[0]); - } - }; - - const getMessagesPre = async (chatItem) => { - setMessageListPreLoading(true); - const data = await fetchMessagesHistory({ ...chatItem, lasttime: chatItem.pretime, pagedir: 'pre', pagesize: BIG_PAGE_SIZE }); - setMessageListPreLoading(false); - setChatItemMessages(prevValue => data.concat(prevValue)); - const loadPrePage = !(data.length === 0 || data.length < BIG_PAGE_SIZE); - setParamsForMsgList({ loadPrePage }); - }; - const getMessagesNext = async (chatItem) => { - setMessageListLoading(true); - const data = await fetchMessagesHistory({...chatItem, pagedir: 'next', pagesize: BIG_PAGE_SIZE }); - setMessageListLoading(false); - setChatItemMessages(prevValue => prevValue.concat(data)); - const loadNextPage = !(data.length === 0 || data.length < BIG_PAGE_SIZE); - setParamsForMsgList({loadNextPage}); - }; - - // 选择指定消息之后, 定位 - const scrollToSelectedMessage = (selected) => { - const findIndex = chatItemMessages.findIndex(item => item.id === selected.id); - if (findIndex !== -1) { - scrollToMessage(selected.id, findIndex); - } - } - const handleMatchMsgClick = async (selected) => { - const findIndex = chatItemMessages.findIndex(item => item.id === selected.id); - if (findIndex === -1) { - setMessageListLoading(true); - await getMessagesPre({...paramsForMsgList }); - setMessageListLoading(false); - } - setSelectedMatch(selected); - } - // 选择指定消息之后, 定位 - useEffect(() => { - if (selectMatch.sn) { - scrollToSelectedMessage(selectMatch); - } - return () => {}; - }, [selectMatch.sn]); - - // 选中会话之后, 获取消息记录 - useEffect(() => { - setChatItemMessages([]); - setParamsForMsgList({}); - setSelectedMatch({}); - if (isEmpty(selectedConversation.conversationid) || isEmpty(selectedConversation.opi_sn)) { - return () => {}; - } - const firstActionPageParams = { opisn: selectedConversation.opi_sn, whatsappid: selectedConversation.whatsapp_phone_number }; - if (isEmpty(selectedConversation.matchMsgList)) { - firstActionPageParams.loadPrePage = false; - firstActionPageParams.loadNextPage = true; - } else { - firstActionPageParams.pretime = selectedConversation.matchMsgList[0].orgmsgtime; - firstActionPageParams.lasttime = selectedConversation.matchMsgList[0].orgmsgtime; - firstActionPageParams.loadPrePage = true; - firstActionPageParams.loadNextPage = true; - } - setParamsForMsgList(firstActionPageParams); - async function getFirstNext() { - await getMessagesNext(firstActionPageParams); - } - async function getFirstPre() { - await getMessagesPre(firstActionPageParams); - } - // getFirstPre(); - getFirstNext(); - - return () => {}; - }, [selectedConversation.conversationid]); - - // 更新是否需要显示上一页,下一页按钮 - useEffect(() => { - if (chatItemMessages.length > 0) { - setParamsForMsgList({pretime: chatItemMessages[0].orgmsgtime, lasttime: chatItemMessages[chatItemMessages.length - 1].orgmsgtime }); - setImageAlbum(chatItemMessages.filter(ele => ele.whatsapp_msg_type === 'image').map(ele => ele.data.uri)); - } - return () => {}; - }, [chatItemMessages]) - - const onLoadMore = () => { - getMessagesNext(paramsForMsgList); - // window.dispatchEvent(new Event('resize')); - }; - const loadMore = !messageListLoading && paramsForMsgList.loadNextPage ? ( -
- -
- ) : null; - const onLoadMorePre = () => { - getMessagesPre(paramsForMsgList); - // window.dispatchEvent(new Event('resize')); - }; - const loadMorePre = - paramsForMsgList.loadPrePage && chatItemMessages.length > 0 ? ( -
- {messageListPreLoading ? : } -
- ) : null; - - useEffect(() => { - getConversationsList(); - return () => {}; - }, [formValues]); - - const RenderText = memo(function renderText({ str, className }) { - 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) ? '' : ''; - 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 { - return part.key; - } - })} - - ); - }); - - const [previewVisible, setPreviewVisible] = useState(false); - const [previewSrc, setPreviewSrc] = useState(); - const [previewIndex, setPreviewIndex] = useState(); - const onPreviewClose = () => { - setPreviewSrc(''); - setPreviewVisible(false); - }; - const handlePreview = (msg) => { - switch (msg.whatsapp_msg_type) { - case 'image': - setPreviewVisible(true); - setPreviewSrc(msg.data.uri); - setPreviewIndex(imageAlbum.findIndex((url) => url === msg.data.uri)); - return false; - - case 'document': - window.open(msg.data.link || msg.data.uri, '_blank', 'noopener,noreferrer'); - return false; - - default: - return false; - } - }; - const handlePreviewItem = (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 [focusMsg, setFocusMsg] = useState(''); - const scrollToMessage = (id, index) => { - const _i = index || chatItemMessages.findIndex((msg) => msg.id === id); - if (_i >= 0) { - messageRefs.current[_i].scrollIntoView({ behavior: 'smooth', block: 'start' }); - setFocusMsg(id); - } - }; - // eslint-disable-next-line react/display-name - const MessageBoxWithRef = forwardRef((props, ref) => ( -
  • - -
  • - )); return ( <> - - {conversationsList.map((item) => ( - setSelectedConversation(item)} - /> - ))} - + - {(selectedConversation.matchMsgList || []).length > 0 && isNotEmpty(formValues.search) && ( -
    -

    {formValues.search} 的相关记录, 点击定位上下文

    - {selectedConversation.matchMsgList.map((item) => ( - handleMatchMsgClick(item)} - /> - ))} -
    - )} - -
    {selectedConversation.whatsapp_name} {selectedConversation.whatsapp_phone_number}
    - -
    - ( - // - // } title={item.title} description={item.msgTime} /> - //
    {item.content}
    - //
    - (messageRefs.current[index] = el)} - key={message.id} - {...message} - // position={message.sender === 'me' ? 'right' : 'left'} - position={'left'} - replyButton={false} - onReplyMessageClick={() => scrollToMessage(message.reply.id)} - onOpen={() => handlePreview(message)} - onTitleClick={() => handlePreview(message)} - notch={false} - title={message.whatsapp_msg_type === 'text' ? '' : message.title} - text={} - copiableDate={true} - dateString={message.dateString || message.localDate} - className={[ - 'whitespace-pre-wrap mb-2', - message.whatsapp_msg_type === 'sticker' ? 'bg-transparent' : '', - message.sender === 'me' ? 'whatsappme-container' : '', - focusMsg === message.id ? 'message-box-focus' : '', - message.status === 'failed' ? 'failed-msg' : '', - ].join(' ')} - style={{ - backgroundColor: message.sender === 'me' ? '#ccd4ae' : '#fff', - }} - {...(message.type === 'meetingLink' - ? { - actionButtons: [ - { - onClickButton: () => { - navigator.clipboard.writeText(message.text); - appMessage.success('复制成功😀'); - }, - Component: () =>
    复制
    , - }, - ], - } - : {})} - renderAddCmp={ -
    - - {message.msg_direction === 'outbound' ? selectedConversation.OPI_Name : message.senderName} - - {message.dateString || message.localDate} - {message.statusCN} -
    - } - // date={null} - // status={null} - /> - )} - /> -
    -
    + +
    - {/* */} - +
    ); -} - -export default ChatHistory; +}; +export default Index; diff --git a/src/views/Conversations/History/ConversationsList.jsx b/src/views/Conversations/History/ConversationsList.jsx new file mode 100644 index 0000000..941d9d8 --- /dev/null +++ b/src/views/Conversations/History/ConversationsList.jsx @@ -0,0 +1,53 @@ +import { useEffect, useState } from 'react'; +import { Spin } from 'antd'; +import { ChatItem } from 'react-chat-elements'; +import useFormStore from '@/stores/FormStore'; +import { flush, pick } from '@/utils/utils'; +import { fetchConversationsSearch } from '@/actions/ConversationActions'; + +const ConversationsList = ({ ...props }) => { + const [formValues,] = useFormStore(((state) => [state.chatHistoryForm,])); + const [selectedConversation, setSelectedConversation] = useFormStore((state) => [state.chatHistorySelectChat, state.setChatHistorySelectChat]); + + const [conversationsListLoading, setConversationsListLoading] = useState(false); + const [conversationsList, setConversationsList] = useState([]); + + useEffect(() => { + getConversationsList(); + return () => {}; + }, [formValues]); + + const getConversationsList = async () => { + setConversationsListLoading(true); + const params = flush(pick(formValues, ['opisn', 'whatsapp_id', 'search', 'from_date', 'end_date', 'coli_id'])); + const data = await fetchConversationsSearch(params); + setConversationsListLoading(false); + setConversationsList(data); + if (data.length === 1) { + setSelectedConversation(data[0]); + } + }; + return ( + <> + + {conversationsList.map((item) => ( + setSelectedConversation(item)} + /> + ))} + + + ); +}; +export default ConversationsList; diff --git a/src/views/Conversations/History/ImageAlumPreview.jsx b/src/views/Conversations/History/ImageAlumPreview.jsx new file mode 100644 index 0000000..4268b3c --- /dev/null +++ b/src/views/Conversations/History/ImageAlumPreview.jsx @@ -0,0 +1,30 @@ +import { useEffect, useState } from 'react'; +import { Image } from 'antd'; +import useFormStore from '@/stores/FormStore'; + +const ImageAlbumPreview = (props) => { + const [ImageAlbum,] = useFormStore((state) => [state.ImageAlbum, ]); + const [ImagePreviewSrc, setImagePreviewSrc] = useFormStore((state) => [state.ImagePreviewSrc, state.setImagePreviewSrc]); + + const [previewVisible, setPreviewVisible] = useState(false); + const [previewIndex, setPreviewIndex] = useState(); + const onPreviewClose = () => { + setImagePreviewSrc(''); + setPreviewVisible(false); + }; + useEffect(() => { + if (ImagePreviewSrc) { + setPreviewVisible(true); + setPreviewIndex(ImageAlbum.findIndex((url) => url === ImagePreviewSrc)); + } + + return () => {}; + }, [ImagePreviewSrc]); + + return ( + <> + + + ); +}; +export default ImageAlbumPreview; diff --git a/src/views/Conversations/History/MessagesList.jsx b/src/views/Conversations/History/MessagesList.jsx new file mode 100644 index 0000000..d8cacfd --- /dev/null +++ b/src/views/Conversations/History/MessagesList.jsx @@ -0,0 +1,268 @@ +import { useRef, useEffect, useState, forwardRef, memo } from 'react'; +import { App, Flex, List, Button, } from 'antd'; +import { LoadingOutlined } from '@ant-design/icons'; +import { MessageBox } from 'react-chat-elements'; +import { MESSAGE_PAGE_SIZE, fetchMessagesHistory } from '@/actions/ConversationActions'; +import useFormStore from '@/stores/FormStore'; +import { isEmpty, stringToColour } from '@/utils/utils'; +import { useShallow } from 'zustand/react/shallow'; + +const BIG_PAGE_SIZE = MESSAGE_PAGE_SIZE * 100; +const MessagesList = ({ ...props }) => { + const { message: appMessage } = App.useApp(); + + const [formValues] = useFormStore((state) => [state.chatHistoryForm]); + const [selectedConversation] = useFormStore((state) => [state.chatHistorySelectChat]); + const [paramsForMsgList, setParamsForMsgList] = useFormStore((state) => [state.msgListParams, state.setMsgListParams]); + const [selectMatch, setSelectedMatch] = useFormStore((state) => [state.msgHistorySelectMatch, state.setMsgHistorySelectMatch]); + const [setImageAlbumList, setImagePreviewSrc] = useFormStore(useShallow((state) => [state.setImageAlbum, state.setImagePreviewSrc])); + + const [chatItemMessages, setChatItemMessages] = useState([]); + const [messageListPreLoading, setMessageListPreLoading] = useState(false); + const [messageListLoading, setMessageListLoading] = useState(false); + + const getMessagesPre = async (chatItem) => { + setMessageListPreLoading(true); + const data = await fetchMessagesHistory({ ...chatItem, lasttime: chatItem.pretime, pagedir: 'pre', pagesize: BIG_PAGE_SIZE }); + setMessageListPreLoading(false); + setChatItemMessages((prevValue) => data.concat(prevValue)); + const loadPrePage = !(data.length === 0 || data.length < BIG_PAGE_SIZE); + setParamsForMsgList({ loadPrePage }); + }; + const getMessagesNext = async (chatItem) => { + setMessageListLoading(true); + const data = await fetchMessagesHistory({ ...chatItem, pagedir: 'next', pagesize: BIG_PAGE_SIZE }); + setMessageListLoading(false); + setChatItemMessages((prevValue) => prevValue.concat(data)); + const loadNextPage = !(data.length === 0 || data.length < BIG_PAGE_SIZE); + setParamsForMsgList({ loadNextPage }); + }; + + // 选择指定消息之后, 定位 + const scrollToSelectedMessage = (selected) => { + const findIndex = chatItemMessages.findIndex((item) => item.id === selected.id); + if (findIndex !== -1) { + scrollToMessage(selected.id, findIndex); + } + }; + + // 选中会话之后, 获取消息记录 + useEffect(() => { + setChatItemMessages([]); + setParamsForMsgList({}); + setSelectedMatch({}); + if (isEmpty(selectedConversation.conversationid) || isEmpty(selectedConversation.opi_sn)) { + return () => {}; + } + const firstActionPageParams = { opisn: selectedConversation.opi_sn, whatsappid: selectedConversation.whatsapp_phone_number, loadNextPage: true }; + // if (isEmpty(selectedConversation.matchMsgList)) { + if (!isEmpty(formValues?.from_date)) { + firstActionPageParams.lasttime = formValues.from_date; + firstActionPageParams.loadPrePage = true; + } + if (!isEmpty(formValues?.search)) { + firstActionPageParams.pretime = selectedConversation.matchMsgList[0].orgmsgtime; + firstActionPageParams.lasttime = selectedConversation.matchMsgList[0].orgmsgtime; + firstActionPageParams.loadPrePage = true; + } + setParamsForMsgList(firstActionPageParams); + async function getFirstNext() { + await getMessagesNext(firstActionPageParams); + } + getFirstNext(); + + return () => {}; + }, [selectedConversation.conversationid]); + + // 点击匹配的记录, 定位滚动 + useEffect(() => { + async function getFirstPre(_params) { + await getMessagesPre(_params); + } + + const findIndex = chatItemMessages.findIndex((item) => item.id === selectMatch.id); + if (findIndex === -1) { + setMessageListLoading(true); + getFirstPre({ ...paramsForMsgList }); + setMessageListLoading(false); + } + scrollToSelectedMessage(selectMatch); + return () => {}; + }, [selectMatch.id]); + + // 更新是否需要显示上一页,下一页按钮 + useEffect(() => { + if (chatItemMessages.length > 0) { + setParamsForMsgList({ pretime: chatItemMessages[0].orgmsgtime, lasttime: chatItemMessages[chatItemMessages.length - 1].orgmsgtime }); + const album = chatItemMessages.filter((ele) => ele.whatsapp_msg_type === 'image').map((ele) => ele.data.uri); + setImageAlbumList(album); + } + return () => {}; + }, [chatItemMessages]); + + const onLoadMore = () => { + getMessagesNext(paramsForMsgList); + // window.dispatchEvent(new Event('resize')); + }; + const loadMore = + !messageListLoading && paramsForMsgList.loadNextPage ? ( +
    + +
    + ) : null; + const onLoadMorePre = () => { + getMessagesPre(paramsForMsgList); + // window.dispatchEvent(new Event('resize')); + }; + const loadMorePre = + paramsForMsgList.loadPrePage && chatItemMessages.length > 0 ? ( +
    + {messageListPreLoading ? : } +
    + ) : null; + + const messagesEndRef = useRef(null); + const messageRefs = useRef([]); + const [focusMsg, setFocusMsg] = useState(''); + const scrollToMessage = (id, index) => { + const _i = index || chatItemMessages.findIndex((msg) => msg.id === id); + if (_i >= 0) { + messageRefs.current[_i].scrollIntoView({ behavior: 'smooth', block: 'start' }); + setFocusMsg(id); + } + }; + + const RenderText = memo(function renderText({ str, className }) { + 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) ? '' : ''; + 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 { + return part.key; + } + })} + + ); + }); + + // eslint-disable-next-line react/display-name + const MessageBoxWithRef = forwardRef((props, ref) => ( +
  • + +
  • + )); + + const handlePreview = (msg) => { + switch (msg.whatsapp_msg_type) { + case 'image': + setImagePreviewSrc(msg.data.uri); + return false; + + case 'document': + window.open(msg.data.link || msg.data.uri, '_blank', 'noopener,noreferrer'); + return false; + + default: + return false; + } + }; + + return ( + <> + +
    + {selectedConversation.whatsapp_name} {selectedConversation.whatsapp_phone_number} +
    + +
    + ( + // + // } title={item.title} description={item.msgTime} /> + //
    {item.content}
    + //
    + (messageRefs.current[index] = el)} + key={message.id} + {...message} + // position={message.sender === 'me' ? 'right' : 'left'} + position={'left'} + replyButton={false} + onReplyMessageClick={() => scrollToMessage(message.reply.id)} + onOpen={() => handlePreview(message)} + onTitleClick={() => handlePreview(message)} + notch={false} + title={message.whatsapp_msg_type === 'text' ? '' : message.title} + text={} + copiableDate={true} + dateString={message.dateString || message.localDate} + className={[ + 'whitespace-pre-wrap mb-2', + message.whatsapp_msg_type === 'sticker' ? 'bg-transparent' : '', + message.sender === 'me' ? 'whatsappme-container' : '', + focusMsg === message.id ? 'message-box-focus' : '', + message.status === 'failed' ? 'failed-msg' : '', + ].join(' ')} + style={{ + backgroundColor: message.sender === 'me' ? '#ccd4ae' : '#fff', + }} + {...(message.type === 'meetingLink' + ? { + actionButtons: [ + { + onClickButton: () => { + navigator.clipboard.writeText(message.text); + appMessage.success('复制成功😀'); + }, + Component: () =>
    复制
    , + }, + ], + } + : {})} + renderAddCmp={ +
    + + {message.msg_direction === 'outbound' ? selectedConversation.OPI_Name : message.senderName} + + {message.dateString || message.localDate} + {message.statusCN} +
    + } + // date={null} + // status={null} + /> + )} + /> +
    +
    + + ); +}; +export default MessagesList; diff --git a/src/views/Conversations/History/MessagesMatchList.jsx b/src/views/Conversations/History/MessagesMatchList.jsx new file mode 100644 index 0000000..6c7a740 --- /dev/null +++ b/src/views/Conversations/History/MessagesMatchList.jsx @@ -0,0 +1,40 @@ +import { ChatItem } from 'react-chat-elements'; +import useFormStore from '@/stores/FormStore'; +import { isNotEmpty } from '@/utils/commons'; + +const MessagesMatchList = ({ ...props }) => { + const [formValues] = useFormStore((state) => [state.chatHistoryForm]); + const [selectedConversation] = useFormStore((state) => [state.chatHistorySelectChat]); + const [selectMatch, setSelectedMatch] = useFormStore((state) => [state.msgHistorySelectMatch, state.setMsgHistorySelectMatch]); + + return ( + <> + {(selectedConversation.matchMsgList || []).length > 0 && isNotEmpty(formValues.search) && ( +
    +

    + {formValues.search} 的相关记录, 点击定位上下文 +

    + {selectedConversation.matchMsgList.map((item) => ( + setSelectedMatch(item)} + /> + ))} +
    + )} + + ); +}; +export default MessagesMatchList; diff --git a/src/views/Conversations/History/SearchForm.jsx b/src/views/Conversations/History/SearchForm.jsx new file mode 100644 index 0000000..16eb4e2 --- /dev/null +++ b/src/views/Conversations/History/SearchForm.jsx @@ -0,0 +1,64 @@ +/* eslint-disable react/display-name */ +import { memo } from 'react'; +import { Form, Flex, Input, Button, DatePicker } from 'antd'; +import SearchInput from '@/components/SearchInput'; +import { isNotEmpty } from '@/utils/commons'; +import { fetchSalesAgent, fetchCustomerList } from '@/actions/CommonActions'; + +const { RangePicker } = DatePicker; +const SearchForm = memo(function ({ initialValues, onSubmit, onReset }) { + const [form] = Form.useForm(); + function handleSubmit(values) { + const multiAgents = (values?.agent || []).map((ele) => ele.value).join(','); + const multiCustomers = (values?.customer || []).map((ele) => ele.value).join(','); + onSubmit?.({ + ...values, + opisn: multiAgents, + whatsapp_id: multiCustomers, + ...(isNotEmpty(values.msgDateRange) + ? { + from_date: values.msgDateRange[0].format('YYYY-MM-DD'), + end_date: values.msgDateRange[1].format('YYYY-MM-DD'), + } + : {}), + }); + } + return ( +
    + + + + + + + + + + + + + + + + + + +
    + {/* */} + +
    +
    +
    + ); +}); +export default SearchForm;