feat(frontend/admin): M10 后台管理面板(/admin hash 路由 + 15 大模块 + RBAC(owner/admin/viewer) + 审计 + Miuix);Docs/api-client.md v0.3 契约补全;tsc+vite build 通过
This commit is contained in:
1 parent
4c48e94659
commit
f43eb17030
26 files changed
+2253
-4
No files matched your search
@@ -0,0 +1,84 @@
|
||||
import { useAsyncData } from "../../lib/useAsyncData";
|
||||
import { adminListIoT } from "../../lib/api";
|
||||
import type { AdminIoTDevice } from "../../lib/types";
|
||||
import { useAutoReload } from "../hooks";
|
||||
import { useAuditStore } from "../audit";
|
||||
import { AdminTable, Notice, PageHeader, type AdminColumn } from "../components";
|
||||
import { Button, Surface, Tag } from "../../components/primitives";
|
||||
|
||||
const columns: AdminColumn<AdminIoTDevice>[] = [
|
||||
{ key: "name", title: "设备", render: (d) => <span className="font-medium">{d.name}</span> },
|
||||
{ key: "type", title: "类型", render: (d) => <Tag tone="accent">{d.type}</Tag> },
|
||||
{ key: "id", title: "ID", render: (d) => <span className="font-mono text-xs text-[var(--mu-text-lo)]">{d.id}</span> },
|
||||
{
|
||||
key: "online",
|
||||
title: "状态",
|
||||
render: (d) => (
|
||||
<Tag tone={d.online ? "ok" : "err"}>
|
||||
<span className={`mr-1 inline-block h-1.5 w-1.5 rounded-full ${d.online ? "bg-[var(--mu-ok)]" : "bg-[var(--mu-err)]"}`} />
|
||||
{d.online ? "在线" : "离线"}
|
||||
</Tag>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "state",
|
||||
title: "实时状态",
|
||||
render: (d) => (
|
||||
<span className="block max-w-md font-mono text-xs text-[var(--mu-text-mid)]">
|
||||
{Object.entries(d.state)
|
||||
.map(([k, v]) => `${k}=${typeof v === "string" ? v : JSON.stringify(v)}`)
|
||||
.join(" · ") || "—"}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export function IoTModule(): React.ReactNode {
|
||||
const { data, loading, error, reload } = useAsyncData(adminListIoT, []);
|
||||
useAutoReload(reload, 8000);
|
||||
const log = useAuditStore((s) => s.log);
|
||||
|
||||
return (
|
||||
<div className="space-y-5">
|
||||
<PageHeader
|
||||
title="IoT 设备"
|
||||
subtitle="GET /api/v1/admin/iot · 设备列表/实时状态 + 控制台 + 场景 + 自动化规则"
|
||||
actions={
|
||||
<>
|
||||
<Button
|
||||
variant="soft"
|
||||
onClick={() => {
|
||||
log("iot.scene", "ok");
|
||||
alert("场景 / 自动化规则 CRUD(占位):后端 M10+ 提供。");
|
||||
}}
|
||||
>
|
||||
场景与规则
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
log("iot.control", "ok");
|
||||
alert("设备控制(占位):后端 M10+ 提供指令下发。");
|
||||
}}
|
||||
>
|
||||
设备控制台
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
<Surface className="space-y-2">
|
||||
<AdminTable
|
||||
columns={columns}
|
||||
rows={loading ? null : data}
|
||||
loading={loading}
|
||||
error={error}
|
||||
emptyTitle="无 IoT 设备"
|
||||
rowKey={(d) => d.id}
|
||||
/>
|
||||
</Surface>
|
||||
|
||||
<Notice>实时上/下线经 WS device_update 事件或轮询刷新;控制/场景/规则写入需后端 M10+ 提供。</Notice>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user