添加功能

This commit is contained in:
马宝龙
2026-07-02 23:55:30 +08:00
parent 648ccc9c77
commit b68322620b
20 changed files with 961 additions and 14 deletions

View File

@@ -1,6 +1,7 @@
package com.ruoyi.cms.controller;
import com.ruoyi.cms.domain.ModelEmploymentMonitorComposite;
import com.ruoyi.cms.domain.vo.ModelEmploymentMonitorCompositeResultVo;
import com.ruoyi.cms.service.ModelEmploymentMonitorCompositeService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
@@ -90,7 +91,21 @@ public class ModelEmploymentMonitorCompositeController extends BaseController {
@ResponseBody
public TableDataInfo page(@RequestBody ModelEmploymentMonitorComposite modelEmploymentMonitorComposite) {
startPage();
List<ModelEmploymentMonitorComposite> list = modelEmploymentMonitorCompositeService.list(modelEmploymentMonitorComposite);
List<ModelEmploymentMonitorComposite> list =
modelEmploymentMonitorCompositeService.list(modelEmploymentMonitorComposite);
return getDataTable(list);
}
/**
* 监测结果
*
* @param regionCode 区域编码
* @return 监测结果
*/
@GetMapping("monitorResult")
public AjaxResult monitorResult(@RequestParam String regionCode) {
ModelEmploymentMonitorCompositeResultVo result =
modelEmploymentMonitorCompositeService.monitorResult(regionCode);
return AjaxResult.success(result);
}
}

View File

@@ -1,6 +1,7 @@
package com.ruoyi.cms.controller;
import com.ruoyi.cms.domain.ModelUnemploymentRateMonitor;
import com.ruoyi.cms.domain.vo.ModelUnemploymentRateResultVo;
import com.ruoyi.cms.service.ModelUnemploymentRateMonitorService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
@@ -90,7 +91,21 @@ public class ModelUnemploymentRateMonitorController extends BaseController {
@ResponseBody
public TableDataInfo page(@RequestBody ModelUnemploymentRateMonitor modelUnemploymentRateMonitor) {
startPage();
List<ModelUnemploymentRateMonitor> list = modelUnemploymentRateMonitorService.list(modelUnemploymentRateMonitor);
List<ModelUnemploymentRateMonitor> list =
modelUnemploymentRateMonitorService.list(modelUnemploymentRateMonitor);
return getDataTable(list);
}
/**
* 监测结果
*
* @param regionCode 区域编码
* @return 监测结果
*/
@GetMapping("monitorResult")
public AjaxResult monitorResult(@RequestParam String regionCode) {
ModelUnemploymentRateResultVo result = modelUnemploymentRateMonitorService.monitorResult(regionCode);
return AjaxResult.success(result);
}
}

View File

@@ -1,6 +1,7 @@
package com.ruoyi.cms.controller;
import com.ruoyi.cms.domain.ModelUnemploymentWarningDiffusion;
import com.ruoyi.cms.domain.vo.ModelUnemploymentWarningDiffusionResultVo;
import com.ruoyi.cms.service.ModelUnemploymentWarningDiffusionService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
@@ -90,7 +91,21 @@ public class ModelUnemploymentWarningDiffusionController extends BaseController
@ResponseBody
public TableDataInfo page(@RequestBody ModelUnemploymentWarningDiffusion modelUnemploymentWarningDiffusion) {
startPage();
List<ModelUnemploymentWarningDiffusion> list = modelUnemploymentWarningDiffusionService.list(modelUnemploymentWarningDiffusion);
List<ModelUnemploymentWarningDiffusion> list =
modelUnemploymentWarningDiffusionService.list(modelUnemploymentWarningDiffusion);
return getDataTable(list);
}
/**
* 监测结果
*
* @param regionCode 区域编码
* @return 监测结果
*/
@GetMapping("monitorResult")
public AjaxResult monitorResult(@RequestParam String regionCode) {
ModelUnemploymentWarningDiffusionResultVo result =
modelUnemploymentWarningDiffusionService.monitorResult(regionCode);
return AjaxResult.success(result);
}
}

View File

