新增: 功能路线图 + 9份需求契约

- feature-roadmap.md: 现有能力盘点 + P1/P2/P3方向 + 竞品参考
- AI深度视差: 远程推理方案(服务端Depth-Anything + 客户端WebGL)
- 自动升级模块文档: 设计规格/任务规划/决策记录
- 9份需求契约: 视频/颜色提取/时间段/番茄钟/播放列表/电池/网页/便签/监控
This commit is contained in:
2026-05-28 19:06:39 +08:00
parent f5a473c4b8
commit cd7247d880
19 changed files with 1044 additions and 33 deletions

View File

@@ -0,0 +1,24 @@
# 自动升级模块
**模块状态**:待开发
**最后更新**2026-05-28
---
## 快速导航
| 类型 | 文档 | 说明 |
|------|------|------|
| 规划 | [任务规划.md](./任务规划.md) | 实施步骤和检查清单 |
| 设计 | [设计文档/自动升级功能设计.md](./设计文档/自动升级功能设计.md) | 完整功能设计 |
| 决策 | [决策记录/](./决策记录/) | 架构和设计决策 |
| 问题 | [问题追踪/](./问题追踪/) | 待解决问题 |
| 检查 | [核对报告/](./核对报告/) | 实现检查报告 |
| 测试 | [测试用例/](./测试用例/) | 测试用例 |
## 核心设计
- **弹窗策略**:非强制 → 右下角气泡(稍后 + 立即升级),强制 → 居中弹窗(仅立即升级)
- **架构**:主程序检查版本 → 弹窗提示 → 启动 updater.exe → 下载替换重启
- **updater.exe**通用升级器参数化驱动可复用于其他产品u-tabs 等)
- **商业化预留**API 预留 tier/license 字段,升级器不含商业逻辑

View File

@@ -0,0 +1,53 @@
# 自动升级 — 任务规划
> 创建时间2026-05-28
## 阶段一:版本基础设施
- [ ] `main.go` 增加版本变量,`-ldflags` 编译注入
- [ ] `config.go` 增加 `update_url``auto_check_update``skip_version` 字段
- [ ] `updater.go` 实现版本检查函数 `checkUpdate()`
## 阶段二:升级弹窗
- [ ] `web/update.html` 升级弹窗页面(右下角气泡 + 居中弹窗两种模式)
- [ ] Go 端创建无边框 WebView2 弹窗窗口
- [ ] 弹窗内容渲染:版本号、更新说明、按钮
- [ ] 根据 `force` 字段切换弹窗位置和按钮
## 阶段三:升级器程序
- [ ] `updater/main.go` 独立程序骨架
- [ ] HTTP 下载安装包 + 进度日志
- [ ] SHA256 校验
- [ ] 备份旧版本
- [ ] 替换 + 启动新版本
- [ ] 启动失败自动回滚
- [ ] 日志写入 `updater.log`
## 阶段四:主程序集成
- [ ] 主程序释放 updater.exe 到临时目录
- [ ] 构造命令行参数启动 updater
- [ ] 主程序退出
- [ ] 托盘菜单增加"检查更新"
## 阶段五:发布流程
- [ ] 构建脚本同时构建 u-desktop.exe + updater.exe
- [ ] publish 技能自动生成 version.json版本号 + SHA256 + 下载 URL
- [ ] 上传 version.json 和安装包到 c.1216.top
## 阶段六:验证
- [ ] 手动模拟版本更新,测试弹窗流程
- [ ] 测试 updater 下载 + 替换 + 重启
- [ ] 测试回滚机制
- [ ] 测试强制升级流程
## 技术要点
- 版本号通过 `-ldflags "-X main.version=x.x.x"` 注入
- updater.exe 通用设计,参数化驱动,不含业务逻辑
- 弹窗用 WebView2 无边框窗口,风格与设置窗口一致
- version.json 放 c.1216.top静态文件

View File

@@ -0,0 +1,17 @@
# 决策记录
记录自动升级模块的架构和设计决策。
## 格式
```
ADR-{编号} - {标题}
状态:提议 | 已接受 | 已废弃
上下文:...
决策:...
理由:...
```
## 已记录
(暂无)

View File

