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.
 
 
 

10 KiB

岗位评价个性化权重与权重模板 API

概述

本模块提供岗位评价维度的个性化权重配置和基于自定义权重的岗位评分计算。学生用户可以:

  • 查看预定义的权重模板
  • 配置个人权重偏好(模板或自定义)
  • 基于个人权重计算岗位的个性化评分

接口列表

方法 路径 权限 说明
GET /review-weight-templates 已登录 获取权重模板列表
GET /profile/me/review-weights STUDENT 获取当前学生的权重配置
PUT /profile/me/review-weights STUDENT 保存当前学生的权重配置
GET /jobs/{jobId}/personalized-review-score STUDENT 基于用户权重计算岗位个性化评分

权限矩阵

角色 模板列表 权重配置 个性化评分
未登录 401 401 401
STUDENT 200 200 200
COMPANY 200 403 403
ADMIN 200 403 403

接口详情

1. GET /review-weight-templates

获取所有预定义的权重模板。

请求示例:

GET /review-weight-templates
Authorization: Bearer <token>

响应示例:

{
  "code": 200,
  "message": "success",
  "data": [
    {
      "code": "BALANCED",
      "name": "均衡权重",
      "description": "八个维度平均分配",
      "weights": {
        "AUTHENTICITY": 12.50,
        "BENEFITS": 12.50,
        "SALARY_TRANSPARENCY": 12.50,
        "JD_CLARITY": 12.50,
        "GROWTH": 12.50,
        "TEAM_ATMOSPHERE": 12.50,
        "PROMOTION": 12.50,
        "WORK_LIFE_BALANCE": 12.50
      }
    }
  ]
}

2. GET /profile/me/review-weights

获取当前学生的权重配置。未配置时返回系统默认配置(BALANCED 模板,source="SYSTEM_DEFAULT")。

请求示例:

GET /profile/me/review-weights
Authorization: Bearer <token>

响应示例(未配置):

{
  "code": 200,
  "message": "success",
  "data": {
    "source": "SYSTEM_DEFAULT",
    "templateCode": "BALANCED",
    "configuredWeights": {
      "AUTHENTICITY": 12.50,
      "BENEFITS": 12.50,
      "SALARY_TRANSPARENCY": 12.50,
      "JD_CLARITY": 12.50,
      "GROWTH": 12.50,
      "TEAM_ATMOSPHERE": 12.50,
      "PROMOTION": 12.50,
      "WORK_LIFE_BALANCE": 12.50
    },
    "updatedAt": null
  }
}

响应示例(已配置模板):

{
  "code": 200,
  "message": "success",
  "data": {
    "source": "TEMPLATE",
    "templateCode": "SALARY_FIRST",
    "configuredWeights": {
      "AUTHENTICITY": 15.00,
      "BENEFITS": 20.00,
      "SALARY_TRANSPARENCY": 30.00,
      "JD_CLARITY": 10.00,
      "GROWTH": 10.00,
      "TEAM_ATMOSPHERE": 5.00,
      "PROMOTION": 5.00,
      "WORK_LIFE_BALANCE": 5.00
    },
    "updatedAt": "2026-08-14T10:00:00"
  }
}

响应示例(自定义配置):

{
  "code": 200,
  "message": "success",
  "data": {
    "source": "CUSTOM",
    "templateCode": null,
    "configuredWeights": {
      "AUTHENTICITY": 15.00,
      "BENEFITS": 15.00,
      "SALARY_TRANSPARENCY": 25.00,
      "JD_CLARITY": 10.00,
      "GROWTH": 10.00,
      "TEAM_ATMOSPHERE": 10.00,
      "PROMOTION": 10.00,
      "WORK_LIFE_BALANCE": 5.00
    },
    "updatedAt": "2026-08-14T10:00:00"
  }
}

3. PUT /profile/me/review-weights

保存当前学生的权重配置。支持模板模式和自定义模式。

请求体(模板模式):

{
  "templateCode": "BALANCED"
}

请求体(自定义模式):

