摘要:客户端界面上看不到积分消耗明细,官方接口也没有暴露流水查询。本文记录我如何从本机 SQLite 数据库里挖出每一笔积分消耗,把请求 ID 解析成精确到毫秒的时间戳,按天、按项目统计出真实账单——并交叉验证了数据可信度(覆盖率 85%)。文末有三个反直觉的实测结论。
我在用 WorkBuddy 的自动化功能做每日积分签到,分是领到了,但很快冒出一个更实际的问题:积分花在哪了?
界面上只有套餐总量,没有逐笔流水。想对账,只能去网页端个人资料页肉眼看总数。作为一个跑了不少自动化任务的人,我很想知道:
翻了本机 WorkBuddy 的数据目录,找到了这个文件:
~/.workbuddy/workbuddy.db用 SQLite 打开后,关键表是 session_usage,里面有个字段叫 credit_json。每一条会话记录对应一个 JSON 对象,结构大致是:
{"01HX8K3M2N4P5Q6R7S8T9V0W1X": 12.5, "01HX8K5A7B9C1D3E5F7G9H1J3K": 0.9}键是请求 ID,值是该次请求消耗的积分数。也就是说,每一次对话请求花的积分,都被原原本本记在了本地。
第一个坑:JSON 的键没有时间戳字段,怎么按天统计?
观察请求 ID 的格式:01HX8K...,这是一个 UUIDv7。UUIDv7 的前 48 位(也就是前 12 个十六进制字符)就是 Unix 毫秒时间戳。所以时间信息一直都在,只是编码在 ID 里:
import json, sqlite3
from pathlib import Path
db = Path.home() / ".workbuddy" / "workbuddy.db"
def ts_ms(uid: str) -> int:
# UUIDv7:前 12 个 hex 字符 = 48 bit 毫秒时间戳
return int(uid[:12], 16)
conn = sqlite3.connect(db)
rows = conn.execute(
"SELECT session_id, credit_json FROM session_usage WHERE credit_json IS NOT NULL"
).fetchall()
by_day = {}
for session_id, cj in rows:
for uid, credits in json.loads(cj).items():
day = time.strftime("%Y-%m-%d", time.localtime(ts_ms(uid) / 1000))
by_day[day] = by_day.get(day, 0.0) + float(credits)
for day in sorted(by_day):
print(day, f"{by_day[day]:.1f}")就这 40 行不到,跑出来按天的积分消耗分布。想再细一层,把 session_id 也分组,就能得到"按天 × 按会话"的交叉表,直接看出哪天哪个项目烧的分最多。
一个必须提醒的坑:不要用 date 命令或手写算术去换算时间戳——直接用上面的十六进制转整型即可,注意是毫秒,除以 1000 再格式化,否则日期全错。
本地挖出来的数,凭什么信?
我拿官方网页端显示的"累计消耗"做了校验:官方数字减去套餐额度,与本地统计出的累计值对比,覆盖率约 85%。差额来自已被清理的会话和后台进程的消耗——本地表只记会话内请求。这个误差方向和数量级都合理,所以按天、按项目的相对分布是可信的。
1. 执行型任务便宜到可以忽略。
自动发一条闲鱼商品帖,实测只花 0.9~1.2 积分。跑一整天所有自动化线(签到、发帖、巡查、台账),合计不到 200 分。所谓"自动化很费积分"的担心,实测不成立。
2. 积分几乎全花在"改代码、试新东西"上。
按会话拆开看,纯运转的日子一天一百多分;而凡是搭新管线、调试新工具的日子,单日能冲到 800+。换句话说,"积分不够用"的正解通常不是"多充",而是"少折腾"或把开发时段和日常运转分开算账。
3. 接口给你的"余额"字段可能根本不是余额。
签到接口返回的 total_credits,实测等于连续签到天数 × 每日额度,是"本活动累计发放",不是账户余额。我就曾把它当成余额报出去,后来才发现。要查真实余额,得用另一个接口(注意路径没有 /v2 前缀,带了反而 404):
POST /billing/meter/get-user-resource-summary它按积分包返回总额/已用/剩余,还带套餐名和是否付费用户。这类"字段名会骗人"的坑,最好一次实测就记下来。
1. 本地数据往往比你想的多。 客户端不给流水,不代表数据不在本机。SQLite + 一个 JSON 字段,就够还原出完整账单。动手爬网页或抓包之前,先看看本地文件。
2. ID 里藏着时间。 UUIDv7 已被越来越多系统采用(含分布式数据库、消息队列),记住"前 12 位 hex = 毫秒时间戳"这一条,很多"没有时间字段"的表都能按时间切。
3. 任何统计都要找官方数字对一次账。 本地 85% 的覆盖率解释清楚了,数据才能用;解释不了的部分(比如那 15%)要明说,不能装看不见。
环境说明:本文基于 Windows 桌面端实测(Python 3.13,纯标准库)。数据库文件路径和表结构以你本机实际为准,字段含义建议先用 sqlite3 打开抽查几条再写脚本。
最后一句实话:这些数字是我本机的实测值,你的消耗结构大概率不同——但"先看本地数据、再对一次官方账、然后按金额排优先级"这个方法,是通用的。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。