feat(桌面与监控): 完善工作台导航和登录活动定位
- 优化桌面标签、上下文标题、前进后退、导航栏隐藏和原生菜单体验 - 补充登录会话 IP 采集、地理位置回退、管理端展示及数据库迁移 - 更新桌面发布检查、运维文档和前后端测试覆盖
This commit is contained in:
@@ -47,7 +47,11 @@ npm run desktop:build:app
|
||||
- [ ] Tauri capability 不包含 shell 权限、持久文件系统 scope 或宽泛目录读写。
|
||||
- [ ] 文件系统与 opener scope 只允许 `$TEMP/ctms-desktop/**`。
|
||||
- [ ] 单实例插件先于其他桌面插件注册。
|
||||
- [ ] Tauri command 白名单仅包含凭据和更新命令。
|
||||
- [ ] macOS 首个顶层 submenu 为应用菜单,包含关于、设置、服务、隐藏和退出;文件菜单保持独立。
|
||||
- [ ] macOS 红色按钮保持真正关闭窗口的系统语义,Dock/Finder reopen 事件在需要时重建、显示并聚焦主窗口。
|
||||
- [ ] 桌面快捷键只通过受控 command 同步到原生菜单,不向 WebView 开放原始窗口或菜单控制权限。
|
||||
- [ ] 桌面主题支持跟随系统、明亮和暗黑,并通过受控 command 同步窗口外观。
|
||||
- [ ] Tauri command 白名单仅包含凭据、更新和已审计的桌面 UI 窄命令。
|
||||
- [ ] 前端源码不通过 query string 传递 token。
|
||||
- [ ] `ctms_token` 只允许由 `secureSessionStorage` 处理。
|
||||
- [ ] 登录表单密码不写入 `localStorage` 或 `sessionStorage`;Web 端只使用浏览器凭据管理能力,Desktop 端只使用系统凭据库。
|
||||
@@ -91,6 +95,10 @@ npm run desktop:build:app
|
||||
| 系统通知拒绝 | 不适用 | 必测 | 开关回退,提示系统权限未开启 |
|
||||
| 通知领取与 ack | 不适用 | 必测 | 显示成功后 ack;失败等待租约重试 |
|
||||
| 单实例重复启动 | 不适用 | 必测 | 恢复、显示并聚焦主窗口 |
|
||||
| 关闭窗口后 Dock 重开 | 不适用 | 必测 | 红色关闭按钮真正关闭主窗口;点击 Dock 后重建、显示并聚焦 |
|
||||
| 原生应用菜单 | 不适用 | 必测 | CTMS、文件、编辑、显示、导航、窗口和帮助菜单顺序及职责符合 macOS 习惯 |
|
||||
| 自定义快捷键同步 | 不适用 | 必测 | 设置修改后原生菜单立即显示并响应新的后退、前进和刷新快捷键 |
|
||||
| 跟随系统主题 | 不适用 | 必测 | 系统明暗模式变化时 WebView、标题栏和系统控件同步更新 |
|
||||
| 自动更新检查 | 不适用 | 必测 | release 通道按当前 CTMS origin 派生清单 |
|
||||
| 更新稍后提醒 | 不适用 | 必测 | 同版本 24 小时内不重复提示 |
|
||||
| 更新安装失败 | 不适用 | 必测 | 不打断业务录入,显示可排障错误 |
|
||||
@@ -107,6 +115,8 @@ npm run desktop:build:app
|
||||
- [ ] 通知开关显示 OS 权限状态。
|
||||
- [ ] 手动检查更新能反馈“已是最新版本”、未启用更新或检查失败。
|
||||
- [ ] 关键弹窗、表单、按钮在最小窗口尺寸 `1180x760` 下不重叠、不溢出。
|
||||
- [ ] “设置…”位于 macOS CTMS 应用菜单并使用 `⌘,`;退出位于应用菜单而不是文件菜单。
|
||||
- [ ] “显示”和“导航”菜单中的快捷键与桌面偏好保存值一致。
|
||||
- [ ] 更新弹窗只显示版本、发布日期和通用 release notes,不展示 token、下载链接或业务详情。
|
||||
|
||||
## 5. 不允许项
|
||||
@@ -231,3 +241,17 @@ npm run desktop:build:app
|
||||
|
||||
- 在真实 macOS `.app` 中以 `1180x760` 检查登录页、服务器设置、个人中心、系统偏好和更新弹窗无重叠、无横向溢出。
|
||||
- 在真实系统通知权限拒绝流程中确认权限状态提示、开关回退和错误提示与 OS 状态一致。
|
||||
|
||||
## 11. 2026-07-13 macOS 原生体验适配记录
|
||||
|
||||
本轮继续保留 Tauri 和共享 Vue 前端,不引入 Swift 业务 UI,也不改变 Windows 内测边界:
|
||||
|
||||
- macOS 新增标准 CTMS 应用菜单,将关于、设置、服务、隐藏和退出等项目收敛到首个应用 submenu;文件、编辑、显示、导航、窗口和帮助菜单保持独立。
|
||||
- macOS 红色关闭按钮保持真正关闭主窗口的系统语义;Tauri `RunEvent::Reopen` 在 Dock/Finder 再激活时从受控配置重建、显示并聚焦主窗口,重复启动继续复用同一恢复 helper。
|
||||
- 新增受控 `desktop_menu_set_shortcuts` command,只接受后退、前进和刷新三项经过双层校验的快捷键,并同步原生菜单 accelerator。
|
||||
- 桌面主题新增“跟随系统”,WebView 监听 `prefers-color-scheme`,受控 `desktop_window_set_theme` command 同步 Tauri 窗口外观;未向 WebView 增加原始窗口权限。
|
||||
- `desktop:release:check` 已增加应用菜单、Dock reopen、关闭后重建、快捷键同步、系统主题和新增 command 白名单约束。
|
||||
|
||||
真实 `.app` 仍需人工验证:红色按钮真正关闭主窗口后 Dock 重建、菜单顺序、个人中心自身关闭按钮、编辑菜单文本输入行为、自定义快捷键即时同步,以及系统明暗模式切换时的标题栏一致性。
|
||||
|
||||
本轮未引入以下条件性 Swift 能力:Quick Look 需先确认附件审阅频率和 Windows 降级语义;Touch ID 会改变现有 30 天会话恢复体验,需先确定凭据访问控制策略;通知点击回跳需先定义固定、无敏感信息的动作和目标页面。三项均不是当前发布前置条件。
|
||||
|
||||
@@ -30,12 +30,19 @@ The runtime contract currently provides:
|
||||
- file picker/save/open adapters
|
||||
- desktop system notification adapters
|
||||
- desktop updater adapters
|
||||
- native desktop application menu and shortcut synchronization
|
||||
- desktop window lifecycle and system appearance synchronization
|
||||
|
||||
Business modules must use this public runtime entry point. They must not inspect
|
||||
Tauri globals or import Tauri packages directly. Native files, notifications,
|
||||
secure session storage, and automatic updates must remain behind
|
||||
`frontend/src/runtime/` and explicit capability flags.
|
||||
|
||||
Desktop menu accelerators and window appearance are synchronized through narrow
|
||||
Tauri commands owned by `frontend/src/runtime/`. macOS close/reopen behavior is
|
||||
handled by the Tauri event loop so a genuinely closed main window can be rebuilt from the Dock;
|
||||
these concerns must not move into Vue business modules.
|
||||
|
||||
## Version Change
|
||||
|
||||
Update every client manifest with one command:
|
||||
|
||||
@@ -33,13 +33,19 @@ docker compose ps
|
||||
MONITORING_ACCESS_LOG_RETENTION_DAYS=90
|
||||
MONITORING_METRIC_RETENTION_DAYS=400
|
||||
MONITORING_RETENTION_INTERVAL_SECONDS=86400
|
||||
MONITORING_IP_GEO_FALLBACK_ENABLED=true
|
||||
MONITORING_IP_GEO_FALLBACK_TIMEOUT_SECONDS=2.5
|
||||
MONITORING_IP_GEO_FALLBACK_CACHE_SECONDS=604800
|
||||
MONITORING_IP_GEO_FALLBACK_MAX_LOOKUPS=10
|
||||
USER_LOGIN_ACTIVITY_RETENTION_DAYS=180
|
||||
USER_SESSION_ONLINE_SECONDS=300
|
||||
```
|
||||
|
||||
访问日志留存范围为 7–3650 天,指标留存范围为 30–3650 天,清理周期范围为 60–604800 秒。修改后需重启后端。正式环境部署新版本前必须先执行 Alembic migration。
|
||||
|
||||
账号管理页的“在线”状态由服务端会话心跳计算:最近 `USER_SESSION_ONLINE_SECONDS` 秒内成功心跳且未退出的会话视为在线。登录记录仅保存客户端类型、版本、登录/最近活动/退出时间;不保存 Token、密码或原始 IP。
|
||||
账号管理页的“在线”状态由服务端会话心跳计算:最近 `USER_SESSION_ONLINE_SECONDS` 秒内成功心跳且未退出的会话视为在线。登录记录保存客户端类型、版本、服务端观测到的登录 IP、登录/最近活动/退出时间;IP 属地由本地离线数据库按需解析,不发送到外部服务。登录记录接口仅限系统管理员访问并禁止 HTTP 缓存,不保存 Token 或密码,并与登录活动一起按 `USER_LOGIN_ACTIVITY_RETENTION_DAYS` 清理。
|
||||
|
||||
登录 IP 只接受可信反向代理提供的转发地址。Docker Compose 默认信任容器常用的 `172.16.0.0/12` 和 `192.168.0.0/16` 内部网段;其他部署必须通过 `TRUSTED_PROXY_CIDRS` 明确配置实际代理网段,不得直接信任任意来源的 `X-Forwarded-For`。
|
||||
|
||||
## 来源地图服务器位置
|
||||
|
||||
@@ -49,7 +55,13 @@ USER_SESSION_ONLINE_SECONDS=300
|
||||
2. `FRONTEND_PUBLIC_URL` 主机名解析出的公网 IP。
|
||||
3. `MONITORING_PUBLIC_IP_DISCOVERY_URLS` 配置的公网出口 IP 查询服务。
|
||||
|
||||
默认公网查询服务为 `https://api64.ipify.org,https://icanhazip.com`,单次超时 2.5 秒。解析成功后通过本地 ip2region 数据库确定属地,再由后端转换为地图坐标;解析失败时 API 返回 `server_location: null`,地图不会使用任意默认城市代替。
|
||||
默认公网查询服务为 `https://api64.ipify.org,https://icanhazip.com`,单次超时 2.5 秒。解析成功后通过本地 ip2region 数据库确定属地并转换为地图坐标;本地库没有坐标时复用下述 IP2Location.io 受控兜底。两条链路均失败时 API 返回 `server_location: null`,地图不会使用任意默认城市代替。默认打开全球视图,以便服务器与访问来源分属不同国家时仍能完整显示飞线。
|
||||
|
||||
## 访问来源坐标兜底
|
||||
|
||||
访问来源始终先使用本地 ip2region 和内置行政区质心解析。只有公网 IP 已识别、但本地链路无法得到地图坐标时,后端才调用 IPAddress.my 使用的 IP2Location.io 官方 JSON API `https://api.ip2location.io/` 补充经纬度;私网、回环、链路本地和无效地址不会发送给第三方。
|
||||
|
||||
兜底默认启用,单次请求最多查询 10 个尚未缓存的公网 IP,最多并发 5 个请求,超时 2.5 秒。成功结果缓存 7 天,失败结果缓存 1 小时;第三方不可用时继续返回本地解析结果,不影响访问来源接口。可设置 `MONITORING_IP_GEO_FALLBACK_ENABLED=false` 完全禁用外部查询。无密钥模式受服务方每日额度限制;如需配置 API Key,使用 `MONITORING_IP_GEO_FALLBACK_API_KEY`,后端通过 `Authorization: Bearer` 发送,禁止把密钥写入 URL 或日志。
|
||||
|
||||
受限网络建议显式配置:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user