18 KiB
修改日志 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 的颜色变量区域追加两行别名定义:
/* 别名:兼容组件中使用的 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 修复:新账号首次解密引导 + 账号切换前端数据刷新
问题描述
- 新账号无法在启动器一键解密:切换到从未登录过的新微信账号时,需要手动进入 chatlog.exe 的 TUI 界面执行解密,启动器无法自动引导。
- 账号切换后前端消息不刷新:切换微信账号并重启控制台后,React 前端仍然显示上一个账号的会话列表和消息,没有切换到新账号的数据。
- FastAPI 层账号数据库不切换:
_resolved_wxid全局变量一旦解析成功后永不刷新,账号切换后 Python 业务层仍读取旧账号的知识库数据库。
修改文件明细
1. electron-launcher/main.js
改动:在 keyProcess.on('close') 回调中,读取完 savedWorkDir 后,新增对工作目录的检测逻辑:
- 若工作目录不存在或目录内无
.db文件 → 判定为"新账号首次解密",向渲染进程发送show-decrypt-dialogIPC 事件,弹出引导弹窗。 - 若工作目录已存在
.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 监听:
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、decryptDialogElapsedDOM 引用。 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
改动:
-
去掉 localStorage 冷加载旧账号数据:将
useState(() => loadSessionCache())改为useState([]),避免启动时直接显示上一个账号的旧会话列表。 -
新增账号指纹机制:
calcFingerprint(sessions)—— 取前 3 个会话 id 拼接成指纹字符串。loadAccountFingerprint()/saveAccountFingerprint(fp)—— 读写 localStorage 中的chatlab_account_fingerprint键。
-
getSessions返回后检测账号切换:loadSessions函数(封装了原getSessions调用)在拿到新会话列表后,对比新旧指纹。若指纹不同,说明账号已切换,立即执行:localStorage.removeItem(CACHE_KEY)清除旧缓存。setSelectedRoom(null)重置当前选中群(否则会拿旧群 id 去查询新账号的消息)。
-
每 30 秒轮询一次:新增
useEffect设置 30 秒定时器,静默调用loadSessions(true)(轮询模式不显示 loading 也不报错),以便在用户不刷新页面的情况下自动感知账号切换。
原因:
- 旧代码的
getSessions()只在组件挂载时执行一次,账号切换不触发重新加载。 - 旧代码从 localStorage 取缓存作为初始 state,导致旧账号数据在新账号登录时"闪现"。
- 两处修复合力确保前端始终显示当前微信账号的真实数据。
位置:chatlab-web/frontend/src/App.jsx
修改约 40 行,新增约 30 行
5. chatlog_fastAPI/database.py
改动:
- 新增
import time。 - 新增全局变量
_wxid_last_resolved: float = 0.0和常量_WXID_TTL = 60.0。 get_current_wxid()函数:在命中现有缓存时增加时间判断(now - _wxid_last_resolved) < _WXID_TTL,超过 60 秒强制重新解析。- 在两处成功解析到 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
改动:
- 新增
import asyncio和import logging。 - 新增后台协程
_account_watch_loop():每 60 秒调用一次update_db_path(),静默捕获异常。 - 在
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 问题
问题描述
- AI话题分析"添加群聊"无搜索:群聊列表使用原生
<select>,群多时只能逐条翻找,体验差。 - 知识库文档无分组:文档平铺展示,无法区分属于哪个群聊/话题。
- AI分析无进度条:点击"AI 分析"或"AI 生成知识文档"后,用户不知道当前执行到哪一步。
- 管理消息弹窗"已添加"不可操作:已加入话题的消息显示静态文字"已添加",无法直接点击移除。
修改文件明细
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}赋值到initProgressstate(初始化/完成时重置为 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字段,更新summarizeProgressstate;若无 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):打开独立数据库连接,UPDATEai_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 |
功能新增 | Bug3B(summarize 接口返回 task_id) |
chatlog_fastAPI/services/summary_engine.py |
功能新增 | Bug3B(运行时更新 ai_tasks 进度状态) |