添加功能

This commit is contained in:
马宝龙
2026-06-26 12:37:58 +08:00
parent 690ce9d49f
commit 4424604b5b
11 changed files with 722 additions and 0 deletions

View File

@@ -75,4 +75,15 @@ public class CommonConstant {
Tuples.of("T", "国际组织")
)));
/**
* 行业列表
*/
public static final List<Tuple2<String, String>> UNIVERSITY_TYPE_LIST =
Collections.unmodifiableList(new ArrayList<>(Arrays.asList(
Tuples.of("1", "一本院校"),
Tuples.of("2", "二本院校"),
Tuples.of("3", "专科院校"),
Tuples.of("4", "民办院校")
)));
}

View File

@@ -41,4 +41,15 @@ public class AnalysisCommonController {
public AjaxResult industryList() {
return AjaxResult.success(analysisCommonService.industryList());
}
/**
* 查询高校类型列表
*
* @return 高校类型列表
*/
@GetMapping("/universityTypeList")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult universityTypeList() {
return AjaxResult.success(analysisCommonService.universityTypeList());
}
}

View File

@@ -0,0 +1,168 @@
package com.ruoyi.cms.controller;
import com.ruoyi.cms.domain.dto.QueryParamDto;
import com.ruoyi.cms.service.AnalysisGraduateEmploymentInfoService;
import com.ruoyi.common.core.domain.AjaxResult;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 高校毕业生就业信息分析
*
* @author 马宝龙
* @date 2026/6/25
*/
@RestController
@RequestMapping("/analysis/graduateEmploymentInfo")
@RequiredArgsConstructor
public class AnalysisGraduateEmploymentInfoController {
private final AnalysisGraduateEmploymentInfoService analysisGraduateEmploymentInfoService;
/**
* 数据总览
*
* @param dto 查询参数
* @return 数据总览
*/
@PostMapping("/overview")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult overview(@RequestBody QueryParamDto dto) {
return AjaxResult.success(analysisGraduateEmploymentInfoService.overview(dto));
}
/**
* 毕业生就业规模与趋势
*
* @param dto 查询参数
* @return 结果列表
*/
@PostMapping("/scaleAndTrend")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult scaleAndTrend(@RequestBody QueryParamDto dto) {
return AjaxResult.success(analysisGraduateEmploymentInfoService.scaleAndTrend(dto));
}
/**
* 学历层次就业分析
*
* @param dto 查询参数
* @return 结果列表
*/
@PostMapping("/educationLevel")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult educationLevel(@RequestBody QueryParamDto dto) {
return AjaxResult.success(analysisGraduateEmploymentInfoService.educationLevel(dto));
}
/**
* 高校类型就业对比
*
* @param dto 查询参数
* @return 结果列表
*/
@PostMapping("/universityType")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult universityType(@RequestBody QueryParamDto dto) {
return AjaxResult.success(analysisGraduateEmploymentInfoService.universityType(dto));
}
/**
* 主要专业就业情况
*
* @param dto 查询参数
* @return 结果列表
*/
@PostMapping("/majorProfessional")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult majorProfessional(@RequestBody QueryParamDto dto) {
return AjaxResult.success(analysisGraduateEmploymentInfoService.majorProfessional(dto));
}
/**
* 性别就业差异分析
*
* @param dto 查询参数
* @return 结果列表
*/
@PostMapping("/gender")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult gender(@RequestBody QueryParamDto dto) {
return AjaxResult.success(analysisGraduateEmploymentInfoService.gender(dto));
}
/**
* 毕业生地区流向分析
*
* @param dto 查询参数
* @return 结果列表
*/
@PostMapping("/areaFlow")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult areaFlow(@RequestBody QueryParamDto dto) {
return AjaxResult.success(analysisGraduateEmploymentInfoService.areaFlow(dto));
}
/**
* 就业行业分布
*
* @param dto 查询参数
* @return 结果列表
*/
@PostMapping("/industryDistribution")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult industryDistribution(@RequestBody QueryParamDto dto) {
return AjaxResult.success(analysisGraduateEmploymentInfoService.industryDistribution(dto));
}
/**
* 薪资水平分析
*
* @param dto 查询参数
* @return 结果列表
*/
@PostMapping("/salaryLevel")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult salaryLevel(@RequestBody QueryParamDto dto) {
return AjaxResult.success(analysisGraduateEmploymentInfoService.salaryLevel(dto));
}
/**
* 就业满意度评估
*
* @param dto 查询参数
* @return 结果列表
*/
@PostMapping("/satisfactionAssessment")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult satisfactionAssessment(@RequestBody QueryParamDto dto) {
return AjaxResult.success(analysisGraduateEmploymentInfoService.satisfactionAssessment(dto));
}
/**
* 毕业生创业情况
*
* @param dto 查询参数
* @return 创业情况
*/
@PostMapping("/startupSituation")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult startupSituation(@RequestBody QueryParamDto dto) {
return AjaxResult.success(analysisGraduateEmploymentInfoService.startupSituation(dto));
}
/**
* 未就业人群分析
*
* @param dto 查询参数
* @return 结果列表
*/
@PostMapping("/notEmploymentCrowd")
// @Log(title = "根据枚举名称查询枚举的所有值", businessType = BusinessType.QUERY)
public AjaxResult notEmploymentCrowd(@RequestBody QueryParamDto dto) {
return AjaxResult.success(analysisGraduateEmploymentInfoService.notEmploymentCrowd(dto));
}
}

