/** * 柜子详情页 * - 显示柜子基本信息(ID、状态) * - 按仓控板分组展示 6 个通道的状态卡片 */ import { useEffect, useState } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Card, Tag, Typography, Space, Spin, Button, Descriptions, Message, Modal, } from '@arco-design/web-react'; import { IconLeft, IconDesktop, IconCopy, IconUnlock, IconPlayArrow, IconPoweroff } from '@arco-design/web-react/icon'; import { cabinetApi, type CabinetDetail } from '@/api/devices'; /** 状态映射 */ const STATUS_MAP: Record = { 0: { label: '空闲', color: 'green' }, 1: { label: '充电中', color: 'blue' }, 2: { label: '故障', color: 'red' }, 3: { label: '禁用', color: 'orange' }, }; /** 柜子状态映射 */ const CABINET_STATUS_MAP: Record = { 0: { label: '离线', color: 'red' }, 1: { label: '在线', color: 'green' }, 2: { label: '充电中', color: 'blue' }, 3: { label: '故障', color: 'red' }, }; export default function CabinetDetail() { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const [loading, setLoading] = useState(true); const [detail, setDetail] = useState(null); const [powLoading, setPowLoading] = useState(false); const [doorLoading, setDoorLoading] = useState(false); /** 复制到剪贴板 */ const copyText = (text: string, label: string) => { navigator.clipboard.writeText(text).then( () => Message.success(`${label} 已复制`), () => Message.error('复制失败'), ); }; useEffect(() => { if (!id) return; setLoading(true); cabinetApi .getDetail(Number(id)) .then((res) => setDetail(res.data)) .catch(() => { // 如果详情接口不可用,显示提示 }) .finally(() => setLoading(false)); }, [id]); /** 开门 */ const handleOpenDoor = async () => { if (!detail) return; setDoorLoading(true); try { const firstComp = detail.cabin_boards[0]?.compartments[0]; if (!firstComp) { Message.warning('没有可用的仓体'); return; } await cabinetApi.openDoor(firstComp.id); Message.success('开门指令已发送'); } catch { Message.error('开门失败'); } finally { setDoorLoading(false); } }; /** 接触器合闸 */ const handlePowOn = () => { if (!id) return; Modal.confirm({ title: '确认操作', content: '确定要合闸恢复380V供电吗?', onOk: async () => { setPowLoading(true); try { await cabinetApi.powOn(Number(id)); Message.success('合闸指令已发送'); // 刷新详情 const res = await cabinetApi.getDetail(Number(id)); setDetail(res.data); } catch { Message.error('操作失败'); } finally { setPowLoading(false); } }, }); }; /** 接触器分闸 */ const handlePowOff = () => { if (!id) return; Modal.confirm({ title: '确认操作', content: '确定要分闸切断380V供电吗?', onOk: async () => { setPowLoading(true); try { await cabinetApi.powOff(Number(id)); Message.success('分闸指令已发送'); // 刷新详情 const res = await cabinetApi.getDetail(Number(id)); setDetail(res.data); } catch { Message.error('操作失败'); } finally { setPowLoading(false); } }, }); }; if (loading) { return (
); } if (!detail) { return ( 柜子不存在或加载失败 ); } const cabStatus = CABINET_STATUS_MAP[detail.status] || { label: '未知', color: 'gray' }; return (
{/* 顶部导航 */}
柜子 {detail.abstract_id} {cabStatus.label}
{/* 柜子信息 */} } > {detail.abstract_id} copyText(detail.abstract_id!, '抽象ID')} /> }, { label: 'IMEI', value: <>{detail.imei} copyText(detail.imei, 'IMEI')} /> }, { label: 'ICCID', value: <>{detail.iccid || '-'} {detail.iccid && copyText(detail.iccid!, 'ICCID')} />} }, { label: '名称', value: detail.name || '-' }, { label: '状态', value: {cabStatus.label} }, { label: 'RSSI', value: detail.rssi != null ? String(detail.rssi) : '-' }, { label: '直流供电', value: detail.pow_fail_dc === true ? 断电 : detail.pow_fail_dc === false ? 正常 : '-' }, { label: '交流供电', value: detail.pow_fail_ac === true ? 断电 : detail.pow_fail_ac === false ? 正常 : '-' }, { label: '地址', value: detail.address || '-' }, ]} column={3} layout="horizontal" labelStyle={{ paddingRight: 36 }} /> {/* 仓控板列表 */} {detail.cabin_boards.map((board) => ( copyText(`${detail.imei}-${board.board_id}`, '仓板ID')} />} size="small" >
{board.compartments.map((comp) => { const st = STATUS_MAP[comp.status] || { label: '未知', color: 'gray' }; const c = comp as any; return (
{detail.imei}-{board.board_id}-{comp.channel_id} { e.stopPropagation(); copyText(`${detail.imei}-${board.board_id}-${comp.channel_id}`, '通道号'); }} /> {st.label}
{c.voltage ?? '-'}mV {c.current ?? '-'}mA {c.power ?? '-'}W {c.soc != null && {c.soc}%} {c.battery_id && {c.battery_id}}
); })}
))}
); }