# 修改日志 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 SDK,chatlog.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 GB(2.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 MB,electron 二进制) ├── 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 MB,Vite + 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.js,keyProcess.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 部分)**:在 `
` 顶部新增 `#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话题分析"添加群聊"无搜索**:群聊列表使用原生 `