@@ -0,0 +1,3 @@
# 核对报告
实现过程中的检查报告。

View File

@@ -0,0 +1,3 @@
# 测试用例
自动升级功能的测试用例。

View File

@@ -0,0 +1,278 @@
# 自动升级系统 — 实现规格
> 来源:需求探索会话 2026-05-28
> 状态:待开发
---
## 1. 架构总览
```
┌──────────────┐
│ 远程版本 JSON │ ← 静态文件,放 CDN / OSS
│ version.json │
└──────┬───────┘
│ HTTP GET
┌──────────────────┐
│ u-desktop.exe │ ← 主程序
│ · 启动时检查版本 │
│ · 弹窗提示升级 │
│ · 释放 updater │
└──────┬───────────┘
│ 启动进程
┌──────────────────┐
│ updater.exe │ ← 通用升级器,参数化驱动
│ · 下载安装包 │
│ · SHA256 校验 │
│ · 备份旧版本 │
│ · 替换 + 启动 │
│ · 失败自动回滚 │
└──────────────────┘
```
---
## 2. 主程序改动
### 2.1 版本号注入
`main.go` 增加版本变量,编译时注入:
```go
var version = "dev" // -ldflags "-X main.version=0.6.0"
```
`build` 脚本 / publish 技能同步更新 ldflags。
### 2.2 版本检查模块
新增 `updater.go`
```
func checkUpdate() (*UpdateInfo, error)
```
- 启动时异步调用(不阻塞主流程)
- 请求远程 `version.json`
- 对比当前 version返回更新信息或 nil
远程 version.json 格式:
```json
{
"version": "0.7.0",
"force": false,
"release_notes": "· 新增视频壁纸\n· 修复全屏检测偶发失效",
"package": {
"url": "https://c.1216.top/u-desktop/u-desktop-0.7.0.zip",
"size": 8388608,
"sha256": "abc123def456..."
}
}
```
version.json URL 存入 config 或硬编码默认值。
### 2.3 升级弹窗
用 WebView2 新建一个无边框小窗口HTML 渲染弹窗内容。
#### 弹窗策略
| force 字段 | 位置 | 按钮 |
|-----------|------|------|
| `false` | 右下角,托盘图标上方 | [稍后] [立即升级] |
| `true` | 屏幕居中 | [立即升级](仅一个按钮) |
#### 弹窗 HTML 结构
右下角气泡(非强制):
```
┌─────────────────────────────┐
│ 发现新版本 v0.7.0 │
│ │
│ · 新增视频壁纸 │
│ · 修复全屏检测偶发失效 │
│ │
│ [稍后] [立即升级] │
└─────────────────────────────┘
```
居中弹窗(强制):
```
┌─────────────────────────────────────┐
│ │
│ 发现新版本 v0.7.0 │
│ │
│ · 新增视频壁纸 │
│ · 修复全屏检测偶发失效 │
│ │
│ 大小: 8MB | 预计用时: ~10秒 │
│ │
│ [立即升级] │
└─────────────────────────────────────┘
```
#### 弹窗窗口参数
| 参数 | 右下角 | 居中 |
|------|--------|------|
| 宽度 | 340px | 420px |
| 高度 | auto内容自适应 | auto |
| 位置 | 屏幕右下角 - 边距 20px | 屏幕居中 |
| 样式 | 无边框,圆角,毛玻璃 | 无边框,圆角,毛玻璃 |
| 置顶 | TOPMOST | TOPMOST |
### 2.4 用户点击"立即升级"
1. 从自身嵌入资源释放 `updater.exe` 到临时目录(或主程序同级目录)
2. 构造命令行参数启动 updater.exe
3. 主程序退出
```go
exec.Command(tmpUpdaterPath,
"--package-url", info.Package.URL,
"--sha256", info.Package.SHA256,
"--target", selfExePath,
"--version", info.Version,
"--force", strconv.FormatBool(info.Force),
).Start()
// 主程序退出
```
### 2.5 托盘菜单
新增菜单项:"检查更新",手动触发版本检查。
---
## 3. updater.exe
### 3.1 职责
通用升级器不含业务逻辑纯参数驱动。可复用于其他产品u-tabs 等)。
### 3.2 命令行参数
```bash
updater.exe \
--package-url <下载地址> \
--sha256 <SHA256校验值> \
--target <目标exe路径> \
--version <目标版本号> \
--force \
--backup-dir <备份目录,默认 target 同级 backup/>
```
### 3.3 流程
```
1. 显示进度窗口WebView2 或控制台)
2. HTTP GET 下载 package-url → 临时文件
- 显示下载进度(已下载/总大小)
- 支持断点续传(可选,初期不做)
3. 计算下载文件 SHA256与参数比对
- 不匹配 → 报错退出
4. 备份当前 target → backup-dir/old-{timestamp}.exe
5. 如果是 zip 包:解压后替换
如果是 exe直接覆盖
6. 启动新版本 target
7. updater 退出
异常处理:
- 下载失败 → 重试 3 次,间隔 5s
- 校验失败 → 报错,不替换
- 启动新版本后监听 5s新进程退出则回滚
- 回滚:将 backup 中的旧 exe 还原
```
### 3.4 进度显示
初期:无 UI日志写 `updater.log``-H windowsgui` 隐藏控制台)。
后续:可加 WebView2 进度窗口。
### 3.5 日志
写入 `updater.log`(与 target 同目录),包含时间戳、步骤、错误信息。
---
## 4. 构建 & 发布流程
### 4.1 主程序构建
```bash
go build -ldflags "-H windowsgui -X main.version=0.7.0" -o u-desktop.exe
```
### 4.2 updater 构建
独立 main 包,单独目录(如 `updater/`
```bash
cd updater && go build -ldflags "-H windowsgui" -o updater.exe
```
### 4.3 发布
1. 构建 `u-desktop.exe` + `updater.exe`
2. UPX 压缩(可选)
3. 计算 SHA256
4. 上传到 `c.1216.top`
5. 更新远程 `version.json`
6. 更新 publish 技能(自动生成 version.json + 上传)
---
## 5. 配置
`config.go` 新增字段:
```go
type Config struct {
// ... 现有字段
UpdateURL string `json:"update_url"` // 版本检查 URL默认 https://c.1216.top/u-desktop/version.json
AutoCheckUpdate bool `json:"auto_check_update"` // 启动时自动检查,默认 true
SkipVersion string `json:"skip_version"` // 用户跳过的版本号
}
```
---
## 6. 目录结构
```
u-desktop/
├── main.go # 增加版本变量
├── updater.go # 新增:版本检查 + 弹窗逻辑
├── config.go # 增加 update 相关字段
├── systray.go # 托盘菜单增加"检查更新"
├── web/
│ ├── update.html # 新增:升级弹窗 HTML
│ └── ...
├── updater/ # 新增:升级器独立目录
│ └── main.go
├── docs/
│ ├── feature-roadmap.md
│ └── auto-update-spec.md # 本文档
└── ...
```
---
## 7. 实施顺序
| 步骤 | 内容 | 依赖 |
|------|------|------|
| 1 | `main.go` 加版本变量,构建脚本加 ldflags | 无 |
| 2 | `updater.go` 版本检查函数 + config 字段 | 步骤 1 |
| 3 | 远程 `version.json` 手动创建 + 上传 | 步骤 2 |
| 4 | 升级弹窗 `update.html` + Go 端窗口创建 | 步骤 2 |
| 5 | 主程序释放 + 启动 updater.exe | 步骤 4 |
| 6 | `updater/` 目录,下载 + 校验 + 替换 + 回滚 | 步骤 5 |
| 7 | 托盘菜单"检查更新" | 步骤 2 |
| 8 | publish 技能集成 version.json 生成 | 步骤 3 |

View File

@@ -0,0 +1,10 @@
# 问题追踪
## 目录
- `待讨论/` — 需要讨论后决定的问题
- `待实现/` — 已确定但未实现的功能点
## 当前问题
(暂无)

View File

@@ -0,0 +1,38 @@
# 便签/待办卡片 — 需求契约
> 创建时间2026-05-28
> 状态:需求待确认
## 目标
桌面显示轻量 TODO 清单,数据持久化。
## 用户场景
1. 用户在设置页添加待办事项
2. 桌面卡片显示待办列表(勾选框 + 文字)
3. 点击勾选完成,已完成的显示删除线
4. 数据本地持久化
## 验收标准
- [ ] 添加/删除待办事项
- [ ] 勾选完成/取消完成
- [ ] 最多显示 N 条(如 10 条),超出滚动
- [ ] 数据持久化到本地 JSON
## 本次范围
- 基础 TODO 列表
## 非目标
- 分组/标签/优先级
- 截止日期提醒
- 同步到云端
## 约束
- 前端组件 + config JSON 持久化
- 复用卡片架构
- 设置页提供添加/删除/编辑入口

View File

@@ -0,0 +1,38 @@
# 壁纸播放列表 — 需求契约
> 创建时间2026-05-28
> 状态:需求待确认
## 目标
用户将 Bing 收藏 + 本地图片 + 视频组成播放列表,定时轮播。
## 用户场景
1. 用户在设置页勾选多个壁纸加入播放列表
2. 设置轮播间隔5 分钟 / 10 分钟 / 30 分钟 / 1 小时)
3. 壁纸按顺序或随机切换,淡入淡出过渡
## 验收标准
- [ ] 播放列表支持图片 + 视频 + Bing 壁纸
- [ ] 可配置轮播间隔
- [ ] 顺序 / 随机模式
- [ ] 切换时淡入淡出过渡
- [ ] 播放列表持久化
## 本次范围
- 基础播放列表 + 定时轮播
## 非目标
- 按时间段分配不同列表
- 按星期几分配不同列表
- 在线同步播放列表
## 约束
- 复用现有壁纸切换逻辑
- config 新增 playlist 数组 + interval + shuffle 字段
- Go 端定时器驱动切换

