From c29fbd1bbbea97b322f88589f1b156e8c2860f1c 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, 7 Jul 2025 14:29:28 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=84=E7=90=86=E8=AF=AD=E6=B3=95?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nkebao/src/contexts/AuthContext.tsx | 32 +- nkebao/src/pages/devices/DeviceDetail.tsx | 12 +- nkebao/src/pages/devices/Devices.tsx | 3 +- nkebao/src/pages/login/Login.tsx | 4 +- nkebao/src/pages/scenarios/NewPlan.tsx | 6 +- nkebao/src/pages/scenarios/ScenarioDetail.tsx | 1 - .../gongzhonghao/GongzhonghaoScenario.tsx | 2 +- .../wechat-accounts/WechatAccountDetail.tsx | 7 +- .../pages/wechat-accounts/WechatAccounts.tsx | 7 +- .../workspace/moments-sync/MomentsSync.tsx | 4 +- nkebao/yarn.lock | 11850 ++++++++++++++++ 11 files changed, 11884 insertions(+), 44 deletions(-) create mode 100644 nkebao/yarn.lock diff --git a/nkebao/src/contexts/AuthContext.tsx b/nkebao/src/contexts/AuthContext.tsx index b0f6da915..b99de779d 100644 --- a/nkebao/src/contexts/AuthContext.tsx +++ b/nkebao/src/contexts/AuthContext.tsx @@ -65,6 +65,21 @@ export function AuthProvider({ children }: AuthProviderProps) { const [isInitialized, setIsInitialized] = useState(false); const navigate = useNavigate(); + // 先声明handleLogout,避免useEffect依赖提前引用 + const handleLogout = () => { + // 先清除所有认证相关的状态 + safeLocalStorage.removeItem("token"); + safeLocalStorage.removeItem("token_expired"); + safeLocalStorage.removeItem("s2_accountId"); + safeLocalStorage.removeItem("userInfo"); + safeLocalStorage.removeItem("user"); + setToken(null); + setUser(null); + setIsAuthenticated(false); + // 跳转到登录页面 + navigate('/login'); + }; + // 检查token是否过期 const isTokenExpired = (): boolean => { const tokenExpired = safeLocalStorage.getItem("token_expired"); @@ -184,22 +199,7 @@ export function AuthProvider({ children }: AuthProviderProps) { }, 60000); // 每分钟检查一次 return () => clearInterval(checkTokenInterval); - }, [isAuthenticated]); - - const handleLogout = () => { - // 先清除所有认证相关的状态 - safeLocalStorage.removeItem("token"); - safeLocalStorage.removeItem("token_expired"); - safeLocalStorage.removeItem("s2_accountId"); - safeLocalStorage.removeItem("userInfo"); - safeLocalStorage.removeItem("user"); - setToken(null); - setUser(null); - setIsAuthenticated(false); - - // 跳转到登录页面 - navigate('/login'); - }; + }, [isAuthenticated, handleLogout]); const login = (newToken: string, userData: User) => { safeLocalStorage.setItem("token", newToken); diff --git a/nkebao/src/pages/devices/DeviceDetail.tsx b/nkebao/src/pages/devices/DeviceDetail.tsx index e0e69859e..48cb55daf 100644 --- a/nkebao/src/pages/devices/DeviceDetail.tsx +++ b/nkebao/src/pages/devices/DeviceDetail.tsx @@ -1,9 +1,9 @@ -import React, { useState, useEffect, useRef, useCallback } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { useParams } from 'react-router-dom'; import PageHeader from '@/components/PageHeader'; import BackButton from '@/components/BackButton'; import { useSimpleBack } from '@/hooks/useBackNavigation'; -import { ChevronLeft, Smartphone, Battery, Wifi, MessageCircle, Users, Settings, History, RefreshCw, Loader2 } from 'lucide-react'; +import { Smartphone, Battery, Wifi, MessageCircle, Users, Settings, History, RefreshCw, Loader2 } from 'lucide-react'; import { devicesApi, fetchDeviceDetail, fetchDeviceRelatedAccounts, fetchDeviceHandleLogs, updateDeviceTaskConfig } from '@/api/devices'; import { useToast } from '@/components/ui/toast'; @@ -73,7 +73,7 @@ export default function DeviceDetail() { momentsSync: false, aiChat: false }); - const [tabChangeLoading, setTabChangeLoading] = useState(false); + const [accountPage, setAccountPage] = useState(1); const [hasMoreAccounts, setHasMoreAccounts] = useState(true); const accountsPerPage = 10; @@ -277,7 +277,7 @@ export default function DeviceDetail() { return () => { observer.disconnect(); }; - }, [hasMoreLogs, logsLoading]); + }, [hasMoreLogs, logsLoading, loadMoreLogs]); // 获取任务配置 const fetchTaskConfig = async () => { @@ -305,7 +305,6 @@ export default function DeviceDetail() { // 标签页切换处理 const handleTabChange = (value: string) => { setActiveTab(value); - setTabChangeLoading(true); setTimeout(() => { if (value === "accounts" && device && (!device.wechatAccounts || device.wechatAccounts.length === 0)) { @@ -315,7 +314,6 @@ export default function DeviceDetail() { setHasMoreLogs(true); fetchHandleLogs(); } - setTabChangeLoading(false); }, 100); }; @@ -421,7 +419,7 @@ export default function DeviceDetail() { return () => { observer.disconnect(); }; - }, [hasMoreAccounts, accountsLoading]); + }, [hasMoreAccounts, accountsLoading, loadMoreAccounts]); if (loading) { return ( diff --git a/nkebao/src/pages/devices/Devices.tsx b/nkebao/src/pages/devices/Devices.tsx index 1fe3a9565..d6300f294 100644 --- a/nkebao/src/pages/devices/Devices.tsx +++ b/nkebao/src/pages/devices/Devices.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useRef, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; -import { Plus, Search, RefreshCw, QrCode, Smartphone, Loader2, AlertTriangle, Trash2, X } from 'lucide-react'; +import { Plus, Search, RefreshCw, QrCode, Loader2, AlertTriangle, X } from 'lucide-react'; import { devicesApi } from '@/api'; import { useToast } from '@/components/ui/toast'; import PageHeader from '@/components/PageHeader'; @@ -27,6 +27,7 @@ export default function Devices() { }); const [searchQuery, setSearchQuery] = useState(""); const [statusFilter, setStatusFilter] = useState("all"); + // 恢复分页功能 const [currentPage, setCurrentPage] = useState(1); const [selectedDeviceId, setSelectedDeviceId] = useState(null); const [isLoading, setIsLoading] = useState(false); diff --git a/nkebao/src/pages/login/Login.tsx b/nkebao/src/pages/login/Login.tsx index 14f23cd94..c985b9bb0 100644 --- a/nkebao/src/pages/login/Login.tsx +++ b/nkebao/src/pages/login/Login.tsx @@ -374,9 +374,9 @@ export default function Login() { className="text-sm text-gray-600 leading-relaxed cursor-pointer" > 我已阅读并同意 - 《存客宝用户协议》 + 和 - 《隐私政策》 + diff --git a/nkebao/src/pages/scenarios/NewPlan.tsx b/nkebao/src/pages/scenarios/NewPlan.tsx index 680e7374b..50ee4cca3 100644 --- a/nkebao/src/pages/scenarios/NewPlan.tsx +++ b/nkebao/src/pages/scenarios/NewPlan.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; import { useNavigate, useSearchParams } from 'react-router-dom'; import { Check, Settings } from 'lucide-react'; import PageHeader from '@/components/PageHeader'; @@ -71,7 +71,7 @@ export default function NewPlan() { const { toast } = useToast(); const [currentStep, setCurrentStep] = useState(1); const [loading, setLoading] = useState(false); - const [loadingScenes, setLoadingScenes] = useState(false); + const [formData, setFormData] = useState({ planName: "", @@ -164,8 +164,6 @@ export default function NewPlan() { // 基础设置步骤 const BasicSettings = () => { - const selectedScenario = scenarioOptions.find(s => s.id === formData.sceneId); - return (
diff --git a/nkebao/src/pages/scenarios/ScenarioDetail.tsx b/nkebao/src/pages/scenarios/ScenarioDetail.tsx index fb6679a72..c982dbfd8 100644 --- a/nkebao/src/pages/scenarios/ScenarioDetail.tsx +++ b/nkebao/src/pages/scenarios/ScenarioDetail.tsx @@ -28,7 +28,6 @@ interface ScenarioData { export default function ScenarioDetail() { const { scenarioId } = useParams<{ scenarioId: string }>(); const navigate = useNavigate(); - const { goBack } = useSimpleBack('/scenarios'); const [scenario, setScenario] = useState(null); const [plans, setPlans] = useState([]); const [loading, setLoading] = useState(true); diff --git a/nkebao/src/pages/scenarios/gongzhonghao/GongzhonghaoScenario.tsx b/nkebao/src/pages/scenarios/gongzhonghao/GongzhonghaoScenario.tsx index 230c6d02d..9098b0c0c 100644 --- a/nkebao/src/pages/scenarios/gongzhonghao/GongzhonghaoScenario.tsx +++ b/nkebao/src/pages/scenarios/gongzhonghao/GongzhonghaoScenario.tsx @@ -81,7 +81,7 @@ export default function GongzhonghaoScenario() { setError(""); fetchPlanList(channel, page, pageSize) .then((res) => { - if (res.code === 200 && Array.isArray(res.data?.list)) { + if (res.code === 200 && res.data && Array.isArray(res.data.list)) { setTasks(res.data.list); setTotal(res.data.total || 0); } else { diff --git a/nkebao/src/pages/wechat-accounts/WechatAccountDetail.tsx b/nkebao/src/pages/wechat-accounts/WechatAccountDetail.tsx index 14782d55a..9afb5cc66 100644 --- a/nkebao/src/pages/wechat-accounts/WechatAccountDetail.tsx +++ b/nkebao/src/pages/wechat-accounts/WechatAccountDetail.tsx @@ -12,12 +12,8 @@ import { Info, UserPlus, Search, - Filter, - Tag, ChevronRight, - Loader2, - AlertCircle, - ArrowRightLeft + Loader2 } from 'lucide-react'; import { useWechatAccount } from '@/contexts/WechatAccountContext'; import { fetchWechatAccountSummary, fetchWechatFriends, fetchWechatFriendDetail } from '@/api/wechat-accounts'; @@ -106,7 +102,6 @@ export default function WechatAccountDetail() { const [isFriendsEmpty, setIsFriendsEmpty] = useState(false); const friendsObserver = useRef(null); const friendsLoadingRef = useRef(null); - const friendsContainerRef = useRef(null); // 如果没有账号数据,返回上一页 useEffect(() => { diff --git a/nkebao/src/pages/wechat-accounts/WechatAccounts.tsx b/nkebao/src/pages/wechat-accounts/WechatAccounts.tsx index 1cca5b834..174b07733 100644 --- a/nkebao/src/pages/wechat-accounts/WechatAccounts.tsx +++ b/nkebao/src/pages/wechat-accounts/WechatAccounts.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useRef, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; -import { Search, RefreshCw, ArrowRightLeft, AlertCircle, Loader2 } from 'lucide-react'; +import { Search, RefreshCw, Loader2 } from 'lucide-react'; import { fetchWechatAccountList, transformWechatAccount } from '@/api/wechat-accounts'; import { useToast } from '@/components/ui/toast'; import { useWechatAccount } from '@/contexts/WechatAccountContext'; @@ -119,7 +119,6 @@ export default function WechatAccounts() { } }; - const filteredAccounts = accounts; const totalPages = Math.ceil(totalAccounts / accountsPerPage); const handleTransferFriends = (account: WechatAccount) => { @@ -259,7 +258,7 @@ export default function WechatAccounts() { handleTransferFriends(account); }} > - + {/* ArrowRightLeft className="h-4 w-4" */}
@@ -274,7 +273,7 @@ export default function WechatAccounts() { 今日可添加: {account.remainingAdds}
- + {/* AlertCircle className="h-4 w-4 text-gray-400" */}
每日最多添加 {account.maxDailyAdds} 个好友
diff --git a/nkebao/src/pages/workspace/moments-sync/MomentsSync.tsx b/nkebao/src/pages/workspace/moments-sync/MomentsSync.tsx index cd2b15404..21a79649f 100644 --- a/nkebao/src/pages/workspace/moments-sync/MomentsSync.tsx +++ b/nkebao/src/pages/workspace/moments-sync/MomentsSync.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import { useNavigate, Link } from 'react-router-dom'; -import { Plus, Filter, Search, RefreshCw, MoreVertical, Clock, Edit, Trash2, Eye, Copy } from 'lucide-react'; +import { Plus, Search, RefreshCw, MoreVertical, Clock, Edit, Trash2, Eye, Copy } from 'lucide-react'; import { Card } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; @@ -244,7 +244,7 @@ export default function MomentsSync() { />