feat: 新建会话; feat: 标记为未读

dev/timezone
Lei OT 1 year ago
parent dc7a13d4b5
commit 72cfe68b64

@ -1,6 +1,6 @@
import { groupBy, pick, sortArrayByOrder } from '@/utils/commons';
import { fetchJSON, postJSON } from '@/utils/request'
import { fetchJSON, postJSON, postForm } from '@/utils/request'
import { parseRenderMessageList } from '@/channel/whatsappUtils';
import { API_HOST } from '@/config';
import { isEmpty } from '@/utils/commons';
@ -70,8 +70,20 @@ export const fetchConversationItemClose = async (body) => {
* @param {object} body { phone_number, name }
*/
export const postNewConversationItem = async (body) => {
const { errcode, result } = await postJSON(`${API_HOST}/newconversation`, body);
return errcode !== 0 ? {} : result;
const formData = new FormData();
Object.keys(body).forEach(function (key) {
formData.append(key, body[key]);
});
const { errcode, result } = await postForm(`${API_HOST}/new_conversation`, formData);
if (errcode !== 0) {
return {};
}
const resultItem = result?.[0] || {};
return {
...resultItem,
customer_name: `${resultItem.whatsapp_name || ''}`.trim(),
whatsapp_name: `${resultItem.whatsapp_name || ''}`.trim(),
};
};
/**
@ -86,6 +98,7 @@ export const fetchCleanUnreadMsgCount = async (params) => {
* 标记未未读
* @param {object} body conversationItem: { sn, ... }
*/
export const UNREAD_MARK = 999;
export const fetchConversationItemUnread = async (body) => {
const { errcode, result } = await fetchJSON(`${API_HOST}/set_state_unread`, body);
return errcode !== 0 ? {} : result;

@ -178,7 +178,7 @@ const conversationSlice = (set, get) => ({
const withoutNew = conversationsList.filter((item) => !newListIds.includes(`${item.sn}`));
const mergedList = [...newList, ...withoutNew];
const refreshTotalNotify = mergedList.reduce((r, c) => r+c.unread_msg_count, 0);
const refreshTotalNotify = mergedList.reduce((r, c) => r+(c.unread_msg_count === 999 ? 0 : c.unread_msg_count), 0);
return set((state) => ({
conversationsList: mergedList,
@ -237,7 +237,7 @@ const messageSlice = (set, get) => ({
totalNotify: 0,
msgListLoading: false,
activeConversations: {},
refreshTotalNotify: () => set((state) => ({ totalNotify: state.conversationsList.reduce((r, c) => r+c.unread_msg_count, 0) })),
refreshTotalNotify: () => set((state) => ({ totalNotify: state.conversationsList.reduce((r, c) => r+(c.unread_msg_count === 999 ? 0 : c.unread_msg_count), 0) })),
setMsgLoading: (msgListLoading) => set({ msgListLoading }),
receivedMessageList: (conversationid, msgList) =>
set((state) => ({

@ -2,7 +2,7 @@ import { useEffect, useState, useRef } from 'react';
import { useParams, useNavigate, useLocation } from 'react-router-dom';
import { Dropdown, Input, Button, Empty, Tooltip, Tag, Select } from 'antd';
import { PlusOutlined, WhatsAppOutlined, LoadingOutlined, HistoryOutlined, FireOutlined, MessageFilled, FilterOutlined, PlusSquareOutlined } from '@ant-design/icons';
import { fetchConversationsList, fetchOrderConversationsList, fetchConversationItemClose, fetchConversationsSearch, postNewConversationItem, fetchConversationItemUnread } from '@/actions/ConversationActions';
import { fetchConversationsList, fetchOrderConversationsList, fetchConversationItemClose, fetchConversationsSearch, postNewConversationItem, fetchConversationItemUnread, UNREAD_MARK } from '@/actions/ConversationActions';
import { ChatItem } from 'react-chat-elements';
import ConversationsNewItem from './ConversationsNewItem';
import { isEmpty, olog } from '@/utils/commons';
@ -29,7 +29,6 @@ const Conversations = ({ mobile }) => {
const [conversationsListLoading, setConversationsListLoading] = useConversationStore((state) => [state.conversationsListLoading, state.setConversationsListLoading]);
const addToConversationList = useConversationStore((state) => state.addToConversationList);
const delConversationitem = useConversationStore((state) => state.delConversationitem);
const updateConversationItem = useConversationStore((state) => state.updateConversationItem);
const closedConversationsList = useConversationStore((state) => state.closedConversationsList);
const setClosedConversationList = useConversationStore((state) => state.setClosedConversationList);
@ -61,11 +60,15 @@ const Conversations = ({ mobile }) => {
return () => {};
}, [isVisible]);
const [activeList, setActiveList] = useState(true);
const [dataSource, setDataSource] = useState(conversationsList);
const [listUpdateFlag, setListUpdateFlag] = useState();
useEffect(() => {
setDataSource(conversationsList);
// setDataSource(conversationsList);
setDataSource(activeList ? conversationsList: closedConversationsList);
return () => {};
}, [conversationsList.length]);
}, [conversationsList.length, listUpdateFlag, currentConversation.unread_msg_count]);
const [switchToC, setSwitchToC] = useState({});
const [shouldFetchCList, setShouldFetchCList] = useState(true);
@ -141,22 +144,9 @@ const Conversations = ({ mobile }) => {
};
const handleConversationItemUnread = async (item) => {
// updateConversationItem({ sn: item.sn, unread_msg_count: 1000 });
// const bak_dataSource = dataSource;
// const targetIndex = bak_dataSource.findIndex((ele) => String(ele.sn) === String(item.sn));
// bak_dataSource.splice(targetIndex, 1, {
// ...conversationsList[targetIndex],
// ...{ sn: item.sn, unread_msg_count: 1000 },
// })
setDataSource((prev) =>
prev.map((ele) => {
return String(ele.sn) === String(item.sn) ? { ...ele, unread_msg_count: 1000 } : ele;
})
);
// setDataSource(bak_dataSource);
// setDataSource(conversationsList);
await fetchConversationItemUnread({ conversationid: item.sn });
refreshConversationList();
await refreshConversationList();
setListUpdateFlag(Math.random());
}
const searchInputRef = useRef(null);
@ -181,23 +171,20 @@ const Conversations = ({ mobile }) => {
}
const [newChatModalVisible, setNewChatModalVisible] = useState(false);
const [newChatFormValues, setNewChatFormValues] = useState();
const [newItemLoading, setNewItemLoading] = useState(false);
const handleNewChat = async (values) => {
// console.log(values);
const hasNewCurrent = await getOrderConversationList(values.coli_sn, values.phone_number);
if (hasNewCurrent !== false) {
//
}
setNewChatModalVisible(false);
// const newItem = await postNewConversationItem({...values, opi_sn: userId });
const newChat = { phone_number: values.wa_id, remark_name: values.name };
setNewItemLoading(true);
const createdNew = await postNewConversationItem({...newChat, opi_sn: userId });
// if ( ! isEmpty(newItem)) {
// addToConversationList(newItem);
// setCurrentConversation(newItem);
addToConversationList([createdNew]);
setCurrentConversation(createdNew);
// }
// setNewChatFormValues(values);
setNewChatModalVisible(false);
setNewItemLoading(false);
};
const [activeList, setActiveList] = useState(true);
// const closedVisible = closedConversationsList.length > 0;
const toggleClosedConversationsList = () => {
const _active = activeList;
@ -235,7 +222,7 @@ const Conversations = ({ mobile }) => {
return (
<div className='flex flex-col h-inherit'>
<div className='flex gap-1'>
{['404', 383].includes(userId) && <Button onClick={() => setNewChatModalVisible(true)} icon={<PlusSquareOutlined />} type={'text'} className='text-primary' />}
<Button onClick={() => setNewChatModalVisible(true)} icon={<PlusOutlined />} type={'primary'} />
<Input.Search
className=''
ref={searchInputRef}
@ -288,7 +275,10 @@ const Conversations = ({ mobile }) => {
<Dropdown
key={item.sn}
menu={{
items: [{ label: '标记为未读', key: 'unread' }, { label: '关闭会话', key: 'close', danger: true }, ],
items: [
{ label: '标记为未读', key: 'unread' },
{ label: '关闭会话', key: 'close', danger: true },
],
onClick: ({ key, domEvent }) => {
domEvent.stopPropagation();
switch (key) {
@ -309,9 +299,7 @@ const Conversations = ({ mobile }) => {
String(item.sn) === String(currentConversation.sn) ? '__active text-primary bg-whatsapp-bg' : '',
String(item.sn) === String(tabSelectedConversation?.sn) ? ' bg-neutral-200' : '',
].join(' ')}>
<div className='pl-4 pt-1 text-xs text-right'>
{/* {filterTags.map((tag) => <Tag color={tag.color} key={tag.value}>{tag.label}</Tag>)} */}
</div>
<div className='pl-4 pt-1 text-xs text-right'>{/* {filterTags.map((tag) => <Tag color={tag.color} key={tag.value}>{tag.label}</Tag>)} */}</div>
<ChatItem
{...item}
key={item.sn}
@ -337,10 +325,11 @@ const Conversations = ({ mobile }) => {
{dataSource.length === 0 && <Empty description={'无数据'} />}
</div>
<ConversationsNewItem
initialValues={{ coli_id: currentConversation.coli_id, coli_sn: currentConversation.coli_sn }}
initialValues={{ is_current_order: false }}
open={newChatModalVisible}
onCreate={handleNewChat}
onCancel={() => setNewChatModalVisible(false)}
loading={newItemLoading}
/>
</div>
);

@ -58,14 +58,15 @@ export const ConversationItemForm = ({ initialValues, onFormInstanceReady }) =>
</>
)}
{!initialValues.is_current_order && (
<Form.Item name={'name'} label='联系人名称' rules={[{ required: true, message: '请输入联系人名称' }]}>
<Form.Item name={'name'} label='联系人名称' rules={[{ required: true, message: '请输入联系人名称' }]} className='mb-1'>
<Input placeholder='请输入联系人名称' />
</Form.Item>
)}
{/* <div className=' text-neutral-500 italic'>如果会话已存在, 将直接切换</div> */}
</Form>
);
};
export const ConversationItemFormModal = ({ open, onCreate, onCancel, initialValues }) => {
export const ConversationItemFormModal = ({ open, onCreate, onCancel, initialValues, loading }) => {
const [formInstance, setFormInstance] = useState();
return (
<Modal
@ -76,6 +77,7 @@ export const ConversationItemFormModal = ({ open, onCreate, onCancel, initialVal
okButtonProps={{
autoFocus: true,
}}
confirmLoading={loading}
onCancel={() => {
onCancel();
formInstance?.resetFields();

@ -46,6 +46,7 @@ const MessagesWrapper = ({ updateRead = true, forceGetMessages }) => {
if (updateRead === true && isVisible && currentConversation.opi_sn && currentConversation.whatsapp_phone_number && activeMessages.length > 0) {
fetchCleanUnreadMsgCount({ opisn: currentConversation.opi_sn, whatsappid: currentConversation.whatsapp_phone_number });
refreshTotalNotify();
updateCurrentConversation({ unread_msg_count: 0 });
}
return () => {};
}, [activeMessages.length, isVisible]);

@ -18,6 +18,7 @@ import dayjs from 'dayjs'
import { memo, useCallback, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { useShallow } from 'zustand/react/shallow'
import { UNREAD_MARK } from '@/actions/ConversationActions';
const { RangePicker } = DatePicker
@ -54,11 +55,11 @@ const AdvanceSearchForm = memo(function noName({ initialValues, onSubmit }) {
orderLabelOptions.unshift({ value: '', label: '全部' })
const orderStatusOptions = copy(OrderStatusDefaultOptions)
orderStatusOptions.unshift({ value: '', label: '全部' })
orderStatusOptions.unshift({ value: '', label: '全部' })
const remindStateOptions = copy(RemindStateDefaultOptions)
remindStateOptions.unshift({ value: '', label: '全部' })
remindStateOptions.unshift({ value: '', label: '全部' })
const [form] = Form.useForm()
function handleSubmit(values) {
@ -151,7 +152,7 @@ function OrderGroupTable({ formValues }) {
title: '订单号',
dataIndex: 'COLI_ID',
width: 222,
render: (text, record) => {
render: (text, record) => {
let tagIcon = ''
if (record.COLI_LineGrade === 240003) tagIcon = <Tag color='red'>重点</Tag>
@ -182,7 +183,7 @@ function OrderGroupTable({ formValues }) {
/>
{text + regularText}
<Badge
count={record.unread_msg}
count={record.unread_msg >= UNREAD_MARK ? ' ' : record.unread_msg}
style={{
backgroundColor: '#52c41a',
}}
@ -213,7 +214,7 @@ function OrderGroupTable({ formValues }) {
title: '报价 Title',
dataIndex: 'lettertitle',
ellipsis: true,
hidden: false,
hidden: false,
// render: (text, record) => {
// return (
// <Tooltip title={text}>{text}</Tooltip>
@ -373,16 +374,16 @@ function OrderGroupTable({ formValues }) {
pagination={newOrderList.length <= 10 ? false : paginationProps} />}
whenFalse={<Empty />}
/>
<Divider orientation='left'>新消息/老邮件</Divider>
<Conditional
condition={newMsgList.length > 0}
whenTrue={<Table key={'newMsgTable' + deptNo} loading={loading} dataSource={newMsgList}
columns={orderColumns}
columns={orderColumns}
pagination={newMsgList.length <= 10 ? false : paginationProps} />}
whenFalse={<Empty />}
/>
<Divider orientation='left'>催信</Divider>
<Conditional
condition={followUpList.length > 0}
@ -391,7 +392,7 @@ function OrderGroupTable({ formValues }) {
pagination={followUpList.length <= 10 ? false : paginationProps} />}
whenFalse={<Empty />}
/>
<Divider orientation='left'>余款收付</Divider>
<Conditional
condition={paymentList.length > 0}
@ -399,8 +400,8 @@ function OrderGroupTable({ formValues }) {
columns={orderColumns}
pagination={paymentList.length <= 10 ? false : paginationProps} />}
whenFalse={<Empty />}
/>
/>
<Divider orientation='left'>入境提醒</Divider>
<Conditional
condition={entryList.length > 0}
@ -409,7 +410,7 @@ function OrderGroupTable({ formValues }) {
pagination={entryList.length <= 10 ? false : paginationProps} /> }
whenFalse={<Empty />}
/>
</>
}
)

Loading…
Cancel
Save