Browse Source

fit: 个人极端赋分规则

main
wxc 1 year ago
parent
commit
b419f200c1
  1. 13
      sql/1114.sql
  2. 2
      src/main/java/com/biutag/supervision/constants/AppConstants.java
  3. 10
      src/main/java/com/biutag/supervision/controller/sensitivePerception/ModelController.java
  4. 47
      src/main/java/com/biutag/supervision/controller/sensitivePerception/RiskScoreRuleController.java
  5. 7
      src/main/java/com/biutag/supervision/mapper/ModelClassMapper.java
  6. 2
      src/main/java/com/biutag/supervision/pojo/entity/Model.java
  7. 22
      src/main/java/com/biutag/supervision/pojo/model/ModelClassModel.java
  8. 2
      src/main/java/com/biutag/supervision/pojo/vo/MenuTree.java
  9. 2
      src/main/java/com/biutag/supervision/pojo/vo/ModelTree.java
  10. 45
      src/main/java/com/biutag/supervision/pojo/vo/RiskScoreRuleTree.java
  11. 6
      src/main/java/com/biutag/supervision/service/BusinessDepartService.java
  12. 1
      src/main/java/com/biutag/supervision/service/ModelClassService.java
  13. 5
      src/main/java/com/biutag/supervision/service/ModelService.java
  14. 199
      src/main/java/com/biutag/supervision/service/NegativeScoreService.java
  15. 2
      src/main/java/com/biutag/supervision/support/ModelClueDistributionAware.java
  16. 6
      src/main/resources/application-local.yml
  17. 2
      src/main/resources/mapper/ProfilePoliceMapper.xml
  18. 41
      src/test/java/com/biutag/supervision/tools/ExcelTest.java
  19. 2
      src/test/java/com/biutag/supervision/tools/GenCodeTests.java
  20. 26
      src/test/java/com/biutag/supervision/tools/HdtExcelDto.java

13
sql/1114.sql