@@ -31,6 +31,10 @@ public class ModelWarningIndicatorData implements Serializable {
*/
@Excel(name = "指标编码")
private String indicatorCode;
/**
* 指标名称
*/
private String indicatorName;
/**
* 指标值
*/

View File

@@ -0,0 +1,71 @@
package com.ruoyi.cms.domain.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 就业失业预警指标数据结果
*
* @author 马宝龙
* @date 2026/7/1
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ModelWarningIndicatorDataResultDto implements Serializable {
private static final long serialVersionUID = 5484203921728117105L;
/**
* ID
*/
private Long id;
/**
* 指标编码
*/
private String indicatorCode;
/**
* 指标名称
*/
private String indicatorName;
/**
* 指标权重
*/
private BigDecimal indicatorWeight;
/**
* 指标类型
*/
private Integer indicatorType;
/**
* 提前期数
*/
private Integer leadPeriod;
/**
* 指标值
*/
private BigDecimal dataValue;
/**
* 年份
*/
private Integer year;
/**
* 月份
*/
private Integer month;
/**
* 区域编码
*/
private String regionCode;
/**
* 区域名称
*/
private String regionName;
/**
* 备注
*/
private String remark;
}

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;
import java.math.BigDecimal;
import java.util.List;
/**
* 就业监测综合指数管理
*
* @author 马宝龙
* @date 2026/7/2
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ModelEmploymentMonitorCompositeResultVo implements Serializable {
private static final long serialVersionUID = 6095346205199667758L;
/**
* 当期指标值
*/
private BigDecimal currentValue;
/**
* 时间列表
*/
private List<String> timeList;
/**
* 就失业监测综合指数
*/
private List<BigDecimal> compositeValueList;
/**
* 指标列表
*/
private List<ModelResultIndicatorDataVo> indicatorList;
}

View File

@@ -0,0 +1,32 @@
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/7/2
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ModelResultDataVo implements Serializable {
private static final long serialVersionUID = 8318496173201831100L;
/**
* 时间
*/
private String time;
/**
* 指标值
*/
private BigDecimal value;
}

View File

@@ -0,0 +1,57 @@
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;
import java.util.List;
/**
* 就业监测综合指数管理数据
*
* @author 马宝龙
* @date 2026/7/2
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ModelResultIndicatorDataVo implements Serializable {
private static final long serialVersionUID = 7793411503083320622L;
/**
* 指标名称
*/
private String indicatorName;
/**
* 指标编码
*/
private String indicatorCode;
/**
* 最大值
*/
private BigDecimal maxValue;
/**
* 最小值
*/
private BigDecimal minValue;
/**
* 指标权重
*/
private BigDecimal indicatorWeight;
/**
* 指标类型
*/
private Integer indicatorType;
/**
* 提前期数
*/
private Integer leadPeriod;
/**
* 指标数据
*/
private List<ModelResultDataVo> dataList;
}

View File

@@ -0,0 +1,32 @@
package com.ruoyi.cms.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* 失业率监测
*
* @author 马宝龙
* @date 2026/7/2
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ModelUnemploymentRateResultVo implements Serializable {
private static final long serialVersionUID = 4699395385615089940L;
/**
* 时间列表
*/
private List<String> timeList;
/**
* 指标列表
*/
private List<ModelResultIndicatorDataVo> indicatorList;
}

View File

@@ -0,0 +1,46 @@
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;
import java.util.List;
/**
* 失业预警扩散指数管理
*
* @author 马宝龙
* @date 2026/7/2
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ModelUnemploymentWarningDiffusionResultVo implements Serializable {
private static final long serialVersionUID = 6095346205199667758L;
/**
* 当期指标值
*/
private BigDecimal currentValue;
/**
* 时间列表
*/
private List<String> timeList;
/**
* 失业预警扩散指数
*/
private List<BigDecimal> diffusionValueList;
/**
* 失业率
*/
private List<BigDecimal> unemploymentRateList;
/**
* 指标列表
*/
private List<ModelResultIndicatorDataVo> indicatorList;
}

View File

@@ -1,6 +1,8 @@
package com.ruoyi.cms.mapper;
import com.ruoyi.cms.domain.ModelWarningIndicatorData;
import com.ruoyi.cms.domain.dto.ModelWarningIndicatorDataResultDto;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -53,9 +55,11 @@ public interface ModelWarningIndicatorDataMapper {
* 通过指标编码查询
*
* @param indicatorCode 指标编码
* @param regionCode 地区编码
* @return 指标数据列表
*/
List<ModelWarningIndicatorData> selectByIndicatorCode(String indicatorCode);
List<ModelWarningIndicatorData> selectByIndicatorCode(@Param("indicatorCode") String indicatorCode,
@Param("regionCode") String regionCode);
/**
* 查询列表
@@ -64,4 +68,28 @@ public interface ModelWarningIndicatorDataMapper {
* @return 列表
*/
List<ModelWarningIndicatorData> list(ModelWarningIndicatorData modelWarningIndicatorData);
/**
* 查询就业失业率监测数据
*
* @param regionCode 地区编码
* @return 指标数据列表
*/
List<ModelWarningIndicatorDataResultDto> listUnemploymentRateMonitor(String regionCode);
/**
* 查询就业监测综合指数管理
*
* @param regionCode 地区编码
* @return 指标数据列表
*/
List<ModelWarningIndicatorDataResultDto> listEmploymentMonitorComposite(String regionCode);
/**
* 查询失业预警扩散指数管理
*
* @param regionCode 地区编码
* @return 指标数据列表
*/
List<ModelWarningIndicatorDataResultDto> listUnemploymentWarningDiffusion(String regionCode);
}

View File

