package cn.huge.module.ai.service;
|
|
import cn.huge.base.common.utils.*;
|
import cn.huge.module.ai.domain.dto.CaseInfoDto;
|
import cn.huge.module.ai.domain.dto.LawInfoDto;
|
import cn.huge.module.ai.domain.po.CaseSimilarityRelations;
|
import cn.huge.module.ai.domain.po.CpwsCaseInfo;
|
import cn.huge.module.ai.domain.po.DyhCaseInfo;
|
import cn.huge.module.ai.domain.po.LawProvision;
|
import cn.huge.module.ai.domain.po.LawSimilarityRelations;
|
import cn.huge.module.ai.domain.vo.AiRequestVo;
|
import cn.huge.module.client.api.impl.KnowledgeCaseClientImpl;
|
import cn.huge.module.constant.AiCaseType;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Service;
|
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
import static cn.huge.module.ai.service.AiCaseClassService.httpPostRaw;
|
|
@Slf4j
|
@Service
|
public class AiSimilarityCaseService {
|
|
@Value("${dify.url}")
|
private String difyUrl;
|
|
@Value("${dify.getSimilarityDyhCaseApi}")
|
private String getSimilarityDyhCaseApi;
|
@Value("${dify.getSimilarityDyhCaseNum}")
|
private String getSimilarityDyhCaseNum;
|
|
@Value("${dify.getSimilarityCpwsCaseApi}")
|
private String getSimilarityCpwsCaseApi;
|
// @Value("${dify.getSimilarityCpwsCaseNum}")
|
// private String getSimilarityCpwsCaseNum;
|
|
|
@Value("${dify.getCaseLawApi}")
|
private String getCaseLawApi;
|
@Value("${dify.getCaseLawNum}")
|
private String getCaseLawNum;
|
|
|
@Value("${dify.user}")
|
private String user;
|
|
@Autowired
|
private KnowledgeCaseClientImpl knowledgeCaseClient;
|
|
public Object getSimilarityCase(AiRequestVo aiRequestVo) {
|
// 先从缓存获取
|
Object cacheAi = GuavaCacheUtils.getCacheAi("getSimilarityCase" + aiRequestVo.getCaseId());
|
if (ObjectUtils.isNotEmpty(cacheAi)) {
|
return ReturnSucUtils.getRepInfo("请求成功", cacheAi);
|
}
|
|
// 先检查数据库中是否存在相似案件关系
|
CaseSimilarityRelations relations = new CaseSimilarityRelations();
|
relations.setCaseId(aiRequestVo.getCaseId());
|
List<CaseSimilarityRelations> existingRelations = knowledgeCaseClient.checkRelations(relations);
|
|
// 如果数据库中没有数据,则调用AI服务
|
if (existingRelations == null || existingRelations.isEmpty()) {
|
JSONObject dyhResponse = requestSimilarCases(aiRequestVo, getSimilarityDyhCaseApi);
|
JSONObject cpwsResponse = requestSimilarCases(aiRequestVo, getSimilarityCpwsCaseApi);
|
if (dyhResponse == null && cpwsResponse == null) {
|
log.error("获取相似案件响应异常");
|
return ReturnSucUtils.getRepInfo("获取相似案件失败", null);
|
}
|
// AI调用后重新获取数据库中的关系
|
existingRelations = knowledgeCaseClient.checkRelations(relations);
|
if (existingRelations == null || existingRelations.isEmpty()) {
|
return ReturnSucUtils.getRepInfo("未找到相似案件", null);
|
}
|
}
|
|
// 转换为前端所需的数据格式
|
List<CaseInfoDto> caseInfoDtoList = convertToCaseInfoList(existingRelations);
|
|
// 放入缓存
|
if (!caseInfoDtoList.isEmpty()) {
|
GuavaCacheUtils.putCacheAi("getSimilarityCase" + aiRequestVo.getCaseId(), caseInfoDtoList);
|
}
|
|
return ReturnSucUtils.getRepInfo("请求成功", caseInfoDtoList);
|
}
|
|
/**
|
* 请求相似案件
|
* @param aiRequestVo 请求参数
|
* @param apiKey API密钥
|
* @return JSONObject 响应结果
|
*/
|
private JSONObject requestSimilarCases(AiRequestVo aiRequestVo, String apiKey) {
|
// 构建请求参数
|
Map<String, Object> requestBody = new HashMap<>();
|
Map<String, Object> inputs = new HashMap<>();
|
inputs.put("caseText", aiRequestVo.getCaseDes() + "\n" + aiRequestVo.getCaseClaim());
|
inputs.put("caseId", aiRequestVo.getCaseId());
|
inputs.put("topK", getSimilarityDyhCaseNum);
|
requestBody.put("inputs", inputs);
|
requestBody.put("response_mode", "blocking");
|
requestBody.put("user", user);
|
|
// 设置请求头
|
Map<String, String> headers = new HashMap<>();
|
headers.put("Authorization", "Bearer " + apiKey);
|
String response;
|
try {
|
log.info("requestBody:{}", requestBody);
|
response = httpPostRaw(difyUrl + "/workflows/run",
|
JSONObject.toJSONString(requestBody), headers, "utf-8");
|
} catch (Exception e) {
|
log.error("获取相似案件失败: {}", e.getMessage());
|
return JSONObject.parseObject("{'msg':'获取相似案件失败'}");
|
}
|
return JSONObject.parseObject(response);
|
}
|
|
/**
|
* 将相似案件关系转换为案件信息列表
|
* @param relations 相似案件关系列表
|
* @return List<CaseInfoDto> 案件信息列表
|
*/
|
private List<CaseInfoDto> convertToCaseInfoList(List<CaseSimilarityRelations> relations) {
|
List<CaseInfoDto> caseInfoDtoList = new ArrayList<>();
|
for (CaseSimilarityRelations relation : relations) {
|
int similarityCaseType = Integer.parseInt(relation.getSimilarityCaseType());
|
DyhCaseInfo caseInfo = new DyhCaseInfo();
|
try {
|
if (similarityCaseType == AiCaseType.AI_CASE_TYPE_DYH) {
|
|
caseInfo = knowledgeCaseClient.getCaseTitleById(relation.getSimilarityCaseId());
|
} else if (similarityCaseType == AiCaseType.AI_CASE_TYPE_JUD) {
|
CpwsCaseInfo cpwsCaseInfo = knowledgeCaseClient.getCpwsCaseTitleById(relation.getSimilarityCaseId());
|
if (ObjectUtils.isNotEmpty(cpwsCaseInfo)) {
|
caseInfo.setId(cpwsCaseInfo.getCpwsCaseInfoId());
|
caseInfo.setCaseTitle(cpwsCaseInfo.getCaseName());
|
}
|
}
|
if (caseInfo.getCaseTitle() != null) {
|
log.info("获取案件标题成功, caseId: {}, caseTitle: {}", caseInfo.getId(), caseInfo.getCaseTitle());
|
CaseInfoDto caseInfoDto = new CaseInfoDto();
|
caseInfoDto.setCaseId(relation.getSimilarityCaseId());
|
caseInfoDto.setCaseName(caseInfo.getCaseTitle());
|
caseInfoDto.setCaseType(similarityCaseType);
|
caseInfoDtoList.add(caseInfoDto);
|
}else{
|
log.error("获取案件标题失败, caseId: {},当前案件标题为空", relation.getSimilarityCaseId());
|
// 如果获取标题失败,使用关系表中的标题作为后备
|
CaseInfoDto caseInfoDto = new CaseInfoDto();
|
caseInfoDto.setCaseId(relation.getSimilarityCaseId());
|
caseInfoDto.setCaseName("-");
|
caseInfoDto.setCaseType(similarityCaseType);
|
caseInfoDtoList.add(caseInfoDto);
|
}
|
} catch (Exception e) {
|
log.error("获取案件标题失败, caseId: {}, error: {}", relation.getSimilarityCaseId(), e.getMessage());
|
}
|
}
|
return caseInfoDtoList;
|
}
|
|
/**
|
* 获取AI推荐法条
|
*/
|
public Object getCaseLaw(AiRequestVo aiRequestVo) {
|
// 先从缓存获取
|
Object cacheAi = GuavaCacheUtils.getCacheAi("get-law" + aiRequestVo.getCaseId());
|
if (ObjectUtils.isNotEmpty(cacheAi)) {
|
return ReturnSucUtils.getRepInfo("请求成功", cacheAi);
|
}
|
|
// 先检查数据库中是否存在案件法条关系
|
LawSimilarityRelations relations = new LawSimilarityRelations();
|
relations.setCaseId(aiRequestVo.getCaseId());
|
List<LawSimilarityRelations> existingRelations = knowledgeCaseClient.checkLawRelations(relations);
|
|
List<LawInfoDto> lawInfoDtos = new ArrayList<>();
|
|
// 如果数据库中没有数据,则调用AI服务
|
if (existingRelations == null || existingRelations.isEmpty()) {
|
JSONObject aiResponse = requestCaseLaw(aiRequestVo);
|
if (aiResponse == null) {
|
return ReturnSucUtils.getRepInfo("获取AI推荐法条失败", null);
|
}
|
// AI调用后重新获取数据库中的关系
|
existingRelations = knowledgeCaseClient.checkLawRelations(relations);
|
if (existingRelations == null || existingRelations.isEmpty()) {
|
return ReturnSucUtils.getRepInfo("未找到推荐法条", null);
|
}
|
}
|
|
// 转换为前端所需的数据格式
|
lawInfoDtos = convertToLawInfoList(existingRelations);
|
|
// 放入缓存
|
if (!lawInfoDtos.isEmpty()) {
|
GuavaCacheUtils.putCacheAi("get-law" + aiRequestVo.getCaseId(), lawInfoDtos);
|
}
|
|
return ReturnSucUtils.getRepInfo("请求成功", lawInfoDtos);
|
}
|
|
/**
|
* 请求AI推荐法条
|
*/
|
private JSONObject requestCaseLaw(AiRequestVo aiRequestVo) {
|
try {
|
// 构建请求参数
|
Map<String, Object> requestBody = new HashMap<>();
|
Map<String, Object> inputs = new HashMap<>();
|
inputs.put("caseText", aiRequestVo.getCaseDes() + "\n" + aiRequestVo.getCaseClaim());
|
inputs.put("caseId", aiRequestVo.getCaseId());
|
requestBody.put("inputs", inputs);
|
requestBody.put("response_mode", "blocking");
|
inputs.put("topK", getCaseLawNum);
|
requestBody.put("user", user);
|
|
// 设置请求头
|
Map<String, String> headers = new HashMap<>();
|
headers.put("Authorization", "Bearer " + getCaseLawApi);
|
|
log.info("请求AI推荐法条, requestBody: {}", requestBody);
|
log.info("请求AI推荐法条, headers: {}", headers);
|
String response = httpPostRaw(difyUrl + "/workflows/run",
|
JSONObject.toJSONString(requestBody), headers, "utf-8");
|
|
return JSONObject.parseObject(response);
|
} catch (Exception e) {
|
log.error("获取AI推荐法条失败: {}", e.getMessage());
|
return null;
|
}
|
}
|
|
/**
|
* 将法条关系转换为法条信息列表
|
*/
|
private List<LawInfoDto> convertToLawInfoList(List<LawSimilarityRelations> relations) {
|
List<LawInfoDto> lawInfoDtos = new ArrayList<>();
|
for (LawSimilarityRelations relation : relations) {
|
try {
|
LawInfoDto lawInfoDto = new LawInfoDto();
|
lawInfoDto.setLawInfoId(relation.getLawProvisionId());
|
LawProvision lawProvision = knowledgeCaseClient.getLawProvisionById(relation.getLawProvisionId());
|
if (lawProvision != null) {
|
lawInfoDto.setLawIndex(lawProvision.getProvisionIndex());
|
lawInfoDto.setLawDesc(lawProvision.getProvisionText());
|
lawInfoDto.setLawTitle(relation.getLawTitle());
|
lawInfoDtos.add(lawInfoDto);
|
}
|
} catch (Exception e) {
|
log.error("转换法条信息失败, lawId: {}, error: {}", relation.getLawInfoId(), e.getMessage());
|
}
|
}
|
return lawInfoDtos;
|
}
|
|
}
|