Skip to content

Commit f9cb70f

Browse files
committed
PWA 适配:可安装到手机主屏幕 (v1.12.0)
- manifest.webmanifest:独立窗口模式、主题色、品牌图标 (192/512 常规 + 512 maskable + 180 apple-touch-icon) - 图标零依赖生成:tools/gen-icons.mjs 用 node:zlib 手写 PNG 编码器, 按品牌 logo(蓝紫渐变+白色折线)光栅化,含抗锯齿 - sw.js:静态资源网络优先 + 缓存回退(Watchtower 自动更新不会被旧缓存 卡住),断网导航回退应用壳;/api 与跨域请求不拦截,数据保持新鲜 - iOS meta(apple-touch-icon / standalone / 状态栏)任何环境可加主屏幕; 独立窗口模式适配刘海与底部指示条安全区 - 注:Android Chrome 安装提示与 SW 需 HTTPS(或 localhost)环境
1 parent 41bc9f1 commit f9cb70f

12 files changed

Lines changed: 199 additions & 2 deletions

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
- **人民币折算**:每个站点可配置充值汇率(站点 $1 折合 ¥ 多少,如 1:2 充值);
3838
余额、消耗、图表等金额主显人民币(未配置按 1:1),站点原始余额作为次要信息展示;
3939
**余额告警阈值仍按站点余额判断**,不受汇率影响
40+
- **PWA**:支持添加到手机主屏幕以独立窗口运行(含品牌图标与离线壳缓存)。
41+
iOS Safari「添加到主屏幕」任何环境可用;Android Chrome 的安装提示要求 HTTPS 访问。
42+
静态资源网络优先(Watchtower 自动更新不受缓存影响),API 不缓存
4043
- **面板登录**:网页需要账号密码登录(scrypt 哈希 + HMAC 签名会话 Cookie,7 天有效;登录失败限流);默认账号 `admin / admin123`,登录后请在「设置」中修改
4144
- **内置演示**:首次启动自动创建演示中转站(数据来自内置 mock,含完整的登录→过期→自动续期链路演示),可直接删除
4245

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "relay-monitor",
3-
"version": "1.11.2",
3+
"version": "1.12.0",
44
"private": true,
55
"description": "监控 sub2api / new-api 中转站余额的网页面板",
66
"type": "module",

public/app.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,6 +1970,13 @@ document.addEventListener("visibilitychange", () => {
19701970
// 我的站点页滚动时同步目录高亮
19711971
$("#content").addEventListener("scroll", updateOwnTocActive, { passive: true });
19721972

1973+
// PWA:注册 Service Worker(需要 HTTPS 或 localhost 环境)
1974+
if ("serviceWorker" in navigator) {
1975+
window.addEventListener("load", () => {
1976+
navigator.serviceWorker.register("/sw.js").catch(() => {});
1977+
});
1978+
}
1979+
19731980
async function bootData() {
19741981
const meta = await api.meta();
19751982
state.types = meta.types;

public/icons/apple-touch-icon.png

4.17 KB
Loading

public/icons/icon-192.png

4.66 KB
Loading

public/icons/icon-512.png

13.8 KB
Loading

public/icons/maskable-512.png

13.6 KB
Loading

public/index.html

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,17 @@
22
<html lang="zh-CN" data-theme="light">
33
<head>
44
<meta charset="UTF-8" />
5-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
66
<title>中转站余额监控</title>
7+
<link rel="manifest" href="/manifest.webmanifest" />
8+
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#F4F5F7" />
9+
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1C1C1E" />
10+
<link rel="icon" href="/icons/icon-192.png" type="image/png" />
11+
<link rel="apple-touch-icon" href="/icons/apple-touch-icon.png" />
12+
<meta name="apple-mobile-web-app-capable" content="yes" />
13+
<meta name="mobile-web-app-capable" content="yes" />
14+
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
15+
<meta name="apple-mobile-web-app-title" content="中转监控" />
716
<link rel="stylesheet" href="styles.css" />
817
</head>
918
<body>

public/manifest.webmanifest

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "中转站余额监控",
3+
"short_name": "中转监控",
4+
"description": "sub2api / new-api 中转站余额监控与经营分析面板",
5+
"start_url": "/",
6+
"scope": "/",
7+
"display": "standalone",
8+
"orientation": "portrait",
9+
"background_color": "#F4F5F7",
10+
"theme_color": "#0A84FF",
11+
"lang": "zh-CN",
12+
"icons": [
13+
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
14+
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" },
15+
{ "src": "/icons/maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
16+
]
17+
}

public/styles.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,12 @@ button { font-family: inherit; cursor: pointer; }
310310
.report-frame { height: 52vh; }
311311
}
312312

313+
/* PWA 独立窗口模式:避开刘海与底部指示条 */
314+
@media (display-mode: standalone) {
315+
.titlebar { padding-top: calc(env(safe-area-inset-top, 0px)); height: calc(42px + env(safe-area-inset-top, 0px)); }
316+
.content { padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px)); }
317+
}
318+
313319
/* ---- 登录屏 ---- */
314320
.login-screen {
315321
position: fixed; inset: 0; background: var(--window-outer-bg); z-index: 100;

0 commit comments

Comments
 (0)