@@ -1,6 +1,7 @@
package com.ruoyi.cms.service;
import com.ruoyi.cms.domain.ModelEmploymentMonitorComposite;
import com.ruoyi.cms.domain.vo.ModelEmploymentMonitorCompositeResultVo;
import java.util.List;
@@ -48,4 +49,13 @@ public interface ModelEmploymentMonitorCompositeService {
* @return 列表
*/
List<ModelEmploymentMonitorComposite> list(ModelEmploymentMonitorComposite modelEmploymentMonitorComposite);
/**
* 监测结果
*
* @param regionCode 区域编码
* @return 监测结果
*/
ModelEmploymentMonitorCompositeResultVo monitorResult(String regionCode);
}

View File

@@ -1,6 +1,7 @@
package com.ruoyi.cms.service;
import com.ruoyi.cms.domain.ModelUnemploymentRateMonitor;
import com.ruoyi.cms.domain.vo.ModelUnemploymentRateResultVo;
import java.util.List;
@@ -48,4 +49,13 @@ public interface ModelUnemploymentRateMonitorService {
* @return 列表
*/
List<ModelUnemploymentRateMonitor> list(ModelUnemploymentRateMonitor modelUnemploymentRateMonitor);
/**
* 监测结果
*
* @param regionCode 区域编码
* @return 监测结果
*/
ModelUnemploymentRateResultVo monitorResult(String regionCode);
}

View File

@@ -1,6 +1,7 @@
package com.ruoyi.cms.service;
import com.ruoyi.cms.domain.ModelUnemploymentWarningDiffusion;
import com.ruoyi.cms.domain.vo.ModelUnemploymentWarningDiffusionResultVo;
import java.util.List;
@@ -48,4 +49,12 @@ public interface ModelUnemploymentWarningDiffusionService {
* @return 列表
*/
List<ModelUnemploymentWarningDiffusion> list(ModelUnemploymentWarningDiffusion modelUnemploymentWarningDiffusion);
/**
* 监测结果
*
* @param regionCode 区域编码
* @return 监测结果
*/
ModelUnemploymentWarningDiffusionResultVo monitorResult(String regionCode);
}

View File

@@ -2,16 +2,24 @@ package com.ruoyi.cms.service.impl;
import com.ruoyi.cms.domain.ModelEmploymentMonitorComposite;
import com.ruoyi.cms.domain.ModelWarningIndicator;
import com.ruoyi.cms.domain.dto.ModelWarningIndicatorDataResultDto;
import com.ruoyi.cms.domain.vo.ModelEmploymentMonitorCompositeResultVo;
import com.ruoyi.cms.domain.vo.ModelResultIndicatorDataVo;
import com.ruoyi.cms.mapper.ModelEmploymentMonitorCompositeMapper;
import com.ruoyi.cms.mapper.ModelWarningIndicatorDataMapper;
import com.ruoyi.cms.mapper.ModelWarningIndicatorMapper;
import com.ruoyi.cms.service.ModelEmploymentMonitorCompositeService;
import com.ruoyi.cms.util.ModelIndicatorUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import reactor.util.function.Tuple2;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@@ -33,6 +41,7 @@ public class ModelEmploymentMonitorCompositeServiceImpl implements ModelEmployme
private final ModelEmploymentMonitorCompositeMapper modelEmploymentMonitorCompositeMapper;
private final ModelWarningIndicatorMapper modelWarningIndicatorMapper;
private final ModelWarningIndicatorDataMapper modelWarningIndicatorDataMapper;
@Override
public void create(ModelEmploymentMonitorComposite modelEmploymentMonitorComposite) {
@@ -138,4 +147,27 @@ public class ModelEmploymentMonitorCompositeServiceImpl implements ModelEmployme
public List<ModelEmploymentMonitorComposite> list(ModelEmploymentMonitorComposite modelEmploymentMonitorComposite) {
return modelEmploymentMonitorCompositeMapper.list(modelEmploymentMonitorComposite);
}
@Override
public ModelEmploymentMonitorCompositeResultVo monitorResult(String regionCode) {
ModelEmploymentMonitorCompositeResultVo vo = ModelEmploymentMonitorCompositeResultVo.builder().build();
List<ModelWarningIndicatorDataResultDto> list =
modelWarningIndicatorDataMapper.listEmploymentMonitorComposite(regionCode);
if (CollectionUtils.isEmpty(list)) {
return vo;
}
// 整理指标
Tuple2<List<String>, List<ModelResultIndicatorDataVo>> result = ModelIndicatorUtil.organizeIndicator(list);
vo.setTimeList(result.getT1());
vo.setIndicatorList(result.getT2());
List<BigDecimal> compositeList = ModelIndicatorUtil.calculateComposite(result);
vo.setCompositeValueList(compositeList);
vo.setCurrentValue(compositeList.get(compositeList.size() - 1));
return vo;
}
}

View File

