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 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 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 requestBody = new HashMap<>(); Map 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 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 案件信息列表 */ private List convertToCaseInfoList(List relations) { List 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 existingRelations = knowledgeCaseClient.checkLawRelations(relations); List 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 requestBody = new HashMap<>(); Map 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 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 convertToLawInfoList(List relations) { List 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; } }