diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/PopChatRoom/index.module.scss b/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/PopChatRoom/index.module.scss index 20d9a3d3..0c34dac0 100644 --- a/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/PopChatRoom/index.module.scss +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/PopChatRoom/index.module.scss @@ -48,6 +48,43 @@ font-weight: 500; font-size: 14px; color: #262626; + display: flex; + justify-content: space-between; + align-items: center; + gap: 12px; +} + +.headerActions { + display: flex; + gap: 8px; + + :global(.ant-btn-sm) { + padding: 0 8px; + } +} + +.actionButton { + color: #fff !important; + border: none !important; + transition: background-color 0.2s ease; + + &:hover, + &:focus { + color: #fff; + opacity: 0.9; + } +} + +.currentPageButton { + background-color: #1677ff !important; +} + +.allSelectButton { + background-color: #13c2c2 !important; +} + +.deselectState { + background-color: #ff7875 !important; } .listContent { @@ -57,6 +94,14 @@ min-height: 0; } +.selectedList { + .listContent { + flex: unset; + height: 600px; + overflow-y: auto; + } +} + .contactItem, .selectedItem { display: flex; diff --git a/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/PopChatRoom/index.tsx b/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/PopChatRoom/index.tsx index 68a99575..7505b815 100644 --- a/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/PopChatRoom/index.tsx +++ b/Touchkebao/src/pages/pc/ckbox/weChat/components/SidebarMenu/PopChatRoom/index.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useMemo } from "react"; +import React, { useState, useEffect, useMemo, useCallback } from "react"; import { Modal, Input, @@ -32,6 +32,7 @@ const PopChatRoom: React.FC = ({ visible, onCancel }) => { const [showNameModal, setShowNameModal] = useState(false); const [chatroomName, setChatroomName] = useState(""); const pageSize = 10; + const MAX_SELECT_COUNT = 50; // 最多选择联系人数量 const { sendCommand } = useWebSocketStore(); const currentUserId = useUserStore(state => state.user?.id) || 0; const currentCustomer = useCustomerStore(state => state.currentCustomer); @@ -91,12 +92,115 @@ const PopChatRoom: React.FC = ({ visible, onCancel }) => { return filteredContacts.slice(start, end); }, [filteredContacts, page]); + const isContactSelected = useCallback( + (contactId: number) => { + return selectedContacts.some(contact => contact.id === contactId); + }, + [selectedContacts], + ); + + const addContactsToSelection = (contacts: Contact[]) => { + setSelectedContacts(prev => { + const existingIds = new Set(prev.map(contact => contact.id)); + const additions = contacts.filter( + contact => !existingIds.has(contact.id), + ); + if (additions.length === 0) return prev; + return [...prev, ...additions]; + }); + }; + + const removeContactsFromSelection = (contacts: Contact[]) => { + if (contacts.length === 0) return; + const removalIds = new Set(contacts.map(contact => contact.id)); + setSelectedContacts(prev => + prev.filter(contact => !removalIds.has(contact.id)), + ); + }; + + const isCurrentPageFullySelected = useMemo(() => { + return ( + paginatedContacts.length > 0 && + paginatedContacts.every(contact => isContactSelected(contact.id)) + ); + }, [isContactSelected, paginatedContacts]); + + const isAllContactsFullySelected = useMemo(() => { + return ( + filteredContacts.length > 0 && + filteredContacts.every(contact => isContactSelected(contact.id)) + ); + }, [filteredContacts, isContactSelected]); + + const handleToggleCurrentPageSelection = () => { + if (isCurrentPageFullySelected) { + removeContactsFromSelection(paginatedContacts); + } else { + const currentSelectedCount = selectedContacts.length; + const remainingSlots = MAX_SELECT_COUNT - currentSelectedCount; + + if (remainingSlots <= 0) { + message.warning(`最多只能选择${MAX_SELECT_COUNT}个联系人`); + return; + } + + // 获取当前页未选中的联系人 + const unselectedContacts = paginatedContacts.filter( + contact => !isContactSelected(contact.id), + ); + + if (unselectedContacts.length > remainingSlots) { + // 只选择前 remainingSlots 个未选中的联系人 + const contactsToAdd = unselectedContacts.slice(0, remainingSlots); + addContactsToSelection(contactsToAdd); + message.warning( + `最多只能选择${MAX_SELECT_COUNT}个联系人,已选择前${remainingSlots}个`, + ); + } else { + addContactsToSelection(unselectedContacts); + } + } + }; + + const handleToggleAllContactsSelection = () => { + if (isAllContactsFullySelected) { + removeContactsFromSelection(filteredContacts); + } else { + const currentSelectedCount = selectedContacts.length; + const remainingSlots = MAX_SELECT_COUNT - currentSelectedCount; + + if (remainingSlots <= 0) { + message.warning(`最多只能选择${MAX_SELECT_COUNT}个联系人`); + return; + } + + if (filteredContacts.length > remainingSlots) { + // 只选择前 remainingSlots 个未选中的联系人 + const unselectedContacts = filteredContacts.filter( + contact => !isContactSelected(contact.id), + ); + const contactsToAdd = unselectedContacts.slice(0, remainingSlots); + addContactsToSelection(contactsToAdd); + message.warning( + `最多只能选择${MAX_SELECT_COUNT}个联系人,已选择前${remainingSlots}个`, + ); + } else { + addContactsToSelection(filteredContacts); + } + } + }; + // 处理联系人选择 const handleContactSelect = (contact: Contact) => { setSelectedContacts(prev => { if (isContactSelected(contact.id)) { return prev.filter(item => item.id !== contact.id); } + // 检查是否超过50个限制 + if (prev.length >= MAX_SELECT_COUNT) { + message.warning(`最多只能选择${MAX_SELECT_COUNT}个联系人`); + return prev; + } return [...prev, contact]; }); }; @@ -108,11 +212,6 @@ const PopChatRoom: React.FC = ({ visible, onCancel }) => { ); }; - // 检查联系人是否已选择 - const isContactSelected = (contactId: number) => { - return selectedContacts.some(contact => contact.id === contactId); - }; - // 处理取消 const handleCancel = () => { setSearchValue(""); @@ -219,6 +318,31 @@ const PopChatRoom: React.FC = ({ visible, onCancel }) => {
联系人 ({filteredContacts.length}) +
+ + + (全选最多50个) +
{loading ? (