Files
get_wechat/CHANGELOG.md

398 lines
18 KiB
Markdown
Raw Permalink 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.
# 修改日志 CHANGELOG
本文件记录每次代码修改的内容、原因与时间,精确到分钟,便于回溯和审查。
**规则:每次修复 Bug 或新增功能,必须在此文件追加一条记录。**
---
## [2026-05-11 01:15] 项目瘦身:清理分发包多余文件
### 背景
项目原始大小 2.3 GB包含构建产物、Go SDK、PyInstaller 输出等开发专用文件,发送给用户体积过大。清理后保留"无痕启动控制台"完整运行所需的最小文件集。
### 删除内容
| 路径 | 大小 | 原因 |
|------|------|------|
| `chatlog_fastAPI/dist/` | 653 MB | PyInstaller 打包输出,不走此 exe 启动 |
| `chatlog_fastAPI/build/` | 206 MB | PyInstaller 中间产物 |
| `electron-launcher/dist/` | 349 MB | electron-builder 安装包,不走此包启动 |
| `go_env/` | 276 MB | 完整 Go SDKchatlog.exe 已编译完毕 |
| `chatlab-web/frontend/dist/` | ~1 MB | Vite 构建输出,走 npm run dev |
| `cmd/` `internal/` `pkg/` `bin/` | <2 MB | Go 源码,不重新编译则无用 |
| `chatlab-web/backend/` | 49 KB | 废弃旧版 Python 后端 |
| `scripts/` `.github/` `.vscode/` | 小 | 开发专用 |
| `main.go` `go.mod` `go.sum` `Makefile` `.goreleaser.yaml` `.gitignore` | 小 | Go 构建文件 |
| `lib/windows_x64/wx_key.exp/.lib/.pdb` | 小 | 链接/调试符号,运行只需 .dll |
| `chatlog_fastAPI/__pycache__/` 等 | 28 KB | Python 字节码缓存,运行时自动重建 |
| `chatlog_fastAPI/chatlog.db` `knowledge.db` `*.spec` `test_wxid.py` `backend_design.md` | 小 | 空文件/调试/设计文档 |
| `test_audio*.py` `test_upload.go.bak` `launcher_error.log` | 小 | 临时调试文件 |
| `README.md` `chatlab.md` `dll调用指南.md` `启动与编译命令指南.md` | 小 | 开发参考文档 |
| `chatlog_fastAPI/knowledge_wxid_*.db` | ~224 KB | 个人账号知识库,用户登录后自动生成 |
**节省:~1.49 GB2.3 GB → 863 MB**
### 保留内容(最小运行集)
```
get_wechat_me/
├── 无痕启动控制台.vbs 启动入口
├── chatlog.exe Go 后端63 MB
├── CHANGELOG.md / README.md / DISCLAIMER.md / LICENSE
├── lib/windows_x64/wx_key.dll
├── electron-launcher/
│ ├── main.js / preload.js / index.html / package.json / package-lock.json
│ └── node_modules/650 MBelectron 二进制)
├── chatlog_fastAPI/
│ ├── main.py / config.py / database.py / scheduler.py
│ ├── .env / requirements.txt
│ ├── routers/ / services/
└── chatlab-web/frontend/
├── src/ / public/ / index.html / vite.config.js / package.json
└── node_modules/150 MBVite + React
```
## [2026-05-11 01:05] Bug 修复:可搜索下拉浮层背景透明
### 问题描述
上一轮新增的"添加群聊"可搜索下拉浮层背景完全透明,条目文字叠在底层内容上,可读性极差。
### 根因
代码中使用了 `var(--surface)``var(--surface-2)` 两个 CSS 变量,但 `index.css``:root` 从未定义这两个变量,浏览器 fallback 为 `transparent`
这两个变量在整个项目(`TopicsPage.jsx``KnowledgePage.jsx``MessageBubble.jsx``SettingsPage.jsx``App.jsx`)中被广泛引用。
### 修改文件明细
#### 1. `chatlab-web/frontend/src/index.css`
**改动**:在 `:root` 的颜色变量区域追加两行别名定义:
```css
/* 别名:兼容组件中使用的 var(--surface) / var(--surface-2) */
--surface: #ffffff; /* 等同于 --bg-surface */
--surface-2: #f0f2f5; /* 等同于 --bg-overlay */
```
**原因**:项目现有的背景变量命名为 `--bg-surface``--bg-overlay` 等,但大量组件使用了更简短的 `--surface`/`--surface-2` 命名。根本修复是在 CSS 中统一补充定义这两个别名,一次修复所有引用,避免逐文件替换。
```
位置chatlab-web/frontend/src/index.css:root 第 6 行后
新增 3 行
```
---
#### 2. `chatlab-web/frontend/src/pages/TopicsPage.jsx`
**改动**:将浮层容器和条目中仍残留的错误变量名手动替换为正确值:
- 浮层容器:`var(--surface)``var(--bg-surface)`
- 条目默认背景:`transparent``var(--bg-surface)`(使其与浮层容器背景一致)
- 条目选中态:`var(--surface-2)``var(--bg-overlay)`
- `onMouseEnter``var(--surface-2)``var(--bg-hover)`
- `onMouseLeave``var(--surface-2)``var(--bg-overlay)`
**原因**:在 CSS 补充别名定义之外,同步将浮层的引用改为语义更明确的 `--bg-*` 系列变量,确保悬停/选中状态的颜色层次感正确(白底 → 悬停浅灰 → 选中深灰)。
```
位置showGroupDropdown 浮层(第 315-340 行)
修改 5 处变量名
```
---
### 总结
| 文件 | 改动性质 | 解决的问题 |
|------|----------|-----------|
| `chatlab-web/frontend/src/index.css` | Bug 修复 | 全局补充 `--surface`/`--surface-2` CSS 变量定义,消除所有相关透明背景问题 |
| `chatlab-web/frontend/src/pages/TopicsPage.jsx` | 变量名规范化 | 浮层下拉列表背景透明,条目悬停/选中状态无法区分 |
---
## [2026-05-10 15:42] Bug 修复:新账号首次解密引导 + 账号切换前端数据刷新
### 问题描述
1. **新账号无法在启动器一键解密**:切换到从未登录过的新微信账号时,需要手动进入 chatlog.exe 的 TUI 界面执行解密,启动器无法自动引导。
2. **账号切换后前端消息不刷新**切换微信账号并重启控制台后React 前端仍然显示上一个账号的会话列表和消息,没有切换到新账号的数据。
3. **FastAPI 层账号数据库不切换**`_resolved_wxid` 全局变量一旦解析成功后永不刷新,账号切换后 Python 业务层仍读取旧账号的知识库数据库。
---
### 修改文件明细
#### 1. `electron-launcher/main.js`
**改动**:在 `keyProcess.on('close')` 回调中,读取完 `savedWorkDir` 后,新增对工作目录的检测逻辑:
- 若工作目录不存在或目录内无 `.db` 文件 → 判定为"新账号首次解密",向渲染进程发送 `show-decrypt-dialog` IPC 事件,弹出引导弹窗。
- 若工作目录已存在 `.db` 文件 → 判定为"已解密账号",直接启动 server不弹窗。
**原因**`chatlog.exe key` 命令执行完毕后会更新 `~/.chatlog/chatlog.json``last_account`,此时读取的 `savedWorkDir` 才是当前账号对应的工作目录。通过检测该目录是否含有解密产物(`.db` 文件),即可区分新旧账号。
```
位置electron-launcher/main.jskeyProcess.on('close') 内,第 251 行附近
新增约 20 行代码
```
---
#### 2. `electron-launcher/preload.js`
**改动**:在 `contextBridge.exposeInMainWorld` 中新增一条 IPC 监听:
```js
onShowDecryptDialog: (callback) => ipcRenderer.on('show-decrypt-dialog', () => callback())
```
**原因**Electron 的 contextIsolation 模式下,渲染进程无法直接访问 `ipcRenderer`,必须通过 `preload.js``contextBridge` 安全暴露。新增的 `show-decrypt-dialog` 事件需要在这里注册后,`index.html` 中的 JS 才能通过 `window.electronAPI.onShowDecryptDialog` 收到通知。
```
位置electron-launcher/preload.js第 19-20 行
新增 1 行
```
---
#### 3. `electron-launcher/index.html`
**改动CSS 部分)**:新增模态弹窗相关样式(`.modal-overlay``.modal-box``.modal-title``.modal-body``.modal-steps``.modal-footer``.modal-spinner` 及其动画)。
**改动HTML 部分)**:在 `<body>` 顶部新增 `#decrypt-dialog` 模态弹窗元素,包含:
- 标题:"🔓 检测到新账号,正在解密数据"
- 操作步骤引导(切换到微信、点击聊天窗口、翻看历史消息)
- 与 chatlog.exe 一致的提示说明
- 底部旋转 spinner + 计时显示
**改动JS 部分)**
- 新增 `decryptDialog``decryptDialogStatus``decryptDialogElapsed` DOM 引用。
- `onDecryptStatus` 回调中额外同步更新弹窗计时器(`decryptDialogElapsed`)。
- `onDecryptReady` 回调中增加 `decryptDialog.classList.remove('show')` 关闭弹窗。
- 新增 `window.electronAPI.onShowDecryptDialog` 监听,收到事件时显示弹窗。
**原因**:用户切换新账号时需要按照 chatlog.exe TUI 中相同的操作提示(点击微信聊天界面)才能完成密钥提取。弹窗承担了原来需要手动进入 TUI 界面的提示职责,实现"一键解密"体验。
```
位置electron-launcher/index.html
新增 ~90 行 CSS + HTML + JS
```
---
#### 4. `chatlab-web/frontend/src/App.jsx`
**改动**
1. **去掉 localStorage 冷加载旧账号数据**:将 `useState(() => loadSessionCache())` 改为 `useState([])`,避免启动时直接显示上一个账号的旧会话列表。
2. **新增账号指纹机制**
- `calcFingerprint(sessions)` —— 取前 3 个会话 id 拼接成指纹字符串。
- `loadAccountFingerprint()` / `saveAccountFingerprint(fp)` —— 读写 localStorage 中的 `chatlab_account_fingerprint` 键。
3. **`getSessions` 返回后检测账号切换**`loadSessions` 函数(封装了原 `getSessions` 调用)在拿到新会话列表后,对比新旧指纹。若指纹不同,说明账号已切换,立即执行:
- `localStorage.removeItem(CACHE_KEY)` 清除旧缓存。
- `setSelectedRoom(null)` 重置当前选中群(否则会拿旧群 id 去查询新账号的消息)。
4. **每 30 秒轮询一次**:新增 `useEffect` 设置 30 秒定时器,静默调用 `loadSessions(true)`(轮询模式不显示 loading 也不报错),以便在用户不刷新页面的情况下自动感知账号切换。
**原因**
- 旧代码的 `getSessions()` 只在组件挂载时执行一次,账号切换不触发重新加载。
- 旧代码从 localStorage 取缓存作为初始 state导致旧账号数据在新账号登录时"闪现"。
- 两处修复合力确保前端始终显示当前微信账号的真实数据。
```
位置chatlab-web/frontend/src/App.jsx
修改约 40 行,新增约 30 行
```
---
#### 5. `chatlog_fastAPI/database.py`
**改动**
1. 新增 `import time`
2. 新增全局变量 `_wxid_last_resolved: float = 0.0` 和常量 `_WXID_TTL = 60.0`
3. `get_current_wxid()` 函数:在命中现有缓存时增加时间判断 `(now - _wxid_last_resolved) < _WXID_TTL`,超过 60 秒强制重新解析。
4. 在两处成功解析到 wxid 时,均更新 `_wxid_last_resolved = time.time()`
**原因**:原代码中 `_resolved_wxid` 一旦解析成功就永久缓存,账号切换后 Python 层仍用旧 wxid 路由到旧知识库数据库文件(`knowledge_<旧wxid>.db`),导致 AI 话题分析、知识库搜索等功能数据错误。60 秒 TTL 平衡了性能与准确性。
```
位置chatlog_fastAPI/database.py第 1-53 行
修改约 10 行,新增约 5 行
```
---
#### 6. `chatlog_fastAPI/main.py`
**改动**
1. 新增 `import asyncio``import logging`
2. 新增后台协程 `_account_watch_loop()`:每 60 秒调用一次 `update_db_path()`,静默捕获异常。
3.`lifespan` 上下文管理器中,`yield` 前用 `asyncio.create_task` 启动该协程,`yield` 后取消任务并等待清理。
**原因**:仅靠 `database.py` 的 TTL 机制还不够——TTL 只在被调用时才重新检测,如果 FastAPI 长时间运行无请求则无法触发。后台轮询任务确保即使 FastAPI 在后台静默运行,账号切换也能在约 60 秒内被感知并切换数据库。
```
位置chatlog_fastAPI/main.py全文
修改约 5 行,新增约 15 行
```
---
### 总结
| 文件 | 改动性质 | 解决的问题 |
|------|----------|-----------|
| `electron-launcher/main.js` | 功能新增 | 新账号自动检测 + 弹窗触发 |
| `electron-launcher/preload.js` | IPC 暴露 | 渲染进程收到新账号通知 |
| `electron-launcher/index.html` | UI 新增 | 首次解密引导弹窗,等同 chatlog.exe TUI 提示 |
| `chatlab-web/frontend/src/App.jsx` | Bug 修复 + 功能增强 | 账号切换后前端立即显示新账号数据 |
| `chatlog_fastAPI/database.py` | Bug 修复 | 账号切换后 Python 层自动切换知识库数据库 |
| `chatlog_fastAPI/main.py` | 功能新增 | 后台定期检测账号变化,无需依赖请求触发 |
---
## [2026-05-11 00:32] Bug 修复AI话题分析 & 知识库 4 个 UI 问题
### 问题描述
1. **AI话题分析"添加群聊"无搜索**:群聊列表使用原生 `<select>`,群多时只能逐条翻找,体验差。
2. **知识库文档无分组**:文档平铺展示,无法区分属于哪个群聊/话题。
3. **AI分析无进度条**:点击"AI 分析"或"AI 生成知识文档"后,用户不知道当前执行到哪一步。
4. **管理消息弹窗"已添加"不可操作**:已加入话题的消息显示静态文字"已添加",无法直接点击移除。
---
### 修改文件明细
#### 1. `chatlab-web/frontend/src/pages/TopicsPage.jsx`
**Bug 1 修复 — 群聊选择改为可搜索下拉**
- 将"添加群聊"面板内的原生 `<select>` 替换为自定义可搜索组件:`<input>` 搜索框 + 绝对定位浮层列表。
- 新增 state`groupSearchKeyword``showGroupDropdown`
- 浮层列表实时过滤(同时匹配群聊名称和群 ID点击某项后填充输入框并收起浮层。
```
位置showAddGroup 块内(第 268 行附近)
新增约 45 行 JSX
```
**Bug 3A 修复 — AI分析进度条**
- `handleInitGroup` 轮询中新增 `JSON.parse(task.progress)` 解析,将 `{processed, total}` 赋值到 `initProgress` state初始化/完成时重置为 null
- 在"AI 分析"按钮下方插入进度条 UI显示 `processed/total` 数值 + 彩色进度条宽度由百分比驱动0.5s 过渡动画)。
- 新增 state`initProgress`
```
位置handleInitGroup 函数(第 117 行)+ 按钮区域(第 336 行)
修改约 15 行,新增约 22 行
```
**Bug 3B 修复 — AI生成知识文档进度条**
- `handleSummarize` 改为接收后端返回的 `task_id``res.data.task_id`),若存在则用 `getTask(task_id)` 每 3 秒轮询,解析 `progress` 字段,更新 `summarizeProgress` state若无 task_id 则 fallback 5 秒后刷新。
- 在"AI 生成知识文档"按钮下方插入进度条 UI与 3A 样式一致,宽度 180px
- 新增导入:`getTask`(已在 `api/index.js` 中定义)。
- 新增 state`summarizeProgress`
```
位置handleSummarize 函数(第 241 行)+ 按钮区域(第 422 行)
修改约 12 行,新增约 40 行
```
**Bug 4 修复 — "已添加"改为红色"移除"按钮**
- 管理消息弹窗左栏:将 `topicSeqs.has(Number(m.id))` 为真时显示的 `<span>已添加</span>` 改为红色 `<button> 移除</button>`,点击调用已有的 `handleRemoveMsg(Number(m.id))`
- 样式:`color: 'var(--danger)'``borderColor: 'rgba(243,139,168,0.4)'`
```
位置:管理消息弹窗左栏消息列表(第 531 行)
修改 1 处,约 6 行
```
---
#### 2. `chatlog_fastAPI/routers/knowledge.py`
**Bug 2 后端 — SQL 联表返回 group_name**
- 两处 `SELECT`(普通查询 + FTS 关键词查询)均扩展为:
- 新增 `LEFT JOIN groups g ON t.group_id=g.id`
- 新增返回字段:`t.group_id``g.name as group_name`
- 普通查询的 `ORDER BY` 改为 `ORDER BY g.name, k.updated_at DESC`,使同一群聊的文档聚在一起。
```
位置chatlog_fastAPI/routers/knowledge.py第 18-33 行
修改约 8 行
```
---
#### 3. `chatlab-web/frontend/src/pages/KnowledgePage.jsx`
**Bug 2 前端 — 文档列表按群聊分组展示**
- 将原来平铺的 `docs.map(...)` 改为先按 `doc.group_name`(后端新增字段)分组,渲染时在每个群聊前加粘性标题头(灰色小号大写文字,背景 `var(--surface-2)``position: sticky`)。
- `group_name` 为空时归入"未知群聊"分组。
```
位置KnowledgePage.jsx第 96-114 行
修改约 20 行,新增约 30 行
```
---
#### 4. `chatlog_fastAPI/routers/topics.py`
**Bug 3B 后端 — summarize 接口返回 task_id**
- `POST /api/topics/{id}/summarize` 在调用 `run_summarize` 前,先向 `ai_tasks` 表插入一条类型为 `'summarize'`、状态为 `'running'` 的记录,并把 `task_id` 随响应返回:`{"ok": True, "task_id": task_id}`
- 前端可用 `getTask(task_id)` 轮询该记录的 `status`/`progress` 字段以展示进度。
```
位置chatlog_fastAPI/routers/topics.py第 142-151 行
修改约 10 行
```
---
#### 5. `chatlog_fastAPI/services/summary_engine.py`
**Bug 3B 后端 — run_summarize 接收 task_id完成/出错时更新状态**
- 函数签名新增可选参数 `task_id: int | None = None`
- 新增内部辅助函数 `_update_task(status, processed, total)`打开独立数据库连接UPDATE `ai_tasks` 记录的 `status``progress`
- 在以下关键节点调用 `_update_task`
- 任务开始:`running, 0, 1`
- 无消息/无有效消息/LLM 失败:`error, 0, 1`
- 生成完成:`done, 1, 1`
- 新增 `import json`(用于序列化 progress 字段)。
```
位置chatlog_fastAPI/services/summary_engine.py第 65-190 行
修改约 8 行,新增约 20 行
```
---
### 总结
| 文件 | 改动性质 | 解决的问题 |
|------|----------|-----------|
| `TopicsPage.jsx` | UI 替换 + 功能新增 | Bug1可搜索下拉+ Bug3A初始化进度条+ Bug3B生成知识文档进度条+ Bug4移除按钮 |
| `KnowledgePage.jsx` | UI 重构 | Bug2知识库按群聊分组展示 |
| `chatlog_fastAPI/routers/knowledge.py` | SQL 扩展 | Bug2返回 group_name 字段) |
| `chatlog_fastAPI/routers/topics.py` | 功能新增 | Bug3Bsummarize 接口返回 task_id |
| `chatlog_fastAPI/services/summary_engine.py` | 功能新增 | Bug3B运行时更新 ai_tasks 进度状态) |