fu-hsi-service/src/main/java/com/supervision/police/service/impl/ModelIndexServiceImpl.java

655 lines
31 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.supervision.police.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.supervision.common.constant.IndexRuleConstants;
import com.supervision.common.constant.NotePromptConstants;
import com.supervision.common.domain.R;
import com.supervision.common.utils.IPages;
import com.supervision.common.utils.StringUtils;
import com.supervision.constant.DataStatus;
import com.supervision.neo4j.dto.WebRelDTO;
import com.supervision.neo4j.service.Neo4jService;
import com.supervision.police.domain.*;
import com.supervision.police.dto.*;
import com.supervision.police.dto.indexRule.IndexRule;
import com.supervision.police.dto.indexRule.RuleCondition;
import com.supervision.police.dto.indexRule.RuleConditionGroup;
import com.supervision.police.dto.neo4j.NodeDTO;
import com.supervision.police.dto.neo4j.PathDTO;
import com.supervision.police.dto.neo4j.RelationshipValueDTO;
import com.supervision.police.mapper.CasePersonMapper;
import com.supervision.police.mapper.ModelAtomicResultMapper;
import com.supervision.police.mapper.ModelIndexMapper;
import com.supervision.police.service.*;
import com.supervision.police.vo.GraphDebugReqVO;
import com.supervision.police.vo.GraphDebugResVO;
import com.supervision.police.vo.ModelIndexReqVO;
import com.supervision.utils.JudgeLogicUtil;
import com.supervision.utils.SqlParserUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.Record;
import org.neo4j.driver.internal.InternalNode;
import org.neo4j.driver.internal.InternalRelationship;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Relationship;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
/**
* 指标表(ModelIndex)表服务实现类
*
* @author qmy
* @since 2024-07-05 09:20:10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class ModelIndexServiceImpl extends ServiceImpl<ModelIndexMapper, ModelIndex> implements ModelIndexService {
private final ComDictionaryService comDictionaryService;
private final ModelIndexMapper modelIndexMapper;
private final ModelAtomicIndexService modelAtomicIndexService;
private final ModelCaseService modelCaseService;
private final ModelAtomicResultMapper modelAtomicResultMapper;
private final CasePersonMapper casePersonMapper;
private final CaseStatusManageService caseStatusManageService;
private final ModelIndexAtomicRelationService modelIndexAtomicRelationService;
private final NotePromptService notePromptService;
private final EvidenceCategoryService evidenceCategoryService;
@Value("${case.evidence.table}")
private List<String> allowedTables;
private final Neo4jService neo4jService;
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public R<?> selectAll(ModelIndexReqVO modelIndex, Integer page, Integer size) {
// 构建查询条件
IPage<ModelIndex> iPage = new Page<>(page, size);
LambdaQueryWrapper<ModelIndex> wrapper = Wrappers.lambdaQuery();
wrapper.like(modelIndex.getName() != null, ModelIndex::getName, modelIndex.getName())
.like(modelIndex.getShortName() != null, ModelIndex::getShortName, modelIndex.getShortName())
.like(modelIndex.getRemark() != null, ModelIndex::getRemark, modelIndex.getRemark())
.eq(StringUtils.isNotEmpty(modelIndex.getIndexType()), ModelIndex::getIndexType, modelIndex.getIndexType())
.eq(StringUtils.isNotEmpty(modelIndex.getCaseType()), ModelIndex::getCaseType, modelIndex.getCaseType())
.eq(ModelIndex::getDataStatus, "1");
if (StrUtil.isNotEmpty(modelIndex.getAtomicIndexName())) {
// 如果查询条件中有原子指标名称则根据原子指标名称过滤关联的指标id
List<ModelIndexAtomicRelationDTO> modelIndexAtomicDTOS = modelIndexAtomicRelationService.listByAtomicIndexName(modelIndex.getAtomicIndexName());
List<String> indexIdList = modelIndexAtomicDTOS.stream().map(ModelIndexAtomicRelationDTO::getModelIndexId).distinct().toList();
if (CollUtil.isEmpty(indexIdList)) {
return R.ok(IPages.buildDataMap(iPage));
}
wrapper.in(CollUtil.isNotEmpty(indexIdList), ModelIndex::getId, indexIdList);
}
wrapper.orderBy(true, false, ModelIndex::getUpdateTime);
iPage = modelIndexMapper.selectPage(iPage, wrapper);
// 分页查询
List<ModelIndex> records = iPage.getRecords();
List<ComDictionary> dicts = comDictionaryService.list();
// 查询结果拼装
for (ModelIndex index : records) {
index.setIndexTypeName(comDictionaryService.getName(dicts, "index_type", index.getIndexType()));
index.setCaseTypeName(comDictionaryService.getName(dicts, "case_type", index.getCaseType()));
//原子指标
String judgeLogic = index.getJudgeLogic();
Set<String> ids = new HashSet<>();
IndexRule indexRule = index.getIndexRule();
if (indexRule != null) {
List<RuleConditionGroup> ruleConditionGroupList = indexRule.getRuleConditionGroupList();
for (RuleConditionGroup ruleConditionGroup : ruleConditionGroupList) {
List<RuleCondition> ruleConditionList = ruleConditionGroup.getRuleConditionList();
for (RuleCondition ruleCondition : ruleConditionList) {
ids.add(ruleCondition.getAtomicIndexId());
}
}
List<ModelAtomicIndex> atomicIndexList = modelAtomicIndexService.selectBatchIds(ids.stream().toList());
index.setAtomicIndexList(atomicIndexList);
} else if (StringUtils.isNotEmpty(judgeLogic)) {
List<JudgeLogic> logic = JSONUtil.toList(judgeLogic, JudgeLogic.class);
for (JudgeLogic judge : logic) {
List<AtomicData> atomicData = judge.getAtomicData();
for (AtomicData atomic : atomicData) {
ids.add(atomic.getAtomicIndex());
}
}
List<ModelAtomicIndex> atomicIndexList = modelAtomicIndexService.selectBatchIds(ids.stream().toList());
index.setAtomicIndexList(atomicIndexList);
}
index.setAtomicIndexNum(ids.size());
}
iPage.setRecords(records);
return R.ok(IPages.buildDataMap(iPage));
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public R<?> addOrUpd(ModelIndex modelIndex) {
int i;
if (StringUtils.isEmpty(modelIndex.getId())) {
i = modelIndexMapper.insert(modelIndex);
modelIndexAtomicRelationService.saveByModelIndex(modelIndex);
} else {
ModelIndex dbModelIndex = super.getById(modelIndex.getId());
modelIndex.setJudgeLogic(dbModelIndex.getJudgeLogic());// 保持原来判断逻辑不变
i = modelIndexMapper.updateById(modelIndex);
modelIndexAtomicRelationService.updateByModelIndex(modelIndex);
}
if (i > 0) {
return R.okMsg("保存成功");
} else {
return R.fail("保存失败");
}
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public R<?> del(String id) {
ModelIndex index = modelIndexMapper.selectById(id);
index.setDataStatus(DataStatus.NOT_AVAILABLE.getCode());
int i = modelIndexMapper.updateById(index);
if (i > 0) {
modelIndexAtomicRelationService.deleteByModelIndex(id);
return R.okMsg("删除成功");
} else {
return R.fail("删除失败");
}
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public R<?> selectAllAtomic(ModelAtomicIndex modelAtomicIndex, Integer page, Integer size) {
IPage<ModelAtomicIndex> iPage = new Page<>(page, size);
iPage = modelAtomicIndexService.selectAll(iPage, modelAtomicIndex);
List<ModelAtomicIndex> records = iPage.getRecords();
List<ComDictionary> dicts = comDictionaryService.list();
String caseType = StrUtil.isNotEmpty(modelAtomicIndex.getCaseType()) ? modelAtomicIndex.getCaseType() : NotePromptConstants.CASE_TYPE_ENGINEERING_CONTRACT_FRAUD;
EvidenceCategoryDTO rootCategory = new EvidenceCategoryDTO(evidenceCategoryService.listCategoryTree(caseType));
for (ModelAtomicIndex index : records) {
index.setCaseTypeName(comDictionaryService.getName(dicts, "case_type", index.getCaseType()));
index.setIndexSourceName(comDictionaryService.getName(dicts, "index_source", index.getIndexSource()));
index.setRecordTypeName(comDictionaryService.getName(dicts, "record_type", index.getRecordType()));
index.setCategoryIdPath(rootCategory.listCategoryIdPath(index.getCategoryId()));
}
iPage.setRecords(records);
return R.ok(IPages.buildDataMap(iPage));
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public R<?> addOrUpdAtomic(ModelAtomicIndex modelAtomicIndex) {
saveAtomicIndexPreDo(modelAtomicIndex);
// 校验是否已经存在了相同名称的原子指标
ModelAtomicIndex existIndex = modelAtomicIndexService.lambdaQuery().eq(ModelAtomicIndex::getName, modelAtomicIndex.getName())
.eq(ModelAtomicIndex::getDataStatus, DataStatus.AVAILABLE.getCode()).last("limit 1").one();
if (ObjectUtil.isNotEmpty(existIndex) && !StringUtils.equals(modelAtomicIndex.getId(), existIndex.getId())) {
throw new IllegalArgumentException("已存在相同名称的原子指标");
}
boolean success = modelAtomicIndexService.saveOrUpdate(modelAtomicIndex);
return success ? R.okMsg("保存成功") : R.fail("保存失败");
}
/**
* 原子指标保存前置处理
*
* @param modelAtomicIndex
*/
private void saveAtomicIndexPreDo(ModelAtomicIndex modelAtomicIndex) {
if (StringUtils.equals(IndexRuleConstants.OPERAND_TYPE_DB, modelAtomicIndex.getIndexSource())) {
Assert.notEmpty(modelAtomicIndex.getCategoryId(), "分类不能为空");
// 如果查询类型为数据查询,则校验查询语句
Assert.notEmpty(modelAtomicIndex.getQueryLang(), "查询语言不能为空");
Assert.isTrue(checkSql(modelAtomicIndex.getQueryLang()), "查询语句不合法");
} else if (StringUtils.equals(IndexRuleConstants.OPERAND_TYPE_STRUCTURE, modelAtomicIndex.getIndexSource())) {
Assert.notEmpty(modelAtomicIndex.getPromptId(), "promptId不能为空");
NotePrompt notePrompt = notePromptService.getBaseMapper().selectById(modelAtomicIndex.getPromptId());
Assert.notNull(notePrompt, "提示词信息不存在");
Assert.notEmpty(notePrompt.getEvidenceCategoryId(), "提示词分类为空");
modelAtomicIndex.setCategoryId(notePrompt.getEvidenceCategoryId());
}else if (StringUtils.equals(IndexRuleConstants.OPERAND_TYPE_GRAPH, modelAtomicIndex.getIndexSource())) {
Assert.notEmpty(modelAtomicIndex.getQueryLang(), "查询语句不能为空");
// NotePrompt notePrompt = notePromptService.getBaseMapper().selectById(modelAtomicIndex.getPromptId());
// Assert.notNull(notePrompt, "提示词信息不存在");
// String query = promptGenerateGraphQuery(notePrompt, queryTemplate);
// modelAtomicIndex.setQueryLang(query);
}
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public R<?> delAtomic(String id) {
ModelAtomicIndex index = modelAtomicIndexService.getMapper().selectById(id);
index.setDataStatus(DataStatus.NOT_AVAILABLE.getCode());
int i = modelAtomicIndexService.getMapper().updateById(index);
if (i > 0) {
modelAtomicIndexService.whenDeleteAtomicIndex(index.getCaseType(), id);
return R.okMsg("删除成功");
} else {
return R.fail("删除失败");
}
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public List<CaseAtomicIndexDTO> listCaseAtomicIndex(String caseId, String indexSource) {
Assert.notEmpty(caseId, "案件id不能为空");
ModelCase modelCase = modelCaseService.getById(caseId);
Assert.notNull(modelCase, "案件不存在");
String caseType = modelCase.getCaseType();
Assert.notEmpty(caseType, "案件类型不能为空");
List<CasePerson> casePersonList = casePersonMapper.selectList(Wrappers.lambdaQuery(CasePerson.class)
.eq(CasePerson::getCaseId, caseId).eq(CasePerson::getRoleCode, "1"));
Assert.notEmpty(casePersonList, "案件行为人不能为空!");
String actorId = CollUtil.getFirst(casePersonList).getId();
// 获取案件类型对应的指标
List<ModelIndex> modelIndexList = modelIndexMapper.selectList(
Wrappers.lambdaQuery(ModelIndex.class)
.eq(ModelIndex::getCaseType, caseType).eq(ModelIndex::getDataStatus, "1"));
if (CollUtil.isEmpty(modelIndexList)) {
return new ArrayList<>(1);
}
// 从指标中计算出所有原子指标id
List<String> atomicIndexIds = modelIndexList.stream().filter(modelIndex -> StrUtil.isNotEmpty(modelIndex.getJudgeLogic()))
.map(modelIndex -> JudgeLogicUtil.pickAtomicIndexIds(modelIndex.getJudgeLogic()))
.flatMap(Collection::stream).distinct().toList();
if (CollUtil.isEmpty(atomicIndexIds)) {
return new ArrayList<>(1);
}
// 查询原子指标相关信息
List<ModelAtomicIndex> modelAtomicIndexList = modelAtomicIndexService.listCaseAtomicIndex(atomicIndexIds, caseType, indexSource);
if (CollUtil.isEmpty(modelAtomicIndexList)) {
return new ArrayList<>(1);
}
// 查询判定结果数据
List<ModelAtomicResult> modelAtomicResults = modelAtomicResultMapper.selectList(
Wrappers.lambdaQuery(ModelAtomicResult.class).eq(ModelAtomicResult::getCaseId, caseId)
.eq(ModelAtomicResult::getCasePersonId, actorId)
.in(ModelAtomicResult::getAtomicId, atomicIndexIds));
Map<String, Map<String, List<ModelAtomicResult>>> modelAtomicResultGroup = modelAtomicResults.stream()
.filter(modelAtomicResult -> StrUtil.isNotEmpty(modelAtomicResult.getAtomicId()))
.collect(Collectors.groupingBy(ModelAtomicResult::getIndexId, Collectors.groupingBy(ModelAtomicResult::getAtomicId)));
Map<String, List<ModelIndex>> modelIndexMapAtomic = groupModelIndexByAtomicIndexId(modelIndexList);
// 以原子指标为基准,组装数据
return modelAtomicIndexList.stream().flatMap(atomicIndex ->
modelIndexMapAtomic.get(atomicIndex.getId()).stream().map(modelIndex -> {
Map<String, List<ModelAtomicResult>> map = modelAtomicResultGroup.getOrDefault(modelIndex.getId(), new HashMap<>(1));
return new CaseAtomicIndexDTO(atomicIndex, modelIndex, CollUtil.getFirst(map.get(atomicIndex.getId())));
})
).toList();
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public Boolean saveCaseAtomicResult(CaseAtomicResultWrapper caseAtomicResultWrapper) {
Assert.notEmpty(caseAtomicResultWrapper.getCaseId(), "案件id不能为空");
ModelCase modelCase = modelCaseService.getById(caseAtomicResultWrapper.getCaseId());
Assert.notNull(modelCase, "案件不存在!");
// 设置行为人id
CasePerson casePerson = casePersonMapper.selectOne(Wrappers.lambdaQuery(CasePerson.class)
.eq(CasePerson::getCaseId, modelCase.getId()).eq(CasePerson::getRoleCode, "1").eq(CasePerson::getCaseActorFlag, 1));
caseAtomicResultWrapper.setActorId(casePerson.getId());
//清空人工评估结果
removeCaseAtomicResult(caseAtomicResultWrapper.getCaseId(), modelCase.getCaseType(),
caseAtomicResultWrapper.getActorId(), "1");
// 保存原子评估结果
caseAtomicResultWrapper.getCaseAtomicIndexList().stream().map(caseAtomicIndexDTO ->
caseAtomicIndexDTO.toModelAtomicResult(
caseAtomicResultWrapper.getCaseId(), caseAtomicResultWrapper.getActorId())).toList()
.forEach(modelAtomicResultMapper::insert);
caseStatusManageService.whenUpdateIndexResult(caseAtomicResultWrapper.getCaseId());
return true;
}
@Override
public boolean checkSql(String sql) {
log.info("checkSql:{}", sql);
if (StringUtils.isEmpty(sql)) {
return false;
}
if (CollUtil.isEmpty(this.allowedTables)) {
log.info("checkSql:未配置允许的表");
return false;
}
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement sqlStatement = SqlParserUtil.parseStatement(parser);
if (Objects.isNull(sqlStatement)) {
log.warn("checkSql sql:{}语句解析失败", sql);
return false;
}
String sqlType = SqlParserUtil.detectSQLType(sqlStatement);
if (!"SELECT".equals(sqlType)) {
log.warn("checkSql:只支持查询类型语句");
return false;
}
List<String> tableList = SqlParserUtil.extractTableNames(sqlStatement);
if (CollUtil.isEmpty(tableList)) {
log.warn("checkSql:未检测到表");
return false;
}
long count = tableList.stream().filter(table -> !this.allowedTables.contains(table)).count();
if (count > 0) {
log.warn("checkSql:表{}不在允许的表列表中", tableList);
return false;
}
return true;
}
@Override
public Map<String, List<ValueCalculateScopeDTO>> listAtomicIndexAttributeScope(List<String> atomicIndexIds) {
if (CollUtil.isEmpty(atomicIndexIds)) {
return Map.of();
}
Map<String, List<ValueCalculateScopeDTO>> result = atomicIndexIds.stream().collect(Collectors.toMap(i -> i, i -> List.of()));
List<ModelAtomicIndex> atomicIndexList = modelAtomicIndexService.listByIds(atomicIndexIds);
if (CollUtil.isEmpty(atomicIndexList)) {
return result;
}
List<String> promptIds = atomicIndexList.stream().map(ModelAtomicIndex::getPromptId).filter(StrUtil::isNotEmpty).toList();
if (CollUtil.isEmpty(promptIds)) {
return result;
}
List<NotePrompt> notePrompts = notePromptService.listByIds(promptIds);
Map<String, String> dicMap = comDictionaryService.getDictionaryMap("prompt_attribute_valuetype");
for (Map.Entry<String, List<ValueCalculateScopeDTO>> entry : result.entrySet()) {
List<ValueCalculateScopeDTO> scopeDTOList = makeScopes(entry.getKey(), atomicIndexList, notePrompts, dicMap);
if (scopeDTOList != null) {
entry.setValue(scopeDTOList);
}
}
return result;
}
@Override
public GraphDebugResVO graphDebug(GraphDebugReqVO graphDebugDTO) {
GraphDebugResVO graphDebugResVO = new GraphDebugResVO();
if (StrUtil.isEmpty(graphDebugDTO.getCaseId())){
graphDebugResVO.setMessageType("2");
graphDebugResVO.setMessage("请选择案件!");
return graphDebugResVO;
}
CasePerson casePerson = casePersonMapper.selectOne(new LambdaQueryWrapper<>(CasePerson.class)
.eq(CasePerson::getCaseId, graphDebugDTO.getCaseId()).eq(CasePerson::getRoleCode, "1")
.eq(CasePerson::getCaseActorFlag, 1));
Map<String, Object> parameters = new HashMap<>();
parameters.put("caseId", graphDebugDTO.getCaseId());
if (null != casePerson){
parameters.put("lawActor", casePerson.getName());
}
// 执行查询语句
List<Record> records;
try {
records = this.neo4jService.executeCypher(graphDebugDTO.getQueryLang(), parameters);
} catch (Exception e) {
graphDebugResVO.setMessageType("1");
graphDebugResVO.setMessage(e.getMessage());
return graphDebugResVO;
}
if (CollUtil.isNotEmpty(records)){
graphDebugResVO.setRecordTitleList(records.get(0).keys());
}
graphDebugResVO.setRecordList(mapRecords(records));
Pair<List<WebRelDTO>, List<Map<String, String>>> pair = this.neo4jService.mergeRecord(generateNodes(records), generateRelations(records));
graphDebugResVO.setGraphRelList(pair.getKey());
graphDebugResVO.setGraphNodeList(pair.getValue());
// 尝试转换为图形数据
return graphDebugResVO;
}
private List<WebRelDTO> generateRelations(List<Record> records) {
List<WebRelDTO> graphRelList = records.stream().flatMap(record -> record.values().stream())
.filter(value -> value.type().name().equals("RELATIONSHIP"))
.map(value -> {
Relationship relationship = value.asRelationship();
return new WebRelDTO(relationship.id(), relationship.endNodeId(), relationship.type());
})
.collect(Collectors.toList());
// 拓展关系信息
Set<Long> relationIds = new HashSet<>();
for (Record record : records) {
// relId
org.neo4j.driver.Value relValue = record.get("relId");
if (StrUtil.equalsAny(relValue.type().name(), "INTEGER")){
relationIds.add(relValue.asLong());
}
}
if (CollUtil.isNotEmpty(relationIds)){
List<Record> extendRecord = neo4jService.executeCypher("MATCH ()-[r]-() where id(r) in $relationIds return r", Map.of("relationIds", relationIds));
if (CollUtil.isNotEmpty(extendRecord)){
graphRelList.addAll(extendRecord.stream().flatMap(r -> r.values().stream()).map(r -> {
Relationship relationship = r.asRelationship();
return new WebRelDTO(relationship.startNodeId(), relationship.endNodeId(), relationship.type());
}).toList());
}
}
Set<String> relIdSet = new HashSet<>();
return graphRelList.stream().filter(map -> relIdSet.add(StrUtil.join("-", map.getSource(), map.getTarget()))).toList();
}
private List<Map<String, String>> generateNodes(List<Record> records) {
List<Map<String, String>> graphNodeList = records.stream().flatMap(record -> record.values().stream())
.filter(value -> value.type().name().equals("NODE")).map(value ->{
Map<String, String> map = new HashMap<>();
Node node = value.asNode();
map.put("id", String.valueOf(node.id()));
map.put("name", node.get("name").asString());
map.put("entityName", node.get("name").asString());
return map;
}
).collect(Collectors.toList());
// 拓展节点信息
Set<Long> nodeIds = new HashSet<>();
for (Record record : records) {
// startId ,endId
org.neo4j.driver.Value startValue = record.get("startId");
org.neo4j.driver.Value endValue = record.get("endId");
if (StrUtil.equalsAny(startValue.type().name(), "INTEGER")){
nodeIds.add(startValue.asLong());
}
if (StrUtil.equalsAny(endValue.type().name(), "INTEGER")){
nodeIds.add(endValue.asLong());
}
}
if (CollUtil.isNotEmpty(nodeIds)){
List<Record> extendRecord = neo4jService.executeCypher("MATCH (n) where id(n) in $nodeIds return n", Map.of("nodeIds", nodeIds));
if (CollUtil.isNotEmpty(extendRecord)){
graphNodeList.addAll(extendRecord.stream().flatMap(r -> r.values().stream()).map(r -> {
Map<String, String> map = new HashMap<>();
map.put("id", String.valueOf(r.asNode().id()));
map.put("name", r.get("name").asString());
map.put("entityName", r.get("name").asString());
return map;
}).toList());
}
}
Set<String> nodeIdSet = new HashSet<>();
return graphNodeList.stream().filter(map -> nodeIdSet.add(map.get("id"))).toList();
}
private List<Map<String, Object>> mapRecords(List<Record> records) {
List<Map<String, Object>> recordList = new ArrayList<>();
for (Record record : records) {
HashMap<String, Object> map = new HashMap<>();
for (String key : record.keys()) {
org.neo4j.driver.Value value = record.get(key);
String typeName = value.type().name();
if (typeName.equals("NULL")){
map.put(key,null);
}
if (StrUtil.equalsAny(typeName, "BOOLEAN","STRING", "NUMBER", "INTEGER", "FLOAT")){
// MATCH (n)-[r]-() where n.caseId= '1' RETURN n.recordId limit 10
map.put(key,value.asObject());
}
if (typeName.equals("PATH")){
// MATCH p=(n)-[*2]-() where n.caseId= '1' RETURN p limit 10
map.put(key,new PathDTO(value.asPath()));
}
if (typeName.equals("RELATIONSHIP")){
// MATCH (n)-[r]-() where n.caseId= '1' RETURN r limit 10
map.put(key,new RelationshipValueDTO((InternalRelationship) value.asRelationship()));
}
if (typeName.equals("LIST OF ANY?")){
List<RelationshipValueDTO> list = value.asList().stream()
.map(i -> new RelationshipValueDTO((InternalRelationship) i)).toList();
map.put(key,list);
}
if (typeName.equals("NODE")){
// MATCH (n)-[r]-() where n.caseId= '1' RETURN r limit 10
map.put(key,new NodeDTO((InternalNode) value.asNode()));
}
recordList.add(map);
}
}
return recordList;
}
private List<ValueCalculateScopeDTO> makeScopes(String atomicIndexId, List<ModelAtomicIndex> atomicIndexList, List<NotePrompt> notePrompts, Map<String, String> dicMap) {
ModelAtomicIndex modelAtomicIndex = atomicIndexList.stream().filter(i -> StrUtil.equals(atomicIndexId, i.getId())).findFirst().orElse(null);
if (null == modelAtomicIndex || StrUtil.isEmpty(modelAtomicIndex.getPromptId())) {
return null;
}
String properties = modelAtomicIndex.getProperties();
if (StrUtil.isEmpty(properties)) {
return null;
}
NotePrompt notePromptDTO = notePrompts.stream().filter(i -> StrUtil.equals(modelAtomicIndex.getPromptId(), i.getId())).findFirst().orElse(null);
if (null == notePromptDTO) {
return null;
}
List<NotePromptExtractAttributesDto> extractAttributes = notePromptDTO.getExtractAttributes();
if (CollUtil.isNotEmpty(extractAttributes)) {
return extractAttributes.stream().map(extractAttribute -> {
ValueCalculateScopeDTO valueCalculateScope = new ValueCalculateScopeDTO();
valueCalculateScope.setValue(extractAttribute.getAttrName());
valueCalculateScope.setValueType(extractAttribute.getAttrValueType());
valueCalculateScope.setValueTypeDesc(dicMap.get(extractAttribute.getAttrValueType()));
valueCalculateScope.setOperatorList(
IndexRuleConstants.VALUE_TYPE_OPERATOR_MAPPING.get(extractAttribute.getAttrValueType()));
Map<String, String> map = IndexRuleConstants.VALUE_TYPE_AGGREGATE_MAPPING.getOrDefault(valueCalculateScope.getValueType(),new HashMap<>());
valueCalculateScope.setAggregateList(map.entrySet().stream().map(entry -> new Pair<>(entry.getKey(), entry.getValue())).toList());
return valueCalculateScope;
}).toList();
}
return null;
}
/**
* 清空案件下的评估结果
*
* @param caseId 案件id
* @param caseType 案件类型
* @param actorId 行为人id
* @param indexSource 原子指标来源
*/
private void removeCaseAtomicResult(String caseId, String caseType, String actorId, String indexSource) {
List<ModelAtomicIndex> modelAtomicIndexList = modelAtomicIndexService.listCaseAtomicIndex(null, caseType, indexSource);
List<String> atomicIndexIds = modelAtomicIndexList.stream().map(ModelAtomicIndex::getId).distinct().toList();
modelAtomicResultMapper.delete(Wrappers.lambdaQuery(ModelAtomicResult.class)
.eq(ModelAtomicResult::getCaseId, caseId)
.eq(ModelAtomicResult::getCasePersonId, actorId)
.in(CollUtil.isNotEmpty(atomicIndexIds), ModelAtomicResult::getAtomicId, atomicIndexIds));
}
private Map<String, List<ModelIndex>> groupModelIndexByAtomicIndexId(List<ModelIndex> modelIndexList) {
Map<String, List<ModelIndex>> groupMap = new HashMap<>();
if (CollUtil.isEmpty(modelIndexList)) {
return groupMap;
}
for (ModelIndex modelIndex : modelIndexList) {
if (StrUtil.isEmpty(modelIndex.getJudgeLogic())) {
continue;
}
String judgeLogic = modelIndex.getJudgeLogic();
List<JudgeLogic> judgeLogicList = JSONUtil.toList(judgeLogic, JudgeLogic.class);
for (JudgeLogic logic : judgeLogicList) {
List<AtomicData> atomicData = logic.getAtomicData();
if (CollUtil.isEmpty(atomicData)) {
continue;
}
for (AtomicData atomic : atomicData) {
List<ModelIndex> modelIndexs = groupMap.getOrDefault(atomic.getAtomicIndex(), new ArrayList<>());
modelIndexs.add(modelIndex);
groupMap.put(atomic.getAtomicIndex(), modelIndexs);
}
}
}
return groupMap;
}
}