From 75987baef87afe314670dc4ca90a8c4ab1689c1e 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: Wed, 30 Jul 2025 16:36:21 +0800 Subject: [PATCH 1/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=20=E5=BA=9F?= =?UTF-8?q?=E5=BC=83=E6=B5=81=E9=87=8F=E6=B1=A0=E4=B8=8D=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/mobile/mine/traffic-pool/list/api.ts | 12 +----------- .../pages/mobile/mine/traffic-pool/list/dataAnyx.tsx | 7 +------ 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/nkebao/src/pages/mobile/mine/traffic-pool/list/api.ts b/nkebao/src/pages/mobile/mine/traffic-pool/list/api.ts index d8bc9af4..25bbd405 100644 --- a/nkebao/src/pages/mobile/mine/traffic-pool/list/api.ts +++ b/nkebao/src/pages/mobile/mine/traffic-pool/list/api.ts @@ -1,5 +1,5 @@ import request from "@/api/request"; -import type { TrafficPoolListResponse, DeviceOption } from "./data"; +import type { DeviceOption } from "./data"; import { fetchDeviceList } from "@/pages/guide/api"; // 获取流量池列表 @@ -11,16 +11,6 @@ export function fetchTrafficPoolList(params: { return request("/v1/traffic/pool", params, "GET"); } -// 获取设备列表(真实接口) -export async function fetchDeviceOptions(): Promise { - const res = await fetchDeviceList({ page: 1, limit: 100 }); - // 假设返回 { list: [{ id, name, ... }], ... } - return (res.list || []).map((item: any) => ({ - id: String(item.id), - name: item.name, - })); -} - // 获取分组列表(如无真实接口可用mock) export async function fetchPackageOptions(): Promise { // TODO: 替换为真实接口 diff --git a/nkebao/src/pages/mobile/mine/traffic-pool/list/dataAnyx.tsx b/nkebao/src/pages/mobile/mine/traffic-pool/list/dataAnyx.tsx index 1cd11561..7a84040a 100644 --- a/nkebao/src/pages/mobile/mine/traffic-pool/list/dataAnyx.tsx +++ b/nkebao/src/pages/mobile/mine/traffic-pool/list/dataAnyx.tsx @@ -1,9 +1,5 @@ import { useState, useEffect, useMemo } from "react"; -import { - fetchTrafficPoolList, - fetchDeviceOptions, - fetchPackageOptions, -} from "./api"; +import { fetchTrafficPoolList, fetchPackageOptions } from "./api"; import type { TrafficPoolUser, DeviceOption, @@ -69,7 +65,6 @@ export function useTrafficPoolListLogic() { // 获取筛选项 useEffect(() => { - fetchDeviceOptions().then(setDeviceOptions); fetchPackageOptions().then(setPackageOptions); }, []); From 3c4d0fcb5f7bc3212302b7235e32c6cfc5c12b63 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: Wed, 30 Jul 2025 17:29:15 +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=20=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=AF=A6=E6=83=85=E6=90=9E=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nkebao/.env.development | 4 +- .../mobile/mine/devices/DeviceDetail.tsx | 35 +++++- .../mobile/mine/traffic-pool/detail/api.ts | 12 +- .../mobile/mine/traffic-pool/detail/data.ts | 76 +++++++++++++ .../traffic-pool/detail/index.module.scss | 20 +++- .../mobile/mine/traffic-pool/detail/index.tsx | 104 +++++++++--------- .../mobile/mine/traffic-pool/list/api.ts | 2 - 7 files changed, 180 insertions(+), 73 deletions(-) diff --git a/nkebao/.env.development b/nkebao/.env.development index d130c9ed..9ac98215 100644 --- a/nkebao/.env.development +++ b/nkebao/.env.development @@ -1,4 +1,4 @@ # 基础环境变量示例 -VITE_API_BASE_URL=http://www.yishi.com -# VITE_API_BASE_URL=https://ckbapi.quwanzhi.com +# VITE_API_BASE_URL=http://www.yishi.com +VITE_API_BASE_URL=https://ckbapi.quwanzhi.com VITE_APP_TITLE=Nkebao Base diff --git a/nkebao/src/pages/mobile/mine/devices/DeviceDetail.tsx b/nkebao/src/pages/mobile/mine/devices/DeviceDetail.tsx index 9a70464c..71398a96 100644 --- a/nkebao/src/pages/mobile/mine/devices/DeviceDetail.tsx +++ b/nkebao/src/pages/mobile/mine/devices/DeviceDetail.tsx @@ -1,7 +1,15 @@ import React, { useEffect, useState, useCallback, useRef } from "react"; import { useParams, useNavigate } from "react-router-dom"; -import { NavBar, Tabs, Switch, Toast, SpinLoading, Button } from "antd-mobile"; -import { SettingOutlined, RedoOutlined } from "@ant-design/icons"; +import { + NavBar, + Tabs, + Switch, + Toast, + SpinLoading, + Button, + Avatar, +} from "antd-mobile"; +import { SettingOutlined, RedoOutlined, UserOutlined } from "@ant-design/icons"; import Layout from "@/components/Layout/Layout"; import { fetchDeviceDetail, @@ -262,15 +270,32 @@ const DeviceDetail: React.FC = () => { navigate(`/wechat-accounts/detail/${acc.wechatId}`); }} > - {acc.nickname} + + + } />
{acc.nickname}
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 0a0a1e92..6d4c4b83 100644 --- a/nkebao/src/pages/mobile/mine/traffic-pool/detail/api.ts +++ b/nkebao/src/pages/mobile/mine/traffic-pool/detail/api.ts @@ -1,13 +1,7 @@ import request from "@/api/request"; -import type { - TrafficPoolUserDetail, - UserJourneyResponse, - UserTagsResponse, -} from "./data"; +import type { UserTagsResponse } from "./data"; -export function getTrafficPoolDetail( - wechatId: string, -): Promise { +export function getTrafficPoolDetail(wechatId: string) { return request("/v1/wechats/getWechatInfo", { wechatId }, "GET"); } @@ -16,7 +10,7 @@ export function getUserJourney(params: { page: number; pageSize: number; userId: string; -}): Promise { +}) { return request("/v1/traffic/pool/getUserJourney", params, "GET"); } diff --git a/nkebao/src/pages/mobile/mine/traffic-pool/detail/data.ts b/nkebao/src/pages/mobile/mine/traffic-pool/detail/data.ts index fd55131e..43615992 100644 --- a/nkebao/src/pages/mobile/mine/traffic-pool/detail/data.ts +++ b/nkebao/src/pages/mobile/mine/traffic-pool/detail/data.ts @@ -30,3 +30,79 @@ export interface TrafficPoolUserDetail { value?: number; }>; } + +// 扩展的用户详情类型 +export interface ExtendedUserDetail extends TrafficPoolUserDetail { + userInfo: { + nickname: string; + avatar: string; + wechatId: string; + friendShip: { + totalFriend: number; + maleFriend: number; + femaleFriend: number; + unknowFriend: number; + }; + }; + rfmScore: { + recency: number; + frequency: number; + monetary: number; + totalScore: number; + }; + trafficPools: { + currentPool: string; + availablePools: string[]; + }; + userTags: Array<{ + id: string; + name: string; + color: string; + type: string; + }>; + valueTags: Array<{ + id: string; + name: string; + color: string; + icon: string; + rfmScore: number; + valueLevel: string; + }>; + restrictions?: Array<{ + id: string; + reason: string; + level: number; + date: number | null; + }>; +} + +// 互动记录类型 +export interface InteractionRecord { + id: string; + type: string; + content: string; + timestamp: string; + value?: number; +} + +// 用户旅程记录类型 +export interface UserJourneyRecord { + id: string; + type: number; + remark: string; + createTime: string; +} + +// 用户标签响应类型 +export interface UserTagsResponse { + wechat: string[]; + siteLabels: UserTagItem[]; +} + +// 用户标签项类型 +export interface UserTagItem { + id: string; + name: string; + color?: string; + type?: string; +} 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 60165acb..6b896216 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 @@ -47,6 +47,18 @@ flex-shrink: 0; } + .avatarFallback { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + font-size: 24px; + border-radius: 50%; + } + .userDetails { flex: 1; min-width: 0; @@ -343,7 +355,7 @@ flex-direction: column; align-items: center; justify-content: center; - padding: 60px 16px; + padding: 20px 16px; text-align: center; } @@ -353,14 +365,14 @@ } .emptyText { - font-size: 16px; + font-size: 14px; color: #666; - margin-bottom: 8px; + margin-bottom: 4px; font-weight: 500; } .emptyDesc { - font-size: 14px; + font-size: 12px; color: #999; line-height: 1.4; } 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 88fd1c41..4c7ce51b 100644 --- a/nkebao/src/pages/mobile/mine/traffic-pool/detail/index.tsx +++ b/nkebao/src/pages/mobile/mine/traffic-pool/detail/index.tsx @@ -1,20 +1,9 @@ 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 { Card, Button, Avatar, Tag, List, SpinLoading } from "antd-mobile"; import { UserOutlined, CrownOutlined, - PlusOutlined, - CloseOutlined, EyeOutlined, DollarOutlined, MobileOutlined, @@ -26,9 +15,7 @@ import Layout from "@/components/Layout/Layout"; import NavCommon from "@/components/NavCommon"; import { getTrafficPoolDetail, getUserJourney, getUserTags } from "./api"; import type { - TrafficPoolUserDetail, ExtendedUserDetail, - InteractionRecord, UserJourneyRecord, UserTagsResponse, UserTagItem, @@ -52,6 +39,7 @@ const TrafficPoolDetail: React.FC = () => { // 用户标签相关状态 const [tagsLoading, setTagsLoading] = useState(false); const [userTagsList, setUserTagsList] = useState([]); + const [wechatTagsList, setWechatTagsList] = useState([]); useEffect(() => { if (!wxid) return; @@ -61,6 +49,8 @@ const TrafficPoolDetail: React.FC = () => { // 将API数据转换为扩展的用户详情数据 const extendedUser: ExtendedUserDetail = { ...res, + // 添加userInfo属性 + userInfo: res.userInfo, // 模拟RFM评分数据 rfmScore: { recency: 5, @@ -92,6 +82,8 @@ const TrafficPoolDetail: React.FC = () => { }, ], }; + console.log(extendedUser); + setUser(extendedUser); }) .finally(() => setLoading(false)); @@ -131,6 +123,7 @@ const TrafficPoolDetail: React.FC = () => { try { const response: UserTagsResponse = await getUserTags(userId); setUserTagsList(response.siteLabels || []); + setWechatTagsList(response.wechat || []); } catch (error) { console.error("获取用户标签失败:", error); } finally { @@ -149,10 +142,6 @@ const TrafficPoolDetail: React.FC = () => { } }; - const handleClose = () => { - navigate(-1); - }; - const getJourneyTypeIcon = (type: number) => { switch (type) { case 0: // 浏览 @@ -207,32 +196,6 @@ const TrafficPoolDetail: React.FC = () => { } }; - 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: @@ -297,7 +260,11 @@ const TrafficPoolDetail: React.FC = () => { } + fallback={ +
+ +
+ } />
{user.userInfo.nickname}
@@ -617,20 +584,22 @@ const TrafficPoolDetail: React.FC = () => { {activeTab === "tags" && (
- {/* 用户标签 */} - + {/* 站内标签 */} + {tagsLoading && userTagsList.length === 0 ? (
- +
加载中...
) : userTagsList.length === 0 ? (
- + +
+
暂无站内标签
+
+ 该用户还没有任何站内标签
-
暂无用户标签
-
该用户还没有任何标签
) : (
@@ -648,6 +617,39 @@ const TrafficPoolDetail: React.FC = () => { )} + {/* 微信标签 */} + + {tagsLoading && wechatTagsList.length === 0 ? ( +
+ +
加载中...
+
+ ) : wechatTagsList.length === 0 ? ( +
+
+ +
+
暂无微信标签
+
+ 该用户还没有任何微信标签 +
+
+ ) : ( +
+ {wechatTagsList.map((tag, index) => ( + + {tag} + + ))} +
+ )} +
+ {/* 价值标签 */} {user.valueTags && user.valueTags.length > 0 ? ( diff --git a/nkebao/src/pages/mobile/mine/traffic-pool/list/api.ts b/nkebao/src/pages/mobile/mine/traffic-pool/list/api.ts index 25bbd405..0a6162a8 100644 --- a/nkebao/src/pages/mobile/mine/traffic-pool/list/api.ts +++ b/nkebao/src/pages/mobile/mine/traffic-pool/list/api.ts @@ -1,6 +1,4 @@ import request from "@/api/request"; -import type { DeviceOption } from "./data"; -import { fetchDeviceList } from "@/pages/guide/api"; // 获取流量池列表 export function fetchTrafficPoolList(params: {