19 KiB
统计分析接口文档
本文档面向 PC 管理端前端,覆盖业务统计、招聘会统计、求职统计、热门岗位统计和用人单位统计。
1. 通用约定
1.1 基础路径
/cms
以下接口均为后台管理接口,实际请求时需要按项目现有登录机制携带登录态/Token。
1.2 响应包装
接口统一使用项目的 AjaxResult 响应包装,前端通常从 data 读取业务数据:
{
"code": 200,
"msg": "操作成功",
"data": {}
}
1.3 统计时间参数
/cms/statics/* 统计接口使用以下参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
startDate |
string | 否 | 开始日期,支持 yyyy-MM-dd 或 yyyy-MM |
endDate |
string | 否 | 结束日期,支持 yyyy-MM-dd 或 yyyy-MM |
startTime |
string | 否 | startDate 的兼容参数名 |
endTime |
string | 否 | endDate 的兼容参数名 |
时间规则:
- 不传开始时间时,默认从当前年度
1 月 1 日开始。 - 不传结束时间时,默认到当前日期结束。
- 传入
yyyy-MM时,开始月份按当月 1 日处理,结束月份按当月最后一天处理。 - 查询时间采用左闭右开区间,结束日期当天的数据会被包含。
startDate和endDate不能颠倒。
示例:
GET /cms/statics/business?startDate=2026-01-01&endDate=2026-06-30
2. 业务统计
2.1 接口信息
GET /cms/statics/business
2.2 统计口径
返回按月统计的数据:
- 岗位来源:从
job表统计data_source。 - 本地石河子模板导入:
data_source = '5'。 - 本地录入:
data_source = '1'。 - 互联网岗位上传:
data_source = '2'。 - 新增注册人数:从
app_user表按create_time统计。
岗位和用户均只统计 del_flag = '0' 的数据。
2.3 返回结构
{
"months": [
"2026-01",
"2026-02",
"2026-03"
],
"jobSourceSeries": [
{
"code": "5",
"name": "本地石河子模板导入",
"data": [12, 18, 21]
},
{
"code": "1",
"name": "本地录入",
"data": [8, 10, 13]
},
{
"code": "2",
"name": "互联网岗位上传",
"data": [35, 42, 50]
}
],
"newRegisterSeries": {
"code": "register",
"name": "新增注册人数",
"data": [20, 31, 46]
}
}
2.4 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
months |
string[] | 横坐标月份,格式为 yyyy-MM |
jobSourceSeries |
object[] | 三种岗位来源序列 |
jobSourceSeries[].code |
string | 来源编码:5、1、2 |
jobSourceSeries[].name |
string | 来源名称 |
jobSourceSeries[].data |
number[] | 与 months 按下标一一对应 |
newRegisterSeries |
object | 新增注册人数序列 |
newRegisterSeries.data |
number[] | 与 months 按下标一一对应 |
2.5 前端图表建议
- 折线图或柱状图横轴使用
months。 jobSourceSeries可以绘制三条岗位来源曲线。newRegisterSeries单独绘制新增注册人数曲线,或作为第二个图表的数据源。
3. 招聘会统计
3.1 接口信息
GET /cms/outdoor-fair/statistics
3.2 请求参数
| 参数 | 类型 | 必填 | 可选值/说明 |
|---|---|---|---|
granularity |
string | 否 | day、week、month、quarter、year,默认 month |
startTime |
string | 否 | 格式为 yyyy-MM-dd HH:mm:ss |
endTime |
string | 否 | 格式为 yyyy-MM-dd HH:mm:ss |
示例:
GET /cms/outdoor-fair/statistics?granularity=quarter&startTime=2026-01-01%2000:00:00&endTime=2026-12-31%2023:59:59
3.3 时间规则
granularity=day:按天统计。granularity=week:按周一作为一周开始统计。granularity=month:按月统计,默认值。granularity=quarter:按季度统计,Q1 为 1-3 月,Q2 为 4-6 月,Q3 为 7-9 月,Q4 为 10-12 月。granularity=year:按年统计。- 不传任何时间参数时,累计统计全部招聘会,曲线时间范围根据招聘会实际举办时间的最小值和最大值生成。
- 只传
endTime时,默认向前推 12 个月作为开始范围。 - 只传
startTime时,结束时间默认为当前日期。
3.4 返回结构
{
"granularity": "quarter",
"totals": {
"fairCount": 12,
"companyCount": 86,
"jobCount": 430
},
"yoy": {
"fairCount": 12,
"previousFairCount": 9,
"rate": 0.3333333333
},
"mom": {
"fairCount": 12,
"previousFairCount": 10,
"rate": 0.2
},
"series": [
{
"time": "2026-Q1",
"fairCount": 3,
"companyCount": 20,
"jobCount": 105
},
{
"time": "2026-Q2",
"fairCount": 4,
"companyCount": 28,
"jobCount": 140
}
]
}
3.5 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
granularity |
string | 实际使用的统计粒度 |
totals.fairCount |
number | 区间内招聘会数量 |
totals.companyCount |
number | 区间内参会单位数量 |
totals.jobCount |
number | 区间内招聘会岗位数量 |
yoy.fairCount |
number | 当前区间招聘会数量 |
yoy.previousFairCount |
number | 去年同期招聘会数量 |
yoy.rate |
number/null | 同比变化率,前值为 0 时返回 null |
mom.fairCount |
number | 当前区间招聘会数量 |
mom.previousFairCount |
number | 上一个等长区间招聘会数量 |
mom.rate |
number/null | 环比变化率,前值为 0 时返回 null |
series |
object[] | 各时间桶的曲线数据 |
series[].time |
string | 时间桶名称 |
series[].fairCount |
number | 当前时间桶招聘会数量 |
series[].companyCount |
number | 当前时间桶参会单位数量 |
series[].jobCount |
number | 当前时间桶岗位数量 |
时间桶格式:
| 粒度 | series[].time 格式 |
示例 |
|---|---|---|
day |
yyyy-MM-dd |
2026-07-30 |
week |
yyyy-Www |
2026-W31 |
month |
yyyy-MM |
2026-07 |
quarter |
yyyy-Qn |
2026-Q3 |
year |
yyyy |
2026 |
同比、环比的 rate 是小数,不是百分数字符串。前端展示百分比时可乘以 100 后保留两位小数,例如 0.3333 展示为 33.33%。
4. 求职统计
4.1 接口信息
GET /cms/statics/jobSeeker
4.2 统计口径
只统计求职者:
app_user.is_company_user = '1'
时间按 app_user.create_time 过滤。
统计维度:
- 年龄:
app_user.age,使用dict_type='age'字典翻译名称。 - 工作经验:
app_user.work_experience,使用dict_type='experience'字典翻译名称。 - 专业/求职方向:解析
app_user.job_title_id,关联job_title获取岗位名称。
4.3 返回结构
{
"total": 156,
"age": [
{
"code": "18-25",
"label": "18-25岁",
"count": 58
},
{
"code": "26-35",
"label": "26-35岁",
"count": 72
}
],
"workExperience": [
{
"code": "0",
"label": "无经验",
"count": 40
},
{
"code": "1-3",
"label": "1-3年",
"count": 63
}
],
"profession": [
{
"code": "101",
"label": "行政管理",
"count": 25
},
{
"code": "102",
"label": "销售",
"count": 31
}
]
}
4.4 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
total |
number | 时间范围内求职者总数 |
age |
object[] | 年龄分组统计 |
workExperience |
object[] | 工作经验分组统计 |
profession |
object[] | 专业/期望岗位统计 |
*.code |
string | 字典值或岗位 ID |
*.label |
string | 前端显示名称 |
*.count |
number | 该分组人数 |
求职者选择多个期望岗位时,会分别计入多个专业/求职方向分组;因此 profession 各项之和可能大于 total。
4.5 前端图表建议
age使用饼图或柱状图。workExperience使用饼图或柱状图。profession使用横向柱状图,岗位较多时建议按数量倒序显示 Top N。
5. 热门岗位统计
5.1 接口信息
GET /cms/statics/hotJob
5.2 统计口径
热门岗位名称来自业务字典数据表:
bussiness_dict_data.dict_type = 'job_hot'
使用字典项的 dict_label 作为热门岗位名称,再按岗位名称前缀匹配 job.job_title:
TRIM(job.job_title) LIKE TRIM(dict_label) || '%'
例如字典中配置 洗碗工,会匹配:
洗碗工
洗碗工杂工
洗碗工服务员
洗碗工(包吃住)
只统计 job.del_flag = '0' 的岗位,并按 job.create_time 过滤时间范围。
5.3 返回结构
{
"items": [
{
"code": "wash_worker",
"name": "洗碗工",
"jobCount": 8
},
{
"code": "sales",
"name": "销售",
"jobCount": 32
}
]
}
5.4 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
items |
object[] | 热门岗位统计列表 |
items[].code |
string | 字典 dict_value |
items[].name |
string | 字典 dict_label,前端图表显示名称 |
items[].jobCount |
number | 匹配到的岗位数量 |
字典中已经配置但时间范围内没有匹配岗位的热门岗位也会返回,jobCount 为 0,便于图表保持固定分类顺序。
5.5 前端图表建议
const categories = data.items.map(item => item.name)
const values = data.items.map(item => item.jobCount)
建议使用柱状图或横向柱状图展示热门岗位数量。
6. 用人单位统计
6.1 接口信息
GET /cms/statics/company
6.2 统计内容
接口返回两组统计:
scale:按企业规模统计单位数量和发布岗位数量。nature:按企业性质统计单位数量和发布岗位数量。
单位数量按 company.create_time 过滤;发布岗位数量按 job.create_time 过滤。这样历史企业在查询时间范围内发布新岗位时,岗位数量仍然可以被统计。
有效单位条件:
company.del_flag = '0'
company.status = 1
company.company_status = '0'
有效发布岗位条件:
job.del_flag = '0'
job.is_publish = 1
job.job_status = '0'
job.review_status = '1'
6.3 企业规模分类
从 dict_type='scale' 的字典值读取企业规模,并按以下规则归并:
| 字典值 | 返回编码 | 返回名称 |
|---|---|---|
1 |
1 |
微型 |
2 |
2 |
小型 |
3 |
3 |
中型 |
4、5 |
4_5 |
大型 |
6、7 |
6_7 |
超大型 |
例如 4 和 5 的企业都会汇总到 大型,对应的 jobCount 也会合并统计。
6.4 企业性质分类
从 dict_type='company_nature' 且状态正常的字典数据读取企业性质,并使用字典 dict_value 匹配:
company.company_nature
如果当前字典中只配置了国企,则 nature 只返回国企;如果后续新增规上企业等字典项,接口会自动返回新增分类。
6.5 返回结构
{
"scale": [
{
"code": "1",
"name": "微型",
"companyCount": 3,
"jobCount": 5
},
{
"code": "2",
"name": "小型",
"companyCount": 20,
"jobCount": 46
},
{
"code": "3",
"name": "中型",
"companyCount": 8,
"jobCount": 31
},
{
"code": "4_5",
"name": "大型",
"companyCount": 4,
"jobCount": 22
},
{
"code": "6_7",
"name": "超大型",
"companyCount": 1,
"jobCount": 12
}
],
"nature": [
{
"code": "1",
"name": "国企",
"companyCount": 5,
"jobCount": 18
}
]
}
6.6 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
scale |
object[] | 企业规模统计列表 |
nature |
object[] | 企业性质统计列表 |
*.code |
string | 统计分类编码 |
*.name |
string | 前端显示名称 |
*.companyCount |
number | 该分类下单位数量 |
*.jobCount |
number | 该分类下有效发布岗位数量 |
6.7 前端图表建议
可以按 scale 和 nature 各绘制一个双系列柱状图:
const categories = data.scale.map(item => item.name)
const companyData = data.scale.map(item => item.companyCount)
const jobData = data.scale.map(item => item.jobCount)
系列名称建议:
单位数量
发布岗位数量
7. 区划企业分析
7.1 接口信息
GET /cms/areaAnalysis/company
7.2 请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
areaCode |
string | 否 | 区划字典值,不传时查询师市整体 |
startDate |
string | 否 | 开始日期,格式 yyyy-MM-dd |
endDate |
string | 否 | 结束日期,格式 yyyy-MM-dd |
areaCode 使用业务字典 dict_type='area' 的 dict_value,前端不需要直接传 sys_area.code。例如区划选择器应使用区域字典接口返回的 dict_value 作为请求参数。
7.3 统计口径
企业统计条件:
company.del_flag = '0'
company.status = 1
company.company_status = '0'
统计内容:
- 单位总数。
- 按行业统计单位数量。
- 按企业规模统计单位数量,名称使用
scale字典翻译。 - 按企业性质统计单位数量,名称使用
company_nature字典翻译。
7.4 返回结构
{
"areaCode": "659001000000",
"areaName": "石河子市",
"totalCompanyCount": 120,
"byIndustry": {
"制造业": 35,
"批发和零售业": 28
},
"byScale": {
"小型": 60,
"中型": 42,
"大型": 18
},
"byNature": {
"国企": 12
}
}
7.5 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
areaCode |
string | 实际统计区域编码 |
areaName |
string | 实际统计区域名称 |
totalCompanyCount |
number | 有效单位总数 |
byIndustry |
object | 行业名称到单位数量的映射 |
byScale |
object | 企业规模名称到单位数量的映射 |
byNature |
object | 企业性质名称到单位数量的映射 |
对象类型字段的 key 为图表显示名称,value 为数量。例如:
const categories = Object.keys(data.byScale)
const values = Object.values(data.byScale)
8. 区划岗位分析
8.1 接口信息
GET /cms/areaAnalysis/job
8.2 请求参数
参数与企业分析相同:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
areaCode |
string | 否 | area 字典的 dict_value,不传查询师市整体 |
startDate |
string | 否 | 格式 yyyy-MM-dd |
endDate |
string | 否 | 格式 yyyy-MM-dd |
8.3 统计口径
岗位统计条件:
job.del_flag = '0'
job.is_publish = 1
job.job_status = '0'
job.review_status = '1'
统计内容:
- 岗位总数。
- 招聘总人数。
- 急招岗位数量。
- 重点人群岗位数量。
- 按岗位分类统计。
- 按薪资区间统计。
- 按学历要求统计。
- 按岗位类型统计。
岗位数量统计使用有效发布岗位。招聘总人数中,岗位 vacancies 为空或小于等于 0 时按 1 人计算。
8.4 返回结构
{
"areaCode": "659001000000",
"areaName": "石河子市",
"totalJobCount": 360,
"totalVacancies": 780,
"urgentJobCount": 48,
"keyPopulationJobCount": 22,
"byCategory": {
"销售": 80,
"餐饮服务": 55
},
"bySalary": {
"3k以下": 30,
"3k-5k": 120,
"5k-8k": 150,
"8k-15k": 48,
"15k+": 12
},
"byEducation": {
"不限": 180,
"大专": 110,
"本科": 70
},
"byType": {
"全职": 300,
"兼职": 60
}
}
8.5 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
areaCode |
string | 实际统计区域编码 |
areaName |
string | 实际统计区域名称 |
totalJobCount |
number | 有效发布岗位总数 |
totalVacancies |
number | 招聘总人数,空值/非正数岗位按 1 人计算 |
urgentJobCount |
number | is_urgent = 1 的岗位数量 |
keyPopulationJobCount |
number | is_key_populations = '0' 的岗位数量 |
byCategory |
object | 岗位分类到岗位数量的映射 |
bySalary |
object | 薪资区间到岗位数量的映射 |
byEducation |
object | 学历名称到岗位数量的映射 |
byType |
object | 岗位类型名称到岗位数量的映射 |
薪资区间固定为:
3k以下、3k-5k、5k-8k、8k-15k、15k+
9. 区划就业分析
9.1 接口信息
GET /cms/areaAnalysis/employment
9.2 请求参数
参数与企业分析、岗位分析相同:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
areaCode |
string | 否 | area 字典的 dict_value,不传查询师市整体 |
startDate |
string | 否 | 格式 yyyy-MM-dd |
endDate |
string | 否 | 格式 yyyy-MM-dd |
9.3 统计口径
已就业人数统计有效且已录用的求职记录:
job_apply.del_flag = '0'
job_apply.hire = '0'
app_user.del_flag = '0'
app_user.is_company_user = '1'
app_user.status = '0'
就业区域根据求职者 app_user.area 进行统计。
录用来源映射:
hire_source |
返回名称 |
|---|---|
0 |
本系统 |
1 |
招聘会 |
| 其他值 | 其他 |
新入职确认人数来自 employee_confirm 表的有效确认记录。
9.4 返回结构
{
"areaCode": "659001000000",
"areaName": "石河子市",
"totalHired": 86,
"byHireSource": {
"本系统": 52,
"招聘会": 26,
"其他": 8
},
"newEmployeeConfirmed": 31
}
9.5 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
areaCode |
string | 实际统计区域编码 |
areaName |
string | 实际统计区域名称 |
totalHired |
number | 有效已录用人数 |
byHireSource |
object | 录用来源名称到人数的映射 |
newEmployeeConfirmed |
number | 新入职确认人数 |
10. 接口汇总
| 统计模块 | 请求地址 | 主要用途 |
|---|---|---|
| 业务统计 | GET /cms/statics/business |
按月统计岗位来源和新增注册人数 |
| 招聘会统计 | GET /cms/outdoor-fair/statistics |
按日/周/月/季度/年度统计招聘会 |
| 求职统计 | GET /cms/statics/jobSeeker |
统计求职者年龄、工作经验、专业 |
| 热门岗位统计 | GET /cms/statics/hotJob |
统计 job_hot 字典配置的热门岗位数量 |
| 用人单位统计 | GET /cms/statics/company |
统计单位规模/性质及其发布岗位数量 |
| 区划企业分析 | GET /cms/areaAnalysis/company |
按区域统计企业总数、行业、规模、性质 |
| 区划岗位分析 | GET /cms/areaAnalysis/job |
按区域统计岗位、招聘人数、薪资、学历等 |
| 区划就业分析 | GET /cms/areaAnalysis/employment |
按区域统计已录用和新入职确认数据 |