fix: 订单跟踪页面的高级查询的状态

style: 消息输入: 字数显示: 最大2000.
perf: 历史记录里面的template
perf: 模板填充顾问的英文名
perf: 历史记录: 发送失败显示时间
feat: 联系人名片: 点击开启会话
perf: 更新会话的下一页参数
perf: 上传文件重命名, 避免重名覆盖
dev/mobile
Lei OT 2 years ago
parent a9c26afade
commit 3238346475

@ -22,6 +22,19 @@ export const fetchConversationsList = async (params) => {
return list;
};
/**
*
* @param {object} params { opisn, whatsappid, colisn }
* * opisn, colisn : 用于查询
* * whatsappid: 用于创建会话
*/
export const fetchOrderConversationsList = async (params) => {
const { errcode, result: data } = await fetchJSON(`${API_HOST}/getorderconversation`, params);
if (errcode !== 0) return [];
const list = data.map((ele) => ({ ...ele, customer_name: `${ele.whatsapp_name || ''}`.trim(), whatsapp_name: `${ele.whatsapp_name || ''}`.trim() }));
return list;
};
export const MESSAGE_PAGE_SIZE = 100;
/**
*
@ -38,17 +51,6 @@ export const fetchMessages = async (params) => {
return errcode !== 0 ? [] : parseRenderMessageList((result || []).reverse());
}
/**
*
* @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 [];
const list = data.map((ele) => ({ ...ele, customer_name: ele.whatsapp_name.trim() }));
return list;
};
/**
*
* @param {object} body { opisn, conversationid }

@ -14,6 +14,9 @@ export const replaceTemplateString = (str, replacements) => {
return result;
}
/**
* @deprecated 在渲染时处理
*/
export const autoLinkText = (text) => {
return text;
// let regex = /(https?:\/\/[^\s]+)/g;
@ -139,7 +142,7 @@ export const sentMsgTypeMapped = {
contentToRender: (msg) => ({
...msg,
...mediaMsg.contentToRender(msg),
text: msg?.name || '',
text: (msg?.name || '') + `\n${msg?.text || ''}`,
title: msg?.name || '',
originText: msg?.name || '',
whatsapp_msg_type: 'document',
@ -360,13 +363,13 @@ export const whatsappMsgTypeMapped = {
data: (msg) => ({
id: msg.wamid,
title: msg.document?.filename || '',
text: msg.document?.caption || msg.document?.filename || '',
data: { uri: msg.document.link, extension: 'PDF', status: { click: false, download: true, loading: 0 } },
text: (msg.document?.filename || '') + `\n${msg.document?.caption || ''}`,
data: { uri: msg.document.link, status: { click: false, download: true, loading: 0 } },
originText: msg.document?.caption || msg.document?.filename || '',
}),
renderForReply: (msg) => ({
id: msg.wamid,
message: msg.document?.caption || msg.document?.filename || '',
message: msg.document?.caption || msg.document?.filename || '[文件]',
}),
},
contacts: {
@ -401,15 +404,11 @@ export const whatsappMsgTypeMapped = {
message: '[位置]',
}),
},
// contact: 'contact',
// 'contact-card': 'contact-card',
// 'contact-card-with-photo': 'contact-card-with-photo',
// 'contact-card-with-photo-and-label': 'contact-card-with-photo-and-label',
template: {
type: 'text',
data: (msg) => {
const templateDataMapped = msg.template?.components ? msg.template.components.reduce((r, v) => ({ ...r, [v.type]: v }), {}) : null;
return { id: msg.wamid, text: autoLinkText(templateDataMapped?.body?.text || templateDataMapped?.body?.parameters?.[0]?.text || ''), title: msg.template.name };
return { id: msg.wamid, text: autoLinkText(templateDataMapped?.body?.text || `......${templateDataMapped?.body?.parameters.map(pv => pv?.text || '').join('......')}......`), title: msg.template.name };
},
renderForReply: (msg) => {
const templateDataMapped = msg.template?.components ? msg.template.components.reduce((r, v) => ({ ...r, [v.type]: v }), {}) : null;
@ -487,7 +486,7 @@ export const parseRenderMessageList = (messages, conversationid = null) => {
sender: 'me',
senderName: 'me',
status: msgStatusRenderMapped[msgContent?.status || 'failed'],
dateString: msgStatusRenderMapped[msgContent?.status || 'failed'] === 'failed' ? `发送失败 ${whatsappError?.[msgContent.errorCode] || msgContent.errorMessage}` : '',
dateString: msgStatusRenderMapped[msgContent?.status || 'failed'] === 'failed' ? `${(msg.msgtime || '').replace('T', ' ')} 发送失败 ${whatsappError?.[msgContent.errorCode] || msgContent.errorMessage}` : '',
statusCN: msgStatusRenderMappedCN[msgContent?.status || 'failed'],
statusTitle: msgStatusRenderMappedCN[msgContent?.status || 'failed'],
}

@ -301,10 +301,10 @@ export const useConversationStore = create(
setInitial: (v) => set({ initialState: v }),
// side effects
fetchInitialData: async (userId) => {
const { addToConversationList, setTemplates, setInitial, receivedMessageList } = get();
fetchInitialData: async (userIds) => {
const { addToConversationList, setTemplates, setInitial, } = get();
const conversationsList = await fetchConversationsList({ opisn: userId });
const conversationsList = await fetchConversationsList({ opisn: userIds });
addToConversationList(conversationsList);
const templates = await fetchTemplates();

@ -301,7 +301,7 @@ export const cartesianProductArray = (arr, sep = '_', index = 0, prefix = '') =>
return result;
};
export const stringToColour = (str) => {
export const stringToColour_bak = (str) => {
// Hash the username using SHA256
const hash = crypto.SHA256(str);
// Convert the hash to a hexadecimal string
@ -310,6 +310,19 @@ export const stringToColour = (str) => {
const color = '#' + hexString.substring(0, 6);
return color;
};
export const stringToColour = (str) => {
var hash = 0
for (let i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash)
}
var colour = '#'
for (let i = 0; i < 3; i++) {
var value = (hash >> (i * 8)) & 0xff
value = (value % 150) + 50
colour += ('00' + value.toString(16)).substr(-2)
}
return colour
}
export const debounce = (func, wait, immediate) => {
var timeout;

@ -21,7 +21,7 @@ function AuthApp() {
const navigate = useNavigate()
const { colorPrimary, borderRadius } = useThemeContext()
const { loginUser } = useAuthStore()
const loginUser = useAuthStore(state => state.loginUser)
const href = useHref()
@ -36,7 +36,7 @@ function AuthApp() {
useEffect(() => {
if (loginUser.userId > 0) {
useConversationStore.getState().connectWebsocket(loginUser.userId);
useConversationStore.getState().fetchInitialData(loginUser.userId);
useConversationStore.getState().fetchInitialData(loginUser.userId); // userIdStr
}
return () => {
useConversationStore.getState().disconnectWebsocket();

@ -1,10 +1,9 @@
import { memo, useCallback, useEffect, useRef, useState, forwardRef } from 'react';
import { Divider, Button, Input, Layout, Select, DatePicker, Form, List, Spin } from 'antd';
import { Divider, Button, Input, Layout, DatePicker, Form, List, Spin } from 'antd';
import { ChatItem, MessageBox } from 'react-chat-elements';
import { fetchConversationsList, fetchMessages, MESSAGE_PAGE_SIZE } from '@/actions/ConversationActions';
import { isEmpty } from '@/utils/utils';
import { isEmpty, stringToColour } from '@/utils/utils';
import useFormStore from '@/stores/FormStore';
import { useShallow } from 'zustand/react/shallow';
import { fetchSalesAgent, fetchCustomerList } from '@/actions/CommonActions';
import SearchInput from '@/components/SearchInput';
@ -87,14 +86,25 @@ function ChatHistory() {
await getMessages(data[0]);
}
};
const getMessagesPre = async (chatItem) => {
setLoading(true);
const data = await fetchMessages({ opisn: chatItem.opi_sn, whatsappid: chatItem.whatsapp_phone_number, lasttime: chatItem?.pretime || '' });
setLoading(false);
setChatItemMessages(prevValue => data.concat(prevValue));
const thisPreTime = data.length > 0 ? data[0].orgmsgtime : '';
const loadPrePage = !(data.length === 0 || data.length < MESSAGE_PAGE_SIZE);
setSelectedConversation({ ...chatItem, pretime: thisPreTime, loadPrePage });
};
const getMessages = async (chatItem) => {
setLoading(true);
const data = await fetchMessages({ opisn: chatItem.opi_sn, whatsappid: chatItem.whatsapp_phone_number, lasttime: chatItem?.lasttime || '' });
setLoading(false);
setChatItemMessages(prevValue => prevValue.concat(data));
const thisPreTime = data.length > 0 ? data[0].orgmsgtime : '';
const loadPrePage = !(data.length === 0 || data.length < MESSAGE_PAGE_SIZE);
const thisLastTime = data.length > 0 ? data[data.length - 1].orgmsgtime : '';
const loadNextPage = !(data.length === 0 || data.length < MESSAGE_PAGE_SIZE);
setSelectedConversation({ ...chatItem, lasttime: thisLastTime, loadNextPage });
const loadNextPage = false; // debug: !(data.length === 0 || data.length < MESSAGE_PAGE_SIZE);
setSelectedConversation({ ...chatItem, lasttime: thisLastTime, loadNextPage, pretime: thisPreTime, loadPrePage});
};
useEffect(() => {
@ -167,6 +177,15 @@ function ChatHistory() {
<Button onClick={onLoadMore}>loading more</Button>
</div>
) : null;
const onLoadMorePre = () => {
getMessagesPre(selectedConversation);
// window.dispatchEvent(new Event('resize'));
};
const loadMorePre = !loading && selectedConversation.loadPrePage ? (
<div className='text-center pt-3 mb-3 h-8 leading-8 border-dotted border-0 border-t border-slate-300'>
<Button onClick={onLoadMorePre}>loading more</Button>
</div>
) : null;
const messagesEndRef = useRef(null);
const messageRefs = useRef([]);
@ -194,7 +213,7 @@ function ChatHistory() {
{...item}
key={item.sn}
id={item.sn}
letterItem={{ id: item.whatsapp_name || item.whatsapp_phone_number, letter: (item.whatsapp_name || item.whatsapp_phone_number).slice(0, 5) }}
letterItem={{ id: item.whatsapp_name || item.whatsapp_phone_number, letter: (item.whatsapp_name || item.whatsapp_phone_number).split(" ")[0] }}
alt={`${item.whatsapp_name}`}
title={item.whatsapp_name || item.whatsapp_phone_number}
subtitle={item.coli_id}
@ -209,6 +228,7 @@ function ChatHistory() {
<div className='h-full relative' ref={messagesEndRef}>
<List
loading={loading}
header={loadMorePre}
loadMore={loadMore}
className='h-full overflow-y-auto px-2 relative'
itemLayout='vertical'
@ -253,7 +273,7 @@ function ChatHistory() {
: {})}
renderAddCmp={
<div className='border-dashed border-0 border-t border-slate-300 text-slate-600 space-x-2 emoji'>
<span>{message.senderName}</span>
<span className={`p-1 rounded-b ${message.msg_direction === 'outbound' ? 'text-white' : ''} `} style={{backgroundColor: message.msg_direction === 'outbound' ? stringToColour(message.senderName) : 'unset'}}>{message.senderName}</span>
<span>{message.dateString || message.localDate}</span>
<span>{message.statusCN}</span>
</div>

@ -1,9 +1,8 @@
import { useEffect, useState, useRef } from 'react';
import { useParams, useNavigate, useLocation } from 'react-router-dom';
import { Button, Dropdown, Input } from 'antd';
import { MoreOutlined } from '@ant-design/icons';
import { fetchOrderConversationsList, fetchConversationItemClose, fetchMessages, MESSAGE_PAGE_SIZE, fetchCleanUnreadMsgCount } from '@/actions/ConversationActions';
import { ChatList, ChatItem } from 'react-chat-elements';
import { Dropdown, Input } from 'antd';
import { fetchOrderConversationsList, fetchConversationItemClose, fetchMessages, MESSAGE_PAGE_SIZE, } from '@/actions/ConversationActions';
import { ChatItem } from 'react-chat-elements';
import { isEmpty } from '@/utils/utils';
import useConversationStore from '@/stores/ConversationStore';
import useAuthStore from '@/stores/AuthStore';
@ -64,7 +63,7 @@ const Conversations = () => {
}
}
if (findCurrentIndex >= 0) {
switchConversation(findCurrent);
setCurrentConversation(findCurrent);
} else {
// reset chat window
setCurrentConversation({ sn: '', customer_name: '', coli_sn: order_sn });
@ -80,16 +79,19 @@ const Conversations = () => {
const loadNextPage = !(data.length === 0 || data.length < MESSAGE_PAGE_SIZE);
updateCurrentConversation({ lasttime: thisLastTime, loadNextPage });
};
const switchConversation = async (item) => {
setCurrentConversation(item);
const messagesList = activeConversations[`${item.sn}`] || [];
useEffect(() => {
const messagesList = activeConversations[`${currentConversation.sn}`] || [];
if (messagesList.length < 20) {
getMessages(item);
getMessages(currentConversation);
}
};
return () => {};
}, [currentConversation.sn]);
const onSwitchConversation = async (item) => {
switchConversation(item);
setCurrentConversation(item);
if (isEmpty(item.coli_sn)) {
navigate(`/order/chat`, { replace: true });
} else {
@ -193,7 +195,7 @@ const Conversations = () => {
date={item.last_received_time}
unread={item.unread_msg_count}
className={
[String(item.sn) === String(currentConversation.sn) ? '__active text-primary border-y-0 border-e-0 border-s-4 border-solid border-whatsapp-bg bg-whatsapp-bg' : '',
[String(item.sn) === String(currentConversation.sn) ? '__active text-primary bg-whatsapp-bg' : '',
String(item.sn) === String(tabSelectedConversation?.sn) ? ' bg-neutral-200' : ''
].join(' ')
}

@ -15,7 +15,7 @@ const InputTemplate = ({ disabled = false, inputEmoji }) => {
overlayClassName='p-0'
placement={'right'}
overlayInnerStyle={{ padding: 0, borderRadius: '8px' }}
// fresh
forceRender={true}
content={<EmojiPicker skinTonesDisabled={true} emojiStyle='google' onEmojiClick={handlePickEmoji} />}
// title='😀'
trigger='click'

@ -1,4 +1,5 @@
import { Upload, Button, message } from 'antd';
import { Upload, Button, message, Tooltip } from 'antd';
import { useState } from 'react';
import { FileAddOutlined } from '@ant-design/icons';
import { v4 as uuid } from 'uuid';
import { API_HOST } from '@/config';
@ -29,17 +30,17 @@ const ImageUpload = ({ disabled, invokeUploadFileMessage, invokeSendUploadMessag
// const setComplexMsg = useConversationStore(state => state.setComplexMsg);
// const complexMsg = useConversationStore(state => state.complexMsg);
const [fileObj, setFileObj] = useState();
const beforeUpload = async (file) => {
// 使 FileReader
const reader = new FileReader();
const suffix = file.name.slice(file.name.lastIndexOf('.')+1);
const type = Object.keys(fileTypesExt).find((type) => fileTypesExt[type].includes(suffix));
const rename = Date.now() + '.' + suffix;
const dataUri = aliOSSHost + rename;
//
reader.onload = (event) => {
const previewSrc = event.target.result;
const suffix = file.name.slice(file.name.lastIndexOf('.')+1);
const type = Object.keys(fileTypesExt).find((type) => fileTypesExt[type].includes(suffix));
const name = file.name;
const rename = Date.now() + '.' + suffix;
const dataUri = aliOSSHost + file.name;
const msgObj = {
type: type,
name: file.name,
@ -48,11 +49,12 @@ const ImageUpload = ({ disabled, invokeUploadFileMessage, invokeSendUploadMessag
id: uuid(),
};
file.msgData = msgObj;
setFileObj(msgObj);
invokeUploadFileMessage(msgObj);
};
// dataURL
reader.readAsDataURL(file);
return file;
return new File([file], rename, { type: file.type })
};
const uploadProps = {
name: 'file',
@ -71,14 +73,16 @@ const ImageUpload = ({ disabled, invokeUploadFileMessage, invokeSendUploadMessag
{...uploadProps}
onChange={({file}) => {
if (file.status === 'done') {
invokeSendUploadMessage(file.msgData);
invokeSendUploadMessage(fileObj);
}
if (file.status === 'error') {
message.error(`添加失败`);
}
}}
>
<Tooltip title={'图片, 视频, 语音, 附件'} placement={'bottom'}>
<Button key={'addPic'} type='text' disabled={disabled} icon={<FileAddOutlined />} size={'middle'} className='text-primary rounded-none' />
</Tooltip>
</Upload>
);
};

@ -24,10 +24,11 @@ const InputTemplate = ({ disabled = false, invokeSendMessage }) => {
const searchInputRef = useRef(null);
const { notification } = App.useApp();
const loginUser = useAuthStore((state) => state.loginUser);
loginUser.usernameEN = loginUser.accountList[0].OPI_NameEN.split(' ')?.[0] || loginUser.username;
const currentConversation = useConversationStore((state) => state.currentConversation);
const templates = useConversationStore((state) => state.templates);
// : customer, agent
const valueMapped = { ...cloneDeep(currentConversation), ...objectMapper(loginUser, { username: [{ key: 'agent_name' }, { key: 'your_name' }] }) };
const valueMapped = { ...cloneDeep(currentConversation), ...objectMapper(loginUser, { usernameEN: [{ key: 'agent_name' }, { key: 'your_name' }] }) };
useEffect(() => {
setDataSource(templates);
return () => {};

@ -129,12 +129,12 @@ const InputComposer = () => {
// 使 FileReader
const reader = new FileReader();
const suffix = file.name.slice(file.name.lastIndexOf('.')+1);
const newName = rename ? `${uuid()}.${suffix}` : file.name;
const newName = `${uuid()}.${suffix}`; // rename ? `${uuid()}.${suffix}` : file.name;
const type = Object.keys(fileTypesExt).find((type) => fileTypesExt[type].includes(suffix));
const dataUri = aliOSSHost + newName;
const msgObj = {
type: type,
name: newName,
name: file.name,
uploadStatus: 'loading',
data: { dataUri: dataUri, link: dataUri, width: '100%', height: 150, loading: 0.01 },
id: uuid(),
@ -248,8 +248,8 @@ const InputComposer = () => {
<Input.TextArea
onPaste={handlePaste}
ref={textInputRef}
size='large'
placeholder={gt24h ? 'This session has expired. Please send a template message to activate the session' : 'Enter for Send, Shift+Enter for new line'}
size='large' maxLength={2000} showCount={textabled}
placeholder={gt24h ? 'This session has expired. Please send a template message to activate the session' : 'Enter 发送, Shift+Enter 换行\n支持复制粘贴 [截图/文件] 以备发送'}
rows={2}
disabled={!textabled}
value={textContent}

@ -6,7 +6,7 @@ import { useShallow } from 'zustand/react/shallow';
import useConversationStore from '@/stores/ConversationStore';
import { isEmpty, } from '@/utils/utils';
const MessagesList = ({ messages, handlePreview, reference, longListLoading, getMoreMessages, shouldScrollBottom, loadNextPage, ...props }) => {
const MessagesList = ({ messages, handlePreview, reference, longListLoading, getMoreMessages, shouldScrollBottom, loadNextPage, handleContactClick, ...props }) => {
const setReferenceMsg = useConversationStore(useShallow((state) => state.setReferenceMsg));
// const messagesEndRef = useRef(null);
@ -43,7 +43,7 @@ const MessagesList = ({ messages, handlePreview, reference, longListLoading, get
return prev;
}, []);
return (
<span className={`text-base leading-5 emoji-text ${extraClass}`}>
<span className={`text-base leading-5 emoji-text whitespace-pre-wrap ${extraClass}`}>
{(objArr || []).map((part, index) => {
if (part.type === 'link') {
return (
@ -103,6 +103,10 @@ const MessagesList = ({ messages, handlePreview, reference, longListLoading, get
{...(message.type === 'meetingLink'
? {
actionButtons: [
{
onClickButton: () => handleContactClick(message.data),
Component: () => <div>发消息</div>,
},
{
onClickButton: () => {
navigator.clipboard.writeText(message.text);

@ -1,13 +1,17 @@
import { useRef, useState, useEffect } from 'react';
import useConversationStore from '@/stores/ConversationStore';
import { useShallow } from 'zustand/react/shallow';
import { Image, } from 'antd';
import { Image, Modal, Button } from 'antd';
import MessagesList from './MessagesList';
import { fetchCleanUnreadMsgCount, fetchMessages, MESSAGE_PAGE_SIZE } from '@/actions/ConversationActions';
import { fetchOrderConversationsList, } from '@/actions/ConversationActions';
import { isEmpty } from '@/utils/utils';
const MessagesWrapper = () => {
const [currentConversation, updateCurrentConversation] = useConversationStore(useShallow((state) => [state.currentConversation, state.updateCurrentConversation]));
const [currentConversation, updateCurrentConversation, setCurrentConversation] = useConversationStore(useShallow((state) => [state.currentConversation, state.updateCurrentConversation, state.setCurrentConversation]));
const conversationsList = useConversationStore(useShallow((state) => state.conversationsList));
const activeMessages = useConversationStore(useShallow((state) => (state.currentConversation.sn && state.activeConversations[state.currentConversation.sn] ? state.activeConversations[state.currentConversation.sn]: [])));
const addToConversationList = useConversationStore((state) => state.addToConversationList);
const [longList, setLongList] = useState([]);
const [longListLoading, setLongListLoading] = useState(false);
@ -18,6 +22,9 @@ const MessagesWrapper = () => {
if (currentConversation.opi_sn && currentConversation.whatsapp_phone_number && activeMessages.length > 0) {
fetchCleanUnreadMsgCount({ opisn: currentConversation.opi_sn, whatsappid: currentConversation.whatsapp_phone_number });
}
const thisLastTime = activeMessages.length > 0 ? activeMessages[0].orgmsgtime : '';
const loadNextPage = !(activeMessages.length === 0 || activeMessages.length < MESSAGE_PAGE_SIZE);
updateCurrentConversation({ lasttime: thisLastTime, loadNextPage });
return () => {};
}, [activeMessages, currentConversation.sn]);
@ -57,10 +64,55 @@ const MessagesWrapper = () => {
return false;
}
};
const openContactConversation = async (whatsappID) => {
const {coli_sn, opi_sn} = currentConversation;
let findCurrentOrderChats = conversationsList.filter((item) => `${item.coli_sn}` === `${coli_sn}` && `${item.opi_sn}` === `${opi_sn}` && `${item.whatsapp_phone_number}` === `${whatsappID}`);
let findCurrentIndex = isEmpty(findCurrentOrderChats) ? -1 : 0; // findCurrentOrderChats.length-1;
let findCurrent = findCurrentOrderChats[findCurrentIndex];
if (findCurrentIndex !== -1) {
addToConversationList(findCurrentOrderChats);
} else if (!isEmpty(whatsappID)) {
const data = await fetchOrderConversationsList({ opisn: opi_sn, colisn: coli_sn, whatsappid: whatsappID });
if (!isEmpty(data)) {
addToConversationList(data);
findCurrentIndex = data.findIndex((item) => `${item.coli_sn}` === `${coli_sn}` && `${item.opi_sn}` === `${opi_sn}` && `${item.whatsapp_phone_number}` === `${whatsappID}`);
findCurrentIndex = findCurrentIndex >= 0 ? findCurrentIndex : 0;
findCurrent = data[findCurrentIndex];
}
}
if (findCurrentIndex >= 0) {
setCurrentConversation(findCurrent);
}
setContactsModalVisible(false);
return false;
};
const [contactsModalVisible, setContactsModalVisible] = useState(false);
const [contactListData, setContactListData] = useState([]);
const handleContactItemClick = (contact) => {
openContactConversation(contact.wa_id);
}
const handleContactListClick = (data) => {
setContactListData(data);
setContactsModalVisible(true);
}
const handleContactClick = (data) => {
return data.length > 1 ? handleContactListClick(data) : handleContactItemClick(data[0]);
}
return (
<>
<MessagesList messages={longList} dataSourceLen={longList.length} {...{ reference, handlePreview, longListLoading, setLongListLoading, getMoreMessages, shouldScrollBottom, loadNextPage: currentConversation?.loadNextPage ?? true }} />
<MessagesList messages={longList} dataSourceLen={longList.length} {...{
reference, shouldScrollBottom,
handlePreview, handleContactClick,
longListLoading, setLongListLoading, getMoreMessages, loadNextPage: currentConversation?.loadNextPage ?? true
}}
/>
<Image width={0} height={0} src={null} preview={{ visible: previewVisible, src: previewSrc, onClose: onPreviewClose }} />
<Modal title="联系人" closable open={contactsModalVisible} onOk={handleContactItemClick} onCancel={() => setContactsModalVisible(false)} footer={null} >
{contactListData.map((contact) => (
<Button onClick={() => handleContactItemClick(contact)} type='link' key={contact.id}>{contact.name}: <span>{contact.wa_id}</span></Button>
))}
</Modal>
</>
);
};

@ -94,6 +94,9 @@
.chatwindow-wrapper .h-parent .ant-layout-side-children, .chatwindow-wrapper .h-inherit{
height: inherit;
}
.chatwindow-wrapper .ant-input-textarea-show-count .ant-input-data-count{
bottom: 0;
}
.chatwindow-wrapper .rce-container-mbox .rce-mbox{
max-width: 500px;
}
@ -118,7 +121,8 @@
.chatwindow-wrapper .rce-mbox-time,
.chatwindow-wrapper .referrer-msg,
.chatwindow-wrapper .rce-mbox-reply-message,
.chatwindow-wrapper .emoji
.chatwindow-wrapper .emoji,
.chatwindow-wrapper .ant-input-textarea-affix-wrapper.ant-input-affix-wrapper >textarea.ant-input
{
font-family: 'Open Sans', 'Noto Sans',"Noto Color Emoji", 'Apple Color Emoji', 'Twemoji Mozilla', 'Segoe UI Emoji', 'Segoe UI Symbol', 'EmojiOne Color', 'Android Emoji', Arial, sans-serif;
font-weight: 400;

@ -195,7 +195,7 @@ function OrderGroupTable({ formValues }) {
else if (record.coli_ordertype === 3 || record.coli_ordertype === 4 || record.coli_ordertype === 5) statusIcon = <Tooltip title={needTo}><PhoneTwoTone /></Tooltip>
else if (record.coli_ordertype === 6) statusIcon = <Tooltip title='老邮件'><MailTwoTone /></Tooltip>
return (
return (
<Space>
{statusIcon}
{text}
@ -320,9 +320,9 @@ function OrderGroupTable({ formValues }) {
}
)
})
return (<Conditional
condition={orderList.length > 0}
return (<Conditional
condition={orderList.length > 0}
whenTrue={<Tabs defaultActiveKey={0} items={collapseItems} />}
whenFalse={<Empty />}
/>)
@ -362,7 +362,7 @@ function OrderFollow() {
disabled={advanceChecked}
/>
<Switch checkedChildren='高级查询' unCheckedChildren='高级查询'
defaultChecked={false}
defaultChecked={advanceChecked} checked={advanceChecked}
onChange={() => { toggleAdvance(!advanceChecked) }} />
</Flex>
<Conditional condition={advanceChecked} whenTrue={<AdvanceSearchForm onSubmit={handleSubmit} initialValues={formValues} />}

Loading…
Cancel
Save