Просмотр исходного кода

AI审核完成初版(AI质控流程容后商议)

Huanyi 2 месяцев назад
Родитель
Сommit
6ae2ec5c12
29 измененных файлов с 699 добавлено и 140 удалено
  1. 3 0
      ruoyi-admin/src/main/resources/application.yml
  2. 1 0
      ruoyi-common/pom.xml
  3. 6 0
      ruoyi-common/ruoyi-common-bom/pom.xml
  4. 32 0
      ruoyi-common/yingpaipay-common-ai/pom.xml
  5. 45 0
      ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/client/SiliconFlowClient.java
  6. 14 0
      ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/config/SiliconConfig.java
  7. 18 0
      ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/enumeration/SiliconFlowRole.java
  8. 16 0
      ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/enumeration/SiliconModel.java
  9. 18 0
      ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/pojo/SiliconFlowMessage.java
  10. 48 0
      ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/pojo/SiliconFlowReq.java
  11. 79 0
      ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/pojo/SiliconFlowResp.java
  12. 1 0
      ruoyi-common/yingpaipay-common-ai/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  13. 2 0
      ruoyi-common/yingpaipay-common-document/src/main/java/com/yingpaipay/common/file/config/TextInConfig.java
  14. 5 0
      ruoyi-modules/yingpaipay-business/pom.xml
  15. 39 39
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/WpsController.java
  16. 12 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/AiAuditDTO.java
  17. 0 13
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/AiAuditDto.java
  18. 10 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/TextInImageToWordDTO.java
  19. 163 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/TextInPdfToMarkdownDTO.java
  20. 1 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsGetVersionsDTO.java
  21. 2 2
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsVersionControlDTO.java
  22. 1 1
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsVersionDTO.java
  23. 65 28
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/AiAuditService.java
  24. 6 0
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/ITextInService.java
  25. 39 5
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentServiceImpl.java
  26. 64 47
      ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/TextInServiceImpl.java
  27. 2 1
      ruoyi-modules/yingpaipay-setting/src/main/java/com/yingpaipay/setting/controller/TextinSettingController.java
  28. 1 1
      ruoyi-modules/yingpaipay-setting/src/main/java/com/yingpaipay/setting/service/ITextinSettingService.java
  29. 6 2
      ruoyi-modules/yingpaipay-setting/src/main/java/com/yingpaipay/setting/service/impl/TextinSettingServiceImpl.java

+ 3 - 0
ruoyi-admin/src/main/resources/application.yml

@@ -272,4 +272,7 @@ textin:
     image-to-word: https://api.textin.com/robot/v1.0/api/doc_restore
     word-to-image: https://api.textin.com/ai/service/v1/file-convert/word-to-image
     word-to-pdf: https://api.textin.com/ai/service/v1/file-convert/word-to-pdf
+    pdf-to-markdown: https://api.textin.com/ai/service/v1/pdf_to_markdown
 
+silicon:
+    v1-url: https://api.siliconflow.cn/v1

+ 1 - 0
ruoyi-common/pom.xml

@@ -35,6 +35,7 @@
         <module>ruoyi-common-websocket</module>
         <module>ruoyi-common-sse</module>
         <module>yingpaipay-common-document</module>
+        <module>yingpaipay-common-ai</module>
     </modules>
 
     <artifactId>ruoyi-common</artifactId>

+ 6 - 0
ruoyi-common/ruoyi-common-bom/pom.xml

@@ -185,6 +185,12 @@
                 <version>${revision}</version>
             </dependency>
 
+            <dependency>
+                <groupId>com.yingpaipay</groupId>
+                <artifactId>yingpaipay-common-ai</artifactId>
+                <version>${revision}</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>
 

+ 32 - 0
ruoyi-common/yingpaipay-common-ai/pom.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.dromara</groupId>
+        <artifactId>ruoyi-common</artifactId>
+        <version>${revision}</version>
+    </parent>
+
+    <groupId>com.yingpaipay</groupId>
+    <artifactId>yingpaipay-common-ai</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-json</artifactId>
+        </dependency>
+    </dependencies>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+</project>

+ 45 - 0
ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/client/SiliconFlowClient.java

@@ -0,0 +1,45 @@
+package com.yingpaipay.common.ai.client;
+
+import cn.hutool.http.ContentType;
+import cn.hutool.http.Header;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.yingpaipay.common.ai.config.SiliconConfig;
+import com.yingpaipay.common.ai.enumeration.SiliconModel;
+import com.yingpaipay.common.ai.pojo.SiliconFlowMessage;
+import com.yingpaipay.common.ai.pojo.SiliconFlowReq;
+import com.yingpaipay.common.ai.pojo.SiliconFlowResp;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.json.utils.JsonUtils;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class SiliconFlowClient {
+
+    private final SiliconConfig config;
+
+    private static final String API_KEY = "sk-ekdouxzwtlrgiiqafirxnfwvrsrczvtezdkvdtapvrhtlpct";
+
+    public SiliconFlowResp askMessages(SiliconModel model, SiliconFlowMessage... messages) {
+        if (messages == null || messages.length == 0) {
+            throw new IllegalArgumentException("至少需要有一条消息");
+        }
+
+        SiliconFlowReq req = new SiliconFlowReq.Builder().model(model).messages(messages).build();
+
+        try (HttpResponse response = HttpRequest.post(config.getV1Url() + "/chat/completions")
+            .contentType(ContentType.JSON.getValue())
+            .header(Header.AUTHORIZATION, "Bearer " + API_KEY)
+            .body(JsonUtils.toJsonString(req))
+            .execute()) {
+
+            if (!response.isOk()) {
+                throw new RuntimeException("请求失败");
+            }
+
+            return JsonUtils.parseObject(response.body(), SiliconFlowResp.class);
+        }
+    }
+
+}

+ 14 - 0
ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/config/SiliconConfig.java