{
  "weights": {
    "AUTHENTICITY": 15.00,
    "BENEFITS": 15.00,
    "SALARY_TRANSPARENCY": 25.00,
    "JD_CLARITY": 10.00,
    "GROWTH": 10.00,
    "TEAM_ATMOSPHERE": 10.00,
    "PROMOTION": 10.00,
    "WORK_LIFE_BALANCE": 5.00
  }
}

请求校验规则:

  1. templateCode 和 weights 必须且只能提供一个
  2. 模板模式:templateCode 必须是 BALANCED、SALARY_FIRST、GROWTH_FIRST、STABILITY_FIRST 之一
  3. 自定义模式:
    • 必须包含全部 8 个维度
    • 每个权重值必须在 [0.00, 100.00] 范围内
    • 每个权重值最多保留两位小数(如 12.345 会被拒绝,返回 400)
    • 8 个权重值总和必须精确等于 100.00
  4. 并发冲突:同一用户并发更新时返回 409(错误码 9106)

错误响应示例:

{
  "code": 1001,
  "message": "bad request",
  "requestId": "xxx",
  "timestamp": "2026-08-14T10:00:00Z"
}
{
  "code": 9106,
  "message": "concurrent weight update conflict",
  "requestId": "xxx",
  "timestamp": "2026-08-14T10:00:00Z"
}

4. GET /jobs/{jobId}/personalized-review-score

基于用户权重配置计算岗位的个性化评分。仅支持 PUBLISHED 状态的岗位。

请求示例:

GET /jobs/1/personalized-review-score
Authorization: Bearer <token>

响应示例(正常计算):

{
  "code": 200,
  "message": "success",
  "data": {
    "jobId": 1,
    "score": 78.50,
    "status": "OK",
    "source": "CUSTOM",
    "templateCode": null,
    "configuredWeights": {
      "AUTHENTICITY": 15.00,
      "BENEFITS": 15.00,
      "SALARY_TRANSPARENCY": 25.00,
      "JD_CLARITY": 10.00,
      "GROWTH": 10.00,
      "TEAM_ATMOSPHERE": 10.00,
      "PROMOTION": 10.00,
      "WORK_LIFE_BALANCE": 5.00
    },
    "effectiveWeights": {
      "AUTHENTICITY": 25.00,
      "BENEFITS": 25.00,
      "SALARY_TRANSPARENCY": 33.33,
      "GROWTH": 16.67
    },
    "dimensionScores": {
      "AUTHENTICITY": 4.20,
      "BENEFITS": 3.80,
      "SALARY_TRANSPARENCY": 4.50,
      "JD_CLARITY": null,
      "GROWTH": 3.00,
      "TEAM_ATMOSPHERE": null,
      "PROMOTION": null,
      "WORK_LIFE_BALANCE": null
    },
    "coveredWeight": 60.00,
    "missingDimensions": ["JD_CLARITY", "TEAM_ATMOSPHERE", "PROMOTION", "WORK_LIFE_BALANCE"]
  }
}

响应示例(数据不足):

{
  "code": 200,
  "message": "success",
  "data": {
    "jobId": 1,
    "score": null,
    "status": "INSUFFICIENT_DATA",
    "source": "SYSTEM_DEFAULT",
    "templateCode": "BALANCED",
    "configuredWeights": { ... },
    "effectiveWeights": {},
    "dimensionScores": {
      "AUTHENTICITY": null,
      "BENEFITS": null,
      "SALARY_TRANSPARENCY": null,
      "JD_CLARITY": null,
      "GROWTH": null,
      "TEAM_ATMOSPHERE": null,
      "PROMOTION": null,
      "WORK_LIFE_BALANCE": null
    },
    "coveredWeight": 0,
    "missingDimensions": ["AUTHENTICITY", "BENEFITS", "SALARY_TRANSPARENCY", "JD_CLARITY", "GROWTH", "TEAM_ATMOSPHERE", "PROMOTION", "WORK_LIFE_BALANCE"]
  }
}

错误响应:

  • 岗位不存在或非 PUBLISHED 状态:404(code=7001)
  • 非 STUDENT 角色:403(code=2002)
  • 未登录:401(code=401)

权重模板

四套预定义模板

BALANCED(均衡权重)

