forked from baskbuddy/zhangshun
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.
6.5 KiB
6.5 KiB
求职者评分卡 API
概述
求职者评价聚合与评分卡模块,提供求职者(STUDENT)查看自己的评价聚合数据、评分趋势和百分位排名。
权限
- 未登录:HTTP 401(code=401)
- STUDENT:HTTP 200
- COMPANY:HTTP 403(code=2002)
- ADMIN:HTTP 403(code=2002)
所有接口只允许当前登录的 STUDENT 查询自己的数据,不接受通过 URL 参数查询其他用户。
接口列表
1. GET /api/v1/profile/me/candidate-score-card
查询求职者评分卡。
响应示例(有数据):
{
"code": 200,
"message": "ok",
"data": {
"candidateId": 10001,
"status": "OK",
"overallScore": null,
"sampleCount": 3,
"feedbackSummary": {
"totalCount": 3,
"averageRating": 4.33,
"ratingDistribution": {
"1": 0,
"2": 0,
"3": 1,
"4": 0,
"5": 2
},
"tags": [
{"name": "沟通良好", "count": 2}
]
},
"matchSignals": {
"candidateInterestScore": {
"average": 82.50,
"sampleCount": 2
},
"hrSuitabilityScore": {
"average": 76.00,
"sampleCount": 1
}
},
"unsupportedDimensions": [
"EDUCATION", "INTERNSHIP", "ABILITY", "COMPLIANCE",
"STABILITY", "GROWTH", "INTEGRITY", "ACTIVITY"
],
"generatedAt": "2026-08-14T12:00:00Z"
}
}
响应示例(无数据):
{
"code": 200,
"message": "ok",
"data": {
"candidateId": 10001,
"status": "INSUFFICIENT_DATA",
"overallScore": null,
"sampleCount": 0,
"feedbackSummary": {
"totalCount": 0,
"averageRating": null,
"ratingDistribution": {
"1": 0, "2": 0, "3": 0, "4": 0, "5": 0
},
"tags": []
},
"matchSignals": {
"candidateInterestScore": {"average": null, "sampleCount": 0},
"hrSuitabilityScore": {"average": null, "sampleCount": 0}
},
"unsupportedDimensions": [
"EDUCATION", "INTERNSHIP", "ABILITY", "COMPLIANCE",
"STABILITY", "GROWTH", "INTEGRITY", "ACTIVITY"
],
"generatedAt": "2026-08-14T12:00:00Z"
}
}
错误响应:
- 未登录:401(code=401)
- 非 STUDENT:403(code=2002)
2. GET /api/v1/profile/me/candidate-score-trend
查询评分趋势。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| months | int | 否 | 6 | 统计月数,范围 1-24 |
响应示例:
{
"code": 200,
"message": "ok",
"data": {
"candidateId": 10001,
"months": 6,
"items": [
{
"month": "2026-03",
"feedbackCount": 2,
"averageRating": 4.50,
"ratingScore": 90.00
}
]
}
}
错误响应:
- 未登录:401(code=401)
- 非 STUDENT:403(code=2002)
- months < 1 或 > 24:400(code=1001)
说明:
- 趋势时间范围:
months=6表示当前月份和前 5 个自然月,起始时间使用当前月份的第一天 - 按
candidate_feedback.created_at的年月分组,结果按yyyy-MM升序 ratingScore = averageRating / 5 * 100,保留两位小数- 无数据时返回
items: [](没有数据的月份不返回空月份条目)
3. GET /api/v1/profile/me/candidate-percentile
查询评分百分位。
响应示例(有数据):
{
"code": 200,
"message": "ok",
"data": {
"candidateId": 10001,
"status": "OK",
"scoreType": "FEEDBACK_RATING",
"score": 86.67,
"percentile": 72.50,
"cohortSize": 38,
"sampleCount": 3,
"minimumSampleCount": 3
}
}
响应示例(样本不足):
{
"code": 200,
"message": "ok",
"data": {
"candidateId": 10001,
"status": "INSUFFICIENT_DATA",
"scoreType": "FEEDBACK_RATING",
"score": null,
"percentile": null,
"cohortSize": 0,
"sampleCount": 1,
"minimumSampleCount": 3
}
}
错误响应:
- 未登录:401(code=401)
- 非 STUDENT:403(code=2002)
百分位计算公式
cohort 定义:
candidate_feedback按student_user_id分组COUNT(*) >= 3的求职者进入 cohort
score 计算:
score = AVG(rating) / 5 * 100
百分位计算:
percentile = COUNT(other.score < current.score) / (cohortSize - 1) * 100- 只统计严格低于当前分数的求职者
- 最高分为 100.00
- 最低分为 0.00
- 同分不互相计入
- 使用 BigDecimal,保留两位小数,HALF_UP
INSUFFICIENT_DATA 条件:
- 当前用户反馈数 < 3
- cohort 总人数 < 2
不支持的评分维度
当前评分卡仅覆盖基于反馈的评分聚合,以下 8 个维度尚未实现,始终返回为 unsupportedDimensions:
- EDUCATION(教育背景)
- INTERNSHIP(实习经历)
- ABILITY(能力评分)
- COMPLIANCE(合规性)
- STABILITY(稳定性)
- GROWTH(成长潜力)
- INTEGRITY(诚信评分)
- ACTIVITY(求职活跃度)
overallScore 在 8 个维度全部实现前固定为 null。
数据来源
| 数据 | 来源表 |
|---|---|
| 反馈总数、平均评分、评分分布 | candidate_feedback |
| 标签聚合 | candidate_feedback.tags(JSON) |
| 求职者意愿分、HR 适配分 | application_match_records |
| 趋势 | candidate_feedback.created_at |
| 百分位 | candidate_feedback 全量聚合 |
null 字段策略
项目全局配置 spring.jackson.default-property-inclusion=non_null,null 字段默认不序列化。
以下关键字段使用 @JsonInclude(JsonInclude.Include.ALWAYS) 标注,无数据时仍显式返回 null:
overallScore(评分卡)averageRating(feedbackSummary)candidateInterestScore.average(匹配信号)hrSuitabilityScore.average(匹配信号)score(百分位)percentile(百分位)
查询次数
评分卡三个接口的实际 SQL 查询次数:
| 接口 | 查询次数 | 说明 |
|---|---|---|
| GET /profile/me/candidate-score-card | 4 条 SQL | 1 反馈摘要(COUNT+AVG合并) + 1 评分分布 + 1 标签 + 2 匹配信号(candidateInterestScore + hrSuitabilityScore) |
| GET /profile/me/candidate-score-trend | 1 条 SQL | 按月聚合趋势 |
| GET /profile/me/candidate-percentile | 3 条 SQL | cohort 人数 + 当前分数 + 排名(仅当样本>=3 且 cohort>=2 时执行全部 3 条) |
所有查询均针对单个 studentUserId,无 N+1 问题。
数据脱敏
- 不返回
candidate_feedback.content - 不返回
companyUserId - 不返回
applicationId - 不返回其他求职者的任何数据
- 不暴露内部审核字段