@@ -0,0 +1,14 @@
+package com.yingpaipay.common.ai.config;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+
+@AutoConfiguration
+@Data
+public class SiliconConfig {
+
+    @Value("${silicon.v1-url}")
+    private String v1Url;
+
+}

+ 18 - 0
ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/enumeration/SiliconFlowRole.java

@@ -0,0 +1,18 @@
+package com.yingpaipay.common.ai.enumeration;
+
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
+@Getter
+public enum SiliconFlowRole {
+
+    SYSTEM("system"),
+    USER("user"),
+    ASSISTANT("assistant"),
+    ;
+
+    private final String value;
+
+}

+ 16 - 0
ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/enumeration/SiliconModel.java

@@ -0,0 +1,16 @@
+package com.yingpaipay.common.ai.enumeration;
+
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
+@Getter
+public enum SiliconModel {
+
+    GLM_4_7("Pro/zai-org/GLM-4.7"),
+    ;
+
+    private final String name;
+
+}

+ 18 - 0
ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/pojo/SiliconFlowMessage.java

@@ -0,0 +1,18 @@
+package com.yingpaipay.common.ai.pojo;
+
+import com.yingpaipay.common.ai.enumeration.SiliconFlowRole;
+import lombok.Getter;
+
+@Getter
+public class SiliconFlowMessage {
+
+    private final String role;
+
+    private final String content;
+
+    public SiliconFlowMessage(SiliconFlowRole role, String content) {
+        this.role = role.getValue();
+        this.content = content;
+    }
+
+}

+ 48 - 0
ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/pojo/SiliconFlowReq.java

@@ -0,0 +1,48 @@
+package com.yingpaipay.common.ai.pojo;
+
+import com.yingpaipay.common.ai.enumeration.SiliconModel;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@Data
+public class SiliconFlowReq {
+
+    private String model;
+
+    private List<SiliconFlowMessage> messages;
+
+    public static class Builder {
+        SiliconFlowReq req = new SiliconFlowReq();
+        List<SiliconFlowMessage> messages = new ArrayList<>();
+
+        public Builder model(SiliconModel model) {
+            req.model = model.getName();
+            return this;
+        }
+
+        public Builder message(SiliconFlowMessage message) {
+            messages.add(message);
+            return this;
+        }
+
+        public Builder messages(List<SiliconFlowMessage> messages) {
+            this.messages = messages;
+            return this;
+        }
+
+        public Builder messages(SiliconFlowMessage[] messages) {
+            this.messages = Arrays.asList(messages);
+            return this;
+        }
+
+        public SiliconFlowReq build() {
+            req.messages = messages;
+            return req;
+        }
+
+    }
+
+}

+ 79 - 0
ruoyi-common/yingpaipay-common-ai/src/main/java/com/yingpaipay/common/ai/pojo/SiliconFlowResp.java

@@ -0,0 +1,79 @@
+package com.yingpaipay.common.ai.pojo;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class SiliconFlowResp {
+
+    private String id;
+
+    private String object;
+
+    private Long created;
+
+    private String model;
+
+    private List<Choice> choices;
+
+    private Usage usage;
+
+    private String system_fingerprint;
+
+    @Data
+    public static class Choice {
+
+        private Integer index;
+
+        private Message message;
+
+        private String finish_reason;
+
+        @Data
+        public static class Message {
+
+            private String role;
+
+            private String content;
+
+            private String reasoning_content;
+
+        }
+
+    }
+
+    @Data
+    public static class Usage {
+
+        private Integer prompt_tokens;
+
+        private Integer completion_tokens;
+
+        private Integer total_tokens;
+
+        private CompletionTokensDetails completion_tokens_details;
+
+        private PromptTokensDetails prompt_tokens_details;
+
+        private Integer prompt_cache_his_tokens;
+
+        private Integer prompt_cache_miss_tokens;
+
+        @Data
+        public static class CompletionTokensDetails {
+
+            private Integer reasoning_tokens;
+
+        }
+
+        @Data
+        public static class PromptTokensDetails {
+
+            private Integer cached_tokens;
+
+        }
+
+    }
+
+}

+ 1 - 0
ruoyi-common/yingpaipay-common-ai/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+com.yingpaipay.common.ai.config.SiliconConfig

+ 2 - 0
ruoyi-common/yingpaipay-common-document/src/main/java/com/yingpaipay/common/file/config/TextInConfig.java

@@ -20,4 +20,6 @@ public class TextInConfig {
     @Value("${textin.word-to-pdf}")
     private String wordToPdf;
 
+    @Value("${textin.pdf-to-markdown}")
+    private String pdfToMarkdown;
 }

+ 5 - 0
ruoyi-modules/yingpaipay-business/pom.xml

@@ -117,6 +117,11 @@
             <groupId>com.yingpaipay</groupId>
             <artifactId>yingpaipay-common-document</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>com.yingpaipay</groupId>
+            <artifactId>yingpaipay-common-ai</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 39 - 39
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/controller/WpsController.java

@@ -1,10 +1,10 @@
 package com.yingpaipay.business.controller;
 
 import com.yingpaipay.business.domain.Document;
-import com.yingpaipay.business.domain.dto.WpsGetVersionsDto;
+import com.yingpaipay.business.domain.dto.WpsGetVersionsDTO;
 import com.yingpaipay.business.domain.dto.WpsR;
-import com.yingpaipay.business.domain.dto.WpsVersionControlDto;
-import com.yingpaipay.business.domain.dto.WpsVersionDto;
+import com.yingpaipay.business.domain.dto.WpsVersionControlDTO;
+import com.yingpaipay.business.domain.dto.WpsVersionDTO;
 import com.yingpaipay.business.service.common.CommonDocumentService;
 import jakarta.servlet.http.HttpServletRequest;
 import lombok.RequiredArgsConstructor;
