优化会话置顶功能,更新状态切换逻辑并添加删除会话功能;新增样式以突出置顶会话,提升用户体验。
This commit is contained in:
@@ -18,6 +18,26 @@
|
|||||||
border-right: 3px solid #1890ff;
|
border-right: 3px solid #1890ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.pinned {
|
||||||
|
background-color: #fff7e6;
|
||||||
|
border-left: 3px solid #faad14;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "📌";
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messageName {
|
||||||
|
color: #d46b08;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,11 @@ import {
|
|||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
import { ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
|
import { ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
|
||||||
import { useWeChatStore } from "@/store/module/weChat/weChat";
|
import { useWeChatStore } from "@/store/module/weChat/weChat";
|
||||||
import { useCkChatStore } from "@/store/module/ckchat/ckchat";
|
import {
|
||||||
|
useCkChatStore,
|
||||||
|
toggleChatSessionPin,
|
||||||
|
deleteChatSession,
|
||||||
|
} from "@/store/module/ckchat/ckchat";
|
||||||
import { updateConfig } from "@/pages/pc/ckbox/api";
|
import { updateConfig } from "@/pages/pc/ckbox/api";
|
||||||
import styles from "./MessageList.module.scss";
|
import styles from "./MessageList.module.scss";
|
||||||
import { formatWechatTime } from "@/utils/common";
|
import { formatWechatTime } from "@/utils/common";
|
||||||
@@ -83,20 +87,20 @@ const MessageList: React.FC<MessageListProps> = () => {
|
|||||||
|
|
||||||
// 置顶/取消置顶
|
// 置顶/取消置顶
|
||||||
const handleTogglePin = (session: ContractData | weChatGroup) => {
|
const handleTogglePin = (session: ContractData | weChatGroup) => {
|
||||||
const isPinned = (session.config as any)?.top || true;
|
const currentPinned = (session.config as any)?.top || false;
|
||||||
|
const newPinned = !currentPinned; // 切换置顶状态
|
||||||
|
|
||||||
updateConfig({
|
updateConfig({
|
||||||
id: session.id,
|
id: session.id,
|
||||||
config: { top: isPinned, chat: true },
|
config: { top: newPinned, chat: true },
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
message.success(`${isPinned ? "取消置顶" : "置顶"}成功`);
|
// API调用成功,更新本地状态
|
||||||
//更新当前这个item的config的top值
|
toggleChatSessionPin(session.id!, newPinned);
|
||||||
//并把当前的Item移动到聊天列表的最上方
|
message.success(`${newPinned ? "置顶" : "取消置顶"}成功`);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
message.error(`${isPinned ? "取消置顶" : "置顶"}失败`);
|
message.error(`${newPinned ? "置顶" : "取消置顶"}失败`);
|
||||||
//更新当前这个item的config的top值
|
|
||||||
//先计算一下最后一个置顶的坐标,并把当前的Item移动到最后一个置顶的 Item下边
|
|
||||||
});
|
});
|
||||||
hideContextMenu();
|
hideContextMenu();
|
||||||
};
|
};
|
||||||
@@ -107,9 +111,18 @@ const MessageList: React.FC<MessageListProps> = () => {
|
|||||||
title: "确认删除",
|
title: "确认删除",
|
||||||
content: `确定要删除与 ${session.conRemark || session.nickname} 的会话吗?`,
|
content: `确定要删除与 ${session.conRemark || session.nickname} 的会话吗?`,
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
// TODO: 调用API删除会话
|
updateConfig({
|
||||||
console.log("删除会话", session);
|
id: session.id,
|
||||||
message.success("删除成功");
|
config: { chat: false },
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
message.success(`删除成功`);
|
||||||
|
//根据id删除会话里Item
|
||||||
|
deleteChatSession(session.id);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
message.error(`删除失败`);
|
||||||
|
});
|
||||||
hideContextMenu();
|
hideContextMenu();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -191,7 +204,7 @@ const MessageList: React.FC<MessageListProps> = () => {
|
|||||||
key={session.id}
|
key={session.id}
|
||||||
className={`${styles.messageItem} ${
|
className={`${styles.messageItem} ${
|
||||||
currentContract?.id === session.id ? styles.active : ""
|
currentContract?.id === session.id ? styles.active : ""
|
||||||
}`}
|
} ${(session.config as any)?.top ? styles.pinned : ""}`}
|
||||||
onClick={() => onContactClick(session)}
|
onClick={() => onContactClick(session)}
|
||||||
onContextMenu={e => handleContextMenu(e, session)}
|
onContextMenu={e => handleContextMenu(e, session)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -429,6 +429,88 @@ export const useCkChatStore = createPersistStore<CkChatState>(
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 切换会话置顶状态
|
||||||
|
toggleChatSessionPin: (sessionId: number, isPinned: boolean) => {
|
||||||
|
set(state => {
|
||||||
|
const updatedSessions = state.chatSessions.map(item => {
|
||||||
|
if (item.id === sessionId) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
config: {
|
||||||
|
...item.config,
|
||||||
|
top: isPinned,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 如果置顶,将会话移到顶部
|
||||||
|
if (isPinned) {
|
||||||
|
const sessionIndex = updatedSessions.findIndex(
|
||||||
|
item => item.id === sessionId,
|
||||||
|
);
|
||||||
|
if (sessionIndex !== -1) {
|
||||||
|
const session = updatedSessions[sessionIndex];
|
||||||
|
const otherSessions = updatedSessions.filter(
|
||||||
|
item => item.id !== sessionId,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
chatSessions: [session, ...otherSessions],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果取消置顶,重新排序(置顶>未读>名称>时间)
|
||||||
|
const sortedSessions = updatedSessions.sort((a, b) => {
|
||||||
|
// 获取置顶状态
|
||||||
|
const aTop = (a.config as any)?.top || false;
|
||||||
|
const bTop = (b.config as any)?.top || false;
|
||||||
|
|
||||||
|
// 首先按置顶状态排序(置顶的排在前面)
|
||||||
|
if (aTop !== bTop) {
|
||||||
|
return aTop ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果都是置顶或都不是置顶,则按未读消息数量降序排列
|
||||||
|
const aUnread = a.config?.unreadCount || 0;
|
||||||
|
const bUnread = b.config?.unreadCount || 0;
|
||||||
|
|
||||||
|
if (aUnread !== bUnread) {
|
||||||
|
return bUnread - aUnread;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果未读消息数量相同,则按显示名称排序
|
||||||
|
const getDisplayName = (session: any) => {
|
||||||
|
return session.conRemark || session.nickname || "";
|
||||||
|
};
|
||||||
|
const aName = getDisplayName(a).toLowerCase();
|
||||||
|
const bName = getDisplayName(b).toLowerCase();
|
||||||
|
|
||||||
|
if (aName !== bName) {
|
||||||
|
return aName.localeCompare(bName, "zh-CN");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果名称也相同,则按时间降序排列
|
||||||
|
if (!a.lastUpdateTime) return 1;
|
||||||
|
if (!b.lastUpdateTime) return -1;
|
||||||
|
|
||||||
|
const timeCompare =
|
||||||
|
new Date(b.lastUpdateTime).getTime() -
|
||||||
|
new Date(a.lastUpdateTime).getTime();
|
||||||
|
|
||||||
|
return timeCompare;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
chatSessions: sortedSessions,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
chatSessions: updatedSessions,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
// 设置用户信息
|
// 设置用户信息
|
||||||
setUserInfo: (userInfo: CkUserInfo) => {
|
setUserInfo: (userInfo: CkUserInfo) => {
|
||||||
set({ userInfo, isLoggedIn: true });
|
set({ userInfo, isLoggedIn: true });
|
||||||
@@ -561,3 +643,5 @@ export const updateIsLoadWeChat = (isLoadWeChat: boolean) =>
|
|||||||
useCkChatStore.getState().updateIsLoadWeChat(isLoadWeChat);
|
useCkChatStore.getState().updateIsLoadWeChat(isLoadWeChat);
|
||||||
export const getIsLoadWeChat = () =>
|
export const getIsLoadWeChat = () =>
|
||||||
useCkChatStore.getState().getIsLoadWeChat();
|
useCkChatStore.getState().getIsLoadWeChat();
|
||||||
|
export const toggleChatSessionPin = (sessionId: number, isPinned: boolean) =>
|
||||||
|
useCkChatStore.getState().toggleChatSessionPin(sessionId, isPinned);
|
||||||
|
|||||||
Reference in New Issue
Block a user