|
@@ -6,24 +6,30 @@ import cn.cslg.pas.common.model.dify.*;
|
|
import cn.cslg.pas.common.model.dify.GenerateClaimDTO;
|
|
import cn.cslg.pas.common.model.dify.GenerateClaimDTO;
|
|
import cn.cslg.pas.common.model.dify.confessionSession.AddConfessionSessionDTO;
|
|
import cn.cslg.pas.common.model.dify.confessionSession.AddConfessionSessionDTO;
|
|
import cn.cslg.pas.common.model.dify.confessionSession.UpdateConfessionSessionDTO;
|
|
import cn.cslg.pas.common.model.dify.confessionSession.UpdateConfessionSessionDTO;
|
|
-import cn.cslg.pas.common.utils.CacheUtils;
|
|
|
|
|
|
+import cn.cslg.pas.common.utils.*;
|
|
import cn.cslg.pas.common.utils.ClaimUtils.ClaimSplitUtils;
|
|
import cn.cslg.pas.common.utils.ClaimUtils.ClaimSplitUtils;
|
|
-import cn.cslg.pas.common.utils.DataUtils;
|
|
|
|
-import cn.cslg.pas.common.utils.DateUtils;
|
|
|
|
-import cn.cslg.pas.common.utils.LoginUtils;
|
|
|
|
import cn.cslg.pas.common.vo.PatentRightParams;
|
|
import cn.cslg.pas.common.vo.PatentRightParams;
|
|
|
|
+import cn.cslg.pas.domain.business.ReportTemple;
|
|
import cn.cslg.pas.domain.business.TechnicalCase;
|
|
import cn.cslg.pas.domain.business.TechnicalCase;
|
|
|
|
+import cn.cslg.pas.domain.dify.AssoConfessionSessionFile;
|
|
import cn.cslg.pas.domain.dify.ConfessionSession;
|
|
import cn.cslg.pas.domain.dify.ConfessionSession;
|
|
import cn.cslg.pas.domain.report.AssoProjectConfession;
|
|
import cn.cslg.pas.domain.report.AssoProjectConfession;
|
|
|
|
+import cn.cslg.pas.exception.ExceptionEnum;
|
|
|
|
+import cn.cslg.pas.exception.XiaoShiException;
|
|
import cn.cslg.pas.mapper.dify.ConfessionSessionMapper;
|
|
import cn.cslg.pas.mapper.dify.ConfessionSessionMapper;
|
|
|
|
+import cn.cslg.pas.service.business.ReportTempleService;
|
|
import cn.cslg.pas.service.business.TechnicalCaseService;
|
|
import cn.cslg.pas.service.business.TechnicalCaseService;
|
|
import cn.cslg.pas.service.dify.ConfessionSessionService;
|
|
import cn.cslg.pas.service.dify.ConfessionSessionService;
|
|
import cn.cslg.pas.service.dify.DifySessionService;
|
|
import cn.cslg.pas.service.dify.DifySessionService;
|
|
|
|
+import cn.cslg.pas.service.dify.GenerateInstructionService;
|
|
import cn.cslg.pas.service.report.AssoProjectConfessionService;
|
|
import cn.cslg.pas.service.report.AssoProjectConfessionService;
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSONArray;
|
|
import com.alibaba.fastjson.JSONArray;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
+import com.deepoove.poi.XWPFTemplate;
|
|
|
|
+import com.deepoove.poi.config.Configure;
|
|
|
|
+import com.deepoove.poi.config.ConfigureBuilder;
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.Gson;
|
|
@@ -31,13 +37,17 @@ import com.google.gson.GsonBuilder;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import okhttp3.*;
|
|
import okhttp3.*;
|
|
|
|
+import okhttp3.Response;
|
|
import org.apache.commons.lang3.ObjectUtils;
|
|
import org.apache.commons.lang3.ObjectUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
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.Autowired;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
+import org.springframework.context.annotation.Lazy;
|
|
import org.springframework.http.HttpHeaders;
|
|
import org.springframework.http.HttpHeaders;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
import org.w3c.dom.DocumentType;
|
|
import org.w3c.dom.DocumentType;
|
|
import reactor.core.publisher.Flux;
|
|
import reactor.core.publisher.Flux;
|
|
|
|
|
|
@@ -81,6 +91,15 @@ public class DifyService {
|
|
private final ConfessionSessionService confessionSessionService;
|
|
private final ConfessionSessionService confessionSessionService;
|
|
@Autowired
|
|
@Autowired
|
|
private ConfessionSessionMapper confessionSessionMapper;
|
|
private ConfessionSessionMapper confessionSessionMapper;
|
|
|
|
+ @Autowired
|
|
|
|
+ private ReportTempleService templeService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private FileUtils fileUtils;
|
|
|
|
+ @Autowired
|
|
|
|
+ private FileManagerService fileManagerService;
|
|
|
|
+ @Autowired
|
|
|
|
+ @Lazy
|
|
|
|
+ private GenerateInstructionService generateInstructionService;
|
|
|
|
|
|
/**
|
|
/**
|
|
* 调用文件系统删除文件接口
|
|
* 调用文件系统删除文件接口
|
|
@@ -482,6 +501,209 @@ public class DifyService {
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public Flux<String> successGetOAHttp1(OAParamDTO vo) {
|
|
|
|
+ Integer confessionSessionId = vo.getConfessionSessionId();
|
|
|
|
+ String patentFileUrls = vo.getPatentFileUrls();
|
|
|
|
+ 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);
|
|
|
|
+
|
|
|
|
+ OAMessageDTO oaMessageDTO = new OAMessageDTO();
|
|
|
|
+ oaMessageDTO.setInputs(map);
|
|
|
|
+ oaMessageDTO.setResponseMode("streaming");
|
|
|
|
+ oaMessageDTO.setUser(userId);
|
|
|
|
+ oaMessageDTO.setQuery("OA答辩");
|
|
|
|
+ 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 " + OAApiKey)
|
|
|
|
+ .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;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try (Reader reader = response.body().charStream()) {
|
|
|
|
+ BufferedReader bufferedReader = new BufferedReader(reader);
|
|
|
|
+ String line;
|
|
|
|
+ String prefixToRemove = "data: ";
|
|
|
|
+ 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(conversationId)) {
|
|
|
|
+ if (StringUtils.isNotEmpty(sessionConversationId)) {
|
|
|
|
+ confessionSessionMapper.updateSingleField(confessionSessionId, "conversation_id", sessionConversationId);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (event.equals("message")) {
|
|
|
|
+ String data = jsonObject.get("answer").toString();
|
|
|
|
+ JSONObject dataObject = null;
|
|
|
|
+ if (StringUtils.isNotEmpty(data)) {
|
|
|
|
+ try {
|
|
|
|
+ dataObject = JSON.parseObject(data);
|
|
|
|
+ String code = dataObject.get("code").toString();
|
|
|
|
+ if (StringUtils.equals(code, "200")) {
|
|
|
|
+ JSONObject object = dataObject.getJSONObject("data");
|
|
|
|
+ generateDoc(conversationName, confessionSessionId, object);
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (ObjectUtils.isNotEmpty(dataObject)) {
|
|
|
|
+ JSONObject obj;
|
|
|
|
+ if (StringUtils.isNotEmpty(sessionContent)) {
|
|
|
|
+ obj = JSON.parseObject(sessionContent);
|
|
|
|
+ obj.put("data", dataObject);
|
|
|
|
+ } else {
|
|
|
|
+ obj = new JSONObject();
|
|
|
|
+ obj.put("data", dataObject);
|
|
|
|
+ }
|
|
|
|
+ confessionSessionMapper.updateSingleField(confessionSessionId, "content", obj.toString());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ }
|
|
|
|
+ emitter.next(line); // 将每行数据发送到 Flux
|
|
|
|
+ }
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ emitter.error(e);
|
|
|
|
+ } finally {
|
|
|
|
+ emitter.complete();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void generateDoc(String conversationName,Integer confessionSessionId,JSONObject object) {
|
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
|
+ String reason = object.getString("reason");
|
|
|
|
+ String num = object.getString("num");
|
|
|
|
+ String claimChange = object.getString("claim_change");
|
|
|
|
+ List<String> claimList = new ArrayList<>();
|
|
|
|
+ if (StringUtils.isNotEmpty(claimChange)) {
|
|
|
|
+ claimList = Arrays.asList(claimChange.split("\n"));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ JSONArray jsonArray = object.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("\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.insert();
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new XiaoShiException(ExceptionEnum.BUSINESS_ERROR, "加载陈述意见书失败");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 生成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();
|
|
|
|
+ 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;
|
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
/**
|
|
* 调用质检
|
|
* 调用质检
|