View File

@@ -46,6 +46,10 @@ public class QueryParamDto implements Serializable {
* 行业
*/
private String industry;
/**
* 高校类型
*/
private String universityType;
/**
* 开始时间
*/

View File

@@ -0,0 +1,64 @@
package com.ruoyi.cms.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 高校毕业生就业信息分析 - 数据总览
*
* @author 马宝龙
* @date 2026/6/25
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class GraduateEmploymentInfoOverviewVo implements Serializable {
private static final long serialVersionUID = -1318931122984257073L;
/**
* 毕业生总数
*/
private Long graduateCount;
/**
* 毕业生总数环比
*/
private BigDecimal graduateCountMom;
/**
* 就业人数
*/
private Long employmentCount;
/**
* 就业人数环比
*/
private BigDecimal employmentCountMom;
/**
* 就业率
*/
private BigDecimal employmentRate;
/**
* 就业率环比
*/
private BigDecimal employmentRateMom;
/**
* 平均起薪
*/
private BigDecimal averageSalary;
/**
* 平均起薪环比
*/
private BigDecimal averageSalaryMom;
/**
* 升学深造人数
*/
private Long furtherEducationCount;
/**
* 升学深造人数环比
*/
private BigDecimal furtherEducationCountMom;
}

View File

@@ -0,0 +1,40 @@
package com.ruoyi.cms.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 高校毕业生就业信息分析 - 毕业生创业情况
*
* @author 马宝龙
* @date 2026/6/26
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class GraduateEmploymentInfoStartupVo implements Serializable {
private static final long serialVersionUID = 7840585628012934541L;
/**
* 创业总数
*/
private Long startupCount;
/**
* 创业占比
*/
private BigDecimal startupPercentage;
/**
* 创业带动就业岗位数
*/
private Long startupEmploymentJobCount;
/**
* 创业成功率
*/
private BigDecimal startupSuccessRate;
}

View File

@@ -0,0 +1,42 @@
package com.ruoyi.cms.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 高校毕业生就业信息分析 - 毕业生就业规模与趋势
*
* @author 马宝龙
* @date 2026/6/26
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class GraduateEmploymentInfoTreadVo implements Serializable {
private static final long serialVersionUID = 3142204610486677940L;
/**
* 编码
*/
private String code;
/**
* 描述
*/
private String desc;
/**
* 就业人数
*/
private Long employmentCount;
/**
* 未就业人数
*/
private Long notEmploymentCount;
/**
* 升学深造人数
*/
private Long furtherEducationCount;
}

View File

@@ -26,4 +26,11 @@ public interface AnalysisCommonService {
* @return 行业列表
*/
List<DictVo> industryList();
/**
* 查询高校类型列表
*
* @return 高校类型列表
*/
List<DictVo> universityTypeList();
}

View File

@@ -0,0 +1,114 @@
package com.ruoyi.cms.service;
import com.ruoyi.cms.domain.dto.QueryParamDto;
import com.ruoyi.cms.domain.vo.GraduateEmploymentInfoOverviewVo;
import com.ruoyi.cms.domain.vo.GraduateEmploymentInfoStartupVo;
import com.ruoyi.cms.domain.vo.GraduateEmploymentInfoTreadVo;
import com.ruoyi.cms.domain.vo.QueryResultVo;
import java.util.List;
/**
* 高校毕业生就业信息分析
*
* @author 马宝龙
* @date 2026/6/25
*/
public interface AnalysisGraduateEmploymentInfoService {
/**
* 数据总览
*
* @param dto 查询参数
* @return 数据总览
*/
GraduateEmploymentInfoOverviewVo overview(QueryParamDto dto);
/**
* 毕业生就业规模与趋势
*
* @param dto 查询参数
* @return 结果列表
*/
List<GraduateEmploymentInfoTreadVo> scaleAndTrend(QueryParamDto dto);
/**
* 学历层次就业分析
*
* @param dto 查询参数
* @return 结果列表
*/
List<GraduateEmploymentInfoTreadVo> educationLevel(QueryParamDto dto);
/**
* 高校类型就业对比
*
* @param dto 查询参数
* @return 结果列表
*/
List<QueryResultVo> universityType(QueryParamDto dto);
/**
* 主要专业就业情况
*
* @param dto 查询参数
* @return 结果列表
*/
List<QueryResultVo> majorProfessional(QueryParamDto dto);
/**
* 性别就业差异分析
*
* @param dto 查询参数
* @return 结果列表
*/
List<QueryResultVo> gender(QueryParamDto dto);
/**
* 毕业生地区流向分析
*
* @param dto 查询参数
* @return 结果列表
*/
List<QueryResultVo> areaFlow(QueryParamDto dto);
/**
* 就业行业分布
*
* @param dto 查询参数
* @return 结果列表
*/
List<QueryResultVo> industryDistribution(QueryParamDto dto);
/**
* 薪资水平分析
*
* @param dto 查询参数
* @return 结果列表
*/
List<QueryResultVo> salaryLevel(QueryParamDto dto);
/**
* 就业满意度评估
*
* @param dto 查询参数
* @return 结果列表
*/
List<QueryResultVo> satisfactionAssessment(QueryParamDto dto);
/**
* 毕业生创业情况
*
* @param dto 查询参数
* @return 结果列表
*/
GraduateEmploymentInfoStartupVo startupSituation(QueryParamDto dto);
/**
* 未就业人群分析
*
* @param dto 查询参数
* @return 结果列表
*/
List<QueryResultVo> notEmploymentCrowd(QueryParamDto dto);
}

View File

@@ -42,4 +42,14 @@ public class AnalysisCommonServiceImpl implements AnalysisCommonService {
return list;
}
@Override
public List<DictVo> universityTypeList() {
List<DictVo> list = new ArrayList<>();
for (Tuple2<String, String> industry : CommonConstant.UNIVERSITY_TYPE_LIST) {
list.add(DictVo.builder().code(industry.getT1()).desc(industry.getT2()).build());
}
return list;
}
}

