Files
kefu/2026-08-19-18-27-34/.workbuddy/memory/2026-08-19.md
T
2026-08-27 14:04:28 +08:00

89 lines
6.6 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.
# 2026-08-19 工作日志
## 企业微信聊天记录导出(完成)
**成果**:成功导出 2 个已登录账号的全部聊天记录,共 **2792 条消息、88 个会话**。
**输出文件**(`wxwork_export/` 目录):
- `企业微信聊天记录.csv` / `.xlsx` — 全部消息(账号、会话、时间、发送者、消息类型、内容等 12 列)
- `会话汇总.csv` / `.xlsx` — 88 个会话的消息数与时间范围
- `聊天记录_1688856770803435.csv`(2756 条)、`聊天记录_1688855555743233.csv`(36 条)
- `decrypted/` — 解密后的 SQLite 数据库
**技术要点**:
- 企业微信 5.x 用 wxSQLite3 AES-128-CBC 加密(每页 4096B 独立加密,密钥派生 `MD5(raw_key + page_no(LE) + "sAlT")`)
- 16 字节原始密钥从 `WXWork.exe` 进程内存提取(内存中 `sAlT` 结构:`[key(16B)] + [page_no(4B LE)] + "sAlT"`)
- 已提取 2 个密钥存于 `wxwork_keys.json`:账号 1688856770803435(`db7288a3...`)、1688855555743233(`d18e7f9a...`)
- 表名:`message_table`(非 message)、`conversation_table`(非 session)、`user_table`(非 userinfo)
- 消息内容为 protobuf 编码,需递归解析 length-delimited 字段
**本轮修复的问题**:
1. `SyntaxWarning: invalid escape sequence '\-'` — 正则字符串中 `''` 提前终止字符串,改为中文引号 `“”‘’`
2. 5 条短文本消息(如"在不")被 `extra_content` 二进制替换 — 兜底条件从 `len(content)<3` 改为 `content.strip()` 为空
3. `?` 前缀残留(protobuf 内部 tag/length 字节 0x3F/0x7A 混入文本)— parse_content 中增加模式 A(`T 残留 T` 去重保留后半)和模式 B(前导 ASCII 残留清理,支持后跟中文标点)
**最终质量**:二进制残留 0、?前缀 0、空内容 0、控制字符 0。
**未完成/限制**:
- 8 个历史用户目录未解密(旧账号未登录,密钥不在内存)——需用户登录后重新提取密钥
- 部分 `S:` 群聊无名称显示为"群聊 S:xxxx"
- 脚本需用 venv python 运行(`pycryptodome`、`openpyxl` 装在 `~/.workbuddy/binaries/python/envs/default/`)
## 桌面应用打包(完成)
将导出能力打包为 Windows 桌面应用 **`dist/企业微信导出助手.exe`**(19MB 单文件,PyInstaller onefile + windowed + 自定义图标)。
**GUI 功能**(`wxwork_gui.py`):
- 一键导出全部聊天记录(CSV + Excel,含进度与日志面板)
- "重新提取密钥"按钮:扫描企微进程内存提取所有已登录账号密钥并保存到 exe 旁 `wxwork_keys.json`
- 每日定时自动导出(时间可设,应用运行期间到点自动触发)
- 输出目录可自定义(默认 exe 旁 `wxwork_export/`)、完成后一键打开文件夹
- 配置持久化到 `wxwork_gui_config.json`
**技术要点**:
- managed Python 3.13 无 tkinter → 改用系统 Python 3.11 建 venv:`C:\Users\pc\.workbuddy\binaries\python\envs\gui311`(继承 tkinter,装 pycryptodome/openpyxl/pyinstaller/pillow)
- PyInstaller 打包命令:`pyinstaller --onefile --windowed --name 企业微信导出助手 --icon app_icon.ico wxwork_gui.py`
- 路径兼容 onefile:`APP_DIR = sys.executable` 所在目录(frozen 模式),密钥/配置/输出目录都在 exe 旁
- 验证:exe 启动进程存活 ✅;打包环境完整导出(2792 消息 + xlsx 校验 2793 行)✅
- 交付:dist/ 含 exe + wxwork_keys.json(2 个已提取密钥)+ app_icon.png
## 按天/范围导出改造(完成)
用户需求:聊天记录可按"天数"导出(如只导今天)。
**核心脚本 `wxwork_export_final.py` v2.1**:
- `export_messages(dbs, out_dir, date_from=None, date_to=None)` — 日期范围过滤(含两端)
- CLI:`--days N`(最近 N 天含今天)、`--date YYYY-MM-DD`、`--all`;默认 `--days 1`
- 输出:单天 `按天/YYYY-MM-DD_聊天记录.csv`,多天 `按天/YYYY-MM-DD_至_YYYY-MM-DD_聊天记录.csv`,全量在根目录(原结构不变)
- 解密缓存:`decrypted/` 下已有解密文件时跳过(二次运行 1 秒,首次 1-2 分钟),`decrypt_with_keys(db_base, out_dir, keys_map, use_cache=True)`
- 实测:`--days 1` 今天 0 条正常提示;`--days 2` 正确导出 08-19 的 17 条
**GUI `wxwork_gui.py`**:
- 设置卡片新增「导出范围」下拉:只导今天/最近3天/7天/30天/全部历史(`DAYS_OPTIONS=[1,3,7,30,0]`)
- 导出按钮文字动态化(`_export_btn_text()`):"立即导出今天的聊天记录" / "最近 N 天" / "全部聊天记录"
- `do_export(keys, out_dir, log, days=N)` 计算 date_from/date_to 传给 export_messages;Excel 生成跟随实际 CSV 路径(按天模式在 按天/ 目录生成 xlsx);空范围返回 None 并提示"该时间范围内没有新消息"
- 定时自动导出也按所选范围执行;days 持久化到 config
- 清理 `_auto_loop` 死代码(`or True: pass`)
**打包**:重新 PyInstaller 打包 `dist/企业微信导出助手.exe`(19MB),启动验证 ✅,三种模式(days=2/1/0)打包环境实测通过
## 数据库导出 (CRM 绑定版, 完成)
用户需求:导出数据入库建表、只导出聊天记录、能否取 unionid 做 CRM 绑定。
**关键发现(unionid)**:
- `user_table.unionid` 字段存在且有数据:主账号 386 联系人中 332 个有 unionid(微信外部联系人,`ozynqs...` 开头);内部成员无 unionid 但 `account` 字段是企微 userid
- `message_table.sender_id` = `user_table.id` 可关联:2794 条消息中 1746 条(62%)能拿到 unionid
- 无 unionid 的消息主要是应用消息(489)/朋友圈(227)/图文链接(133) 等非人工对话
**新脚本 `wxwork_export_db.py`**(复用 wxwork_export_final.py 的 decrypt/parse 逻辑):
- 只导出聊天记录:消息表带 `sender_unionid/sender_userid/sender_mobile` 关联列(CRM 绑定键)
- 产出 `crm_import/`:`crm_wecom.db`(SQLite 三表:chat_messages/chat_users/chat_conversations,每次重建)、`聊天记录_仅消息.csv`(干净消息 CSV)、`create_tables_mysql.sql`、`create_tables_sqlite.sql`
- CLI:`--all` / `--days N` / `--date`;chat_users 总是全量(390 联系人,333 带 unionid)
- 实测:全量 2794 条 / 带 unionid 1746 条(62%);CRM 查询示例:高兴亮 669 条、李思佳 111 条
**解析增强(wxwork_export_final.py parse_content)**:
- 模式 C:单数字残留前缀剥离(`^[0-9](?=[\u4e00-\u9fff])(?![\u4e00-\u9fff]{0,2}(?:量词表))`),保护 "3月13日" 等合法文本
- 子串去重:meaningful 中互为子串的短文本跳过(`len(t)>=3`),消除 `A | 子串A` 冗余
- 修复效果:拼接冗余 596 → 0 条;`3关于系统...` 残留清理为干净文本