From e0feb6dff1bcacc1537cb0dbf6d41d54b6a375a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E7=BA=A7=E8=80=81=E7=99=BD=E5=85=94?= Date: Fri, 26 Sep 2025 14:33:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/PowerNavtion/index.module.scss | 1 + .../src/components/PowerNavtion/index.tsx | 3 + .../communication-record/index.module.scss | 300 +++++++++++++++-- .../communication-record/index.tsx | 313 +++++++++++++++++- 4 files changed, 587 insertions(+), 30 deletions(-) diff --git a/Touchkebao/src/components/PowerNavtion/index.module.scss b/Touchkebao/src/components/PowerNavtion/index.module.scss index b57617ad..04110530 100644 --- a/Touchkebao/src/components/PowerNavtion/index.module.scss +++ b/Touchkebao/src/components/PowerNavtion/index.module.scss @@ -11,6 +11,7 @@ align-items: center; min-height: 64px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + justify-content: space-between; .headerLeft { display: flex; diff --git a/Touchkebao/src/components/PowerNavtion/index.tsx b/Touchkebao/src/components/PowerNavtion/index.tsx index 42b9b002..b2255d1d 100644 --- a/Touchkebao/src/components/PowerNavtion/index.tsx +++ b/Touchkebao/src/components/PowerNavtion/index.tsx @@ -13,6 +13,7 @@ export interface PowerNavigationProps { onBackClick?: () => void; className?: string; style?: React.CSSProperties; + rightContent?: React.ReactNode; } const PowerNavigation: React.FC = ({ @@ -23,6 +24,7 @@ const PowerNavigation: React.FC = ({ onBackClick, className, style, + rightContent, }) => { const navigate = useNavigate(); @@ -57,6 +59,7 @@ const PowerNavigation: React.FC = ({ {subtitle && {subtitle}} +
{rightContent}
); }; diff --git a/Touchkebao/src/pages/pc/ckbox/powerCenter/communication-record/index.module.scss b/Touchkebao/src/pages/pc/ckbox/powerCenter/communication-record/index.module.scss index bf1ac1e6..c9a9cb8c 100644 --- a/Touchkebao/src/pages/pc/ckbox/powerCenter/communication-record/index.module.scss +++ b/Touchkebao/src/pages/pc/ckbox/powerCenter/communication-record/index.module.scss @@ -5,39 +5,289 @@ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } -.header { - margin-bottom: 24px; - - h1 { - font-size: 24px; - font-weight: 600; - color: #262626; - margin: 0 0 8px 0; - } - - p { - font-size: 14px; - color: #8c8c8c; - margin: 0; - } +// 导出按钮样式 +.exportButton { + height: 36px; + border-radius: 6px; + font-size: 14px; + font-weight: 500; } .content { min-height: 400px; } -.placeholder { +// 顶部搜索和筛选区域 +.headerSection { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 24px; + padding: 16px 0; + border-bottom: 1px solid #f0f0f0; +} + +.searchBar { + flex: 1; + max-width: 400px; +} + +.filterButtons { + display: flex; + gap: 12px; + + .ant-btn { + height: 36px; + border-radius: 6px; + font-size: 14px; + } +} + +// 导航栏样式 +.navigationTabs { + margin-bottom: 24px; + + .tabs { + .ant-tabs-nav { + margin-bottom: 0; + } + + .ant-tabs-tab { + padding: 12px 24px; + font-size: 14px; + font-weight: 500; + + .anticon { + margin-right: 8px; + } + } + + .ant-tabs-tab-active { + color: #1890ff; + + .ant-tabs-tab-btn { + color: #1890ff; + } + } + + .ant-tabs-ink-bar { + background: #1890ff; + } + } +} + +// 记录列表样式 +.recordsList { + display: flex; + flex-direction: column; + gap: 16px; +} + +.recordCard { + border-radius: 8px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); + border: 1px solid #f0f0f0; + transition: all 0.3s ease; + + &:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + border-color: #d9d9d9; + } + + .ant-card-body { + padding: 16px 20px; + } +} + +.cardContent { + display: flex; + justify-content: space-between; + align-items: flex-start; +} + +.cardLeft { + display: flex; + gap: 12px; + flex: 1; +} + +.avatar { + width: 40px; + height: 40px; + background: #1890ff; + color: #fff; + font-size: 16px; + font-weight: 600; + flex-shrink: 0; +} + +.recordInfo { + flex: 1; + display: flex; + flex-direction: column; + gap: 6px; +} + +.nameAndType { + display: flex; + align-items: center; + gap: 12px; + + .name { + font-size: 15px; + font-weight: 600; + color: #262626; + } + + .type { + display: flex; + align-items: center; + gap: 4px; + font-size: 13px; + color: #8c8c8c; + + .anticon { + font-size: 13px; + } + } +} + +.statusAndTime { + display: flex; + align-items: center; + gap: 12px; + + .dateTime { + font-size: 13px; + color: #8c8c8c; + } + + .duration { + font-size: 13px; + color: #8c8c8c; + } +} + +.directionAndSubject { + display: flex; + align-items: center; + gap: 12px; + + .subject { + font-size: 13px; + color: #262626; + font-weight: 500; + } +} + +.content { + font-size: 13px; + color: #595959; + line-height: 1.4; + margin: 2px 0; +} + +.tags { + display: flex; + gap: 6px; + flex-wrap: wrap; + + .tag { + font-size: 11px; + background: #f5f5f5; + border: 1px solid #d9d9d9; + color: #8c8c8c; + border-radius: 3px; + padding: 1px 6px; + margin: 0; + } +} + +.attachments { + display: flex; + flex-direction: column; + gap: 6px; + margin-top: 6px; + + .attachmentsLabel { + font-size: 12px; + color: #8c8c8c; + font-weight: 500; + } + + .attachment { + display: flex; + align-items: center; + gap: 6px; + padding: 6px 10px; + background: #fafafa; + border-radius: 4px; + border: 1px solid #f0f0f0; + + .attachmentIcon { + font-size: 14px; + } + + .attachmentName { + font-size: 12px; + color: #262626; + flex: 1; + } + + .downloadIcon { + color: #8c8c8c; + cursor: pointer; + transition: color 0.3s ease; + font-size: 12px; + + &:hover { + color: #1890ff; + } + } + } +} + +.cardRight { display: flex; align-items: center; justify-content: center; - height: 300px; - background: #fafafa; - border: 1px dashed #d9d9d9; - border-radius: 6px; - - p { - font-size: 16px; + width: 28px; + height: 28px; + + .viewIcon { + font-size: 14px; color: #8c8c8c; - margin: 0; + cursor: pointer; + transition: color 0.3s ease; + + &:hover { + color: #1890ff; + } } -} \ No newline at end of file +} + +// 响应式设计 +@media (max-width: 768px) { + .headerSection { + flex-direction: column; + gap: 16px; + align-items: stretch; + } + + .searchBar { + max-width: none; + } + + .filterButtons { + justify-content: center; + } + + .cardContent { + flex-direction: column; + gap: 16px; + } + + .cardRight { + align-self: flex-end; + } +} diff --git a/Touchkebao/src/pages/pc/ckbox/powerCenter/communication-record/index.tsx b/Touchkebao/src/pages/pc/ckbox/powerCenter/communication-record/index.tsx index f13c4347..8432cafd 100644 --- a/Touchkebao/src/pages/pc/ckbox/powerCenter/communication-record/index.tsx +++ b/Touchkebao/src/pages/pc/ckbox/powerCenter/communication-record/index.tsx @@ -1,20 +1,323 @@ -import React from "react"; +import React, { useState } from "react"; +import { Input, Button, Tabs, Tag, Avatar, Card } from "antd"; +import { + SearchOutlined, + FilterOutlined, + CalendarOutlined, + MessageOutlined, + PhoneOutlined, + VideoCameraOutlined, + MailOutlined, + EyeOutlined, + DownloadOutlined, +} from "@ant-design/icons"; import PowerNavigation from "@/components/PowerNavtion"; import styles from "./index.module.scss"; +const { Search } = Input; + +interface CommunicationRecord { + id: string; + avatar: string; + name: string; + type: "chat" | "call" | "video" | "email"; + status: "completed" | "pending" | "cancelled"; + dateTime: string; + duration?: string; + direction: "incoming" | "outgoing"; + subject?: string; + content: string; + tags: string[]; + attachments?: Array<{ + name: string; + type: "pdf" | "xlsx" | "doc" | "other"; + }>; +} + const CommunicationRecord: React.FC = () => { + const [activeTab, setActiveTab] = useState("chat"); + const [searchValue, setSearchValue] = useState(""); + + // 模拟数据 + const mockData: CommunicationRecord[] = [ + { + id: "1", + avatar: "李", + name: "李先生", + type: "chat", + status: "completed", + dateTime: "2024/3/5 14:30:00", + direction: "incoming", + content: "咨询AI营销产品的详细功能和价格", + tags: ["产品咨询", "价格询问"], + }, + { + id: "2", + avatar: "张", + name: "张总", + type: "call", + status: "completed", + dateTime: "2024/3/5 10:15:00", + duration: "25分钟", + direction: "outgoing", + subject: "产品演示预约", + content: "与客户确认产品演示时间,讨论具体需求", + tags: ["产品演示", "需求确认"], + }, + { + id: "3", + avatar: "王", + name: "王女士", + type: "video", + status: "completed", + dateTime: "2024/3/4 16:45:00", + duration: "45分钟", + direction: "incoming", + subject: "产品功能演示", + content: "详细演示AI客服功能,客户表示很满意", + tags: ["产品演示", "功能介绍"], + attachments: [ + { name: "产品介绍.pdf", type: "pdf" }, + { name: "报价单.xlsx", type: "xlsx" }, + ], + }, + ]; + + const getTypeIcon = (type: string) => { + switch (type) { + case "chat": + return ; + case "call": + return ; + case "video": + return ; + case "email": + return ; + default: + return ; + } + }; + + const getStatusColor = (status: string) => { + switch (status) { + case "completed": + return "success"; + case "pending": + return "processing"; + case "cancelled": + return "error"; + default: + return "default"; + } + }; + + const getDirectionColor = (direction: string) => { + return direction === "incoming" ? "green" : "blue"; + }; + + const getDirectionText = (direction: string) => { + return direction === "incoming" ? "来电/来信" : "去电/去信"; + }; + + const getStatusText = (status: string) => { + switch (status) { + case "completed": + return "已完成"; + case "pending": + return "进行中"; + case "cancelled": + return "已取消"; + default: + return "未知"; + } + }; + + const getAttachmentIcon = (type: string) => { + switch (type) { + case "pdf": + return "📄"; + case "xlsx": + return "📊"; + case "doc": + return "📝"; + default: + return "📎"; + } + }; + + const filteredData = mockData.filter( + record => + record.type === activeTab && + (searchValue === "" || + record.name.includes(searchValue) || + record.content.includes(searchValue) || + record.tags.some(tag => tag.includes(searchValue))), + ); + + const tabItems = [ + { + key: "chat", + label: ( + + + 聊天(1) + + ), + }, + { + key: "call", + label: ( + + + 通话(2) + + ), + }, + { + key: "video", + label: ( + + + 视频(1) + + ), + }, + { + key: "email", + label: ( + + + 邮件(1) + + ), + }, + ]; + + // 导出记录处理函数 + const handleExportRecords = () => { + console.log("导出记录功能"); + // TODO: 实现导出功能 + }; + return (
} + onClick={handleExportRecords} + className={styles.exportButton} + > + 导出记录 + + } /> +
- {/* 功能内容待开发 */} -
-

沟通记录功能正在开发中...

+ {/* 顶部搜索和筛选区域 */} +
+
+ setSearchValue(e.target.value)} + style={{ width: 300 }} + prefix={} + /> +
+
+ + +
+
+ + {/* 通信类型导航栏 */} +
+ +
+ + {/* 通信记录列表 */} +
+ {filteredData.map(record => ( + +
+
+ {record.avatar} +
+
+ {record.name} + + {getTypeIcon(record.type)} + {record.type === "chat" + ? "聊天" + : record.type === "call" + ? "通话" + : record.type === "video" + ? "视频" + : "邮件"} + +
+
+ + {getStatusText(record.status)} + + {record.dateTime} + {record.duration && ( + + 时长:{record.duration} + + )} +
+
+ + {getDirectionText(record.direction)} + + {record.subject && ( + {record.subject} + )} +
+
{record.content}
+
+ {record.tags.map((tag, index) => ( + + {tag} + + ))} +
+ {record.attachments && record.attachments.length > 0 && ( +
+ 附件: + {record.attachments.map((attachment, index) => ( +
+ + {getAttachmentIcon(attachment.type)} + + + {attachment.name} + + +
+ ))} +
+ )} +
+
+
+ +
+
+
+ ))}