View File

@@ -0,0 +1,45 @@
# 壁纸颜色提取 + 卡片自适应 — 需求契约
> 创建时间2026-05-28
> 状态:需求已确认
## 目标
从当前壁纸自动提取主色调,动态调整信息卡片的文字颜色和背景,确保在任何壁纸上都可读。
## 用户场景
1. 用户切换壁纸后,卡片文字颜色自动适配(深色壁纸白字、浅色壁纸黑字)
2. 卡片背景增加半透明遮罩,提升文字可读性
3. 用户无需手动调色,全程自动
## 验收标准
- [ ] 壁纸切换后 1s 内完成颜色提取
- [ ] 文字颜色自动切换:深底白字 / 浅底黑字
- [ ] 卡片背景增加自适应半透明遮罩
- [ ] 支持所有壁纸类型(主题/图片/Bing/视频/颜色)
- [ ] 提取结果缓存,同一壁纸不重复计算
## 本次范围
- 壁纸主色调提取
- 卡片文字颜色自适应
- 卡片背景遮罩
## 非目标
- 完整调色板提取(只取主色调)
- 用户手动覆盖颜色
## 约束
- 前端 Canvas 采样,不依赖 Go 端图像处理
- 采样频率:壁纸切换时触发一次
- 不影响壁纸渲染性能
## 技术方案
- 壁纸切换后Canvas 绘制壁纸帧 → 采样若干像素点 → 取平均值 → 判断明暗
- 前端状态管理增加 `isDarkWallpaper` 变量
- 卡片组件根据 `isDarkWallpaper` 切换 CSS class

