From f574c56bf8f0ea4e50ad91911ee312a43c2587ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=AC=94=E8=AE=B0=E6=9C=AC=E9=87=8C=E7=9A=84=E6=B0=B8?= =?UTF-8?q?=E5=B9=B3?= Date: Mon, 21 Jul 2025 14:05:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9C=AC=E6=AC=A1=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=86=85=E5=AE=B9=E5=A6=82=E4=B8=8B=20?= =?UTF-8?q?=E9=A6=96=E9=A1=B5=E6=A0=B7=E5=BC=8F=E5=A4=8D=E5=8E=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nkebao/src/pages/home/index.module.scss | 169 +++++++++++---- nkebao/src/pages/home/index.tsx | 266 +++++++++++------------- 2 files changed, 256 insertions(+), 179 deletions(-) diff --git a/nkebao/src/pages/home/index.module.scss b/nkebao/src/pages/home/index.module.scss index 5ead01a4..bd72ec6a 100644 --- a/nkebao/src/pages/home/index.module.scss +++ b/nkebao/src/pages/home/index.module.scss @@ -1,12 +1,20 @@ .home-page { padding: 12px; + background: #f8f6f3; + min-height: 100vh; +} +.content-wrapper { + padding: 12px; + display: flex; + flex-direction: column; + gap: 12px; } // 导航栏样式 .nav-title { display: flex; - align-items: center; + width: 100%; justify-content: center; } @@ -17,58 +25,133 @@ text-shadow: 0 2px 4px rgba(24, 142, 238, 0.2); } +.nav-right { + display: flex; + align-items: center; + gap: 8px; +} + +.error-tip { + font-size: 12px; + color: #f97316; + background: #fef3c7; + padding: 4px 8px; + border-radius: 4px; + margin-right: 8px; +} + +.nav-button { + padding: 8px; + border-radius: 50%; + border: none; + background: transparent; + cursor: pointer; + transition: background-color 0.2s; + + &:hover { + background: #f3f4f6; + } +} + // 统计卡片网格 .stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); - gap: 8px; + gap: 12px; margin-bottom: 16px; } .stat-card { background: white; - border-radius: 12px; - padding: 12px 8px; + border-radius: 8px; + padding: 12px; display: flex; - align-items: center; + flex-direction: column; gap: 8px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); + cursor: pointer; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); transition: all 0.3s ease; &:hover { transform: translateY(-1px); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); } } -.stat-icon { - width: 32px; - height: 32px; - border-radius: 8px; - background: rgba(24, 142, 238, 0.1); - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; -} - -.stat-content { - flex: 1; - min-width: 0; +.stat-label { + font-size: 16px; + color: #666; + line-height: 1.2; + font-weight: bold; } .stat-value { - font-size: 18px; + font-size: 20px; font-weight: 700; - color: var(--primary-color); + color: #3b82f6; line-height: 1.2; + display: flex; + align-items: center; + justify-content: space-between; } -.stat-label { - font-size: 11px; - color: #666; - margin-top: 2px; - line-height: 1.2; +.progress-bar { + height: 4px; + background: #e5e7eb; + border-radius: 2px; + margin-top: 8px; + overflow: hidden; +} + +.progress-fill { + height: 100%; + background: #3b82f6; + border-radius: 2px; + transition: width 0.3s ease; +} + +// Loading状态样式 +.stat-card { + .stat-label:empty::before { + content: ''; + display: block; + width: 60px; + height: 12px; + background: #f0f0f0; + border-radius: 2px; + animation: pulse 1.5s ease-in-out infinite; + } + + .stat-value { + span:empty::before { + content: ''; + display: block; + width: 40px; + height: 20px; + background: #f0f0f0; + border-radius: 2px; + animation: pulse 1.5s ease-in-out infinite; + } + + div:empty::before { + content: ''; + display: block; + width: 20px; + height: 20px; + background: #f0f0f0; + border-radius: 4px; + animation: pulse 1.5s ease-in-out infinite; + } + } +} + +@keyframes pulse { + 0%, 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } } // 通用区域样式 @@ -157,37 +240,47 @@ // 今日数据网格 .today-grid { display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 8px; + grid-template-columns: repeat(2, 1fr); + gap: 12px; } .today-item { - text-align: center; - padding: 8px 4px; - background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); + display: flex; + align-items: center; + gap: 12px; + padding: 12px; + background: #f8fafc; border-radius: 8px; transition: all 0.3s ease; + cursor: pointer; &:hover { + background: #f1f5f9; transform: translateY(-1px); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } } .today-icon { - margin-bottom: 4px; - opacity: 0.8; + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + background: white; + border-radius: 50%; + flex-shrink: 0; } .today-value { - font-size: 14px; + font-size: 18px; font-weight: 700; - margin-bottom: 2px; + color: #333; line-height: 1.2; } .today-label { - font-size: 10px; + font-size: 12px; color: #666; line-height: 1.2; } diff --git a/nkebao/src/pages/home/index.tsx b/nkebao/src/pages/home/index.tsx index 3ac3b164..a72b4dc2 100644 --- a/nkebao/src/pages/home/index.tsx +++ b/nkebao/src/pages/home/index.tsx @@ -1,21 +1,17 @@ import React, { useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; import { NavBar } from "antd-mobile"; import { - AppOutline, - UserOutline, - ClockCircleOutline, - SendOutline, - StarOutline, - Bell, - Smartphone, - Users, - Activity, - MessageSquare, - TrendingUp, -} from "antd-mobile-icons"; + BellOutlined, + MobileOutlined, + UserOutlined, + MessageOutlined, + TeamOutlined, + RiseOutlined, + LineChartOutlined, +} from "@ant-design/icons"; import MeauMobile from "@/components/MeauMobile/MeauMoible"; import Layout from "@/components/Layout/Layout"; -import style from "./index.module.scss"; import LineChart from "@/components/LineChart"; import { getPlanStats, @@ -23,19 +19,39 @@ import { getTodayStats, getDashboard, } from "./api"; +import style from "./index.module.scss"; + +interface DashboardData { + deviceNum?: number; + wechatNum?: number; + aliveWechatNum?: number; +} + +interface TodayStatsData { + momentsNum?: number; + groupPushNum?: number; + passRate?: string; + sysActive?: string; +} + +interface SevenDayStatsData { + date?: string[]; + allNum?: number[]; +} const Home: React.FC = () => { + const navigate = useNavigate(); const [sceneStats, setSceneStats] = useState([]); const [todayStats, setTodayStats] = useState([]); - const [dashboard, setDashboard] = useState({}); - const [sevenDayStats, setSevenDayStats] = useState({}); + const [dashboard, setDashboard] = useState({}); + const [sevenDayStats, setSevenDayStats] = useState({}); const [isLoading, setIsLoading] = useState(true); const [apiError, setApiError] = useState(""); // 场景获客数据 const scenarioFeatures = [ { - id: "douyin", + id: "3", name: "抖音获客", icon: "https://hebbkx1anhila5yf.public.blob.vercel-storage.com/image-QR8ManuDplYTySUJsY4mymiZkDYnQ9.png", color: "bg-blue-100 text-blue-600", @@ -43,7 +59,7 @@ const Home: React.FC = () => { growth: 12, }, { - id: "xiaohongshu", + id: "4", name: "小红书获客", icon: "https://hebbkx1anhila5yf.public.blob.vercel-storage.com/image-yvnMxpoBUzcvEkr8DfvHgPHEo1kmQ3.png", color: "bg-red-100 text-red-600", @@ -51,7 +67,7 @@ const Home: React.FC = () => { growth: 8, }, { - id: "gongzhonghao", + id: "6", name: "公众号获客", icon: "https://hebbkx1anhila5yf.public.blob.vercel-storage.com/image-Gsg0CMf5tsZb41mioszdjqU1WmsRxW.png", color: "bg-green-100 text-green-600", @@ -59,7 +75,7 @@ const Home: React.FC = () => { growth: 15, }, { - id: "haibao", + id: "1", name: "海报获客", icon: "https://hebbkx1anhila5yf.public.blob.vercel-storage.com/image-x92XJgXy4MI7moNYlA1EAes2FqDxMH.png", color: "bg-orange-100 text-orange-600", @@ -73,28 +89,28 @@ const Home: React.FC = () => { { title: "朋友圈同步", value: "12", - icon: , + icon: , color: "text-purple-600", path: "/workspace/moments-sync", }, { title: "群发任务", value: "8", - icon: , + icon: , color: "text-orange-600", path: "/workspace/group-push", }, { title: "获客转化", value: "85%", - icon: , + icon: , color: "text-green-600", path: "/scenarios", }, { title: "系统活跃度", value: "98%", - icon: , + icon: , color: "text-blue-600", path: "/workspace", }, @@ -142,35 +158,31 @@ const Home: React.FC = () => { const todayStatsData = [ { label: "同步朋友圈", - value: todayResult.value.momentsNum, + value: todayResult.value?.momentsNum || 0, icon: ( - + ), - color: "#ff6b35", + color: "#8b5cf6", }, { label: "群发任务", - value: todayResult.value.groupPushNum, - icon: , - color: "#ffd700", + value: todayResult.value?.groupPushNum || 0, + icon: , + color: "#f97316", }, { label: "获客转化率", - value: todayResult.value.passRate, - icon: , - color: "#4caf50", + value: todayResult.value?.passRate || "0%", + icon: , + color: "#22c55e", }, { label: "系统活跃度", - value: todayResult.value.sysActive, + value: todayResult.value?.sysActive || "0%", icon: ( - + ), - color: "#2196f3", + color: "#3b82f6", }, ]; setTodayStats(todayStatsData); @@ -189,13 +201,11 @@ const Home: React.FC = () => { }, []); const handleDevicesClick = () => { - // 导航到设备页面 - console.log("点击设备"); + navigate("/devices"); }; const handleWechatClick = () => { - // 导航到微信号页面 - console.log("点击微信号"); + navigate("/wechat-accounts"); }; if (isLoading) { @@ -211,13 +221,16 @@ const Home: React.FC = () => { footer={} loading={true} > -
-
-
+
+
+
{[...Array(3)].map((_, i) => ( -
-
-
+
+
+
+ +
+
))}
@@ -233,132 +246,103 @@ const Home: React.FC = () => {
存客宝 -
- {apiError && ( -
- API连接异常,显示默认数据 -
- )} - -
} footer={} > -
-
+
+
{/* 统计卡片 */} -
-
-
-
- 设备数量 -
- - {dashboard.deviceNum || 42} - - -
-
-
+
+
+
设备数量
+
+ {dashboard.deviceNum || 42} +
-
-
-
- 微信号数量 -
- - {dashboard.wechatNum || 42} - - -
-
-
+
+
微信号数量
+
+ {dashboard.wechatNum || 42} +
-
-
- 在线微信号 -
- - {dashboard.aliveWechatNum || 35} - - -
-
-
0 - ? (dashboard.aliveWechatNum / dashboard.wechatNum) * - 100 - : 0 - }%`, - }} - >
-
+
+
在线微信号
+
+ {dashboard.aliveWechatNum || 35} + +
+
+
0 + ? ((dashboard.aliveWechatNum || 0) / + (dashboard.wechatNum || 1)) * + 100 + : 0 + }%`, + }} + >
{/* 场景获客统计 */} -
-
-

场景获客统计

+
+
+

场景获客统计

-
+
{scenarioFeatures .sort((a, b) => b.value - a.value) .slice(0, 4) // 只显示前4个 .map((scenario) => (
+ navigate( + `/scenarios/list/${scenario.id}/${encodeURIComponent( + scenario.name + )}` + ) + } > -
-
- {scenario.name} -
-
- {scenario.value} -
-
- {scenario.name} -
+
+ {scenario.name}
+
{scenario.value}
+
{scenario.name}
))}
{/* 今日数据统计 */} -
-
-

今日数据

+
+
+

今日数据

-
+
{todayStatsData.map((stat, index) => (
stat.path && navigate(stat.path)} > -
- {stat.icon} -
+
{stat.icon}
-
{stat.value}
-
{stat.title}
+
{stat.value}
+
{stat.title}
))} @@ -372,8 +356,8 @@ const Home: React.FC = () => {