# 统计分析接口文档 本文档面向 PC 管理端前端,覆盖业务统计、招聘会统计、求职统计、热门岗位统计和用人单位统计。 ## 1. 通用约定 ### 1.1 基础路径 ```text /cms ``` 以下接口均为后台管理接口,实际请求时需要按项目现有登录机制携带登录态/Token。 ### 1.2 响应包装 接口统一使用项目的 `AjaxResult` 响应包装,前端通常从 `data` 读取业务数据: ```json { "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` 不能颠倒。 示例: ```http GET /cms/statics/business?startDate=2026-01-01&endDate=2026-06-30 ``` ## 2. 业务统计 ### 2.1 接口信息 ```http 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 返回结构 ```json { "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 接口信息 ```http 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` | 示例: ```http 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 返回结构 ```json { "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 接口信息 ```http GET /cms/statics/jobSeeker ``` ### 4.2 统计口径 只统计求职者: ```text 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 返回结构 ```json { "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 接口信息 ```http GET /cms/statics/hotJob ``` ### 5.2 统计口径 热门岗位名称来自业务字典数据表: ```sql bussiness_dict_data.dict_type = 'job_hot' ``` 使用字典项的 `dict_label` 作为热门岗位名称,再按岗位名称前缀匹配 `job.job_title`: ```sql TRIM(job.job_title) LIKE TRIM(dict_label) || '%' ``` 例如字典中配置 `洗碗工`,会匹配: ```text 洗碗工 洗碗工杂工 洗碗工服务员 洗碗工(包吃住) ``` 只统计 `job.del_flag = '0'` 的岗位,并按 `job.create_time` 过滤时间范围。 ### 5.3 返回结构 ```json { "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 前端图表建议 ```javascript const categories = data.items.map(item => item.name) const values = data.items.map(item => item.jobCount) ``` 建议使用柱状图或横向柱状图展示热门岗位数量。 ## 6. 用人单位统计 ### 6.1 接口信息 ```http GET /cms/statics/company ``` ### 6.2 统计内容 接口返回两组统计: - `scale`:按企业规模统计单位数量和发布岗位数量。 - `nature`:按企业性质统计单位数量和发布岗位数量。 单位数量按 `company.create_time` 过滤;发布岗位数量按 `job.create_time` 过滤。这样历史企业在查询时间范围内发布新岗位时,岗位数量仍然可以被统计。 有效单位条件: ```text company.del_flag = '0' company.status = 1 company.company_status = '0' ``` 有效发布岗位条件: ```text 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` 匹配: ```text company.company_nature ``` 如果当前字典中只配置了国企,则 `nature` 只返回国企;如果后续新增规上企业等字典项,接口会自动返回新增分类。 ### 6.5 返回结构 ```json { "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` 各绘制一个双系列柱状图: ```javascript const categories = data.scale.map(item => item.name) const companyData = data.scale.map(item => item.companyCount) const jobData = data.scale.map(item => item.jobCount) ``` 系列名称建议: ```text 单位数量 发布岗位数量 ``` ## 7. 区划企业分析 ### 7.1 接口信息 ```http 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 统计口径 企业统计条件: ```text company.del_flag = '0' company.status = 1 company.company_status = '0' ``` 统计内容: - 单位总数。 - 按行业统计单位数量。 - 按企业规模统计单位数量,名称使用 `scale` 字典翻译。 - 按企业性质统计单位数量,名称使用 `company_nature` 字典翻译。 ### 7.4 返回结构 ```json { "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 为数量。例如: ```javascript const categories = Object.keys(data.byScale) const values = Object.values(data.byScale) ``` ## 8. 区划岗位分析 ### 8.1 接口信息 ```http GET /cms/areaAnalysis/job ``` ### 8.2 请求参数 参数与企业分析相同: | 参数 | 类型 | 必填 | 说明 | |---|---|---:|---| | `areaCode` | string | 否 | `area` 字典的 `dict_value`,不传查询师市整体 | | `startDate` | string | 否 | 格式 `yyyy-MM-dd` | | `endDate` | string | 否 | 格式 `yyyy-MM-dd` | ### 8.3 统计口径 岗位统计条件: ```text job.del_flag = '0' job.is_publish = 1 job.job_status = '0' job.review_status = '1' ``` 统计内容: - 岗位总数。 - 招聘总人数。 - 急招岗位数量。 - 重点人群岗位数量。 - 按岗位分类统计。 - 按薪资区间统计。 - 按学历要求统计。 - 按岗位类型统计。 岗位数量统计使用有效发布岗位。招聘总人数中,岗位 `vacancies` 为空或小于等于 0 时按 1 人计算。 ### 8.4 返回结构 ```json { "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 | 岗位类型名称到岗位数量的映射 | 薪资区间固定为: ```text 3k以下、3k-5k、5k-8k、8k-15k、15k+ ``` ## 9. 区划就业分析 ### 9.1 接口信息 ```http GET /cms/areaAnalysis/employment ``` ### 9.2 请求参数 参数与企业分析、岗位分析相同: | 参数 | 类型 | 必填 | 说明 | |---|---|---:|---| | `areaCode` | string | 否 | `area` 字典的 `dict_value`,不传查询师市整体 | | `startDate` | string | 否 | 格式 `yyyy-MM-dd` | | `endDate` | string | 否 | 格式 `yyyy-MM-dd` | ### 9.3 统计口径 已就业人数统计有效且已录用的求职记录: ```text 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 返回结构 ```json { "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` | 按区域统计已录用和新入职确认数据 |