diff --git a/nkebao/src/pages/mobile/mine/traffic-pool/detail/api.ts b/nkebao/src/pages/mobile/mine/traffic-pool/detail/api.ts index a31a1c345..dfad51951 100644 --- a/nkebao/src/pages/mobile/mine/traffic-pool/detail/api.ts +++ b/nkebao/src/pages/mobile/mine/traffic-pool/detail/api.ts @@ -1,5 +1,31 @@ import request from "@/api/request"; +import type { + TrafficPoolUserDetail, + UserJourneyResponse, + UserTagsResponse, +} from "./data"; -export function getTrafficPoolDetail(id: string): Promise { - return request("/v1/workbench/detail", { id }, "GET"); +export function getTrafficPoolDetail( + wechatId: string +): Promise { + return request("/v1/wechats/getWechatInfo", { wechatId }, "GET"); +} + +// 获取用户旅程记录 +export function getUserJourney(params: { + page: number; + pageSize: number; + userId: string; +}): Promise { + return request("/v1/traffic/pool/getUserJourney", params, "GET"); +} + +// 获取用户标签 +export function getUserTags(userId: string): Promise { + return request("/v1/traffic/pool/getUserTags", { userId }, "GET"); +} + +// 添加用户标签 +export function addUserTag(userId: string, tagData: any): Promise { + return request("/v1/user/tags", { userId, ...tagData }, "POST"); } diff --git a/nkebao/src/pages/mobile/mine/traffic-pool/detail/index.module.scss b/nkebao/src/pages/mobile/mine/traffic-pool/detail/index.module.scss index a3833543c..60165acbb 100644 --- a/nkebao/src/pages/mobile/mine/traffic-pool/detail/index.module.scss +++ b/nkebao/src/pages/mobile/mine/traffic-pool/detail/index.module.scss @@ -1,291 +1,420 @@ -.container { - padding: 12px; - background: #f5f5f5; - min-height: 100vh; -} - -.userCard { - margin-bottom: 12px; - border-radius: 12px; - overflow: hidden; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); -} - -.userInfo { - display: flex; - align-items: center; - gap: 16px; - padding: 16px; -} - -.avatar { - width: 64px; - height: 64px; - border-radius: 50%; - flex-shrink: 0; -} - -.userDetails { - flex: 1; - min-width: 0; -} - -.nickname { - font-size: 18px; - font-weight: 600; - color: #333; - margin-bottom: 4px; - line-height: 1.2; -} - -.wechatId { - font-size: 14px; - color: #1677ff; - margin-bottom: 4px; - line-height: 1.2; -} - -.alias { - font-size: 12px; - color: #666; - margin-bottom: 8px; - line-height: 1.2; -} - -.tags { - display: flex; - flex-wrap: wrap; - gap: 6px; -} - -.genderTag { - font-size: 12px; - padding: 2px 8px; - border-radius: 12px; -} - -.weightTag { - font-size: 12px; - padding: 2px 8px; - border-radius: 12px; -} - -.tabs { - background: transparent; - - :global(.adm-tabs-header) { - background: white; - border-radius: 12px 12px 0 0; - margin-bottom: 0; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); - } - - :global(.adm-tabs-tab) { - font-size: 14px; - font-weight: 500; - } - - :global(.adm-tabs-tab-active) { - color: #1677ff; - } - - :global(.adm-tabs-tab-line) { - background: #1677ff; - } - - :global(.adm-tabs-content) { - background: white; - border-radius: 0 0 12px 12px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); - } -} - -.tabContent { - padding: 16px; -} - -.infoCard { - margin-bottom: 12px; - border-radius: 8px; - overflow: hidden; - - &:last-child { - margin-bottom: 0; - } - - :global(.adm-card-header) { - padding: 12px 16px; - border-bottom: 1px solid #f0f0f0; - font-size: 14px; - font-weight: 600; - color: #333; - } - - :global(.adm-card-body) { - padding: 0; - } -} - -.statsGrid { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 16px; - padding: 16px; -} - -.statItem { - text-align: center; -} - -.statValue { - font-size: 18px; - font-weight: 700; - line-height: 1.2; - margin-bottom: 4px; -} - -.statLabel { - font-size: 12px; - color: #666; - line-height: 1.2; -} - -.restrictionTitle { - display: flex; - align-items: center; - justify-content: space-between; - gap: 8px; - font-size: 14px; - font-weight: 500; - color: #333; - line-height: 1.4; -} - -.restrictionLevel { - font-size: 10px; - padding: 2px 6px; - border-radius: 8px; - flex-shrink: 0; -} - -.restrictionContent { - display: flex; - flex-direction: column; - gap: 4px; - font-size: 12px; - color: #666; - line-height: 1.4; - margin-top: 4px; -} - -.emptyState { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 48px 16px; - text-align: center; -} - -.emptyText { - color: #999; - font-size: 14px; - line-height: 1.4; -} - -// 响应式设计 -@media (max-width: 375px) { - .container { - padding: 8px; - } - - .userInfo { - padding: 12px; - gap: 12px; - } - - .avatar { - width: 56px; - height: 56px; - } - - .nickname { - font-size: 16px; - } - - .wechatId { - font-size: 13px; - } - - .alias { - font-size: 11px; - } - - .tabContent { - padding: 12px; - } - - .statsGrid { - gap: 12px; - padding: 12px; - } - - .statValue { - font-size: 16px; - } - - .restrictionTitle { - font-size: 13px; - } - - .restrictionContent { - font-size: 11px; - } -} - -// 暗色模式支持 -@media (prefers-color-scheme: dark) { - .container { - background: #1a1a1a; - } - - .userCard, - .tabs :global(.adm-tabs-header), - .tabs :global(.adm-tabs-content) { - background: #2a2a2a; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); - } - - .nickname { - color: #fff; - } - - .wechatId { - color: #4a9eff; - } - - .alias { - color: #999; - } - - .infoCard :global(.adm-card-header) { - color: #fff; - border-bottom-color: #3a3a3a; - } - - .statLabel { - color: #999; - } - - .restrictionTitle { - color: #fff; - } - - .restrictionContent { - color: #999; - } - - .emptyText { - color: #666; - } -} +.container { + padding: 0; + background: #f5f5f5; + min-height: 100vh; +} + +// 头部样式 +.header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px; + background: #fff; + border-bottom: 1px solid #f0f0f0; + + .title { + font-size: 18px; + font-weight: 600; + color: #333; + } + + .closeBtn { + padding: 8px; + border: none; + background: transparent; + color: #999; + font-size: 16px; + } +} + +// 用户卡片 +.userCard { + margin: 16px; + border-radius: 12px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + + .userInfo { + display: flex; + align-items: flex-start; + gap: 16px; + } + + .avatar { + width: 60px; + height: 60px; + border-radius: 50%; + flex-shrink: 0; + } + + .userDetails { + flex: 1; + min-width: 0; + } + + .nickname { + font-size: 18px; + font-weight: 600; + color: #333; + margin-bottom: 4px; + } + + .wechatId { + font-size: 14px; + color: #666; + margin-bottom: 8px; + } + + .tags { + display: flex; + flex-wrap: wrap; + gap: 8px; + } + + .userTag { + font-size: 12px; + padding: 4px 8px; + border-radius: 12px; + } +} + +// 标签导航 +.tabNav { + display: flex; + background: #fff; + margin: 0 16px; + border-radius: 8px; + overflow: hidden; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + + .tabItem { + flex: 1; + padding: 12px 16px; + text-align: center; + font-size: 14px; + color: #666; + cursor: pointer; + transition: all 0.3s ease; + border-bottom: 2px solid transparent; + + &.active { + color: var(--primary-color); + border-bottom-color: var(--primary-color); + background: rgba(24, 142, 238, 0.05); + } + + &:hover { + background: rgba(24, 142, 238, 0.05); + } + } +} + +// 内容区域 +.content { + padding: 16px; +} + +.tabContent { + display: flex; + flex-direction: column; + gap: 16px; +} + +// 信息卡片 +.infoCard { + border-radius: 12px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + overflow: hidden; + + :global(.adm-card-header) { + padding: 16px; + border-bottom: 1px solid #f0f0f0; + font-weight: 600; + color: #333; + } + + :global(.adm-card-body) { + padding: 0; + } +} + +// RFM评分网格 +.rfmGrid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 16px; + padding: 16px; +} + +.rfmItem { + text-align: center; + padding: 12px; + background: #f8f9fa; + border-radius: 8px; +} + +.rfmLabel { + font-size: 12px; + color: #666; + margin-bottom: 4px; +} + +.rfmValue { + font-size: 18px; + font-weight: 600; +} + +// 流量池区域 +.poolSection { + padding: 16px; + display: flex; + flex-direction: column; + gap: 12px; +} + +.currentPool, +.availablePools { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; +} + +.poolLabel { + font-size: 14px; + color: #666; + white-space: nowrap; +} + +// 统计数据网格 +.statsGrid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 16px; + padding: 16px; +} + +.statItem { + text-align: center; + padding: 12px; + background: #f8f9fa; + border-radius: 8px; +} + +.statValue { + font-size: 18px; + font-weight: 600; + margin-bottom: 4px; +} + +.statLabel { + font-size: 12px; + color: #666; +} + +// 用户旅程 +.journeyItem { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 12px; + color: #666; + margin-top: 4px; +} + +.timestamp { + color: #999; +} + +// 加载状态 +.loadingContainer { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 40px 16px; + text-align: center; +} + +.loadingText { + font-size: 14px; + color: #999; + margin-top: 8px; +} + +.loadingMore { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + padding: 16px; + color: #666; + font-size: 14px; +} + +.loadMoreBtn { + display: flex; + justify-content: center; + padding: 16px; +} + +// 标签区域 +.tagsSection { + padding: 16px; + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.valueTagsSection { + padding: 16px; + display: flex; + flex-direction: column; + gap: 12px; +} + +.tagItem { + font-size: 12px; + padding: 6px 12px; + border-radius: 16px; +} + +.valueTagContainer { + display: flex; + flex-direction: column; + gap: 8px; +} + +.valueTagRow { + display: flex; + justify-content: space-between; + align-items: center; + gap: 8px; +} + +.rfmScoreText { + font-size: 12px; + color: #666; + white-space: nowrap; +} + +.valueLevelLabel { + font-size: 12px; + color: #666; + white-space: nowrap; +} + +.valueTagItem { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 0; + border-bottom: 1px solid #f0f0f0; + + &:last-child { + border-bottom: none; + } +} + +.valueInfo { + display: flex; + align-items: center; + gap: 8px; + font-size: 12px; + color: #666; +} + +// 添加标签按钮 +.addTagBtn { + margin-top: 16px; + border-radius: 8px; + height: 48px; + font-size: 16px; + font-weight: 500; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +// 空状态 +.emptyState { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 60px 16px; + text-align: center; +} + +.emptyIcon { + margin-bottom: 16px; + opacity: 0.6; +} + +.emptyText { + font-size: 16px; + color: #666; + margin-bottom: 8px; + font-weight: 500; +} + +.emptyDesc { + font-size: 14px; + color: #999; + line-height: 1.4; +} + +// 限制记录样式 +.restrictionTitle { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + font-size: 14px; + font-weight: 500; + color: #333; + line-height: 1.4; +} + +.restrictionLevel { + font-size: 10px; + padding: 2px 6px; + border-radius: 8px; + flex-shrink: 0; +} + +.restrictionContent { + display: flex; + flex-direction: column; + gap: 4px; + font-size: 12px; + color: #666; + line-height: 1.4; + margin-top: 4px; +} + +// 响应式设计 +@media (max-width: 375px) { + .rfmGrid, + .statsGrid { + grid-template-columns: 1fr; + } + + .userInfo { + flex-direction: column; + text-align: center; + } + + .avatar { + align-self: center; + } + + .restrictionTitle { + font-size: 13px; + } + + .restrictionContent { + font-size: 11px; + } +} diff --git a/nkebao/src/pages/mobile/mine/traffic-pool/detail/index.tsx b/nkebao/src/pages/mobile/mine/traffic-pool/detail/index.tsx index 1b89ca17c..f478fdfc4 100644 --- a/nkebao/src/pages/mobile/mine/traffic-pool/detail/index.tsx +++ b/nkebao/src/pages/mobile/mine/traffic-pool/detail/index.tsx @@ -1,47 +1,285 @@ import React, { useEffect, useState } from "react"; import { useParams, useNavigate } from "react-router-dom"; +import { + Card, + Button, + Avatar, + Tag, + Tabs, + List, + Badge, + SpinLoading, +} from "antd-mobile"; +import { + UserOutlined, + CrownOutlined, + PlusOutlined, + CloseOutlined, + EyeOutlined, + DollarOutlined, + MobileOutlined, + TagOutlined, + FileTextOutlined, + UserAddOutlined, +} from "@ant-design/icons"; import Layout from "@/components/Layout/Layout"; -import { getTrafficPoolDetail } from "./api"; -import type { TrafficPoolUserDetail } from "./data"; -import { Card, Button, Avatar, Tag, Spin } from "antd"; - -const tabList = [ - { key: "base", label: "基本信息" }, - { key: "journey", label: "用户旅程" }, - { key: "tags", label: "用户标签" }, -]; +import NavCommon from "@/components/NavCommon"; +import { getTrafficPoolDetail, getUserJourney, getUserTags } from "./api"; +import type { + TrafficPoolUserDetail, + ExtendedUserDetail, + InteractionRecord, + UserJourneyRecord, + UserTagsResponse, + UserTagItem, +} from "./data"; +import styles from "./index.module.scss"; const TrafficPoolDetail: React.FC = () => { - const { id } = useParams(); + const { wxid, userId } = useParams(); const navigate = useNavigate(); const [loading, setLoading] = useState(true); - const [user, setUser] = useState(null); - const [activeTab, setActiveTab] = useState<"base" | "journey" | "tags">( - "base" - ); + const [user, setUser] = useState(null); + const [activeTab, setActiveTab] = useState("basic"); + + // 用户旅程相关状态 + const [journeyLoading, setJourneyLoading] = useState(false); + const [journeyList, setJourneyList] = useState([]); + const [journeyPage, setJourneyPage] = useState(1); + const [journeyTotal, setJourneyTotal] = useState(0); + const pageSize = 10; + + // 用户标签相关状态 + const [tagsLoading, setTagsLoading] = useState(false); + const [userTagsList, setUserTagsList] = useState([]); useEffect(() => { - if (!id) return; + if (!wxid) return; setLoading(true); - getTrafficPoolDetail(id as string) - .then(res => setUser(res)) + getTrafficPoolDetail(wxid as string) + .then(res => { + // 将API数据转换为扩展的用户详情数据 + const extendedUser: ExtendedUserDetail = { + ...res, + // 模拟RFM评分数据 + rfmScore: { + recency: 5, + frequency: 5, + monetary: 5, + totalScore: 15, + }, + // 模拟流量池数据 + trafficPools: { + currentPool: "新用户池", + availablePools: ["高价值客户池", "活跃用户池"], + }, + // 模拟用户标签数据 + userTags: [ + { id: "1", name: "近期活跃", color: "success", type: "user" }, + { id: "2", name: "高频互动", color: "primary", type: "user" }, + { id: "3", name: "高消费", color: "warning", type: "user" }, + { id: "4", name: "老客户", color: "danger", type: "user" }, + ], + // 模拟价值标签数据 + valueTags: [ + { + id: "1", + name: "重要保持客户", + color: "primary", + icon: "crown", + rfmScore: 14, + valueLevel: "高价值", + }, + ], + }; + setUser(extendedUser); + }) .finally(() => setLoading(false)); - }, [id]); + }, [wxid]); + + // 获取用户旅程数据 + const fetchUserJourney = async (page: number = 1) => { + if (!userId) return; + + setJourneyLoading(true); + try { + const response = await getUserJourney({ + page, + pageSize, + userId: userId, + }); + + if (page === 1) { + setJourneyList(response.list); + } else { + setJourneyList(prev => [...prev, ...response.list]); + } + setJourneyTotal(response.total); + setJourneyPage(page); + } catch (error) { + console.error("获取用户旅程失败:", error); + } finally { + setJourneyLoading(false); + } + }; + + // 获取用户标签数据 + const fetchUserTags = async () => { + if (!userId) return; + + setTagsLoading(true); + try { + const response: UserTagsResponse = await getUserTags(userId); + setUserTagsList(response.siteLabels || []); + } catch (error) { + console.error("获取用户标签失败:", error); + } finally { + setTagsLoading(false); + } + }; + + // 标签切换处理 + const handleTabChange = (tab: string) => { + setActiveTab(tab); + if (tab === "journey" && journeyList.length === 0) { + fetchUserJourney(1); + } + if (tab === "tags" && userTagsList.length === 0) { + fetchUserTags(); + } + }; + + const handleClose = () => { + navigate(-1); + }; + + const getJourneyTypeIcon = (type: number) => { + switch (type) { + case 0: // 浏览 + return ; + case 2: // 提交订单 + return ; + case 3: // 注册 + return ; + default: + return ; + } + }; + + const getJourneyTypeText = (type: number) => { + switch (type) { + case 0: + return "浏览行为"; + case 2: + return "提交订单"; + case 3: + return "注册行为"; + default: + return "其他行为"; + } + }; + + const formatDateTime = (dateTime: string) => { + try { + const date = new Date(dateTime); + return date.toLocaleString("zh-CN", { + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + }); + } catch (error) { + return dateTime; + } + }; + + const getActionIcon = (type: string) => { + switch (type) { + case "click": + return ; + case "view": + return ; + case "purchase": + return ; + default: + return ; + } + }; + + const formatCurrency = (amount: number) => { + return `¥${amount.toLocaleString()}`; + }; + + const getGenderText = (gender: number) => { + switch (gender) { + case 1: + return "男"; + case 2: + return "女"; + default: + return "未知"; + } + }; + + const getGenderColor = (gender: number) => { + switch (gender) { + case 1: + return "#1677ff"; + case 2: + return "#eb2f96"; + default: + return "#999"; + } + }; + + const getRestrictionLevelText = (level: number) => { + switch (level) { + case 1: + return "轻微"; + case 2: + return "中等"; + case 3: + return "严重"; + default: + return "未知"; + } + }; + + const getRestrictionLevelColor = (level: number) => { + switch (level) { + case 1: + return "warning"; + case 2: + return "danger"; + case 3: + return "danger"; + default: + return "default"; + } + }; + + const formatDate = (timestamp: number | null) => { + if (!timestamp) return "--"; + try { + const date = new Date(timestamp * 1000); + return date.toLocaleDateString("zh-CN"); + } catch (error) { + return "--"; + } + }; + + // 获取标签颜色 + const getTagColor = (index: number): string => { + const colors = ["primary", "success", "warning", "danger", "default"]; + return colors[index % colors.length]; + }; - if (loading) { - return ( - -
- -
-
- ); - } if (!user) { return ( - -
- 未找到该用户 + } loading={loading}> +
+
未找到该用户
); @@ -49,249 +287,418 @@ const TrafficPoolDetail: React.FC = () => { return ( - -
用户详情
-
+ <> + + {/* 用户基本信息 */} + +
+ } + /> +
+
{user.userInfo.nickname}
+
{user.userInfo.wechatId}
+
+ + + 重要价值客户 + + + 优先添加 + +
+
+
+
+ {/* 导航标签 */} +
+
handleTabChange("basic")} + > + 基本信息 +
+
handleTabChange("journey")} + > + 用户旅程 +
+
handleTabChange("tags")} + > + 用户标签 +
+
+ } > -
- {/* 顶部信息 */} -
- -
-
{user.nickname}
-
- {user.wechatId} -
- {user.packages && - user.packages.length > 0 && - user.packages.map(pkg => ( - - {pkg} - - ))} -
-
- {/* Tab栏 */} -
- {tabList.map(tab => ( -
setActiveTab(tab.key as any)} - > - {tab.label} -
- ))} -
- {/* Tab内容 */} - {activeTab === "base" && ( - <> - -
-
设备:{user.deviceName || "--"}
-
微信号:{user.wechatAccountName || "--"}
-
客服:{user.customerServiceName || "--"}
-
添加时间:{user.addTime || "--"}
-
最近互动:{user.lastInteraction || "--"}
-
-
- -
-
-
- {user.rfmScore?.recency ?? "-"} -
-
最近性(R)
-
-
-
- {user.rfmScore?.frequency ?? "-"} -
-
频率(F)
-
-
-
- {user.rfmScore?.monetary ?? "-"} -
-
金额(M)
-
-
-
- -
-
-
- ¥{user.totalSpent ?? "-"} -
-
总消费
-
-
-
- {user.interactionCount ?? "-"} -
-
互动次数
-
-
-
- {user.conversionRate ?? "-"} -
-
转化率
-
-
-
- {user.status === "failed" - ? "添加失败" - : user.status === "added" - ? "添加成功" - : "未添加"} -
-
添加状态
-
-
-
- - )} - {activeTab === "journey" && ( - - {user.interactions && user.interactions.length > 0 ? ( - user.interactions.slice(0, 4).map(it => ( -
-
- {it.type === "click" && "📱"} - {it.type === "message" && "💬"} - {it.type === "purchase" && "💲"} - {it.type === "view" && "👁️"} -
-
-
- {it.type === "click" && "点击行为"} - {it.type === "message" && "消息互动"} - {it.type === "purchase" && "购买行为"} - {it.type === "view" && "页面浏览"} +
+ {/* 内容区域 */} +
+ {activeTab === "basic" && ( +
+ {/* 关联信息 */} + + + 设备 + 微信号 + 客服 + 添加时间 + 最近互动 + + + + {/* RFM评分 */} + {user.rfmScore && ( + +
+
+
最近性(R)
+
+ {user.rfmScore.recency} +
-
- {it.content} - {it.type === "purchase" && it.value && ( - - ¥{it.value} - - )} +
+
频率(F)
+
+ {user.rfmScore.frequency} +
+
+
+
金额(M)
+
+ {user.rfmScore.monetary} +
+
+
+
总分
+
+ {user.rfmScore.totalScore}/15 +
-
- {it.timestamp} -
-
- )) - ) : ( -
- 暂无互动记录 -
- )} -
- )} - {activeTab === "tags" && ( - -
- {user.tags && user.tags.length > 0 ? ( - user.tags.map(tag => ( - - {tag} - - )) - ) : ( - 暂无标签 + )} + + {/* 流量池 */} + {user.trafficPools && ( + +
+
+ 当前池: + + {user.trafficPools.currentPool} + +
+
+ 可选池: + {user.trafficPools.availablePools.map((pool, index) => ( + + {pool} + + ))} +
+
+
+ )} + + {/* 统计数据 */} + +
+
+
+ ¥9561 +
+
总消费
+
+
+
+ 6 +
+
互动次数
+
+
+
+ 3% +
+
转化率
+
+
+
+ 未添加 +
+
添加状态
+
+
+
+ + {/* 好友统计 */} + +
+
+
+ {user.userInfo.friendShip.totalFriend} +
+
总好友
+
+
+
+ {user.userInfo.friendShip.maleFriend} +
+
男性好友
+
+
+
+ {user.userInfo.friendShip.femaleFriend} +
+
女性好友
+
+
+
+ {user.userInfo.friendShip.unknowFriend} +
+
未知性别
+
+
+
+ + {/* 限制记录 */} + + {user.restrictions && user.restrictions.length > 0 ? ( + + {user.restrictions.map(restriction => ( + + {restriction.reason || "未知原因"} + + {getRestrictionLevelText(restriction.level)} + +
+ } + description={ +
+ 限制ID: {restriction.id} + {restriction.date && ( + + 限制时间: {formatDate(restriction.date)} + + )} +
+ } + /> + ))} + + ) : ( +
+
+ +
+
暂无限制记录
+
+ 该用户没有任何限制记录 +
+
+ )} +
- - - )} + )} + + {activeTab === "journey" && ( +
+ + {journeyLoading && journeyList.length === 0 ? ( +
+ +
加载中...
+
+ ) : journeyList.length === 0 ? ( +
+
+ +
+
暂无互动记录
+
+ 该用户还没有任何互动行为 +
+
+ ) : ( + + {journeyList.map(record => ( + + {record.remark} + + {formatDateTime(record.createTime)} + +
+ } + /> + ))} + {journeyLoading && journeyList.length > 0 && ( +
+ + 加载更多... +
+ )} + {!journeyLoading && journeyList.length < journeyTotal && ( +
+ +
+ )} + + )} + +
+ )} + + {activeTab === "tags" && ( +
+ {/* 用户标签 */} + + {tagsLoading && userTagsList.length === 0 ? ( +
+ +
加载中...
+
+ ) : userTagsList.length === 0 ? ( +
+
+ +
+
暂无用户标签
+
该用户还没有任何标签
+
+ ) : ( +
+ {userTagsList.map((tag, index) => ( + + {tag.name} + + ))} +
+ )} +
+ + {/* 价值标签 */} + + {user.valueTags && user.valueTags.length > 0 ? ( +
+ {user.valueTags.map(tag => ( +
+
+ + {tag.icon === "crown" && } + {tag.name} + + + RFM总分: {tag.rfmScore}/15 + +
+
+ + 价值等级: + + + {tag.valueLevel} + +
+
+ ))} +
+ ) : ( +
+
+ +
+
暂无价值标签
+
+ 该用户还没有任何价值标签 +
+
+ )} +
+ + {/* 添加新标签按钮 */} + +
+ )} +
); diff --git a/nkebao/src/pages/mobile/mine/traffic-pool/list/index.tsx b/nkebao/src/pages/mobile/mine/traffic-pool/list/index.tsx index a802394d9..7e0005240 100644 --- a/nkebao/src/pages/mobile/mine/traffic-pool/list/index.tsx +++ b/nkebao/src/pages/mobile/mine/traffic-pool/list/index.tsx @@ -192,7 +192,7 @@ const TrafficPoolList: React.FC = () => { className={styles.card} style={{ cursor: "pointer" }} onClick={() => - navigate(`/traffic-pool/detail/${item.sourceId}`) + navigate(`/traffic-pool/detail/${item.sourceId}/${item.id}`) } >
diff --git a/nkebao/src/router/module/mine.tsx b/nkebao/src/router/module/mine.tsx index 7a190068b..46e852e8b 100644 --- a/nkebao/src/router/module/mine.tsx +++ b/nkebao/src/router/module/mine.tsx @@ -29,7 +29,7 @@ const routes = [ auth: true, }, { - path: "/traffic-pool/detail/:id", + path: "/traffic-pool/detail/:wxid/:userId", element: , auth: true, },