From be6a7b83946b383202782c708db94c5f39298f95 Mon Sep 17 00:00:00 2001
From: lapuda <577732344@qq.com>
Date: Thu, 23 Jul 2026 18:13:30 +0800
Subject: [PATCH] feat: add recruitment fair statistics API
---
...recruitment-fair-statistics-proposals.html | 473 ++++++++++++++++++
.../cms/FairStatisticsController.java | 148 ++++++
.../cms/domain/vo/FairStatisticsFairItem.java | 100 ++++
.../cms/mapper/FairStatisticsMapper.java | 23 +
.../mapper/app/FairStatisticsMapper.xml | 147 ++++++
.../cms/FairStatisticsControllerTest.java | 116 +++++
6 files changed, 1007 insertions(+)
create mode 100644 docs/recruitment-fair-statistics-proposals.html
create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/FairStatisticsController.java
create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/vo/FairStatisticsFairItem.java
create mode 100644 ruoyi-bussiness/src/main/java/com/ruoyi/cms/mapper/FairStatisticsMapper.java
create mode 100644 ruoyi-bussiness/src/main/resources/mapper/app/FairStatisticsMapper.xml
create mode 100644 ruoyi-bussiness/src/test/java/com/ruoyi/cms/controller/cms/FairStatisticsControllerTest.java
diff --git a/docs/recruitment-fair-statistics-proposals.html b/docs/recruitment-fair-statistics-proposals.html
new file mode 100644
index 0000000..3f7b2b7
--- /dev/null
+++ b/docs/recruitment-fair-statistics-proposals.html
@@ -0,0 +1,473 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
招聘会数据统计
+
+
+
+
+
+
+ 统计范围
+ 单场招聘会 ⌄
+ 2026 年春风行动线上招聘会 ⌄
+ 查询
+
+
也可切换为 按起始时间统计,选择起始日期与结束日期后汇总多场招聘会。
+
+
+ - 参会单位数
- 128家
+ - 职位数
- 356个
+ - 需求人数
- 1,024人
+ - 投递岗位数
- 687个
+ - 签到数
- 932人次
+
+
+
+
+
+
2026 年春风行动户外线上招聘会128 家 / 356 职位
+
起始时间2026-03-07
+
投递最热岗位行政专员 · 54 次
+
签到高峰时段10:00–11:00 · 328 人次
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
招聘会名称 ⌄
+
统计方式
+
统计单场按起始时间段
+
2026-03-01 至 2026-03-31
+
+
+
+ - 参会单位
- 128家
+ - 职位数
- 356个
+ - 需求人数
- 1,024人
+ - 投递岗位
- 687个
+ - 签到数
- 932人次
+
+
+
+
+
+
+
+ 03/0103/0703/1403/2103/31
+
+
+
+
+
1春风行动专场154 次投递246 人签到
+
2民营企业专场122 次投递211 人签到
+
+
+
+
+
+
+
+
+
+
+
+
+
+
招聘会数据统计
+
+
+
+
+
+
+ 统计单场 ⌄
+ 选择招聘会 ⌄
+
+
+ 当前统计范围2026 年春风行动线上户外招聘会
+ 起始 2026-03-07
+
+
+
+ - 参会单位数
- 128家
+ - 职位数
- 356个
+ - 需求人数
- 1,024人
+ - 投递岗位数
- 687个
+ - 签到数
- 932人次
+
+
+
i本场招聘会共有 356 个岗位获得投递,其中 687 个岗位投递记录已去重汇总。
+
i户外招聘会不提供报名投递简历,现场到场数据以签到记录累计为准。
+
+ 统计说明自动汇总
+
+
单位与职位按有效参会单位及岗位统计
+
需求人数“若干”按 1 人计算
+
投递岗位数按投递岗位汇总
+
签到数按现场签到累计
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/FairStatisticsController.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/FairStatisticsController.java
new file mode 100644
index 0000000..fd11e0e
--- /dev/null
+++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/cms/FairStatisticsController.java
@@ -0,0 +1,148 @@
+package com.ruoyi.cms.controller.cms;
+
+import com.ruoyi.cms.domain.vo.FairStatisticsFairItem;
+import com.ruoyi.cms.mapper.FairStatisticsMapper;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.utils.StringUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 后台招聘会数据统计。
+ */
+@RestController
+@RequestMapping("/cms/fair-statistics")
+@Api(tags = "后台:招聘会数据统计")
+public class FairStatisticsController extends BaseController
+{
+ private static final String ONLINE = "online";
+
+ private static final String OUTDOOR = "outdoor";
+
+ @Autowired
+ private FairStatisticsMapper fairStatisticsMapper;
+
+ /**
+ * 按单场招聘会或按招聘会起始时间范围统计。
+ *
+ * @param fairType 招聘会类型:online(线上)或 outdoor(户外)
+ * @param fairId 单场招聘会 ID;传该参数时不接受时间范围
+ * @param startDate 按时间统计的起始日期(含当天)
+ * @param endDate 按时间统计的结束日期(含当天)
+ */
+ @ApiOperation("招聘会数据汇总统计")
+ @PreAuthorize("@ss.hasAnyPermi('cms:publicJobFair:list,cms:outdoorFair:list')")
+ @GetMapping("/summary")
+ public AjaxResult summary(@RequestParam String fairType,
+ @RequestParam(required = false) String fairId,
+ @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
+ @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate)
+ {
+ String normalizedType = fairType == null ? "" : fairType.trim().toLowerCase();
+ if (!ONLINE.equals(normalizedType) && !OUTDOOR.equals(normalizedType))
+ {
+ return AjaxResult.error("招聘会类型仅支持线上招聘会或户外招聘会");
+ }
+
+ boolean hasFairId = StringUtils.isNotEmpty(fairId);
+ boolean hasStartDate = startDate != null;
+ boolean hasEndDate = endDate != null;
+ if (hasFairId && (hasStartDate || hasEndDate))
+ {
+ return AjaxResult.error("单场统计与时间范围统计不能同时使用");
+ }
+ if (!hasFairId && (!hasStartDate || !hasEndDate))
+ {
+ return AjaxResult.error("请选择一场招聘会,或完整选择起始日期和结束日期");
+ }
+
+ Date rangeStart = null;
+ Date rangeEnd = null;
+ if (!hasFairId)
+ {
+ LocalDate start = toLocalDate(startDate);
+ LocalDate end = toLocalDate(endDate);
+ if (end.isBefore(start))
+ {
+ return AjaxResult.error("结束日期不能早于起始日期");
+ }
+ rangeStart = toStartOfDay(start);
+ // SQL 使用左闭右开区间,确保结束日期当天的招聘会被计入。
+ rangeEnd = toStartOfDay(end.plusDays(1));
+ }
+
+ List