Files
Qt_DesktopPet/docs/implementation_plan.md
T

658 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# QtDesktopPet 实施计划
本文档用于把 `Qt_DesktopPet_开发文档.md` 中的总体目标拆成可执行阶段。
说明:
```text
1. Qt_DesktopPet_开发文档.md 是项目总纲,定义长期目标、模块职责和整体约束
2. 本文档是当前实际开发顺序,会在不违背总纲的前提下进一步拆小阶段
3. 如果两份文档的阶段编号不同,以本文档作为当前执行计划
```
总原则:
```text
1. 先让程序跑起来,再逐步完善架构和功能
2. AI 接入放到桌宠内核稳定之后
3. UI 优化作为项目收尾,不阻塞早期功能验证
4. 每个阶段结束后做最小验收,避免问题堆到后期
5. 修改、删除、移动文件前需要先说明风险并获得确认
```
---
## 1. 已确认约定
```text
项目名:QtDesktopPet
当前目录:Qt_DesktopPet
主要平台:Windows 10 / Windows 11
界面框架:Qt Widgets
构建系统:CMake
优先编译链:Qt 6.5.3 + MinGW 11.2.0 + Ninja
默认角色包:shiroko
AI 接入:放到后期阶段
UI 优化:所有核心功能调试正常后再做
远程仓库:https://git.emoera.com/Make/Qt_DesktopPet.git
```
---
## 2. 本机工具检查结果
当前已检查到:
```text
Git2.51.0.windows.1
CMake3.29.3
Qt6.5.3
Ninja1.12.0
MinGW g++11.2.0
MinGW mingw32-make4.2.1
```
相关路径:
```text
Qt MinGW KitD:/Qt/6.5.3/mingw_64
Qt MSVC KitD:/Qt/6.5.3/msvc2019_64
MinGW 工具链:D:/Qt/Tools/mingw1120_64/bin
CMakeD:/Qt/Tools/CMake_64/bin/cmake.exe
NinjaD:/Qt/Tools/Ninja/ninja.exe
```
注意:
```text
1. 当前 PATH 中的 qmake 默认指向 msvc2019_64
2. g++ 未直接出现在 PATH 中
3. 使用 MinGW 构建时,应显式指定 Qt MinGW 路径和编译器路径
```
建议 CMake 配置方式:
```powershell
cmake -S . -B build/mingw-debug -G Ninja `
-DCMAKE_BUILD_TYPE=Debug `
-DCMAKE_PREFIX_PATH=D:/Qt/6.5.3/mingw_64 `
-DCMAKE_C_COMPILER=D:/Qt/Tools/mingw1120_64/bin/gcc.exe `
-DCMAKE_CXX_COMPILER=D:/Qt/Tools/mingw1120_64/bin/g++.exe
```
---
## 3. 角色包约定
`resources/characters/shiroko` 目录作为当前默认内置角色包。内置角色按 `resources/characters/<characterId>/` 组织,用户导入角色复制到 `QStandardPaths::AppDataLocation/characters/<characterId>/`
已检查到的结构:
```text
resources/characters/shiroko/
├── character.json
├── preview.png
├── README.md
├── idle/
├── talk/
├── think/
├── sleep/
├── happy/
├── drag/
└── error/
```
当前素材版本:`2.1.0-stable`
当前帧数:
```text
idle 30 帧
talk 20 帧
think 30 帧
sleep 30 帧
happy 20 帧
drag 30 帧
error 20 帧
```
需要注意:
```text
1. character.json 中 base.width/base.height 当前为 512x512
2. 当前实现已接入状态级懒加载:enableLazyLoad=true 时先保存帧路径,状态首次播放时再加载对应帧
3. 如果项目公开发布或推送远程仓库,需要确认 shiroko 素材版权和再分发权限
4. 版权不明确前,不应把它作为正式开源发布素材承诺
5. 当前已接入主线程分批预热和状态级 LRU 卸载,并避免低缓存上限下的重复预热/卸载循环;尚未做后台线程预热、单帧级缓存和长期压测记录
```
---
## 4. 阶段 0:仓库与工程准备
目标:
```text
建立可回滚、可构建的工程基础,不写复杂业务逻辑。
```
已确定操作:
```text
1. 初始化 Git 仓库
2. 配置 origin 为 https://git.emoera.com/Make/Qt_DesktopPet.git
3. 新增实施计划文档
```
后续待做:
```text
1. 创建 .gitignore
2. 创建 CMakeLists.txt
3. 创建 main.cpp
4. 创建 src/、resources/ 等基础目录
5. 建立 resources/characters/<characterId> 角色包目录约定
6. 创建最小 README.md
7. 确认 LICENSE 是否采用 MIT
```
验收标准:
```text
1. Git 仓库存在
2. origin 配置正确
3. CMake 能完成配置
4. 空项目或最小窗口项目能编译
```
需要确认:
```text
1. 是否创建 .gitignore
2. 是否创建 MIT LICENSE
3. 是否将默认角色包作为文件型内置资源保留在 resources/characters/shiroko
4. 是否立即创建最小 Qt 工程
```
---
## 5. 阶段 1:最小可运行桌宠窗口
目标:
```text
先让程序启动并显示一个可交互的透明桌宠窗口。
```
只做:
```text
1. Qt Widgets + CMake 工程
2. main.cpp
3. PetWindow
4. 透明无边框窗口
5. 显示单张占位 PNG 或 shiroko preview.png
6. 鼠标拖动
7. 右键退出
8. 置顶开关
```
暂不做:
```text
1. 完整角色包加载
2. 多状态动画
3. 状态机
4. 托盘
5. 配置系统
6. 日志系统
7. AI 接入
8. UI 美化
```
验收标准:
```text
1. 程序能编译
2. 程序能启动
3. 窗口透明无边框
4. 图片能显示
5. 鼠标能拖动窗口
6. 右键菜单能退出
7. 置顶开关生效
```
---
## 6. 阶段 2A:角色包最小读取
目标:
```text
先把 shiroko 角色包作为结构化数据读进程序,暂不播放动画。
```
只做:
```text
1. CharacterPackage
2. CharacterPackageLoader
3. 读取 resources/characters/shiroko/character.json
4. 校验 schemaVersion
5. 校验 defaultState
6. 校验 states
7. 读取 idle 状态配置
8. 收集 idle 帧路径
9. PetWindow 显示 idle 第一帧
10. 加载失败时回退 preview.png 或内置占位图
```
暂不做:
```text
1. 多角色切换
2. 角色导入界面
3. AnimationClip
4. FrameAnimator
5. QTimer 帧动画
6. 完整状态机
7. AI 联动
```
验收标准:
```text
1. 能读取 resources/characters/shiroko/character.json
2. 能获取 idle 状态帧路径列表
3. 能显示 idle 第一帧
4. 不在 paintEvent 中加载图片
5. character.json 缺失或损坏时程序不崩溃
6. idle 状态缺失时程序不崩溃
```
---
## 7. 阶段 2Bidle 帧动画
目标:
```text
在角色包读取稳定后,把 idle 第一帧显示升级为按 FPS 播放 PNG 序列帧。
```
只做:
```text
1. AnimationClip
2. FrameAnimator
3. 使用 QTimer 按 idle fps 播放帧
4. 启动后播放 idle 时加载 idle 帧到内存
5. loop=true 时循环播放
6. 仍然只播放 idle 状态
```
暂不做:
```text
1. 多状态切换
2. 状态机
3. 托盘隐藏暂停
4. AI 联动
5. 角色切换
```
验收标准:
```text
1. idle 动画正常播放
2. fps 使用 character.json 配置
3. 不每帧读取硬盘
4. 不在 paintEvent 中加载图片
5. QTimer 间隔不低于 character.json 推导值
6. 图片加载失败时跳过坏帧或回退 preview.png
```
---
## 8. 阶段 3:状态机与多状态动画
目标:
```text
集中管理桌宠状态,避免状态切换逻辑散落在窗口和动画类中。
```
只做:
```text
1. PetStateMachine
2. idle / drag / think / talk / happy / sleep / error
3. 拖动时切换 drag
4. 松开后回 idle
5. 右键菜单提供模拟状态切换
6. loop=false 的状态播放完后切 next
7. 缺失状态回退 idle
```
暂不做:
```text
1. 真实 AI 请求
2. 长期记忆
3. 复杂 sleep 触发策略
4. UI 美化
```
验收标准:
```text
1. 状态切换由 PetStateMachine 决策
2. FrameAnimator 只负责播放动画
3. PetWindow 不堆积复杂状态判断
4. shiroko 的多个状态动画都能被触发
```
---
## 9. 阶段 4:托盘、配置、日志
目标:
```text
补齐常驻桌面应用的基础设施。
```
只做:
```text
1. TrayController
2. 托盘显示 / 隐藏桌宠
3. 托盘退出
4. ConfigManager
5. 保存窗口位置、置顶状态、缩放、性能模式
6. Logger
7. 基础日志轮转
8. app config、AI config 和 conversation history 损坏时备份为带时间戳的 .broken 文件
```
暂不做:
```text
1. AI 配置界面
2. 角色包市场
3. 自动更新
4. 安装器实机验证和发布流程自动化
```
验收标准:
```text
1. 隐藏到托盘后动画暂停
2. 重新显示后动画恢复
3. 重启后窗口位置恢复
4. 配置损坏不会导致程序崩溃
5. 日志不会无限增长
```
---
## 10. 阶段 5:稳定性与性能检查
目标:
```text
在接入 AI 前,先确认桌宠内核稳定。
```
检查内容:
```text
1. 启动后静置 CPU 和内存
2. idle 动画连续播放
3. 隐藏到托盘后 CPU 是否下降
4. 重复显示 / 隐藏
5. 重复切换状态
6. 删除或破坏 character.json 后是否兜底
7. 删除部分状态目录后是否回退 idle
8. 切换窗口置顶和缩放是否稳定
```
验收标准:
```text
1. 空闲 CPU 占用低
2. 内存不随时间持续增长
3. 没有明显资源泄漏
4. 常见资源损坏不会崩溃
```
---
## 11. 阶段 6AI 接入
目标:
```text
在桌宠内核稳定后,实现 OpenAI Compatible 非流式对话闭环。
```
只做:
```text
1. LLMProvider
2. OpenAICompatibleProvider
3. ConversationManager
4. Base URL / API Key / Model / Path 配置
5. QNetworkAccessManager 异步请求
6. 请求超时
7. 同时只允许一个请求
8. think -> talk -> idle
9. 失败 -> error -> idle
10. 气泡显示 AI 回复或错误提示
```
暂不做:
```text
1. 流式输出
2. 自定义 Body Template
3. 多 Provider 市场
4. 语音输入
5. 语音朗读
6. 长期记忆
```
验收标准:
```text
1. 能发送一条消息并显示回复
2. Base URL 为空时有提示
3. API Key 为空时有提示
4. Model 为空时有提示
5. 错误 API Key 不崩溃
6. 错误 URL 或超时不崩溃
7. 日志不输出完整 API Key、Authorization Header、完整消息正文和完整错误响应正文
8. 对话历史不会无限增长
```
---
## 12. 阶段 7UI 优化与收尾
目标:
```text
核心功能可用后,再统一处理视觉体验和易用性。
```
只做:
```text
1. 优化右键菜单结构
2. 优化气泡样式
3. 优化设置界面布局
4. 优化错误提示文案
5. 优化 README 截图和说明
6. 检查 DPI 和多屏表现
7. 整理发布包
```
发布包排除:
```text
tools/
docs/
reports/
build/
dist/
release_packages/
.git/
```
暂不做:
```text
1. 新增大功能
2. 插件系统
3. 角色包市场
4. 在线素材下载
```
验收标准:
```text
1. Windows 10 / Windows 11 基本体验正常
2. 无 Qt 开发环境机器上可运行
3. README 能指导用户构建和配置
4. 素材版权、AI 隐私和 API Key 本地保存说明齐全
```
---
## 13. 当前项目进度
截至当前工作区,项目已经完成以下内容:
```text
1. 阶段 0 工程基础:
已有 .gitignore、CMakeLists.txt、main.cpp、src/、docs/ 等基础结构
LICENSE 已采用 MIT,版权主体为 Make
2. 阶段 1 最小桌宠窗口:
已实现透明无边框窗口、拖动、右键菜单、置顶切换
已支持双击桌宠打开聊天输入框
3. 阶段 2A 角色包最小读取:
已有 CharacterPackage / CharacterPackageLoader
能读取 resources/characters/shiroko/character.json 并收集状态帧路径
4. 阶段 2B idle 帧动画:
已新增 AnimationClip / FrameAnimator
当前实现会把当前角色包状态帧加载为 QPixmap 缓存,避免每帧读硬盘
5. 阶段 3 状态机初版:
已新增 PetStateMachine
已支持 idle / drag / think / talk / happy / sleep / error 的基础请求、拖动优先和缺失状态回退 idle
已补充流式聊天过程中的状态保持:等待首段回复时保持 think,输出期间保持 talk
6. 阶段 4 基础设施:
已新增 PetView,拆分显示职责
已新增 TrayController,支持托盘显示、隐藏、退出
已新增 ConfigManager,保存窗口位置、置顶状态和部分预留性能字段
已新增 Logger,支持文件日志和基础轮转
7. 阶段 5 稳定性与性能检查:
已做过一轮人工稳定性观察,包括静置、idle 动画、托盘隐藏/显示、重复状态切换和资源损坏兜底
已新增开发用性能采样脚本 tools/perf_sample.ps1
已新增稳定性检查记录模板 docs/performance_stability_check.md
当前尚未形成长期压测记录
8. 阶段 6 AI 接入:
已新增 LLMProvider / OpenAICompatibleProvider / GoogleGeminiProvider / ConversationManager
已支持 OpenAI Compatible 异步请求、超时、取消、错误提示和网络诊断日志
已支持 Google Gemini generateContent / streamGenerateContent、x-goog-api-key、contents 多轮上下文和 systemInstruction
已支持 SSE 流式输出,气泡中流式显示,历史面板只记录最终对话
已限制同一时间只允许一个 AI 请求
已避免在日志中输出完整 API Key、Authorization Header、完整消息正文和完整错误响应正文
9. 阶段 7 UI 基础优化:
已新增 ChatBubble、ChatInputDialog、ChatHistoryPanel、SettingsDialog
已支持右键聊天、显示对话、取消 AI 请求、清空对话、设置
已删除临时 AI 测试入口和气泡测试入口
已将 AI 连通性测试迁移到设置页
已支持 OpenAI / Google / DeepSeek / Custom 配置分 Provider 保存
已移除废弃 Provider 配置入口,并在读取旧配置时清理废弃 Provider 配置
已支持内存历史上限和可选本地历史保存
已支持应用设置页:缩放、性能模式、隐藏暂停、懒加载、动画预热、动画缓存上限、隐藏时释放动画缓存
已将 AppConfig 的 scale / performanceMode / pauseWhenHidden / enableLazyLoad / enableAnimationPrewarm / animationCacheLimitMb / unloadAnimationsWhenHidden 接入运行时
懒加载当前为状态级首次播放加载,并已接入主线程分批预热和状态级 LRU 卸载;单轮预热不会反复重新加载刚被 LRU 卸载的状态
Windows 下 API Key 使用 DPAPI 加密保存,非 Windows 需用户确认后才允许明文保存
运行时资源优先读取可执行文件同级 resources/,找不到时回退到源码目录 resources/
已支持角色文件夹导入、角色切换和删除用户导入角色:验证通过后复制到用户数据目录,验证失败不做文件操作;内置角色不可删除
已新增 Windows 发布打包脚本和 Inno Setup 安装器脚本;脚本不负责 CMake 构建,安装器卸载时可由用户确认后清理当前用户数据目录
已接入单实例限制,重复启动会唤醒已有实例;设置页打开时按当前屏幕居中
已设置 Windows GUI 子系统,Release exe 双击不弹控制台窗口
```
当前实现与计划仍存在差异:
```text
1. SettingsDialog 已支持角色导入、切换、删除用户角色、导出角色和打开用户角色目录;后续更复杂的角色市场/分享仍不在当前范围
2. 对话历史已有内存上限、可选本地保存、关键词搜索、Provider/模型筛选和 Markdown/JSON 导出
3. 状态级懒加载尚未包含后台线程预热、单帧级缓存和长期压测记录
4. README 和开发文档已开始同步当前进度,但仍需随功能继续维护
```
---
## 14. 下一步建议
短期建议:
```text
1. 用户手测单实例和窗口行为:
- 连续双击 exe 只保留一个 QtDesktopPet 进程
- 隐藏到托盘后重复启动应唤醒已有实例
- 设置页打开后重复启动应置前设置页
- 多屏环境设置页应出现在当前屏幕中间
2. 用户手测 Google Gemini Provider
- Google Provider 配置保存
- Gemini 普通回复
- Gemini 流式回复
- 错误 Key / 错误模型错误提示
3. 用户手测流式状态修正:
- 发送消息后等待阶段应保持 think
- 等待阶段拖动松开应回到 think
- 收到首段回复后应进入 talk
- 长文本流式输出期间应持续 talk
4. 用户手测应用设置:
- 缩放比例
- 标准 / 低功耗性能模式
- 隐藏到托盘时暂停动画
- 动画懒加载
```
中期建议:
```text
1. 完善设置界面:
- 更完整的角色管理状态提示
- 后续如果做角色分享,需要补版权提示和包格式校验
2. 使用 tools/perf_sample.ps1 补一轮可重复的稳定性与性能测试记录
3. 使用 tools/perf_sample.ps1 验证状态级 LRU 卸载、主线程分批预热和动画缓存上限策略
4. 做发布包安装/卸载实机验证,并确认 release_packages/ 或根目录安装包输出规则
5. 按 docs/QtDesktopPet_测试清单与验收标准.md 做全功能手测
```
---
## 15. 当前未决问题
后续开始写代码前,需要逐项确认:
```text
1. shiroko 素材是否允许作为正式开源发布素材继续保留在仓库中
2. 角色管理后续是否需要角色分享/市场能力
3. 对话历史后续是否需要更复杂的会话分组、归档或全文索引
```