SCU-CLI:四川大学校园服务命令行
scu 把四川大学各类校园服务封装成机器可读的命令行,面向 AI 与脚本设计。统一认证登录后,教务/微服务/缴费/体测/第二课堂的子系统 SSO 由 CLI 自动建立,会话过期自动重新认证并重放请求一次——这些对你完全透明,只需调用业务命令。
1. 安装 CLI
先探测:scu --version 能跑通则跳过本节。
方式 A — npm(首选,一条命令):
npm install -g @the-brotherhood-of-scu/scu-cli
需要 Node.js ≥ 18。自动按平台/架构(linux / darwin / windows × amd64 / arm64)下载二进制(SHA256 校验),并把本 Skill 安装到 ~/.claude/skills/scu-cli/(用户设 SCU_CLI_NO_SKILL=1 时会跳过)。
方式 B — GitHub Release 二进制(无 Node 环境时;资产附带 checksums.txt 可校验 SHA256):
| 平台 | 资产 |
|---|---|
| Linux amd64 / arm64 | scu-linux-amd64 / scu-linux-arm64 |
| macOS Intel / Apple Silicon | scu-darwin-amd64 / scu-darwin-arm64 |
| Windows amd64 / arm64 | scu-windows-amd64.exe / scu-windows-arm64.exe |
# Linux / macOS(以 linux-amd64 为例)
curl -L -o scu https://github.com/The-Brotherhood-of-SCU/SCU-CLI/releases/latest/download/scu-linux-amd64
chmod +x scu && sudo mv scu /usr/local/bin/
# Windows PowerShell
Invoke-WebRequest -Uri https://github.com/The-Brotherhood-of-SCU/SCU-CLI/releases/latest/download/scu-windows-amd64.exe -OutFile scu.exe
方式 C:go install github.com/The-Brotherhood-of-SCU/SCU-CLI/cmd/scu@latest
验证:scu --version、scu --help。
2. 登录(统一认证)
scu login -u <学号> -p <密码>
- 验证码由 CLI 内置本地 OCR 自动识别,识别错误自动换新验证码重试(最多 5 次),不需要人工参与。
- 登录态持久化在凭据文件(Linux/macOS
~/.config/scu-cli/,Windows%APPDATA%\scu-cli\,0600 权限;可用SCU_CLI_CONFIG_DIR覆盖),本地 1 小时 TTL;过期后任何命令都会用保存的凭据 + OCR 静默重新登录,对你透明。 -p会进入 shell 历史/进程列表;共享环境建议隔离SCU_CLI_CONFIG_DIR。- 查状态:
scu whoami(返回 principal、本地 TTL 是否到期及剩余秒数 expires_in_seconds);退出:scu logout(清除凭据)。 - 非 TTY 保证:所有交互式输入(学号/密码/人工验证码)仅在 stdin 是终端时才会发起,非 TTY 下立即报错退出、绝不阻塞——所以调用时必须把参数带齐。
- 备用(OCR 连续失败时):
scu captcha --solve取验证码(输出captcha_code+ OCR 结果 + 图片路径),再scu login -u <学号> --captcha-code <code> --captcha-text <文本>。
3. 输出约定(必读)
所有命令向 stdout 输出 JSON 包层,诊断信息走 stderr(解析时只读 stdout):
{"ok": true, "data": { ... }}
{"ok": false, "error": {"kind": "unauthenticated", "message": "..."}}
失败时退出码非 0。error.kind 处理建议:
| kind | 含义 | 处理 |
|---|---|---|
unauthenticated |
未登录或会话失效且自动恢复失败 | 引导用户重新 scu login 后重试 |
service |
服务端业务错误 / 网络错误 | 按 message 判断,不要盲目重试 |
login |
登录阶段错误(验证码/密码错误等) | 修正后重试 |
captcha |
验证码获取/识别失败 | 用 scu captcha --solve 人工通道重试 |
logout |
清除本地凭据失败 | 检查配置目录权限 |
config |
本地配置/凭据文件错误 | 检查配置目录(必要时删除凭据文件重新 login),不要重试 |
input |
命令参数缺失/格式错误 | 按 message 修正参数,不要重试 |
环境变量(按需设置,均有默认值):
| 变量 | 作用 |
|---|---|
SCU_CLI_CONFIG_DIR |
覆盖配置目录(凭据、快照存放位置) |
SCU_CLI_TIMEOUT |
单次 HTTP 请求超时秒数(默认 30;校园网不通时快速报错而非挂起) |
SCU_CLI_COMPACT |
设为 1 输出单行紧凑 JSON(省 token;默认缩进便于人工排障) |
4. 参数发现链(所有 num/id/code 都不用猜)
每个编号参数都有无参的根命令逐级发现;每条命令的 --help 也标注了参数来源:
| 参数 | 来源 |
|---|---|
planCode |
scu zhjw semesters 输出的 value(如 2025-2026-2-1) |
| 校区/教学楼编号与名称 | scu zhjw classroom index → campuses[].campusNumber/campusName、buildings[].teachingBuildingNumber/teachingBuildingName |
| 学院/年级代码 | scu zhjw program colleges / grades 输出的 value |
fajhh(培养方案号) |
scu zhjw program search 输出记录 |
urlPath(课程详情路径) |
scu zhjw program detail 输出 treeList 节点 |
| 院系/专业/班级编号 | scu zhjw class options → subjects <dept> → class list(记录含 id.executiveEducationPlanNumber、id.classNum) |
schoolCode/regCode/unitCode |
scu balance campus → buildings → units,每级输出 [{name, code}],上一级 code 是下一级入参 |
activityLibraryId |
scu ccyl activities 输出记录的 id |
activityId |
scu ccyl lib-detail <activityLibraryId> 输出中各场次活动的 id |
--score-type |
scu ccyl score-types <activityLibraryId> 输出的能力类型 id |
creditId |
scu ccyl credits 输出记录 |
| 报修地址 id | scu repair addresses(无地址先 repair save-address) |
| 报修项目 id | scu repair projects <area_id> 输出的叶子项目 value |
| 报修预约日期/时段 | scu repair book-dates → book-times <date> |
| 报修工单 id / 评价 repairId | scu repair list 输出的 id → repair detail 输出的 finished_info.repair_id |
| 无感设备 MAC | scu passpoint devices 输出的 user_mac |
5. 教务系统 scu zhjw
scu zhjw week # 当前教学周(含 on_vacation)
scu zhjw semesters # 学期列表(value 为 planCode,如 2025-2026-2-1)
scu zhjw schedule --plan 2025-2026-2-1 # 课表(原始 JSON)
scu zhjw grades # 及格成绩
scu zhjw grades --scheme # 方案成绩
scu zhjw exams # 考表(考试安排)
scu zhjw completion # 计划完成度(多份培养方案:主修/辅修各一份,输出 plans[])
scu zhjw calendar # 校历(免认证,网络优先、失败回退本地缓存)
# ICS 日历导出(--ics 必须带文件路径值;输出 JSON 含 file/events 等元信息)
scu zhjw schedule --plan 2025-2026-2-1 --ics schedule.ics
# 学期起始日自动从校历匹配(planCode → 校历学期名);匹配失败时用 --start-date 2026-03-02 手动指定
# 节次时段按课程地点自动探测校区(江安/望江/华西),也可用 --campus 江安 强制
scu zhjw exams --ics exams.ics # 考表导出(日期时间无法解析的考试自动跳过,见 skipped_unparseable)
scu zhjw calendar --ics calendar.ics # 校历导出(全天事件,开学/假期/考试周)
# 教室查询(编号链:index → types → query)
scu zhjw classroom index # 校区与教学楼列表(所有编号的来源)
scu zhjw classroom types --campus-num 1 --building-num 101 --campus-name 江安 --building-name 一教A
scu zhjw classroom query --campus-num 1 --building-num 101 --date 2026-08-14
# query 可选:--type 教室类型代码(来自 types)--name 教室名 --seat-from/--seat-to 座位数区间
# 培养方案(编号链:colleges/grades → search → detail → course)
scu zhjw program colleges # 学院列表(value = --college)
scu zhjw program grades # 年级列表(value = --grade)
scu zhjw program search --college 301 --grade 2023 # 记录含 fajhh
scu zhjw program detail <fajhh> # 方案详情(treeList 节点含 urlPath)
scu zhjw program course <urlPath> # 课程详情
# 班级课表(编号链:options → subjects → list → schedule)
scu zhjw class options # 筛选项(semesters/grades/departments 的 value)
scu zhjw class subjects <departmentNum> # 专业列表(含 subjectCode)
scu zhjw class list --plan 2025-2026-2-1 --dept 301 # 记录含 id.executiveEducationPlanNumber / id.classNum
scu zhjw class schedule <planCode> <classCode> # 即上一步输出的两个字段
# 课程课表(按教学班查排课;编号链:course index → search → schedule)
scu zhjw course index # 筛选项(semesters/departments/categories 的 value)
scu zhjw course search --name 高等数学 --page-size 10 # 课程(教学班)列表
# 可选筛选:--semester --department --name --code --seq --category --page
scu zhjw course schedule <ZXJXJHH> <KCH> <KXH> # 三元组取自 search 记录
6. 用户信息 scu user(微服务)
scu user info # 基本信息(realname 姓名、role.number 学号等)
scu user labels # 用户标签
scu user devices # 校园网在线设备(输出 device_id / ip)
scu user offline --device-id <id> --ip <ip> # 强制指定设备下线(参数取自 devices 输出)
scu user transactions [--sdate YYYY-MM-DD] [--edate YYYY-MM-DD] # 校园卡扣费/充值明细(日期可省略,省略时服务端返回最近几天;输出 transactions 平铺明细 + by_day 每日消费合计 + total_cost/balance。余额字段取自最近一笔交易,余额本身也可经 scu user labels 查看)
7. 缴费平台 scu balance
房间参数逐级发现(各级输出均为 [{name, code}],上一级的 code 是下一级的入参):
scu balance campus # 校区列表,code = schoolCode
scu balance buildings <schoolCode> # 楼栋列表,code = regCode
scu balance units <schoolCode> <regCode> # 单元列表,code = unitCode
# 查询余额(--type 1 照明电费 / 2 空调电费;学号与姓名自动取自 user info)
# 首次查询需绑定房间:
scu balance query --type 1 --school-code 1 --reg-code 101 --unit-code 1 --room 101
# 之后直接查询已绑定房间:
scu balance query --type 1
scu balance query --type 2 # 空调电费
# 余额趋势:每次 query 成功自动记录本地快照(按房间+类型归集,保留 365 天)
scu balance trend --type 1 # 日均电费/日均度数/累计消耗 + daily_points 序列
scu balance trend --type 1 --days 30 # 只统计最近 30 天
trend 说明:快照按北京日历日聚合(每日取最后一条),充值段(余额上升)自动跳过并计入
skipped_recharge_segments;record_count 为 0 时表示还没积累快照(用 note 字段的话术回复用户,
过几天查询后再看)。
8. 体测系统 scu fitness
scu fitness notices # 体测通知
scu fitness score # 今年体测成绩
scu fitness score --year 2025
9. 第二课堂 scu ccyl
ID 发现链:activities(→ activityLibraryId)→ lib-detail(→ activityId)→ score-types(→ --score-type);credits(→ creditId)。
scu ccyl activities --name 讲座 --page 1 --size 10 # 搜索活动库,记录的 id = activityLibraryId
# 可选筛选:--level --score-type --org --order --status --quality
scu ccyl mine # 我参与的活动(--page/--size)
scu ccyl subscribed # 已预约的活动系列(--name/--page/--size)
scu ccyl dicts <groupCode...> # 数据字典(activities 筛选参数的合法枚举来源,如 level/quality)
scu ccyl orgs # 组织列表
scu ccyl lib-detail <activityLibraryId> # 活动系列详情,含场次活动 id = activityId
scu ccyl detail <activityId> # 活动详情
scu ccyl score-types <activityLibraryId> # 能力类型,id = signup --score-type
scu ccyl signup <activityId> --score-type <id> # 报名
scu ccyl cancel <activityId> # 取消报名
scu ccyl subscribe <activityLibraryId> # 预约活动系列
scu ccyl unsubscribe <activityLibraryId> # 取消预约
scu ccyl credits # 成绩单(记录含 creditId,--page/--size)
scu ccyl export <email> <creditId...> # 导出成绩单到邮箱
完整命令树:scu --help;子命令细节与参数来源:scu <组> <命令> --help。
10. 办事大厅 scu service
scu service applications # 我的申请列表(--status 0全部/1进行中+草稿/3已完成,--page 分页,每页20条)
# 列表项:app_name 事项名、created 提交时间、inst_status 中文状态文案(不要自己映射 status 数字)
事项办理(动态表单,三步):
# ① 查看表单结构:fields 按填写顺序给出 key/label/type/required/options/prefilled,
# date_rules 为日期顺序校验(first_key 必须早于等于 second_key)
scu service form 350
# ② 组装字段并预览提交体(强烈建议先 dry-run 给用户确认)
scu service submit 350 --fields '{"Radio_30":"1","Input_31":"成都市","Calendar_40":"2026-08-14"}' --dry-run
# ③ 确认后正式提交(去掉 --dry-run)
scu service submit 350 --fields '{"Radio_30":"1","Input_31":"成都市","Calendar_40":"2026-08-14"}'
--fields 的值按 form 输出的 type 给:
| type | 值形态 |
|---|---|
| input / multiInput / dataSource | 字符串 |
| radio / select / selectV2 | options 里的 value 字符串 |
| checkbox | value 字符串数组 ["1","2"] |
| calendar | "2026-08-14" 或 "2026-08-14 10:00" |
| region | {"province":"四川省","city":"成都市","area":"武侯区","details":"详细地址"}(省/市/区给名称或 6 位编码,直辖市可省略 city) |
| file | 不走 --fields,用 --attach File_71=./照片.png(可重复,上限见 max_count) |
注意:
- 只读/隐藏/user 字段由服务端透传,不要出现在 --fields 里(会报错)。
- dataSource 字段给出名称后 CLI 自动取数联动(如导师姓名 → 回填工号/日期等配对字段),取数失败降级为仅提交名称并在 warnings 中说明。
- 选项 value 合法性、必填、ShowHide 动态显隐/动态必填、日期顺序都在本地校验,报错即修正后重试。
- 输出的 warnings 非空时要如实转告用户。
11. 在线报修 scu repair(智慧后勤)
宿舍报修工单的提交与跟踪。status 由后端直接返回中文(待完工/待评价/已关闭/已撤回),不要自己映射数字。
# 只读查询
scu repair addresses # 常用报修地址(id 供 submit;user_id 供 list)
scu repair areas # 区域树(id/full_name 供 projects 与 save-address)
scu repair projects <area_id> # 维修项目两级树,--project 取叶子 value
scu repair book-dates # 可预约上门日期
scu repair book-times <date> # 某日期的可预约时段
scu repair list # 我的报修工单(按时间倒序;--user-id 可省略自动发现)
scu repair detail <工单id> # 工单详情(logs 为进度时间线;评价用 finished_info.repair_id)
scu repair evaluate-projects # 评价项(维修质量/态度/速度,id 供 --stars)
# 写操作(先向用户确认)
scu repair save-address --area-id 30006 --area-name 江安学生区/西苑六栋 \
--detail 5单元301C --phone 1xxxxxxxxxx [--default]
scu repair submit --address-id <地址id> --project 101 --content '水龙头漏水关不紧' \
[--book-date 2026-09-15 --book-time 08:00-10:00] [--image 现场照片.jpg]... \
[--allow-absent] [--dry-run]
scu repair withdraw <工单id> # 撤回(仅待完工状态;不可撤回会明确报错)
scu repair evaluate <repairId> --star 5 [--stars 评价项id:4]... [--content 感谢] [--labels 及时,专业]
submit 说明:--project 必须取 projects 输出的叶子 value(大类 value 会报错);提交流程与 App 一致(上传图片 → 预取负责部门 → 提交),先 --dry-run 输出完整提交体给用户确认。图片限 jpg/jpeg/png/heic/heif、单张 ≤10MB、最多 3 张。
12. 校园网无感认证 scu passpoint
绑定设备 MAC 后连接校园网自动完成认证(Passpoint),无需手动登录。
scu passpoint devices # 已绑定设备(user_mac / 到期日期 / 出口 / 在线状态)
scu passpoint user # 校园网账户信息(account_state 1 为在线)
scu passpoint add --mac B8782EBDCE85 [--days 30] [--exit 中国电信]
# --days 0-365(0 = 最长有效期 6 年);--exit 空=校园网 / 中国电信 / 中国移动 / 中国联通
scu passpoint cancel --mac B8782EBDCE85 # 取消绑定(mac 取自 devices)
MAC 为 12 位十六进制、无分隔符、大写(如 B8782EBDCE85);冒号/连字符小写写法会自动归一化,位数不对报 input 错误。add/cancel 为写操作,执行前确认。
13. 行为准则
- 写操作先确认:
ccyl signup/cancel/subscribe/unsubscribe/export、user offline、service submit(先 --dry-run 给用户看提交体)、repair submit(先 --dry-run)/withdraw/evaluate/save-address、passpoint add/cancel、balance query首次绑房等写操作,执行前向用户确认目标与参数;失败后不要自动重试(CLI 自身也不会重放写请求),先把错误报给用户。 - 只读命令可自由串行调用;优先用发现链逐级取 ID,不要向用户索要可以自动发现的编号。
- 凭据文件含账号密码,不要打印、复制或外发其内容。
unauthenticated错误一律引导重新登录,不要尝试其他绕过方式。