"use client"; import { useCallback, useEffect, useRef, useState } from "react"; import { Button, Chip, Input, Label, Modal, Spinner, Table, TextField } from "@heroui/react"; import { Pencil, TrashBin } from "@gravity-ui/icons"; import { api, type ChargePoint } from "@/lib/api"; const statusColorMap: Record = { Available: "success", Charging: "success", Occupied: "warning", Reserved: "warning", Faulted: "danger", Unavailable: "danger", Preparing: "warning", Finishing: "warning", SuspendedEV: "warning", SuspendedEVSE: "warning", }; const registrationColorMap: Record = { Accepted: "success", Pending: "warning", Rejected: "danger", }; export default function ChargePointsPage() { const [chargePoints, setChargePoints] = useState([]); const [editTarget, setEditTarget] = useState(null); const [feeInput, setFeeInput] = useState("0"); const [saving, setSaving] = useState(false); const [deleteTarget, setDeleteTarget] = useState(null); const [deleting, setDeleting] = useState(false); const hasFetched = useRef(false); const load = useCallback(async () => { const data = await api.chargePoints.list().catch(() => []); setChargePoints(data); }, []); useEffect(() => { if (!hasFetched.current) { hasFetched.current = true; load(); } }, [load]); const openEdit = (cp: ChargePoint) => { setEditTarget(cp); setFeeInput(String(cp.feePerKwh)); }; const handleSave = async () => { if (!editTarget) return; const fee = Math.max(0, Math.round(Number(feeInput) || 0)); setSaving(true); try { await api.chargePoints.update(String(editTarget.id), { feePerKwh: fee }); setChargePoints((prev) => prev.map((cp) => (cp.id === editTarget.id ? { ...cp, feePerKwh: fee } : cp)), ); } finally { setSaving(false); } }; const handleDelete = async () => { if (!deleteTarget) return; setDeleting(true); try { await api.chargePoints.delete(String(deleteTarget.id)); setChargePoints((prev) => prev.filter((cp) => cp.id !== deleteTarget.id)); setDeleteTarget(null); } finally { setDeleting(false); } }; return (

充电桩管理

共 {chargePoints.length} 台设备

标识符 品牌 / 型号 注册状态 电价(分/kWh) 最后心跳 接口状态 {""} {chargePoints.length === 0 && ( 暂无设备 {""} {""} {""} {""} {""} {""} )} {chargePoints.map((cp) => ( {cp.chargePointIdentifier} {cp.chargePointVendor && cp.chargePointModel ? ( `${cp.chargePointVendor} / ${cp.chargePointModel}` ) : ( )} {cp.registrationStatus} {cp.feePerKwh > 0 ? ( {cp.feePerKwh} 分 (¥{(cp.feePerKwh / 100).toFixed(2)}/kWh) ) : ( 免费 )} {cp.lastHeartbeatAt ? ( new Date(cp.lastHeartbeatAt).toLocaleString("zh-CN") ) : ( )}
{cp.connectors.length === 0 ? ( ) : ( cp.connectors.map((conn) => ( #{conn.connectorId} {conn.status} )) )}
配置电价

充电桩: {cp.chargePointIdentifier}

setFeeInput(e.target.value)} />

设为 0 则免费充电。当前:¥ {((Number(feeInput) || 0) / 100).toFixed(2)}/kWh

确认删除充电桩

将删除充电桩{" "} {cp.chargePointIdentifier} 及其所有连接器和充电记录,此操作不可恢复。

))}
); }