有关志愿通的代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

27 KiB

志愿通当前接口文档

1 文档范围

本文档描述当前 Spring Boot 服务中已经实现并通过实库验证的接口,包括:

  • 数据审核台接口 /api/**
  • P0 考生端公共接口 /api/v1/**
  • 数据发布与版本切换接口 /api/admin/v1/publications/**

本文档不包含规划中但尚未实现的院校推荐、专业详情、用户、收藏和志愿表接口。

2 基本约定

2.1 服务地址

本地开发地址:

http://127.0.0.1:8080

前端开发环境通过 Vite 将 /api 代理到该地址。

2.2 数据格式

  • 请求和响应编码:UTF-8
  • JSON 请求头:Content-Type: application/json
  • 时间口径:Asia/Shanghai
  • 审核台 SQL 查询结果主要使用 snake_case
  • P0 公共接口和发布校验接口使用 camelCase
  • 全局配置不输出值为 null 的字段,因此部分可选字段可能不出现在 JSON 中

2.3 当前安全状态

当前服务尚未接入登录、角色和权限校验。以下写接口和管理接口只能部署在受控内网环境:

  • PUT /api/reviews/{entityType}/{entityKey}
  • /api/admin/v1/**

正式开放公网前必须增加管理员认证、角色权限、操作审计和接口限流。

2.4 通用错误

业务参数错误通常返回 HTTP 400:

{
  "message": "year 必须在 2000 到 2100 之间"
}

请求参数类型错误或 Bean Validation 校验失败由 Spring Boot 返回 HTTP 400,响应中通常包含:

{
  "timestamp": "2026-09-06T10:00:00+08:00",
  "status": 400,
  "error": "Bad Request",
  "message": "...",
  "path": "/api/..."
}

未处理异常返回 HTTP 500。当前数据详情不存在时实现上返回 HTTP 400,而不是 HTTP 404。

3 接口总览

分类 方法 路径 说明
系统 GET /api/health 服务健康检查
审核台 GET /api/dashboard 数据规模、覆盖和审核总览
审核台 GET /api/metadata 查询筛选项和数据集元数据
审核台 GET /api/collection-scopes 查询各省各年度采集范围
审核台 GET /api/data/{dataset} 通用数据集分页查询
审核台 GET /api/data/{dataset}/{id} 通用数据详情
审核台 PUT /api/reviews/{entityType}/{entityKey} 提交审核结论
审核台 GET /api/reviews/{entityType}/{entityKey}/history 查询审核历史
P0 公共 GET /api/v1/meta/admission-contexts 查询省份招录上下文与数据可用性
P0 公共 GET /api/v1/score-ranks/convert 分数与位次互换
发布管理 GET /api/admin/v1/publications/datasets 查询支持发布校验的数据集
发布管理 POST /api/admin/v1/publications/validate 执行只读发布前质量门禁
发布管理 GET /api/admin/v1/publications 查询发布历史和当前版本
发布管理 POST /api/admin/v1/publications 创建不可变公共快照
发布管理 POST /api/admin/v1/publications/{id}/publish 切换当前版本或回滚
发布管理 POST /api/admin/v1/publications/{id}/withdraw 撤回版本

4 系统接口

4.1 健康检查

GET /api/health

响应示例:

{
  "status": "ok",
  "service": "志愿通数据审核后台"
}

该接口只表示 Web 服务能够响应,不代表所有数据集均已审核或具备发布条件。

5 审核台接口

5.1 数据总览

GET /api/dashboard

响应字段:

字段 类型 说明
schools number 院校主档记录数
gansuSchools number 甘肃省院校数
groups number 院校专业组总数
majorPlans number 专业招生计划总数
majorLines number 专业录取线总数
cutoffLines number 院校或专业组投档线总数
scorePoints number 2025 年一分一段记录数
controlLines number 2025 年控制线记录数
unmatchedCutoffLines number 未匹配稳定院校 ID 的投档线数
pendingReviews number 尚未形成终态审核结论的记录数
cutoffBreakdown array 按科类、层次和段次汇总的投档线统计
coverage array 2025 年各省各数据集覆盖与缺口
reviewStats array 按审核状态汇总的记录数

cutoffBreakdown 元素字段:

subject_category, education_level, segment_code, record_count,
matched_count, min_score, max_score

coverage 元素字段:

province_name, dataset_name, subject_category, segment_code,
coverage_status, record_count, notes

5.2 筛选元数据

GET /api/metadata

响应字段:

字段 类型 说明
provinces string[] 院校主档中出现的省级地区
educationLevels string[] 院校培养层次
ownershipTypes string[] 公办、民办等办学性质
subjects string[] 招录数据中的原始科类值
controlLineLevels string[] 控制线层次
segments string[] 原始批次或段次值
categories string[] 招生类别
reviewStatuses string[] 审核状态枚举
admissionYears number[] 已建档年份,当前为 2022 至 2026
datasets string[] 通用数据查询支持的数据集代码

审核状态:

值 含义
pending 待审核,或尚无 review_records 记录
approved 已通过
needs_review 需要复核
rejected 已驳回

5.3 省份年度采集范围

GET /api/collection-scopes

当前接口返回全部省份和全部建档年份,不支持分页和筛选。

响应元素字段:

字段 说明
collection_scope_id 采集范围主键
province_name 招生省份
admission_year 招生年度
collection_status not_collected、partial、collected 或 verified
priority_level low、normal 或 high
status_note 数据范围和缺口说明
first_collected_at 首次采集时间
last_collected_at 最近采集时间
batch_count 批次规则记录数
plan_release_count 招生计划发布批次数
group_count 院校专业组数
major_plan_count 专业招生计划数
major_line_count 专业录取线数
score_point_count 一分一段记录数
control_line_count 控制线记录数
cutoff_line_count 投档线记录数
coverage_item_count 覆盖说明记录数

5.4 通用分页查询

GET /api/data/{dataset}

通用查询参数:

参数 必填 默认值 说明
page 否 1 页码,服务端限制为 1 至 100000
size 否 20 每页数量,服务端限制为 1 至 200
keyword 否 - 模糊搜索;部分数据集不支持
reviewStatus 否 - pending、approved、needs_review、rejected
sort 否 数据集默认排序 只接受各数据集声明的排序代码
direction 否 desc 只有 asc 表示升序,其他值均按降序处理
minScore 否 - 仅分数类数据集生效
maxScore 否 - 仅分数类数据集生效

分页响应:

{
  "items": [],
  "total": 94,
  "page": 1,
  "size": 20,
  "totalPages": 5
}

每条记录都会附加以下审核字段;没有值时可能省略:

review_status, reviewer_name, review_note, reviewed_at

5.4.1 schools 全国院校

  • entityType:school
  • 关键词搜索:院校名称、教育部代码、城市、主管部门
  • 筛选参数:province、educationLevel、ownership、schoolStatus
  • 排序代码:name、province、updatedAt
  • 主要字段:school_id、moe_school_code、official_name、province_name、city_name、authority_name、education_level、ownership_type、school_status、official_website、admission_website、first_seen_year、last_seen_year、source_title、source_url

示例:

GET /api/data/schools?page=1&size=20&province=北京市&keyword=大学&sort=name&direction=asc

5.4.2 groups 院校专业组

  • entityType:admission_group
  • 关键词搜索:院校名称、院校代号、专业组代码、专业组名称
  • 筛选参数:province、subject、segment、category、year、matched
  • 排序代码:school、segment、groupCode
  • matched=true 表示已匹配 school_id,matched=false 表示未匹配
  • 主要字段:admission_group_id、admission_year、admission_category、subject_category、batch_name、segment_code、source_school_code、school_name_raw、group_code、group_name、school_id、moe_school_code、source_title、source_url

5.4.3 major-plans 专业招生计划

  • entityType:major_plan
  • 关键词搜索:院校名称、院校代号、专业名称、专业代号、备注
  • 筛选参数:province、subject、segment、category、year
  • 排序代码:school、major、planCount
  • 主要字段:major_plan_id、admission_year、admission_category、subject_category、batch_name、segment_code、source_school_code、school_name_raw、group_code、major_code、major_name、subject_requirements、plan_count、tuition_yuan_per_year、study_years、campus_name、notes、source_row_number、source_title、source_url

5.4.4 major-admissions 专业录取线

  • entityType:major_admission
  • 关键词搜索:院校名称、院校代号、专业组、专业名称、专业代码、专业备注
  • 筛选参数:province、subject、segment、educationLevel、category、year、matched
  • 分数参数:minScore、maxScore,作用于 min_score
  • 排序代码:score、rank、school、major
  • 主要字段:major_line_id、admission_year、admission_category、subject_category、education_level、batch_name、source_school_code、school_name_raw、group_code、major_code、major_name、major_note、subject_requirements、min_score、min_rank、max_score、avg_score、admit_count、school_province、school_nature、is_985、is_211、school_id、moe_school_code、source_row_number、source_title、source_url

5.4.5 score-ranks 一分一段

  • entityType:score_rank
  • 不支持关键词搜索
  • 筛选参数:province、subject、year
  • 分数参数:minScore、maxScore,作用于 score
  • 排序代码:score、rank
  • 主要字段:score_rank_id、admission_year、admission_category、subject_category、score、same_score_count、cumulative_count、rank_from、rank_to、source_title、source_url

5.4.6 control-lines 省级控制线

  • entityType:control_line
  • 关键词搜索:备注
  • 筛选参数:province、subject、educationLevel、category、year
  • 分数参数:minScore、maxScore,作用于 culture_score
  • 排序代码:score、level
  • 主要字段:control_line_id、admission_year、admission_category、subject_category、education_level、culture_score、professional_score、notes、source_title、source_url

5.4.7 cutoff-lines 院校或专业组投档线

  • entityType:cutoff_line
  • 关键词搜索:院校名称、院校代号、专业组代码、专业组名称
  • 筛选参数:province、subject、segment、educationLevel、category、year、matched
  • 分数参数:minScore、maxScore,作用于 cutoff_score
  • 排序代码:score、school、groupCode
  • 主要字段:cutoff_line_id、admission_year、admission_category、subject_category、education_level、batch_name、segment_code、source_school_code、school_name_raw、group_code、group_name、cutoff_score、cutoff_rank、control_score、score_diff、admit_count、school_province、school_nature、同分排序项、volunteer_number、school_id、moe_school_code、source_title、source_url

同分排序项字段:

raw_total_score, chinese_math_sum, chinese_or_math_max,
foreign_language_score, first_choice_subject_score,
second_choice_subject_max, second_choice_subject_second

5.4.8 batches 招生批次与段次

  • entityType:admission_batch
  • 关键词搜索:批次名称、段次代码
  • 筛选参数:province、segment、educationLevel、category、year
  • 排序代码:segment、level
  • 主要字段:admission_batch_id、admission_year、admission_category、education_level、segment_code、batch_name、volunteer_mode、max_group_volunteers、max_majors_per_group、solicitation_count、source_title、source_url

5.4.9 releases 招生计划发布批次

  • entityType:plan_release
  • 关键词搜索:发布标题、计划轮次
  • 筛选参数:province、year、coverageStatus
  • coverageStatus 实际匹配数据库字段 coverage_scope
  • 排序代码:publishedOn、title
  • 主要字段:plan_release_id、admission_year、release_title、plan_round、coverage_scope、published_on、plan_count、source_title、source_url

5.4.10 sources 数据来源档案

  • entityType:data_source
  • 关键词搜索:发布机构、标题、SHA-256
  • 筛选参数:sourceType
  • 排序代码:publishedOn、publisher
  • 主要字段:source_id、source_type、publisher、title、landing_page_url、file_url、published_on、retrieved_at、sha256、raw_file_path、notes

5.4.11 coverage 数据覆盖与缺口

  • entityType:dataset_coverage
  • 关键词搜索:数据集名称、缺口说明
  • 筛选参数:province、coverageStatus、subject、segment、year
  • 排序代码:dataset、count
  • 主要字段:coverage_id、dataset_name、admission_year、admission_category、subject_category、segment_code、coverage_status、record_count、notes、source_title、source_url

覆盖状态:

值 含义
complete_public_snapshot 当前公开来源中的完整快照
partial_public_snapshot 仅有部分公开数据或关键字段缺失
unavailable_publicly 暂未取得公开全量数据

5.5 通用数据详情

GET /api/data/{dataset}/{id}

返回对应数据集的完整列表字段、审核字段以及:

{
  "review_history": []
}

当 dataset=schools 时额外返回:

  • external_codes:省级招生代码和外部代码映射
  • campuses:校区、地址、坐标核验状态等信息

路径中的 id 和 entityKey 应进行 URL 编码。

5.6 提交审核结论

PUT /api/reviews/{entityType}/{entityKey}
Content-Type: application/json

支持的 entityType:

school
admission_group
major_plan
major_admission
score_rank
control_line
cutoff_line
admission_batch
plan_release
data_source
dataset_coverage

请求体:

{
  "status": "approved",
  "reviewer": "reviewer-001",
  "note": "已与考试院原始公告核对"
}

字段约束:

字段 必填 说明
status 是 pending、approved、needs_review 或 rejected
reviewer 是 审核人员姓名或账号标识,不能为空
note 否 审核说明

响应示例:

{
  "reviewId": 123,
  "entityType": "score_rank",
  "entityKey": "456",
  "status": "approved"
}

该操作会覆盖当前审核结论,同时向 review_audit_logs 追加不可覆盖的历史记录。

5.7 审核历史

GET /api/reviews/{entityType}/{entityKey}/history

响应元素字段:

review_log_id, previous_status, new_status,
reviewer_name, review_note, created_at

结果按操作时间倒序排列。

6 P0 公共接口

6.1 省份招录上下文

GET /api/v1/meta/admission-contexts

查询参数:

参数 必填 默认值 说明
year 否 2025 招生年度,允许 2000 至 2100
province 否 - 省份全称;不传时返回该年度所有建档省份

示例:

GET /api/v1/meta/admission-contexts?year=2025&province=河北省

响应示例:

{
  "year": 2025,
  "items": [
    {
      "province": "河北省",
      "collectionStatus": "collected",
      "examMode": "three_plus_one_plus_two",
      "examModeSource": "verified_publication",
      "dataVersion": "2025.exam-mode.v1",
      "publishedAt": "2026-09-06T01:12:00",
      "sourcePublisher": "中华人民共和国教育部",
      "sourceTitle": "对十三届全国人大二次会议第5836号建议的答复",
      "sourceUrl": "https://www.moe.gov.cn/",
      "subjects": [
        {
          "code": "HISTORY",
          "name": "历史类",
          "sourceValues": ["历史类"]
        },
        {
          "code": "PHYSICS",
          "name": "物理类",
          "sourceValues": ["物理类"]
        }
      ],
      "groupCount": 0,
      "majorPlanCount": 0,
      "majorAdmissionCount": 0,
      "scoreRankCount": 0,
      "controlLineCount": 0,
      "cutoffLineCount": 0,
      "warnings": [
        "尚未发布一分一段,暂不支持分数位次转换",
        "尚未发布省级控制线",
        "尚未发布院校或专业组投档线",
        "尚未发布专业录取线"
      ]
    }
  ]
}

examMode 当前可能值:

值 含义
three_plus_one_plus_two 3+1+2
three_plus_three 3+3
traditional 传统文理科
unknown 配置异常或尚未配置;正常已发布记录不会返回该值

当前 examModeSource 固定为 verified_publication。接口只读取 public_province_exam_configs 的当前发布版本,不再根据一分一段科类推断考试模式。 dataVersion 和 publishedAt 用于定位具体配置快照;来源字段用于核验追溯。

各项数量表示已经发布到公共读模型中的记录数,不是内部审核业务表的原始记录数。

当数据缺失时,warnings 可能包含:

该省份当前为部分采集或未采集状态
尚未发布一分一段,暂不支持分数位次转换
尚未发布省级控制线
尚未发布院校或专业组投档线
尚未发布专业录取线

6.2 分数与位次转换

GET /api/v1/score-ranks/convert

查询参数:

参数 必填 默认值 说明
province 是 - 省份全称
year 否 2025 招生年度
admissionCategory 否 普通类 招生类别,必须与来源数据一致
subject 是 - 原始科类名称或标准科类代码
score 条件必填 - 分数;与 rank 必须且只能提供一个
rank 条件必填 - 位次,必须大于 0;与 score 必须且只能提供一个

当前标准科类代码:

代码 标准名称 可识别来源值示例
PHYSICS 物理类 物理类、物理科目组合
HISTORY 历史类 历史类、历史科目组合
SCIENCE 理科 理科、理工类
ARTS 文科 文科、文史类
COMPREHENSIVE 综合 综合、不分科类
VOCATIONAL 中职升学 中职升学

分数转位次:

GET /api/v1/score-ranks/convert?province=河北省&year=2025&admissionCategory=普通类&subject=PHYSICS&score=650

响应示例:

{
  "province": "河北省",
  "year": 2025,
  "admissionCategory": "普通类",
  "subjectCode": "PHYSICS",
  "subjectName": "物理类",
  "sourceSubject": "物理类",
  "queryType": "score",
  "requestedValue": 650,
  "score": 650.0,
  "rankFrom": 3106,
  "rankTo": 3294,
  "sameScoreCount": 189,
  "cumulativeCount": 3294,
  "sourceTitle": "河北省2025年一分一段",
  "sourceUrl": "https://example.gov.cn/score-ranks/2025",
  "dataVersion": "2025.1",
  "publishedAt": "2026-09-10T10:00:00"
}

位次转分数:

GET /api/v1/score-ranks/convert?province=河北省&year=2025&admissionCategory=普通类&subject=PHYSICS&rank=3106

转换规则:

  • 分数查询要求一分一段中存在精确分数,当前不自动取临近分数。
  • 位次查询使用闭区间 rankFrom <= rank <= rankTo。
  • rankFrom 是该分数的最佳位次,rankTo 是该分数的最末位次。
  • 科类标准代码会解析为该省该年实际存在的来源科类值。
  • 如果同一标准科类对应多个来源值,传入接口实际返回的 sourceSubject 最明确。
  • 查询只使用 current_dataset_publications 指向的 public_score_rank_points 快照。
  • 当前尚未发布任何一分一段版本;完成审核和发布后该接口才返回转换结果。

常见错误:

{
  "message": "score 和 rank 必须且只能提供一个"
}
{
  "message": "当前省份和年份尚未发布一分一段公共版本"
}
{
  "message": "一分一段中没有该精确分数"
}

7 发布与版本管理接口

7.1 支持的数据集

GET /api/admin/v1/publications/datasets

响应:

[
  "control-lines",
  "groups",
  "major-plans",
  "major-admissions",
  "score-ranks",
  "cutoff-lines",
  "province-exam-configs"
]

返回顺序不应作为前端业务逻辑依据。

7.2 发布前质量门禁

POST /api/admin/v1/publications/validate
Content-Type: application/json

该接口只读,不会创建发布版本,也不会修改审核状态。

请求体:

{
  "province": "河北省",
  "year": 2025,
  "dataset": "score-ranks"
}

字段约束:

字段 必填 说明
province 是 省份全称,不能为空
year 是 2000 至 2100
dataset 是 必须来自支持的数据集接口

响应示例:

{
  "province": "河北省",
  "year": 2025,
  "dataset": "score-ranks",
  "sourceRecordCount": 1088,
  "publishableRecordCount": 0,
  "blockedRecordCount": 1088,
  "unapprovedRecordCount": 1088,
  "unmatchedSchoolCount": 0,
  "invalidRecordCount": 0,
  "qualityGrade": "A",
  "passed": false,
  "issues": [
    {
      "code": "UNAPPROVED_RECORDS",
      "severity": "error",
      "affectedRecords": 1088,
      "message": "存在尚未通过人工审核的记录"
    }
  ]
}

字段说明:

字段 说明
sourceRecordCount 指定省份、年份、数据集的源记录总数
publishableRecordCount 已审核通过且满足结构质量条件的记录数
blockedRecordCount 当前不能发布的记录数
unapprovedRecordCount 未处于 approved 状态的记录数
unmatchedSchoolCount 未匹配稳定 school_id 的记录数;无院校维度的数据集恒为 0
invalidRecordCount 关键字段缺失或数值无效的记录数
qualityGrade 结构质量等级 A、B、C、D,不包含人工审核进度
passed 只有存在数据且全部记录均可发布时为 true
issues 阻断原因列表

当前问题代码:

代码 严重级别 说明
DATASET_EMPTY fatal 指定范围没有数据
UNAPPROVED_RECORDS error 存在未审核通过记录
UNMATCHED_SCHOOLS error 存在未匹配稳定院校 ID 的记录
INVALID_KEY_FIELDS error 查询或推荐所需关键字段无效

质量等级与 passed 是两个不同概念。例如数据结构可以评为 A,但如果尚未经过人工审核,passed 仍为 false。

7.3 查询发布版本

GET /api/admin/v1/publications?province=河北省&year=2025&dataset=province-exam-configs

三个查询参数均可省略。响应中的 current=true 表示该版本是当前公共查询实际使用的版本。

7.4 创建公共快照

POST /api/admin/v1/publications
Content-Type: application/json
{
  "province": "河北省",
  "year": 2025,
  "dataset": "score-ranks",
  "version": "2025.1",
  "publisher": "data-admin"
}

创建操作会重新执行质量门禁。只有全部记录通过时才创建 draft 版本,并把已审核记录复制到对应的不可变公共快照表;创建版本不会自动切换线上当前版本。

当前可生成快照的数据集:

  • province-exam-configs → public_province_exam_configs
  • score-ranks → public_score_rank_points
  • cutoff-lines → public_school_admission_stats
  • major-admissions → public_major_admission_stats

7.5 发布、回滚与撤回

POST /api/admin/v1/publications/{publicationId}/publish?publisher=data-admin

该操作把版本状态改为 published,并原子替换同一省份、年份、数据集的当前版本指针。把历史 published 版本再次调用本接口即可回滚。

POST /api/admin/v1/publications/{publicationId}/withdraw?publisher=data-admin

撤回当前版本时会同时删除当前指针,公共接口随即停止读取该版本。已撤回版本不能重新发布,需要创建新版本。

发布版本响应的主要字段:

publicationId, province, year, dataset, version, status,
sourceRecordCount, publishedRecordCount, qualityGrade, current,
publishedBy, publishedAt, createdAt

8 PowerShell 调用示例

查询河北 2025 招录上下文:

Invoke-RestMethod `
  -Uri 'http://127.0.0.1:8080/api/v1/meta/admission-contexts?year=2025&province=河北省'

分数转位次:

Invoke-RestMethod `
  -Uri 'http://127.0.0.1:8080/api/v1/score-ranks/convert?province=河北省&year=2025&subject=PHYSICS&score=650'

执行发布校验:

$body = @{
  province = '河北省'
  year = 2025
  dataset = 'score-ranks'
} | ConvertTo-Json

Invoke-RestMethod `
  -Method Post `
  -Uri 'http://127.0.0.1:8080/api/admin/v1/publications/validate' `
  -ContentType 'application/json; charset=utf-8' `
  -Body $body

9 当前接口限制

  1. 尚无 OpenAPI 或 Swagger 页面,本文档与代码同步维护。
  2. 尚无统一响应包装,审核台和 P0 接口命名风格不同。
  3. 尚未实现认证授权,审核和管理接口不可直接暴露公网。
  4. 审核台通用数据接口仍直接查询内部业务表;P0 公共接口已经与其隔离,只读当前公共版本。
  5. 目前仅考试模式已经发布;一分一段、投档线和专业录取线仍需逐条审核后才能生成公共版本。
  6. 分数转换只支持精确分数,不做插值和临近值匹配。
  7. 数据详情不存在时当前返回 400,后续应改为 404。
  8. 当前没有接口版本化的审核台路由,后续计划迁移至 /api/admin/v1/**。

10 后续文档维护规则

新增或修改接口时,应同步更新:

  • 路径和 HTTP 方法
  • 请求参数与默认值
  • 请求和响应示例
  • 枚举值
  • 错误条件
  • 鉴权要求
  • 数据来源、审核状态和质量限制

下一阶段接入 Springdoc OpenAPI 后,应以自动生成的 OpenAPI 描述作为字段级契约,本文档保留业务说明、调用示例和重要限制。