# 教务同步只读 API(学生异动 + 学生基本信息) 供教务或其它系统调用,**对外接口说明见 [`接口调用说明.md`](./接口调用说明.md)**。 - **学生异动**:视图 `vw_jw_student_change_export` → `GET /api/v1/student-changes` - **学生基本信息**:视图 `vw_jw_student_export` → `GET /api/v1/students` - **Python**:开发与生产建议 **3.7.9**(与现网一致)。 - **依赖**:见 `requirements.txt`(Flask 2.0.x + PyMySQL)。 - **异动类型映射**:见 [`异动类型映射说明.md`](../异动类型映射说明.md) - **学生基本信息口径**:见 [`学生基本信息对接说明.md`](../../跟教务系统同步学生基础信息/学生基本信息对接说明.md) ## 配置文件与环境对应关系 | 本目录文件 | 后端配置来源 | Spring 环境 | |------------|----------------|-------------| | **`config.dev.ini`** | `backend/ruoyi-admin/src/main/resources/application-dev.yml`(`spring.datasource.dynamic.datasource.master`) | dev(测试/开发) | | **`config.prod.ini`** | `backend/ruoyi-admin/src/main/resources/application-prod.yml`(同上) | prod(生产) | 主机、端口、库名、用户名、密码已与上述 YAML 中 **master** 数据源保持一致;后端配置变更时请同步修改对应 INI。 ## 安装 ### 开发机(推荐虚拟环境) ```bash cd 跟教务系统同步学生异动信息/api_service python3.7 -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txt ``` ### Linux 生产环境 ```bash cd /path/to/api_service python3 -m pip install -r requirements.txt python3 -c "import pymysql, flask; print('ok')" ``` ## 选用配置并启动 **测试/开发**: ```bash cp config.dev.ini config.ini python app.py ``` **生产**: ```bash export JW_CX_CONFIG=/opt/jw-cx/config.prod.ini python app.py ``` ### INI 节说明 **`[database]`**:`host`、`port`、`user`、`password`、`database` **`[api]`**: | 键 | 说明 | |----|------| | `api_key` | 与请求头 `X-Jw-Cx-Key` 一致 | | `bind_host` / `bind_port` | HTTP 监听(仅直接运行 `python app.py` 时生效) | | `default_year` | 异动接口默认筛选年份(`year` 未传时);未配置则当前自然年 | | `page_size` | 学生基本信息接口默认每页条数;请求可带 `page_size` 覆盖,范围 1~5000 | ## 密钥校验 所有 **`/api/v1/*`** 业务接口必须在 HTTP Header 中携带: ```http X-Jw-Cx-Key: <与配置文件中 [api] api_key 相同,默认 JWCX001> ``` **`/health`** 不做密钥校验。 ## 生产进程(gunicorn) ```bash pip install 'gunicorn>=20.1.0,<21' export JW_CX_CONFIG=/path/to/config.prod.ini gunicorn -w 2 -b 0.0.0.0:5050 app:app ``` ## 接口说明 ### GET `/health` 返回 `{"status":"ok"}`。 ### GET `/api/v1/student-changes` **数据范围**:**`异动生效时间` 落在指定自然年**内的已办结记录,**一次返回全部**(不分页);年份由 **`year`** 指定,**未传则使用当前自然年**(或配置 `default_year`)。 | Query | 说明 | 未传时的默认值 | |--------|------|------------------| | `year` | 按「异动生效时间」所在自然年筛选,有效范围 2000~2100 | 当前自然年 | **响应 `data` 每条记录字段**(与教务对接清单一致): | 字段 | 说明 | |------|------| | 提交时间 | `YYYY-MM-DD` | | 异动生效学期 | 本系统无数据,为 `null` | | 异动类型 | **教务中文名称**(退学、休学、复学、转班级) | | 申请人学号 / 姓名 | | | 异动前/后 年级、院系、专业、班级、学制 | 院系/专业优先 `sys_dept`;班级优先 `xg_class_msg`;学籍异动「前」优先历史快照 | | 异动前/后 所在校区 | 班级 `campus_id` → `xg_dorm_campus.campus_name`,再回退班级 `campus_name` | | 异动后班主任工号 / 姓名 | | | 新名字 | 本系统无改名流水,为 `null` | | 审核状态 | 固定「已通过」 | 成功响应元数据: | JSON 字段 | 说明 | |-----------|------| | `total` | 本次返回的记录总数(等于 `data` 数组长度) | | `filter_year` | 本次请求实际生效的筛选年份 | | `filter_by_column` | 固定为 `异动生效时间` | **未授权**(HTTP 401):未带或错误的 `X-Jw-Cx-Key`。 ### GET `/api/v1/students` **数据范围**:全部未逻辑删除的学生(`xg_student_msg.deleted = 0`),**分页返回**。 | Query | 说明 | 未传时的默认值 | |--------|------|------------------| | `page` | 页码,从 1 开始 | `1` | | `page_size` | 每页条数,有效范围 1~5000 | `[api] page_size`(默认 500) | 成功响应元数据: | JSON 字段 | 说明 | |-----------|------| | `total` | 符合条件的记录总数 | | `page` | 当前页码 | | `page_size` | 本页大小 | | `total_pages` | 总页数(`ceil(total / page_size)`) | 字段口径见 [`学生基本信息对接说明.md`](../../跟教务系统同步学生基础信息/学生基本信息对接说明.md)。 **拉取全量示例**(教务侧循环): ```python page = 1 while True: resp = get(f"/api/v1/students?page={page}&page_size=500") # 处理 resp["data"] if page >= resp["total_pages"]: break page += 1 ``` ## 调用示例 ```bash # 异动:当前自然年全部 curl -s -H "X-Jw-Cx-Key: JWCX001" \ "http://127.0.0.1:5050/api/v1/student-changes?year=2026" # 学生基本信息:分页(第 1 页,默认每页 500 条) curl -s -H "X-Jw-Cx-Key: JWCX001" \ "http://127.0.0.1:5050/api/v1/students?page=1" # 指定每页 1000 条、第 2 页 curl -s -H "X-Jw-Cx-Key: JWCX001" \ "http://127.0.0.1:5050/api/v1/students?page=2&page_size=1000" ``` ## 部署前:重建视图 ```bash mysql -h -u root -p hzdyjs_xg < docs/设计文档/database/vw_jw_student_change_export.sql mysql -h -u root -p hzdyjs_xg < docs/设计文档/database/vw_jw_student_export.sql ``` ## 联调测试脚本 仅调用两个业务接口(学生基本信息、学生异动)并打印结果: ```bash cd 跟教务系统同步学生异动信息/api_service # 生产 python test_jw_cx_api.py --prod # 若 Nginx 带路径前缀 python test_jw_cx_api.py --base-url http://web.hzdyjsxy.cn:18081/jw-cx-api --year 2026 ``` 脚本仅依赖 Python 标准库;详见 `test_jw_cx_api.py --help`。 ## 安全说明 1. `config.dev.ini` / `config.prod.ini` 含数据库凭据,请按公司规范控制仓库可见性与部署权限。 2. 建议数据库侧使用**仅对视图** `vw_jw_student_change_export`、`vw_jw_student_export` 有 `SELECT` 的专用账号,与后端 `root` 分离。 3. 生产将 **`api_key`** 换为强随机串,并走 HTTPS;必要时加网络白名单。