From 9a0faa3a46cec934305b8b2aca1fba4a23cb7049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=B8=85=E7=88=BD?= Date: Fri, 16 May 2025 17:40:13 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=81=E5=9F=9F=E6=93=8D=E7=9B=98=E6=89=8B?= =?UTF-8?q?=20-=20=E4=BC=98=E5=8C=96=E8=B0=83=E6=95=B4=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E9=9D=A2=E7=9A=84=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cunkebao/app/devices/[id]/page.tsx | 231 +++++++++++++++++------------ 1 file changed, 135 insertions(+), 96 deletions(-) diff --git a/Cunkebao/app/devices/[id]/page.tsx b/Cunkebao/app/devices/[id]/page.tsx index 8058b7f5..51d89b4d 100644 --- a/Cunkebao/app/devices/[id]/page.tsx +++ b/Cunkebao/app/devices/[id]/page.tsx @@ -76,6 +76,7 @@ interface HandleLog { export default function DeviceDetailPage() { const params = useParams() + const deviceId = params?.id as string const router = useRouter() const [device, setDevice] = useState(null) const [activeTab, setActiveTab] = useState("info") @@ -94,12 +95,15 @@ export default function DeviceDetailPage() { aiChat: false }) const [tabChangeLoading, setTabChangeLoading] = useState(false) + const [accountPage, setAccountPage] = useState(1) + const [hasMoreAccounts, setHasMoreAccounts] = useState(true) + const accountsPerPage = 10 + const accountsEndRef = useRef(null) // 添加登录检查 useEffect(() => { const token = localStorage.getItem('token') if (!token) { - // 如果没有token,重定向到登录页面,并携带当前页面URL作为回调 const currentPath = window.location.pathname + window.location.search router.push(`/login?redirect=${encodeURIComponent(currentPath)}`) return @@ -107,12 +111,12 @@ export default function DeviceDetailPage() { }, [router]) useEffect(() => { - if (!params.id) return + if (!deviceId) return const fetchDevice = async () => { try { setLoading(true) - const response = await fetchDeviceDetail(params.id as string) + const response = await fetchDeviceDetail(deviceId) if (response && response.code === 200 && response.data) { const serverData = response.data @@ -140,7 +144,6 @@ export default function DeviceDetailPage() { // 解析features if (serverData.features) { - // 如果后端直接返回了features对象,使用它 formattedDevice.features = { autoAddFriend: Boolean(serverData.features.autoAddFriend), autoReply: Boolean(serverData.features.autoReply), @@ -149,7 +152,6 @@ export default function DeviceDetailPage() { } } else if (serverData.taskConfig) { try { - // 解析taskConfig字段 const taskConfig = JSON.parse(serverData.taskConfig || '{}'); if (taskConfig) { @@ -165,57 +167,33 @@ export default function DeviceDetailPage() { } } - // 如果有微信账号信息,构建微信账号对象 - if (serverData.wechatId) { - formattedDevice.wechatAccounts = [ - { - id: serverData.wechatId?.toString() || "1", - avatar: "/placeholder.svg", // 默认头像 - nickname: serverData.memo || "微信账号", - wechatId: serverData.imei || "", - gender: 1, // 默认性别 - status: serverData.alive === 1 ? 1 : 0, - statusText: serverData.alive === 1 ? "可加友" : "已停用", - wechatAlive: serverData.alive === 1 ? 1 : 0, - wechatAliveText: serverData.alive === 1 ? "正常" : "异常", - addFriendStatus: 1, - totalFriend: serverData.totalFriend || 0, - lastActive: serverData.lastUpdateTime || new Date().toISOString() - } - ] - } - setDevice(formattedDevice) - // 如果当前激活标签是"accounts",则加载关联微信账号 + // 如果当前激活标签是"accounts",则立即加载关联微信账号 if (activeTab === "accounts") { fetchRelatedAccounts() } } else { - // 如果API返回错误,显示错误提示 toast.error("获取设备信息失败: " + ((response as any)?.msg || "未知错误")) - setLoading(false) } } catch (error) { console.error("获取设备信息失败:", error) toast.error("获取设备信息出错,请稍后重试") - setLoading(false) } finally { - // 确保loading状态被关闭 setLoading(false) } } fetchDevice() - }, [params.id, activeTab]) + }, [deviceId]) // 使用 deviceId 替代 params.id // 获取设备关联微信账号 - const fetchRelatedAccounts = async () => { - if (!params.id || accountsLoading) return + const fetchRelatedAccounts = async (page = 1) => { + if (!deviceId || accountsLoading) return try { setAccountsLoading(true) - const response = await fetchDeviceRelatedAccounts(params.id as string) + const response = await fetchDeviceRelatedAccounts(deviceId) if (response && response.code === 200 && response.data) { const accounts = response.data.accounts || [] @@ -225,21 +203,20 @@ export default function DeviceDetailPage() { if (!prev) return null return { ...prev, - wechatAccounts: accounts + // 如果是第一页,替换数据;否则追加数据 + wechatAccounts: page === 1 + ? accounts + : [...(prev.wechatAccounts || []), ...accounts] } }) - if (accounts.length > 0) { - toast.success(`成功获取${accounts.length}个关联微信账号`) - } else { - toast.info("此设备暂无关联微信账号") - } + // 判断是否还有更多数据 + setHasMoreAccounts(accounts.length === accountsPerPage) } else { - toast.error("获取关联微信账号失败") + console.error("获取关联微信账号失败") } } catch (error) { console.error("获取关联微信账号失败:", error) - toast.error("获取关联微信账号出错") } finally { setAccountsLoading(false) } @@ -247,12 +224,12 @@ export default function DeviceDetailPage() { // 获取设备操作记录 const fetchHandleLogs = async () => { - if (!params.id || logsLoading) return + if (!deviceId || logsLoading) return try { setLogsLoading(true) const response = await fetchDeviceHandleLogs( - params.id as string, + deviceId, logPage, logsPerPage ) @@ -527,6 +504,51 @@ export default function DeviceDetailPage() { return nameMap[feature] || feature } + // 加载更多账号 + const loadMoreAccounts = () => { + if (accountsLoading || !hasMoreAccounts) return + setAccountPage(prev => prev + 1) + fetchRelatedAccounts(accountPage + 1) + } + + // 监听账号列表滚动加载更多 + useEffect(() => { + if (activeTab !== "accounts") return + + const observerOptions = { + root: null, + rootMargin: '0px', + threshold: 0.1 + } + + const handleIntersect = (entries: IntersectionObserverEntry[]) => { + const [entry] = entries + if (entry.isIntersecting && hasMoreAccounts && !accountsLoading) { + loadMoreAccounts() + } + } + + const observer = new IntersectionObserver(handleIntersect, observerOptions) + + if (accountsEndRef.current) { + observer.observe(accountsEndRef.current) + } + + return () => { + if (accountsEndRef.current) { + observer.unobserve(accountsEndRef.current) + } + } + }, [activeTab, hasMoreAccounts, accountsLoading]) + + // 当切换到账号标签时重置页码 + useEffect(() => { + if (activeTab === "accounts") { + setAccountPage(1) + setHasMoreAccounts(true) + } + }, [activeTab]) + if (loading) { return (
@@ -547,7 +569,7 @@ export default function DeviceDetailPage() {
设备不存在或已被删除
- 无法加载ID为 "{params.id}" 的设备信息,请检查设备是否存在。 + 无法加载ID为 "{deviceId}" 的设备信息,请检查设备是否存在。
- + {/* 标签切换时的加载状态 */} {tabChangeLoading && (
@@ -735,14 +774,13 @@ export default function DeviceDetailPage() {
)} - {accountsLoading && ( + + {accountsLoading && !device?.wechatAccounts?.length ? (
加载微信账号中...
- )} - - {!accountsLoading && device.wechatAccounts && device.wechatAccounts.length > 0 ? ( + ) : device?.wechatAccounts && device.wechatAccounts.length > 0 ? (
{device.wechatAccounts.map((account) => (
@@ -770,22 +808,44 @@ export default function DeviceDetailPage() {
))} + + {/* 加载更多区域 */} +
+ {accountsLoading && hasMoreAccounts ? ( +
+
+ 加载更多... +
+ ) : hasMoreAccounts ? ( + + ) : device.wechatAccounts.length > 0 && ( + - 已加载全部记录 - + )} +
) : ( - !accountsLoading && ( -
-

此设备暂无关联的微信账号

- -
- ) +
+

此设备暂无关联的微信账号

+ +
)}
@@ -894,27 +954,6 @@ export default function DeviceDetailPage() { - -
- -
- - 好友总数 -
-
- {(device.totalFriend || 0).toLocaleString()} -
-
- -
- - 消息数量 -
-
- {(device.thirtyDayMsgCount || 0).toLocaleString()} -
-
-