diff --git a/sql/1114.sql b/sql/1114.sql new file mode 100644 index 0000000..2feba64 --- /dev/null +++ b/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='个人极端赋分规则'; diff --git a/src/main/java/com/biutag/supervision/constants/AppConstants.java b/src/main/java/com/biutag/supervision/constants/AppConstants.java index 8fdbdb4..6d67389 100644 --- a/src/main/java/com/biutag/supervision/constants/AppConstants.java +++ b/src/main/java/com/biutag/supervision/constants/AppConstants.java @@ -2,7 +2,7 @@ package com.biutag.supervision.constants; 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"; diff --git a/src/main/java/com/biutag/supervision/controller/sensitivePerception/ModelController.java b/src/main/java/com/biutag/supervision/controller/sensitivePerception/ModelController.java index 49a15ce..9911300 100644 --- a/src/main/java/com/biutag/supervision/controller/sensitivePerception/ModelController.java +++ b/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 com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 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.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.vo.ModelTree; -import com.biutag.supervision.service.ModelClassService; import com.biutag.supervision.service.ModelService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -24,7 +24,7 @@ public class ModelController { private final ModelService modelService; - private final ModelClassService modelClassService; + private final ModelClassMapper modelClassMapper; @GetMapping public Result> list(ModelQueryParam queryParam) { @@ -39,13 +39,14 @@ public class ModelController { @GetMapping("tree") public Result> tree() { - List modelClasses = modelClassService.list(); + List modelClasses = modelClassMapper.selectListAll(); List models = modelService.list(); List list = new ArrayList<>(); list.addAll(modelClasses.stream().map(item -> { ModelTree node = new ModelTree(); node.setValue(item.getId()); node.setLabel(item.getName()); + node.setSize(item.getSize()); node.setType("modelClass"); List children = models.stream().filter(model -> item.getId().equals(model.getClassId())).map(ModelTree::of).toList(); node.setChildren(children); @@ -57,7 +58,6 @@ public class ModelController { @PostMapping public Result add(@RequestBody Model model) { - return Result.success(modelService.saveModel(model)); } diff --git a/src/main/java/com/biutag/supervision/controller/sensitivePerception/RiskScoreRuleController.java b/src/main/java/com/biutag/supervision/controller/sensitivePerception/RiskScoreRuleController.java new file mode 100644 index 0000000..ca965aa --- /dev/null +++ b/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() { + return Result.success(riskScoreRuleService.buildTree()); + } + + @PostMapping + public Result add(@RequestBody RiskScoreRule scoreRule) { + scoreRule.setCreateTime(LocalDateTime.now()); + scoreRule.setUpdateTime(LocalDateTime.now()); + return Result.success(riskScoreRuleService.save(scoreRule)); + } + + @PutMapping + public Result update(@RequestBody RiskScoreRule scoreRule) { + scoreRule.setUpdateTime(LocalDateTime.now()); + return Result.success(riskScoreRuleService.updateById(scoreRule)); + } + + @DeleteMapping("{id}") + public Result update(@PathVariable Integer id) { + return Result.success(riskScoreRuleService.removeById(id)); + } + +} diff --git a/src/main/java/com/biutag/supervision/mapper/ModelClassMapper.java b/src/main/java/com/biutag/supervision/mapper/ModelClassMapper.java index 8db59f1..c5ce565 100644 --- a/src/main/java/com/biutag/supervision/mapper/ModelClassMapper.java +++ b/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.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 { + @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 selectListAll(); + } \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/pojo/entity/Model.java b/src/main/java/com/biutag/supervision/pojo/entity/Model.java index aa66988..ceae6c5 100644 --- a/src/main/java/com/biutag/supervision/pojo/entity/Model.java +++ b/src/main/java/com/biutag/supervision/pojo/entity/Model.java @@ -91,4 +91,6 @@ public class Model { @TableField("model_sql") private String modelSql; + + private Integer riskScoreRuleId; } \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/pojo/model/ModelClassModel.java b/src/main/java/com/biutag/supervision/pojo/model/ModelClassModel.java new file mode 100644 index 0000000..fbfd6ac --- /dev/null +++ b/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; + +} diff --git a/src/main/java/com/biutag/supervision/pojo/vo/MenuTree.java b/src/main/java/com/biutag/supervision/pojo/vo/MenuTree.java index 0350ebd..ffb622b 100644 --- a/src/main/java/com/biutag/supervision/pojo/vo/MenuTree.java +++ b/src/main/java/com/biutag/supervision/pojo/vo/MenuTree.java @@ -52,7 +52,7 @@ public class MenuTree { private List children; public static List buildTree(List list) { - return buildTree(list, AppConstants.MENU_ROOT_ID); + return buildTree(list, AppConstants.TREE_ROOT_ID); } public static List buildTree(List list, Integer pid) { diff --git a/src/main/java/com/biutag/supervision/pojo/vo/ModelTree.java b/src/main/java/com/biutag/supervision/pojo/vo/ModelTree.java index 05db427..688d766 100644 --- a/src/main/java/com/biutag/supervision/pojo/vo/ModelTree.java +++ b/src/main/java/com/biutag/supervision/pojo/vo/ModelTree.java @@ -21,6 +21,8 @@ public class ModelTree { private String type; + private Integer size; + private List children = new ArrayList<>(); public static ModelTree of(Model model) { diff --git a/src/main/java/com/biutag/supervision/pojo/vo/RiskScoreRuleTree.java b/src/main/java/com/biutag/supervision/pojo/vo/RiskScoreRuleTree.java new file mode 100644 index 0000000..aa7f539 --- /dev/null +++ b/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 children = new ArrayList<>(); +} diff --git a/src/main/java/com/biutag/supervision/service/BusinessDepartService.java b/src/main/java/com/biutag/supervision/service/BusinessDepartService.java index 9e8a50c..46f44a7 100644 --- a/src/main/java/com/biutag/supervision/service/BusinessDepartService.java +++ b/src/main/java/com/biutag/supervision/service/BusinessDepartService.java @@ -278,7 +278,9 @@ public class BusinessDepartService extends ServiceImpl list(Date beginTime, Date endTime, String businessType) { - return list(new LambdaQueryWrapper().between(BusinessDepart::getDate, beginTime, endTime).eq(BusinessDepart::getBusinessType, businessType)); + public List list(Date beginTime, Date endTime, String departId, String businessType) { + return list(new LambdaQueryWrapper().between(BusinessDepart::getDate, beginTime, endTime) + .eq(BusinessDepart::getDepartId, departId) + .eq(BusinessDepart::getBusinessType, businessType)); } } diff --git a/src/main/java/com/biutag/supervision/service/ModelClassService.java b/src/main/java/com/biutag/supervision/service/ModelClassService.java index 37a42bc..6e78464 100644 --- a/src/main/java/com/biutag/supervision/service/ModelClassService.java +++ b/src/main/java/com/biutag/supervision/service/ModelClassService.java @@ -8,4 +8,5 @@ import org.springframework.stereotype.Service; @Service public class ModelClassService extends ServiceImpl { + } diff --git a/src/main/java/com/biutag/supervision/service/ModelService.java b/src/main/java/com/biutag/supervision/service/ModelService.java index 884d0e0..4e470fd 100644 --- a/src/main/java/com/biutag/supervision/service/ModelService.java +++ b/src/main/java/com/biutag/supervision/service/ModelService.java @@ -1,5 +1,6 @@ package com.biutag.supervision.service; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.biutag.supervision.common.UserContextHolder; @@ -24,7 +25,7 @@ public class ModelService extends ServiceImpl { } 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()) : ExpressionBuilder.build(model.getDistributionCycleTime(), model.getDistributionCycleDayOfWeek()); model.setDistributionCycleExpression(expression); @@ -39,7 +40,7 @@ public class ModelService extends ServiceImpl { } 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()) : ExpressionBuilder.build(model.getDistributionCycleTime(), model.getDistributionCycleDayOfWeek()); model.setDistributionCycleExpression(expression); diff --git a/src/main/java/com/biutag/supervision/service/NegativeScoreService.java b/src/main/java/com/biutag/supervision/service/NegativeScoreService.java index a1899cc..5ebb868 100644 --- a/src/main/java/com/biutag/supervision/service/NegativeScoreService.java +++ b/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 lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.math.BigDecimal; @@ -116,90 +115,77 @@ public class NegativeScoreService { System.out.println("calculateScore-------------------------------------------------End"); } - - private final BusinessPoliceService businessPoliceService; - private final BusinessDepartService businessDepartService; private final SupPoliceService policeService; // 业务权重 = 单个业务风险指数 / 总业务风险指数之和 - public double calculateBusinessWeight(Double totalScore, Double score) { + public double calculateBusinessWeight(Double score, Double totalScore) { if (totalScore == 0) { return 0.0; } - + log.info("业务权重 = {} / {}", score, totalScore); return NumberUtil.div(score, totalScore); } - // 平均问题数 = 单个业务问题数 / 业务涉及人数 - public double calculateAvgNumber(int size, int policeSize) { - if (policeSize == 0) { + // 平均问题发生率 = 单个业务问题加权数 / 单位总业务量 + public double calculateAvgNumber(double businessWeightScore, int totalBusinessSize) { + if (totalBusinessSize == 0) { + log.info("平均问题发生率 = 0"); return 0; } - return NumberUtil.div(size, policeSize); + log.info("平均问题发生率 = {} / {}", businessWeightScore, totalBusinessSize); + return NumberUtil.div(businessWeightScore, totalBusinessSize); } + // 业务标准差 = 根号(sum((个人问题数 - 平均问题数)²) / 业务涉及人数) - public double calculateSd(double[] diffNumber, int policeSize) { + public double calculateSd1(double[] diffNumber, int policeSize) { if (policeSize == 0) { + log.info("业务标准差 = 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); } - // 业务差异值1 = (个人问题发生率 - 平均问题发生率) / 业务标准差 - // 平均问题发生率 = 总问题数 / 总业务量 - // 个人问题发生率 = 个人问题数 / 个人业务量 - public double calculateDiff1(List businessScorePolice, SupPolice police, Date beginTime, Date endTime, String businessTypeCode, double sd) { - if (sd == 0) { + // 业务标准差 = 根号(sum((个人问题数 - 平均问题数)²) / 业务涉及人数) + public double calculateSd2(double[] diffNumber, int policeSize) { + if (policeSize == 0) { + log.info("业务标准差 = 0"); return 0; } - List businessDeparts = businessDepartService.list(beginTime, endTime, businessTypeCode); - // 总业务量 - 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); + 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); } - public double calculateDiff1ByDepart(List businessScoreDeparts, String departId, Date beginTime, Date endTime, String businessTypeCode, double sd) { + // 业务差异值1 = (个人问题发生率 - 平均问题发生率) / 业务标准差 + // 平均问题发生率 = 总问题数 / 总业务量 + // 个人问题发生率 = 个人问题数 / 个人业务量 + public double calculateDiff1(double personalRate, double avgNumber, double sd) { if (sd == 0) { + log.info("业务差异值(发生率) = 0"); return 0; } - List businessDeparts = businessDepartService.list(beginTime, endTime, businessTypeCode); - // 总业务量 - 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); + log.info("业务差异值(发生率) = ({} - {}) / {}", personalRate, avgNumber, sd); + return NumberUtil.div(personalRate - avgNumber, sd); } - // 业务差异值2 = (问题数 - 平均问题数) / 业务标准差 - public double calculateDiff2(long personalSize, double avgNumber, double sd) { + // 业务差异值2 = (加权问题数 - 平均问题数) / 业务标准差 + public double calculateDiff2(double personalScore, double avgNumber, double sd) { if (sd == 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) { return 0; } - return 50 + (diff * 15); + log.info("单个业务风险指数 = 50 + ({} * 5)", diff); + return 50 + (diff * 5); } private final SupDepartService departService; @@ -228,43 +214,75 @@ public class NegativeScoreService { List expressionArr = new ArrayList<>(); StringBuilder remarks = new StringBuilder(); double policeScore = Arrays.stream(BusinessTypeEnum.values()).mapToDouble(businessTypeEnum -> { + log.info("业务 【{}】 开始-------------------------------------------------------------------", businessTypeEnum.getLabel()); List 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(); - remarks.append(String.format("业务设计人数 %s", policeSize)); - // 业务问题数 - int businessSize = businessScorePolice.size(); - //--------------------------------------------------------- - // 平均问题数 - double avgNumber = calculateAvgNumber(businessSize, policeSize); - // 差值集合 = 个人问题数 - 平均问题数 - Map> 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); + log.info("业务涉及人数 = {}", policeSize); + // 业务加权问题数(风险指数) + double personalScore = businessScorePolice.stream().filter(item -> idCode.equals(item.getIdCode())).mapToDouble(NegativeScorePolice::getScore).sum(); + log.info("个人业务加权问题数 = {}", personalScore); // 业务差异值 double diff; - long personalSize = businessScorePolice.stream().filter(item -> idCode.equals(item.getIdCode())).count(); - if (businessTypeEnum.getBusinessVolume()) { - diff = calculateDiff1(businessScorePolice, police, beginTime, endTime, businessTypeEnum.getValue(), sd); + if (false) { + String departId = depart.getId(); + // 如果是4级单位 则找他上级单位 + if (depart.getLevel() == 4) { + departId = departService.getById(depart.getPid()).getId(); + } + List 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> 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 { - diff = calculateDiff2(personalSize, avgNumber, sd); + remarks.append(String.format("业务涉及人数 %s", policeSize)); + // 业务平均加权问题数 + double avgNumber = calculateAvgNumber(businessWeightScore, policeSize); + // 差值集合 = 个人问题数 - 平均问题数 + Map> 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); - log.info("业务风险指数:{}", businessScore); + double businessScore = calculateBusinessScore(diff, personalScore); + // 业务权重 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)); remarks.append(String.format("%s:", businessTypeEnum.getLabel())).append("\n"); remarks.append(String.format("业务涉及人数 %s", policeSize)).append("\n"); - remarks.append(String.format("业务问题数 %s", businessSize)).append("\n"); - remarks.append(String.format("平均问题数 %s", avgNumber)).append("\n"); - remarks.append(String.format("业务标准差 %s", sd)).append("\n"); + remarks.append(String.format("业务问题数 %s", businessWeightScore)).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); }).sum(); BigDecimal score = NumberUtil.roundHalfEven(policeScore, 2); @@ -288,35 +306,46 @@ public class NegativeScoreService { StringBuilder remarks = new StringBuilder(); double policeScore = Arrays.stream(BusinessTypeEnum.values()).mapToDouble(businessTypeEnum -> { List 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(); - // 当前部门问题数 - long personalSize = businessScoreDeparts.stream().filter(item -> departId.equals(item.getDepartId())).count(); - // 平均问题数 - double avgNumber = calculateAvgNumber(businessScoreDeparts.size(), departSize); - // 差值集合 = 个人问题数 - 平均问题数 - Map> 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 personalScore = businessScoreDeparts.stream().filter(item -> departId.equals(item.getDepartId())).mapToDouble(NegativeScoreDepart::getScore).sum(); // 业务差异值 double diff; - if (businessTypeEnum.getBusinessVolume()) { - diff = calculateDiff1ByDepart(businessScoreDeparts, departId, beginTime, endTime, businessTypeEnum.getValue(), sd); + if (false) { + List businessDeparts = businessDepartService.list(beginTime, endTime, departId, businessTypeEnum.getValue()); + // 总业务量 + int totalBusinessSize = businessDeparts.stream().mapToInt(BusinessDepart::getNumber).sum(); + // 平均加权问题发生率 + double avgNumber = calculateAvgNumber(businessWeightScore, totalBusinessSize); + Map> 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 { + // 当前部门问题数 + long personalSize = businessScoreDeparts.stream().filter(item -> departId.equals(item.getDepartId())).count(); + // 平均问题数 + double avgNumber = calculateAvgNumber(businessScoreDeparts.size(), departSize); + // 差值集合 = 个人问题数 - 平均问题数 + Map> 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); } // 业务风险指数 - double businessScore = calculateBusinessScore(diff, personalSize); + double businessScore = calculateBusinessScore(diff, personalScore); // 业务权重 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)); remarks.append(String.format("%s:", businessTypeEnum.getLabel())).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"); return NumberUtil.mul(businessScore, businessWeight); }).sum(); diff --git a/src/main/java/com/biutag/supervision/support/ModelClueDistributionAware.java b/src/main/java/com/biutag/supervision/support/ModelClueDistributionAware.java index 854487c..719eb16 100644 --- a/src/main/java/com/biutag/supervision/support/ModelClueDistributionAware.java +++ b/src/main/java/com/biutag/supervision/support/ModelClueDistributionAware.java @@ -51,7 +51,7 @@ public class ModelClueDistributionAware { log.info("新增模型【{}】分发任务", model.getModelName()); String expression = model.getDistributionCycleExpression(); if (StrUtil.isBlank(expression)) { - throw new RuntimeException("分发周期配置[expression]为空"); + return; } if (taskMap.containsKey(model.getId())) { remove(model.getId()); diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 506acbc..7c967c0 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -19,9 +19,9 @@ spring: port: 6379 password: 123456 -mybatis-plus: - configuration: - log-impl: org.apache.ibatis.logging.stdout.StdOutImpl +#mybatis-plus: +# configuration: +# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl fdfs: tracker-list: #TrackerList参数,支持多个 diff --git a/src/main/resources/mapper/ProfilePoliceMapper.xml b/src/main/resources/mapper/ProfilePoliceMapper.xml index a13a5cd..12b9e6a 100644 --- a/src/main/resources/mapper/ProfilePoliceMapper.xml +++ b/src/main/resources/mapper/ProfilePoliceMapper.xml @@ -28,7 +28,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND d.statistics_group_id = #{departGroupId} - AND pc.score > 0 + AND p.name like concat('%', #{name}, '%') diff --git a/src/test/java/com/biutag/supervision/tools/ExcelTest.java b/src/test/java/com/biutag/supervision/tools/ExcelTest.java new file mode 100644 index 0000000..dc24199 --- /dev/null +++ b/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() { + @Override + public void invoke(DataCaseVerifImportDto data, AnalysisContext analysisContext) { + + + } + + @Override + public void doAfterAllAnalysed(AnalysisContext analysisContext) { + + } + }).build(); + } +} diff --git a/src/test/java/com/biutag/supervision/tools/GenCodeTests.java b/src/test/java/com/biutag/supervision/tools/GenCodeTests.java index f57ee08..b9769ae 100644 --- a/src/test/java/com/biutag/supervision/tools/GenCodeTests.java +++ b/src/test/java/com/biutag/supervision/tools/GenCodeTests.java @@ -25,7 +25,7 @@ public class GenCodeTests { @Test public void genEntity() throws TemplateException, IOException { - String tableName = "depart_score"; + String tableName = "risk_model_task_clue"; String tableSchema = "negative"; boolean genMapper = true; boolean genService = true; diff --git a/src/test/java/com/biutag/supervision/tools/HdtExcelDto.java b/src/test/java/com/biutag/supervision/tools/HdtExcelDto.java new file mode 100644 index 0000000..bf6a5f7 --- /dev/null +++ b/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; + +}