View File

@@ -0,0 +1,47 @@
# 时间段动态壁纸 — 需求契约
> 创建时间2026-05-28
> 状态:需求已确认
## 目标
根据用户地理位置的日出日落时间,自动切换壁纸主题(白天明亮主题,夜晚深色主题)。
## 用户场景
1. 白天自动使用 gradient/aurora 等明亮主题
2. 日落后自动切换为 starfield/fractal 等深色主题
3. 用户可自定义白天/夜晚对应的主题
4. 切换过程平滑过渡,无突兀跳变
## 验收标准
- [ ] 根据天气 API 已有的经纬度数据计算日出日落时间
- [ ] 日出后切换到"白天主题",日落后切换到"夜晚主题"
- [ ] 默认配对:白天 gradient / 夜晚 starfield
- [ ] 用户可在设置页自定义白天/夜晚主题
- [ ] 主题切换有淡入淡出过渡效果
- [ ] 无网络时使用固定时间6:00 日出 / 18:00 日落)
## 本次范围
- 基于日出日落的两种主题自动切换
## 非目标
- 多时段(上午/下午/傍晚/深夜)细分
- 基于天气的主题切换(晴天/阴天)
- 渐变过渡动画(日出/日落期间缓慢变化壁纸色调)
## 约束
- 复用天气 API 已有的城市经纬度,不新增 API 调用
- 日出日落算法用前端 JS 计算SunCalc 库或简单公式)
- config 新增 `dayTheme``nightTheme``autoTheme bool` 字段
## 风险
| 风险 | 缓解 |
|------|------|
| 天气城市未设置 | 降级为固定时间6:00/18:00 |
| 用户关闭天气卡片 | 经纬度使用上次缓存值 |

