将正方软件教务系统(V9)的课表导出为标准 .ics 日历文件,可导入 Apple 日历、Google Calendar、Outlook 等任意支持 iCalendar 格式的应用。
支持两种使用方式:离线下载(将 .ics 文件导入日历应用)与在线订阅(发布到 GitHub Gist,日历应用通过订阅 URL 自动同步更新)。
- 自动识别:在
*.edu.cn域名下检测页脚是否包含「正方软件股份有限公司」,符合则激活扩展 - 双套作息支持:自动探测秋冬 / 春夏两套节次时间,在五一 / 国庆前后自动切换;切换日期可手动覆盖
- 理论 + 实验合并:同一课程在同一天相邻排列的理论课与实验 / 实践课可合并为单个日历事件
- 完整事件信息:SUMMARY(课程名)、LOCATION(场地,可选附带校区前缀)、DESCRIPTION(节次、周次、教师、教学班、考核方式、学分等非空字段)
- RFC 5545 兼容:正确处理 CRLF 换行、75 字节行折叠(不截断 UTF-8 字符)、TZID 时区声明
- iCal 在线订阅:通过 GitHub OAuth 授权,将生成的 ICS 发布到 GitHub Gist;日历应用订阅后可自动获取更新
- 防空提交:更新 Gist 前自动比对内容,若与已有版本完全一致则跳过写入,避免产生无意义的提交记录
- 教务数据本地处理:课表 API 请求由 content script 在已登录的教务系统页面内发起,课表数据不经过任何第三方服务器
https://chromewebstore.google.com/detail/chnhhdhbciemnjaohomeohlklfdlmhbl
https://microsoftedge.microsoft.com/addons/detail/lpfdidogfdkdnidleioieajgdofajlna
- 下载本仓库的 ZIP 包并解压,或使用 Git 克隆到本地
- 打开 Chrome 扩展管理页面(
chrome://extensions/) - 开启「开发者模式」
- 点击「加载已解压的扩展程序」,选择
extension/目录 - 安装完成后,扩展图标会出现在工具栏中
- (可选)右键图标选择「固定到工具栏」以便随时访问
-
登录学校的正方教务系统
-
点击浏览器工具栏中的扩展图标,弹出窗口会自动检测当前页面
-
填写 / 确认以下参数:
字段 说明 学年(起始年份) 如 2025,代表 2025–2026 学年学期 第一学期(秋冬)= xqm 3;第二学期(春夏)= xqm 12 第 1 周周一日期 开学第一周的周一,必填 生成截止日期 可选;留空则生成整个学期 作息切换日期 五一 / 国庆前一天,由扩展自动探测并预填,可手动修改 在地点中显示校区 多校区院校推荐开启,生成如「荆东校区·博学楼-202」 合并连续的理论+实验节次 将同课程相邻排列的理论与实验合并为一个事件 -
点击「获取课表并生成 ICS」,扩展会请求课表数据并在内存中生成 ICS 内容
-
根据需要选择后续操作:
- 下载文件:点击「⬇ 下载 .ics 文件」,将文件保存到本地后手动导入日历应用;文件名格式:
姓名_学年_学期[_截至日期].ics - iCal 在线订阅:参见下方「iCal 在线订阅(GitHub Gist)」说明
- 下载文件:点击「⬇ 下载 .ics 文件」,将文件保存到本地后手动导入日历应用;文件名格式:
通过发布到 GitHub Gist,可获得一个稳定的订阅 URL。日历应用(Apple 日历、Google Calendar 等)订阅该 URL 后,每次重新生成并发布即可自动同步更新,无需重新导入文件。
- 在弹出窗口底部「ICAL 订阅」区域,点击「连接 GitHub 以发布 iCal 订阅链接」
- 在弹出的 GitHub 授权页面完成 OAuth 登录,授权后窗口会自动关闭并显示已连接的账号名
- 生成 ICS 后,点击「发布 / 更新 Gist 订阅链接」
- 首次发布:自动创建新的私密 Gist,并显示订阅 URL
- 再次发布:更新同一 Gist 文件;订阅 URL 保持不变,日历应用无需重新添加
- 若内容与上次完全一致,会提示「没有可提交的变更」并跳过写入
- 复制显示的「iCal 订阅链接」,粘贴到日历应用的「订阅日历」或「添加账户 > iCalendar」入口
所有请求均通过运行时探测到的 API 根路径(apiBase)构造;不同学校的根路径可能不同(例如三明学院为 https://jwxxt.fjsmu.edu.cn/jwglxt,湖北某校为 http://jwxt1.hbfs.edu.cn)。
| 端点 | 用途 |
|---|---|
POST <apiBase>/kbcx/xskbcx_cxXsgrkb.html |
学生个人课表(kbList、xsxx) |
POST <apiBase>/kbcx/xskbcx_cxRjc.html |
节次时间表(每节的起止时间) |
所有请求均携带 Cookie(credentials: include),依赖用户已登录的会话。
根路径探测方式:向当前页面发送不带 Cookie 的请求,跟随重定向后从登录页 URL(<apiBase>/xtgl/login_slogin.html)中反推 apiBase;探测失败则回退到 window.location.origin。
- 春季学期(xqm=12):节前使用
xqm=12作息,五一后切换至xqm=3作息 - 秋季学期(xqm=3):节前使用
xqm=3作息,国庆后切换至xqm=12作息 - content script 会主动查询另一套作息,若两套时间不同则视为双作息学校,并将切换日期(4/30 或 9/30)预填到表单
同一 kch(课程号)、同一 xqj(星期)、同一 zcd(周次)下的多条记录,按节次排序后,若首尾相连(无间隔节次),则合并为一条,jcs 取整体跨度。中间有空隙的视为独立排课,不合并。
extension/
├── manifest.json # Manifest V3 配置
├── background.js # 后台 Service Worker(GitHub OAuth 流程)
├── content.js # 页面检测 & API 请求
├── popup.html # 弹出窗口 UI
├── popup.js # ICS 生成 & GitHub Gist 发布逻辑
└── icons/ # 扩展图标
ref/ # 正方 API 响应样本(.jsonc)
- 仅支持正方软件 V9 系列,其他版本的教务系统未经验证,不保证兼容
- 不支持调停课(
rqazcList)的自动处理
Claude Sonnet 4.6 对此 codebase 全权负责,本人仅提供思路指导、API 返回值示例与对部分代码的细微改动。