Parcourir la source

评分接口-分值计算优化

songxinlu il y a 3 ans
Parent
commit
b7098b4598

+ 17 - 0
common/src/main/java/com/lantone/common/vo/analyze/QcCasesHospitalVO.java

@@ -0,0 +1,17 @@
+package com.lantone.common.vo.analyze;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Description:模块对应分值对象
+ * @Author songxl
+ * @Date 2021/9/23
+ */
+@Data
+public class QcCasesHospitalVO {
+    @ApiModelProperty(value = "模块ID")
+    private Long casesId;
+    @ApiModelProperty(value = "模块总分")
+    private Long score;
+}

+ 344 - 0
security-center/src/main/java/com/lantone/security/facade/analyze/compute/AlgorithmFacade_New.java

@@ -0,0 +1,344 @@
+package com.lantone.security.facade.analyze.compute;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Range;
+import com.lantone.common.dto.analyze.AlgorithmDTO;
+import com.lantone.common.enums.IsDeleteEnum;
+import com.lantone.common.exception.Asserts;
+import com.lantone.common.util.BigDecimalUtil;
+import com.lantone.common.util.ListUtil;
+import com.lantone.common.util.StringUtil;
+import com.lantone.common.vo.analyze.AlgorithmVO;
+import com.lantone.common.vo.analyze.MedQcresultCasesVO;
+import com.lantone.common.vo.analyze.QcCasesHospitalVO;
+import com.lantone.common.vo.analyze.QcResultAlgVO;
+import com.lantone.dblayermbg.entity.HospitalSet;
+import com.lantone.dblayermbg.entity.analyze.MedQcresultDetail;
+import com.lantone.dblayermbg.facade.HospitalSetFacade;
+import com.lantone.dblayermbg.facade.analyze.MedQcresultDetailFacade;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 评分算法
+ * @author: gaodm
+ * @time: 2020/4/14 9:52
+ */
+@Component
+public class AlgorithmFacade_New {
+    private final static List<Integer> types = Arrays.asList(0, 1, 2, 3, 4);
+
+    @Autowired
+    private HospitalSetFacade sysHospitalSetFacade;
+    @Autowired
+    private MedQcresultDetailFacade qcresultDetailFacade;
+    @Autowired
+    private HospitalSetFacade hospitalSetFacade;
+
+
+    /**
+     * 评结果分数
+     *
+     * @param algorithmVO 操作条目的所有信息
+     * @return 评分结果对象
+     */
+    public AlgorithmDTO getScoreDto(AlgorithmVO algorithmVO) {
+        AlgorithmDTO algorithmDTO = new AlgorithmDTO();
+        if (!types.contains(algorithmVO.getType())) {
+            Asserts.fail("操作类型只有0,1,2,3,4!");
+        }
+        //处理数据
+        dataDeal(algorithmVO);
+        //获取本医院相关评分配置
+        Map<String, String> scoreSet = hospitalSetFacade.getHospitalCodeMap(algorithmVO.getHospitalId() + "", "score_set");
+        //合格率配置
+        JSONObject qualifiedJSON = JSONObject.parseObject(scoreSet.get("qualified"));
+        //结果等级配置
+        JSONObject resultJSON = JSONObject.parseObject(scoreSet.get("level"));
+        //该医院总分
+        BigDecimal totalScore = new BigDecimal(JSONObject.parseObject(scoreSet.get("score")).getLong("totalScore"));
+        BigDecimal notHomePageScore = new BigDecimal(JSONObject.parseObject(scoreSet.get("score")).getLong("notHomePageScore"));
+        //生成各模块扣分条目map
+        Map<Long, List<QcResultAlgVO>> casesQcResultAlgMap = new HashMap<>();
+        if (ListUtil.isNotEmpty(algorithmVO.getQcResultAlgVOList())) {
+            casesQcResultAlgMap = algorithmVO.getQcResultAlgVOList().stream()
+                    .collect(Collectors.groupingBy(QcResultAlgVO::getCasesId));
+        }
+        if (ListUtil.isNotEmpty(algorithmVO.getQcCasesHospitalVOS())) {
+            //遍历各个模块
+            for (QcCasesHospitalVO qcCasesHospitalVO : algorithmVO.getQcCasesHospitalVOS()) {
+                //计算各个模块分值
+                BigDecimal casesRes = casesCal(casesQcResultAlgMap.get(qcCasesHospitalVO.getCasesId()), qcCasesHospitalVO.getScore());
+                //合格率计算
+                String level = getLevel(qualifiedJSON.getJSONObject(qcCasesHospitalVO.getCasesId() + ""), casesRes.longValue());
+                //添加各个模块要保存的评分结果
+                addSaveQcResultCasesInfo(casesRes, qcCasesHospitalVO.getCasesId(), level, algorithmVO);
+            }
+        }
+        //非病案首页模块分值计算
+        List<QcResultAlgVO> notHomePageQcResultAlg = algorithmVO.getQcResultAlgVOList().stream()
+                .filter(qcResultAlgVO -> !"243".equals(qcResultAlgVO.getCasesId().toString())).collect(Collectors.toList());
+        BigDecimal casesRes = casesCal(notHomePageQcResultAlg, notHomePageScore.longValue());
+        //合格率计算
+        String notHomePageLevel = getLevel(qualifiedJSON.getJSONObject("0"), casesRes.longValue());
+        //添加各个模块要保存的评分结果
+        addSaveQcResultCasesInfo(casesRes, 0l, notHomePageLevel, algorithmVO);
+
+        //总分算分
+        BigDecimal res = casesCal(algorithmVO.getQcResultAlgVOList(), totalScore.longValue());
+        //等级计算
+        String level = getLevel(resultJSON, res.longValue());
+        //结果转为100进制
+        res = res.multiply(new BigDecimal(100))
+                .divide(totalScore, 1, RoundingMode.HALF_UP);
+        algorithmDTO.setLevel(level);
+        algorithmDTO.setScore(res);
+        return algorithmDTO;
+    }
+
+
+    /**
+     * @param casesRes    模块分值
+     * @param casesId     模块id
+     * @param level       合格率
+     * @param algorithmVO 算分对象
+     * @Description拼装要保存的med_qcresult_cases表信息
+     * @Return void
+     */
+    private void addSaveQcResultCasesInfo(BigDecimal casesRes, Long casesId, String level, AlgorithmVO algorithmVO) {
+
+        if (ListUtil.isEmpty(algorithmVO.getMedQcresultCasesVOList())) {
+            algorithmVO.setMedQcresultCasesVOList(new ArrayList<>());
+        }
+        //拼装要保存的med_qcresult_cases 表信息
+        MedQcresultCasesVO medQcresultCasesVOHp = new MedQcresultCasesVO();
+        medQcresultCasesVOHp.setHospitalId(algorithmVO.getHospitalId());
+        medQcresultCasesVOHp.setBehospitalCode(algorithmVO.getBehospitalCode());
+        medQcresultCasesVOHp.setCasesId(casesId);
+        medQcresultCasesVOHp.setScoreRes(casesRes);
+        medQcresultCasesVOHp.setLevel(level);
+        algorithmVO.getMedQcresultCasesVOList().add(medQcresultCasesVOHp);
+    }
+
+
+    /**
+     * 根据分数评定等级
+     *
+     * @param getLevJSON 区间及对应区间等级json
+     * @param value      字符串区间用逗号隔开
+     * @return 等级
+     */
+    private String getLevel(JSONObject getLevJSON, Long value) {
+        if (getLevJSON == null) {
+            return "";
+        }
+        String strSection = getLevJSON.getString("section");
+        String strLevs = getLevJSON.getString("lev");
+        if (StringUtil.isNotBlank(strSection) && StringUtil.isNotBlank(strLevs)) {
+            List<String> sections = Lists.newArrayList(Splitter.on(",").split(strSection));
+            List<String> levs = Lists.newArrayList(Splitter.on(",").split(strLevs));
+            int i = 0;
+            for (; i <= sections.size(); i++) {
+                //区间采用左开右闭原则
+                if (i == 0) {
+                    //(-∞..b]
+                    if (Range.atMost(Long.parseLong(sections.get(i))).contains(value)) {
+                        return getLev(levs, i);
+                    }
+                } else if (i == sections.size()) {
+                    //(a..+∞)
+                    if (Range.greaterThan(Long.parseLong(sections.get(i - 1))).contains(value)) {
+                        return getLev(levs, i);
+                    }
+                } else {
+                    //(a..b]
+                    if (Range.openClosed(Long.parseLong(sections.get(i - 1)), Long.parseLong(sections.get(i))).contains(value)) {
+                        return getLev(levs, i);
+                    }
+                }
+            }
+        }
+        return "";
+    }
+
+    /**
+     * @param levs
+     * @param index
+     * @Description根据位置获取数组指定位置的值
+     * @Return java.lang.String
+     */
+    private String getLev(List<String> levs, int index) {
+        if (Range.closedOpen(0, levs.size()).contains(index)) {
+            return levs.get(index);
+        }
+        return "无对应结果区间";
+    }
+
+    /**
+     * 处理数据
+     *
+     * @param algorithmVO 操作条目的所有信息
+     */
+    private void dataDeal(AlgorithmVO algorithmVO) {
+        List<QcResultAlgVO> qcResultAlgVOList = algorithmVO.getQcResultAlgVOList();
+        //新增
+        if (algorithmVO.getType().equals(1)) {
+            if (null == algorithmVO.getOptResultAlgVO()) {
+                Asserts.fail("新增操作条目不能为空!");
+            }
+            //验证和操作数据
+            if (ListUtil.isNotEmpty(qcResultAlgVOList)) {
+                for (QcResultAlgVO qcResultAlgVO : qcResultAlgVOList) {
+                    if (qcResultAlgVO.getCasesId().equals(algorithmVO.getOptResultAlgVO().getCasesId())
+                            && qcResultAlgVO.getCasesEntryId().equals(algorithmVO.getOptResultAlgVO().getCasesEntryId())) {
+                        Asserts.fail("不能重复加入已经评分的条目");
+                    } else {
+                        if (algorithmVO.getOptResultAlgVO().getCasesId().equals(qcResultAlgVO.getCasesId())) {
+                            algorithmVO.getOptResultAlgVO().setCasesScore(qcResultAlgVO.getCasesScore());
+                        }
+                    }
+                }
+                qcResultAlgVOList.add(algorithmVO.getOptResultAlgVO());
+            }
+            if (ListUtil.isEmpty(qcResultAlgVOList)) {
+                qcResultAlgVOList = new ArrayList<>();
+                qcResultAlgVOList.add(algorithmVO.getOptResultAlgVO());
+                algorithmVO.setQcResultAlgVOList(qcResultAlgVOList);
+            }
+        }
+        //删除
+        else if (algorithmVO.getType().equals(2) || (algorithmVO.getType().equals(4) && 0 == algorithmVO.getDelStatus())) {
+            if (null == algorithmVO.getOptResultAlgVO()) {
+                Asserts.fail("删除操作条目不能为空!");
+            }
+            //操作数据
+            if (ListUtil.isNotEmpty(qcResultAlgVOList)) {
+                Boolean hasData = false;
+                Long optId = algorithmVO.getOptResultAlgVO().getId(); // 操作id
+                for (QcResultAlgVO qcResultAlgVO : qcResultAlgVOList) {
+                    if (qcResultAlgVO.getId().equals(optId)) {
+                        qcResultAlgVOList.remove(qcResultAlgVO);
+                        hasData = true;
+                        break;
+                    }
+                }
+                if (!hasData) {
+                    Asserts.fail("删除的条目不存在!");
+                }
+            }
+        }
+        //恢复
+        else if (algorithmVO.getType().equals(4) && 1 == algorithmVO.getDelStatus()) {
+            if (null == algorithmVO.getOptResultAlgVO()) {
+                Asserts.fail("恢复操作条目不能为空!");
+            }
+            //操作数据
+            Boolean hasData = false;
+            Long optId = algorithmVO.getOptResultAlgVO().getId(); // 操作id
+            MedQcresultDetail qcresultDetail = qcresultDetailFacade.getOne(new QueryWrapper<MedQcresultDetail>()
+                    .eq("id", optId));
+            if (qcresultDetail != null) {
+                QcResultAlgVO qcResultAlgVO = new QcResultAlgVO();
+                qcResultAlgVO.setScore(qcresultDetail.getScore());
+                qcResultAlgVO.setId(qcresultDetail.getId());
+                qcResultAlgVO.setCasesEntryId(qcresultDetail.getCasesEntryId());
+                qcResultAlgVO.setCasesId(qcresultDetail.getCasesId());
+                qcResultAlgVO.setMsg(qcresultDetail.getMsg());
+                qcResultAlgVO.setIsReject(qcresultDetail.getIsReject());
+                qcResultAlgVO.setCasesScore(qcresultDetail.getCasesScore());
+                if (ListUtil.isNotEmpty(qcResultAlgVOList)) {
+                    qcResultAlgVOList.add(qcResultAlgVO);
+                } else {
+                    qcResultAlgVOList = new ArrayList<>();
+                    qcResultAlgVOList.add(qcResultAlgVO);
+                    algorithmVO.setQcResultAlgVOList(qcResultAlgVOList);
+                }
+                hasData = true;
+            }
+            if (!hasData) {
+                Asserts.fail("恢复的条目不存在!");
+            }
+        }
+
+        //修改
+        else if (algorithmVO.getType().equals(3)) {
+            if (null == algorithmVO.getOptResultAlgVO()) {
+                Asserts.fail("修改操作条目不能为空!");
+            }
+            //操作数据
+            if (ListUtil.isNotEmpty(qcResultAlgVOList)) {
+                Boolean hasData = false;
+                for (QcResultAlgVO qcResultAlgVO : qcResultAlgVOList) {
+                    if (qcResultAlgVO.getId().equals(algorithmVO.getOptResultAlgVO().getId())) {
+                        qcResultAlgVOList.remove(qcResultAlgVO);
+                        qcResultAlgVOList.add(algorithmVO.getOptResultAlgVO());
+                        hasData = true;
+                        break;
+                    }
+                }
+                if (!hasData) {
+                    Asserts.fail("修改的条目不存在!");
+                }
+            }
+        }
+    }
+
+    /**
+     * 计算分数
+     *
+     * @param qcResultAlgVOList 扣分条目
+     * @return 评分分数
+     */
+    private BigDecimal casesCal(List<QcResultAlgVO> qcResultAlgVOList, Long totalScore) {
+        //总分
+        BigDecimal res = new BigDecimal(totalScore);
+        //模块内单票否决扣分
+        BigDecimal subRejectScore = BigDecimal.ZERO;
+        //模块内其他扣分
+        BigDecimal subOrderScore = BigDecimal.ZERO;
+        if (ListUtil.isNotEmpty(qcResultAlgVOList)) {
+            //遍历扣分条目
+            for (QcResultAlgVO qcResultAlgVO : qcResultAlgVOList) {
+                if (qcResultAlgVO.getIsReject().equals(1)) {
+                    //单票否决扣分
+                    subRejectScore = subRejectScore.add(qcResultAlgVO.getScore());
+                } else {
+                    //非单票否决扣分
+                    subOrderScore = subOrderScore.add(qcResultAlgVO.getScore());
+                }
+            }
+            //总分小于等于其他扣分时
+            if (BigDecimalUtil.le(new BigDecimal(totalScore), subOrderScore)) {
+                subOrderScore = new BigDecimal(totalScore);
+            }
+            //模块总分减去模块单票否决扣分
+            res = res.subtract(subRejectScore);
+            //结果小于0按0返回
+            if (BigDecimalUtil.lt(res, BigDecimal.ZERO)) {
+                return BigDecimal.ZERO;
+            } else {
+                //模块总分减去其他扣分
+                res = res.subtract(subOrderScore);
+            }
+            //结果小于0按0计算
+            if (BigDecimalUtil.lt(res, BigDecimal.ZERO)) {
+                res = BigDecimal.ZERO;
+            }
+        }
+        return res;
+    }
+}

Fichier diff supprimé car celui-ci est trop grand
+ 1763 - 0
security-center/src/main/java/com/lantone/security/facade/analyze/compute/BehospitalInfoManagementFacade_New.java