# 计算机学院第七届新媒体中心 · 空课查询系统

一个基于空课表（Excel）的**纯前端空课查询网页**。选择「周数 · 星期 · 课节」即可查看该时段有空的干事与干部名单。

- 单文件 HTML，双击 `index.html` 即可使用，无需服务器、无需联网、无需安装任何依赖
- 蓝色背景 + 居中标题（标题前展示学院院徽，院徽以 Base64 内嵌于页面，单文件即可显示）
- 周数、星期必选；课节可不选——不选课节即**查询一整天**（此时只显示当天 5 个课节都有空的人，即「全天都有空」）
- **课节支持多选**：可同时勾选多个课节，输出所选课节**都有空**的人员名单（交集）
- 课节按**上午 / 下午 / 晚上**分组：第1、2节与第3、4节=上午，第5、6节与第7、8节=下午，第9、10、11节=晚上
- 点击「查询」按钮出结果：名单一人一行；**选课节时**备注相邻时段是否有空（「有空」绿色、「有课」红色），**不选课节时**只显示全天都有空的人
- 查询结果顶部显示**当天值班的干事**（按单周/双周值班表）；当天无人值班则不显示该行；名单中当天值班的干事**整行黄色高亮**
- 干事与干部样式一致（不标红），结果先干事、后干部分组展示；全员空闲时输出「全有空」
- 电脑 / 手机均可使用（响应式布局）
- 开放源码（MIT License），数据更新只需改 Excel 后运行一个脚本

## 快速开始

1. 打开 `index.html`（推荐用 Chrome / Edge 浏览器）
2. 在三个下拉框中选择：**周数**（第 1–20 周，必选）→ **星期**（周一至周日，必选）→ **课节**（第1、2节 … 第9、10、11节，可选，**可多选**）
3. 点击「查询」，下方即显示该时段有空的人员名单：
   - 结果顶部为**当天值班的干事**一行（按单双周值班表；当天无人值班则不显示）
   - 每人一行；选课节时备注相邻时段是否有空（规则见下），不选课节时只显示全天都有空的人
   - **多选课节**时只保留**所选课节都有空**的人员（交集）
   - 先展示干事，后展示干部；名单中当天值班的干事**整行黄色高亮**
   - 全员空闲时显示「全有空」

### 相邻时段备注规则

查询一个或多个课节时，会备注**所选时段边界外相邻**的课节是否有空（便于判断能否前后连上整段空闲）：

- **单选**时备注两侧相邻时段（第1、2节只有后侧）：

| 查询课节 | 备注的相邻时段 |
|---|---|
| 第1、2节 | 第3、4节 |
| 第3、4节 | 第1、2节、第5、6节 |
| 第5、6节 | 第3、4节、第7、8节 |
| 第7、8节 | 第5、6节、第9、10、11节 |
| 第9、10、11节 | 第7、8节 |

- **多选**时按「连续段」处理：只备注选中范围**边界外相邻**的课节，中间不重复备注。例如：
  - 选中整个上午（第1、2节 + 第3、4节）→ 只备注第5、6节
  - 选中整个下午（第5、6节 + 第7、8节）→ 备注第3、4节与第9、10、11节
  - 非连续多选（如第1、2节 + 第5、6节）→ 备注第3、4节与第7、8节（自动去重）

相邻时段有空显示「有空」（绿色），有课显示「有课」（红色）。

### 值班表（干事）

查询任意周数时，结果顶部会显示**当天值班的干事**。值班按**单周 / 双周**轮换（单数周=单周、双数周=双周）：

| 星期 | 单周 | 双周 |
|---|---|---|
| 周一 | 刘润冬 | 杨玥佳 |
| 周二 | 夏思婷 | 全正蔚 |
| 周三 | 彭杰 | 马鉴麟 |
| 周四 | 王浩锦 | 唐敏 |
| 周五 | 高裕涵 | 曾子韵 |
| 周六 | 李立刚 | 杨舒焱 |
| 周日 | 李玄 | （无人值班） |

- 当天无人值班（如双周周日）时不输出值班行
- 名单中出现当天值班的干事时，该成员所在**整行以黄色高亮**（与顶部值班行同款金色样式），便于区分

值班数据与空课表相互独立，内嵌于 `index.html` 的 `DUTY` 常量中；如需调整值班安排，直接修改该常量即可（无需重新运行转换脚本）。

## 数据如何更新

1. 修改《计算机学院第七届新媒体中心空课表.xlsx》（沿用原格式：每格为「姓名（空闲周数）」，黑色=干事、红色=干部）
2. 运行：

   ```bash
   python tools/convert_xlsx.py "你的空课表.xlsx"
   ```

3. 脚本会自动解析并重写两处：
   - `index.html` 内嵌的数据块（页面即生效）
   - `data/schedule.json`（结构化数据，供程序化使用）

不传路径时默认读取桌面上的《计算机学院第七届新媒体中心空课表.xlsx》。

## 项目结构

```
├── index.html              # 页面本体（单文件自包含：样式、逻辑、数据全部内嵌）
├── assets/
│   └── emblem.png          # 学院院徽源文件（页面内已以 Base64 内嵌展示）
├── data/
│   └── schedule.json       # 解析出的结构化数据（机器可读，供引用/排查）
├── tools/
│   ├── convert_xlsx.py     # Excel → 页面数据 的转换脚本（核心维护工具）
│   ├── verify_query.py     # 查询逻辑抽样验证脚本（回归检查用）
│   └── ui_interaction_test.py  # 浏览器交互测试（可选，需 pip install playwright）
├── README.md
├── LICENSE                 # MIT
├── CONTRIBUTING.md         # 贡献指南
└── CHANGELOG.md            # 变更记录
```

## 数据格式说明

Excel 的列 B–H 对应 周一–周日，行 3–7 对应 5 个课节段。每个格子内是多行文本：

```
姓名（空闲周数）
```

- 空闲周数支持：单周（`3`）、连续区间（`14-20`）、混合写法（`1，5-6，15-20`）
- 单元格内黑色文字 = 干事，红色文字 = 干部（按字体颜色自动识别）
- 转换脚本会自动忽略括号里的中英文标点差异（`，` `,` `（` `(` 等均可解析）

## 技术说明

- 纯原生 HTML / CSS / JavaScript，无任何外部依赖、无构建步骤
- 数据以内嵌 JS 对象的形式固化在 `index.html` 中，因此离线双击即可运行
- 查询为 O(n) 遍历 + 周集合判断，18 人规模下无性能压力

## 参与贡献

见 [CONTRIBUTING.md](CONTRIBUTING.md)。

## 许可证

[MIT](LICENSE) © 计算机学院第七届新媒体中心