@@ -2,15 +2,23 @@ package com.ruoyi.cms.service.impl;
import com.ruoyi.cms.domain.ModelUnemploymentRateMonitor;
import com.ruoyi.cms.domain.ModelWarningIndicator;
import com.ruoyi.cms.domain.ModelWarningIndicatorData;
import com.ruoyi.cms.domain.dto.ModelWarningIndicatorDataResultDto;
import com.ruoyi.cms.domain.vo.ModelResultIndicatorDataVo;
import com.ruoyi.cms.domain.vo.ModelUnemploymentRateResultVo;
import com.ruoyi.cms.mapper.ModelUnemploymentRateMonitorMapper;
import com.ruoyi.cms.mapper.ModelWarningIndicatorDataMapper;
import com.ruoyi.cms.mapper.ModelWarningIndicatorMapper;
import com.ruoyi.cms.service.ModelUnemploymentRateMonitorService;
import com.ruoyi.cms.util.ModelIndicatorUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import reactor.util.function.Tuple2;
import java.util.List;
import java.util.Objects;
@@ -31,6 +39,7 @@ public class ModelUnemploymentRateMonitorServiceImpl implements ModelUnemploymen
private final ModelUnemploymentRateMonitorMapper modelUnemploymentRateMonitorMapper;
private final ModelWarningIndicatorMapper modelWarningIndicatorMapper;
private final ModelWarningIndicatorDataMapper modelWarningIndicatorDataMapper;
@Override
public void create(ModelUnemploymentRateMonitor modelUnemploymentRateMonitor) {
@@ -126,4 +135,22 @@ public class ModelUnemploymentRateMonitorServiceImpl implements ModelUnemploymen
public List<ModelUnemploymentRateMonitor> list(ModelUnemploymentRateMonitor modelUnemploymentRateMonitor) {
return modelUnemploymentRateMonitorMapper.list(modelUnemploymentRateMonitor);
}
@Override
public ModelUnemploymentRateResultVo monitorResult(String regionCode) {
ModelUnemploymentRateResultVo vo = ModelUnemploymentRateResultVo.builder().build();
List<ModelWarningIndicatorDataResultDto> list =
modelWarningIndicatorDataMapper.listUnemploymentRateMonitor(regionCode);
if (CollectionUtils.isEmpty(list)) {
return vo;
}
// 整理指标
Tuple2<List<String>, List<ModelResultIndicatorDataVo>> result = ModelIndicatorUtil.organizeIndicator(list);
vo.setTimeList(result.getT1());
vo.setIndicatorList(result.getT2());
return vo;
}
}

View File

@@ -2,18 +2,31 @@ package com.ruoyi.cms.service.impl;
import com.ruoyi.cms.domain.ModelUnemploymentWarningDiffusion;
import com.ruoyi.cms.domain.ModelWarningIndicator;
import com.ruoyi.cms.domain.ModelWarningIndicatorData;
import com.ruoyi.cms.domain.dto.ModelWarningIndicatorDataResultDto;
import com.ruoyi.cms.domain.vo.ModelResultDataVo;
import com.ruoyi.cms.domain.vo.ModelResultIndicatorDataVo;
import com.ruoyi.cms.domain.vo.ModelUnemploymentWarningDiffusionResultVo;
import com.ruoyi.cms.mapper.ModelUnemploymentWarningDiffusionMapper;
import com.ruoyi.cms.mapper.ModelWarningIndicatorDataMapper;
import com.ruoyi.cms.mapper.ModelWarningIndicatorMapper;
import com.ruoyi.cms.service.ModelUnemploymentWarningDiffusionService;
import com.ruoyi.cms.util.ModelIndicatorUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import reactor.util.function.Tuple2;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
@@ -33,6 +46,7 @@ public class ModelUnemploymentWarningDiffusionServiceImpl implements ModelUnempl
private final ModelUnemploymentWarningDiffusionMapper modelUnemploymentWarningDiffusionMapper;
private final ModelWarningIndicatorMapper modelWarningIndicatorMapper;
private final ModelWarningIndicatorDataMapper modelWarningIndicatorDataMapper;
@Override
public void create(ModelUnemploymentWarningDiffusion modelUnemploymentWarningDiffusion) {
@@ -141,4 +155,58 @@ public class ModelUnemploymentWarningDiffusionServiceImpl implements ModelUnempl
public List<ModelUnemploymentWarningDiffusion> list(ModelUnemploymentWarningDiffusion modelUnemploymentWarningDiffusion) {
return modelUnemploymentWarningDiffusionMapper.list(modelUnemploymentWarningDiffusion);
}
@Override
public ModelUnemploymentWarningDiffusionResultVo monitorResult(String regionCode) {
ModelUnemploymentWarningDiffusionResultVo vo = ModelUnemploymentWarningDiffusionResultVo.builder().build();
List<ModelWarningIndicatorDataResultDto> list =
modelWarningIndicatorDataMapper.listUnemploymentWarningDiffusion(regionCode);
if (CollectionUtils.isEmpty(list)) {
return vo;
}
// 整理指标
Tuple2<List<String>, List<ModelResultIndicatorDataVo>> result = ModelIndicatorUtil.organizeIndicator(list);
vo.setTimeList(result.getT1());
vo.setIndicatorList(result.getT2());
// 获取失业率指标
List<String> timeList = result.getT1();
List<ModelWarningIndicatorData> unemploymentIndicatorDataList =
modelWarningIndicatorDataMapper.selectByIndicatorCode("syzb000", regionCode);
Map<String, ModelWarningIndicatorData> unemploymentIndicatorDataMap = new HashMap<>();
for (ModelWarningIndicatorData modelWarningIndicatorData : unemploymentIndicatorDataList) {
unemploymentIndicatorDataMap.put(modelWarningIndicatorData.getYear() + ""
+ modelWarningIndicatorData.getMonth() + "", modelWarningIndicatorData);
}
List<ModelResultDataVo> dataList = new ArrayList<>();
for (String time : timeList) {
ModelWarningIndicatorData unemploymentIndicatorData = unemploymentIndicatorDataMap.get(time);
dataList.add(ModelResultDataVo.builder()
.time(time)
.value(Optional.ofNullable(unemploymentIndicatorData)
.map(ModelWarningIndicatorData::getDataValue).orElse(null))
.build());
}
ModelResultIndicatorDataVo unemploymentRateData = ModelResultIndicatorDataVo.builder()
.indicatorName("城镇调查失业率")
.indicatorCode("syzb000")
.indicatorType(1)
.leadPeriod(1)
.dataList(dataList)
.build();
List<BigDecimal> unemploymentRateList = new ArrayList<>();
for (ModelResultDataVo dataVo : unemploymentRateData.getDataList()) {
unemploymentRateList.add(dataVo.getValue());
}
vo.setUnemploymentRateList(unemploymentRateList);
List<BigDecimal> diffusionList = ModelIndicatorUtil.calculateDiffusion(result, null);
vo.setDiffusionValueList(diffusionList);
vo.setCurrentValue(diffusionList.get(diffusionList.size() - 1));
return vo;
}
}

