小组团队项目个人博客5.0

今天我制作了判断新添加的数据与历史数据是否相同的功能:“支持录入安全风险项点过程中,自动判断风险库中是否有相似内容,如有相似内容给出合并提示字样,如“本次录入内容与风险库第 15、18 项内容相似或接近,建议进行合并! ”等字样”
代码如下:

mapper层:
//判断是否相似
@Select("SELECT id, riskPoint, controlMeasures FROM risk_management WHERE id != #{id}")
List findAllExceptCurrent(String id);

@Select("SELECT id, riskPoint FROM risk_management WHERE MATCH(riskPoint, controlMeasures) AGAINST(#{keywords} IN NATURAL LANGUAGE MODE)")
List<RiskMangement> fullTextSearch(String keywords);

@Insert("INSERT INTO risk_similarity(risk_id, similar_risk_id, similarity_score) VALUES(#{riskId}, #{similarRiskId}, #{score})")
void saveSimilarity(@Param("riskId") String riskId,
                    @Param("similarRiskId") String similarRiskId,
                    @Param("score") double score);

service层:
@Value("${risk.similarity.threshold:0.7}")
private double similarityThreshold;

// 检查相似风险
public RiskSimilarityCheckResult checkSimilarity(RiskMangement currentRisk) {
    RiskSimilarityCheckResult result = new RiskSimilarityCheckResult();

    // 获取所有风险项(排除当前项)
    List<RiskMangement> allRisks = riskMapper.findAllExceptCurrent(currentRisk.getId());

    // 计算相似度
    List<SimilarRiskDTO> similarRisks = new ArrayList<>();
    for (RiskMangement risk : allRisks) {
        double score = calculateSimilarity(currentRisk, risk);
        if (score >= similarityThreshold) {
            SimilarRiskDTO dto = new SimilarRiskDTO();
            dto.setId(risk.getId());
            dto.setRiskPoint(risk.getRiskPoint());
            dto.setControlMeasures(risk.getControlMeasures());
            dto.setSimilarityScore(score);
            similarRisks.add(dto);

            // 保存相似性记录
            riskMapper.saveSimilarity(currentRisk.getId(), risk.getId(), score);
        }
    }

    result.setHasSimilar(!similarRisks.isEmpty());
    result.setSimilarRisks(similarRisks);

    if (!similarRisks.isEmpty()) {
        String ids = similarRisks.stream()
                .map(SimilarRiskDTO::getId)
                .collect(Collectors.joining("、"));
        result.setMessage(String.format("本次录入内容与风险库第 %s 项内容相似或接近,建议进行合并!", ids));
    }

    return result;
}

// 计算相似度(简化版,实际可以使用更复杂的算法)
private double calculateSimilarity(RiskMangement risk1, RiskMangement risk2) {
    String text1 = risk1.getRiskPoint() + " " + risk1.getControlMeasures();
    String text2 = risk2.getRiskPoint() + " " + risk2.getControlMeasures();

    // 使用Jaccard相似度
    Set<String> words1 = new HashSet<>(Arrays.asList(text1.split("\\s+")));
    Set<String> words2 = new HashSet<>(Arrays.asList(text2.split("\\s+")));

    Set<String> intersection = new HashSet<>(words1);
    intersection.retainAll(words2);

    Set<String> union = new HashSet<>(words1);
    union.addAll(words2);

    return union.isEmpty() ? 0 : (double) intersection.size() / union.size();
}

controller层:
@PostMapping("/check-similarity")
public ResponseEntity checkSimilarity(@RequestBody RiskMangement risk) {
RiskSimilarityCheckResult result = riskservice.checkSimilarity(risk);
return ResponseEntity.ok(result);
}

不过很遗憾的是,代码本身并未报错,可是却无法实现我想要的功能,回头接着再改改


posted @ 2025-04-21 21:43  鱼一直摸  阅读(16)  评论(0)    收藏  举报