123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 |
- package cn.cslg.pas.service.dify;
- import cn.cslg.pas.common.model.dify.*;
- import cn.cslg.pas.common.model.dify.confessionSession.AddConfessionSessionDTO;
- import cn.cslg.pas.common.utils.ClaimUtils.ClaimSplitUtils;
- import cn.cslg.pas.common.utils.DateUtils;
- import cn.cslg.pas.common.utils.FileUtils;
- import cn.cslg.pas.common.utils.StringUtils;
- import cn.cslg.pas.common.vo.PatentRightParams;
- import cn.cslg.pas.common.vo.RePatentClaim;
- import cn.cslg.pas.domain.business.ReportProject;
- import cn.cslg.pas.domain.business.ReportTemple;
- import cn.cslg.pas.domain.dify.AssoConfessionSessionFile;
- import cn.cslg.pas.domain.dify.ConfessionSession;
- import cn.cslg.pas.exception.ExceptionEnum;
- import cn.cslg.pas.exception.XiaoShiException;
- import cn.cslg.pas.service.business.ReportTempleService;
- import cn.cslg.pas.service.common.DifyService;
- import cn.cslg.pas.service.common.FileManagerService;
- import cn.hutool.core.util.IdUtil;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.deepoove.poi.XWPFTemplate;
- import com.deepoove.poi.config.Configure;
- import com.google.gson.Gson;
- import okhttp3.MediaType;
- import okhttp3.OkHttpClient;
- import okhttp3.Request;
- import okhttp3.RequestBody;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Service;
- import reactor.core.publisher.Flux;
- import reactor.core.publisher.FluxSink;
- import java.io.File;
- import java.io.IOException;
- import java.util.*;
- import java.util.concurrent.TimeUnit;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import java.util.stream.Collectors;
- @Service
- public class GenerateInstructionService {
- @Autowired
- private ReportTempleService templeService;
- @Autowired
- private FileUtils fileUtils;
- @Autowired
- private AssoConfessionSessionFileService assoConfessionSessionFileService;
- @Autowired
- private DifyService difyService;
- @Autowired
- private FileManagerService fileManagerService;
- @Autowired
- private ConfessionSessionService confessionSessionService;
- private final static String ALL_START = "all_start";
- private final static String ALL_END = "all_end";
- private final static String START = "start";
- private final static String END = "end";
- private final static String MESSAGE = "message";
- private final static String FIELD_TITLE = "title";
- private final static String FIELD_TECHNICAL = "technical";
- private final static String FIELD_IMPLEMENTATION = "implementation";
- private final static String FIELD_BACKGROUND = "background";
- private final static String FIELD_CONTENT = "content";
- private final static String ERROR = "error";
- private Integer SESSION_ID;
- @Value("${DIFY.gInstructionKey}")
- private String gInstructionKey;
- public String getClaimContent(String claim) {
- // 正则表达式模式(注意 Java 中需要双反斜杠转义)
- String regex = "其特征在于[,。;!?、]+(.+)";
- Pattern pattern = Pattern.compile(regex);
- Matcher matcher = pattern.matcher(claim);
- if (matcher.find()) {
- // 提取第一个捕获组的内容(即括号内的部分)
- return matcher.group(1).trim();
- }
- return "其中," + claim; // 未找到匹配时返回空字符串
- }
- public String getMainClaimContent(String claim) {
- // 正则表达式模式(注意 Java 中需要双反斜杠转义)
- // String regex1 = "^[0-9]+\\.";
- // String regex2 = "^\\[[0-9]+]";
- // String regex3 = "^[0-9]+、";
- // String outPut1 = claim.replaceAll(regex1, "");
- // String outPut2 = outPut1.replaceAll(regex2, "");
- // String outPut3 =outPut2.replaceAll(regex3,"");
- String combinedRegex = "^(\\d+[.、]|\\[[0-9]+])";
- String output = claim.replaceAll(combinedRegex, "").replaceAll("[\\n\\r]+$", "");
- return output; // 未找到匹配时返回空字符串
- }
- public String getClaimText(String claim) {
- String combinedRegex = "^(\\d+[.、]|\\[[0-9]+])";
- String output = claim.replaceAll(combinedRegex, "").replaceAll("[\\n\\r]+$", "");
- return output; // 未找到匹配时返回空字符串
- }
- private XWPFTemplate getTemplate(Map<String, Object> map, String filePath) {
- //装载标的专利信息
- XWPFTemplate template = null;
- try {
- Configure configure = Configure.builder()
- .build();
- template = XWPFTemplate.compile(filePath, configure).render(map);
- } catch (Exception e) {
- e.printStackTrace();
- throw new XiaoShiException(ExceptionEnum.BUSINESS_ERROR, "未匹配到模版文件");
- }
- return template;
- }
- public Flux<String> generateInstruction2(GenerateClaimDTO generateClaimDTO) throws Exception {
- Integer templeId = 19;
- String claim = generateClaimDTO.getClaim();
- String background = generateClaimDTO.getBackground();
- Map<String, Object> addMap = new HashMap<>();
- Map<String, Object> queryMap = new HashMap<>();
- queryMap.put("claim", claim);
- queryMap.put("background", background);
- addMap.put("query", queryMap);
- String addStr = JSONObject.toJSONString(addMap);
- AddConfessionSessionDTO addConfessionSessionDTO = new AddConfessionSessionDTO();
- addConfessionSessionDTO.setType(3);
- addConfessionSessionDTO.setContent(addStr);
- ConfessionSession confessionSession = confessionSessionService.addSessionReDO(addConfessionSessionDTO);
- SESSION_ID = confessionSession.getId();
- ReportTemple reportTemplate = templeService.getById(templeId);
- String templateFilePath = fileUtils.getPath(reportTemplate.getTemplatePath());
- Map<String, Object> map = new HashMap<>();
- return Flux.create(emitter -> {
- new Thread(() -> {
- try {
- //;流程开始
- String startMess = getFluxMessage("", ALL_START, "");
- emitter.next(startMess);
- PatentRightParams params = new PatentRightParams();
- params.setCountry("CN");
- params.setContent(claim);
- params.setPatentNo("CN");
- List<RePatentClaim> rePatentClaims = ClaimSplitUtils.formatPatentRight(params);
- //生成标题和技术领域
- GenerateInstructAnswerVO generateInstructAnswerVO = this.genrateTechcialAndTitle(emitter, claim, background);
- String conversionId = generateInstructAnswerVO.getConversionId();
- String title = generateInstructAnswerVO.getTitle();
- String technical = generateInstructAnswerVO.getTechnical();
- map.put("title", title);
- map.put("conversionId", conversionId);
- map.put("technical", technical);
- //生成背景技术
- GenerateInstructAnswerVO generateInstructAnswerVO4 = this.generateBackGround(emitter, background);
- map.put("background", generateInstructAnswerVO4.getAnswers());
- //更新会话
- String name = DateUtils.dateTimeToStr(new Date(), "yyyyMMdd");
- name = name + "-" + title + "-生成说明书";
- confessionSession.setConversationName(name);
- confessionSession.setConversationId(conversionId);
- confessionSession.updateById();
- //生成发明内容
- String startMessage = getFluxMessage(FIELD_CONTENT, START, "");
- emitter.next(startMessage);
- ClaimExplainVO claimExplainVO = this.getFirstImplementation(rePatentClaims.get(0), background, conversionId);
- GenerateInstructAnswerVO generateInstructAnswerVO3 = this.generateContent(emitter, rePatentClaims, claimExplainVO);
- map.put("content",generateInstructAnswerVO3.getAnswers());
- //生成具体实施方式
- GenerateInstructAnswerVO generateInstructAnswerVO2 = this.generateImplementation(emitter, claimExplainVO, background, conversionId, rePatentClaims);
- map.put("implementation", generateInstructAnswerVO2.getImplementations());
- //生成文档
- String fileGuid = this.generateFile(map, templateFilePath, name);
- AssoConfessionSessionFile assoConfessionSessionFile = new AssoConfessionSessionFile();
- assoConfessionSessionFile.setGuid(fileGuid);
- assoConfessionSessionFile.setConfessionSessionId(confessionSession.getId());
- assoConfessionSessionFile.insert();
- String endMess = getFluxMessage("", ALL_END, fileGuid);
- emitter.next(endMess);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- emitter.complete();
- }
- }).start();
- });
- }
- /**
- * 生成文件
- *
- * @param map
- * @param templateFilePath
- * @param name
- * @return
- * @throws Exception
- */
- public String generateFile(Map<String, Object> map, String templateFilePath, String name) throws Exception {
- XWPFTemplate xwpfTemplate = this.getTemplate(map, templateFilePath);
- String fileName = name + ".docx";
- String directoryName = fileUtils.createDirectory();
- String outPath = fileUtils.getSavePath(directoryName) + fileName;
- File file = new File(outPath);
- // 生成word保存在指定目录
- xwpfTemplate.writeToFile(outPath);
- xwpfTemplate.close();
- List<String> ids = fileManagerService.uploadFileGetGuid2(Arrays.asList(file));
- if (ids == null || ids.size() == 0) {
- throw new XiaoShiException("保存记录失败");
- }
- return ids.get(0);
- }
- /**
- * 生成标题和技术领域
- *
- * @param fluxSink
- * @param claim
- * @param background
- * @return
- * @throws Exception
- */
- public GenerateInstructAnswerVO genrateTechcialAndTitle(FluxSink fluxSink, String claim, String background) throws Exception {
- GenerateInstructAnswerVO generateInstructAnswerVO = null;
- GenerateTechnicalVO generateTechnicalVO = null;
- String startMessage = getFluxMessage(FIELD_TITLE, START, "");
- fluxSink.next(startMessage);
- Boolean ifError = false;
- try {
- generateInstructAnswerVO = this.getAnswerFromAI(claim, background, null, "g&technical", null);
- String answer = generateInstructAnswerVO.getAnswer();
- generateTechnicalVO = JSONObject.parseObject(answer, GenerateTechnicalVO.class);
- } catch (Exception e) {
- e.printStackTrace();
- ifError = true;
- }
- generateInstructAnswerVO.setTitle(generateTechnicalVO.getTitle());
- generateInstructAnswerVO.setTechnical(generateTechnicalVO.getTechnical());
- String message = "";
- if (ifError) {
- message = getFluxMessage(FIELD_TITLE, ERROR, "生成标题异常");
- } else {
- message = getFluxMessage(FIELD_TITLE, MESSAGE, generateTechnicalVO.getTitle());
- }
- fluxSink.next(message);
- String endMessage = getFluxMessage(FIELD_TITLE, END, "");
- fluxSink.next(endMessage);
- String startMessage2 = getFluxMessage(FIELD_TECHNICAL, START, "");
- fluxSink.next(startMessage2);
- String message2 = "";
- if (ifError) {
- message2 = getFluxMessage(FIELD_TECHNICAL, ERROR, "生成技术领域异常");
- } else {
- message2 = getFluxMessage(FIELD_TECHNICAL, MESSAGE, generateTechnicalVO.getTechnical());
- }
- fluxSink.next(message2);
- String endMessage2 = getFluxMessage(FIELD_TECHNICAL, END, "");
- fluxSink.next(endMessage2);
- return generateInstructAnswerVO;
- }
- /**
- * 生成第一个权利要求解释
- *
- * @param rePatentClaim
- * @return
- */
- public ClaimExplainVO getFirstImplementation(RePatentClaim rePatentClaim, String background, String conversationId) throws Exception {
- ClaimExplainVO claimExplainVO = null;
- try {
- String claimContent = rePatentClaim.getContent();
- GenerateInstructAnswerVO generateInstructAnswerVO = this.getAnswerFromAI(claimContent, background, 0, "g&implementation", conversationId);
- String answer = generateInstructAnswerVO.getAnswer();
- claimExplainVO = JSONObject.parseObject(answer, ClaimExplainVO.class);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return claimExplainVO;
- }
- /**
- * 生成权要的具体实施方式
- *
- * @param fluxSink
- * @param firstClaimExplainVO
- * @param background
- * @param conversationId
- * @param rePatentClaims
- * @return
- * @throws Exception
- */
- public GenerateInstructAnswerVO generateImplementation(FluxSink fluxSink, ClaimExplainVO firstClaimExplainVO, String background, String conversationId, List<RePatentClaim> rePatentClaims) throws Exception {
- String startMessage = getFluxMessage(FIELD_IMPLEMENTATION, START, "");
- fluxSink.next(startMessage);
- GenerateInstructAnswerVO mainVO = new GenerateInstructAnswerVO();
- List<String> reContents = new ArrayList<>();
- for (int i = 0; i < rePatentClaims.size(); i++) {
- ClaimExplainVO claimExplainVO = null;
- if (i == 0) {
- claimExplainVO = firstClaimExplainVO;
- } else {
- try {
- RePatentClaim rePatentClaim = rePatentClaims.get(i);
- String claimContent = rePatentClaim.getContent();
- GenerateInstructAnswerVO generateInstructAnswerVO = this.getAnswerFromAI(claimContent, background, i, "g&implementation", conversationId);
- String answer = generateInstructAnswerVO.getAnswer();
- if (generateInstructAnswerVO.getConversionId() != null) {
- mainVO.setConversionId(generateInstructAnswerVO.getConversionId());
- }
- claimExplainVO = JSONObject.parseObject(answer, ClaimExplainVO.class);
- } catch (Exception e) {
- }
- }
- String message = "";
- String reStr = null;
- if (claimExplainVO != null) {
- List<String> contents = this.formatImplementation(claimExplainVO);
- if(contents.size()>0){
- reContents.addAll(contents);
- reStr = StringUtils.join(contents, "\n");
- }
- if (i != 0) {
- reStr = "\n" + reStr;
- }
- message = getFluxMessage(FIELD_IMPLEMENTATION, MESSAGE, reStr);
- } else {
- message = getFluxMessage(FIELD_IMPLEMENTATION, MESSAGE, "生成权要" + (i + 1) + "的具体实施方式异常");
- }
- fluxSink.next(message);
- }
- mainVO.setImplementations(reContents);
- String endMessage = getFluxMessage(FIELD_IMPLEMENTATION, END, "");
- fluxSink.next(endMessage);
- return mainVO;
- }
- /**
- * 生成单个权要的具体实施方式
- *
- * @param claimExplainVO
- * @return
- */
- private List<String> formatImplementation(ClaimExplainVO claimExplainVO) {
- String reStr = null;
- List<String> contents = new ArrayList<>();
- String explainVOClaim = claimExplainVO.getClaim();
- String effect = claimExplainVO.getEffects();
- String explain = claimExplainVO.getExplain();
- if (explainVOClaim != null && !explainVOClaim.trim().equals("")) {
- String tem= this.getClaimText(explainVOClaim);
- contents.add(tem);
- }
- if (effect != null && !effect.trim().equals("")) {
- contents.add(effect);
- }
- if (explain != null && !explain.trim().equals("")) {
- contents.add(explain);
- }
- return contents;
- }
- private String getFluxMessage(String field, String event, String content) {
- FluxMessageVO fluxMessage = new FluxMessageVO();
- fluxMessage.setEvent(event);
- fluxMessage.setField(field);
- fluxMessage.setContent(content);
- fluxMessage.setId(SESSION_ID);
- String json = JSONObject.toJSONString(fluxMessage);
- return json;
- }
- public GenerateInstructAnswerVO getAnswerFromAI(String claim, String background, Integer index, String type, String conversationId) throws Exception {
- GenerateInstructAnswerVO generateInstructAnswerVO = new GenerateInstructAnswerVO();
- DifyChatMessageDTO difyChatMessageDTO = new DifyChatMessageDTO();
- difyChatMessageDTO.setUser("1");
- difyChatMessageDTO.setResponseMode("blocking");
- difyChatMessageDTO.setQuery(type);
- difyChatMessageDTO.setConversationId(conversationId);
- Map<String, Object> map = new HashMap<>();
- map.put("claim", claim);
- map.put("background", background);
- map.put("num_index", index);
- difyChatMessageDTO.setInputs(map);
- String re = difyService.chatMessage(difyChatMessageDTO, gInstructionKey);
- JSONObject jsonObject = JSONObject.parseObject(re);
- String answer = jsonObject.get("answer").toString();
- String conversionId = jsonObject.get("conversation_id").toString();
- generateInstructAnswerVO.setAnswer(answer);
- generateInstructAnswerVO.setConversionId(conversionId);
- return generateInstructAnswerVO;
- }
- /**
- * 生成背景技术
- *
- * @param fluxSink
- * @param background
- * @return
- */
- public GenerateInstructAnswerVO generateBackGround(FluxSink fluxSink, String background) {
- GenerateInstructAnswerVO generateInstructAnswerVO = new GenerateInstructAnswerVO();
- generateInstructAnswerVO.setAnswer(background);
- String startMessage = getFluxMessage(FIELD_BACKGROUND, START, "");
- fluxSink.next(startMessage);
- String message = getFluxMessage(FIELD_BACKGROUND, MESSAGE, background);
- fluxSink.next(message);
- String endMessage = getFluxMessage(FIELD_BACKGROUND, END, "");
- fluxSink.next(endMessage);
- List<String> answers =Arrays.asList( background.split("\n"));
- generateInstructAnswerVO.setAnswers(answers);
- return generateInstructAnswerVO;
- }
- /**
- * 生成发明/实用新型内容
- *
- * @param fluxSink
- * @param rePatentClaims
- * @return
- */
- public GenerateInstructAnswerVO generateContent(FluxSink fluxSink, List<RePatentClaim> rePatentClaims, ClaimExplainVO claimExplainVO) {
- GenerateInstructAnswerVO generateInstructAnswerVO = new GenerateInstructAnswerVO();
- List<String> contentStrs = new ArrayList<>();
- for (RePatentClaim rePatentClaim : rePatentClaims) {
- String claimContent = rePatentClaim.getContent();
- String temContent = "";
- if (rePatentClaim != null && rePatentClaim.getType() != null && rePatentClaim.getType().equals(1)) {
- temContent = "为解决上述问题,本申请提出"+ this.getClaimText(claimContent);
- } else {
- temContent = this.getClaimContent(claimContent);
- }
- contentStrs.add(temContent);
- }
- String reContent = "";
- if (contentStrs.size() != 0) {
- reContent = StringUtils.join(contentStrs, "\n");
- }
- String message = getFluxMessage(FIELD_CONTENT, MESSAGE, reContent);
- fluxSink.next(message);
- if (claimExplainVO != null) {
- String temContent="有益效果是:" + claimExplainVO.getEffects();
- contentStrs.add(temContent);
- message = getFluxMessage(FIELD_CONTENT, MESSAGE,"\n"+temContent);
- fluxSink.next(message);
- } else {
- message = getFluxMessage(FIELD_CONTENT, ERROR, "生成有益效果异常");
- fluxSink.next(message);
- }
- String endMessage = getFluxMessage(FIELD_CONTENT, END, "");
- fluxSink.next(endMessage);
- generateInstructAnswerVO.setAnswer(reContent);
- generateInstructAnswerVO.setAnswers(contentStrs);
- return generateInstructAnswerVO;
- }
- }
|