|
|
@@ -0,0 +1,409 @@
|
|
|
+package cn.cslg.pas.service.dify;
|
|
|
+
|
|
|
+import cn.cslg.pas.common.model.dify.OAMessageDTO;
|
|
|
+import cn.cslg.pas.common.model.dify.OAParamDTO;
|
|
|
+import cn.cslg.pas.common.model.dify.oa.OaGenerateResultDTO;
|
|
|
+import cn.cslg.pas.common.utils.DateUtils;
|
|
|
+import cn.cslg.pas.common.utils.FileUtils;
|
|
|
+import cn.cslg.pas.common.utils.LoginUtils;
|
|
|
+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.mapper.dify.ConfessionSessionMapper;
|
|
|
+import cn.cslg.pas.service.business.ReportTempleService;
|
|
|
+import cn.cslg.pas.service.common.FileManagerService;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.deepoove.poi.XWPFTemplate;
|
|
|
+import com.deepoove.poi.config.Configure;
|
|
|
+import com.deepoove.poi.config.ConfigureBuilder;
|
|
|
+import com.google.gson.Gson;
|
|
|
+import com.google.gson.JsonArray;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import okhttp3.*;
|
|
|
+import org.apache.commons.lang3.ObjectUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.ddr.poi.html.HtmlRenderPolicy;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.http.HttpHeaders;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+import reactor.core.publisher.Flux;
|
|
|
+
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.Reader;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+@Service
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class OADifyService {
|
|
|
+ @Value("${FileDownloadUrl}")
|
|
|
+ private String fileDownloadUrl;
|
|
|
+
|
|
|
+ private final LoginUtils loginUtils;
|
|
|
+ @Value("${DIFY.OAApiKey2}")
|
|
|
+ private String OAApiKey2;
|
|
|
+ @Value("${DIFY.url}")
|
|
|
+ private String url;
|
|
|
+ private final ConfessionSessionService confessionSessionService;
|
|
|
+ private final FileUtils fileUtils;
|
|
|
+ private final ReportTempleService templeService;
|
|
|
+ private final ConfessionSessionMapper confessionSessionMapper;
|
|
|
+ private final OaChatRecordService oaChatRecordService;
|
|
|
+ private final AssoConfessionSessionFileService assoConfessionSessionFileService;
|
|
|
+ private final FileManagerService fileManagerService;
|
|
|
+
|
|
|
+ public Flux<String> successGetOAHttp1(OAParamDTO vo) {
|
|
|
+ Integer confessionSessionId = vo.getConfessionSessionId();
|
|
|
+ String patentFileUrls = vo.getPatentFileUrls();
|
|
|
+ String appFileGuid = vo.getAppFileGuid();
|
|
|
+ String modifyFileGuid = vo.getModifyFileGuid();
|
|
|
+ String query = vo.getQuery();
|
|
|
+ String operate = vo.getOperation();
|
|
|
+ Integer messageId = vo.getMessageId();
|
|
|
+ ConfessionSession confessionSession = confessionSessionService.getById(confessionSessionId);
|
|
|
+ if (ObjectUtils.isEmpty(confessionSession)) {
|
|
|
+ throw new XiaoShiException(ExceptionEnum.BUSINESS_ERROR, "未查询到OA答辩记录");
|
|
|
+ }
|
|
|
+ String conversationId = confessionSession.getConversationId();
|
|
|
+ String sessionContent = confessionSession.getContent();
|
|
|
+ String conversationName = confessionSession.getConversationName();
|
|
|
+ String fileUrl = fileDownloadUrl + confessionSession.getGuid();
|
|
|
+ String userId = loginUtils.getId().toString();
|
|
|
+
|
|
|
+ OkHttpClient client = new OkHttpClient.Builder()
|
|
|
+ .connectTimeout(600, TimeUnit.SECONDS)
|
|
|
+ .writeTimeout(600, TimeUnit.SECONDS)
|
|
|
+ .readTimeout(600, TimeUnit.SECONDS)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("fileUrl", fileUrl);
|
|
|
+ map.put("patent_fileUrls", patentFileUrls);
|
|
|
+ map.put("app_file_guid", appFileGuid);
|
|
|
+ map.put("modify_file_guid", modifyFileGuid);
|
|
|
+ map.put("changeClaim", vo.getChangeClaim());
|
|
|
+ map.put("claim", vo.getClaim());
|
|
|
+ map.put("main_claim_reason", vo.getMainClaimReason());
|
|
|
+ map.put("near_index", vo.getNearIndex());
|
|
|
+ map.put("operation", operate);
|
|
|
+ map.put("patent_files", new ArrayList<>());
|
|
|
+ map.put("claimChangeSuggestion", vo.getClaimChangeSuggestion());
|
|
|
+
|
|
|
+ OAMessageDTO oaMessageDTO = new OAMessageDTO();
|
|
|
+ oaMessageDTO.setInputs(map);
|
|
|
+ oaMessageDTO.setResponseMode("streaming");
|
|
|
+ oaMessageDTO.setUser(userId);
|
|
|
+ oaMessageDTO.setQuery(query);
|
|
|
+ oaMessageDTO.setConversationId(conversationId);
|
|
|
+ oaMessageDTO.setFiles(new ArrayList<>());
|
|
|
+
|
|
|
+ String param = new Gson().toJson(oaMessageDTO);
|
|
|
+ RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), param);
|
|
|
+ Request request = new Request.Builder()
|
|
|
+ .url(url + "chat-messages")
|
|
|
+ .addHeader("Authorization", "Bearer " + OAApiKey2)
|
|
|
+ .addHeader(HttpHeaders.CONTENT_TYPE, "application/json")
|
|
|
+ .post(requestBody)
|
|
|
+ .build();
|
|
|
+
|
|
|
+
|
|
|
+ return Flux.create(emitter -> {
|
|
|
+ client.newCall(request).enqueue(new Callback() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onFailure(Call call, IOException e) {
|
|
|
+ emitter.error(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onResponse(Call call, Response response) throws IOException {
|
|
|
+
|
|
|
+ if (!response.isSuccessful()) {
|
|
|
+ emitter.error(new IOException("Unexpected code: " + response));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String json = "";
|
|
|
+ try (Reader reader = response.body().charStream()) {
|
|
|
+ BufferedReader bufferedReader = new BufferedReader(reader);
|
|
|
+ String line;
|
|
|
+ String prefixToRemove = "data: ";
|
|
|
+ String runId = conversationId;
|
|
|
+ StringBuilder stringBuilder = new StringBuilder("");
|
|
|
+ while ((line = bufferedReader.readLine()) != null) {
|
|
|
+ if (line.isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (line.startsWith(prefixToRemove)) {
|
|
|
+ line = line.substring(prefixToRemove.length());
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ JSONObject jsonObject = JSON.parseObject(line);
|
|
|
+ String sessionConversationId = jsonObject.get("conversation_id").toString();
|
|
|
+ String event = jsonObject.get("event").toString();
|
|
|
+ if (StringUtils.isEmpty(runId)) {
|
|
|
+ if (StringUtils.isNotEmpty(sessionConversationId)) {
|
|
|
+ runId = sessionConversationId;
|
|
|
+ confessionSessionMapper.updateSingleField(confessionSessionId, "conversation_id", sessionConversationId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (event.equals("message")) {
|
|
|
+ String data = jsonObject.get("answer").toString();
|
|
|
+ if (data != null && operate.equals("6")) {
|
|
|
+ String formatData = data.trim();
|
|
|
+ if ((formatData.startsWith("{") && formatData.endsWith("}")) || (formatData.startsWith("[") && formatData.endsWith("]"))) {
|
|
|
+ json = data;
|
|
|
+ data = "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ stringBuilder.append(data);
|
|
|
+ }
|
|
|
+ //保存内容
|
|
|
+
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ }
|
|
|
+ emitter.next(line); // 将每行数据发送到 Flux
|
|
|
+ }
|
|
|
+ String reMessage = stringBuilder.toString();
|
|
|
+ saveMessage(operate, reMessage, sessionContent, confessionSessionId, vo, json);
|
|
|
+ oaChatRecordService.add(oaMessageDTO, messageId, reMessage);
|
|
|
+ } catch (IOException e) {
|
|
|
+ emitter.error(e);
|
|
|
+ } finally {
|
|
|
+ emitter.complete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成OA答辩文件
|
|
|
+ *
|
|
|
+ * @param map
|
|
|
+ * @param templateFilePath
|
|
|
+ * @param name
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public String generateOADefenseFile(Map<String, Object> map, String templateFilePath, String name) throws Exception {
|
|
|
+ XWPFTemplate xwpfTemplate = this.getHtmlTemplate(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(Collections.singletonList(file));
|
|
|
+ if (CollectionUtils.isEmpty(ids)) {
|
|
|
+ throw new XiaoShiException("保存记录失败");
|
|
|
+ }
|
|
|
+ return ids.get(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ private XWPFTemplate getHtmlTemplate(Map<String, Object> map, String filePath) {
|
|
|
+ XWPFTemplate template = null;
|
|
|
+ try {
|
|
|
+ HtmlRenderPolicy htmlRenderPolicy = new HtmlRenderPolicy();
|
|
|
+ ConfigureBuilder configureBuilder = Configure.builder().useSpringEL(false);
|
|
|
+ configureBuilder.bind("#this", htmlRenderPolicy);
|
|
|
+ Configure configure = configureBuilder.build();
|
|
|
+ template = XWPFTemplate.compile(filePath, configure).render(map);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new XiaoShiException(ExceptionEnum.BUSINESS_ERROR, "未匹配到模版文件");
|
|
|
+ }
|
|
|
+ return template;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 对话完成后保存信息
|
|
|
+ */
|
|
|
+ public void saveMessage(String operateType, String reMessage, String sessionContent, Integer confessionSessionId, OAParamDTO oaParamDTO, String json) {
|
|
|
+ try {
|
|
|
+ JSONObject obj = null;
|
|
|
+ if (sessionContent == null) {
|
|
|
+ obj = new JSONObject();
|
|
|
+ } else {
|
|
|
+ obj = JSON.parseObject(sessionContent);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (operateType.equals("1")) {
|
|
|
+ JSONObject dataObject = JSON.parseObject(reMessage);
|
|
|
+ String code = dataObject.get("code").toString();
|
|
|
+ if (StringUtils.equals(code, "203")) {
|
|
|
+ Object data = dataObject.get("data");
|
|
|
+ if (obj.get("query") == null) {
|
|
|
+ obj.put("query", new JSONObject());
|
|
|
+ }
|
|
|
+ JSONObject jsonObject = (JSONObject) obj.get("query");
|
|
|
+ jsonObject.put("relevant_file", data);
|
|
|
+
|
|
|
+ }
|
|
|
+ } else if (operateType.equals("2")) {
|
|
|
+ if (obj.get("query") == null) {
|
|
|
+ obj.put("query", new JSONObject());
|
|
|
+ }
|
|
|
+ JSONObject jsonObject = (JSONObject) obj.get("query");
|
|
|
+ if (jsonObject.get("claimChange") == null) {
|
|
|
+ jsonObject.put("claimChange", new JSONObject());
|
|
|
+ }
|
|
|
+ JSONObject jsonObject1 = (JSONObject) jsonObject.get("claimChange");
|
|
|
+ JSONObject dataObject = JSON.parseObject(reMessage);
|
|
|
+ jsonObject1.put("nearNo", dataObject.get("nearNo"));
|
|
|
+ jsonObject1.put("near_index", dataObject.get("nearIndex"));
|
|
|
+ jsonObject1.put("novelty_innovative", dataObject.get("novelty_innovative"));
|
|
|
+ jsonObject1.put("changeClaim", dataObject.get("claimChange"));
|
|
|
+ jsonObject1.put("claim", oaParamDTO.getClaim());
|
|
|
+ jsonObject1.put("claimChangeSuggestion", oaParamDTO.getClaimChangeSuggestion());
|
|
|
+ } else if (operateType.equals("3")) {
|
|
|
+ if (obj.get("query") == null) {
|
|
|
+ obj.put("query", new JSONObject());
|
|
|
+ }
|
|
|
+ JSONObject jsonObject = (JSONObject) obj.get("query");
|
|
|
+ if (jsonObject.get("claimChange") == null) {
|
|
|
+ jsonObject.put("claimChange", new JSONObject());
|
|
|
+ }
|
|
|
+ JSONObject jsonObject1 = (JSONObject) jsonObject.get("claimChange");
|
|
|
+ jsonObject1.put("claimChangeSuggestion", reMessage);
|
|
|
+ } else if (operateType.equals("4")) {
|
|
|
+ if (obj.get("query") == null) {
|
|
|
+ obj.put("query", new JSONObject());
|
|
|
+ }
|
|
|
+ JSONObject jsonObject = (JSONObject) obj.get("query");
|
|
|
+ if (jsonObject.get("claimChange") == null) {
|
|
|
+ jsonObject.put("claimChange", new JSONObject());
|
|
|
+ }
|
|
|
+ JSONObject jsonObject1 = (JSONObject) jsonObject.get("claimChange");
|
|
|
+ jsonObject1.put("claimChange", reMessage);
|
|
|
+ } else if (operateType.equals("5")) {
|
|
|
+ if (obj.get("query") == null) {
|
|
|
+ obj.put("query", new JSONObject());
|
|
|
+ }
|
|
|
+ JSONObject jsonObject = (JSONObject) obj.get("query");
|
|
|
+ List<Object> jsonArray = JSONArray.parseArray(reMessage);
|
|
|
+ jsonObject.put("main_claim_reason", jsonArray);
|
|
|
+ } else if (operateType.equals("6")) {
|
|
|
+ JSONObject dataObject = JSON.parseObject(json);
|
|
|
+ obj.put("data", dataObject);
|
|
|
+ }
|
|
|
+ String reJson = JSONObject.toJSONString(obj);
|
|
|
+ confessionSessionMapper.updateSingleField(confessionSessionId, "content", reJson);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void generateOaResult(OaGenerateResultDTO oaGenerateResultDTO) {
|
|
|
+ Integer confessionSessionId = oaGenerateResultDTO.getConfessionSessionId();
|
|
|
+ ConfessionSession confessionSession = confessionSessionService.getById(confessionSessionId);
|
|
|
+ assoConfessionSessionFileService.removeByConversionSessionId(confessionSessionId);
|
|
|
+ this.generateDoc(confessionSession);
|
|
|
+ this.generateDoc2(confessionSession);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void generateDoc(ConfessionSession confessionSession) {
|
|
|
+ String content = confessionSession.getContent();
|
|
|
+ Integer confessionSessionId = confessionSession.getId();
|
|
|
+ String conversationName = confessionSession.getConversationName();
|
|
|
+ JSONObject orgJsonObject = JSONObject.parseObject(content);
|
|
|
+ JSONObject dataJsonObject = orgJsonObject.getJSONObject("data");
|
|
|
+ JSONObject jsonObject = dataJsonObject.getJSONObject("data");
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ String reason = jsonObject.getString("reason");
|
|
|
+ String num = jsonObject.getString("num");
|
|
|
+ String claimChange = jsonObject.getString("claim_change");
|
|
|
+ List<String> claimList = new ArrayList<>();
|
|
|
+ if (StringUtils.isNotEmpty(claimChange)) {
|
|
|
+ claimList = Arrays.asList(claimChange.split("\r?\n+"));
|
|
|
+ }
|
|
|
+ JSONArray jsonArray = jsonObject.getJSONArray("defense_opinion");
|
|
|
+ // 创建List集合
|
|
|
+ List<String> list = new ArrayList<>();
|
|
|
+ // 遍历JSONArray并添加元素到List
|
|
|
+ if (!CollectionUtils.isEmpty(jsonArray)) {
|
|
|
+ for (Object o : jsonArray) {
|
|
|
+ String str = o.toString();
|
|
|
+ if (StringUtils.isNotEmpty(str)) {
|
|
|
+ String[] split1 = str.split("\r?\n+");
|
|
|
+ list.addAll(Arrays.asList(split1));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ map.put("num", num);
|
|
|
+ map.put("reason", reason);
|
|
|
+ map.put("claim_change", claimList);
|
|
|
+ map.put("defense_opinion", list);
|
|
|
+
|
|
|
+ ReportTemple reportTemplate = templeService.getById(20);
|
|
|
+ String templateFilePath = fileUtils.getPath(reportTemplate.getTemplatePath());
|
|
|
+ //更新会话
|
|
|
+ String name = DateUtils.dateTimeToStr(new Date(), "yyyyMMdd");
|
|
|
+ String finalName = name + "-" + conversationName + "-陈述意见书";
|
|
|
+ //生成文档
|
|
|
+ String fileGuid = null;
|
|
|
+ try {
|
|
|
+ fileGuid = this.generateOADefenseFile(map, templateFilePath, finalName);
|
|
|
+ AssoConfessionSessionFile assoConfessionSessionFile = new AssoConfessionSessionFile();
|
|
|
+ assoConfessionSessionFile.setGuid(fileGuid);
|
|
|
+ assoConfessionSessionFile.setConfessionSessionId(confessionSessionId);
|
|
|
+ assoConfessionSessionFile.setType(1);
|
|
|
+ assoConfessionSessionFile.insert();
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new XiaoShiException(ExceptionEnum.BUSINESS_ERROR, "加载陈述意见书失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void generateDoc2(ConfessionSession confessionSession) {
|
|
|
+ String content = confessionSession.getContent();
|
|
|
+ Integer confessionSessionId = confessionSession.getId();
|
|
|
+ String conversationName = confessionSession.getConversationName();
|
|
|
+ JSONObject orgJsonObject = JSONObject.parseObject(content);
|
|
|
+ JSONObject jsonObject = orgJsonObject.getJSONObject("data");
|
|
|
+ String modify_claim = "";
|
|
|
+ if (jsonObject.get("data") != null) {
|
|
|
+ JSONObject jsonObject1 = (JSONObject) jsonObject.get("data");
|
|
|
+ modify_claim = jsonObject1.getString("modify_claim");
|
|
|
+ }
|
|
|
+ if (modify_claim == null || modify_claim.trim().equals("")) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<String> claims = cn.cslg.pas.common.utils.StringUtils.changeStringToString(modify_claim, "\r?\n+|<br>+");
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("claims", claims);
|
|
|
+
|
|
|
+ ReportTemple reportTemplate = templeService.getById(21);
|
|
|
+ String templateFilePath = fileUtils.getPath(reportTemplate.getTemplatePath());
|
|
|
+ //更新会话
|
|
|
+ String name = DateUtils.dateTimeToStr(new Date(), "yyyyMMdd");
|
|
|
+ String finalName = name + "-" + conversationName + "-修改对照页";
|
|
|
+ //生成文档
|
|
|
+ String fileGuid = null;
|
|
|
+ try {
|
|
|
+ fileGuid = this.generateOADefenseFile(map, templateFilePath, finalName);
|
|
|
+ AssoConfessionSessionFile assoConfessionSessionFile = new AssoConfessionSessionFile();
|
|
|
+ assoConfessionSessionFile.setGuid(fileGuid);
|
|
|
+ assoConfessionSessionFile.setConfessionSessionId(confessionSessionId);
|
|
|
+ assoConfessionSessionFile.setType(1);
|
|
|
+ assoConfessionSessionFile.insert();
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new XiaoShiException(ExceptionEnum.BUSINESS_ERROR, "加载陈述意见书失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|