View File

@@ -0,0 +1,251 @@
package com.ruoyi.cms.service.impl;
import com.ruoyi.cms.constant.CommonConstant;
import com.ruoyi.cms.domain.dto.QueryParamDto;
import com.ruoyi.cms.domain.vo.GraduateEmploymentInfoOverviewVo;
import com.ruoyi.cms.domain.vo.GraduateEmploymentInfoStartupVo;
import com.ruoyi.cms.domain.vo.GraduateEmploymentInfoTreadVo;
import com.ruoyi.cms.domain.vo.QueryResultVo;
import com.ruoyi.cms.service.AnalysisGraduateEmploymentInfoService;
import com.ruoyi.cms.util.MathUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* 高校毕业生就业信息分析
*
* @author 马宝龙
* @date 2026/6/25
*/
@Service
@Validated
@Slf4j
public class AnalysisGraduateEmploymentInfoServiceImpl implements AnalysisGraduateEmploymentInfoService {
@Override
public GraduateEmploymentInfoOverviewVo overview(QueryParamDto dto) {
return GraduateEmploymentInfoOverviewVo.builder()
.graduateCount(12000L)
.graduateCountMom(BigDecimal.valueOf(5.2))
.employmentCount(10380L)
.employmentCountMom(BigDecimal.valueOf(3.8))
.employmentRate(BigDecimal.valueOf(86.5))
.employmentRateMom(BigDecimal.valueOf(2.1))
.averageSalary(BigDecimal.valueOf(6850.50))
.averageSalaryMom(BigDecimal.valueOf(4.2))
.furtherEducationCount(1850L)
.furtherEducationCountMom(BigDecimal.valueOf(8.6))
.build();
}
@Override
public List<GraduateEmploymentInfoTreadVo> scaleAndTrend(QueryParamDto dto) {
List<GraduateEmploymentInfoTreadVo> list = new ArrayList<>();
for (int i = 0; i < 12; i++) {
list.add(GraduateEmploymentInfoTreadVo.builder()
.code(i + 1 + "")
.desc(i + 1 + "")
.employmentCount((long) Math.floor(Math.random() * 10000) + 1)
.notEmploymentCount((long) Math.floor(Math.random() * 10000) + 1)
.furtherEducationCount((long) Math.floor(Math.random() * 2000) + 1)
.build());
}
return list;
}
@Override
public List<GraduateEmploymentInfoTreadVo> educationLevel(QueryParamDto dto) {
List<GraduateEmploymentInfoTreadVo> list = new ArrayList<>();
List<Tuple2<String, String>> educationLevelList =
Collections.unmodifiableList(new ArrayList<>(Arrays.asList(
Tuples.of("1", "大学专科"),
Tuples.of("2", "大学本科"),
Tuples.of("3", "研究生及以上")
)));
for (Tuple2<String, String> educationLevel : educationLevelList) {
list.add(GraduateEmploymentInfoTreadVo.builder()
.code(educationLevel.getT1())
.desc(educationLevel.getT2())
.employmentCount((long) Math.floor(Math.random() * 10000) + 1)
.notEmploymentCount((long) Math.floor(Math.random() * 10000) + 1)
.furtherEducationCount((long) Math.floor(Math.random() * 2000) + 1)
.build());
}
return list;
}
@Override
public List<QueryResultVo> universityType(QueryParamDto dto) {
List<QueryResultVo> list = new ArrayList<>();
for (Tuple2<String, String> type : CommonConstant.UNIVERSITY_TYPE_LIST) {
list.add(QueryResultVo.builder()
.code(type.getT1())
.desc(type.getT2())
.count((long) Math.floor(Math.random() * 100000) + 1)
.build());
}
return list;
}
@Override
public List<QueryResultVo> majorProfessional(QueryParamDto dto) {
List<QueryResultVo> list = new ArrayList<>();
List<Tuple2<String, String>> majorList =
Collections.unmodifiableList(new ArrayList<>(Arrays.asList(
Tuples.of("1", "计算机科学与技术"),
Tuples.of("2", "软件工程"),
Tuples.of("3", "金融学"),
Tuples.of("4", "临床医学"),
Tuples.of("5", "电子信息工程"),
Tuples.of("6", "机械设计制造及其自动化"),
Tuples.of("7", "土木工程"),
Tuples.of("8", "会计学"),
Tuples.of("9", "工商管理"),
Tuples.of("10", "法学")
)));
for (Tuple2<String, String> major : majorList) {
list.add(QueryResultVo.builder()
.code(major.getT1())
.desc(major.getT2())
.count((long) Math.floor(Math.random() * 100000) + 1)
.build());
}
return list;
}
@Override
public List<QueryResultVo> gender(QueryParamDto dto) {
List<QueryResultVo> list = new ArrayList<>();
List<Tuple2<String, String>> genderList =
Collections.unmodifiableList(new ArrayList<>(Arrays.asList(
Tuples.of("1", ""),
Tuples.of("2", "")
)));
for (Tuple2<String, String> gender : genderList) {
list.add(QueryResultVo.builder()
.code(gender.getT1())
.desc(gender.getT2())
.count((long) Math.floor(Math.random() * 100000) + 1)
.build());
}
MathUtil.calculatePercentage(list);
return list;
}
@Override
public List<QueryResultVo> areaFlow(QueryParamDto dto) {
List<QueryResultVo> list = new ArrayList<>();
List<Tuple2<String, String>> areaList =
Collections.unmodifiableList(new ArrayList<>(Arrays.asList(
Tuples.of("1", "本地"),
Tuples.of("2", "省内"),
Tuples.of("3", "省外")
)));
for (Tuple2<String, String> area : areaList) {
list.add(QueryResultVo.builder()
.code(area.getT1())
.desc(area.getT2())
.count((long) Math.floor(Math.random() * 100000) + 1)
.build());
}
MathUtil.calculatePercentage(list);
return list;
}
@Override
public List<QueryResultVo> industryDistribution(QueryParamDto dto) {
List<QueryResultVo> list = new ArrayList<>();
for (Tuple2<String, String> industry : CommonConstant.INDUSTRY_LIST) {
list.add(QueryResultVo.builder()
.code(industry.getT1())
.desc(industry.getT2())
.count((long) Math.floor(Math.random() * 100000) + 1)
.build());
}
MathUtil.calculatePercentage(list);
return list;
}
@Override
public List<QueryResultVo> salaryLevel(QueryParamDto dto) {
List<QueryResultVo> list = new ArrayList<>();
List<Tuple2<String, String>> salaryList =
Collections.unmodifiableList(new ArrayList<>(Arrays.asList(
Tuples.of("1", "5K以下"),
Tuples.of("2", "5-8K"),
Tuples.of("3", "8-12K"),
Tuples.of("4", "12-15K"),
Tuples.of("5", "15K以上")
)));
for (Tuple2<String, String> salary : salaryList) {
list.add(QueryResultVo.builder()
.code(salary.getT1())
.desc(salary.getT2())
.count((long) Math.floor(Math.random() * 100000) + 1)
.build());
}
return list;
}
@Override
public List<QueryResultVo> satisfactionAssessment(QueryParamDto dto) {
List<QueryResultVo> list = new ArrayList<>();
List<Tuple2<String, String>> satisfactionList =
Collections.unmodifiableList(new ArrayList<>(Arrays.asList(
Tuples.of("1", "工作环境"),
Tuples.of("2", "薪酬福利"),
Tuples.of("3", "发展前景"),
Tuples.of("4", "综合满意度")
)));
for (Tuple2<String, String> satisfaction : satisfactionList) {
list.add(QueryResultVo.builder()
.code(satisfaction.getT1())
.desc(satisfaction.getT2())
.amount(new BigDecimal(Math.random() * 100 + 1).setScale(2, RoundingMode.HALF_UP))
.build());
}
return list;
}
@Override
public GraduateEmploymentInfoStartupVo startupSituation(QueryParamDto dto) {
return GraduateEmploymentInfoStartupVo.builder()
.startupCount(156L)
.startupPercentage(BigDecimal.valueOf(10.3))
.startupEmploymentJobCount(890L)
.startupSuccessRate(BigDecimal.valueOf(72.5))
.build();
}
@Override
public List<QueryResultVo> notEmploymentCrowd(QueryParamDto dto) {
List<QueryResultVo> list = new ArrayList<>();
List<Tuple2<String, String>> crowdList =
Collections.unmodifiableList(new ArrayList<>(Arrays.asList(
Tuples.of("1", "继续求职"),
Tuples.of("2", "备考公招/考研"),
Tuples.of("3", "其他")
)));
for (Tuple2<String, String> crowd : crowdList) {
list.add(QueryResultVo.builder()
.code(crowd.getT1())
.desc(crowd.getT2())
.count((long) Math.floor(Math.random() * 100000) + 1)
.build());
}
MathUtil.calculatePercentage(list);
return list;
}
}