优化客户管理模块:更新标签页样式,调整按钮组件,重构联系人展示为表格形式,提升用户体验和代码可读性。

This commit is contained in:
超级老白兔
2025-10-11 15:49:05 +08:00
parent b067134ae7
commit 31c7980a9a
3 changed files with 117 additions and 130 deletions

View File

@@ -114,9 +114,9 @@
// 标签页
.tabs {
padding: 20px;
display: flex;
gap: 0;
border-bottom: 1px solid #f0f0f0;
gap: 10px;
.tab {
padding: 12px 24px;
@@ -127,15 +127,6 @@
color: #8c8c8c;
cursor: pointer;
transition: all 0.3s;
&:hover {
color: #1890ff;
}
&.activeTab {
color: #1890ff;
border-bottom-color: #1890ff;
}
}
}

View File

@@ -1,13 +1,8 @@
import React, { useState, useEffect } from "react";
import PowerNavigation from "@/components/PowerNavtion";
import {
SearchOutlined,
FilterOutlined,
MessageOutlined,
PhoneOutlined,
} from "@ant-design/icons";
import { SearchOutlined, FilterOutlined } from "@ant-design/icons";
import styles from "./index.module.scss";
import { Button, Input, Row, Col, Pagination, Spin, message } from "antd";
import { Button, Input, Table, message } from "antd";
import { getContactList } from "@/pages/pc/ckbox/weChat/api";
import { ContractData } from "@/pages/pc/ckbox/data";
import Layout from "@/components/Layout/LayoutFiexd";
@@ -196,132 +191,129 @@ const CustomerManagement: React.FC = () => {
</Button>
</div>
{/* 标签 */}
{/* 标签按钮组 */}
<div className={styles.tabs}>
{tabs.map(tab => (
<button
<Button
key={tab.key}
className={`${styles.tab} ${activeTab === tab.key ? styles.activeTab : ""}`}
type={activeTab === tab.key ? "primary" : "default"}
onClick={() => setActiveTab(tab.key)}
>
{tab.label} ({tab.count})
</button>
{tab.label}
<span style={{ marginLeft: 6, opacity: 0.85 }}>
{tab.count}
</span>
</Button>
))}
</div>
</div>
</>
}
footer={
<div className="pagination-wrapper">
<Pagination
current={pagination.current}
pageSize={pagination.pageSize}
total={pagination.total}
showSizeChanger
showQuickJumper
showTotal={(total, range) =>
`${range[0]}-${range[1]} 条,共 ${total}`
}
onChange={(page, pageSize) => {
loadContacts(page, pageSize || pagination.pageSize);
}}
onShowSizeChange={(current, size) => {
loadContacts(1, size);
}}
pageSizeOptions={["6", "12", "24", "48"]}
/>
</div>
}
footer={null}
>
<div className={styles.container}>
<div className={styles.content}>
{/* 联系人卡片列表 */}
<div className={styles.contactsList}>
{loading ? (
<div style={{ textAlign: "center", padding: "50px" }}>
<Spin size="large" />
<p style={{ marginTop: "16px", color: "#666" }}>
...
</p>
</div>
) : filteredContacts.length === 0 ? (
<div style={{ textAlign: "center", padding: "50px" }}>
<p style={{ color: "#999" }}></p>
</div>
) : (
<>
<Row gutter={[16, 16]}>
{filteredContacts.map(contact => (
<Col span={8} key={contact.id || contact.serverId}>
<div className={styles.contactCard}>
<div className={styles.cardHeader}>
<div className={styles.contactInfo}>
<Avatar
name={
contact.conRemark ||
contact.nickname ||
contact.alias ||
"未知用户"
}
avatar={contact.avatar}
size={48}
/>
<div className={styles.nameSection}>
<h3 className={styles.contactName}>
{contact.conRemark ||
contact.nickname ||
contact.alias ||
"未知用户"}
</h3>
<p className={styles.roleCompany}>
{"·"} {contact.desc || "未设置公司"}
</p>
</div>
</div>
</div>
<div className={styles.contactDetails}>
<div className={styles.contactInfo}>
<p className={styles.contactItem}>
<span className={styles.label}>:</span>{" "}
{contact.phone || "未设置电话"}
</p>
<p className={styles.contactItem}>
<span className={styles.label}>:</span>{" "}
{contact.region || contact.city || "未设置地区"}
</p>
<p className={styles.contactItem}>
<span className={styles.label}>ID:</span>{" "}
{contact.wechatId}
</p>
</div>
</div>
<div className={styles.tagsSection}>
<div className={styles.tags}>
{contact?.labels?.map(
(tag: string, index: number) => (
<span key={index} className={styles.tag}>
{tag}
</span>
),
)}
</div>
</div>
<div className={styles.actions}>
<Button type="primary" block>
<MessageOutlined />
</Button>
</div>
{/* 联系人表 */}
<Table
rowKey={(record: any) => record.id || record.serverId}
loading={loading}
dataSource={filteredContacts as any}
columns={[
{
title: "客户姓名",
key: "name",
render: (_: any, record: any) => {
const displayName =
record.conRemark ||
record.nickname ||
record.alias ||
"未知用户";
return (
<div className={styles.contactInfo}>
<Avatar
name={displayName}
avatar={record.avatar}
size={40}
/>
<div className={styles.nameSection}>
<h3 className={styles.contactName}>{displayName}</h3>
<p className={styles.roleCompany}>
· {record.desc || "未设置公司"}
</p>
</div>
</Col>
))}
</Row>
</>
)}
</div>
</div>
);
},
},
{
title: "RFM评分",
dataIndex: "rfmScore",
key: "rfmScore",
width: 100,
render: (val: any) => val ?? "-",
},
{
title: "电话",
dataIndex: "phone",
key: "phone",
width: 180,
render: (val: string) => val || "未设置电话",
},
{
title: "微信号",
dataIndex: "wechatId",
key: "wechatId",
width: 200,
},
{
title: "地址",
key: "address",
ellipsis: true,
render: (_: any, record: any) =>
record.region || record.city || "未设置地区",
},
{
title: "标签",
key: "labels",
render: (_: any, record: any) => (
<div className={styles.tags}>
{(record?.labels || []).map(
(tag: string, index: number) => (
<span key={index} className={styles.tag}>
{tag}
</span>
),
)}
</div>
),
},
{
title: "操作",
key: "action",
width: 120,
render: () => (
<Button type="primary" size="small">
</Button>
),
},
]}
pagination={{
current: pagination.current,
pageSize: pagination.pageSize,
total: pagination.total,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total: number, range: [number, number]) =>
`${range[0]}-${range[1]} 条,共 ${total}`,
pageSizeOptions: ["6", "12", "24", "48"],
}}
onChange={(pager: any) => {
const nextCurrent = pager.current || 1;
const nextSize = pager.pageSize || pagination.pageSize;
loadContacts(nextCurrent, nextSize);
}}
/>
</div>
</div>
</Layout>

View File

@@ -5,6 +5,7 @@ import AudioMessage from "./components/AudioMessage/AudioMessage";
import SmallProgramMessage from "./components/SmallProgramMessage";
import VideoMessage from "./components/VideoMessage";
import ClickMenu from "./components/ClickMeau";
import LocationMessage from "./components/LocationMessage";
import { ChatRecord, ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
import { formatWechatTime } from "@/utils/common";
import { getEmojiPath } from "@/components/EmojiSeclection/wechatEmoji";
@@ -270,6 +271,9 @@ const MessageRecord: React.FC<MessageRecordProps> = ({ contract }) => {
}
return renderErrorMessage("[表情包]");
case 48: // 定位消息
return <LocationMessage content={content || ""} />;
case 49: // 小程序/文章/其他:图文、文件
return <SmallProgramMessage content={content || ""} />;