更新联系人分组逻辑:将分组类型从“group”更改为“chatroom”,并在联系人上下文菜单中添加移动分组的回调函数。调整相关组件以支持新的分组管理功能,确保在移动分组时使用正确的类型。

This commit is contained in:
乘风
2025-12-17 16:20:58 +08:00
parent bde1d36005
commit 65167be7f8
11 changed files with 316 additions and 203 deletions

View File

@@ -35,7 +35,7 @@ export function getGroupList() {
// 移动分组
interface MoveGroupData {
type: "friend" | "group";
type: "friend" | "chatroom";
groupId: number;
id: number;
}

View File

@@ -8,7 +8,6 @@ import { Menu, Modal, Input, Form, Select, message } from "antd";
import { EditOutlined, SwapOutlined } from "@ant-design/icons";
import { Contact } from "@/utils/db";
import { ContactGroup } from "@/store/module/weChat/contacts.data";
import { moveGroup } from "@/api/module/group";
import styles from "./index.module.scss";
/**
@@ -29,7 +28,9 @@ export interface ContactContextMenuProps {
/** 操作完成回调 */
onComplete?: () => void;
/** 修改备注回调 */
onUpdateRemark?: (contactId: number, remark: string) => Promise<void>;
onUpdateRemark?: (contact: Contact, remark: string) => Promise<void>;
/** 移动分组回调 */
onMoveGroup?: (contact: Contact, targetGroupId: number) => Promise<void>;
}
/**
@@ -52,6 +53,7 @@ export const ContactContextMenu: React.FC<ContactContextMenuProps> = ({
onClose,
onComplete,
onUpdateRemark,
onMoveGroup,
}) => {
const [remarkForm] = Form.useForm<{ remark: string }>();
const [moveForm] = Form.useForm<{ targetGroupId: number }>();
@@ -102,7 +104,7 @@ export const ContactContextMenu: React.FC<ContactContextMenuProps> = ({
setLoading(true);
if (onUpdateRemark) {
await onUpdateRemark(contact.id, values.remark);
await onUpdateRemark(contact, values.remark);
message.success("修改备注成功");
} else {
message.warning("修改备注功能未实现");
@@ -129,13 +131,12 @@ export const ContactContextMenu: React.FC<ContactContextMenuProps> = ({
const values = await moveForm.validateFields();
setLoading(true);
await moveGroup({
type: contact.type === "group" ? "group" : "friend",
groupId: values.targetGroupId,
id: contact.id,
});
if (onMoveGroup) {
await onMoveGroup(contact, values.targetGroupId);
message.success("移动分组成功");
} else {
message.warning("移动分组功能未实现");
}
setMoveModalVisible(false);
moveForm.resetFields();
onComplete?.();
@@ -172,9 +173,9 @@ export const ContactContextMenu: React.FC<ContactContextMenuProps> = ({
g => g.groupType === (contact.type === "group" ? 2 : 1),
);
if (!visible) return null;
return (
<>
{visible && (
<>
<div
className={styles.contextMenuOverlay}
@@ -192,6 +193,8 @@ export const ContactContextMenu: React.FC<ContactContextMenuProps> = ({
items={menuItems}
onClick={onClose}
/>
</>
)}
{/* 修改备注Modal */}
<Modal

View File

