鉴权(用户定案:访问面板即需登录): - PANEL.pin 存 sha256+salt(salt:hex,绝不含明文);与未来锁屏 PIN 同源预留 system.pin(g_sets 注记)。 - 未设 PIN → /api/auth/setup 首次设置流程;未设 PIN 前读/写端点全拦(require_auth 无条件,登录/设置流程除外)。 - token 128bit(16B→32hex) 只存进程内存(重启自然失效),3 天固定不滑动续期,多会话并存。 - 连错 5 次 PIN 锁 5 分钟(429 LOCKED,status 透出 lock_remaining_ms)。 - 旧密码机制 panel.auth_enabled/panel.auth_pass 兼容迁移:未设 PIN 时可暂用旧密码登录(status=legacy),设 PIN 后以 PIN 为准。 新只读端点(均需 PIN 会话): - /api/power: meow_powermgr MSG_PM_QUERY(0xD0)→RESULT(0xD1) battery/estimate/breakdown,confidence 原样透传。 - /api/audio: 补 rms/peak/lvlseq(追加键,ABI 兼容),抽 audio_fill() 供 overview 复用。 - /api/ams: am list 解析 App 表(pkg/name/state/pid/launches/crashes/last_kind/last_code)。 - /api/svcd: meow_svcd status all 解析服务表(name/state/pid/restart/backoff_ms/trigger/src/exit/exec)。 - /api/overview: 单线程后端只暴露聚合——perf/power/audio/net/ams/svcd 六源顺序 fan-out,任一源失败该子块 available:false,绝不假数据。 前端最小支撑:登录页(PIN 输入+首次设置双态)+ 401 自动跳登录 + token 存 localStorage 随请求带 X-MeowToken(后端亦认 Authorization: Bearer)。 红线:仅新增读级端点,未加任何写端点(音量/路由/策略等);本任务不含批1-B 页面。 md5: meowpanel 3696e85b5eaf111f530c5c39fa68886e(mipsel 静态)/ meowpanel_host 3180e4f87e77db8717597619097805eb。 验证:host+mips -Werror 0 warning;假 IPC/am/svcd 桩六源聚合(含 power 宕机降级)PASS;PIN 全流程(设置→登录→连错5次锁→token 过期)PASS;qemu-mipsel 冒烟 PASS。
149 lines
9.4 KiB
HTML
149 lines
9.4 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN" data-style="md3" data-mode="dark">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||
<meta name="color-scheme" content="dark light">
|
||
<title>MeowPanel · MeowOS 面板</title>
|
||
<link rel="stylesheet" href="meowpanel.css">
|
||
</head>
|
||
<body>
|
||
|
||
<!-- 顶部横幅:后端未连接 / 网络错误 -->
|
||
<div id="offline-banner" class="offline-banner" hidden>⚠️ 后端未连接 — 请确认设备上的 MeowPanel 后端已启动(<code>http://<host>.local:8080</code>)</div>
|
||
|
||
<div id="app" class="app">
|
||
|
||
<!-- 左侧导航(宝塔式) -->
|
||
<aside class="sidebar" id="sidebar">
|
||
<div class="brand">
|
||
<span class="brand-mark">M</span>
|
||
<span class="brand-name">MeowPanel</span>
|
||
</div>
|
||
<nav class="nav" id="nav">
|
||
<button class="nav-item" data-route="perf" title="实时性能">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><path d="M3 13h4l2-5 3 9 2-4h5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
|
||
<span class="nav-label">性能</span>
|
||
</button>
|
||
<button class="nav-item" data-route="bright" title="亮度 / 音量">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><circle cx="12" cy="12" r="4" fill="none" stroke="currentColor" stroke-width="2"/></svg></span>
|
||
<span class="nav-label">亮度·音量</span>
|
||
</button>
|
||
<button class="nav-item" data-route="audio" title="音频服务状态(meow_audiod)">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><path d="M4 10v4h3l5 4V6l-5 4H4z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/><path d="M15.5 9.5a3.5 3.5 0 0 1 0 5M18 7a7 7 0 0 1 0 10" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></span>
|
||
<span class="nav-label">音频</span>
|
||
</button>
|
||
<button class="nav-item" data-route="net" title="网络管理(meow_netmgrd)">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><path d="M2.5 9a15 15 0 0 1 19 0M5.5 12.5a10 10 0 0 1 13 0M8.5 16a5 5 0 0 1 7 0" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><circle cx="12" cy="19" r="1.4" fill="currentColor"/></svg></span>
|
||
<span class="nav-label">网络</span>
|
||
</button>
|
||
<button class="nav-item" data-route="files" title="文件管理">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/></svg></span>
|
||
<span class="nav-label">文件</span>
|
||
</button>
|
||
<button class="nav-item" data-route="apps" title="MeowAPPs 管理">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><rect x="4" y="4" width="7" height="7" rx="2" fill="none" stroke="currentColor" stroke-width="2"/><rect x="13" y="4" width="7" height="7" rx="2" fill="none" stroke="currentColor" stroke-width="2"/><rect x="4" y="13" width="7" height="7" rx="2" fill="none" stroke="currentColor" stroke-width="2"/><rect x="13" y="13" width="7" height="7" rx="4" fill="none" stroke="currentColor" stroke-width="2"/></svg></span>
|
||
<span class="nav-label">应用</span>
|
||
</button>
|
||
<button class="nav-item" data-route="fonts" title="字体库管理">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><path d="M5 18L10 5h1.4L16.5 18h-2.2l-1.2-3.2H8.3L7.1 18H5zm4-5h3.4l-1.7-4.7L9 13z" fill="currentColor"/><path d="M17 19h4v1.6h-4z" fill="currentColor"/></svg></span>
|
||
<span class="nav-label">字体</span>
|
||
</button>
|
||
<button class="nav-item" data-route="settings" title="设置镜像">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><path d="M4 6h16M4 12h16M4 18h16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><circle cx="9" cy="6" r="2" fill="var(--bg)"/><circle cx="15" cy="12" r="2" fill="var(--bg)"/><circle cx="7" cy="18" r="2" fill="var(--bg)"/></svg></span>
|
||
<span class="nav-label">设置</span>
|
||
</button>
|
||
<button class="nav-item" data-route="remote" title="远程控制">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><rect x="7" y="3" width="10" height="18" rx="2" fill="none" stroke="currentColor" stroke-width="2"/><circle cx="12" cy="15" r="2" fill="none" stroke="currentColor" stroke-width="2"/><path d="M10 7h4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></span>
|
||
<span class="nav-label">远程</span>
|
||
</button>
|
||
<button class="nav-item" data-route="screen" title="实时画面 / 点击遥控">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><rect x="3" y="5" width="18" height="12" rx="2" fill="none" stroke="currentColor" stroke-width="2"/><path d="M8 21h8M12 17v4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><circle cx="8.5" cy="11" r="1.2" fill="currentColor"/><path d="M12 11l3.5 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></span>
|
||
<span class="nav-label">屏幕</span>
|
||
</button>
|
||
<button class="nav-item" data-route="system" title="系统信息 / 升级">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><rect x="6" y="3" width="12" height="18" rx="2" fill="none" stroke="currentColor" stroke-width="2"/><path d="M9 8h6M9 12h6M9 16h3" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></span>
|
||
<span class="nav-label">系统</span>
|
||
</button>
|
||
<button class="nav-item" data-route="logs" title="系统日志">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><path d="M5 4h14v16l-2-2-2 2-2-2-2 2-2-2-2 2z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/><path d="M8 9h8M8 13h5" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></span>
|
||
<span class="nav-label">日志</span>
|
||
</button>
|
||
<button class="nav-item" data-route="notif" title="通知中心">
|
||
<span class="nav-ico"><svg viewBox="0 0 24 24"><path d="M6 9a6 6 0 0 1 12 0v4l2 3H4l2-3z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/><path d="M10 20a2 2 0 0 0 4 0" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></span>
|
||
<span class="nav-label">通知</span>
|
||
</button>
|
||
</nav>
|
||
</aside>
|
||
|
||
<!-- 右侧:顶栏 + 内容 -->
|
||
<div class="main">
|
||
<header class="topbar">
|
||
<button class="icon-btn menu-btn" id="menu-btn" title="展开/收起导航" aria-label="菜单">
|
||
<svg viewBox="0 0 24 24"><path d="M4 6h16M4 12h16M4 18h16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
|
||
</button>
|
||
<h1 class="topbar-title" id="page-title">实时性能</h1>
|
||
<div class="topbar-actions">
|
||
<span class="conn" id="conn-dot" data-state="unknown" title="后端连接">
|
||
<span class="conn-dot"></span><span class="conn-text" id="conn-text">检测中…</span>
|
||
</span>
|
||
<div class="seg" id="style-seg" title="风格">
|
||
<button class="seg-btn" data-style="md3">MD3</button>
|
||
<button class="seg-btn" data-style="miuix">MIUIx</button>
|
||
</div>
|
||
<div class="seg" id="theme-seg" title="明暗">
|
||
<button class="seg-btn" data-mode="dark">深色</button>
|
||
<button class="seg-btn" data-mode="light">浅色</button>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="content" id="content">
|
||
<p class="placeholder">加载中…</p>
|
||
</main>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 通用确认弹窗 -->
|
||
<div id="modal" class="modal-scrim" hidden>
|
||
<div class="modal">
|
||
<h2 class="modal-title" id="modal-title">确认</h2>
|
||
<p class="modal-body" id="modal-body"></p>
|
||
<div class="modal-actions">
|
||
<button class="btn" id="modal-no">取消</button>
|
||
<button class="btn btn-primary btn-danger" id="modal-yes">确定</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 登录 / 首次设置 PIN(访问级 PIN 鉴权;访问面板即需登录) -->
|
||
<div id="login" class="login-scrim" hidden>
|
||
<div class="login-box">
|
||
<div class="login-brand"><span class="login-brand-mark">M</span><span>MeowPanel</span></div>
|
||
<p class="login-sub" id="login-sub">此面板已开启访问鉴权,请输入 4 位 PIN。</p>
|
||
<input type="password" id="login-pin" class="login-input" placeholder="4 位 PIN" inputmode="numeric" autocomplete="off" maxlength="4">
|
||
<input type="password" id="login-pin2" class="login-input" placeholder="再次输入 PIN" inputmode="numeric" autocomplete="off" maxlength="4" hidden>
|
||
<p class="login-err" id="login-err" hidden></p>
|
||
<button class="btn btn-primary login-btn" id="login-btn">登 录</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 设置面板密码对话框 -->
|
||
<div id="pwdlg" class="modal-scrim" hidden>
|
||
<div class="modal">
|
||
<h2 class="modal-title" id="pwdlg-title">设置面板密码</h2>
|
||
<p class="modal-body" id="pwdlg-body">请输入新密码(留空则清除密码)。</p>
|
||
<input type="password" id="pwdlg-input" class="login-input" placeholder="新密码" autocomplete="new-password">
|
||
<div class="modal-actions">
|
||
<button class="btn" id="pwdlg-cancel">取消</button>
|
||
<button class="btn btn-primary" id="pwdlg-ok">确定</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="toast" class="toast" hidden></div>
|
||
|
||
<script src="meowpanel.js"></script>
|
||
</body>
|
||
</html>
|