|
|
package com.supervision.police.service.impl;
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.lang.Assert;
|
|
|
import cn.hutool.core.util.NumberUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.deepoove.poi.XWPFTemplate;
|
|
|
import com.supervision.common.constant.IndexRuleConstants;
|
|
|
import com.supervision.common.domain.R;
|
|
|
import com.supervision.common.utils.StringUtils;
|
|
|
import com.supervision.constant.JudgeResultEnum;
|
|
|
import com.supervision.neo4j.dto.ResultDTO;
|
|
|
import com.supervision.neo4j.utils.Neo4jUtils;
|
|
|
import com.supervision.police.domain.*;
|
|
|
import com.supervision.police.dto.*;
|
|
|
import com.supervision.police.dto.caseScore.CaseScore;
|
|
|
import com.supervision.police.dto.caseScore.CaseScoreDetailBuilder;
|
|
|
import com.supervision.police.dto.caseScore.CaseScoreDetailDTO;
|
|
|
import com.supervision.police.dto.indexRule.IndexRule;
|
|
|
import com.supervision.police.dto.indexRule.Operand;
|
|
|
import com.supervision.police.dto.indexRule.OperandUnit;
|
|
|
import com.supervision.police.dto.indexRule.RuleCondition;
|
|
|
import com.supervision.police.mapper.*;
|
|
|
import com.supervision.police.mybatis.RowSqlMapper;
|
|
|
import com.supervision.police.service.*;
|
|
|
import com.supervision.utils.CalculationUtil;
|
|
|
import com.supervision.utils.DifyApiUtil;
|
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.neo4j.driver.Driver;
|
|
|
import org.neo4j.driver.Result;
|
|
|
import org.neo4j.driver.Session;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.core.io.Resource;
|
|
|
import org.springframework.core.io.ResourceLoader;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
import java.io.InputStream;
|
|
|
import java.net.URLEncoder;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
import static com.supervision.common.constant.IndexRuleConstants.*;
|
|
|
import static com.supervision.common.constant.NotePromptConstants.TYPE_STRUCTURAL_REASONING;
|
|
|
|
|
|
@Slf4j
|
|
|
@Service
|
|
|
@RequiredArgsConstructor
|
|
|
public class ModelServiceImpl implements ModelService {
|
|
|
|
|
|
private final ResourceLoader resourceLoader;
|
|
|
|
|
|
private final Driver driver;
|
|
|
|
|
|
private final ModelCaseMapper modelCaseMapper;
|
|
|
|
|
|
private final ModelAtomicIndexMapper modelAtomicIndexMapper;
|
|
|
|
|
|
private final ModelAtomicResultMapper modelAtomicResultMapper;
|
|
|
|
|
|
private final ModelIndexMapper modelIndexMapper;
|
|
|
|
|
|
private final ModelIndexResultMapper modelIndexResultMapper;
|
|
|
|
|
|
private final CasePersonMapper casePersonMapper;
|
|
|
|
|
|
private final CaseEvidenceService caseEvidenceService;
|
|
|
|
|
|
private final ModelAtomicResultService modelAtomicResultService;
|
|
|
|
|
|
private final RowSqlMapper rowSqlMapper;
|
|
|
|
|
|
private final ModelIndexService modelIndexService;
|
|
|
|
|
|
private final CaseStatusManageService caseStatusManageService;
|
|
|
|
|
|
private final ModelIndexAtomicRelationService modelIndexAtomicRelationService;
|
|
|
|
|
|
private final NoteRecordService noteRecordService;
|
|
|
|
|
|
@Autowired
|
|
|
private NotePromptService notePromptService;
|
|
|
|
|
|
@Autowired
|
|
|
private EvidenceDirectoryService evidenceDirectoryService;
|
|
|
|
|
|
private final EvidenceCategoryService evidenceCategoryService;
|
|
|
|
|
|
private final CaseEvidencePropertyService caseEvidencePropertyService;
|
|
|
|
|
|
private final DifyApiUtil difyApiUtil;
|
|
|
|
|
|
@Autowired
|
|
|
private ModelCaseService modelCaseService;
|
|
|
|
|
|
@Override
|
|
|
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
|
|
|
public R<?> analyseCase(AnalyseCaseDTO analyseCaseDTO) {
|
|
|
|
|
|
ModelCase modelCase = modelCaseMapper.selectById(analyseCaseDTO.getCaseId());
|
|
|
// 获取案件行为人ID
|
|
|
CasePerson casePerson = casePersonMapper.selectOne(new LambdaQueryWrapper<CasePerson>()
|
|
|
.eq(CasePerson::getCaseId, analyseCaseDTO.getCaseId())
|
|
|
.eq(CasePerson::getCaseActorFlag, 1)
|
|
|
.eq(CasePerson::getRoleCode, "1")
|
|
|
.eq(StrUtil.isNotEmpty(analyseCaseDTO.getLawActorName()), CasePerson::getName, analyseCaseDTO.getLawActorName()));
|
|
|
if (ObjectUtil.isEmpty(casePerson)) {
|
|
|
throw new RuntimeException("未找到的行为人" + analyseCaseDTO.getLawActorName());
|
|
|
}
|
|
|
// 首先将原先的值进行赋值,设置到pre_result
|
|
|
modelIndexResultMapper.updatePreResult(analyseCaseDTO.getCaseId());
|
|
|
//原子指标
|
|
|
List<ModelAtomicIndex> atomicIndices = modelAtomicIndexMapper.selectByCaseType(modelCase.getCaseType());
|
|
|
// 存放原子指标的结果,key:原子指标ID,value:(key大指标ID,value:结果)
|
|
|
Map<String, Map<String, String>> atomicResultMap = new HashMap<>();
|
|
|
for (ModelAtomicIndex atomicIndex : atomicIndices) {
|
|
|
//原子指标结果
|
|
|
ModelAtomicResult result = new ModelAtomicResult();
|
|
|
result.setCasePersonId(casePerson.getId());
|
|
|
result.setCaseId(analyseCaseDTO.getCaseId());
|
|
|
result.setAtomicId(atomicIndex.getId());
|
|
|
//查询语句
|
|
|
String ql = atomicIndex.getQueryLang();
|
|
|
|
|
|
//原子指标结果表
|
|
|
try {
|
|
|
//查询图谱 index_source: 1人工定义 2数据库查询 3图谱生成 4大模型
|
|
|
if ("1".equals(atomicIndex.getIndexSource())) {
|
|
|
// list
|
|
|
manuallyDefinedCase(analyseCaseDTO, result, atomicIndex);
|
|
|
} else if ("2".equals(atomicIndex.getIndexSource()) && StringUtils.isNotEmpty(ql)) {
|
|
|
//
|
|
|
analyseDataBaseCase(analyseCaseDTO, result, ql, casePerson.getName());
|
|
|
} else if ("3".equals(atomicIndex.getIndexSource()) && StringUtils.isNotEmpty(ql)) {
|
|
|
// 使用知识图谱进行计算
|
|
|
analyseGraphCase(analyseCaseDTO, result, ql, casePerson.getName());
|
|
|
} else if ("4".equals(atomicIndex.getIndexSource())) {
|
|
|
//
|
|
|
} else if ("5".equals(atomicIndex.getIndexSource())) {
|
|
|
// todo: 结构化推理
|
|
|
//analyseStructuredInference(analyseCaseDTO, result);
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
log.error(e.getMessage(), e);
|
|
|
}
|
|
|
// 根据原子指标ID查model_index_atomic_relation表所有的指标ID
|
|
|
List<ModelIndexAtomicRelation> relationList = modelIndexAtomicRelationService.lambdaQuery().eq(ModelIndexAtomicRelation::getAtomicIndexId, atomicIndex.getId()).list();
|
|
|
for (ModelIndexAtomicRelation relation : relationList) {
|
|
|
// 保存或更新原子指标结果表
|
|
|
ModelAtomicResult exist = modelAtomicResultMapper.selectByCaseIdAndAtomicId(analyseCaseDTO.getCaseId(), casePerson.getId(), relation.getModelIndexId(), atomicIndex.getId());
|
|
|
result.setIndexId(relation.getModelIndexId());
|
|
|
if (exist == null) {
|
|
|
result.setId(null);
|
|
|
modelAtomicResultMapper.insert(result);
|
|
|
} else {
|
|
|
result.setId(exist.getId());
|
|
|
modelAtomicResultMapper.updateById(result);
|
|
|
}
|
|
|
Map<String, String> indexMap = atomicResultMap.computeIfAbsent(
|
|
|
result.getAtomicId(),
|
|
|
k -> new HashMap<>() // 如果不存在则创建一个新的 HashMap
|
|
|
);
|
|
|
indexMap.put(relation.getModelIndexId(), result.getAtomicResult());
|
|
|
}
|
|
|
|
|
|
}
|
|
|
// 最终计算得分
|
|
|
calculateFinalScore(analyseCaseDTO, modelCase, atomicResultMap);
|
|
|
caseStatusManageService.whenAnalyseCaseSuccess(analyseCaseDTO.getCaseId(), modelCase.getTotalScore());
|
|
|
// 计算完成之后,把所有的笔录上传到模型
|
|
|
difyApiUtil.syncCaseFileToDifyKnowledgeBase(modelCase, modelCaseService.listCaseFileIds(analyseCaseDTO.getCaseId()));
|
|
|
return R.ok();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public R<?> analyseCaseNew(AnalyseCaseDTO analyseCaseDTO) {
|
|
|
log.info("数据准备阶段");
|
|
|
String caseId = analyseCaseDTO.getCaseId();
|
|
|
Map<String, Integer> typeScoreMap = new HashMap<>();
|
|
|
ModelCase modelCase = modelCaseMapper.selectById(caseId);
|
|
|
if (modelCase == null) {
|
|
|
log.error("未找到案件信息:【{}】", caseId);
|
|
|
return R.fail("未找到案件信息");
|
|
|
}
|
|
|
CasePerson casePerson = casePersonMapper.selectOne(new LambdaQueryWrapper<CasePerson>()
|
|
|
.eq(CasePerson::getCaseId, analyseCaseDTO.getCaseId())
|
|
|
.eq(CasePerson::getCaseActorFlag, 1)
|
|
|
.eq(CasePerson::getRoleCode, "1")
|
|
|
.eq(StrUtil.isNotEmpty(analyseCaseDTO.getLawActorName()), CasePerson::getName, analyseCaseDTO.getLawActorName()));
|
|
|
if (ObjectUtil.isEmpty(casePerson)) {
|
|
|
log.error("未找到的行为人:【{}】", analyseCaseDTO.getLawActorName());
|
|
|
return R.fail("未找到的行为人");
|
|
|
}
|
|
|
List<ModelIndex> modelIndices = modelIndexService.list(new LambdaQueryWrapper<ModelIndex>().eq(ModelIndex::getDataStatus, "1").eq(ModelIndex::getCaseType, modelCase.getCaseType()));
|
|
|
if (modelIndices.isEmpty()) {
|
|
|
log.error("未找到指标信息:【{}】", modelCase.getCaseType());
|
|
|
return R.fail("未找到指标信息");
|
|
|
}
|
|
|
List<ModelAtomicIndex> atomicIndices = modelAtomicIndexMapper.selectByCaseType(modelCase.getCaseType());
|
|
|
if (atomicIndices.isEmpty()) {
|
|
|
log.error("未找到原子指标信息:【{}】", modelCase.getCaseType());
|
|
|
return R.fail("未找到原子指标信息");
|
|
|
}
|
|
|
List<NotePrompt> notePrompts = notePromptService.list(new LambdaQueryWrapper<NotePrompt>().eq(NotePrompt::getType, TYPE_STRUCTURAL_REASONING));
|
|
|
if (notePrompts.isEmpty()) {
|
|
|
log.error("未找到提示词信息:【{}】", TYPE_STRUCTURAL_REASONING);
|
|
|
return R.fail("未找到提示词信息");
|
|
|
}
|
|
|
// 查询提示词对应的属性
|
|
|
for (NotePrompt notePrompt : notePrompts) {
|
|
|
notePrompt.setExtractAttributes(caseEvidencePropertyService.findExtractAttributes(notePrompt.getEvidenceCategoryId()));
|
|
|
}
|
|
|
|
|
|
List<EvidenceDirectory> evidenceDirectories = evidenceDirectoryService.list(new LambdaQueryWrapper<EvidenceDirectory>().eq(EvidenceDirectory::getCaseId, caseId));
|
|
|
if (evidenceDirectories.isEmpty()) {
|
|
|
log.error("未找到证据目录信息:【{}】", caseId);
|
|
|
return R.fail("未找到证据目录信息");
|
|
|
}
|
|
|
List<CaseEvidence> caseEvidences = caseEvidenceService.list(new LambdaQueryWrapper<CaseEvidence>().eq(CaseEvidence::getCaseId, caseId));
|
|
|
caseEvidenceService.redoExtractAttributes(caseId, caseEvidences);
|
|
|
|
|
|
|
|
|
List<ModelIndexAtomicRelation> modelIndexAtomicRelations = modelIndexAtomicRelationService.list();
|
|
|
if (modelIndexAtomicRelations.isEmpty()) {
|
|
|
log.error("未找到指标原子关系信息");
|
|
|
return R.fail("未找到指标原子关系信息");
|
|
|
}
|
|
|
|
|
|
List<ModelAtomicResult> modelAtomicResultList = modelAtomicResultService.lambdaQuery().eq(ModelAtomicResult::getCaseId, caseId).list();
|
|
|
|
|
|
log.info("开始计算指标结果");
|
|
|
// 遍历指标集合,处理每个指标的判断逻辑,得出结果
|
|
|
modelIndices.forEach(modelIndex -> {
|
|
|
log.info("开始计算指标【{}】,ID:{}", modelIndex.getId(), modelIndex.getName());
|
|
|
IndexRule indexRule = modelIndex.getIndexRule();
|
|
|
Set<Boolean> ruleConditionGroupResultList = new HashSet<>();
|
|
|
if (indexRule != null) {
|
|
|
indexRule.getRuleConditionGroupList().forEach(ruleConditionGroup -> {
|
|
|
Set<Boolean> ruleConditionResultSet = new HashSet<>();
|
|
|
ruleConditionGroup.getRuleConditionList().forEach(ruleCondition -> {
|
|
|
Set<Boolean> operandUnitResultSet = new HashSet<>();
|
|
|
// 得到当前指标要求的存在关系(存在或不存在)
|
|
|
boolean relationSymbol = IndexRuleConstants.EVALUATE_RESULT_EXIST.equals(ruleCondition.getRelationalSymbol());
|
|
|
ModelAtomicIndex modelAtomicIndex = atomicIndices.stream().filter(atomicIndex -> atomicIndex.getId().equals(ruleCondition.getAtomicIndexId())).findAny().orElse(null);
|
|
|
if (modelAtomicIndex == null && !OPERAND_TYPE_STRUCTURE.equals(ruleCondition.getIndexSource())) {
|
|
|
log.error("原子指标不存在,跳出当前循环。原子指标ID:{}", ruleCondition.getAtomicIndexId());
|
|
|
return;
|
|
|
}
|
|
|
// 定义原子指标结果共有属性
|
|
|
ModelAtomicResult result = new ModelAtomicResult();
|
|
|
result.setIndexId(modelIndex.getId());
|
|
|
result.setCasePersonId(casePerson.getId());
|
|
|
result.setCaseId(analyseCaseDTO.getCaseId());
|
|
|
result.setAtomicId(ruleCondition.getAtomicIndexId());
|
|
|
result.setAtomicResult(JudgeResultEnum.NOT_EXIST.getCode());
|
|
|
ModelAtomicResult exist = modelAtomicResultMapper.selectByCaseIdAndAtomicId(caseId, casePerson.getId(), modelIndex.getId(), ruleCondition.getAtomicIndexId());
|
|
|
if (exist != null) {
|
|
|
result.setId(exist.getId());
|
|
|
}
|
|
|
switch (ruleCondition.getIndexSource()) {
|
|
|
case OPERAND_TYPE_MANUAL:
|
|
|
operandUnitResultSet.add(relationSymbol == manualIndexAnalysis(ruleCondition.getAtomicIndexId(), caseId));
|
|
|
break;
|
|
|
case OPERAND_TYPE_DB:
|
|
|
operandUnitResultSet.add(relationSymbol == dbIndexAnalysis(caseId, modelAtomicIndex, evidenceDirectories, result));
|
|
|
break;
|
|
|
case OPERAND_TYPE_GRAPH:
|
|
|
operandUnitResultSet.add(relationSymbol == graphIndexAnalysis(casePerson.getName(), modelAtomicIndex.getQueryLang(), analyseCaseDTO.getCaseId(), ruleCondition, result));
|
|
|
break;
|
|
|
case OPERAND_TYPE_STRUCTURE:
|
|
|
if (ruleCondition.getOperandUnitList().isEmpty()) {
|
|
|
log.info("结构化查询条件为空,直接设置为不存在并更新原子指标结果");
|
|
|
result.setAtomicResult(JudgeResultEnum.NOT_EXIST.getCode());
|
|
|
modelAtomicResultService.saveOrUpdate(result);
|
|
|
}
|
|
|
ruleCondition.getOperandUnitList().forEach(operandUnit -> operandUnitResultSet.add(structureIndexAnalysis(operandUnit, ruleCondition.getAtomicIndexId(), atomicIndices, notePrompts, evidenceDirectories, caseEvidences, result)));
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
ruleConditionResultSet.add(CalculationUtil.calculateBooleanSet(operandUnitResultSet, ruleCondition.getLogic()));
|
|
|
});
|
|
|
ruleConditionGroupResultList.add(CalculationUtil.calculateBooleanSet(ruleConditionResultSet, ruleConditionGroup.getRowLogic()));
|
|
|
});
|
|
|
} else {
|
|
|
log.error("指标规则不存在,跳出当前循环。指标ID:{}", modelIndex.getId());
|
|
|
return;
|
|
|
}
|
|
|
// 计算指标结果并保存
|
|
|
boolean result = CalculationUtil.calculateBooleanSet(ruleConditionGroupResultList, indexRule.getGroupLogic());
|
|
|
ModelIndexResult modelIndexResult = new ModelIndexResult();
|
|
|
modelIndexResult.setCaseId(caseId);
|
|
|
modelIndexResult.setIndexId(modelIndex.getId());
|
|
|
modelIndexResult.setAtomicIds(modelIndexAtomicRelations.stream().filter(relation -> relation.getModelIndexId().equals(modelIndex.getId())).map(ModelIndexAtomicRelation::getAtomicIndexId).collect(Collectors.joining(",")));
|
|
|
ModelIndexResult exist = modelIndexResultMapper.selectByCaseIdAndIndexId(analyseCaseDTO.getCaseId(), modelIndex.getId());
|
|
|
if (exist != null) {
|
|
|
modelIndexResult.setId(exist.getId());
|
|
|
}
|
|
|
modelIndexResult.setIndexResult(result ? "true" : "false");
|
|
|
|
|
|
// 先清除掉与指标失去关联的原子指标对应的结果
|
|
|
removeAtomicResultWithNoReference(modelIndex.getId(), modelIndexAtomicRelations, modelAtomicResultList);
|
|
|
|
|
|
if (exist == null) {
|
|
|
modelIndexResultMapper.insert(modelIndexResult);
|
|
|
} else {
|
|
|
modelIndexResultMapper.updateById(modelIndexResult);
|
|
|
}
|
|
|
if (result) {
|
|
|
Integer score = typeScoreMap.getOrDefault(modelIndex.getIndexType(), 0);
|
|
|
log.info("指标ID:{},指标类型:{},得分:{}分", modelIndex.getId(), modelIndex.getIndexType(), modelIndex.getIndexScore());
|
|
|
typeScoreMap.put(modelIndex.getIndexType(), score + modelIndex.getIndexScore());
|
|
|
log.info("当前类型总分:{}分", typeScoreMap.get(modelIndex.getIndexType()));
|
|
|
}
|
|
|
});
|
|
|
Integer gx = typeScoreMap.getOrDefault("1", 0);
|
|
|
Integer rz = typeScoreMap.getOrDefault("2", 0);
|
|
|
Integer cz = typeScoreMap.getOrDefault("3", 0);
|
|
|
int max = Integer.max(gx + rz, gx + cz);
|
|
|
modelCase.setTotalScore(max);
|
|
|
log.info("更新案件得分情况。最终得分:{}分(共性+入罪/共性+出罪 取最大值)。入罪:{}分。出罪:{}分。共性:{}分。", max, rz, cz, gx);
|
|
|
caseStatusManageService.whenAnalyseCaseSuccess(analyseCaseDTO.getCaseId(), modelCase.getTotalScore());
|
|
|
difyApiUtil.syncCaseFileToDifyKnowledgeBase(modelCase, modelCaseService.listCaseFileIds(caseId));
|
|
|
return R.ok();
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void removeAtomicResultWithNoReference(String modelIndexId, List<ModelIndexAtomicRelation> modelIndexAtomicRelations,
|
|
|
List<ModelAtomicResult> modelAtomicResultList) {
|
|
|
List<String> atomicIds = modelIndexAtomicRelations.stream()
|
|
|
.filter(relation -> StrUtil.equals(relation.getModelIndexId(), modelIndexId))
|
|
|
.map(ModelIndexAtomicRelation::getAtomicIndexId).toList();
|
|
|
|
|
|
List<ModelAtomicResult> modelAtomicResults = modelAtomicResultList.stream()
|
|
|
.filter(atomicResult -> StrUtil.equals(atomicResult.getIndexId(), modelIndexId)
|
|
|
&& !atomicIds.contains(atomicResult.getAtomicId())).toList();
|
|
|
|
|
|
for (ModelAtomicResult modelAtomicResult : modelAtomicResults) {
|
|
|
log.info("删除无引用的原子指标结果,指标id:{},原子指标ID:{}", modelIndexId,modelAtomicResult.getAtomicId());
|
|
|
modelAtomicResultMapper.deleteById(modelAtomicResult.getId());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 人工定义指标分析
|
|
|
*
|
|
|
* @param atomicIndexId 原子指标ID
|
|
|
* @param caseId 案件ID
|
|
|
*/
|
|
|
private boolean manualIndexAnalysis(String atomicIndexId, String caseId) {
|
|
|
boolean flag = false;
|
|
|
List<ModelAtomicResult> modelAtomicResults = modelAtomicResultMapper.selectList(
|
|
|
new LambdaQueryWrapper<ModelAtomicResult>().eq(ModelAtomicResult::getCaseId, caseId)
|
|
|
.eq(ModelAtomicResult::getAtomicId, atomicIndexId));
|
|
|
if (modelAtomicResults != null && !modelAtomicResults.isEmpty()) {
|
|
|
ModelAtomicResult modelAtomicResult = CollUtil.getFirst(modelAtomicResults);
|
|
|
flag = EVALUATE_RESULT_EXIST.equals(modelAtomicResult.getAtomicResult());
|
|
|
}
|
|
|
return flag;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 数据库查询指标分析
|
|
|
*
|
|
|
* @param caseId 案件ID
|
|
|
* @param modelAtomicIndex 原子指标
|
|
|
* @param evidenceDirectories 证据目录
|
|
|
* @param atomicResult 原子指标结果
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean dbIndexAnalysis(String caseId, ModelAtomicIndex modelAtomicIndex, List<EvidenceDirectory> evidenceDirectories, ModelAtomicResult atomicResult) {
|
|
|
Map<String, Object> params = new HashMap<>();
|
|
|
params.put("caseId", caseId);
|
|
|
List<Map> mapList = rowSqlMapper.selectList(modelAtomicIndex.getQueryLang(), params, Map.class);
|
|
|
boolean flag = false;
|
|
|
if (mapList != null && !mapList.isEmpty()) {
|
|
|
flag = evidenceDirectories.stream().anyMatch(evidenceDirectory -> StrUtil.equals(evidenceDirectory.getCategoryId(), modelAtomicIndex.getCategoryId()));
|
|
|
String evidenceIds = mapList.stream().map(map -> map.get("id").toString()).collect(Collectors.joining(","));
|
|
|
atomicResult.setEvidenceId(evidenceIds);
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.EXIST.getCode());
|
|
|
}
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
return flag;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 图谱查询指标分析
|
|
|
*
|
|
|
* @param casePersonName 行为人
|
|
|
* @param queryLang 查询语句
|
|
|
* @param caseId 案件ID
|
|
|
* @param ruleCondition 规则条件
|
|
|
* @param atomicResult 原子指标结果
|
|
|
* @return 是否存在
|
|
|
*/
|
|
|
private boolean graphIndexAnalysis(String casePersonName, String queryLang, String caseId, RuleCondition ruleCondition, ModelAtomicResult atomicResult) {
|
|
|
boolean flag = false;
|
|
|
Session session = driver.session();
|
|
|
//图谱
|
|
|
Map<String, Object> params = new HashMap<>();
|
|
|
// 行为人
|
|
|
params.put("lawActor", casePersonName);
|
|
|
// 案号
|
|
|
params.put("caseId", caseId);
|
|
|
Result run;
|
|
|
try {
|
|
|
run = session.run(queryLang, params);
|
|
|
} catch (Exception e) {
|
|
|
log.error("图数据库查询出现错误,查询语句{},参数{}", queryLang, JSONUtil.toJsonStr(params), e);
|
|
|
return flag;
|
|
|
}
|
|
|
List<ResultDTO> res = Neo4jUtils.getResultDTOList(run);
|
|
|
int count = 0;
|
|
|
if (!res.isEmpty()) {
|
|
|
// 进行遍历,如果有存在的,就设置为有
|
|
|
for (ResultDTO resultDTO : res) {
|
|
|
if (StringUtils.isNotEmpty(resultDTO.getRelId())) {
|
|
|
//存在关系
|
|
|
count++;
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.EXIST.getCode());
|
|
|
atomicResult.setRecordId(resultDTO.getRecordId());
|
|
|
// 在退出循环之前先合并相关文本分片id
|
|
|
String recordSplitIdJoin = res.stream().filter(r ->
|
|
|
StringUtils.isNotEmpty(r.getRelId())
|
|
|
&& StringUtils.isNotEmpty(r.getRecordSplitId()))
|
|
|
.map(ResultDTO::getRecordSplitId).collect(Collectors.joining(","));
|
|
|
atomicResult.setRecordSplitId(recordSplitIdJoin);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (StringUtils.isNotEmpty(ruleCondition.getOperator()) && StringUtils.isNotEmpty(ruleCondition.getValue()) && CalculationUtil.evaluateExpression(String.valueOf(count), ruleCondition.getOperator(), ruleCondition.getValue())) {
|
|
|
flag = true;
|
|
|
}
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
return flag;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 结构化查询指标分析
|
|
|
*
|
|
|
* @param operandUnit 操作单元
|
|
|
* @param modelAtomicIndexId 原子指标ID
|
|
|
* @param atomicIndices 原子指标集合
|
|
|
* @param notePrompts 提示词集合
|
|
|
* @param evidenceDirectories 证据目录集合
|
|
|
* @param caseEvidences 证据集合
|
|
|
* @param atomicResult 原子指标结果
|
|
|
* @return 是否存在
|
|
|
*/
|
|
|
private boolean structureIndexAnalysis(OperandUnit operandUnit, String modelAtomicIndexId, List<ModelAtomicIndex> atomicIndices, List<NotePrompt> notePrompts, List<EvidenceDirectory> evidenceDirectories, List<CaseEvidence> caseEvidences, ModelAtomicResult atomicResult) {
|
|
|
Operand left = operandUnit.getLeftOperand();
|
|
|
String operator = operandUnit.getOperator();
|
|
|
Operand right = operandUnit.getRightOperand();
|
|
|
boolean flag = false;
|
|
|
ModelAtomicIndex modelAtomicIndex = atomicIndices.stream().filter(atomicIndex -> atomicIndex.getId().equals(modelAtomicIndexId)).findAny().orElse(null);
|
|
|
if (modelAtomicIndex == null) {
|
|
|
log.error("原子指标不存在。原子指标ID:{}", modelAtomicIndexId);
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.NOT_EXIST.getCode());
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
return flag;
|
|
|
}
|
|
|
List<CaseEvidence> evidences = getEvidencesByPromptId(modelAtomicIndex.getPromptId(), caseEvidences, evidenceDirectories, notePrompts);
|
|
|
atomicResult.setEvidenceId(evidences.stream().map(CaseEvidence::getId).collect(Collectors.joining(",")));
|
|
|
ModelAtomicIndex rightModelAtomicIndex = null;
|
|
|
if (OPERAND_TYPE_STRUCTURE.equals(right.getOperandType())) {
|
|
|
log.info("右操作数为结构化查询,提前查好对应的原子指标");
|
|
|
rightModelAtomicIndex = atomicIndices.stream().filter(atomicIndex -> atomicIndex.getId().equals(left.getAtomicIndexId())).findAny().orElse(null);
|
|
|
if (rightModelAtomicIndex == null || StringUtils.isEmpty(rightModelAtomicIndex.getPromptId())) {
|
|
|
log.error("原子指标不存在。原子指标ID:{}", left.getAtomicIndexId());
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.NOT_EXIST.getCode());
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
return flag;
|
|
|
}
|
|
|
}
|
|
|
if (!evidences.isEmpty()) {
|
|
|
log.info("聚合类型为【{}】,右操作数操作类型为:【{}】", AGGREGATE_TYPE_SUM.equals(left.getAggregateType()) ? "求和" : AGGREGATE_TYPE_COUNT.equals(left.getAggregateType()) ? "计数" : "任一", OPERAND_TYPE_STRUCTURE.equals(right.getOperandType()) ? "结构化查询" : "值");
|
|
|
switch (left.getAggregateType()) {
|
|
|
case AGGREGATE_TYPE_SUM:
|
|
|
if (OPERAND_TYPE_STRUCTURE.equals(right.getOperandType())) {
|
|
|
log.info("左操作数总和:【{}】,操作符:【{}】,右操作数:【{}】", getSumFromEvidences(left.getPropertyKey(), evidences), operator, right.getValue());
|
|
|
List<CaseEvidence> rightEvidences = getEvidencesByPromptId(rightModelAtomicIndex.getPromptId(), caseEvidences, evidenceDirectories, notePrompts);
|
|
|
if (CalculationUtil.evaluateExpression(String.valueOf(getSumFromEvidences(left.getPropertyKey(), evidences)), operator, String.valueOf(getSumFromEvidences(right.getPropertyKey(), rightEvidences)))) {
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.EXIST.getCode());
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
return true;
|
|
|
}
|
|
|
} else if (OPERAND_TYPE_VALUE.equals(right.getOperandType())) {
|
|
|
log.info("左操作数总和:【{}】,操作符:【{}】,右操作数:【{}】", getSumFromEvidences(left.getPropertyKey(), evidences), operator, right.getValue());
|
|
|
if (CalculationUtil.evaluateExpression(String.valueOf(getSumFromEvidences(left.getPropertyKey(), evidences)), operator, right.getValue())) {
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.EXIST.getCode());
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case AGGREGATE_TYPE_COUNT:
|
|
|
if (OPERAND_TYPE_STRUCTURE.equals(right.getOperandType())) {
|
|
|
log.info("左操作数数量:【{}】,操作符:【{}】,右操作数:【{}】", evidences.size(), operator, right.getValue());
|
|
|
List<CaseEvidence> rightEvidences = getEvidencesByPromptId(rightModelAtomicIndex.getPromptId(), caseEvidences, evidenceDirectories, notePrompts);
|
|
|
if (CalculationUtil.evaluateExpression(String.valueOf(evidences.size()), operator, String.valueOf(rightEvidences.size()))) {
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.EXIST.getCode());
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
return true;
|
|
|
}
|
|
|
} else if (OPERAND_TYPE_VALUE.equals(right.getOperandType())) {
|
|
|
log.info("左操作数数量:【{}】,操作符:【{}】,右操作数:【{}】", evidences.size(), operator, right.getValue());
|
|
|
if (CalculationUtil.evaluateExpression(String.valueOf(evidences.size()), operator, right.getValue())) {
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.EXIST.getCode());
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case AGGREGATE_TYPE_ANY:
|
|
|
if (OPERAND_TYPE_STRUCTURE.equals(right.getOperandType())) {
|
|
|
List<CaseEvidence> rightEvidences = getEvidencesByPromptId(rightModelAtomicIndex.getPromptId(), caseEvidences, evidenceDirectories, notePrompts);
|
|
|
Set<String> leftValueSet = getValueSetFromEvidences(left, evidences);
|
|
|
Set<String> rightValueSet = getValueSetFromEvidences(right, rightEvidences);
|
|
|
log.info("左操作数值集合:【{}】,操作符:【{}】,右操作数:【{}】", leftValueSet, operator, right.getValue());
|
|
|
// 使用CalculationUtil.evaluateExpression方法遍历比较leftValueSet和rightValueSet的任一值,一旦有一个满足(返回true),则return true
|
|
|
if (leftValueSet.stream().anyMatch(leftValue -> rightValueSet.stream().anyMatch(rightValue -> CalculationUtil.evaluateExpression(leftValue, operator, rightValue)))) {
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.EXIST.getCode());
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
return true;
|
|
|
}
|
|
|
} else if (OPERAND_TYPE_VALUE.equals(right.getOperandType())) {
|
|
|
Set<String> leftValueSet = getValueSetFromEvidences(left, evidences);
|
|
|
log.info("左操作数值集合:【{}】,操作符:【{}】,右操作数:【{}】", leftValueSet, operator, right.getValue());
|
|
|
if (leftValueSet.stream().anyMatch(leftValue -> CalculationUtil.evaluateExpression(leftValue, operator, right.getValue()))) {
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.EXIST.getCode());
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.NOT_EXIST.getCode());
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
break;
|
|
|
}
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.NOT_EXIST.getCode());
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
} else {
|
|
|
log.error("证据不存在。提示词ID:{}", modelAtomicIndex.getPromptId());
|
|
|
atomicResult.setAtomicResult(JudgeResultEnum.NOT_EXIST.getCode());
|
|
|
modelAtomicResultService.saveOrUpdate(atomicResult);
|
|
|
}
|
|
|
return flag;
|
|
|
}
|
|
|
|
|
|
private Double getSumFromEvidences(String propertyKey, List<CaseEvidence> evidences) {
|
|
|
AtomicReference<Double> sum = new AtomicReference<>(0.0);
|
|
|
if (evidences != null && !evidences.isEmpty()) {
|
|
|
evidences.forEach(e -> {
|
|
|
List<NotePromptExtractAttributesDto> properties = e.getProperty();
|
|
|
if (properties != null && !properties.isEmpty()) {
|
|
|
properties.forEach(p -> {
|
|
|
if (p.getAttrName().equals(propertyKey)) {
|
|
|
if (StringUtils.isNotEmpty(p.getAttrValue())) {
|
|
|
sum.updateAndGet(v -> v + NumberUtil.parseDouble(p.getAttrValue()));
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
return sum.get();
|
|
|
}
|
|
|
|
|
|
private Set<String> getValueSetFromEvidences(Operand operand, List<CaseEvidence> evidences) {
|
|
|
Set<String> valueSet = new HashSet<>();
|
|
|
evidences.forEach(e -> {
|
|
|
List<NotePromptExtractAttributesDto> properties = e.getProperty();
|
|
|
if (properties != null && !properties.isEmpty()) {
|
|
|
properties.forEach(p -> {
|
|
|
if (p.getAttrName().equals(operand.getPropertyKey())) {
|
|
|
if (StringUtils.isNotEmpty(p.getAttrValue())) {
|
|
|
valueSet.add(p.getAttrValue());
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
return valueSet;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据原子指标ID获取证据集合
|
|
|
*
|
|
|
* @param promptId 提示词ID
|
|
|
* @param caseEvidences 全量案件证据集合
|
|
|
* @param evidenceDirectories 证据目录集合
|
|
|
* @param notePrompts 提示词集合
|
|
|
* @return 证据集合
|
|
|
*/
|
|
|
private static List<CaseEvidence> getEvidencesByPromptId(String promptId, List<CaseEvidence> caseEvidences, List<EvidenceDirectory> evidenceDirectories, List<NotePrompt> notePrompts) {
|
|
|
List<CaseEvidence> evidences = new ArrayList<>();
|
|
|
NotePrompt notePrompt = notePrompts.stream().filter(n -> n.getId().equals(promptId)).findAny().orElse(null);
|
|
|
if (notePrompt == null) {
|
|
|
log.error("提示词不存在。提示词ID:{}", promptId);
|
|
|
return evidences;
|
|
|
}
|
|
|
List<EvidenceDirectory> directories = evidenceDirectories.stream().filter(e -> e.getCategoryId().equals(notePrompt.getEvidenceCategoryId())).toList();
|
|
|
List<String> directoryIds = directories.stream().map(EvidenceDirectory::getId).toList();
|
|
|
evidences = caseEvidences.stream().filter(e -> directoryIds.contains(e.getDirectoryId())).toList();
|
|
|
return evidences;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 手动定义原子指标处理
|
|
|
*
|
|
|
* @param analyseCaseDTO 案件信息
|
|
|
* @param result 原子指标结果
|
|
|
* @param atomicIndex 原子指标
|
|
|
*/
|
|
|
private void manuallyDefinedCase(AnalyseCaseDTO analyseCaseDTO, ModelAtomicResult result, ModelAtomicIndex atomicIndex) {
|
|
|
List<ModelAtomicResult> modelAtomicResults = modelAtomicResultMapper.selectList(
|
|
|
new LambdaQueryWrapper<ModelAtomicResult>().eq(ModelAtomicResult::getCaseId, analyseCaseDTO.getCaseId())
|
|
|
.eq(ModelAtomicResult::getAtomicId, atomicIndex.getId()));
|
|
|
|
|
|
if (CollUtil.isEmpty(modelAtomicResults)) {
|
|
|
log.info("manuallyDefinedCase:根据caseId:{},atomicId:{}未找到原子指标结果", analyseCaseDTO.getCaseId(), atomicIndex.getId());
|
|
|
return;
|
|
|
}
|
|
|
if (CollUtil.size(modelAtomicResults) > 0) {
|
|
|
log.warn("manuallyDefinedCase:根据caseId:{},atomicId:{}找到多个原子指标结果", analyseCaseDTO.getCaseId(), atomicIndex.getId());
|
|
|
}
|
|
|
ModelAtomicResult modelAtomicResult = CollUtil.getFirst(modelAtomicResults);
|
|
|
|
|
|
|
|
|
result.setAtomicResult(modelAtomicResult.getAtomicResult());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public CaseScoreDetailDTO caseScoreDetail(String caseId) {
|
|
|
Assert.notEmpty(caseId, "案件id不能为空");
|
|
|
|
|
|
CaseScoreDetailBuilder caseScoreDetailBuilder = new CaseScoreDetailBuilder()
|
|
|
.setOllamaChatClient(null)
|
|
|
.setMapper(modelCaseMapper, casePersonMapper, modelAtomicIndexMapper,
|
|
|
modelIndexResultMapper, modelIndexMapper, modelAtomicResultMapper);
|
|
|
|
|
|
caseScoreDetailBuilder.loadCaseScoreDetail(caseId);
|
|
|
List<EvidenceDirectoryDTO> evidenceDirectoryDTOS = evidenceDirectoryService.listDirectoryTree(caseId);
|
|
|
List<EvidenceCategoryDTO> evidenceCategoryDTOS = evidenceCategoryService.listCategoryTree(caseScoreDetailBuilder.getCaseType());
|
|
|
caseScoreDetailBuilder.setEvidence(new EvidenceDirectoryDTO(evidenceDirectoryDTOS), new EvidenceCategoryDTO(evidenceCategoryDTOS));
|
|
|
return caseScoreDetailBuilder.build();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public CaseScore caseScoreByCaseId(String caseId) {
|
|
|
CaseScoreDetailBuilder caseScoreDetailBuilder = new CaseScoreDetailBuilder()
|
|
|
.setOllamaChatClient(null)
|
|
|
.setMapper(modelCaseMapper, casePersonMapper, modelAtomicIndexMapper,
|
|
|
modelIndexResultMapper, modelIndexMapper, modelAtomicResultMapper);
|
|
|
|
|
|
caseScoreDetailBuilder.loadCaseScoreDetail(caseId);
|
|
|
CaseScore caseScore = new CaseScore();
|
|
|
caseScore.setCommonScore(caseScoreDetailBuilder.getCommonScore());
|
|
|
caseScore.setCrimeScore(caseScoreDetailBuilder.getCrimeScore());
|
|
|
caseScore.setCrimeOutScore(caseScoreDetailBuilder.getCrimeOutScore());
|
|
|
return caseScore;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public CaseStatus getCaseDateStatus(String caseId) {
|
|
|
|
|
|
Assert.notEmpty(caseId, "案件id不能为空");
|
|
|
|
|
|
ModelCase modelCase = modelCaseMapper.selectById(caseId);
|
|
|
Assert.notNull(modelCase, "案件不存在");
|
|
|
|
|
|
return new CaseStatus(modelCase.getCaseDataStatus(), modelCase.getCaseAnalysisStatus());
|
|
|
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void exportCaseScoreDetail(String caseId, HttpServletResponse response) {
|
|
|
CaseScoreDetailDTO caseScoreDetailDTO = caseScoreDetail(caseId);
|
|
|
caseScoreDetailDTO.buildDesc();
|
|
|
|
|
|
// 加载模板
|
|
|
Resource resource = resourceLoader.getResource("classpath:template/case_detail.docx");
|
|
|
InputStream inputStream = null;
|
|
|
try {
|
|
|
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
|
|
|
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(caseScoreDetailDTO.getCaseName() + ".docx", StandardCharsets.UTF_8));
|
|
|
inputStream = resource.getInputStream();
|
|
|
XWPFTemplate template = XWPFTemplate.compile(inputStream).render(caseScoreDetailDTO);
|
|
|
template.writeAndClose(response.getOutputStream());
|
|
|
} catch (IOException e) {
|
|
|
throw new RuntimeException(e);
|
|
|
} finally {
|
|
|
if (inputStream != null) {
|
|
|
try {
|
|
|
inputStream.close();
|
|
|
} catch (IOException e) {
|
|
|
log.error("exportCaseScoreDetail: inputStream.close() error", e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 最终计算得分
|
|
|
*/
|
|
|
private void calculateFinalScore(AnalyseCaseDTO analyseCaseDTO, ModelCase modelCase, Map<String, Map<String, String>> atomicResultMap) {
|
|
|
// 根据案件类型获取所有的指标
|
|
|
List<ModelIndex> modelIndices = modelIndexService.list(new LambdaQueryWrapper<ModelIndex>().eq(ModelIndex::getDataStatus, "1").eq(ModelIndex::getCaseType, modelCase.getCaseType()));
|
|
|
Map<String, Integer> typeScoreMap = new HashMap<>();
|
|
|
for (ModelIndex modelIndex : modelIndices) {
|
|
|
ModelIndexResult result = new ModelIndexResult();
|
|
|
result.setCaseId(analyseCaseDTO.getCaseId());
|
|
|
result.setIndexId(modelIndex.getId());
|
|
|
Set<String> atomicIds = new HashSet<>();
|
|
|
// 判断逻辑是否为空,如果不为空,就根据判断逻辑进行判断
|
|
|
if (StringUtils.isNotEmpty(modelIndex.getJudgeLogic())) {
|
|
|
List<JudgeLogic> judgeLogics = JSONUtil.toList(modelIndex.getJudgeLogic(), JudgeLogic.class);
|
|
|
if (CollUtil.isNotEmpty(judgeLogics)) {
|
|
|
boolean finalJudgeResult = false;
|
|
|
// 遍历组
|
|
|
for (int i = 0; i < judgeLogics.size(); i++) {
|
|
|
// 组内结果
|
|
|
boolean innerGroupJudge = false;
|
|
|
JudgeLogic logic = judgeLogics.get(i);
|
|
|
// 获取组之间的的判断逻辑
|
|
|
String rowLogic = logic.getRowLogic();
|
|
|
// 首先对组内进行判断,判断组内的结果
|
|
|
List<AtomicData> atomicData = logic.getAtomicData();
|
|
|
for (int j = 0; j < atomicData.size(); j++) {
|
|
|
AtomicData data = atomicData.get(j);
|
|
|
atomicIds.add(data.getAtomicIndex());
|
|
|
// 先找到原子指标对应的大指标的结果
|
|
|
Map<String, String> atomicIndexMap = atomicResultMap.get(data.getAtomicIndex());
|
|
|
String atomicIndexResult;
|
|
|
if (CollUtil.isEmpty(atomicIndexMap)) {
|
|
|
atomicIndexResult = JudgeResultEnum.UNKNOWN.getCode();
|
|
|
} else {
|
|
|
// 这里可能不存在,如果未找到,就默认为false
|
|
|
atomicIndexResult = atomicIndexMap.getOrDefault(modelIndex.getId(), JudgeResultEnum.UNKNOWN.getCode());
|
|
|
}
|
|
|
String relationalSymbol = data.getRelationalSymbol();
|
|
|
JudgeResultEnum instance = JudgeResultEnum.getInstance(relationalSymbol);
|
|
|
boolean ato = StrUtil.equals(atomicIndexResult, instance.getCode());
|
|
|
if (j == 0) {
|
|
|
innerGroupJudge = ato;
|
|
|
} else {
|
|
|
if ("1".equals(rowLogic)) {
|
|
|
innerGroupJudge = innerGroupJudge && ato;
|
|
|
} else if ("2".equals(rowLogic)) {
|
|
|
innerGroupJudge = innerGroupJudge || ato;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// 组间进行判断
|
|
|
String groupLogic = logic.getGroupLogic();
|
|
|
if (i == 0) {
|
|
|
finalJudgeResult = innerGroupJudge;
|
|
|
} else {
|
|
|
// 如果组间判断为1 与,则进行与操作
|
|
|
if ("1".equals(groupLogic)) {
|
|
|
finalJudgeResult = finalJudgeResult && innerGroupJudge;
|
|
|
// 如果组间判断为或,则进行或操作
|
|
|
} else if ("2".equals(groupLogic)) {
|
|
|
finalJudgeResult = finalJudgeResult || innerGroupJudge;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
result.setIndexResult(finalJudgeResult ? "true" : "false");
|
|
|
result.setAtomicIds(StringUtils.join(atomicIds, ","));
|
|
|
}
|
|
|
}
|
|
|
// 最后保存结果
|
|
|
ModelIndexResult exist = modelIndexResultMapper.selectByCaseIdAndIndexId(analyseCaseDTO.getCaseId(), modelIndex.getId());
|
|
|
if (exist == null) {
|
|
|
modelIndexResultMapper.insert(result);
|
|
|
} else {
|
|
|
result.setId(exist.getId());
|
|
|
modelIndexResultMapper.updateById(result);
|
|
|
}
|
|
|
|
|
|
if ("true".equals(result.getIndexResult())) {
|
|
|
Integer orDefault = typeScoreMap.getOrDefault(modelIndex.getIndexType(), 0);
|
|
|
typeScoreMap.put(modelIndex.getIndexType(), orDefault + modelIndex.getIndexScore());
|
|
|
}
|
|
|
}
|
|
|
// 计算分数 共性+入罪/共性+出罪 取最大值
|
|
|
Integer gx = typeScoreMap.getOrDefault("1", 0);
|
|
|
Integer rz = typeScoreMap.getOrDefault("2", 0);
|
|
|
Integer cz = typeScoreMap.getOrDefault("3", 0);
|
|
|
int max = Integer.max(gx + rz, gx + cz);
|
|
|
modelCase.setTotalScore(max);
|
|
|
modelCaseMapper.updateById(modelCase);
|
|
|
}
|
|
|
|
|
|
private void analyseGraphCase(AnalyseCaseDTO analyseCaseDTO, ModelAtomicResult result, String ql, String caseActorName) {
|
|
|
Session session = driver.session();
|
|
|
//图谱
|
|
|
int i = 1;
|
|
|
Map<String, Object> params = new HashMap<>();
|
|
|
// 行为人
|
|
|
params.put("lawActor", caseActorName);
|
|
|
// 案号
|
|
|
params.put("caseId", analyseCaseDTO.getCaseId());
|
|
|
// 参数中是否传了受害人
|
|
|
String lawPartys = analyseCaseDTO.getLawParty();
|
|
|
// 如果有受害人的话就进行分割
|
|
|
String[] split = StringUtils.isEmpty(lawPartys) ? new String[0] : lawPartys.split(",");
|
|
|
if (ql.contains("$lawParty") && split.length > 1) {
|
|
|
i = split.length;
|
|
|
}
|
|
|
// 只有有符合的,就认为符合,不进行遍历了
|
|
|
judge:
|
|
|
for (int j = 0; j < i; j++) {
|
|
|
if (split.length > 0) {
|
|
|
params.put("lawParty", split[j]);
|
|
|
}
|
|
|
Result run;
|
|
|
try {
|
|
|
run = session.run(ql, params);
|
|
|
} catch (Exception e) {
|
|
|
result.setAtomicResult("-1");
|
|
|
log.error("图数据库查询出现错误,查询语句{},参数{}", ql, JSONUtil.toJsonStr(params), e);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
List<ResultDTO> res = Neo4jUtils.getResultDTOList(run);
|
|
|
if (res.isEmpty()) {
|
|
|
result.setAtomicResult(JudgeResultEnum.NOT_EXIST.getCode());
|
|
|
} else {
|
|
|
// 设置为0,不存在
|
|
|
result.setAtomicResult(JudgeResultEnum.NOT_EXIST.getCode());
|
|
|
// 进行遍历,如果有存在的,就设置为有
|
|
|
for (ResultDTO resultDTO : res) {
|
|
|
if (StringUtils.isNotEmpty(resultDTO.getRelId())) {
|
|
|
//存在关系
|
|
|
result.setAtomicResult(JudgeResultEnum.EXIST.getCode());
|
|
|
result.setRecordId(resultDTO.getRecordId());
|
|
|
|
|
|
// 在退出循环之前先合并相关文本分片id
|
|
|
String recordSplitIdJoin = res.stream().filter(r ->
|
|
|
StringUtils.isNotEmpty(r.getRelId())
|
|
|
&& StringUtils.isNotEmpty(r.getRecordSplitId()))
|
|
|
.map(ResultDTO::getRecordSplitId).collect(Collectors.joining(","));
|
|
|
result.setRecordSplitId(recordSplitIdJoin);
|
|
|
// 如果只要存在,就不进行校验了,直接跳出循环
|
|
|
break judge;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 分析数据库类型的原子信息
|
|
|
*
|
|
|
* @param analyseCaseDTO
|
|
|
* @param result
|
|
|
* @param sql
|
|
|
*/
|
|
|
private void analyseDataBaseCase(AnalyseCaseDTO analyseCaseDTO, ModelAtomicResult result, String sql, String caseActorName) {
|
|
|
|
|
|
Map<String, Object> params = new HashMap<>();
|
|
|
params.put("caseId", result.getCaseId());
|
|
|
params.put("evidenceName", analyseCaseDTO.getEvidenceName());
|
|
|
params.put("provider", null);
|
|
|
params.put("party_a", caseActorName);
|
|
|
params.put("party_b", analyseCaseDTO.getLawParty());
|
|
|
boolean success = false;
|
|
|
if (modelIndexService.checkSql(sql)) {
|
|
|
success = parseResult(rowSqlMapper.selectList(sql, params, Map.class));
|
|
|
}
|
|
|
result.setAtomicResult(success ? JudgeResultEnum.EXIST.getCode() : JudgeResultEnum.NOT_EXIST.getCode());
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 执行结果分析:
|
|
|
* 1. 如果查询出的结果只有一行,判断列数是否大于1,如果大于1,返回真,如果=1,继续判断值是否大于0,如果大于0,返回真,如果=0,返回假
|
|
|
* 2. 如果查询出的结果大于一行,则返回真
|
|
|
*
|
|
|
* @param mapList 查询结果
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean parseResult(List<Map> mapList) {
|
|
|
|
|
|
if (CollUtil.isEmpty(mapList)) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (CollUtil.size(mapList) > 1) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
Map firstRow = CollUtil.getFirst(mapList);
|
|
|
if (firstRow.size() == 1 && CollUtil.size(firstRow.values()) == 1) {
|
|
|
Object first = CollUtil.getFirst(firstRow.values());
|
|
|
if (NumberUtil.isNumber(first.toString())) {
|
|
|
return NumberUtil.parseInt(first.toString()) > 0;
|
|
|
}
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
}
|