View File

@@ -0,0 +1,37 @@
# 电池感知 — 需求契约
> 创建时间2026-05-28
> 状态:需求待确认
## 目标
笔记本拔电时自动暂停动画壁纸,省电。插电后恢复。
## 用户场景
1. 用户拔掉电源线 → 动画壁纸暂停,显示静态帧
2. 重新插电 → 壁纸恢复动画
3. 设置页可开关此功能
## 验收标准
- [ ] 检测电源状态变化(`GetSystemPowerStatus`
- [ ] 拔电暂停动画壁纸
- [ ] 插电恢复动画
- [ ] 桌面右下角托盘气泡提示"已切换为省电模式"
- [ ] 静态壁纸(图片/纯色)不受影响
## 本次范围
- 拔电暂停 / 插电恢复
## 非目标
- 用户自定义省电策略(如暂停哪些卡片)
- 电量低于 X% 自动暂停
## 约束
- Go 端 `GetSystemPowerStatus` 轮询(每 10 秒)
- evalJS 调用前端 pause/resume
- config 新增 `batteryAware bool`

View File

@@ -0,0 +1,51 @@
# 番茄钟 + 自定义倒计时卡片 — 需求契约
> 创建时间2026-05-28
> 状态:需求已确认
## 目标
新增两种效率类卡片番茄钟25/5 循环倒计时)和自定义倒计时(用户设定目标日期)。
## 用户场景
### 番茄钟
1. 桌面显示番茄钟进度环25 分钟工作倒计时
2. 倒计时结束进度环变色提示休息5 分钟)
3. 显示今日完成番茄数
4. 设置页可开关番茄钟卡片
### 自定义倒计时
1. 用户在设置页添加倒计时事件(名称 + 日期)
2. 桌面显示"距离 XX 还有 N 天"
3. 支持多个倒计时事件
4. 过期事件显示"已过去 N 天"或自动归档
## 验收标准
- [ ] 番茄钟25 分钟工作 / 5 分钟休息自动循环
- [ ] 番茄钟:进度环可视化
- [ ] 番番钟:今日完成数显示
- [ ] 倒计时:支持添加/删除事件
- [ ] 倒计时:显示剩余天数
- [ ] 数据持久化,重启后恢复
## 本次范围
- 番茄钟卡片(基础 25/5 循环)
- 自定义倒计时卡片(多事件)
## 非目标
- 番茄钟声音提醒(仅视觉)
- 番茄钟统计报表(日/周/月)
- 倒计时精确到小时/分钟(只显示天数)
## 约束
- 复用现有卡片架构Vue 组件 + Go 数据推送)
- 番茄钟状态前端本地管理localStorage不需要 Go 端计时
- 倒计时事件存储在 config JSON 中
- 布局:单栏模式追加在底部,多栏模式适配现有 grid

View File

