增强CustomerList组件:添加客户信息提示功能,优化样式以改善用户体验。更新样式文件以支持新的tooltip样式和加载指示器。

This commit is contained in:
乘风
2026-01-16 15:13:43 +08:00
parent d144bfb849
commit 29df2a3d8e
2 changed files with 128 additions and 39 deletions

View File

@@ -105,45 +105,98 @@
flex-direction: column;
align-items: center;
padding: 10px 0;
}
.skeletonItem {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10px 0;
position: relative;
margin-bottom: 10px;
}
.skeletonAvatar {
width: 50px;
height: 50px;
border-radius: 50%;
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: skeleton-loading 1.5s infinite;
}
.skeletonIndicator {
position: absolute;
bottom: 10px;
right: 10px;
width: 8px;
height: 8px;
border-radius: 50%;
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: skeleton-loading 1.5s infinite;
}
@keyframes skeleton-loading {
0% {
background-position: 200% 0;
.skeletonItem {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10px 0;
position: relative;
margin-bottom: 10px;
}
100% {
background-position: -200% 0;
.skeletonAvatar {
width: 50px;
height: 50px;
border-radius: 50%;
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: skeleton-loading 1.5s infinite;
}
.skeletonIndicator {
position: absolute;
bottom: 10px;
right: 10px;
width: 8px;
height: 8px;
border-radius: 50%;
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: skeleton-loading 1.5s infinite;
}
@keyframes skeleton-loading {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
}
}
// Tooltip 样式
:global {
.customerTooltip {
.ant-tooltip-inner {
background-color: rgba(0, 0, 0, 0.85);
padding: 12px 16px;
border-radius: 6px;
box-shadow:
0 3px 6px -4px rgba(0, 0, 0, 0.12),
0 6px 16px 0 rgba(0, 0, 0, 0.08),
0 9px 28px 8px rgba(0, 0, 0, 0.05);
}
.ant-tooltip-arrow {
&::before {
background-color: rgba(0, 0, 0, 0.85);
}
}
}
}
.tooltipContent {
min-width: 200px;
.tooltipItem {
display: flex;
align-items: center;
line-height: 1.4;
margin-bottom: 6px;
&:last-child {
margin-bottom: 0;
}
.tooltipLabel {
color: rgba(255, 255, 255, 0.65);
font-size: 12px;
min-width: 70px;
flex-shrink: 0;
line-height: 1.4;
}
.tooltipValue {
color: #ffffff;
font-size: 13px;
font-weight: 500;
word-break: break-all;
flex: 1;
line-height: 1.4;
}
}
}

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useState } from "react";
import { Avatar, Badge } from "antd";
import { Avatar, Badge, Tooltip } from "antd";
import styles from "./com.module.scss";
import {
useCustomerStore,
@@ -74,6 +74,35 @@ const CustomerList: React.FC = () => {
</div>
);
// 渲染客服信息提示内容
const renderTooltipContent = (customer: any) => {
const deviceName = customer.deviceExtra?.memo || customer.deviceExtra?.market_name || "未知设备";
const deviceModel = customer.deviceExtra?.market_name || "未知型号";
const wechatAlias = customer.alias || "未设置";
const wechatId = customer.wechatId || "未知";
return (
<div className={styles.tooltipContent}>
<div className={styles.tooltipItem}>
<span className={styles.tooltipLabel}></span>
<span className={styles.tooltipValue}>{deviceName}</span>
</div>
<div className={styles.tooltipItem}>
<span className={styles.tooltipLabel}></span>
<span className={styles.tooltipValue}>{deviceModel}</span>
</div>
<div className={styles.tooltipItem}>
<span className={styles.tooltipLabel}></span>
<span className={styles.tooltipValue}>{wechatAlias}</span>
</div>
<div className={styles.tooltipItem}>
<span className={styles.tooltipLabel}>ID</span>
<span className={styles.tooltipValue}>{wechatId}</span>
</div>
</div>
);
};
return (
<div className={styles.customerList}>
<div className={styles.userListHeader}>
@@ -106,6 +135,12 @@ const CustomerList: React.FC = () => {
count={getUnreadCount(customer.id)}
overflowCount={99}
className={styles.messageBadge}
>
<Tooltip
title={renderTooltipContent(customer)}
placement="right"
mouseEnterDelay={0.3}
overlayClassName={styles.customerTooltip}
>
<div className={styles.avatarWrapper}>
<Avatar
@@ -118,7 +153,7 @@ const CustomerList: React.FC = () => {
: undefined,
}}
>
{!customer.avatar && customer.name.charAt(0)}
{!customer.avatar && customer.nickname?.charAt(0)}
</Avatar>
{customer.isOnline && (
<span
@@ -126,6 +161,7 @@ const CustomerList: React.FC = () => {
/>
)}
</div>
</Tooltip>
</Badge>
</div>
))}