小麦出勤率统计表自动填报
把小麦助教的班级与点名数据,按周汇总成 4 个数字,写进腾讯文档《出勤率统计表》
里该老师所在的那一行。
⚠️ 使用前必须做的两件事(硬性要求)
开始任何操作之前,必须先向用户确认这两项,缺一不可:
- 老师姓名(
--teacher)—— 决定表格里填哪一行,也决定去小麦拉谁的班。 - 小麦登录账号 + 密码(
--account/--password)—— 每个老师用自己的账号登录。
> 除非用户明确说"用上次那份/沿用已保存的",否则每次都要问,不要默认复用上次的账号密码。
> 密码只用于本次登录换 token,不会写进任何文件(token 缓存里只有 token,不含密码)。
拿到之后,密码建议用环境变量传入,避免出现在进程列表里:
export XIAOMAI_ACCOUNT='138xxxxxxxx'
export XIAOMAI_PASSWORD='******'
口径(已与用户逐格核对,2026-10-08 定版)
每周为一位老师填 7 个格子:
| 格子 | 含义 | 怎么算 |
|---|---|---|
| C | 在读活跃人数 | 该老师名下所有班(含已结课班)的在读学员去重数 |
| M / P | 带班数 | 名下在读周课班按语言分类的班级个数(Python→M,C++→P) |
| N / Q | 带生数 | 上述班级的在班学员去重数 |
| O / R | 出勤数 | 该周实到人次 ΣattendNumber |
三条容易踩的规则:
- 带班数 / 带生数是"静态基数" —— 它描述"我带了几个班、几个学生",
与本周上没上课无关,所以每周都要填,不能因为没课就留空。 - 没上常规周课 → 出勤数填
0,不是留空。 - ⛔ 集训班不算。班名含
集训/营地/冬令营/夏令营/冲刺的整条排除,
不计入出勤数。(但若它在读,仍属于老师名下班级。)
列位置(1-based,可脚本内改):Python = M/N/O(13/14/15),C++ = P/Q/R(16/17/18),C = 3。
S~V 是公式(总带班/应出勤/实出勤/出勤率),不要写。
用法
Node 18+,无第三方依赖。脚本目录:scripts/
1. 先看该老师名下有哪些班(核对 带班数/带生数/C)
node scripts/weekly_attendance.js --teacher 赵宇琦 --roster
2. 预览某一周(默认只算不写)
# 指定日期区间(左闭右开,TO = 下周一)
node scripts/weekly_attendance.js --teacher 赵宇琦 --from 2026-10-12 --to 2026-10-19
# 或者直接给周内任意一天,自动取周一~周日
node scripts/weekly_attendance.js --teacher 赵宇琦 --week 2026-10-12
3. 确认无误后写入
node scripts/weekly_attendance.js --teacher 赵宇琦 --from 2026-10-12 --to 2026-10-19 --write
带 --write 时会先打印拟填值,写完后自动回读该行做校验。
常用参数
| 参数 | 说明 |
|---|---|
--teacher 姓名 |
必填,老师姓名(表格行 + 小麦班级都按它匹配) |
--account / --password |
小麦账号密码(不给则读环境变量 / ~/.config/xiaomai.env) |
--from / --to |
日期区间 YYYY-MM-DD,一次只填一周 |
--week |
给周内任意一天,自动算周一~周日 |
--roster |
只打印名下班级与四个汇总数,不涉表格 |
--write |
真正写表(默认只预览) |
--file-id |
换一张目标表(默认《出勤率统计表》) |
工作流建议
- 问:老师姓名 + 账号密码。
--roster跑一次,把"带班数/带生数/C"给用户看一眼 —— 班级变动时这几个数会变。- 对目标周跑不带
--write的预览,把拟填的 7 个数报给用户确认。 - 用户点头后再
--write。 - 写入后核对脚本回读的结果,并把"这一周填了什么"回报给用户。
> 写表是外部写操作。未经用户确认不要直接 --write。
常见坑(都在脚本里处理好了,出问题时对照排查)
- token 会"提前失效",且失效时不报错 —— 返回
code=200但数据缺人。
只按缓存时间判断是否复用会得到错误结论。脚本每次请求前先探活(见xiaomai_auth.js)。 - 日期参数传错会被当成"全量查询" —— 若
--from是非法日期(例如把"2026-09-28 2026-10-05"
整串塞进去),new Date()得到 Invalid Date,时间范围变NaN,后端会静默返回全量历史数据。
脚本已加合法性断言,会直接报错退出。 zsh里for w in "a b"; do set -- $w; ...不做词分割 —— 会把整串塞进$1。
一次只跑一周,日期写字面量,别用循环变量拼。- 读腾讯文档的公式格必须
include_formula:true取number_value——
用return_csv:true拿到的是缓存旧值,会读错(曾把 66 读成 65)。 - 讲师行不要写死偏移量 —— 不同月/不同区块的讲师顺序可能不同,
脚本是在区块内按姓名搜索定位的。 PYTHON暑期集训这类班级名同时含python和集训——
分类时必须先判 Python 再判 C++,否则会被误归 C++。- 班级名单别用"点名名单"代替 —— 点课后有人退班,点名名单会多出人。
班级在班人数用student/getStuDigestListCheckPermission,它与getClassDetail.stuNum一致。
更多接口细节见 references/api_reference.md。