'use client'; import React, { useState, useEffect, useCallback } from 'react'; import { useAuth } from '@/contexts/AuthContext'; import { useRouter } from 'next/navigation'; import Link from 'next/link'; import LoadingSpinner from '@/components/LoadingSpinner'; import { api, BaseResponse } from '@/utils/axios'; import { FiZap, FiClock, FiAlertCircle, FiCheckCircle, FiPower, FiArrowLeft, FiInfo } from 'react-icons/fi'; // 与 dashboard/page.tsx 类似的活动会话接口,可能需要根据后端VO调整 interface ActiveChargingSession { id: number; spotUidSnapshot: string | null; robotUidSnapshot?: string | null; chargeStartTime: string | null; // ISO String Date status: string; // 根据需要可以从后端 ChargingSessionVO 添加更多字段 // e.g., energyConsumedKwh, cost (though these might be final values) } const POLLING_INTERVAL = 5000; // 5 seconds for polling // 定义终止状态常量,用于组件内多处使用 const TERMINAL_STATUSES = ['COMPLETED', 'PAID', 'CANCELLED_BY_USER', 'CANCELLED_BY_SYSTEM', 'ERROR', 'ROBOT_TASK_TIMEOUT']; export default function ChargingStatusPage() { const { isAuthenticated, isLoading: authLoading } = useAuth(); const router = useRouter(); const [session, setSession] = useState(undefined); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [isStopping, setIsStopping] = useState(false); const [elapsedTime, setElapsedTime] = useState("00:00:00"); const fetchActiveSession = useCallback(async () => { if (!isAuthenticated) return; try { const response = await api.get>('/session/my/active'); console.log('Active charging session response:', response.data); if (response.data && response.data.code === 0) { const activeSessionData = response.data.data; setSession(activeSessionData); setError(null); if (activeSessionData) { console.log('Current session status:', activeSessionData.status); if (TERMINAL_STATUSES.includes(activeSessionData.status)) { setTimeout(() => router.push('/dashboard'), 3000); } } else { console.log('No active charging session found'); } } else { setError(response.data?.message || '获取充电状态失败'); } } catch (err: any) { console.error("Error fetching active session:", err); setError(err.response?.data?.message || err.message || '网络错误,无法获取充电状态'); } finally { setIsLoading(false); } }, [isAuthenticated, router]); useEffect(() => { if (!authLoading && !isAuthenticated) { router.replace('/login'); return; } if (isAuthenticated) { setIsLoading(true); fetchActiveSession(); } }, [authLoading, isAuthenticated, router, fetchActiveSession]); useEffect(() => { let intervalId: NodeJS.Timeout; if (isAuthenticated && session && !isLoading) { if (session && !TERMINAL_STATUSES.includes(session.status)) { intervalId = setInterval(fetchActiveSession, POLLING_INTERVAL); } } return () => clearInterval(intervalId); }, [isAuthenticated, session, isLoading, fetchActiveSession]); const calculateDuration = useCallback((startTime: string | null): string => { if (!startTime) return '00:00:00'; const start = new Date(startTime).getTime(); const now = Date.now(); if (now < start) return '00:00:00'; let diff = Math.floor((now - start) / 1000); const hours = String(Math.floor(diff / 3600)).padStart(2, '0'); diff %= 3600; const minutes = String(Math.floor(diff / 60)).padStart(2, '0'); const seconds = String(diff % 60).padStart(2, '0'); return `${hours}:${minutes}:${seconds}`; }, []); useEffect(() => { let timerId: NodeJS.Timeout; if (session && session.chargeStartTime && (session.status === 'CHARGING_STARTED' || session.status === 'CHARGING_IN_PROGRESS')) { setElapsedTime(calculateDuration(session.chargeStartTime)); // Initial calculation timerId = setInterval(() => { setElapsedTime(calculateDuration(session.chargeStartTime)); }, 1000); } else if (session && session.chargeStartTime) { setElapsedTime(calculateDuration(session.chargeStartTime)); // Calculate final duration once if session ended } else { setElapsedTime('00:00:00'); } return () => clearInterval(timerId); }, [session, calculateDuration]); const handleStopCharging = async () => { if (!session || !session.id) { setError("无法停止充电:无效的会话信息。"); return; } setIsStopping(true); setError(null); try { const response = await api.post>(`/session/stop`, { sessionId: session.id }); if (response.data && response.data.code === 0) { // Rely on polling to update the session state // Optionally, trigger an immediate refresh: fetchActiveSession(); } else { setError(response.data?.message || "停止充电请求失败"); } } catch (err: any) { console.error("Error stopping charging session:", err); setError(err.response?.data?.message || err.message || "停止充电时发生错误"); } setIsStopping(false); }; if (authLoading || (isLoading && session === undefined)) { return ; } if (!isAuthenticated) { return
请先登录。
; } return (

充电状态

{error && (

{error}

)} {session === null && !error && (

无活动充电会话

您当前没有正在进行的充电。是否要开始新的充电?

前往充电
)} {session && (

会话ID: {session.id}

状态: {session.status}

车位编号

{session.spotUidSnapshot || 'N/A'}

机器人编号

{session.robotUidSnapshot || 'N/A'}

开始时间

{session.chargeStartTime ? new Date(session.chargeStartTime).toLocaleString() : '等待开始'}

已充电时长

{elapsedTime}

充电进度 (基于时间)

充电电量将根据总充电时间计算。

{/* 根据会话状态显示不同的内容 */} {(session.status === 'CHARGING_STARTED' || session.status === 'CHARGING_IN_PROGRESS' || session.status === 'ROBOT_ARRIVED' || session.status === 'ROBOT_ASSIGNED') ? ( // 显示停止充电按钮 ) : ( // 会话状态不适合显示停止按钮,显示原因
当前会话状态为 {session.status},无法执行停止充电操作。 {TERMINAL_STATUSES.includes(session.status) && " 会话已结束或处于终止状态。"}
)} {(session.status === 'COMPLETED' || session.status === 'PAID' || session.status === 'PAYMENT_PENDING') && (

充电已完成或等待支付。

感谢您的使用!

查看充电记录
)}
)}
); }