@ -0,0 +1,13 @@
CREATE TABLE `risk_score_rule` (
`id` int NOT NULL AUTO_INCREMENT,
`pid` int DEFAULT NULL,
`risk_name` varchar(255) COMMENT '风险因素',
`score` varchar(255) COMMENT '分值',
`rule_desc` text COLLATE utf8mb4_general_ci COMMENT '规则描述',
`weight` int DEFAULT NULL COMMENT '权重',
`status` tinyint DEFAULT NULL COMMENT '状态',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`sort_id` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 COMMENT='个人极端赋分规则';

2
src/main/java/com/biutag/supervision/constants/AppConstants.java

@ -2,7 +2,7 @@ package com.biutag.supervision.constants;
public class AppConstants { public class AppConstants {
public static final int MENU_ROOT_ID = 0; public static final Integer TREE_ROOT_ID = 0;
// 单位 // 单位
public static final String DICT_CONTENT_ROOT_PARENT_CODE = "-1"; public static final String DICT_CONTENT_ROOT_PARENT_CODE = "-1";

10
src/main/java/com/biutag/supervision/controller/sensitivePerception/ModelController.java

@ -3,12 +3,12 @@ package com.biutag.supervision.controller.sensitivePerception;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.biutag.supervision.mapper.ModelClassMapper;
import com.biutag.supervision.pojo.Result; import com.biutag.supervision.pojo.Result;
import com.biutag.supervision.pojo.entity.Model; import com.biutag.supervision.pojo.entity.Model;
import com.biutag.supervision.pojo.entity.ModelClass; import com.biutag.supervision.pojo.model.ModelClassModel;
import com.biutag.supervision.pojo.param.ModelQueryParam; import com.biutag.supervision.pojo.param.ModelQueryParam;
import com.biutag.supervision.pojo.vo.ModelTree; import com.biutag.supervision.pojo.vo.ModelTree;
import com.biutag.supervision.service.ModelClassService;
import com.biutag.supervision.service.ModelService; import com.biutag.supervision.service.ModelService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -24,7 +24,7 @@ public class ModelController {
private final ModelService modelService; private final ModelService modelService;
private final ModelClassService modelClassService; private final ModelClassMapper modelClassMapper;
@GetMapping @GetMapping
public Result<Page<Model>> list(ModelQueryParam queryParam) { public Result<Page<Model>> list(ModelQueryParam queryParam) {
@ -39,13 +39,14 @@ public class ModelController {
@GetMapping("tree") @GetMapping("tree")
public Result<List<ModelTree>> tree() { public Result<List<ModelTree>> tree() {
List<ModelClass> modelClasses = modelClassService.list(); List<ModelClassModel> modelClasses = modelClassMapper.selectListAll();
List<Model> models = modelService.list(); List<Model> models = modelService.list();
List<ModelTree> list = new ArrayList<>(); List<ModelTree> list = new ArrayList<>();
list.addAll(modelClasses.stream().map(item -> { list.addAll(modelClasses.stream().map(item -> {
ModelTree node = new ModelTree(); ModelTree node = new ModelTree();
node.setValue(item.getId()); node.setValue(item.getId());
node.setLabel(item.getName()); node.setLabel(item.getName());
node.setSize(item.getSize());
node.setType("modelClass"); node.setType("modelClass");
List<ModelTree> children = models.stream().filter(model -> item.getId().equals(model.getClassId())).map(ModelTree::of).toList(); List<ModelTree> children = models.stream().filter(model -> item.getId().equals(model.getClassId())).map(ModelTree::of).toList();
node.setChildren(children); node.setChildren(children);
@ -57,7 +58,6 @@ public class ModelController {
@PostMapping @PostMapping
public Result<Boolean> add(@RequestBody Model model) { public Result<Boolean> add(@RequestBody Model model) {
return Result.success(modelService.saveModel(model)); return Result.success(modelService.saveModel(model));
} }

47
src/main/java/com/biutag/supervision/controller/sensitivePerception/RiskScoreRuleController.java

@ -0,0 +1,47 @@
package com.biutag.supervision.controller.sensitivePerception;
import com.biutag.supervision.pojo.Result;
import com.biutag.supervision.pojo.entity.RiskScoreRule;
import com.biutag.supervision.pojo.vo.RiskScoreRuleTree;
import com.biutag.supervision.service.RiskScoreRuleService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author wxc
* @date 2024/11/14
*/
@RequiredArgsConstructor
@RequestMapping("risk/scoreRule")
@RestController
public class RiskScoreRuleController {
private final RiskScoreRuleService riskScoreRuleService;
@GetMapping("tree")
public Result<List<RiskScoreRuleTree>> list() {
return Result.success(riskScoreRuleService.buildTree());
}
@PostMapping
public Result<Boolean> add(@RequestBody RiskScoreRule scoreRule) {
scoreRule.setCreateTime(LocalDateTime.now());
scoreRule.setUpdateTime(LocalDateTime.now());
return Result.success(riskScoreRuleService.save(scoreRule));
}
@PutMapping
public Result<Boolean> update(@RequestBody RiskScoreRule scoreRule) {
scoreRule.setUpdateTime(LocalDateTime.now());
return Result.success(riskScoreRuleService.updateById(scoreRule));
}
@DeleteMapping("{id}")
public Result<Boolean> update(@PathVariable Integer id) {
return Result.success(riskScoreRuleService.removeById(id));
}
}

7
src/main/java/com/biutag/supervision/mapper/ModelClassMapper.java

@ -2,7 +2,14 @@ package com.biutag.supervision.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.biutag.supervision.pojo.entity.ModelClass; import com.biutag.supervision.pojo.entity.ModelClass;
import com.biutag.supervision.pojo.model.ModelClassModel;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface ModelClassMapper extends BaseMapper<ModelClass> { public interface ModelClassMapper extends BaseMapper<ModelClass> {
@Select("select mc.id, mc.name, mc.sort, count(m.id) size from model_class mc left join model m on mc.id = m.class_id GROUP BY mc.id, mc.name, mc.sort order by sort")
List<ModelClassModel> selectListAll();
} }

2
src/main/java/com/biutag/supervision/pojo/entity/Model.java

@ -91,4 +91,6 @@ public class Model {
@TableField("model_sql") @TableField("model_sql")
private String modelSql; private String modelSql;
private Integer riskScoreRuleId;
} }

22
src/main/java/com/biutag/supervision/pojo/model/ModelClassModel.java

@ -0,0 +1,22 @@
package com.biutag.supervision.pojo.model;
import lombok.Getter;
import lombok.Setter;
/**
* @author wxc
* @date 2024/11/13
*/
@Setter
@Getter
public class ModelClassModel {
private Integer id;
private String name;
private Integer sort;
private Integer size;
}

2
src/main/java/com/biutag/supervision/pojo/vo/MenuTree.java

@ -52,7 +52,7 @@ public class MenuTree {
private List<MenuTree> children; private List<MenuTree> children;
public static List<MenuTree> buildTree(List<Menu> list) { public static List<MenuTree> buildTree(List<Menu> list) {
return buildTree(list, AppConstants.MENU_ROOT_ID); return buildTree(list, AppConstants.TREE_ROOT_ID);
} }
public static List<MenuTree> buildTree(List<Menu> list, Integer pid) { public static List<MenuTree> buildTree(List<Menu> list, Integer pid) {

2
src/main/java/com/biutag/supervision/pojo/vo/ModelTree.java

@ -21,6 +21,8 @@ public class ModelTree {
private String type; private String type;
private Integer size;
private List<ModelTree> children = new ArrayList<>(); private List<ModelTree> children = new ArrayList<>();
public static ModelTree of(Model model) { public static ModelTree of(Model model) {

45
src/main/java/com/biutag/supervision/pojo/vo/RiskScoreRuleTree.java

@ -0,0 +1,45 @@
package com.biutag.supervision.pojo.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
* @author wxc
* @date 2024/11/14
*/
@Setter
@Getter
public class RiskScoreRuleTree {
private Integer id;
private Integer pid;
// 风险因素
private String riskName;
// 分值
private String score;
// 规则描述
private String ruleDesc;
// 权重
private Integer weight;
// 状态
private Boolean status;
// 更新时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
private LocalDateTime updateTime;
private Integer sortId;
private List<RiskScoreRuleTree> children = new ArrayList<>();
}

6
src/main/java/com/biutag/supervision/service/BusinessDepartService.java

@ -278,7 +278,9 @@ public class BusinessDepartService extends ServiceImpl<BusinessDepartMapper, Bus
return result; return result;
} }
public List<BusinessDepart> list(Date beginTime, Date endTime, String businessType) { public List<BusinessDepart> list(Date beginTime, Date endTime, String departId, String businessType) {
return list(new LambdaQueryWrapper<BusinessDepart>().between(BusinessDepart::getDate, beginTime, endTime).eq(BusinessDepart::getBusinessType, businessType)); return list(new LambdaQueryWrapper<BusinessDepart>().between(BusinessDepart::getDate, beginTime, endTime)
.eq(BusinessDepart::getDepartId, departId)
.eq(BusinessDepart::getBusinessType, businessType));
} }
} }

1
src/main/java/com/biutag/supervision/service/ModelClassService.java

@ -8,4 +8,5 @@ import org.springframework.stereotype.Service;
@Service @Service
public class ModelClassService extends ServiceImpl<ModelClassMapper, ModelClass> { public class ModelClassService extends ServiceImpl<ModelClassMapper, ModelClass> {
} }

5
src/main/java/com/biutag/supervision/service/ModelService.java

@ -1,5 +1,6 @@
package com.biutag.supervision.service; package com.biutag.supervision.service;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.biutag.supervision.common.UserContextHolder; import com.biutag.supervision.common.UserContextHolder;
@ -24,7 +25,7 @@ public class ModelService extends ServiceImpl<ModelMapper, Model> {
} }
public boolean saveModel(Model model) { public boolean saveModel(Model model) {
if (DistributionMethodEnum.NEGATIVE_DISTRIBUTE.getValue().equals(model.getDistributionMethod())) { if (StrUtil.isNotBlank(model.getDistributionCycle()) && DistributionMethodEnum.NEGATIVE_DISTRIBUTE.getValue().equals(model.getDistributionMethod())) {
String expression = DistributionCycleEnum.day.name().equals(model.getDistributionCycle()) ? ExpressionBuilder.build(model.getDistributionCycleTime()) : String expression = DistributionCycleEnum.day.name().equals(model.getDistributionCycle()) ? ExpressionBuilder.build(model.getDistributionCycleTime()) :
ExpressionBuilder.build(model.getDistributionCycleTime(), model.getDistributionCycleDayOfWeek()); ExpressionBuilder.build(model.getDistributionCycleTime(), model.getDistributionCycleDayOfWeek());
model.setDistributionCycleExpression(expression); model.setDistributionCycleExpression(expression);
@ -39,7 +40,7 @@ public class ModelService extends ServiceImpl<ModelMapper, Model> {
} }
public boolean updateModel(Model model) { public boolean updateModel(Model model) {
if (DistributionMethodEnum.NEGATIVE_DISTRIBUTE.getValue().equals(model.getDistributionMethod())) { if (StrUtil.isNotBlank(model.getDistributionCycle()) && DistributionMethodEnum.NEGATIVE_DISTRIBUTE.getValue().equals(model.getDistributionMethod())) {
String expression = DistributionCycleEnum.day.name().equals(model.getDistributionCycle()) ? ExpressionBuilder.build(model.getDistributionCycleTime()) : String expression = DistributionCycleEnum.day.name().equals(model.getDistributionCycle()) ? ExpressionBuilder.build(model.getDistributionCycleTime()) :
ExpressionBuilder.build(model.getDistributionCycleTime(), model.getDistributionCycleDayOfWeek()); ExpressionBuilder.build(model.getDistributionCycleTime(), model.getDistributionCycleDayOfWeek());
model.setDistributionCycleExpression(expression); model.setDistributionCycleExpression(expression);

199
src/main/java/com/biutag/supervision/service/NegativeScoreService.java

@ -11,7 +11,6 @@ import com.biutag.supervision.pojo.entity.*;
import com.biutag.supervision.util.ScoreRule; import com.biutag.supervision.util.ScoreRule;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -116,90 +115,77 @@ public class NegativeScoreService {
System.out.println("calculateScore-------------------------------------------------End"); System.out.println("calculateScore-------------------------------------------------End");
} }
private final BusinessPoliceService businessPoliceService;
private final BusinessDepartService businessDepartService; private final BusinessDepartService businessDepartService;
private final SupPoliceService policeService; private final SupPoliceService policeService;
// 业务权重 = 单个业务风险指数 / 总业务风险指数之和 // 业务权重 = 单个业务风险指数 / 总业务风险指数之和
public double calculateBusinessWeight(Double totalScore, Double score) { public double calculateBusinessWeight(Double score, Double totalScore) {
if (totalScore == 0) { if (totalScore == 0) {
return 0.0; return 0.0;
} }
log.info("业务权重 = {} / {}", score, totalScore);
return NumberUtil.div(score, totalScore); return NumberUtil.div(score, totalScore);
} }
// 平均问题数 = 单个业务问题数 / 业务涉及人数 // 平均问题发生率 = 单个业务问题加权数 / 单位总业务量
public double calculateAvgNumber(int size, int policeSize) { public double calculateAvgNumber(double businessWeightScore, int totalBusinessSize) {
if (policeSize == 0) { if (totalBusinessSize == 0) {
log.info("平均问题发生率 = 0");
return 0; return 0;
} }
return NumberUtil.div(size, policeSize); log.info("平均问题发生率 = {} / {}", businessWeightScore, totalBusinessSize);
return NumberUtil.div(businessWeightScore, totalBusinessSize);
} }
// 业务标准差 = 根号(sum((个人问题数 - 平均问题数)²) / 业务涉及人数) // 业务标准差 = 根号(sum((个人问题数 - 平均问题数)²) / 业务涉及人数)
public double calculateSd(double[] diffNumber, int policeSize) { public double calculateSd1(double[] diffNumber, int policeSize) {
if (policeSize == 0) { if (policeSize == 0) {
log.info("业务标准差 = 0");
return 0; return 0;
} }
log.info("业务标准差 = 根号({}) / {}", Arrays.stream(diffNumber).mapToObj(val -> String.format("(%s)²", val)).collect(Collectors.joining(" + ")), policeSize);
return Math.sqrt(Arrays.stream(diffNumber).map(val -> Math.pow(val, 2)).sum() / policeSize); return Math.sqrt(Arrays.stream(diffNumber).map(val -> Math.pow(val, 2)).sum() / policeSize);
} }
// 业务差异值1 = (个人问题发生率 - 平均问题发生率) / 业务标准差 // 业务标准差 = 根号(sum((个人问题数 - 平均问题数)²) / 业务涉及人数)
// 平均问题发生率 = 总问题数 / 总业务量 public double calculateSd2(double[] diffNumber, int policeSize) {
// 个人问题发生率 = 个人问题数 / 个人业务量 if (policeSize == 0) {
public double calculateDiff1(List<NegativeScorePolice> businessScorePolice, SupPolice police, Date beginTime, Date endTime, String businessTypeCode, double sd) { log.info("业务标准差 = 0");
if (sd == 0) {
return 0; return 0;
} }
List<BusinessDepart> businessDeparts = businessDepartService.list(beginTime, endTime, businessTypeCode); log.info("业务标准差 = 根号({}) / {}", Arrays.stream(diffNumber).mapToObj(val -> String.format("(%s)²", val)).collect(Collectors.joining(" + ")), policeSize);
// 总业务量 return Math.sqrt(Arrays.stream(diffNumber).map(val -> Math.pow(val, 2)).sum() / policeSize);
int totalBusinessSize = businessDeparts.stream().mapToInt(BusinessDepart::getNumber).sum();
// 平均问题发生率
double avgRate = totalBusinessSize == 0? 0: NumberUtil.div(businessScorePolice.size(), totalBusinessSize);
// 个人问题数
long personSize = businessScorePolice.stream().filter(item -> police.getOrgId().equals(item.getIdCode())).count();
// 单位业务量
long departBusinessSize = businessDeparts.stream().filter(item -> police.getOrgId().equals(item.getDepartId())).count();
// 个人问题发生率
double personRate = departBusinessSize == 0? 0: NumberUtil.div(personSize, departBusinessSize);
return NumberUtil.div(personRate - avgRate, sd);
} }
public double calculateDiff1ByDepart(List<NegativeScoreDepart> businessScoreDeparts, String departId, Date beginTime, Date endTime, String businessTypeCode, double sd) { // 业务差异值1 = (个人问题发生率 - 平均问题发生率) / 业务标准差
// 平均问题发生率 = 总问题数 / 总业务量
// 个人问题发生率 = 个人问题数 / 个人业务量
public double calculateDiff1(double personalRate, double avgNumber, double sd) {
if (sd == 0) { if (sd == 0) {
log.info("业务差异值(发生率) = 0");
return 0; return 0;
} }
List<BusinessDepart> businessDeparts = businessDepartService.list(beginTime, endTime, businessTypeCode); log.info("业务差异值(发生率) = ({} - {}) / {}", personalRate, avgNumber, sd);
// 总业务量 return NumberUtil.div(personalRate - avgNumber, sd);
int totalBusinessSize = businessDeparts.stream().mapToInt(BusinessDepart::getNumber).sum();
// 平均问题发生率
double avgRate = totalBusinessSize == 0? 0: NumberUtil.div(businessScoreDeparts.size(), totalBusinessSize);
// 个人问题数
long personSize = businessScoreDeparts.stream().filter(item -> departId.equals(item.getDepartId())).count();
// 个人业务量
long personBusinessSize = businessDeparts.stream().filter(item -> departId.equals(item.getDepartId())).count();
// 个人问题发生率
double personRate = personBusinessSize == 0? 0: NumberUtil.div(personSize, personBusinessSize);
return NumberUtil.div(personRate - avgRate, sd);
} }
// 业务差异值2 = (问题数 - 平均问题数) / 业务标准差 // 业务差异值2 = (加权问题数 - 平均问题数) / 业务标准差
public double calculateDiff2(long personalSize, double avgNumber, double sd) { public double calculateDiff2(double personalScore, double avgNumber, double sd) {
if (sd == 0) { if (sd == 0) {
return 0; return 0;
} }
return NumberUtil.div(personalSize - avgNumber, sd); log.info("业务差异值(数量) = ({} - {}) / {}", personalScore, avgNumber, sd);
return NumberUtil.div(personalScore - avgNumber, sd);
} }
public double calculateBusinessScore(double diff, long personalSize) { public double calculateBusinessScore(double diff, double personalSize) {
if (personalSize == 0) { if (personalSize == 0) {
return 0; return 0;
} }
return 50 + (diff * 15); log.info("单个业务风险指数 = 50 + ({} * 5)", diff);
return 50 + (diff * 5);
} }
private final SupDepartService departService; private final SupDepartService departService;
@ -228,43 +214,75 @@ public class NegativeScoreService {
List<String> expressionArr = new ArrayList<>(); List<String> expressionArr = new ArrayList<>();
StringBuilder remarks = new StringBuilder(); StringBuilder remarks = new StringBuilder();
double policeScore = Arrays.stream(BusinessTypeEnum.values()).mapToDouble(businessTypeEnum -> { double policeScore = Arrays.stream(BusinessTypeEnum.values()).mapToDouble(businessTypeEnum -> {
log.info("业务 【{}】 开始-------------------------------------------------------------------", businessTypeEnum.getLabel());
List<NegativeScorePolice> businessScorePolice = scorePolices.stream().filter(item -> item.getBusinessTypeCode().equals(businessTypeEnum.getValue())).toList(); List<NegativeScorePolice> businessScorePolice = scorePolices.stream().filter(item -> item.getBusinessTypeCode().equals(businessTypeEnum.getValue())).toList();
// 业务加权问题总数
double businessWeightScore = businessScorePolice.stream().mapToDouble(NegativeScorePolice::getScore).sum();
log.info("业务加权问题数 = {}", businessWeightScore);
// 业务涉及人数 // 业务涉及人数
int policeSize = businessScorePolice.stream().map(NegativeScorePolice::getIdCode).collect(Collectors.toSet()).size(); int policeSize = businessScorePolice.stream().map(NegativeScorePolice::getIdCode).collect(Collectors.toSet()).size();
remarks.append(String.format("业务设计人数 %s", policeSize)); log.info("业务涉及人数 = {}", policeSize);
// 业务问题数 // 业务加权问题数(风险指数)
int businessSize = businessScorePolice.size(); double personalScore = businessScorePolice.stream().filter(item -> idCode.equals(item.getIdCode())).mapToDouble(NegativeScorePolice::getScore).sum();
//--------------------------------------------------------- log.info("个人业务加权问题数 = {}", personalScore);
// 平均问题数
double avgNumber = calculateAvgNumber(businessSize, policeSize);
// 差值集合 = 个人问题数 - 平均问题数
Map<String, List<NegativeScorePolice>> group = businessScorePolice.stream().collect(Collectors.groupingBy(NegativeScorePolice::getIdCode));
double[] diffNumbers = group.values().stream().mapToDouble(val -> val.size() - avgNumber).toArray();
// 业务标准差
double sd = calculateSd(diffNumbers, policeSize);
log.info("业务标准差为:{}", sd);
// 业务差异值 // 业务差异值
double diff; double diff;
long personalSize = businessScorePolice.stream().filter(item -> idCode.equals(item.getIdCode())).count(); if (false) {
if (businessTypeEnum.getBusinessVolume()) { String departId = depart.getId();
diff = calculateDiff1(businessScorePolice, police, beginTime, endTime, businessTypeEnum.getValue(), sd); // 如果是4级单位 则找他上级单位
if (depart.getLevel() == 4) {
departId = departService.getById(depart.getPid()).getId();
}
List<BusinessDepart> businessDeparts = businessDepartService.list(beginTime, endTime, departId, businessTypeEnum.getValue());
// 单位总业务量
int totalBusinessSize = businessDeparts.stream().mapToInt(BusinessDepart::getNumber).sum();
log.info("单位总业务量 = {}", totalBusinessSize);
// 平均加权问题发生率
double avgNumber = calculateAvgNumber(businessWeightScore, totalBusinessSize);
log.info("平均加权问题发生率 = {}", avgNumber);
Map<String, List<NegativeScorePolice>> group = businessScorePolice.stream().collect(Collectors.groupingBy(NegativeScorePolice::getIdCode));
double[] diffNumbers = group.values().stream().mapToDouble(val -> {
if (totalBusinessSize == 0) {
return -avgNumber;
}
return (val.stream().mapToDouble(NegativeScorePolice::getScore).sum() / totalBusinessSize) - avgNumber;
}).toArray();
// 业务标准差
double sd = calculateSd1(diffNumbers, policeSize);
double rate = personalScore / totalBusinessSize;
log.info("个人问题发生率 = {} / {}", personalScore, totalBusinessSize);
log.info("个人问题发生率 = {}", rate);
diff = calculateDiff1(personalScore / totalBusinessSize, avgNumber, sd);
} else { } else {
diff = calculateDiff2(personalSize, avgNumber, sd); remarks.append(String.format("业务涉及人数 %s", policeSize));
// 业务平均加权问题数
double avgNumber = calculateAvgNumber(businessWeightScore, policeSize);
// 差值集合 = 个人问题数 - 平均问题数
Map<String, List<NegativeScorePolice>> group = businessScorePolice.stream().collect(Collectors.groupingBy(NegativeScorePolice::getIdCode));
double[] diffNumbers = group.values().stream().mapToDouble(val -> val.stream().mapToDouble(NegativeScorePolice::getScore).sum() - avgNumber).toArray();
// 业务标准差
double sd = calculateSd2(diffNumbers, policeSize);
log.info("业务标准差为 = {}", sd);
diff = calculateDiff2(personalScore, avgNumber, sd);
} }
log.info("业务差异值为:{}", diff); log.info("业务差异值为 = {}", diff);
// 业务风险指数 // 业务风险指数
double businessScore = calculateBusinessScore(diff, personalSize); double businessScore = calculateBusinessScore(diff, personalScore);
log.info("业务风险指数:{}", businessScore);
// 业务权重 // 业务权重
Double score = businessScorePolice.stream().mapToDouble(NegativeScorePolice::getScore).sum(); Double score = businessScorePolice.stream().mapToDouble(NegativeScorePolice::getScore).sum();
double businessWeight = calculateBusinessWeight(totalScore, score); double businessWeight = calculateBusinessWeight(score, totalScore);
expressionArr.add(String.format("(%s * %s)", businessScore, businessWeight)); expressionArr.add(String.format("(%s * %s)", businessScore, businessWeight));
remarks.append(String.format("%s:", businessTypeEnum.getLabel())).append("\n"); remarks.append(String.format("%s:", businessTypeEnum.getLabel())).append("\n");
remarks.append(String.format("业务涉及人数 %s", policeSize)).append("\n"); remarks.append(String.format("业务涉及人数 %s", policeSize)).append("\n");
remarks.append(String.format("业务问题数 %s", businessSize)).append("\n"); remarks.append(String.format("业务问题数 %s", businessWeightScore)).append("\n");
remarks.append(String.format("平均问题数 %s", avgNumber)).append("\n");
remarks.append(String.format("业务标准差 %s", sd)).append("\n");
remarks.append(String.format("业务差异值 %s", diff)).append("\n"); remarks.append(String.format("业务差异值 %s", diff)).append("\n");
log.info("业务风险指数 = {}", businessScore);
log.info("业务权重 = {}", businessWeight);
log.info("单个业务风险指数 = {} * {}", businessScore, businessWeight);
log.info("单个业务结束-------------------------------------------------------------------", businessTypeEnum.getLabel());
return NumberUtil.mul(businessScore, businessWeight); return NumberUtil.mul(businessScore, businessWeight);
}).sum(); }).sum();
BigDecimal score = NumberUtil.roundHalfEven(policeScore, 2); BigDecimal score = NumberUtil.roundHalfEven(policeScore, 2);
@ -288,35 +306,46 @@ public class NegativeScoreService {
StringBuilder remarks = new StringBuilder(); StringBuilder remarks = new StringBuilder();
double policeScore = Arrays.stream(BusinessTypeEnum.values()).mapToDouble(businessTypeEnum -> { double policeScore = Arrays.stream(BusinessTypeEnum.values()).mapToDouble(businessTypeEnum -> {
List<NegativeScoreDepart> businessScoreDeparts = scoreDeparts.stream().filter(item -> item.getBusinessTypeCode().equals(businessTypeEnum.getValue())).toList(); List<NegativeScoreDepart> businessScoreDeparts = scoreDeparts.stream().filter(item -> item.getBusinessTypeCode().equals(businessTypeEnum.getValue())).toList();
// 业务加权问题数
double businessWeightScore = businessScoreDeparts.stream().mapToDouble(NegativeScoreDepart::getScore).sum();
// 业务涉及人数 // 业务涉及人数
int departSize = businessScoreDeparts.stream().map(NegativeScoreDepart::getDepartId).collect(Collectors.toSet()).size(); int departSize = businessScoreDeparts.stream().map(NegativeScoreDepart::getDepartId).collect(Collectors.toSet()).size();
// 当前部门问题数 // 业务加权问题数(风险指数)
long personalSize = businessScoreDeparts.stream().filter(item -> departId.equals(item.getDepartId())).count(); double personalScore = businessScoreDeparts.stream().filter(item -> departId.equals(item.getDepartId())).mapToDouble(NegativeScoreDepart::getScore).sum();
// 平均问题数
double avgNumber = calculateAvgNumber(businessScoreDeparts.size(), departSize);
// 差值集合 = 个人问题数 - 平均问题数
Map<String, List<NegativeScoreDepart>> group = businessScoreDeparts.stream().collect(Collectors.groupingBy(NegativeScoreDepart::getDepartId));
double[] diffNumbers = group.values().stream().mapToDouble(val -> val.size() - avgNumber).toArray();
// 业务标准差
double sd = calculateSd(diffNumbers, departSize);
// 业务差异值 // 业务差异值
double diff; double diff;
if (businessTypeEnum.getBusinessVolume()) { if (false) {
diff = calculateDiff1ByDepart(businessScoreDeparts, departId, beginTime, endTime, businessTypeEnum.getValue(), sd); List<BusinessDepart> businessDeparts = businessDepartService.list(beginTime, endTime, departId, businessTypeEnum.getValue());
// 总业务量
int totalBusinessSize = businessDeparts.stream().mapToInt(BusinessDepart::getNumber).sum();
// 平均加权问题发生率
double avgNumber = calculateAvgNumber(businessWeightScore, totalBusinessSize);
Map<String, List<NegativeScoreDepart>> group = businessScoreDeparts.stream().collect(Collectors.groupingBy(NegativeScoreDepart::getDepartId));
double[] diffNumbers = group.values().stream().mapToDouble(val -> val.stream().mapToDouble(NegativeScoreDepart::getScore).sum() - avgNumber).toArray();
// 业务标准差
double sd = calculateSd1(diffNumbers, departSize);
log.info("");
diff = calculateDiff1(personalScore, avgNumber, sd);
} else { } else {
// 当前部门问题数
long personalSize = businessScoreDeparts.stream().filter(item -> departId.equals(item.getDepartId())).count();
// 平均问题数
double avgNumber = calculateAvgNumber(businessScoreDeparts.size(), departSize);
// 差值集合 = 个人问题数 - 平均问题数
Map<String, List<NegativeScoreDepart>> group = businessScoreDeparts.stream().collect(Collectors.groupingBy(NegativeScoreDepart::getDepartId));
double[] diffNumbers = group.values().stream().mapToDouble(val -> val.size() - avgNumber).toArray();
// 业务标准差
double sd = calculateSd2(diffNumbers, departSize);
diff = calculateDiff2(personalSize, avgNumber, sd); diff = calculateDiff2(personalSize, avgNumber, sd);
} }
// 业务风险指数 // 业务风险指数
double businessScore = calculateBusinessScore(diff, personalSize); double businessScore = calculateBusinessScore(diff, personalScore);
// 业务权重 // 业务权重
Double score = businessScoreDeparts.stream().mapToDouble(NegativeScoreDepart::getScore).sum(); Double score = businessScoreDeparts.stream().mapToDouble(NegativeScoreDepart::getScore).sum();
double businessWeight = calculateBusinessWeight(totalScore, score); double businessWeight = calculateBusinessWeight(score, totalScore);
expressionArr.add(String.format("(%s * %s)", businessScore, businessWeight)); expressionArr.add(String.format("(%s * %s)", businessScore, businessWeight));
remarks.append(String.format("%s:", businessTypeEnum.getLabel())).append("\n"); remarks.append(String.format("%s:", businessTypeEnum.getLabel())).append("\n");
remarks.append(String.format("业务涉及人数 %s", departSize)).append("\n"); remarks.append(String.format("业务涉及人数 %s", departSize)).append("\n");
remarks.append(String.format("当前部门问题数 %s", personalSize)).append("\n");
remarks.append(String.format("平均问题数 %s", avgNumber)).append("\n");
remarks.append(String.format("业务标准差 %s", sd)).append("\n");
remarks.append(String.format("业务差异值 %s", diff)).append("\n"); remarks.append(String.format("业务差异值 %s", diff)).append("\n");
return NumberUtil.mul(businessScore, businessWeight); return NumberUtil.mul(businessScore, businessWeight);
}).sum(); }).sum();

2
src/main/java/com/biutag/supervision/support/ModelClueDistributionAware.java

@ -51,7 +51,7 @@ public class ModelClueDistributionAware {
log.info("新增模型【{}】分发任务", model.getModelName()); log.info("新增模型【{}】分发任务", model.getModelName());
String expression = model.getDistributionCycleExpression(); String expression = model.getDistributionCycleExpression();
if (StrUtil.isBlank(expression)) { if (StrUtil.isBlank(expression)) {
throw new RuntimeException("分发周期配置[expression]为空"); return;
} }
if (taskMap.containsKey(model.getId())) { if (taskMap.containsKey(model.getId())) {
remove(model.getId()); remove(model.getId());

6
src/main/resources/application-local.yml

@ -19,9 +19,9 @@ spring:
port: 6379 port: 6379
password: 123456 password: 123456
mybatis-plus: #mybatis-plus:
configuration: # configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
fdfs: fdfs:
tracker-list: #TrackerList参数,支持多个 tracker-list: #TrackerList参数,支持多个

2
src/main/resources/mapper/ProfilePoliceMapper.xml

@ -28,7 +28,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="departGroupId != null and departGroupId != ''"> <if test="departGroupId != null and departGroupId != ''">
AND d.statistics_group_id = #{departGroupId} AND d.statistics_group_id = #{departGroupId}
</if> </if>
AND pc.score > 0
<if test="name != null and name != ''"> <if test="name != null and name != ''">
AND p.name like concat('%', #{name}, '%') AND p.name like concat('%', #{name}, '%')
</if> </if>

41
src/test/java/com/biutag/supervision/tools/ExcelTest.java

@ -0,0 +1,41 @@
package com.biutag.supervision.tools;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.biutag.supervision.pojo.dto.DataCaseVerifImportDto;
import com.biutag.supervision.pojo.entity.SupDepart;
import jakarta.validation.ConstraintViolation;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author wxc
* @date 2024/11/13
*/
public class ExcelTest {
public void test() throws FileNotFoundException {
File file = new File("");
ExcelReader excelReader = EasyExcel.read(new FileInputStream(file), HdtExcelDto.class, new ReadListener<DataCaseVerifImportDto>() {
@Override
public void invoke(DataCaseVerifImportDto data, AnalysisContext analysisContext) {
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}).build();
}
}

2
src/test/java/com/biutag/supervision/tools/GenCodeTests.java

@ -25,7 +25,7 @@ public class GenCodeTests {
@Test @Test
public void genEntity() throws TemplateException, IOException { public void genEntity() throws TemplateException, IOException {
String tableName = "depart_score"; String tableName = "risk_model_task_clue";
String tableSchema = "negative"; String tableSchema = "negative";
boolean genMapper = true; boolean genMapper = true;
boolean genService = true; boolean genService = true;

26
src/test/java/com/biutag/supervision/tools/HdtExcelDto.java

@ -0,0 +1,26 @@
package com.biutag.supervision.tools;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
/**
* @author wxc
* @date 2024/11/13
*/
@Setter
@Getter
public class HdtExcelDto {
@ExcelProperty("姓名")
private String departId;
@ExcelProperty("部门")
private String departName;
@ExcelProperty("姓名")
private LocalDateTime discoveryTime;
}
Loading…
Cancel
Save