@@ -0,0 +1,38 @@
# 系统监控卡片 — 需求契约
> 创建时间2026-05-28
> 状态:需求待确认
## 目标
桌面显示 CPU、内存、网速等系统指标的实时数据。
## 用户场景
1. 桌面卡片显示 CPU 使用率、内存占用、上传/下载网速
2. 数据每秒刷新
3. 紧凑数字 + 进度条风格,不占太多空间
## 验收标准
- [ ] CPU 使用率(百分比 + 进度条)
- [ ] 内存使用率(已用/总量 + 百分比)
- [ ] 网速(上传/下载,自动切换单位 KB/s MB/s
- [ ] 1 秒刷新间隔
- [ ] Go 端 gopsutil 采集
## 本次范围
- CPU / 内存 / 网速 三个指标
## 非目标
- 磁盘 I/O
- GPU 温度/使用率
- 历史曲线图
## 约束
- Go 端 `github.com/shirou/gopsutil/v3` 采集
- evalJS 推送到前端1s 间隔
- 卡片样式紧凑,不抢视觉焦点

View File

@@ -0,0 +1,45 @@
# 网页壁纸 — 需求契约
> 创建时间2026-05-28
> 状态:需求待确认
## 目标
用户输入 URLWebView2 直接渲染任意网页作为桌面壁纸。
## 用户场景
1. 用户在设置页输入网址(如 Shadertoy、CodePen、任意网页
2. 桌面壁纸变为该网页的实时渲染
3. 支持交互式网页(鼠标穿透可选开关)
## 验收标准
- [ ] 支持输入任意 HTTPS URL
- [ ] 网页实时渲染为壁纸
- [ ] URL 持久化,重启恢复
- [ ] 网页加载失败时显示错误提示
## 本次范围
- 单个 URL 渲染为壁纸
## 非目标
- 网页收藏列表
- 网页交互(穿透模式下无法点击)
- 本地 HTML 文件
## 约束
- 复用 WebView2 实例,替换壁纸 HTML 为 `<iframe src="url">`
- iframe 需考虑跨域限制
- 安全禁止加载本地文件路径file:///
## 风险
| 风险 | 缓解 |
|------|------|
| 部分网站禁止 iframe 嵌入 | 提示用户该网站不支持 |
| 网页 JS 报错影响壁纸 | sandbox 属性隔离 |
| 网页持续消耗资源 | 全屏暂停复用 |

View File

@@ -0,0 +1,59 @@
# 视频壁纸 — 需求契约
> 创建时间2026-05-28
> 状态:需求已确认
## 目标
支持将视频文件mp4/WebM/GIF设为桌面壁纸WebView2 `<video>` 标签播放。
## 用户场景
1. 用户在设置页选择"视频壁纸",弹出文件选择对话框(过滤 mp4/WebM/GIF
2. 选中视频后,桌面壁纸立即切换为视频循环播放
3. 视频静音播放,不干扰用户工作
4. 全屏应用(游戏/视频播放器)时自动暂停,退出全屏后恢复
## 验收标准
- [ ] 支持 mp4、WebM、GIF 格式
- [ ] 视频循环播放,无黑帧闪烁
- [ ] 默认静音,设置页可选开启声音
- [ ] 全屏应用时暂停视频,退出恢复
- [ ] 视频文件路径持久化,重启后恢复
- [ ] 视频填充方式cover默认不拉伸变形
- [ ] 设置页可预览当前视频壁纸
## 本次范围
- 本地视频文件作为壁纸
- 视频播放控制(静音/循环/暂停恢复)
## 非目标
- 在线视频 URL 播放(属于"网页壁纸"方向)
- 视频编辑/裁剪
- 多显示器不同视频
## 约束
- WebView2 `<video>` 原生能力,不引入额外播放器库
- 视频文件不嵌入 exe用户自行管理文件路径
- 大视频文件(>500MB需考虑内存占用不做完整 dataURI 转换,用文件 URL
- 复用现有壁纸类型切换架构(`saveWallpaperType`
## 风险
| 风险 | 缓解 |
|------|------|
| 大视频内存占用 | 不转 dataURI`file:///` 协议加载 |
| WebView2 视频解码兼容性 | 测试 H.264/VP9 编码,不支持的格式提示用户 |
| 视频切换时闪烁 | 预加载下一帧CSS transition 淡入 |
## 技术方案
- `wallpaper.go` 新增壁纸类型 `video`
- 视频 HTML 模板:全屏 `<video>` 标签autoplay/loop/muted/cover
- `config.go` 新增 `VideoPath string` 字段
- `settings.go` 新增 `pickVideoFile` 函数(复用文件对话框,过滤视频格式)
- 前端设置页 WallpaperSection 新增"视频壁纸"选项