feat(ckchat): 添加客服在线状态显示和选择功能
- 在KfUserListData接口中添加isOnline字段表示客服在线状态 - 在CkChatState中添加kfSelected字段存储当前选中的客服ID - 重构VerticalUserList组件,使用zustand管理选中状态 - 添加在线状态指示器样式,区分在线和离线状态 - 优化persistUtils工具,添加分片存储功能处理大数据
This commit is contained in:
@@ -5,33 +5,33 @@
|
||||
background-color: #2e2e2e;
|
||||
color: #fff;
|
||||
width: 60px;
|
||||
|
||||
|
||||
.userListHeader {
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #3a3a3a;
|
||||
|
||||
cursor: pointer;
|
||||
.allFriends {
|
||||
font-size: 12px;
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.userList {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 10px 0;
|
||||
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: #555;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.userItem {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -40,16 +40,16 @@
|
||||
padding: 10px 0;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
|
||||
&:hover {
|
||||
background-color: #3a3a3a;
|
||||
}
|
||||
|
||||
|
||||
&.active {
|
||||
background-color: #3a3a3a;
|
||||
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
@@ -60,15 +60,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.userAvatar {
|
||||
border: 2px solid transparent;
|
||||
|
||||
|
||||
.active & {
|
||||
border-color: #1890ff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.messageBadge {
|
||||
:global(.ant-badge-count) {
|
||||
background-color: #ff4d4f;
|
||||
@@ -81,7 +81,7 @@
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.onlineIndicator {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
@@ -89,7 +89,14 @@
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background-color: #52c41a;
|
||||
border: 1px solid #2e2e2e;
|
||||
|
||||
&.online {
|
||||
background-color: #52c41a; // 绿色表示在线
|
||||
}
|
||||
|
||||
&.offline {
|
||||
background-color: #8c8c8c; // 灰色表示离线
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
import React, { useState } from "react";
|
||||
import { Avatar, Badge, Tooltip } from "antd";
|
||||
import styles from "./VerticalUserList.module.scss";
|
||||
import { useCkChatStore } from "@/store/module/ckchat";
|
||||
interface VerticalUserListProps {
|
||||
activeKfUserId: number;
|
||||
onUserSelect: (userId: string) => void;
|
||||
}
|
||||
const VerticalUserList: React.FC<VerticalUserListProps> = ({
|
||||
activeKfUserId,
|
||||
onUserSelect,
|
||||
}) => {
|
||||
const [activeUserId, setActiveUserId] = useState<number>(activeKfUserId);
|
||||
import { useCkChatStore, asyncKfSelected } from "@/store/module/ckchat";
|
||||
|
||||
import { TeamOutlined } from "@ant-design/icons";
|
||||
const VerticalUserList: React.FC = () => {
|
||||
// 格式化消息数量显示
|
||||
const formatMessageCount = (count: number) => {
|
||||
if (count > 99) return "99+";
|
||||
@@ -19,21 +12,25 @@ const VerticalUserList: React.FC<VerticalUserListProps> = ({
|
||||
};
|
||||
|
||||
const handleUserSelect = (userId: number) => {
|
||||
setActiveUserId(userId);
|
||||
onUserSelect(userId.toString());
|
||||
asyncKfSelected(userId);
|
||||
};
|
||||
const kfUserList = useCkChatStore(state => state.kfUserList);
|
||||
const kfSelected = useCkChatStore(state => state.kfSelected);
|
||||
|
||||
return (
|
||||
<div className={styles.verticalUserList}>
|
||||
<div className={styles.userListHeader}>
|
||||
<div
|
||||
className={styles.userListHeader}
|
||||
onClick={() => handleUserSelect(0)}
|
||||
>
|
||||
<TeamOutlined style={{ fontSize: "26px" }} />
|
||||
<div className={styles.allFriends}>全部好友</div>
|
||||
</div>
|
||||
<div className={styles.userList}>
|
||||
{kfUserList.map(user => (
|
||||
<Tooltip key={user.id} title={user.name} placement="right">
|
||||
<div
|
||||
className={`${styles.userItem} ${activeUserId === user.id ? styles.active : ""}`}
|
||||
className={`${styles.userItem} ${kfSelected === user.id ? styles.active : ""}`}
|
||||
onClick={() => handleUserSelect(user.id)}
|
||||
>
|
||||
<Badge
|
||||
@@ -54,7 +51,9 @@ const VerticalUserList: React.FC<VerticalUserListProps> = ({
|
||||
{!user.avatar && user.name.charAt(0)}
|
||||
</Avatar>
|
||||
</Badge>
|
||||
{user.isOnline && <div className={styles.onlineIndicator} />}
|
||||
<div
|
||||
className={`${styles.onlineIndicator} ${user.isOnline ? styles.online : styles.offline}`}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
))}
|
||||
|
||||
@@ -23,6 +23,7 @@ export interface KfUserListData {
|
||||
wechatVersion: string;
|
||||
labels: string[];
|
||||
lastUpdateTime: string;
|
||||
isOnline?: boolean;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
@@ -71,6 +72,7 @@ export interface CkChatState {
|
||||
contractList: ContractData[];
|
||||
chatSessions: any[];
|
||||
kfUserList: KfUserListData[];
|
||||
kfSelected: number;
|
||||
newContractList: { groupName: string; contacts: any[] }[];
|
||||
getkfUserList: () => KfUserListData[];
|
||||
asyncKfUserList: (data: KfUserListData[]) => void;
|
||||
|
||||
Reference in New Issue
Block a user