From 8af3ad3549014e53cbec3f9d4d44f3fabd4c8db0 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: Sat, 16 Aug 2025 17:34:36 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B5=81=E9=87=8F?= =?UTF-8?q?=E5=88=86=E7=99=BC=E8=A8=98=E9=8C=84=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=A8=A3=E5=BC=8F=E4=BB=A5=E6=94=B9=E5=96=84?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A2=9D=E5=92=8C=E5=88=86=E7=99=BC=E7=B5=B1?= =?UTF-8?q?=E8=A8=88=E5=BD=88=E7=AA=97=E7=9A=84=E9=A1=AF=E7=A4=BA=E6=95=88?= =?UTF-8?q?=E6=9E=9C=EF=BC=8C=E4=B8=A6=E5=9C=A8=E5=88=97=E8=A1=A8=E4=B8=AD?= =?UTF-8?q?=E6=95=B4=E5=90=88=E7=9B=B8=E6=87=89=E7=9A=84=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E9=82=8F=E8=BC=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../traffic-distribution/list/api.ts | 10 + .../list/components/SendRcrodModal.tsx | 232 ++++++++++++++++++ .../list/index.module.scss | 36 +++ .../traffic-distribution/list/index.tsx | 22 +- 4 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/components/SendRcrodModal.tsx diff --git a/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/api.ts b/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/api.ts index 93c5002e..67d4ba32 100644 --- a/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/api.ts +++ b/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/api.ts @@ -31,3 +31,13 @@ export function deleteDistributionRule(id: number): Promise { export function fetchDistributionRuleDetail(id: number): Promise { return request(`/v1/workbench/detail?id=${id}`, {}, "GET"); } + +//流量分发记录 +export function fetchTransferFriends(params: { + page?: number; + limit?: number; + keyword?: string; + workbenchId: number; +}) { + return request("/v1/workbench/transfer-friends", params, "GET"); +} diff --git a/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/components/SendRcrodModal.tsx b/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/components/SendRcrodModal.tsx new file mode 100644 index 00000000..e82d27e9 --- /dev/null +++ b/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/components/SendRcrodModal.tsx @@ -0,0 +1,232 @@ +import React, { useEffect, useState } from "react"; +import { Popup, Avatar, SpinLoading, Input } from "antd-mobile"; +import { Button, message, Pagination } from "antd"; +import { CloseOutlined, SearchOutlined } from "@ant-design/icons"; +import style from "../index.module.scss"; +import { fetchTransferFriends } from "../api"; + +interface SendRecordItem { + id: string | number; + nickname?: string; + wechatId?: string; + avatar?: string; + status?: string; + isRecycle?: number; + sendTime?: string; + sendCount?: number; +} + +interface SendRcrodModalProps { + visible: boolean; + onClose: () => void; + ruleId?: number; + ruleName?: string; +} + +const SendRcrodModal: React.FC = ({ + visible, + onClose, + ruleId, + ruleName, +}) => { + const [sendRecords, setSendRecords] = useState([]); + const [loading, setLoading] = useState(false); + const [searchQuery, setSearchQuery] = useState(""); + const [searchKeyword, setSearchKeyword] = useState(""); + const [currentPage, setCurrentPage] = useState(1); + const [total, setTotal] = useState(0); + const pageSize = 20; + + // 获取分发记录数据 + const fetchSendRecords = async (page = 1, keyword = "") => { + if (!ruleId || !visible) return; + + setLoading(true); + try { + const detailRes = await fetchTransferFriends({ + workbenchId: ruleId, + page, + limit: pageSize, + keyword, + }); + console.log(detailRes); + + const recordData = detailRes.list || []; + setSendRecords(recordData); + setTotal(detailRes.total || 0); + } catch (error) { + console.error("获取分发记录失败:", error); + message.error("获取分发记录失败"); + } finally { + setLoading(false); + } + }; + + // 当弹窗打开且有ruleId时,获取数据 + useEffect(() => { + if (visible && ruleId) { + setCurrentPage(1); + setSearchQuery(""); + setSearchKeyword(""); + fetchSendRecords(1, ""); + } + }, [visible, ruleId]); + + // 搜索关键词变化时触发搜索 + useEffect(() => { + if (!visible || !ruleId) return; + setCurrentPage(1); + fetchSendRecords(1, searchKeyword); + }, [searchKeyword, visible, ruleId]); + + // 页码变化 + useEffect(() => { + if (!visible || !ruleId || currentPage === 1) return; + fetchSendRecords(currentPage, searchKeyword); + }, [currentPage, visible, ruleId]); + + // 处理页码变化 + const handlePageChange = (page: number) => { + setCurrentPage(page); + }; + + // 处理搜索回车 + const handleSearchEnter = () => { + setSearchKeyword(searchQuery); + }; + + // 处理搜索输入 + const handleSearchChange = (value: string) => { + setSearchQuery(value); + }; + + const title = ruleName ? `${ruleName} - 分发统计` : "分发统计"; + const getRecycleColor = (isRecycle?: number) => { + switch (isRecycle) { + case 0: + return "#52c41a"; // 绿色 - 未回收 + case 1: + return "#ff4d4f"; // 红色 - 已回收 + default: + return "#d9d9d9"; // 灰色 - 未知状态 + } + }; + + const getRecycleText = (isRecycle?: number) => { + switch (isRecycle) { + case 0: + return "未回收"; + case 1: + return "已回收"; + default: + return "未知"; + } + }; + + return ( + +
+ {/* 头部 */} +
+

{title}

+
+ + {/* 搜索栏 */} +
+
+ + +
+
+ + {/* 分发记录列表 */} +
+ {loading ? ( +
+ +
+ 正在加载分发记录... +
+
+ ) : sendRecords.length > 0 ? ( + sendRecords.map((record, index) => ( +
+
+ +
+
+
+ {record.nickname || record.wechatId || `账号${record.id}`} +
+
+ {record.wechatId || "未绑定微信号"} +
+
+
+ + + {getRecycleText(record.isRecycle)} + +
+
+ )) + ) : ( +
+
暂无分发记录
+
+ )} +
+ + {/* 底部统计和分页 */} +
+
+ 共 {total} 条分发记录 +
+
+ +
+
+
+
+ ); +}; + +export default SendRcrodModal; diff --git a/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/index.module.scss b/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/index.module.scss index 9f5adc14..1415242c 100644 --- a/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/index.module.scss +++ b/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/index.module.scss @@ -255,6 +255,9 @@ padding: 16px 20px; border-top: 1px solid #f0f0f0; background: #fff; + display: flex; + justify-content: space-between; + align-items: center; } .accountStats { @@ -263,6 +266,39 @@ color: #666; } +.searchBar { + padding: 16px 20px; + border-bottom: 1px solid #f0f0f0; + background: #fff; +} + +.searchInputWrapper { + position: relative; + display: flex; + align-items: center; +} + +.searchIcon { + position: absolute; + left: 12px; + top: 50%; + transform: translateY(-50%); + color: #999; + font-size: 16px; + z-index: 1; +} + +.searchInputWrapper :global(.adm-input) { + padding-left: 40px; + border-radius: 8px; + height: 40px; +} + +.paginationContainer { + display: flex; + justify-content: center; +} + // 设备列表弹窗样式 .deviceModal { height: 100%; diff --git a/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/index.tsx b/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/index.tsx index b36a58ef..f94f54ba 100644 --- a/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/index.tsx +++ b/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/index.tsx @@ -34,6 +34,7 @@ import { useNavigate } from "react-router-dom"; import AccountListModal from "./components/AccountListModal"; import DeviceListModal from "./components/DeviceListModal"; import PoolListModal from "./components/PoolListModal"; +import SendRcrodModal from "./components/SendRcrodModal"; const PAGE_SIZE = 10; @@ -57,6 +58,7 @@ const TrafficDistributionList: React.FC = () => { const [accountModalVisible, setAccountModalVisible] = useState(false); const [deviceModalVisible, setDeviceModalVisible] = useState(false); const [poolModalVisible, setPoolModalVisible] = useState(false); + const [sendRecordModalVisible, setSendRecordModalVisible] = useState(false); const [currentRule, setCurrentRule] = useState(null); const navigate = useNavigate(); @@ -153,6 +155,12 @@ const TrafficDistributionList: React.FC = () => { setPoolModalVisible(true); }; + // 显示分发统计弹窗 + const showSendRecord = (item: DistributionRule) => { + setCurrentRule(item); + setSendRecordModalVisible(true); + }; + const renderCard = (item: DistributionRule) => { const menu = ( handleMenuClick(key, item)}> @@ -287,7 +295,11 @@ const TrafficDistributionList: React.FC = () => { 总流量池数量 -
+
showSendRecord(item)} + > {item.config?.total?.totalUsers || 0} @@ -394,6 +406,14 @@ const TrafficDistributionList: React.FC = () => { ruleId={currentRule?.id} ruleName={currentRule?.name} /> + + {/* 分发统计弹窗 */} + setSendRecordModalVisible(false)} + ruleId={currentRule?.id} + ruleName={currentRule?.name} + /> ); }; From 60e5a682bda03efa2425e950c625d06b578b3e15 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: Sat, 16 Aug 2025 17:59:36 +0800 Subject: [PATCH 2/2] =?UTF-8?q?FEAT=20=3D>=20=E6=9C=AC=E6=AC=A1=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E9=A1=B9=E7=9B=AE=E4=B8=BA=EF=BC=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../list/components/SendRcrodModal.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/components/SendRcrodModal.tsx b/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/components/SendRcrodModal.tsx index e82d27e9..d74c5219 100644 --- a/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/components/SendRcrodModal.tsx +++ b/Cunkebao/src/pages/mobile/workspace/traffic-distribution/list/components/SendRcrodModal.tsx @@ -39,7 +39,7 @@ const SendRcrodModal: React.FC = ({ // 获取分发记录数据 const fetchSendRecords = async (page = 1, keyword = "") => { - if (!ruleId || !visible) return; + if (!ruleId) return; setLoading(true); try { @@ -74,16 +74,16 @@ const SendRcrodModal: React.FC = ({ // 搜索关键词变化时触发搜索 useEffect(() => { - if (!visible || !ruleId) return; + if (!visible || !ruleId || searchKeyword === "") return; setCurrentPage(1); fetchSendRecords(1, searchKeyword); - }, [searchKeyword, visible, ruleId]); + }, [searchKeyword]); // 页码变化 useEffect(() => { if (!visible || !ruleId || currentPage === 1) return; fetchSendRecords(currentPage, searchKeyword); - }, [currentPage, visible, ruleId]); + }, [currentPage]); // 处理页码变化 const handlePageChange = (page: number) => {