You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fu-hsi-service/src/main/java/com/supervision/police/service/impl/ModelCaseServiceImpl.java

373 lines
17 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.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
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.chat.UploadParamEnum;
import com.supervision.chat.client.LangChainChatService;
import com.supervision.chat.client.dto.CreateBaseDTO;
import com.supervision.chat.client.dto.LangChainChatRes;
import com.supervision.common.domain.R;
import com.supervision.common.enums.ResultStatusEnum;
import com.supervision.common.exception.CustomException;
import com.supervision.common.utils.ExcelReader;
import com.supervision.common.utils.IPages;
import com.supervision.common.utils.StringUtils;
import com.supervision.config.BusinessException;
import com.supervision.constant.DataStatus;
import com.supervision.police.domain.CasePerson;
import com.supervision.police.domain.ComDictionary;
import com.supervision.police.dto.*;
import com.supervision.police.mapper.ModelCaseMapper;
import com.supervision.police.domain.ModelCase;
import com.supervision.police.service.CasePersonService;
import com.supervision.police.service.CaseStatusManageService;
import com.supervision.police.service.ComDictionaryService;
import com.supervision.police.service.ModelCaseService;
import com.supervision.police.vo.ModelCaseVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
/**
* 案件表(ModelCase)表服务实现类
*
* @author qmy
* @since 2024-07-02 14:51:27
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class ModelCaseServiceImpl extends ServiceImpl<ModelCaseMapper, ModelCase> implements ModelCaseService {
private final ComDictionaryService comDictionaryService;
private final ModelCaseMapper modelCaseMapper;
private final CasePersonService casePersonService;
private final CaseStatusManageService caseStatusManageService;
private final LangChainChatService langChainChatService;
/**
* 查询列表
*
* @param modelCase
* @param page
* @param size
* @return
*/
@Override
public IPage<ModelCaseDTO> queryList(ModelCaseVO modelCase, Integer page, Integer size) {
IPage<ModelCase> modelCaseIPage = modelCaseMapper.selectAll(Page.of(page, size), modelCase);
if (CollUtil.isEmpty(modelCaseIPage.getRecords())) {
return Page.of(page, size);
}
List<String> caseIdList = modelCaseIPage.getRecords().stream().map(ModelCase::getId).toList();
List<CasePerson> casePersonList = casePersonService.list(
Wrappers.lambdaQuery(CasePerson.class).in(CasePerson::getCaseId, caseIdList));
// 多级分组
Map<String, Map<String, List<CasePerson>>> persionMap = casePersonList.stream().collect(Collectors.groupingBy(CasePerson::getCaseId,
Collectors.groupingBy(person -> NumberUtil.equals(person.getCaseActorFlag(), 1) ? "1" : "2")));
List<ComDictionary> dicts = comDictionaryService.list();
return modelCaseIPage.convert(modelCaseInfo -> {
ModelCaseDTO modelCaseDTO = BeanUtil.toBean(modelCaseInfo, ModelCaseDTO.class, CopyOptions.create().setIgnoreProperties("lawActor"));
String[] caseTypes = modelCaseDTO.getCaseType().split(",");
List<String> caseType = new ArrayList<>();
for (String type : caseTypes) {
caseType.add(comDictionaryService.getName(dicts, "case_type", type));
}
if (StrUtil.isEmpty(modelCaseDTO.getCaseStatus())) {
modelCaseDTO.setCaseStatus("1");
}
modelCaseDTO.setCaseTypeName(StringUtils.join(caseType, ","));
modelCaseDTO.setCaseStatusName(comDictionaryService.getName(dicts, "case_status", modelCaseDTO.getCaseStatus()));
modelCaseDTO.setCrimeModeName(comDictionaryService.getName(dicts, "crime_mode", modelCaseDTO.getCrimeMode()));
modelCaseDTO.setIdentifyResultName(comDictionaryService.getName(dicts, "identify_result", modelCaseDTO.getIdentifyResult()));
Map<String, List<CasePerson>> casePersonMap = persionMap.get(modelCaseDTO.getId());
if (CollUtil.isNotEmpty(casePersonMap)) {
Optional<CasePerson> optionalCasePerson = casePersonMap.getOrDefault("1", new ArrayList<>())
.stream().filter(person -> Integer.valueOf(1).equals(person.getCaseActorFlag())).findAny();
if (optionalCasePerson.isPresent()){
modelCaseDTO.setLawActor(optionalCasePerson.get());
modelCaseDTO.floatLawActorInfo();
}
modelCaseDTO.setLawPartyList(casePersonMap.getOrDefault("2", new ArrayList<>()));
}
if (Objects.isNull(modelCaseDTO.getLawPartyList())) {
modelCaseDTO.setLawPartyList(new ArrayList<>());
}
return modelCaseDTO;
});
}
@Override
public R<?> checkCaseNo(String caseNo, String caseId) {
Long count = modelCaseMapper.selectCount(new LambdaQueryWrapper<ModelCase>()
.eq(ModelCase::getCaseNo, caseNo)
.eq(ModelCase::getDataStatus, "1")
.ne(StrUtil.isNotEmpty(caseId), ModelCase::getId, caseId));
if (count == 0) {
return R.ok(caseNo);
} else {
return R.okMsg("案件编号已存在,请勿重复添加");
}
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public R<?> addOrUpd(ModelCaseBase modelCaseBase) {
int i = 0;
if (StrUtil.isBlank(modelCaseBase.getCaseNo())) {
throw new BusinessException("案件编号不能为空");
}
ModelCase modelCase = modelCaseBase.toModelCase();
if (modelCase.getId() != null) {
// 如果更新,则校验案件编码,案件编码不允许修改(案件编码作为和知识库交互的主键,是唯一的)
ModelCase exist = modelCaseMapper.selectById(modelCase.getId());
if (!StrUtil.equals(exist.getCaseNo(), modelCase.getCaseNo())) {
throw new BusinessException("案件编号不允许修改");
}
i = modelCaseMapper.updateById(modelCase);
} else {
Long num = modelCaseMapper.selectCount(null);
modelCase.setIndexNum(Integer.parseInt(num.toString()) + 1);
i = modelCaseMapper.insert(modelCase);
// 保存案件行为人
casePersonService.saveCaseActor(modelCase.getId(), modelCaseBase.getCaseActorName(), modelCaseBase.getCaseActorIdCard());
// 这里需要调用知识库的接口,去保存知识库
CreateBaseDTO createBaseDTO = new CreateBaseDTO();
createBaseDTO.setKnowledge_base_name(modelCase.getCaseNo());
LangChainChatRes chat = langChainChatService.createBase(createBaseDTO);
log.info("创建知识库:{}", chat);
if (200 != chat.getCode()) {
throw new BusinessException("保存知识库失败");
}
}
if (i > 0) {
return R.okMsg("保存成功");
} else {
return R.fail("保存失败");
}
}
@Override
public R<?> del(String id) {
ModelCase modelCase = modelCaseMapper.selectById(id);
LangChainChatRes langChainChatRes = langChainChatService.deleteBase(modelCase.getCaseNo());
if (200 != langChainChatRes.getCode()){
log.info("删除知识库失败");
}
modelCase.setDataStatus(DataStatus.NOT_AVAILABLE.getCode());
int i = modelCaseMapper.updateById(modelCase);
if (i > 0) {
return R.okMsg("删除成功");
} else {
return R.fail("删除失败");
}
}
@Override
public R<List<CasePerson>> getPerson(String caseId, String name) {
LambdaQueryWrapper<CasePerson> wrapper = Wrappers.lambdaQuery();
wrapper.eq(CasePerson::getCaseId, caseId)
.like(StrUtil.isNotEmpty(name), CasePerson::getName, name);
List<CasePerson> casePeople = casePersonService.list(wrapper);
List<ComDictionary> dicts = comDictionaryService.list();
for (CasePerson cp : casePeople) {
cp.setRoleName(comDictionaryService.getName(dicts, "case_role", cp.getRoleCode()));
}
return R.ok(casePeople);
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public R<?> addPerson(CasePerson person) {
Assert.notEmpty(person.getCaseId(), "案件id不能为空");
Assert.notEmpty(person.getIdCard(), "身份证号不能为空");
Assert.notEmpty(person.getName(), "姓名不能为空");
Assert.notEmpty(person.getRoleCode(), "角色不能为空");
long count = casePersonService.count(new LambdaQueryWrapper<CasePerson>()
.eq(CasePerson::getCaseId, person.getCaseId()).eq(CasePerson::getIdCard, person.getIdCard()));
Assert.isTrue(count == 0, "该身份证号已存在");
boolean success = casePersonService.save(person);
if (success) {
caseStatusManageService.whenSaveCasePeople(person.getCaseId(), person);
return R.okMsg("新增成功");
} else {
return R.fail("新增失败");
}
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public boolean updatePerson(CasePerson person) {
Assert.notEmpty(person.getId(), "id不能为空");
Assert.notEmpty(person.getCaseId(), "案件id不能为空");
Assert.notEmpty(person.getIdCard(), "身份证号不能为空");
Assert.notEmpty(person.getName(), "姓名不能为空");
Assert.notEmpty(person.getRoleCode(), "角色不能为空");
CasePerson casePerson = casePersonService.getById(person.getId());
Assert.notNull(casePerson, "该人员不存在");
Assert.isFalse(Integer.valueOf(1).equals(casePerson.getCaseActorFlag()), "该人员为案件行为人,不能修改");
boolean update = casePersonService.lambdaUpdate().eq(CasePerson::getId, person.getId())
.set(CasePerson::getIdCard, person.getIdCard())
.set(CasePerson::getName, person.getName())
.set(CasePerson::getRoleCode, person.getRoleCode())
.update();
if (update){
caseStatusManageService.whenSaveCasePeople(person.getCaseId(), person);
}
return update;
}
@Override
public R<?> uploadCase(MultipartFile file) {
/**
* 检查文件格式
*/
String fileName = file.getOriginalFilename();
assert fileName != null;
// 截取文件的类型符
String substring = fileName.substring(fileName.lastIndexOf(".") + 1);
if (!("xls".equals(substring) || "xlsx".equals(substring))) {
throw new CustomException(ResultStatusEnum.INCORRECT_FILE_FORMAT);// 响应“文件格式不正确”异常
}
List<ModelCase> putList = new ArrayList<>();
try {
putList = ExcelReader.getCaseList(file.getInputStream(), substring, null);
} catch (IOException e) {
e.printStackTrace();
throw new CustomException(ResultStatusEnum.UPLOAD_EXCEPTION);// 响应“文件上传异常”错误
}
List<ComDictionary> dicts = comDictionaryService.list();
/**
* 读取bean列表导入到数据库中
*/
List<Map<String, Object>> errorList = new ArrayList<>();
int index = modelCaseMapper.selectMaxIndex() + 1;
int add = 0;
for (ModelCase modelCase : putList) {
if (StringUtils.isEmpty(modelCase.getCaseNo()) || StringUtils.isEmpty(modelCase.getCaseName())
|| StringUtils.isEmpty(modelCase.getCaseTypeName()) || StringUtils.isEmpty(modelCase.getCaseStatusName())
|| StringUtils.isEmpty(modelCase.getCrimeModeName())) {
errorList.add(errorMapBuilder(modelCase, "必填项为空"));
continue;
}
//替换字典项
String[] split = modelCase.getCaseTypeName().split(",");
List<String> caseTypes = new ArrayList<>();
for (String type : split) {
caseTypes.add(comDictionaryService.getValue(dicts, "case_type", type));
}
modelCase.setCaseType(StringUtils.join(caseTypes, ","));
modelCase.setCaseStatus(comDictionaryService.getValue(dicts, "case_status", modelCase.getCaseStatusName()));
modelCase.setCrimeMode(comDictionaryService.getValue(dicts, "crime_mode", modelCase.getCrimeModeName()));
modelCase.setIndexNum(index);
modelCaseMapper.insert(modelCase);
add++;
index++;
}
Map<String, Object> returnMap = new HashMap<>();
returnMap.put("errorList", errorList);
returnMap.put("add", add);
return R.ok(returnMap);
}
private Map<String, Object> errorMapBuilder(ModelCase modelCase, String errorText) {
return new HashMap<String, Object>(2) {{
put("caseNo", modelCase.getCaseNo());
put("caseName", modelCase.getCaseName());
put("errorText", errorText);
}};
}
@Override
public R<?> getIndexDetail(String caseId, String indexType, Integer page, Integer size) {
IPage<IndexDetail> iPage = new Page<>(page, size);
iPage = modelCaseMapper.getIndexDetail(iPage, caseId, indexType);
List<IndexDetail> records = iPage.getRecords();
for (IndexDetail record : records) {
if (StringUtils.isEmpty(record.getAtomicIds())) {
continue;
}
// 是否是新的结果
record.setNewFlag(!StrUtil.equals(record.getIndexResult(), record.getPreResult()));
String judgeLogic = record.getJudgeLogic();
Map<String, String> indexJundgeLogicMap = parseLogicMap(judgeLogic);
String[] array = record.getAtomicIds().split(",");
List<String> atomicIds = Arrays.asList(array);
List<AtomicIndexDTO> atomics = modelCaseMapper.getAtomicDetail(caseId, atomicIds);
for (AtomicIndexDTO atomic : atomics) {
// 需要和原子指标的规则判断是否一致(解决出罪和入罪冲突的问题)
String s = indexJundgeLogicMap.get(atomic.getAtomicIndexId());
atomic.judgeWithIndexResult(s);
if (StrUtil.isBlank(atomic.getRecord())) {
atomic.setRecord("无");
}
}
record.setRecord("无");
// 遍历,atomic的record字段存在不为空,且不是无的,如果有,就是有
if (atomics.stream().anyMatch(atomic -> StrUtil.isNotBlank(atomic.getRecord()) && !StrUtil.equals("无", atomic.getRecord()))) {
record.setRecord("有");
}
record.setChildren(atomics);
}
iPage.setRecords(records);
return R.ok(IPages.buildDataMap(iPage));
}
private Map<String, String> parseLogicMap(String judgeLogic) {
List<JudgeLogic> judgeLogics = JSONUtil.toList(judgeLogic, JudgeLogic.class);
Map<String, String> resultMap = new HashMap<>();
for (JudgeLogic logic : judgeLogics) {
for (AtomicData atomicDatum : logic.getAtomicData()) {
// 原子指标结果 -1:未知, 0:不存在, 1存在
if (atomicDatum.getRelationalSymbol().equals("1") || atomicDatum.getRelationalSymbol().equals("3")) {
resultMap.put(atomicDatum.getAtomicIndex(), "1");
} else if (atomicDatum.getRelationalSymbol().equals("2") || atomicDatum.getRelationalSymbol().equals("4")) {
resultMap.put(atomicDatum.getAtomicIndex(), "0");
} else {
resultMap.put(atomicDatum.getAtomicIndex(), "-1");
}
}
}
return resultMap;
}
}