@@ -6,6 +6,7 @@
.virtualList {
width: 100%;
height: 100%;
overflow: inherit !important;
}
.groupHeader {
@@ -13,12 +14,7 @@
padding: 0;
box-sizing: border-box;
cursor: pointer;
transition: background-color 0.2s;
border-bottom: 1px solid #f0f0f0;
&:hover {
background-color: rgba(0, 0, 0, 0.02);
}
/* 样式由具体业务组件(如 WechatFriends/com.module.scss控制这里只负责布局和点击区域 */
}
.contactItem {
@@ -26,16 +22,7 @@
padding: 0;
box-sizing: border-box;
cursor: pointer;
transition: background-color 0.2s;
border-bottom: 1px solid #f0f0f0;
&:hover {
background-color: rgba(0, 0, 0, 0.02);
}
&.selected {
background-color: rgba(24, 144, 255, 0.1);
}
/* 避免样式穿透:不在这里设置边框/背景,全部交由内部渲染的联系人项样式控制 */
}
.empty {

View File

@@ -22,7 +22,7 @@ import styles from "./index.module.scss";
const GROUP_HEADER_HEIGHT = 40;
/**
* 联系人项高度(固定)
* 联系人项高度(固定),由设计统一控制,避免高度动态变化造成折叠/抖动
*/
const CONTACT_ITEM_HEIGHT = 60;
@@ -188,9 +188,8 @@ export const VirtualContactList: React.FC<VirtualContactListProps> = ({
} else if (item.type === "loadMore") {
return LOAD_MORE_ITEM_HEIGHT;
} else {
// 联系人项使用固定高度或缓存的高度
const cachedHeight = itemHeightsRef.current.get(index);
return cachedHeight || CONTACT_ITEM_HEIGHT;
// 联系人项使用固定高度,避免动态计算造成的样式折叠
return CONTACT_ITEM_HEIGHT;
}
},
[virtualItems],

View File

@@ -93,10 +93,9 @@ function jsonToQueryString(json) {
}
return params.toString();
}
//转移客户
//转移好友
export function WechatFriendAllot(params: {
wechatFriendId?: number;
wechatChatroomId?: number;
toAccountId: number;
notifyReceiver: boolean;
comment: string;
@@ -107,6 +106,19 @@ export function WechatFriendAllot(params: {
"PUT",
);
}
//转移群
export function WechatChatroomAllot(params: {
wechatChatroomId?: number;
toAccountId: number;
notifyReceiver: boolean;
comment: string;
}) {
return request2(
"/api/wechatChatroom/allot?" + jsonToQueryString(params),
undefined,
"PUT",
);
}
//获取可转移客服列表
export function getTransferableAgentList() {

View File

@@ -5,6 +5,7 @@ import {
getTransferableAgentList,
WechatFriendAllot,
WechatFriendRebackAllot,
WechatChatroomAllot,
} from "@/pages/pc/ckbox/weChat/api";
import { dataProcessing } from "@/api/ai";
import { useCurrentContact } from "@/store/module/weChat/weChat";
@@ -75,10 +76,14 @@ const ToContract: React.FC<ToContractProps> = ({
try {
setLoading(true);
// 调用转接接口
// 调用转接接口:区分好友 / 群聊
if (currentContact) {
if ("chatroomId" in currentContact && currentContact.chatroomId) {
await WechatFriendAllot({
const isGroup =
"chatroomId" in currentContact && !!currentContact.chatroomId;
if (isGroup) {
// 群聊转移:使用 WechatChatroomAllot
await WechatChatroomAllot({
wechatChatroomId: currentContact.id,
toAccountId: selectedTarget as number,
notifyReceiver: true,
@@ -91,6 +96,7 @@ const ToContract: React.FC<ToContractProps> = ({
wechatAccountId: currentContact.wechatAccountId,
});
} else {
// 好友转移:使用 WechatFriendAllot
await WechatFriendAllot({
wechatFriendId: currentContact.id,
toAccountId: selectedTarget as number,

View File

@@ -28,7 +28,7 @@ export function deleteGroup(id) {
//移动分组
interface MoveGroupParams {
type: "friend" | "group";
type: "friend" | "chatroom";
groupId: number;
id: number;
}

View File

@@ -74,7 +74,8 @@
.list {
flex: 1;
overflow-y: auto;
// 避免嵌套滚动条,由外层容器控制滚动
overflow-y: visible;
:global(.ant-list-item) {
padding: 10px 15px;

View File

@@ -1,5 +1,14 @@
import React, { useState, useCallback, useEffect, useRef } from "react";
import { List, Avatar, Skeleton, Modal, Form, Input, message } from "antd";
import {
List,
Avatar,
Skeleton,
Modal,
Form,
Input,
Select,
message,
} from "antd";
import dayjs from "dayjs";
import styles from "./com.module.scss";
import { Contact, ChatSession } from "@/utils/db";
@@ -107,13 +116,16 @@ const ContactListSimple: React.FC<WechatFriendsProps> = ({
groupName: string;
groupMemo: string;
sort: number;
groupType: 1 | 2;
}>();
const [addGroupVisible, setAddGroupVisible] = useState(false);
const [editGroupVisible, setEditGroupVisible] = useState(false);
const [deleteGroupVisible, setDeleteGroupVisible] = useState(false);
const [groupModalLoading, setGroupModalLoading] = useState(false);
const [editingGroup, setEditingGroup] = useState<ContactGroup | undefined>();
const [currentGroupTypeForAdd, setCurrentGroupTypeForAdd] = useState<1 | 2>(1);
const [currentGroupTypeForAdd, setCurrentGroupTypeForAdd] = useState<1 | 2>(
1,
);
// 生成分组Key的函数
const getGroupKey = useCallback(
@@ -162,28 +174,35 @@ const ContactListSimple: React.FC<WechatFriendsProps> = ({
);
// 打开新增分组弹窗
const handleOpenAddGroupModal = useCallback((groupType: 1 | 2) => {
setCurrentGroupTypeForAdd(groupType);
groupForm.resetFields();
groupForm.setFieldsValue({
groupName: "",
groupMemo: "",
sort: 0,
});
setAddGroupVisible(true);
}, [groupForm]);
const handleOpenAddGroupModal = useCallback(
(groupType: 1 | 2) => {
setCurrentGroupTypeForAdd(groupType);
groupForm.resetFields();
groupForm.setFieldsValue({
groupName: "",
groupMemo: "",
sort: 0,
groupType: groupType || 1, // 默认使用右键菜单传过来的类型如果没有则默认为1好友分组
});
setAddGroupVisible(true);
},
[groupForm],
);
// 打开编辑分组弹窗
const handleOpenEditGroupModal = useCallback((group: ContactGroup) => {
setEditingGroup(group);
groupForm.resetFields();
groupForm.setFieldsValue({
groupName: group.groupName,
groupMemo: group.groupMemo || "",
sort: group.sort || 0,
});
setEditGroupVisible(true);
}, [groupForm]);
const handleOpenEditGroupModal = useCallback(
(group: ContactGroup) => {
setEditingGroup(group);
groupForm.resetFields();
groupForm.setFieldsValue({
groupName: group.groupName,
groupMemo: group.groupMemo || "",
sort: group.sort || 0,
});
setEditGroupVisible(true);
},
[groupForm],
);
// 打开删除分组确认弹窗
const handleOpenDeleteGroupModal = useCallback((group: ContactGroup) => {
@@ -200,7 +219,7 @@ const ContactListSimple: React.FC<WechatFriendsProps> = ({
await useContactStoreNew.getState().addGroup({
groupName: values.groupName,
groupMemo: values.groupMemo || "",
groupType: currentGroupTypeForAdd,
groupType: values.groupType || 1, // 必填默认1好友分组
sort: values.sort || 0,
});
@@ -254,10 +273,9 @@ const ContactListSimple: React.FC<WechatFriendsProps> = ({
try {
setGroupModalLoading(true);
await useContactStoreNew.getState().deleteGroup(
editingGroup.id,
editingGroup.groupType,
);
await useContactStoreNew
.getState()
.deleteGroup(editingGroup.id, editingGroup.groupType);
message.success("删除分组成功");
setDeleteGroupVisible(false);
@@ -291,40 +309,21 @@ const ContactListSimple: React.FC<WechatFriendsProps> = ({
// 这里可以根据需要实现
}, []);
// 处理修改备注
// 处理修改备注:直接使用联系人自身的分组信息,不再遍历分组数据
const handleUpdateRemark = useCallback(
async (contactId: number, remark: string) => {
// 找到联系人所在的分组
let foundGroup: ContactGroup | undefined;
let foundGroupKey: string | undefined;
async (contact: Contact, remark: string) => {
// 联系人上已经带有 groupId 与 type 信息
const groupId = contact.groupId ?? 0;
const groupType: 1 | 2 = contact.type === "group" ? 2 : 1;
for (const [groupKey, groupDataItem] of newGroupData.entries()) {
const contact = groupDataItem.contacts.find(c => c.id === contactId);
if (contact) {
foundGroupKey = groupKey;
// 从groupKey解析groupId和groupType
const [groupId, groupType] = groupKey.split("_");
// 使用newGroups查找分组优先使用新架构的数据
foundGroup = newGroups.find(
g => g.id === Number(groupId) && g.groupType === Number(groupType),
);
break;
}
}
if (foundGroup && foundGroupKey) {
const [groupId, groupType] = foundGroupKey.split("_");
await updateContactRemark(
contactId,
Number(groupId),
Number(groupType) as 1 | 2,
remark,
);
} else {
message.error("未找到联系人所在的分组");
try {
await updateContactRemark(contact.id, groupId, groupType, remark);
} catch (error) {
console.error("更新联系人备注失败:", error);
message.error("更新备注失败,请稍后重试");
}
},
[updateContactRemark, newGroupData, newGroups],
[updateContactRemark],
);
// 从服务器同步数据(静默同步,不显示提示)
@@ -551,10 +550,12 @@ const ContactListSimple: React.FC<WechatFriendsProps> = ({
// 渲染分组头部(用于虚拟滚动)
const renderGroupHeader = useCallback(
(group: ContactGroup, isExpanded: boolean) => {
const displayCount =
typeof group.count === "number" && group.count >= 0 ? group.count : "-";
return (
<div className={styles.groupHeader}>
<span>{group.groupName}</span>
<span className={styles.contactCount}>{group.count || 0}</span>
<span className={styles.contactCount}>{displayCount}</span>
</div>
);
},
@@ -577,19 +578,6 @@ const ContactListSimple: React.FC<WechatFriendsProps> = ({
</div>
);
// 不限制容器高度,让列表根据内容自动扩展
// const [containerHeight, setContainerHeight] = useState(600);
// useEffect(() => {
// const updateHeight = () => {
// if (virtualListRef.current) {
// const rect = virtualListRef.current.getBoundingClientRect();
// setContainerHeight(rect.height || 600);
// }
// };
// updateHeight();
// window.addEventListener("resize", updateHeight);
// return () => window.removeEventListener("resize", updateHeight);
// }, []);
const containerHeight = undefined; // 不限制高度,使用内容总高度
// 处理分组展开/折叠(使用新架构的方法)
@@ -688,9 +676,31 @@ const ContactListSimple: React.FC<WechatFriendsProps> = ({
x={contactContextMenu.x}
y={contactContextMenu.y}
visible={contactContextMenu.visible}
onClose={() => setContactContextMenu({ visible: false, x: 0, y: 0 })}
onClose={() =>
setContactContextMenu(prev => ({
...prev,
visible: false,
}))
}
onComplete={handleContactOperationComplete}
onUpdateRemark={handleUpdateRemark}
onMoveGroup={async (contact, targetGroupId) => {
const fromGroupId = contact.groupId ?? 0;
const groupType: 1 | 2 = contact.type === "group" ? 2 : 1;
try {
await useContactStoreNew
.getState()
.moveContactToGroup(
contact.id,
fromGroupId,
targetGroupId,
groupType,
);
} catch (error) {
console.error("移动分组失败:", error);
message.error("移动分组失败,请稍后重试");
}
}}
/>
)}
@@ -708,6 +718,17 @@ const ContactListSimple: React.FC<WechatFriendsProps> = ({
cancelText="取消"
>
<Form form={groupForm} layout="vertical">
<Form.Item
name="groupType"
label="分组类型"
rules={[{ required: true, message: "请选择分组类型" }]}
initialValue={currentGroupTypeForAdd || 1}
>
<Select placeholder="请选择分组类型">
<Select.Option value={1}></Select.Option>
<Select.Option value={2}></Select.Option>
</Select>
</Form.Item>
<Form.Item
name="groupName"
label="分组名称"

View File

@@ -31,11 +31,8 @@ const SidebarMenu: React.FC<SidebarMenuProps> = ({ loading = false }) => {
} = useContactStore();
// 使用新架构的ContactStore进行搜索
const {
searchKeyword,
searchContacts,
clearSearch,
} = useContactStoreNew();
const contactStoreNew = useContactStoreNew();
const { searchKeyword, searchContacts, clearSearch } = contactStoreNew;
const currentCustomer = useCustomerStore(state => state.currentCustomer);
const { setCurrentContact } = useWeChatStore();
@@ -222,7 +219,18 @@ const SidebarMenu: React.FC<SidebarMenuProps> = ({ loading = false }) => {
</div>
<div
className={`${styles.tabItem} ${activeTab === "contracts" ? styles.active : ""}`}
onClick={() => setActiveTab("contracts")}
onClick={async () => {
setActiveTab("contracts");
try {
const accountId = currentCustomer?.id || 0;
// 每次切到联系人标签时,强制从接口刷新一次分组列表(通过全局 store 调用,避免 hook 实例问题)
await useContactStoreNew
.getState()
.loadGroupsFromAPI(accountId);
} catch (error) {
console.error("刷新联系人分组失败:", error);
}
}}
>
<span></span>
</div>

View File

@@ -20,7 +20,12 @@ import {
getGroupList,
getLabelsListByGroup,
} from "@/pages/pc/ckbox/weChat/api";
import { addGroup, updateGroup, deleteGroup, moveGroup } from "@/api/module/group";
import {
addGroup,
updateGroup,
deleteGroup,
moveGroup,
} from "@/api/module/group";
import { updateFriendInfo } from "@/pages/pc/ckbox/weChat/components/ChatWindow/components/ProfileCard/components/ProfileModules/api";
import {
convertFriendsToContacts,
@@ -32,6 +37,7 @@ import {
groupStatsCache,
} from "@/utils/cache";
import { ContactManager } from "@/utils/dbAction/contact";
import { useMessageStore } from "./message";
import { performanceMonitor } from "@/utils/performance";
/**
@@ -81,15 +87,21 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
* 设置分组列表
*/
setGroups: async (groups: ContactGroup[]) => {
// 先重置人数为占位值 -1等真正展开分组、拿到 total 后再更新
const groupsWithPlaceholder = groups.map(g => ({
...g,
count: -1,
}));
// 按自定义规则排序:
// 1. 默认群分组groupType=2 且 id=0始终在最前
// 2. 未分组groupType=1 且 id=99999999)始终在最后
// 2. 未分组groupType=1 且 id=0)始终在最后
// 3. 其他分组按 sort 升序
const sortedGroups = [...groups].sort((a, b) => {
const sortedGroups = [...groupsWithPlaceholder].sort((a, b) => {
const isDefaultGroupA = a.groupType === 2 && a.id === 0;
const isDefaultGroupB = b.groupType === 2 && b.id === 0;
const isUngroupedA = a.groupType === 1 && a.id === 99999999;
const isUngroupedB = b.groupType === 1 && b.id === 99999999;
const isUngroupedA = a.groupType === 1 && a.id === 0;
const isUngroupedB = b.groupType === 1 && b.id === 0;
// 默认群分组始终最前
if (isDefaultGroupA && !isDefaultGroupB) return -1;
@@ -144,39 +156,68 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
const params: any = {
page: 1,
limit: 1000, // 分组列表通常不会太多
// 即便为 0 也要把 wechatAccountId 传给接口,由后端决定含义
wechatAccountId: accountId,
};
if (accountId !== 0) {
params.wechatAccountId = accountId;
}
// 单次请求分组列表,按 groupType 区分好友/群分组
const result = await getLabelsListByGroup(params);
const list = result?.list || [];
// 并行请求好友分组和群分组
const [friendsResult, groupsResult] = await Promise.all([
getLabelsListByGroup(1, params, { debounceGap: 0 }),
getLabelsListByGroup(2, params, { debounceGap: 0 }),
]);
const friendGroups: ContactGroup[] =
friendsResult?.list?.map((item: any) => ({
const friendGroups: ContactGroup[] = list
.filter((item: any) => Number(item.groupType) === 1)
.map((item: any) => ({
id: item.id,
groupName: item.groupName,
groupType: 1,
count: item.count || 0,
sort: item.sort || 0,
groupMemo: item.groupMemo || "",
})) || [];
}));
const groupGroups: ContactGroup[] =
groupsResult?.list?.map((item: any) => ({
const groupGroups: ContactGroup[] = list
.filter((item: any) => Number(item.groupType) === 2)
.map((item: any) => ({
id: item.id,
groupName: item.groupName,
groupType: 2,
count: item.count || 0,
sort: item.sort || 0,
groupMemo: item.groupMemo || "",
})) || [];
}));
const allGroups = [...friendGroups, ...groupGroups];
// 额外补充:默认群分组 & 未分组(接口不返回,由前端约定)
const extraGroups: ContactGroup[] = [];
const hasDefaultGroup = groupGroups.some(
g => g.id === 0 && g.groupType === 2,
);
if (!hasDefaultGroup) {
extraGroups.push({
id: 0,
groupName: "默认群分组",
groupType: 2,
count: 0,
sort: -9999,
groupMemo: "",
});
}
const hasUngrouped = friendGroups.some(
g => g.id === 0 && g.groupType === 1,
);
if (!hasUngrouped) {
extraGroups.push({
id: 0,
groupName: "未分组",
groupType: 1,
count: 0,
sort: 999999,
groupMemo: "",
});
}
const allGroups = [...extraGroups, ...friendGroups, ...groupGroups];
await get().setGroups(allGroups);
return allGroups;
@@ -244,7 +285,8 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
// 第一页时,先尝试从缓存读取
if (page === 1) {
const cacheKey = `groupContacts_${groupKey}`;
const cached = await groupContactsCache.get<GroupContactData>(cacheKey);
const cached =
await groupContactsCache.get<GroupContactData>(cacheKey);
if (cached && cached.contacts && cached.contacts.length > 0) {
// 立即显示缓存数据
const groupData = new Map(state.groupData);
@@ -341,29 +383,33 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
};
// 根据groupType调用不同的API
let total = 0;
if (groupType === 1) {
// 好友列表API
if (groupId !== 0) {
params.groupId = groupId; // 分组ID
}
if (accountId !== 0) {
params.wechatAccountId = accountId;
}
// 分组ID即便为 0未分组也要传给接口由后端决定语义
params.groupId = groupId;
// 账号ID即便为 0 也要传
params.wechatAccountId = accountId;
const result = await getContactList(params, { debounceGap: 0 });
const friendList = result?.list || [];
total =
typeof result?.total === "number"
? result.total
: friendList.length;
contacts = convertFriendsToContacts(friendList, userId);
} else if (groupType === 2) {
// 群列表API
if (groupId !== 0) {
params.groupId = groupId; // 分组ID
}
if (accountId !== 0) {
params.wechatAccountId = accountId;
}
// 分组ID即便为 0默认群分组也要传给接口
params.groupId = groupId;
// 账号ID即便为 0 也要传
params.wechatAccountId = accountId;
const result = await getGroupList(params, { debounceGap: 0 });
const groupList = result?.list || [];
total =
typeof result?.total === "number" ? result.total : groupList.length;
contacts = convertGroupsToContacts(groupList, userId);
}
@@ -373,10 +419,7 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
const existingContacts = latestGroupData?.contacts || [];
const updatedData: GroupContactData = {
contacts:
page === 1
? contacts
: [...existingContacts, ...contacts], // 使用最新的 contacts而不是 currentData
contacts: page === 1 ? contacts : [...existingContacts, ...contacts], // 使用最新的 contacts而不是 currentData
page,
pageSize: limit,
hasMore: contacts.length === limit,
@@ -387,7 +430,15 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
const updatedGroupData = new Map(latestState.groupData);
updatedGroupData.set(groupKey, updatedData);
set({ groupData: updatedGroupData });
// 同步更新分组人数:使用接口返回的 total
const updatedGroups = latestState.groups.map(g =>
g.id === groupId && g.groupType === groupType
? { ...g, count: total }
: g,
);
set({ groupData: updatedGroupData, groups: updatedGroups });
// 缓存第一页数据
if (page === 1) {
@@ -523,48 +574,48 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
const state = get();
set({ selectedAccountId: accountId });
// 重新加载展开的分组
const expandedGroups = Array.from(state.expandedGroups);
const groupData = new Map<string, GroupContactData>();
// 重新加载展开的分组
const expandedGroups = Array.from(state.expandedGroups);
const groupData = new Map<string, GroupContactData>();
// 清理旧账号的数据
for (const groupKey of expandedGroups) {
// 检查是否是当前账号的分组
const parts = groupKey.split("_");
if (parts.length === 3) {
const oldAccountId = parseInt(parts[2], 10);
if (oldAccountId === accountId) {
// 保留当前账号的数据
const oldData = state.groupData.get(groupKey);
if (oldData) {
groupData.set(groupKey, oldData);
// 清理旧账号的数据
for (const groupKey of expandedGroups) {
// 检查是否是当前账号的分组
const parts = groupKey.split("_");
if (parts.length === 3) {
const oldAccountId = parseInt(parts[2], 10);
if (oldAccountId === accountId) {
// 保留当前账号的数据
const oldData = state.groupData.get(groupKey);
if (oldData) {
groupData.set(groupKey, oldData);
}
}
}
}
}
}
set({ groupData });
set({ groupData });
// 重新加载展开的分组
for (const groupKey of expandedGroups) {
const parts = groupKey.split("_");
if (parts.length === 3) {
const groupId = parseInt(parts[0], 10);
const groupType = parseInt(parts[1], 10) as 1 | 2;
const oldAccountId = parseInt(parts[2], 10);
// 重新加载展开的分组
for (const groupKey of expandedGroups) {
const parts = groupKey.split("_");
if (parts.length === 3) {
const groupId = parseInt(parts[0], 10);
const groupType = parseInt(parts[1], 10) as 1 | 2;
const oldAccountId = parseInt(parts[2], 10);
if (oldAccountId !== accountId) {
// 不同账号,需要重新加载
const newGroupKey = getGroupKey(groupId, groupType, accountId);
const expandedGroupsNew = new Set(state.expandedGroups);
expandedGroupsNew.delete(groupKey);
expandedGroupsNew.add(newGroupKey);
set({ expandedGroups: expandedGroupsNew });
if (oldAccountId !== accountId) {
// 不同账号,需要重新加载
const newGroupKey = getGroupKey(groupId, groupType, accountId);
const expandedGroupsNew = new Set(state.expandedGroups);
expandedGroupsNew.delete(groupKey);
expandedGroupsNew.add(newGroupKey);
set({ expandedGroups: expandedGroupsNew });
await get().loadGroupContacts(groupId, groupType, 1, 50);
await get().loadGroupContacts(groupId, groupType, 1, 50);
}
}
}
}
}
},
{ accountId, expandedGroupsCount: state.expandedGroups.size },
);
@@ -585,11 +636,15 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
const newGroup: ContactGroup = {
id: result?.id || result?.data?.id || 0,
groupName: result?.groupName || result?.data?.groupName || group.groupName,
groupType: (result?.groupType || result?.data?.groupType || group.groupType) as 1 | 2,
groupName:
result?.groupName || result?.data?.groupName || group.groupName,
groupType: (result?.groupType ||
result?.data?.groupType ||
group.groupType) as 1 | 2,
count: 0, // 新分组初始数量为0
sort: result?.sort || result?.data?.sort || group.sort || 0,
groupMemo: result?.groupMemo || result?.data?.groupMemo || group.groupMemo,
groupMemo:
result?.groupMemo || result?.data?.groupMemo || group.groupMemo,
};
const groups = [...get().groups, newGroup];
@@ -613,9 +668,7 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
sort: group.sort || 0,
});
const groups = get().groups.map(g =>
g.id === group.id ? group : g,
);
const groups = get().groups.map(g => (g.id === group.id ? group : g));
get().setGroups(groups);
} catch (error) {
console.error("更新分组失败:", error);
@@ -766,9 +819,8 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
// 更新缓存
const cacheKey = `groupContacts_${groupKey}`;
const cachedData = await groupContactsCache.get<GroupContactData>(
cacheKey,
);
const cachedData =
await groupContactsCache.get<GroupContactData>(cacheKey);
if (cachedData && cachedData.contacts) {
const updatedContacts = cachedData.contacts.map(c =>
c.id === contactId ? { ...c, conRemark: remark } : c,
@@ -803,6 +855,30 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
});
}
}
// 同步更新会话列表中的备注名称
try {
const messageState = useMessageStore.getState();
const existingSessions = messageState.allSessions;
if (existingSessions && existingSessions.length > 0) {
existingSessions
.filter(
s =>
s.id === contactId &&
(groupType === 1
? s.type === "friend"
: s.type === "group"),
)
.forEach(s => {
messageState.addSession({
...s,
conRemark: remark,
});
});
}
} catch (err) {
console.error("同步会话列表备注失败:", err);
}
} catch (error) {
console.error("更新联系人备注失败:", error);
throw error;
@@ -850,7 +926,8 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
try {
// 调用API移动分组
await moveGroup({
type: groupType === 1 ? "friend" : "group",
// 好友用 friend群聊用 chatroom
type: groupType === 1 ? "friend" : "chatroom",
groupId: toGroupId,
id: contactId,
});
@@ -895,9 +972,8 @@ export const useContactStoreNew = createPersistStore<ContactStoreState>(
// 更新缓存
const cacheKey = `groupContacts_${toGroupKey}`;
const cachedData = await groupContactsCache.get<GroupContactData>(
cacheKey,
);
const cachedData =
await groupContactsCache.get<GroupContactData>(cacheKey);
if (cachedData) {
await groupContactsCache.set(cacheKey, {
...cachedData,