维度 权重
AUTHENTICITY 12.50
BENEFITS 12.50
SALARY_TRANSPARENCY 12.50
JD_CLARITY 12.50
GROWTH 12.50
TEAM_ATMOSPHERE 12.50
PROMOTION 12.50
WORK_LIFE_BALANCE 12.50
合计 100.00

SALARY_FIRST(薪资优先)

维度 权重
AUTHENTICITY 15.00
BENEFITS 20.00
SALARY_TRANSPARENCY 30.00
JD_CLARITY 10.00
GROWTH 10.00
TEAM_ATMOSPHERE 5.00
PROMOTION 5.00
WORK_LIFE_BALANCE 5.00
合计 100.00

GROWTH_FIRST(成长优先)

维度 权重
AUTHENTICITY 10.00
BENEFITS 5.00
SALARY_TRANSPARENCY 5.00
JD_CLARITY 15.00
GROWTH 30.00
TEAM_ATMOSPHERE 10.00
PROMOTION 20.00
WORK_LIFE_BALANCE 5.00
合计 100.00

STABILITY_FIRST(稳定优先)

维度 权重
AUTHENTICITY 10.00
BENEFITS 25.00
SALARY_TRANSPARENCY 15.00
JD_CLARITY 5.00
GROWTH 5.00
TEAM_ATMOSPHERE 5.00
PROMOTION 5.00
WORK_LIFE_BALANCE 30.00
合计 100.00

八维评价维度

维度代码 说明
AUTHENTICITY 信息真实性
BENEFITS 福利待遇
SALARY_TRANSPARENCY 薪资透明度
JD_CLARITY 职位描述清晰度
GROWTH 成长空间
TEAM_ATMOSPHERE 团队氛围
PROMOTION 晋升机制
WORK_LIFE_BALANCE 工作生活平衡

个性化评分计算规则

数据来源

使用专用聚合查询直接从 job_review_dimension_scores 表按 jobId 聚合,只统计状态为 PUBLISHED 且审核状态为 AUTO_APPROVED 或 APPROVED 的评价。不修改原有 /jobs/{id}/reviews/summary 接口的语义。

维度可用性判定

仅当某个维度同时满足以下条件时,该维度才参与计算:

  • sampleCount >= 3
  • averageScore 非空

sampleCount 为 1 或 2 的维度视为缺失维度。

计算步骤

  1. coveredWeight:所有可用维度的 configuredWeight 之和

  2. 若 coveredWeight = 0:

    • score = null
    • status = INSUFFICIENT_DATA
    • effectiveWeights = {}
    • missingDimensions = 完整八维
  3. effectiveWeight(归一化):

    effectiveWeight = configuredWeight / coveredWeight × 100
    

    最后一项 effectiveWeight 用差额修正,确保总和严格等于 100.00

  4. 单维百分制分数:

    dimensionScore100 = averageScore / 5 × 100
    
  5. 最终分数:

    score = Σ(dimensionScore100 × effectiveWeight / 100)
    

精度要求

  • 全程使用 BigDecimal
  • 中间除法 scale=8、HALF_UP
  • 最终 score、coveredWeight、effectiveWeight 保留两位 HALF_UP

并发冲突处理

当同一用户并发更新权重配置时,系统使用乐观锁(@Version)进行控制。

异常类型 错误码 HTTP 状态码
ObjectOptimisticLockingFailureException 9106 409 Conflict
DataIntegrityViolationException(UNIQUE 冲突) 9106 409 Conflict

任何异常发生时,整笔事务回滚,不会留下不完整的权重配置。


接入方式

Apifox 导入

  1. 打开 Apifox,选择"导入数据"
  2. 选择 "OpenAPI/Swagger" 格式
  3. 导入文件:docs/openapi-rc.json
  4. 配置 Base URL:http://localhost:8080

Base URL

  • 本地开发:http://localhost:8080
  • 测试环境:根据实际部署地址配置

不修改的既有接口

本模块不修改以下已有接口:

  • GET /jobs/{id}/reviews/summary — 岗位评价汇总
  • 所有 V1–V22 迁移和已验收接口