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}
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 d8bc9af4..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 { TrafficPoolListResponse, DeviceOption } from "./data";
-import { fetchDeviceList } from "@/pages/guide/api";
// 获取流量池列表
export function fetchTrafficPoolList(params: {
@@ -11,16 +9,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);
}, []);