View File

@@ -114,7 +114,7 @@ public class ModelWarningIndicatorServiceImpl implements ModelWarningIndicatorSe
ModelWarningIndicator detail = detail(id);
// 就业失业预警指标数据是否有数据
List<ModelWarningIndicatorData> uniqueData =
modelWarningIndicatorDataMapper.selectByIndicatorCode(detail.getIndicatorCode());
modelWarningIndicatorDataMapper.selectByIndicatorCode(detail.getIndicatorCode(), null);
if (CollectionUtils.isNotEmpty(uniqueData)) {
throw new ServiceException("就业失业预警指标数据有数据,请先删除就业失业预警指标数据");
}

View File

@@ -0,0 +1,293 @@
package com.ruoyi.cms.util;
import com.ruoyi.cms.domain.dto.ModelWarningIndicatorDataResultDto;
import com.ruoyi.cms.domain.vo.ModelResultDataVo;
import com.ruoyi.cms.domain.vo.ModelResultIndicatorDataVo;
import org.apache.commons.collections4.CollectionUtils;
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.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* 模型指标工具类
*
* @author 马宝龙
* @date 2026/7/2
*/
public class ModelIndicatorUtil {
private ModelIndicatorUtil() {
}
/**
* 整理指标数据
*
* @param list 指标数据
* @return 指标数据
*/
public static Tuple2<List<String>, List<ModelResultIndicatorDataVo>> organizeIndicator(
List<ModelWarningIndicatorDataResultDto> list) {
Set<String> timeSet = new HashSet<>();
Map<String, List<ModelWarningIndicatorDataResultDto>> indicatorNameMap = new HashMap<>();
for (ModelWarningIndicatorDataResultDto indicatorData : list) {
timeSet.add(indicatorData.getYear() + "_" + String.format("%02d", indicatorData.getMonth()));
List<ModelWarningIndicatorDataResultDto> indicatorDataList =
indicatorNameMap.computeIfAbsent(indicatorData.getIndicatorName(), k -> new ArrayList<>());
indicatorDataList.add(indicatorData);
indicatorNameMap.put(indicatorData.getIndicatorName(), indicatorDataList);
}
List<String> timeTempList = new ArrayList<>(timeSet);
Collections.sort(timeTempList);
List<String> timeList = new ArrayList<>();
for (String time : timeTempList) {
String[] split = time.split("_");
timeList.add(split[0] + "" + Integer.parseInt(split[1]) + "");
}
List<ModelResultIndicatorDataVo> indicatorList = new ArrayList<>();
for (Map.Entry<String, List<ModelWarningIndicatorDataResultDto>> entry : indicatorNameMap.entrySet()) {
List<ModelWarningIndicatorDataResultDto> value = entry.getValue();
ModelWarningIndicatorDataResultDto dataResultDto = value.get(0);
BigDecimal maxValue = dataResultDto.getDataValue();
BigDecimal minValue = dataResultDto.getDataValue();
ModelResultIndicatorDataVo indicatorVo = ModelResultIndicatorDataVo.builder()
.indicatorName(entry.getKey())
.indicatorCode(dataResultDto.getIndicatorCode())
.indicatorType(dataResultDto.getIndicatorType())
.indicatorWeight(dataResultDto.getIndicatorWeight())
.leadPeriod(dataResultDto.getLeadPeriod())
.build();
Map<String, ModelWarningIndicatorDataResultDto> valueMap = new HashMap<>();
for (ModelWarningIndicatorDataResultDto indicatorData : value) {
valueMap.put(indicatorData.getYear() + "_" + String.format("%02d", indicatorData.getMonth()),
indicatorData);
}
List<ModelResultDataVo> dataList = new ArrayList<>();
for (String time : timeTempList) {
ModelWarningIndicatorDataResultDto indicatorData = valueMap.get(time);
BigDecimal dataValue = null;
if (Objects.nonNull(indicatorData)) {
dataValue = indicatorData.getDataValue();
maxValue = max(maxValue, indicatorData.getDataValue());
minValue = min(minValue, indicatorData.getDataValue());
}
String[] split = time.split("_");
dataList.add(ModelResultDataVo.builder()
.time(split[0] + "" + Integer.parseInt(split[1]) + "")
.value(dataValue)
.build());
}
indicatorVo.setMaxValue(maxValue);
indicatorVo.setMinValue(minValue);
indicatorVo.setDataList(dataList);
indicatorList.add(indicatorVo);
}
return Tuples.of(timeList, indicatorList);
}
/**
* 就失业监测综合指数
*
* @param resultList 指标结果数据
* @return 计算结果
*/
public static List<BigDecimal> calculateComposite(Tuple2<List<String>, List<ModelResultIndicatorDataVo>> resultList) {
List<ModelResultIndicatorDataVo> indicatorDataList = resultList.getT2();
// 预警指标值标准化
for (ModelResultIndicatorDataVo indicatorData : indicatorDataList) {
BigDecimal maxValue = indicatorData.getMaxValue();
BigDecimal minValue = indicatorData.getMinValue();
BigDecimal denominator = null;
if (Objects.nonNull(maxValue) && Objects.nonNull(minValue)) {
denominator = maxValue.subtract(minValue);
}
List<ModelResultDataVo> dataList = indicatorData.getDataList();
for (ModelResultDataVo dataVo : dataList) {
if (Objects.nonNull(denominator) && denominator.compareTo(BigDecimal.ZERO) != 0) {
// 正向指标 = (x-min)/(max-min)
BigDecimal value;
if (1 == indicatorData.getIndicatorType()) {
value = (dataVo.getValue().subtract(minValue))
.divide(denominator, 10, RoundingMode.HALF_UP);
} else {
// 负向指标 = (max-x)/(max-min)
value = (maxValue.subtract(dataVo.getValue()))
.divide(denominator, 10, RoundingMode.HALF_UP);
}
dataVo.setValue(value);
} else {
dataVo.setValue(BigDecimal.ZERO);
}
}
}
// 预警指标加权平均值
for (ModelResultIndicatorDataVo indicatorData : indicatorDataList) {
BigDecimal indicatorWeight = indicatorData.getIndicatorWeight();
if (Objects.isNull(indicatorWeight)) {
indicatorWeight = BigDecimal.ZERO;
}
List<ModelResultDataVo> dataList = indicatorData.getDataList();
for (ModelResultDataVo dataVo : dataList) {
dataVo.setValue(dataVo.getValue().multiply(indicatorWeight));
}
}
// 每个月数据求和
List<List<ModelResultDataVo>> dataList = new ArrayList<>();
for (ModelResultIndicatorDataVo indicatorData : indicatorDataList) {
dataList.add(indicatorData.getDataList());
}
List<String> timeList = resultList.getT1();
BigDecimal[] sums = new BigDecimal[timeList.size()];
for (List<ModelResultDataVo> innerList : dataList) {
if (CollectionUtils.isEmpty(innerList)) {
continue;
}
for (int i = 0; i < innerList.size(); i++) {
ModelResultDataVo vo = innerList.get(i);
if (Objects.nonNull(vo) && Objects.nonNull(vo.getValue())) {
sums[i] = sums[i].add(vo.getValue());
}
}
}
return new ArrayList<>(Arrays.asList(sums));
}
/**
* 失业预警扩散指数
*
* @param resultList 指标结果数据
* @param unemploymentRateData 失业率数据
* @return 计算结果
*/
public static List<BigDecimal> calculateDiffusion(Tuple2<List<String>, List<ModelResultIndicatorDataVo>> resultList,
ModelResultIndicatorDataVo unemploymentRateData) {
List<ModelResultIndicatorDataVo> indicatorDataList = resultList.getT2();
if (Objects.nonNull(unemploymentRateData)) {
indicatorDataList.add(unemploymentRateData);
}
int maxLeadPeriod = 0;
// 计算各个警兆指标的景气值
for (ModelResultIndicatorDataVo indicatorData : indicatorDataList) {
Integer leadPeriod = indicatorData.getLeadPeriod();
if (Objects.isNull(leadPeriod) || leadPeriod < 1) {
leadPeriod = 1;
}
maxLeadPeriod = Math.max(maxLeadPeriod, leadPeriod);
List<ModelResultDataVo> dataList = indicatorData.getDataList();
for (int i = dataList.size() - 1; i >= 0; i--) {
ModelResultDataVo dataVo = dataList.get(i);
if (i < leadPeriod) {
dataVo.setValue(null);
continue;
}
BigDecimal value;
BigDecimal currentValue = dataVo.getValue();
BigDecimal previousValue = dataList.get(i - 1).getValue();
if (1 == indicatorData.getIndicatorType()) {
// 正向指标
value = currentValue.compareTo(previousValue) > 0 ? BigDecimal.ONE :
(currentValue.compareTo(previousValue) == 0 ? new BigDecimal("0.5") : BigDecimal.ZERO);
} else {
// 负向指标
value = currentValue.compareTo(previousValue) > 0 ? BigDecimal.ZERO :
(currentValue.compareTo(previousValue) == 0 ? new BigDecimal("0.5") : BigDecimal.ONE);
}
dataVo.setValue(value);
}
}
// 景气值加权值
BigDecimal weight = BigDecimal.ONE.divide(new BigDecimal(indicatorDataList.size()), 10,
RoundingMode.HALF_UP);
for (ModelResultIndicatorDataVo indicatorData : indicatorDataList) {
List<ModelResultDataVo> dataList = indicatorData.getDataList();
for (int i = dataList.size() - 1; i >= 0; i--) {
ModelResultDataVo dataVo = dataList.get(i);
if (i < maxLeadPeriod) {
dataVo.setValue(null);
continue;
}
BigDecimal value = dataVo.getValue().multiply(weight).setScale(10, RoundingMode.HALF_UP);
dataVo.setValue(value);
}
}
// 每个月数据求和
List<List<ModelResultDataVo>> dataList = new ArrayList<>();
for (ModelResultIndicatorDataVo indicatorData : indicatorDataList) {
dataList.add(indicatorData.getDataList());
}
List<String> timeList = resultList.getT1();
BigDecimal[] sums = new BigDecimal[timeList.size() - maxLeadPeriod];
for (List<ModelResultDataVo> innerList : dataList) {
if (CollectionUtils.isEmpty(innerList)) {
continue;
}
for (int i = 0; i < innerList.size(); i++) {
if (i < maxLeadPeriod) {
continue;
}
ModelResultDataVo vo = innerList.get(i);
if (Objects.nonNull(vo) && Objects.nonNull(vo.getValue())) {
sums[i - maxLeadPeriod] = sums[i - maxLeadPeriod].add(vo.getValue());
}
}
}
return new ArrayList<>(Arrays.asList(sums));
}
/**
* 求最大值
*
* @param a a
* @param b b
* @return 最大值
*/
public static BigDecimal max(BigDecimal a, BigDecimal b) {
if (Objects.isNull(a)) {
return b;
}
if (Objects.isNull(b)) {
return a;
}
return a.max(b);
}
/**
* 求最小值
*
* @param a a
* @param b b
* @return 最小值
*/
public static BigDecimal min(BigDecimal a, BigDecimal b) {
if (Objects.isNull(a)) {
return b;
}
if (Objects.isNull(b)) {
return a;
}
return a.min(b);
}
}

