Files
shz-backend/docs/cms-statistics-api.md

19 KiB
Raw Blame History

统计分析接口文档

本文档面向 PC 管理端前端,覆盖业务统计、招聘会统计、求职统计、热门岗位统计和用人单位统计。

1. 通用约定

1.1 基础路径

/cms

以下接口均为后台管理接口,实际请求时需要按项目现有登录机制携带登录态/Token。

1.2 响应包装

接口统一使用项目的 AjaxResult 响应包装,前端通常从 data 读取业务数据:

{
  "code": 200,
  "msg": "操作成功",
  "data": {}
}

1.3 统计时间参数

/cms/statics/* 统计接口使用以下参数:

参数 类型 必填 说明
startDate string 开始日期,支持 yyyy-MM-ddyyyy-MM
endDate string 结束日期,支持 yyyy-MM-ddyyyy-MM
startTime string startDate 的兼容参数名
endTime string endDate 的兼容参数名

时间规则:

  • 不传开始时间时,默认从当前年度 1 月 1 日 开始。
  • 不传结束时间时,默认到当前日期结束。
  • 传入 yyyy-MM 时,开始月份按当月 1 日处理,结束月份按当月最后一天处理。
  • 查询时间采用左闭右开区间,结束日期当天的数据会被包含。
  • startDateendDate 不能颠倒。

示例:

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 来源编码:512
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 dayweekmonthquarteryear,默认 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 匹配到的岗位数量

字典中已经配置但时间范围内没有匹配岗位的热门岗位也会返回,jobCount0,便于图表保持固定分类顺序。

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 超大型

例如 45 的企业都会汇总到 大型,对应的 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 前端图表建议

可以按 scalenature 各绘制一个双系列柱状图:

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 按区域统计已录用和新入职确认数据