@@ -47,7 +47,7 @@ public class WpsController extends BaseController {
     /**
      * 这里为版本控制缓存
      */
-    private static final Map<Long, WpsVersionControlDto> DOCUMENT_MAP = new ConcurrentHashMap<>();
+    private static final Map<Long, WpsVersionControlDTO> DOCUMENT_MAP = new ConcurrentHashMap<>();
 
     private final ISysOssService ossService;
     private final CommonDocumentService documentService;
@@ -56,7 +56,7 @@ public class WpsController extends BaseController {
     @PutMapping(value = "/upload/file/{documentId}", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
     public void upload(@PathVariable String documentId, HttpServletRequest request) {
         String[] ids = documentId.split("_");
-        WpsVersionControlDto dto = DOCUMENT_MAP.get(Long.valueOf(ids[0]));
+        WpsVersionControlDTO dto = DOCUMENT_MAP.get(Long.valueOf(ids[0]));
         File tempFile = null;
         try {
 
@@ -77,8 +77,8 @@ public class WpsController extends BaseController {
             OssClient storage = OssFactory.instance();
             UploadResult uploadResult = storage.uploadSuffix(tempFile, suffix, originalfileName);
             dto.setCurrentVersion(Long.parseLong(ids[1]));
-            List<WpsVersionDto> versions = dto.getVersions();
-            for (WpsVersionDto version : versions) {
+            List<WpsVersionDTO> versions = dto.getVersions();
+            for (WpsVersionDTO version : versions) {
                 if (Objects.equals(version.getVersion(), Long.valueOf(ids[1]))) {
 
                     // FIXME 由于原始版本不能被删除,暂时先不实现: 每新增一个版本,就将原始版本上传一个全新的版本
@@ -150,12 +150,12 @@ public class WpsController extends BaseController {
         long version = Long.parseLong(ids[1]);
 
         if (DOCUMENT_MAP.containsKey(id)) {
-            WpsVersionControlDto dto = DOCUMENT_MAP.get(id);
+            WpsVersionControlDTO dto = DOCUMENT_MAP.get(id);
             return WpsR.ok(new WpsGetFileInfoDto(
                 documentId, dto.getFileName(), 1, dto.getSize(), Math.toIntExact(new Date().getTime() / 1000L), Math.toIntExact(new Date().getTime() / 1000L), dto.getCreator(), dto.getUpdator()
             ));
         }
-        WpsVersionControlDto dto = initDocument(id);
+        WpsVersionControlDTO dto = initDocument(id);
         return WpsR.ok(new WpsGetFileInfoDto(
             documentId, dto.getFileName(), 1, dto.getSize(), Math.toIntExact(new Date().getTime() / 1000L), Math.toIntExact(new Date().getTime() / 1000L), dto.getCreator(), dto.getUpdator()
         ));
@@ -186,9 +186,9 @@ public class WpsController extends BaseController {
         long version = Long.parseLong(ids[1]);
 
         if (DOCUMENT_MAP.containsKey(id)) {
-            WpsVersionControlDto dto = DOCUMENT_MAP.get(id);
-            List<WpsVersionDto> versions = dto.getVersions();
-            for (WpsVersionDto versionDto : versions) {
+            WpsVersionControlDTO dto = DOCUMENT_MAP.get(id);
+            List<WpsVersionDTO> versions = dto.getVersions();
+            for (WpsVersionDTO versionDto : versions) {
                 if (versionDto.getVersion() == version) {
                     return WpsR.ok(new WpsGetUrlDto(versionDto.getUrl()));
                 }
@@ -196,9 +196,9 @@ public class WpsController extends BaseController {
             return WpsR.ok(new WpsGetUrlDto(dto.getVersions().get(0).getUrl()));
         }
 
-        WpsVersionControlDto dto = initDocument(id);
-        List<WpsVersionDto> versions = dto.getVersions();
-        for (WpsVersionDto versionDto : versions) {
+        WpsVersionControlDTO dto = initDocument(id);
+        List<WpsVersionDTO> versions = dto.getVersions();
+        for (WpsVersionDTO versionDto : versions) {
             if (Objects.equals(versionDto.getVersion(), dto.getCurrentVersion())) {
                 return WpsR.ok(new WpsGetUrlDto(versionDto.getUrl()));
             }
@@ -209,10 +209,10 @@ public class WpsController extends BaseController {
     @GetMapping("/files/{documentId}/versions/{version}/download")
     public WpsR getUrlByVersion(@PathVariable String documentId, @PathVariable Integer version) {
         if (DOCUMENT_MAP.containsKey(Long.valueOf(documentId.split("_")[0]))) {
-            WpsVersionControlDto dto = DOCUMENT_MAP.get(Long.valueOf(documentId.split("_")[0]));
+            WpsVersionControlDTO dto = DOCUMENT_MAP.get(Long.valueOf(documentId.split("_")[0]));
             return WpsR.ok(new WpsGetUrlDto(dto.getVersions().get(Integer.parseInt(documentId.split("_")[1])).getUrl()));
         }
-        WpsVersionControlDto dto = initDocument(Long.valueOf(documentId.split("_")[0]));
+        WpsVersionControlDTO dto = initDocument(Long.valueOf(documentId.split("_")[0]));
         return WpsR.ok(new WpsGetUrlDto(dto.getVersions().get(0).getUrl()));
     }
 
@@ -249,17 +249,17 @@ public class WpsController extends BaseController {
         return R.ok(DOCUMENT_MAP.get(documentId).getCurrentVersion());
     }
 
-    private WpsVersionControlDto initDocument(Long ossId) {
+    private WpsVersionControlDTO initDocument(Long ossId) {
         SysOssVo ossVo = ossService.getById(ossId);
         Document document = documentService.getByOssId(ossId);
         if (DOCUMENT_MAP.containsKey(document.getId())) {
             throw new BusinessException("已有其他人正在审核该文件");
         }
         long currentVersion = System.currentTimeMillis();
-        List<WpsVersionDto> list = new ArrayList<>();
-        list.add(new WpsVersionDto(ossVo.getFileName(), 0L, ossVo.getUrl(), new Date(), new Date(), Math.toIntExact(document.getCreateTime().getTime() / 1000L), Math.toIntExact(document.getUpdateTime().getTime() / 1000L)));
-        list.add(new WpsVersionDto(ossVo.getFileName(), currentVersion, ossVo.getUrl(), new Date(), new Date(), Math.toIntExact(document.getCreateTime().getTime() / 1000L), Math.toIntExact(document.getUpdateTime().getTime() / 1000L)));
-        WpsVersionControlDto dto = new WpsVersionControlDto();
+        List<WpsVersionDTO> list = new ArrayList<>();
+        list.add(new WpsVersionDTO(ossVo.getFileName(), 0L, ossVo.getUrl(), new Date(), new Date(), Math.toIntExact(document.getCreateTime().getTime() / 1000L), Math.toIntExact(document.getUpdateTime().getTime() / 1000L)));
+        list.add(new WpsVersionDTO(ossVo.getFileName(), currentVersion, ossVo.getUrl(), new Date(), new Date(), Math.toIntExact(document.getCreateTime().getTime() / 1000L), Math.toIntExact(document.getUpdateTime().getTime() / 1000L)));
+        WpsVersionControlDTO dto = new WpsVersionControlDTO();
         dto.setCurrentVersion(currentVersion);
         dto.setVersions(list);
         dto.setSuffix(ossVo.getFileSuffix());
@@ -275,9 +275,9 @@ public class WpsController extends BaseController {
 
     @PutMapping("/clean/{documentId}")
     public R clean(@PathVariable Long documentId) {
-        WpsVersionControlDto dto = DOCUMENT_MAP.get(documentId);
+        WpsVersionControlDTO dto = DOCUMENT_MAP.get(documentId);
         long currentVersion = System.currentTimeMillis();
-        dto.getVersions().add(new WpsVersionDto(
+        dto.getVersions().add(new WpsVersionDTO(
             dto.getVersions().get(0).getFileName(), currentVersion, dto.getVersions().get(0).getUrl(), new Date(), new Date(), Math.toIntExact(new Date().getTime() / 1000L), Math.toIntExact(new Date().getTime() / 1000L)
         ));
         dto.setCurrentVersion(currentVersion);
@@ -291,10 +291,10 @@ public class WpsController extends BaseController {
      */
     @GetMapping("/files/{documentId}/versions")
     public WpsR getVersions(@PathVariable Long documentId, @RequestParam(value = "offset", required = false) Integer offset, @RequestParam(value = "limit", required = false) Integer size) {
-        WpsVersionControlDto dto = DOCUMENT_MAP.get(documentId);
-        List<WpsVersionDto> versions = dto.getVersions();
+        WpsVersionControlDTO dto = DOCUMENT_MAP.get(documentId);
+        List<WpsVersionDTO> versions = dto.getVersions();
 
-        List<WpsVersionDto> reversed = new ArrayList<>(versions);
+        List<WpsVersionDTO> reversed = new ArrayList<>(versions);
         Collections.reverse(reversed);
 
         if (offset == null || size == null) {
@@ -304,14 +304,14 @@ public class WpsController extends BaseController {
         int fromIndex = Math.min(offset, reversed.size());
         int toIndex = Math.min(offset + size, reversed.size());
 
-        List<WpsVersionDto> paginated = reversed.subList(fromIndex, toIndex);
+        List<WpsVersionDTO> paginated = reversed.subList(fromIndex, toIndex);
 
-        List<WpsGetVersionsDto> list = new ArrayList<>();
-        paginated.forEach(e -> list.add(new WpsGetVersionsDto(
+        List<WpsGetVersionsDTO> list = new ArrayList<>();
+        paginated.forEach(e -> list.add(new WpsGetVersionsDTO(
             String.valueOf(documentId), dto.getFileName(), Math.toIntExact(e.getVersion() / 1000L), dto.getSize(), e.getCreate_time(), e.getUpdate_time(), dto.getCreator(), dto.getUpdator()
         )));
 
-        WpsR<List<WpsGetVersionsDto>> r = WpsR.ok(list);
+        WpsR<List<WpsGetVersionsDTO>> r = WpsR.ok(list);
         String str = JsonUtils.toJsonString(r);
         log.warn(str);
         return r;
@@ -322,16 +322,16 @@ public class WpsController extends BaseController {
      */
     @GetMapping("/files/{documentId}/versions/{version}")
     public WpsR getFileByVersion(@PathVariable Long documentId, @PathVariable Integer version) {
-        WpsVersionControlDto dto = DOCUMENT_MAP.get(documentId);
-        WpsVersionDto current = dto.getVersions().get(version - 1);
-        return WpsR.ok(new WpsGetVersionsDto(
+        WpsVersionControlDTO dto = DOCUMENT_MAP.get(documentId);
+        WpsVersionDTO current = dto.getVersions().get(version - 1);
+        return WpsR.ok(new WpsGetVersionsDTO(
             String.valueOf(documentId), dto.getFileName(), Math.toIntExact(current.getVersion() / 1000L), dto.getSize(), current.getCreate_time(), current.getUpdate_time(), dto.getCreator(), dto.getUpdator()
         ));
     }
 
     @GetMapping("/files/list")
-    public R<List<WpsVersionDto>> getVersionList(@RequestParam("ossId") Long ossId) {
-        List<WpsVersionDto> list = DOCUMENT_MAP.get(ossId).getVersions();
+    public R<List<WpsVersionDTO>> getVersionList(@RequestParam("ossId") Long ossId) {
+        List<WpsVersionDTO> list = DOCUMENT_MAP.get(ossId).getVersions();
         list.forEach(e -> log.info("{}", JsonUtils.toJsonString(e)));
         return R.ok(list.stream().filter(e -> e.getVersion() != 0L).sorted((e1, e2) -> Math.toIntExact(e2.getVersion() - e1.getVersion())).toList());
     }
@@ -344,9 +344,9 @@ public class WpsController extends BaseController {
 
         log.info("文档编号为 {}, 版本号为 : {}", documentId, version);
 
-        WpsVersionControlDto dto = DOCUMENT_MAP.get(documentId);
-        List<WpsVersionDto> versions = dto.getVersions();
-        for (WpsVersionDto versionDto : versions) {
+        WpsVersionControlDTO dto = DOCUMENT_MAP.get(documentId);
+        List<WpsVersionDTO> versions = dto.getVersions();
+        for (WpsVersionDTO versionDto : versions) {
             log.info("当前轮询的版本号为 {}", versionDto.getVersion());
             if (versionDto.getVersion() == version) {
                 String url = versionDto.getUrl();

+ 12 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/AiAuditDTO.java

@@ -0,0 +1,12 @@
+package com.yingpaipay.business.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class AiAuditDTO {
+
+    private Boolean result;
+
+    private String rejectReason;
+
+}

+ 0 - 13
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/AiAuditDto.java

@@ -1,13 +0,0 @@
-package com.yingpaipay.business.domain.dto;
-
-import com.yingpaipay.business.enumeration.AiAuditRejectReasonEnum;
-import lombok.Data;
-
-@Data
-public class AiAuditDto {
-
-    private Integer result;
-
-    private AiAuditRejectReasonEnum rejectReason;
-
-}

+ 10 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/TextInImageToWordDTO.java

@@ -0,0 +1,10 @@
+package com.yingpaipay.business.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class TextInImageToWordDTO {
+
+    private String docx;
+
+}

+ 163 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/TextInPdfToMarkdownDTO.java

@@ -0,0 +1,163 @@
+package com.yingpaipay.business.domain.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class TextInPdfToMarkdownDTO {
+
+    private Integer total_page_number;
+
+    private Integer valid_page_number;
+
+    private List<Page> pages;
+
+    private List<Detail> detail;
+
+    private Catalog catalog;
+
+    private String markdown;
+
+    private String excel_base64;
+
+
+    @Data
+    public static class Page {
+
+        private String status;
+
+        private Integer page_id;
+
+        private Integer durations;
+
+        private String image_id;
+
+        private String origin_image_id;
+
+        private String base64;
+
+        private String origin_base64;
+
+        private Integer width;
+
+        private Integer height;
+
+        private Integer angle;
+
+        private List<Object> content;
+
+        private List<Object> raw_ocr;
+
+        private List<Object> structured;
+
+    }
+
+    @Data
+    public static class Detail {
+
+        private Integer page_id;
+
+        private Integer paragraph_id;
+
+        private Integer outline_level;
+
+        private String text;
+
+        private String type;
+
+        private String image_url;
+
+        private Integer content;
+
+        private List<Object> position;
+
+        private List<Object> origin_position;
+
+        private String sub_type;
+
+        private List<Object> tags;
+
+        private CaptionId caption_id;
+
+        private List<Cell> cells;
+
+        private List<Object> split_section_page_ids;
+
+        private List<Object> split_section_positions;
+
+        private Stamp stamp;
+
+
+        @Data
+        public static class CaptionId {
+
+            private Integer page_id;
+
+            private Integer paragraph_id;
+
+        }
+
+        @Data
+        public static class Cell {
+
+            private Integer row;
+
+            private Integer col;
+
+            private Integer row_span;
+
+            private Integer col_span;
+
+            private List<Object> position;
+
+            private List<Object> origin_position;
+
+            private String text;
+
+            private String type;
+
+        }
+
+        @Data
+        public static class Stamp {
+
+            private String value;
+
+            private String stamp_shape;
+
+            private String type;
+
+            private String color;
+
+        }
+
+    }
+
+    @Data
+    public static class Catalog {
+
+        private List<Toc> toc;
+
+        @Data
+        public static class Toc {
+
+            private String sub_type;
+
+            private String hierachy;
+
+            private String title;
+
+            private Integer page_id;
+
+            private Integer paragraph_id;
+
+            private List<Object> pos;
+
+            private List<Object> pos_list;
+
+        }
+
+    }
+
+}

+ 1 - 1
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsGetVersionsDto.java → ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsGetVersionsDTO.java

@@ -6,7 +6,7 @@ import lombok.Data;
 @Deprecated
 @Data
 @AllArgsConstructor
-public class WpsGetVersionsDto {
+public class WpsGetVersionsDTO {
 
     private String id;
     private String name;

+ 2 - 2
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsVersionControlDto.java → ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsVersionControlDTO.java

@@ -6,7 +6,7 @@ import java.util.List;
 
 @Deprecated
 @Data
-public class WpsVersionControlDto {
+public class WpsVersionControlDTO {
 
     private String fileName;
 
@@ -20,6 +20,6 @@ public class WpsVersionControlDto {
 
     private String updator;
 
-    private List<WpsVersionDto> versions;
+    private List<WpsVersionDTO> versions;
 
 }

+ 1 - 1
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsVersionDto.java → ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/domain/dto/WpsVersionDTO.java

@@ -8,7 +8,7 @@ import java.util.Date;
 @Deprecated
 @Data
 @AllArgsConstructor
-public class WpsVersionDto {
+public class WpsVersionDTO {
 
     private String fileName;
 

+ 65 - 28
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/AiAuditService.java

@@ -1,21 +1,30 @@
 package com.yingpaipay.business.service;
 
+import cn.hutool.core.lang.Dict;
 import com.yingpaipay.business.constant.AiAuditResultConst;
-import com.yingpaipay.business.domain.dto.AiAuditDto;
-import com.yingpaipay.business.enumeration.AiAuditRejectReasonEnum;
+import com.yingpaipay.business.domain.dto.AiAuditDTO;
+import com.yingpaipay.business.domain.dto.TextInPdfToMarkdownDTO;
+import com.yingpaipay.common.ai.client.SiliconFlowClient;
+import com.yingpaipay.common.ai.enumeration.SiliconFlowRole;
+import com.yingpaipay.common.ai.enumeration.SiliconModel;
+import com.yingpaipay.common.ai.pojo.SiliconFlowMessage;
+import com.yingpaipay.common.ai.pojo.SiliconFlowResp;
 import com.yingpaipay.setting.service.IAiSettingService;
+import io.swagger.v3.core.util.Json;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.common.oss.core.OssClient;
+import org.dromara.common.oss.factory.OssFactory;
 import org.dromara.system.domain.vo.SysOssVo;
 import org.dromara.system.service.ISysOssService;
 import org.springframework.stereotype.Component;
 
-import java.io.File;
 import java.io.IOException;
-import java.net.URL;
+import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
+import java.util.Base64;
 
 @Component
 @RequiredArgsConstructor
@@ -24,47 +33,75 @@ public class AiAuditService {
 
     private final IAiSettingService settingService;
     private final ISysOssService ossService;
+    private final ITextInService textInService;
 
-    public AiAuditDto audit(Long ossId) {
+    private final SiliconFlowClient siliconFlowClient;
+
+    public AiAuditDTO audit(Long ossId) {
         if (!settingService.query().getEnabledFlag()) {
             return null;
         }
         return handleAudit(ossId);
     }
 
-    public AiAuditDto handleAudit(Long ossId) {
+    public AiAuditDTO handleAudit(Long ossId) {
         SysOssVo ossVo = ossService.getById(ossId);
-        String url = ossVo.getUrl();
-        File file;
 
+        Path tempFile;
         try {
-            Path tempFile = Files.createTempFile("ai_audit_", ".pdf");
-
-            try (var inputStream = new URL(url).openStream()) {
-                Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING);
-            }
-            file = tempFile.toFile();
-
+            tempFile = Files.createTempFile("ai_audit_", ".pdf");
         } catch (IOException e) {
-            log.error("下载文件失败: {}", url, e);
+            log.error("创建临时文件失败", e);
+            throw new RuntimeException("AI 审核临时文件创建失败", e);
+        }
+
+        try (OutputStream fos = Files.newOutputStream(tempFile)) {
+            OssClient storage = OssFactory.instance(ossVo.getService());
+            storage.download(ossVo.getFileName(), fos, size -> {});
+        } catch (Exception e) {
+            log.error("OSS 文件下载失败: ossId={}, fileName={}", ossId, ossVo.getFileName(), e);
             throw new RuntimeException("AI 审核文件下载失败", e);
         }
 
-        AiAuditDto dto = new AiAuditDto();
         // TODO 进行具体的审核环节
-        boolean pageFlag = checkPages(file);
-        if (!pageFlag) {
-            dto.setResult(AiAuditResultConst.REJECT);
-            dto.setRejectReason(AiAuditRejectReasonEnum.PAGE_ERROR);
+        AiAuditDTO dto = new AiAuditDTO();
+        TextInPdfToMarkdownDTO textInDto;
+
+        try {
+            textInDto = textInService.pdfToMarkdown(Base64.getEncoder().encodeToString(Files.readAllBytes(tempFile)));
+        } catch (IOException e) {
+            throw new RuntimeException("解析文件失败");
+        } finally {
+            try {
+                Files.deleteIfExists(tempFile);
+            } catch (IOException e) {
+                log.warn("清理临时文件失败: {}", tempFile, e);
+            }
         }
 
-        dto.setResult(AiAuditResultConst.PASS);
-        return dto;
-    }
+        String systemContent = """
+                                你是一名医药科技文件审核员,你需要负责用户传过来的文件,审核内容如下:
+                                1.有页码标识的文件,页码不完整
+                                2.GCP证书日期是2020年7月1日之前的
+                                3.设备校准证书有效期到期日期在中心启动日期之前(中心SIV日期,可检索SIVR日期
+
+                                最终需要给出的结果为JSON字符串,如下:
+                                通过的结果:{"result":true,"rejectReason":null}
+                                驳回的结果:{"result":false,"rejectReason":"驳回原因"}
 
-    private boolean checkPages(File file) {
-        // TODO 使用 textin 进行 OCR 解析
-        return true;
+                                不要返回分析过程并且在一个rejectReason中说明所有原因,我只要最终的JSON结果。
+                                例如只回复:
+                                {"result":true,"rejectReason":null}
+                                或者只回复:
+                                {"result":false,"rejectReason":"1、驳回原因1;2、驳回原因2"}
+                                """;
+        SiliconFlowResp resp = siliconFlowClient.askMessages(
+            SiliconModel.GLM_4_7,
+            new SiliconFlowMessage(SiliconFlowRole.SYSTEM, systemContent),
+            new SiliconFlowMessage(SiliconFlowRole.USER, JsonUtils.toJsonString(textInDto))
+        );
+        log.info("回复内容 : \n{}", resp.getChoices().get(0).getMessage().getContent());
+        return JsonUtils.parseObject(resp.getChoices().get(0).getMessage().getContent(), AiAuditDTO.class);
     }
 
 }

+ 6 - 0
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/ITextInService.java

@@ -1,6 +1,7 @@
 package com.yingpaipay.business.service;
 
 import com.yingpaipay.business.domain.bo.AppletScanBo;
+import com.yingpaipay.business.domain.dto.TextInPdfToMarkdownDTO;
 
 
 public interface ITextInService {
@@ -11,4 +12,9 @@ public interface ITextInService {
     String wordToImage(String docx);
 
     String wordToPdf(String docx);
+
+    /**
+     * 官方文档 : <a href="https://www.textin.com/document/legacy/pdf_to_markdown"></a>
+     */
+    TextInPdfToMarkdownDTO pdfToMarkdown(String file);
 }

+ 39 - 5
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/DocumentServiceImpl.java

@@ -12,6 +12,7 @@ import com.yingpaipay.business.domain.DocumentAuditLog;
 import com.yingpaipay.business.domain.Folder;
 import com.yingpaipay.business.domain.Project;
 import com.yingpaipay.business.domain.bo.*;
+import com.yingpaipay.business.domain.dto.AiAuditDTO;
 import com.yingpaipay.business.domain.excel.ProjectExcel;
 import com.yingpaipay.business.domain.vo.*;
 import com.yingpaipay.business.enumeration.DocumentStatusEnum;
@@ -324,13 +325,13 @@ public class DocumentServiceImpl implements IDocumentService {
         document.setEffectiveDate(bo.getEffectiveDate());
         document.setStatus(DocumentStatusEnum.UN_AUDIT.getValue());
 
+        aiAudit(document);
+
         boolean updateFlag = baseMapper.updateById(document) == 0;
         if (updateFlag) {
             throw new RuntimeException("更新文档失败");
         }
 
-        aiAuditService.audit(bo.getOssId());
-
         return true;
     }
 
@@ -934,7 +935,10 @@ public class DocumentServiceImpl implements IDocumentService {
                 document.setSubmitTime(new Date());
                 document.setStatus(DocumentStatusEnum.UN_AUDIT.getValue());
                 document.setEffectiveDate(bo.getEffectiveDate());
-                return baseMapper.updateById(document) > 0;
+
+                aiAudit(document);
+
+                return baseMapper.updateById(document) == 0;
             }
         }
 
@@ -954,14 +958,44 @@ public class DocumentServiceImpl implements IDocumentService {
         document.setSpecificationType(bo.getFolder() != 0L ? SpecificationTypeConst.CENTER : SpecificationTypeConst.PROJECT);
         document.setTenantId(TenantHelper.getTenantId());
 
-        aiAuditService.audit(ossVo.getOssId());
-
         boolean documentInserFlag = baseMapper.insert(document) == 0;
         if (documentInserFlag) {
             throw new RuntimeException("文档插入失败");
         }
+        aiAudit(document);
+        boolean documentUpdateFlag = baseMapper.updateById(document) == 0;
+        if (documentUpdateFlag) {
+            throw new RuntimeException("文档更新状态失败");
+        }
 
         return true;
+//        throw new RuntimeException("测试成功");
+    }
+
+    private void aiAudit(Document document) {
+        AiAuditDTO result = aiAuditService.audit(document.getActualDocument());
+        if (result != null) {
+            DocumentAuditLog log = new DocumentAuditLog();
+            log.setDocumentId(document.getId());
+            log.setUploadVersion(document.getActualDocument());
+            log.setAuditorType(DocumentAuditorTypeConst.AI);
+            log.setResult(result.getResult() ? DocumentStatusEnum.ARCHIEVED.getValue() : DocumentStatusEnum.AUDIT_REJECT.getValue());
+            log.setAuditor(0L);
+            log.setRejectReason(result.getRejectReason());
+            log.setAuditTime(new Date());
+            log.setSubmitter(document.getSubmitter());
+            log.setTenantId(TenantHelper.getTenantId());
+            boolean logFlag = auditLogMapper.insert(log) == 0;
+            if (logFlag) {
+                throw new RuntimeException("审核结果追加失败");
+            }
+
+            if (result.getResult()) {
+                document.setStatus(DocumentStatusEnum.UN_AUDIT.getValue());
+            } else {
+                document.setStatus(DocumentStatusEnum.AUDIT_REJECT.getValue());
+            }
+        }
     }
 
     @Override

+ 64 - 47
ruoyi-modules/yingpaipay-business/src/main/java/com/yingpaipay/business/service/impl/TextInServiceImpl.java

@@ -3,7 +3,12 @@ package com.yingpaipay.business.service.impl;
 import cn.hutool.http.Header;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.yingpaipay.business.domain.bo.AppletScanBo;
+import com.yingpaipay.business.domain.dto.TextInImageToWordDTO;
+import com.yingpaipay.business.domain.dto.TextInPdfToMarkdownDTO;
 import com.yingpaipay.business.domain.dto.TextInR;
 import com.yingpaipay.business.service.ITextInService;
 import com.yingpaipay.common.file.config.TextInConfig;
@@ -11,12 +16,10 @@ import com.yingpaipay.setting.domain.vo.TextinSettingVo;
 import com.yingpaipay.setting.service.ITextinSettingService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.logging.log4j.message.Message;
 import org.dromara.common.core.exception.BusinessException;
 import org.dromara.common.core.utils.MessageUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.json.utils.JsonUtils;
-import org.jspecify.annotations.NonNull;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Service;
 
@@ -39,71 +42,78 @@ public class TextInServiceImpl implements ITextInService {
 
     private final ITextinSettingService settingService;
 
-    private HttpResponse getResponse(HttpRequest request) {
+    private <T> T getResponse(HttpRequest request, Class<T> clazz) {
         TextinSettingVo setting = settingService.query();
-        return request
+
+        try (HttpResponse response = request
             .header(HEADER_APP_ID, setting.getAppId())
             .header(HEADER_SECRET_CODE, setting.getSecretCode())
-            .execute();
-    }
+            .execute()) {
 
-    @Override
-    public String imageToPdf(AppletScanBo bo) {
+            if (!response.isOk()) {
+                throw new BusinessException(MessageUtils.message("textin.networkerror"));
+            }
 
-        HttpResponse response = getResponse(
-            HttpRequest.post(config.getImageToPdf()).body(JsonUtils.toJsonString(bo))
-        );
 
-        TextInR result = getR(response);
+            String body = response.body();
+            log.info("返回的实体为 : {}", body);
 
-        return result.getResult().toString();
+            if (StringUtils.isEmpty(body)) {
+                throw new BusinessException(MessageUtils.message("textin.recognitionfail"));
+            }
 
-    }
+            // 由于 jsonUtils 中自带的parseObject中, Jackson会自动将未匹配的泛型强行匹配成LinkedHashMap, 由此在转换为真实的对象时会报错。
+            TextInR<T> result;
+            ObjectMapper mapper = JsonUtils.getObjectMapper();
+            JavaType type = mapper.getTypeFactory().constructParametricType(TextInR.class, clazz);
+            try {
+                result = mapper.readValue(body, type);
+            } catch (JsonProcessingException e) {
+                throw new RuntimeException(e);
+            }
 
-    private static @NonNull TextInR getR(HttpResponse response) {
-        if (!response.isOk()) {
-            throw new BusinessException(MessageUtils.message("textin.networkerror"));
-        }
-        String body = response.body();
-        if (StringUtils.isEmpty(body)) {
-            throw new BusinessException(MessageUtils.message("textin.recognitionfail"));
-        }
-        TextInR result = JsonUtils.parseObject(body, TextInR.class);
-        if (result == null) {
-            throw new BusinessException(MessageUtils.message("textin.recognitionfail"));
-        }
-        if (result.isError()) {
-            throw new RuntimeException(result.getMessage());
+            if (result == null) {
+                throw new BusinessException(MessageUtils.message("textin.recognitionfail"));
+            }
+            if (result.isError()) {
+                throw new RuntimeException(result.getMessage());
+            }
+            return result.getResult();
+        } catch (Exception e) {
+            log.error("向 TextIn 发送请求执行失败", e);
+            throw new RuntimeException(e);
         }
-        return result;
     }
 
     @Override
-    public String imageToWord(String image) {
-
-        HttpResponse response = getResponse(
-            HttpRequest.post(config.getImageToWord())
-                .header(Header.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
-                .body(Base64.getDecoder().decode(image))
+    public String imageToPdf(AppletScanBo bo) {
+        return getResponse(
+            HttpRequest.post(config.getImageToPdf()).body(JsonUtils.toJsonString(bo)),
+            String.class
         );
+    }
 
-        TextInR result = getR(response);
 
-        return JsonUtils.parseMap(JsonUtils.toJsonString(result.getResult())).getStr("docx");
+    @Override
+    public String imageToWord(String image) {
+        return getResponse(
+            HttpRequest.post(config.getImageToWord())
+                .header(Header.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
+                .body(Base64.getDecoder().decode(image)),
+            TextInImageToWordDTO.class
+        ).getDocx();
     }
 
     @Override
     public String wordToImage(String docx) {
 
-        HttpResponse response = getResponse(
+        String zipBase64 = getResponse(
             HttpRequest.post(config.getWordToImage())
                 .header(Header.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
-                .body(docx)
+                .body(docx),
+            String.class
         );
 
-        TextInR result = getR(response);
-        String zipBase64 = result.getResult().toString();
-
         if (zipBase64.contains(",")) {
             zipBase64 = zipBase64.substring(zipBase64.indexOf(",") + 1);
         }
@@ -149,16 +159,23 @@ public class TextInServiceImpl implements ITextInService {
 
     @Override
     public String wordToPdf(String docx) {
-
-        HttpResponse response = getResponse(
+        return getResponse(
             HttpRequest.post(config.getWordToPdf())
                 .header(Header.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
-                .body(Base64.getDecoder().decode(docx))
+                .body(Base64.getDecoder().decode(docx)),
+            String.class
         );
+    }
 
-        TextInR result = getR(response);
 
-        return result.getResult().toString();
+    @Override
+    public TextInPdfToMarkdownDTO pdfToMarkdown(String file) {
+        return getResponse(
+            HttpRequest.post(config.getPdfToMarkdown())
+                .header(Header.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
+                .body(Base64.getDecoder().decode(file)),
+            TextInPdfToMarkdownDTO.class
+        );
     }
 
 }

+ 2 - 1
ruoyi-modules/yingpaipay-setting/src/main/java/com/yingpaipay/setting/controller/TextinSettingController.java

@@ -37,7 +37,8 @@ public class TextinSettingController extends BaseController {
     @Log(title = "TextIn", businessType = BusinessType.UPDATE)
     @PutMapping()
     public R<Void> edit(@RequestBody TextinSettingBo bo) {
-        return toAjax(textinSettingService.update(bo));
+        TextinSettingVo vo = textinSettingService.update(bo);
+        return toAjax(vo != null);
     }
 
 }

+ 1 - 1
ruoyi-modules/yingpaipay-setting/src/main/java/com/yingpaipay/setting/service/ITextinSettingService.java

@@ -13,5 +13,5 @@ public interface ITextinSettingService {
 
     TextinSettingVo query();
 
-    boolean update(TextinSettingBo bo);
+    TextinSettingVo update(TextinSettingBo bo);
 }

+ 6 - 2
ruoyi-modules/yingpaipay-setting/src/main/java/com/yingpaipay/setting/service/impl/TextinSettingServiceImpl.java

@@ -35,8 +35,12 @@ public class TextinSettingServiceImpl implements ITextinSettingService {
 
     @CachePut(cacheNames = CacheNames.SETTING, key = "'textin'")
     @Override
-    public boolean update(TextinSettingBo bo) {
+    public TextinSettingVo update(TextinSettingBo bo) {
         TextinSetting entity = MapstructUtils.convert(bo, TextinSetting.class);
-        return baseMapper.updateById(entity) > 0;
+        boolean flag = baseMapper.updateById(entity) == 0;
+        if (flag) {
+            throw new RuntimeException("失败");
+        }
+        return MapstructUtils.convert(entity, TextinSettingVo.class);
     }
 }