41 KiB
招生协作系统 API 接口文档
1. 适用场景
企业微信暂时无法完成真实授权联调时,可使用 Mock 登录先验证招生协作系统后续业务。
Mock 登录与正式企业微信登录使用同一个接口:
POST /api/admission/wecom/login
区别仅在 code:
- 正式登录:企业微信临时授权码。
- Mock 登录:
MOCK:<SysUser.Id>。
Mock 登录只跳过企业微信身份识别,不绕过招生业务权限。
2. 环境要求
- 仅支持
ASPNETCORE_ENVIRONMENT=Development。 - 非开发环境会拒绝 Mock 登录。
SysUser.Id必须存在且账号状态为启用。- 建议使用专用测试用户。
本地环境可检查:
WeCom.Admin.NET/WeCom.Admin.NET.Web.Entry/Properties/launchSettings.json
X-Admission-Mock-Key:qmv22PlpQWLvyqMVMEUPBbzy9DZpaSXdii49mogphWY
3. 请求 Demo
JavaScript:
const response = await fetch('/api/admission/wecom/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Admission-Mock-Key': '这里填写临时密钥'
},
body: JSON.stringify({
code: 'MOCK:190000000000001'
})
})
const data = await response.json()
if (data.code !== 200 || !data.result?.accessToken) {
throw new Error(data.message || 'Mock 登录失败')
}
localStorage.setItem('accessToken', data.result.accessToken)
localStorage.setItem('refreshToken', data.result.refreshToken)
4. 返回 Demo
{
"code": 200,
"type": "success",
"message": "",
"result": {
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "eyJhbGciOiJIUzI1NiIs...",
"sysUserId": 190000000000001,
"employeeId": "mock-190000000000001",
"employeeName": "招生测试用户",
"departmentId": 10001,
"roles": 23,
"dataScope": 3
},
"extras": null,
"time": "2026-07-21T10:30:00"
}
字段说明:
| 字段 | 中文说明 |
|---|---|
accessToken |
后续接口使用的 JWT |
refreshToken |
刷新登录状态的令牌 |
sysUserId |
Mock 使用的系统用户 ID |
employeeId |
新建 Mock 授权时为 mock-<用户ID> |
employeeName |
测试用户名称 |
departmentId |
用户所属机构 ID |
roles |
招生业务角色位标记 |
dataScope |
数据范围 |
新建 Mock 授权默认:
roles = 23
教师 1 + 门卫 2 + 接待人员 4 + 招生管理员 16
dataScope = 3
全部数据范围
5. 授权处理规则
| 场景 | 处理方式 |
|---|---|
| 系统用户不存在 | 登录失败 |
| 系统用户已停用 | 登录失败 |
| 没有招生授权 | 自动创建 Mock 授权 |
| 已存在 Mock 授权 | 更新登录时间并继续使用 |
| 已存在启用的真实授权 | 保留原角色和数据范围 |
| 已存在已停用的真实授权 | 登录失败 |
6. 使用 Token
登录后保存:
result.accessToken
后续请求头:
Authorization: Bearer <result.accessToken>
Content-Type: application/json
验证当前授权:
GET /api/admission/authorization/current
Authorization: Bearer <result.accessToken>
7. 推荐验证顺序
| 顺序 | 接口 | 用途 |
|---|---|---|
| 1 | POST /api/admission/wecom/login |
Mock 登录 |
| 2 | GET /api/admission/authorization/current |
验证角色和数据范围 |
| 3 | GET /api/admission/options/invitation-form |
加载学段和学校区域 |
| 4 | POST /api/admission/school/search |
查询学校 |
| 5 | POST /api/admission/contact/search |
查询家长 |
| 6 | POST /api/admission/student/search |
查询学生缴费 |
| 7 | POST /api/admission/invitation/create |
创建邀约 |
| 8 | POST /api/checkin/manual |
人工补录到校 |
| 9 | POST /api/checkin/reception/page |
查询接待任务 |
| 10 | POST /api/checkin/reception/claim |
领取任务 |
| 11 | POST /api/checkin/reception/complete |
完成接待 |
| 12 | GET /api/admission/sheet/standard-record |
查询标准数据 |
完整流程:
Mock 登录
↓
获取 accessToken
↓
查询辅助数据和家长学生
↓
创建邀约
↓
核销或人工补录
↓
领取并完成接待
↓
查询看板和标准表格数据
8. 常见错误
Mock 登录仅允许在 Development 环境使用
检查 ASPNETCORE_ENVIRONMENT,修改为 Development 后重启后端。
Mock 登录用户不存在或已停用
确认请求中的 SysUser.Id 存在,并且系统账号已启用。
当前员工没有该业务权限
检查登录返回的 roles,或调用:
GET /api/admission/authorization/current
建议改用专用 Mock 测试用户。
返回 401
确认:
- 使用的是
result.accessToken。 - 请求头格式为
Authorization: Bearer <accessToken>。 - Token 未过期。
9. 恢复正式企业微信登录
接口地址无需修改。
将:
{
"code": "MOCK:190000000000001"
}
替换为真实企业微信临时授权码:
{
"code": "WE_COM_TEMP_CODE"
}
正式流程:
企业微信临时授权码
↓
企业微信 getuserinfo
↓
获取员工 UserId
↓
查询本地员工和招生授权
↓
生成 Admin.NET JWT
招生协作系统 API 接口文档
本文档说明新增招生协作功能的接口分类、接口用途、字段含义和完整调用示例。
1. 通用调用说明
接口基础地址示例:
"X-Admission-Mock-Key: ": "qmv22PlpQWLvyqMVMEUPBbzy9DZpaSXdii49mogphWY"
text
https://api.zsfz.jinzek.com
除企业微信免登、家长公开邀约页面和 4G 设备核销外,其余接口均需携带:
Authorization: Bearer <accessToken>
Content-Type: application/json
Admin.NET 统一响应结构:
{
"code": 200,
"type": "success",
"message": "",
"result": {},
"extras": null,
"time": "2026-07-18T10:30:00"
}
| 字段 | 类型 | 中文说明 |
|---|---|---|
code |
int | 状态码,成功通常为 200 |
type |
string | success、warning 或 error |
message |
string | 提示或错误信息 |
result |
object | 实际业务数据 |
extras |
object | 框架附加数据 |
time |
datetime | 服务端响应时间 |
分页接口的 result 字段:
| 字段 | 类型 | 中文说明 |
|---|---|---|
page |
int | 当前页码 |
pageSize |
int | 每页数量 |
total |
int | 总记录数 |
totalPages |
int | 总页数 |
items |
array | 当前页数据 |
hasPrevPage |
bool | 是否有上一页 |
hasNextPage |
bool | 是否有下一页 |
2. 功能分类
| 功能分类 | 接口 |
|---|---|
| 企业微信登录与授权 | /api/admission/wecom/login、/api/admission/authorization/current、/api/admission/authorization/save、/api/admission/authorization/page |
| 家长与学生查询 | /api/admission/contact/search、/api/admission/student/search |
| 招生辅助数据 | /api/admission/options/consult-stages、/api/admission/options/invitation-form、/api/admission/school/regions、/api/admission/school/search、/api/admission/school/detail |
| 邀约与二维码 | /api/admission/invitation/create、update、cancel、detail、public-detail、regenerate-qr、page |
| 数据看板 | /api/admission/invitation/dashboard |
| 4G 核销设备 | /api/checkin/device/save、device/list、device/verify |
| 人工核销 | /api/checkin/manual、/api/checkin/revoke |
| 接待任务 | /api/checkin/reception/page、claim、complete |
| 在线表格 | /api/admission/sheet/standard-record、standard-list、outbox/page、outbox/retry |
2.1 招生辅助数据
所有辅助数据接口均要求员工已通过企业微信登录并获得招生业务授权。
查询咨询学段
GET /api/admission/options/consult-stages
返回字段:
| 字段 | 类型 | 说明 |
|---|---|---|
label |
string | 页面显示文字 |
value |
int | 提交到邀约 consultStage 的枚举整数 |
sort |
int | 展示顺序 |
disabled |
bool | 是否禁止选择 |
当前顺序:高中、职教高考、综合高中、小学、初中、国际/出国、复读。具体枚举值与校区映射见 10.8。
初始化邀约表单
GET /api/admission/options/invitation-form
一次返回 consultStages 和 schoolRegions。页面首次打开时调用,学校明细仍按区域单独查询。
查询学校区域
GET /api/admission/school/regions
返回字段:
| 字段 | 类型 | 说明 |
|---|---|---|
region |
string | 区域名称 |
label |
string | 页面显示名称 |
schoolCount |
int | 该区域有效学校数量 |
sort |
int | 移动端左侧区域顺序 |
分页查询学校
POST /api/admission/school/search
请求示例:
{
"page": 1,
"pageSize": 50,
"region": "市中区",
"keyword": "实验"
}
请求字段:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
page |
int | 否 | 页码,小于 1 自动按 1 处理 |
pageSize |
int | 否 | 每页数量,最大 100 |
region |
string | 否 | 区域精确筛选 |
keyword |
string | 否 | 学校名称模糊搜索 |
返回分页数据,items 子字段为 id、region、schoolName。
查询学校详情
GET /api/admission/school/detail?id=<学校ID>
用于选择学校后再次校验记录是否存在且未删除。学校数据直接来自现有 busmiddleschoolinfo 表,所有查询均过滤 IsDelete = 0。
3. 企业微信登录与员工授权
3.1 企业微信员工免登
POST /api/admission/wecom/login
接口说明: 前端取得企业微信临时授权码后调用。后端识别企微员工、校验招生业务授权、关联 Admin.NET 用户并返回 JWT。
权限: 无需登录。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
code |
string | 是 | 企业微信应用临时授权码 |
请求示例
{
"code": "WE_COM_TEMP_CODE"
}
返回字段
| 字段 | 类型 | 中文说明 |
|---|---|---|
accessToken |
string | 后续接口使用的 JWT |
refreshToken |
string | 刷新登录状态的令牌 |
sysUserId |
long | 关联的 Admin.NET 用户 ID |
employeeId |
string | 企业微信员工 UserId |
employeeName |
string | 员工姓名 |
departmentId |
long | 企业微信部门 ID |
roles |
int | 业务角色位标记 |
dataScope |
int | 数据查看范围 |
3.1.1 获取企业微信 JS-SDK 签名
POST /api/admission/wecom/jssdk-signature
接口说明: 为 @wecom/jssdk 的 getConfigSignature(url) 生成 config 签名。后端自动获取并缓存企业微信 access_token 和 jsapi_ticket,不会向前端返回 CorpSecret 或 ticket。
权限: 无需登录。生产环境只允许为配置白名单内的 HTTPS 页面地址签名。
请求示例
{
"url": "https://admission.example.com/invitation/detail?id=1001#/share"
}
服务端签名时会自动移除 URL 中的 # 及其后内容。
返回示例
{
"corpId": "wwxxxxxxxxxxxxxxxx",
"timestamp": 1784645000,
"nonceStr": "randomNonce",
"signature": "sha1Signature",
"url": "https://admission.example.com/invitation/detail?id=1001"
}
生产环境配置
AdmissionWeComJsSdk__AllowedHosts=admission.example.com,*.example.com
- 多个域名使用英文逗号或分号分隔。
- 精确域名示例:
admission.example.com。 - 子域名通配示例:
*.example.com,不包含根域名example.com。 - 生产环境仅接受 HTTPS URL;开发环境允许 HTTP 和 HTTPS。
- 企业微信管理后台还需在自建应用的“网页授权及 JS-SDK”中设置对应可信域名。
3.2 查询当前员工授权
GET /api/admission/authorization/current
接口说明: 查询当前员工的角色、数据范围、授权状态和最近登录时间。
返回字段
| 字段 | 类型 | 中文说明 |
|---|---|---|
id |
long | 授权记录 ID |
sysUserId |
long | Admin.NET 用户 ID |
weComEmployeeId |
string | 企业微信员工 UserId |
openUserId |
string | 企业微信 OpenUserId |
employeeName |
string | 员工姓名 |
departmentId |
long | 企业微信部门 ID |
roles |
int | 业务角色位标记 |
dataScope |
int | 数据范围 |
status |
int | 授权状态 |
authorizedTime |
datetime | 授权时间 |
lastLoginTime |
datetime | 最近登录时间 |
3.3 新增或修改员工授权
POST /api/admission/authorization/save
接口说明: 将企业微信员工与系统用户绑定,并配置业务角色和数据权限。
权限: 系统管理员或招生管理员。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
id |
long | 否 | 不传为新增,传入为修改 |
sysUserId |
long | 是 | Admin.NET 用户 ID |
weComEmployeeId |
string | 是 | 企业微信员工 UserId |
roles |
int | 是 | 角色位标记,可将多个角色值相加 |
dataScope |
int | 否 | 1本人、2本部门、3全部 |
status |
int | 否 | 0待授权、1启用、2停用、3离职 |
请求示例
{
"sysUserId": 190000000000001,
"weComEmployeeId": "zhangsan",
"roles": 5,
"dataScope": 1,
"status": 1
}
返回: result 为授权记录 ID。
3.4 分页查询员工授权
POST /api/admission/authorization/page
接口说明: 后台分页查询员工授权记录。
权限: 系统管理员或招生管理员。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
page |
int | 否 | 当前页,默认 1 |
pageSize |
int | 否 | 每页数量,默认 20 |
keyword |
string | 否 | 员工姓名或企微 UserId |
status |
int | 否 | 授权状态 |
返回分页结构,items 字段与“查询当前员工授权”一致。
4. 家长与学生查询
4.1 查询企业微信外部联系人
POST /api/admission/contact/search
接口说明: 按当前教师数据权限查询已有企业微信家长联系人,可按姓名、备注或备注手机号匹配。
权限: 教师或招生管理员。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
keyword |
string | 是 | 至少 2 个字符 |
limit |
int | 否 | 默认 50,最大 100 |
返回字段
| 字段 | 类型 | 中文说明 |
|---|---|---|
externalUserId |
string | 企业微信外部联系人 ID |
parentName |
string | 家长名称 |
parentPhone |
string | 家长备注手机号 |
employeeId |
string | 跟进教师企微 UserId |
employeeName |
string | 跟进教师姓名 |
remark |
string | 客户备注 |
tags |
string[] | 客户标签 |
4.2 查询学生缴费与退款
POST /api/admission/student/search
接口说明: 查询现有 BusGaiBillLog 和退款数据,按学生姓名、手机号或身份证号匹配,并汇总多笔交易。
权限: 教师或招生管理员。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
keyword |
string | 是 | 学生姓名、手机号或身份证号 |
limit |
int | 否 | 默认 50,最大 100 |
返回字段
| 字段 | 类型 | 中文说明 |
|---|---|---|
studentName |
string | 学生姓名 |
phone |
string | 原联系电话 |
maskedPhone |
string | 脱敏手机号 |
idCard |
string | 脱敏身份证号 |
stage |
string | 学段 |
gradeLevel |
string | 年级 |
paymentStatus |
int | 报名缴费状态 |
paidAmountYuan |
decimal | 累计缴费金额,单位元 |
refundAmountYuan |
decimal | 累计退款金额,单位元 |
latestPaymentTime |
datetime | 最近支付时间 |
transactionIds |
string[] | 交易单号集合 |
5. 邀约与二维码
5.1 创建邀约
POST /api/admission/invitation/create
接口说明: 教师创建到校邀约,后端自动写入教师和部门信息,并生成二维码 Token。
规则:
- 同一学生、同一手机号、同一天不允许重复有效邀约。
consultStage为整数枚举,后端根据学段自动确定南校或北校,前端不再决定校区。- 二维码从预约到访日当天
00:00:00开始,连续 3 个自然日有效。 - 超过预约到访日仍未签到时,邀约自动标记为“未到访”,但二维码有效期独立计算。
- “未到访”邀约在二维码有效期内完成门卫核销后,状态自动更新为“已到访”。
- 同一二维码通过原子状态更新只允许成功核销一次,不会重复增加到访记录。
权限: 教师或招生管理员。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
studentName |
string | 是 | 学生姓名 |
parentName |
string | 否 | 家长姓名 |
parentPhone |
string | 是 | 家长手机号 |
externalUserId |
string | 否 | 企业微信外部联系人 ID |
consultStage |
int | 是 | 咨询学段枚举,见 10.8;后端据此自动匹配南校或北校 |
gradeLevel |
string | 否 | 年级 |
schoolName |
string | 否 | 毕业或在读学校 |
campusName |
string | 否 | 兼容字段,后端会忽略该值并按 consultStage 自动设置校区 |
appointmentStart |
datetime | 是 | 预约开始时间 |
appointmentEnd |
datetime | 是 | 预约结束时间 |
remark |
string | 否 | 备注 |
请求示例
{
"studentName": "王小明",
"parentName": "李女士",
"parentPhone": "13800138000",
"externalUserId": "wmABC123",
"consultStage": 5,
"gradeLevel": "初三",
"schoolName": "某某实验学校",
"appointmentStart": "2026-07-20T09:00:00+08:00",
"appointmentEnd": "2026-07-20T11:00:00+08:00",
"remark": "了解秋季班"
}
邀约返回字段
| 字段 | 类型 | 中文说明 |
|---|---|---|
id |
long | 邀约 ID |
invitationNo |
string | 邀约业务编号 |
studentName |
string | 学生姓名 |
parentName |
string | 家长姓名 |
parentPhone |
string | 家长手机号 |
maskedPhone |
string | 脱敏手机号 |
consultStage |
int | 咨询学段枚举 |
consultStageName |
string | 咨询学段中文名称 |
gradeLevel |
string | 年级 |
schoolName |
string | 学校 |
campusName |
string | 到访校区 |
appointmentStart |
datetime | 预约开始时间 |
appointmentEnd |
datetime | 预约结束时间 |
teacherName |
string | 邀约教师 |
status |
int | 邀约状态 |
arrivedTime |
datetime | 实际到校时间 |
qrToken |
string | 二维码唯一 Token |
qrStatus |
int | 二维码状态 |
qrValidFrom |
datetime | 二维码生效时间 |
qrValidTo |
datetime | 二维码失效时间 |
publicPageUrl |
string | 可用于短信发送的家长邀约页面地址 |
5.2 修改邀约
POST /api/admission/invitation/update
接口说明: 修改本人创建的待到访邀约。预约时间或咨询学段发生变化时,旧二维码作废并生成新二维码。
请求字段
与“创建邀约”一致,增加:
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
id |
long | 是 | 邀约 ID |
成功时无业务返回值。
5.3 取消邀约
POST /api/admission/invitation/cancel
接口说明: 取消待到访邀约,并作废所有未使用二维码。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
id |
long | 是 | 邀约 ID |
reason |
string | 是 | 取消原因 |
5.4 查询邀约详情
GET /api/admission/invitation/detail?id=<邀约ID>
接口说明: 查询单条邀约和最新二维码。
查询参数
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
id |
long | 是 | 邀约 ID |
返回字段与“邀约返回字段”一致。
5.4.1 查询家长邀约页面
GET /api/admission/invitation/public-detail?token=<二维码Token>
接口说明: 家长通过短信中的 publicPageUrl 打开页面后调用。接口无需登录,使用二维码 Token 查询预约日期、二维码、学校地址、导航信息和当前有效状态。
页面建议展示:
- 预约到访日期和当前状态。
- 供门卫核验的二维码。
- 二维码有效起止时间。
- 南校或北校名称及详细地址。
- “导航到校”按钮,点击后打开
navigationUrl对应的手机地图应用。
返回字段
| 字段 | 类型 | 中文说明 |
|---|---|---|
invitationNo |
string | 邀约编号 |
studentName |
string | 学生姓名 |
consultStage |
int | 咨询学段枚举 |
consultStageName |
string | 咨询学段中文名称 |
appointmentDate |
date | 预约到访日期 |
status |
int | 邀约状态 |
statusName |
string | 邀约状态中文名称 |
campusName |
string | 南校或北校名称 |
campusAddress |
string | 学校详细地址 |
latitude |
double | 纬度 |
longitude |
double | 经度 |
navigationUrl |
string | 手机地图导航地址 |
qrValidFrom |
datetime | 二维码生效时间 |
qrValidTo |
datetime | 二维码失效时间 |
qrStatus |
int | 二维码状态 |
canCheckin |
bool | 当前是否允许门卫核销 |
服务器配置
AdmissionInvitation__PublicPageBaseUrl=https://admission.example.com/appointment
AdmissionCampus__South__Name=南校
AdmissionCampus__South__Address=<南校实际地址>
AdmissionCampus__South__Latitude=<南校纬度>
AdmissionCampus__South__Longitude=<南校经度>
AdmissionCampus__South__NavigationUrl=<南校地图导航链接>
AdmissionCampus__North__Name=北校
AdmissionCampus__North__Address=<北校实际地址>
AdmissionCampus__North__Latitude=<北校纬度>
AdmissionCampus__North__Longitude=<北校经度>
AdmissionCampus__North__NavigationUrl=<北校地图导航链接>
PublicPageBaseUrl 不需要预先携带 Token,后端会自动追加 ?token=...。学校真实地址、经纬度和地图链接必须在部署时填写,不能使用示例占位值。
5.5 重新生成二维码
POST /api/admission/invitation/regenerate-qr
接口说明: 作废当前未使用二维码并生成新 Token,只允许待到访邀约调用。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
id |
long | 是 | 邀约 ID |
返回更新后的邀约对象。
5.6 分页查询邀约
POST /api/admission/invitation/page
接口说明: 按员工数据范围分页查询邀约。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
page |
int | 否 | 当前页 |
pageSize |
int | 否 | 每页数量 |
keyword |
string | 否 | 学生姓名、手机号或邀约编号 |
status |
int | 否 | 邀约状态 |
startDate |
datetime | 否 | 预约开始时间下限 |
endDate |
datetime | 否 | 预约开始时间上限,包含该自然日 |
items 为邀约对象,列表接口不返回二维码 Token。
5.7 招生基础看板
POST /api/admission/invitation/dashboard
接口说明: 按员工权限和邀约创建时间统计邀约、到访、接待与教师排名。未传日期时默认最近 30 天。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
startDate |
datetime | 否 | 创建时间起点 |
endDate |
datetime | 否 | 创建时间终点 |
返回字段
| 字段 | 类型 | 中文说明 |
|---|---|---|
totalInvitations |
int | 邀约总数 |
arrived |
int | 已到访或已完成数量 |
pendingArrival |
int | 待到访数量 |
noShow |
int | 未到访数量 |
cancelled |
int | 已取消数量 |
waitingReception |
int | 待领取接待任务数 |
completedReception |
int | 已完成接待任务数 |
teacherRanking |
array | 教师排名,子字段为 teacherName、count |
6. 4G 核销设备
6.1 新增或修改设备
POST /api/checkin/device/save
接口说明: 配置 4G 核销设备、设备密钥、所属校区和门岗。
权限: 系统管理员或招生管理员。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
id |
long | 否 | 不传新增,传入修改 |
deviceId |
string | 是 | 设备唯一编号 |
deviceName |
string | 是 | 设备名称 |
serialNumber |
string | 否 | 出厂序列号 |
deviceSecret |
string | 新增时是 | HMAC 签名密钥;修改时不传则保持不变 |
campusName |
string | 是 | 所属校区 |
gateName |
string | 否 | 门岗 |
enabled |
bool | 否 | 是否启用 |
返回: result 为设备记录 ID。
6.2 查询设备列表
GET /api/checkin/device/list
接口说明: 查询设备及最近在线情况,不返回密钥。
权限: 系统管理员或招生管理员。
返回字段
| 字段 | 类型 | 中文说明 |
|---|---|---|
id |
long | 设备记录 ID |
deviceId |
string | 设备编号 |
deviceName |
string | 设备名称 |
serialNumber |
string | 序列号 |
campusName |
string | 校区 |
gateName |
string | 门岗 |
enabled |
bool | 是否启用 |
firmwareVersion |
string | 固件版本 |
lastOnlineTime |
datetime | 最近在线时间 |
lastRequestIp |
string | 最近请求 IP |
6.3 设备二维码核销
POST /api/checkin/device/verify
接口说明: 设备扫码后直接调用。接口校验设备、时间戳、签名、二维码、邀约状态、有效时间和校区,并自动创建到校记录与待接待任务。
核销规则:
待到访和未到访状态都允许在二维码有效期内核销。- 核销成功后,邀约状态更新为
已到访。 - 二维码状态通过数据库原子更新从
未使用改为已核销;同一二维码并发或重复扫码只会生成一条到访记录。
权限: 无需用户 Token,使用设备签名。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
deviceId |
string | 是 | 设备编号 |
requestId |
string | 是 | 请求唯一编号;重试必须保持不变 |
nonce |
string | 是 | 随机字符串 |
timestamp |
long | 是 | Unix 秒级时间戳 |
qrCode |
string | 是 | 二维码原文,可为 Token 或含 Token 的 URL |
signature |
string | 是 | HMAC-SHA256 小写十六进制签名 |
firmwareVersion |
string | 否 | 固件版本 |
签名规则
qrHash = SHA256(qrCode),小写十六进制
canonical =
deviceId + "\n" +
requestId + "\n" +
timestamp + "\n" +
nonce + "\n" +
qrHash
signature = HMAC-SHA256(deviceSecret, canonical),小写十六进制
返回字段
设备读取统一响应中的 result:
| 字段 | 类型 | 中文说明 |
|---|---|---|
success |
bool | 核销是否成功 |
resultCode |
string | 设备结果码 |
message |
string | 屏幕显示内容 |
voiceText |
string | 语音播报内容 |
invitationNo |
string | 邀约编号 |
studentName |
string | 学生姓名 |
checkinTime |
datetime | 核销时间 |
结果码
| resultCode | 中文说明 |
|---|---|
CHECKIN_SUCCESS |
核销成功 |
DEVICE_UNAUTHORIZED |
设备未授权或已停用 |
REQUEST_EXPIRED |
请求时间戳过期 |
SIGNATURE_INVALID |
签名错误 |
QR_NOT_FOUND |
二维码不存在 |
INVITATION_NOT_FOUND |
邀约不存在 |
INVITATION_CANCELLED |
邀约已取消 |
QR_ALREADY_USED |
二维码已使用 |
QR_DISABLED |
二维码已作废 |
QR_EXPIRED |
不在有效核销时间内 |
CAMPUS_MISMATCH |
设备校区与邀约校区不一致 |
7. 人工核销
7.1 人工补录到校
POST /api/checkin/manual
接口说明: 设备故障或二维码无法识别时,由门卫人工补录。成功后自动创建接待任务。
权限: 门卫或招生管理员。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
invitationId |
long | 是 | 邀约 ID |
reason |
string | 是 | 补录原因 |
返回: result 为新建核销记录 ID。
7.2 撤销核销
POST /api/checkin/revoke
接口说明: 撤销误核销,同时恢复邀约状态、处理二维码并取消关联接待任务。
权限: 系统管理员或招生管理员。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
checkinId |
long | 是 | 核销记录 ID |
reason |
string | 是 | 撤销原因 |
8. 接待任务
8.1 分页查询接待任务
POST /api/checkin/reception/page
接口说明: 查询设备核销或人工补录后自动生成的接待任务。
权限: 接待人员或招生管理员。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
page |
int | 否 | 当前页 |
pageSize |
int | 否 | 每页数量 |
status |
int | 否 | 接待状态 |
keyword |
string | 否 | DTO 已保留,当前接口尚未使用该字段过滤 |
接待任务字段
| 字段 | 类型 | 中文说明 |
|---|---|---|
id |
long | 接待任务 ID |
invitationId |
long | 邀约 ID |
checkinRecordId |
long | 核销记录 ID |
status |
int | 接待状态 |
receptionistSysUserId |
long | 接待人员系统用户 ID |
receptionistName |
string | 接待人员姓名 |
claimedTime |
datetime | 领取时间 |
startedTime |
datetime | 开始时间 |
completedTime |
datetime | 完成时间 |
receptionResult |
string | 接待结果 |
receptionRecord |
string | 接待过程 |
followSuggestion |
string | 跟进建议 |
unregisteredReason |
string | 未报名原因 |
unpaidReason |
string | 未缴费原因 |
nextFollowTime |
datetime | 下次跟进时间 |
8.2 领取接待任务
POST /api/checkin/reception/claim
接口说明: 接待人员领取待领取任务。使用数据库条件更新,同一任务只能有一人领取成功。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
id |
long | 是 | 接待任务 ID,不是邀约 ID |
8.3 完成接待
POST /api/checkin/reception/complete
接口说明: 接待人员填写结果并完成任务,同时将邀约状态更新为已完成。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
taskId |
long | 是 | 接待任务 ID |
receptionResult |
string | 是 | 接待结果 |
receptionRecord |
string | 否 | 接待过程记录 |
followSuggestion |
string | 否 | 跟进建议 |
unregisteredReason |
string | 否 | 未报名原因 |
unpaidReason |
string | 否 | 未缴费原因 |
nextFollowTime |
datetime | 否 | 下次跟进时间 |
9. 在线表格标准数据
9.1 获取单条标准数据
GET /api/admission/sheet/standard-record?id=<邀约ID>
接口说明: 合并邀约、教师、到校、接待、缴费和退款信息,输出可供飞书或企业微信在线表格映射的统一记录。
返回字段
| 字段 | 类型 | 中文说明 |
|---|---|---|
invitationId |
string | 邀约 ID,按文本输出 |
invitationNo |
string | 邀约编号,建议作为表格唯一键 |
studentName |
string | 学生姓名 |
parentName |
string | 家长姓名 |
parentPhone |
string | 家长手机号 |
teacherUserId |
string | 教师企微 UserId |
teacherName |
string | 教师姓名 |
departmentId |
long | 部门 ID |
consultStage |
int | 咨询学段枚举 |
gradeLevel |
string | 年级 |
schoolName |
string | 学校 |
campusName |
string | 校区 |
appointmentStart |
datetime | 预约时间 |
invitationStatus |
int | 邀约状态 |
checkinTime |
datetime | 到校时间 |
checkinMode |
string | 核销方式 |
receptionStatus |
int | 接待状态 |
receptionistName |
string | 接待人员 |
receptionResult |
string | 接待结果 |
paymentStatus |
int | 缴费状态 |
paidAmountYuan |
decimal | 缴费金额,单位元 |
refundAmountYuan |
decimal | 退款金额,单位元 |
createdTime |
datetime | 创建时间 |
updatedTime |
datetime | 更新时间 |
9.2 批量获取标准数据
POST /api/admission/sheet/standard-list
接口说明: 按数据权限和日期范围批量输出标准数据,单次最大 200 条。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
page |
int | 否 | 当前页 |
pageSize |
int | 否 | 每页数量,最大 200 |
startDate |
datetime | 否 | 预约时间起点 |
endDate |
datetime | 否 | 预约时间终点 |
keyword |
string | 否 | DTO 已保留,当前接口尚未使用 |
status |
int | 否 | DTO 已保留,当前接口尚未使用 |
返回标准数据数组。
9.3 查询同步任务
POST /api/admission/sheet/outbox/page
接口说明: 查询邀约创建、核销、接待完成等业务动作产生的在线表格同步任务。
权限: 系统管理员或招生管理员。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
page |
int | 否 | 当前页 |
pageSize |
int | 否 | 每页数量 |
同步任务字段
| 字段 | 类型 | 中文说明 |
|---|---|---|
id |
long | 任务 ID |
platform |
string | 平台,当前初始值为 STANDARD |
businessKey |
string | 业务唯一键,当前为邀约编号 |
operation |
string | 操作类型,当前主要为 UPSERT |
payload |
string | JSON 数据 |
status |
int | 同步状态 |
retryCount |
int | 重试次数 |
nextRetryTime |
datetime | 下次重试时间 |
lastError |
string | 最近错误信息 |
9.4 重试同步任务
POST /api/admission/sheet/outbox/retry
接口说明: 将任务重置为待处理状态并清空错误信息。
权限: 系统管理员或招生管理员。
请求字段
| 字段 | 类型 | 必填 | 中文说明 |
|---|---|---|---|
id |
long | 是 | 同步任务 ID |
10. 枚举值说明
10.1 roles 角色位标记
| 数值 | 中文说明 |
|---|---|
1 |
教师 |
2 |
门卫 |
4 |
接待人员 |
8 |
部门负责人 |
16 |
招生管理员 |
多个角色相加,例如 5 = 教师 1 + 接待人员 4。
10.2 dataScope 数据范围
| 数值 | 中文说明 |
|---|---|
1 |
仅本人 |
2 |
本部门 |
3 |
全部数据 |
10.3 邀约状态
| 数值 | 中文说明 |
|---|---|
1 |
待到访 |
2 |
已到访 |
3 |
已完成 |
4 |
已取消 |
5 |
未到访 |
未到访: 超过预约到访日仍未签到;有效期内后续签到时,状态自动更新为“已到访”。
例如预约到访日为 7月25日:
7月25日 23:59:59前未签到:邀约为“待到访”,二维码可用。7月26日 00:00仍未签到:邀约转为“未到访”,二维码仍可用。7月26日至7月27日完成签到:邀约转为“已到访”。7月28日 00:00起仍未签到:邀约保持“未到访”,二维码转为“已过期”。
10.4 二维码状态
| 数值 | 中文说明 |
|---|---|
1 |
未使用 |
2 |
已核销 |
3 |
已过期 |
4 |
已作废 |
10.5 接待状态
| 数值 | 中文说明 |
|---|---|
1 |
待领取 |
2 |
已分配 |
3 |
接待中 |
4 |
已完成 |
5 |
已取消 |
10.6 缴费状态
| 数值 | 中文说明 |
|---|---|
0 |
未找到报名缴费记录 |
1 |
已报名未缴费 |
2 |
已缴费 |
3 |
部分退款 |
4 |
全额退款 |
5 |
待确认 |
10.7 同步状态
| 数值 | 中文说明 |
|---|---|
0 |
待处理 |
1 |
处理中 |
2 |
成功 |
3 |
失败 |
10.8 咨询学段枚举
| 数值 | 中文说明 | 自动到访校区 |
|---|---|---|
1 |
高中 | 南校 |
2 |
职教高考 | 北校 |
3 |
综合高中 | 北校 |
4 |
小学 | 南校 |
5 |
初中 | 南校 |
6 |
国际/出国 | 南校 |
7 |
复读 | 南校 |
GET /api/admission/options/consult-stages 返回的 value 即上述整数枚举。创建和修改邀约时,consultStage 必须提交整数,不再接受中文字符串。
11. 新功能完整使用示例
以下示例说明“教师邀约家长到校—设备核销—接待完成—输出在线表格数据”的完整过程。
第一步:管理员授权教师
POST /api/admission/authorization/save
Authorization: Bearer <管理员Token>
{
"sysUserId": 190000000000001,
"weComEmployeeId": "zhangsan",
"roles": 5,
"dataScope": 1,
"status": 1
}
roles = 5 表示张老师同时具有教师和接待人员角色。
第二步:教师企业微信免登
POST /api/admission/wecom/login
{
"code": "企业微信临时授权码"
}
保存返回的:
result.accessToken
后续教师接口统一携带:
Authorization: Bearer <result.accessToken>
第三步:查询家长
POST /api/admission/contact/search
Authorization: Bearer <教师Token>
{
"keyword": "1380013",
"limit": 20
}
从结果中取得 externalUserId、家长姓名和手机号。
第四步:查询学生交易状态
POST /api/admission/student/search
Authorization: Bearer <教师Token>
{
"keyword": "王小明",
"limit": 20
}
前端可以展示当前报名、缴费、退款和最近交易时间。
第五步:创建邀约
POST /api/admission/invitation/create
Authorization: Bearer <教师Token>
{
"studentName": "王小明",
"parentName": "李女士",
"parentPhone": "13800138000",
"externalUserId": "wmABC123",
"consultStage": 5,
"gradeLevel": "初三",
"schoolName": "某某实验学校",
"appointmentStart": "2026-07-20T09:00:00+08:00",
"appointmentEnd": "2026-07-20T11:00:00+08:00",
"remark": "了解秋季班"
}
consultStage = 5 表示初中,后端自动将到访校区设置为南校。创建成功后,从返回值取得 result.publicPageUrl,将该地址放入短信发送给家长:
https://admission.example.com/appointment?token=<qrToken>
家长打开页面后,前端读取 URL 中的 token,调用 GET /api/admission/invitation/public-detail,展示二维码、预约日期、学校地址、有效期和“导航到校”按钮。
第六步:设备扫码核销
设备按照签名规则生成 signature,然后调用:
POST /api/checkin/device/verify
{
"deviceId": "WG-CHECKIN-001",
"requestId": "WG-CHECKIN-001-1784512800-000001",
"nonce": "b964cf98d5d14d21",
"timestamp": 1784512800,
"qrCode": "创建邀约返回的qrToken",
"signature": "设备计算的HMAC签名",
"firmwareVersion": "1.0.3"
}
设备读取:
result.success
result.resultCode
result.message
result.voiceText
成功后系统自动创建待接待任务。
第七步:接待人员领取任务
查询待领取任务:
POST /api/checkin/reception/page
Authorization: Bearer <接待人员Token>
{
"page": 1,
"pageSize": 20,
"status": 1
}
取得任务 ID 后调用:
POST /api/checkin/reception/claim
Authorization: Bearer <接待人员Token>
{
"id": 190000000000300
}
第八步:完成接待
POST /api/checkin/reception/complete
Authorization: Bearer <接待人员Token>
{
"taskId": 190000000000300,
"receptionResult": "待家长确认",
"receptionRecord": "已介绍秋季班课程与时间",
"followSuggestion": "两天后电话回访",
"unregisteredReason": "需要与家人商量",
"unpaidReason": "尚未确定班型",
"nextFollowTime": "2026-07-22T15:00:00+08:00"
}
第九步:获取在线表格标准数据
GET /api/admission/sheet/standard-record?id=<邀约ID>
Authorization: Bearer <有权限的Token>
建议使用 invitationNo 作为飞书或企业微信在线表格的唯一业务键:
- 不存在该编号时新增一行。
- 已存在该编号时更新原有行。
12. 调用注意事项
- 校区由
consultStage自动确定。门卫设备的CampusName必须与AdmissionCampus__South__Name或AdmissionCampus__North__Name完全一致,否则返回CAMPUS_MISMATCH。 - 后端负责生成
publicPageUrl和提供公开详情接口;短信发送服务、家长 H5 页面和二维码渲染仍需前端或短信平台接入。 - “导航到校”直接打开后端返回的
navigationUrl。南北校真实地址、经纬度和地图链接必须在服务器部署配置中填写。 - 二维码只存
qrToken,不要写入姓名、手机号或身份证。 - 设备重试同一次核销时必须复用原
requestId;不同请求重复扫描同一二维码也只会有一次核销成功。 - 重新生成二维码后,旧二维码立即失效。
- 手机号、身份证号、交易号和邀约 ID 在在线表格中应设置为文本类型。
- 接待人员只能完成本人领取的任务,招生管理员可以处理其他任务。
数据库升级注意事项
AdmissionInvitation.ConsultStage 已由字符串改为整数枚举。已有数据库在部署新版本前,必须先备份并迁移历史数据:
| 原字符串 | 新枚举值 |
|---|---|
| 高中 | 1 |
| 职教高考 | 2 |
| 综合高中班、综合高中 | 3 |
| 小学 | 4 |
| 初中 | 5 |
| 国际、国际/出国、出国 | 6 |
| 复读 | 7 |
应先将历史字符串转换为上述数值,再将数据库字段调整为整数类型。存在无法识别的历史值时应先人工处理,不能直接上线让 ORM 自动转换。