View File

@@ -3,7 +3,8 @@
<mapper namespace="com.ruoyi.cms.mapper.ModelWarningIndicatorDataMapper">
<insert id="insert" parameterType="com.ruoyi.cms.domain.ModelWarningIndicatorData">
INSERT INTO model_warning_indicator_data (indicator_code, data_value, year, month, region_code, region_name, remark)
INSERT INTO model_warning_indicator_data (indicator_code, data_value, year, month, region_code, region_name,
remark)
VALUES (#{indicatorCode}, #{dataValue}, #{year}, #{month}, #{regionCode}, #{regionName}, #{remark})
</insert>
@@ -29,8 +30,17 @@
<select id="selectById" parameterType="com.ruoyi.cms.domain.ModelWarningIndicatorData"
resultType="com.ruoyi.cms.domain.ModelWarningIndicatorData">
SELECT *
FROM model_warning_indicator_data
SELECT a.id,
a.indicator_code,
a.data_value,
a.year,
a.month,
a.region_code,
a.region_name,
a.remark,
b.indicator_name
FROM model_warning_indicator_data a
LEFT JOIN model_warning_indicator b ON a.indicator_code = b.indicator_code
WHERE id = #{id}
</select>
@@ -39,12 +49,12 @@
SELECT *
FROM model_warning_indicator_data
WHERE indicator_code = #{indicatorCode}
AND year = #{year}
AND month = #{month}
AND year = #{year}
AND month = #{month}
AND region_code = #{regionCode}
</select>
<select id="selectByIndicatorCode" parameterType="java.lang.String"
<select id="selectByIndicatorCode"
resultType="com.ruoyi.cms.domain.ModelWarningIndicatorData">
SELECT *
FROM model_warning_indicator_data
@@ -52,15 +62,26 @@
<if test="indicatorCode != null and indicatorCode != ''">
AND indicator_code = #{indicatorCode}
</if>
<if test="regionCode != null and regionCode != ''">
AND region_code = #{regionCode}
</if>
</where>
ORDER BY year DESC, month DESC, indicator_code
</select>
<select id="list" parameterType="com.ruoyi.cms.domain.ModelWarningIndicatorData"
resultType="com.ruoyi.cms.domain.ModelWarningIndicatorData">
SELECT *
FROM model_warning_indicator_data
SELECT a.id,
a.indicator_code,
a.data_value,
a.year,
a.month,
a.region_code,
a.region_name,
a.remark,
b.indicator_name
FROM model_warning_indicator_data a
LEFT JOIN model_warning_indicator b ON a.indicator_code = b.indicator_code
<where>
<if test="id != null ">
AND id = #{id}
@@ -84,4 +105,124 @@
ORDER BY year DESC, month DESC, indicator_code
</select>
<select id="listUnemploymentRateMonitor" parameterType="java.lang.String"
resultType="com.ruoyi.cms.domain.dto.ModelWarningIndicatorDataResultDto">
WITH ranked_data AS (
SELECT
a.year,
a.month,
ROW_NUMBER() OVER (ORDER BY year DESC, month DESC) as row_num,
COUNT(*) OVER () as total_count
FROM model_warning_indicator_data a
INNER JOIN model_unemployment_rate_monitor b ON a.indicator_code = b.indicator_code
WHERE a.region_code = #{regionCode}
),
year_month AS (
SELECT
year,
month
FROM ranked_data
WHERE row_num = LEAST(36, total_count) LIMIT 1 )
SELECT a.id,
a.indicator_code,
a.data_value,
a.year,
a.month,
a.region_code,
a.region_name,
a.remark,
c.indicator_name
FROM year_month d
LEFT JOIN model_warning_indicator_data a
ON a.year &gt;= d.year AND a.month &gt;= d.month
AND a.region_code = #{regionCode}
INNER JOIN model_unemployment_rate_monitor b ON a.indicator_code = b.indicator_code
LEFT JOIN model_warning_indicator c ON a.indicator_code = c.indicator_code;
</select>
<select id="listEmploymentMonitorComposite" parameterType="java.lang.String"
resultType="com.ruoyi.cms.domain.dto.ModelWarningIndicatorDataResultDto">
WITH ranked_data AS (
SELECT
a.year,
a.month,
ROW_NUMBER() OVER (ORDER BY year DESC, month DESC) as row_num,
COUNT(*) OVER () as total_count
FROM model_warning_indicator_data a
INNER JOIN model_employment_monitor_composite b ON a.indicator_code = b.indicator_code
WHERE a.region_code = #{regionCode}
),
year_month AS (
SELECT
year,
month
FROM ranked_data
WHERE row_num = LEAST(36, total_count) LIMIT 1 )
SELECT a.id,
a.indicator_code,
a.data_value,
a.year,
a.month,
a.region_code,
a.region_name,
a.remark,
c.indicator_name,
b.indicator_weight,
b.indicator_type
FROM year_month d
LEFT JOIN model_warning_indicator_data a
ON a.year &gt;= d.year AND a.month &gt;= d.month
AND a.region_code = #{regionCode}
INNER JOIN model_employment_monitor_composite b ON a.indicator_code = b.indicator_code
LEFT JOIN model_warning_indicator c ON a.indicator_code = c.indicator_code;
</select>
<select id="listUnemploymentWarningDiffusion" parameterType="java.lang.String"
resultType="com.ruoyi.cms.domain.dto.ModelWarningIndicatorDataResultDto">
WITH ranked_data AS (
SELECT
a.year,
a.month,
ROW_NUMBER() OVER (ORDER BY year DESC, month DESC) as row_num,
COUNT(*) OVER () as total_count
FROM model_warning_indicator_data a
INNER JOIN model_unemployment_warning_diffusion b ON a.indicator_code = b.indicator_code
WHERE a.region_code = #{regionCode}
),
year_month AS (
SELECT
year,
month
FROM ranked_data
WHERE row_num = LEAST(36, total_count) LIMIT 1 )
SELECT a.id,
a.indicator_code,
a.data_value,
a.year,
a.month,
a.region_code,
a.region_name,
a.remark,
c.indicator_name,
b.indicator_weight,
b.indicator_type,
b.lead_period
FROM year_month d
LEFT JOIN model_warning_indicator_data a
ON a.year &gt;= d.year AND a.month &gt;= d.month
AND a.region_code = #{regionCode}
INNER JOIN model_unemployment_warning_diffusion b ON a.indicator_code = b.indicator_code
LEFT JOIN model_warning_indicator c ON a.indicator_code = c.indicator_code;
</select>
</mapper>