From d2bebf83a3bfc113f85f909fc24970fc2c1c0d2c Mon Sep 17 00:00:00 2001 From: luotaiqian <1147642922@qq.com> Date: Fri, 21 Aug 2026 14:42:57 +0800 Subject: [PATCH] PaperBasicInfo --- .../adapter/web/H5OpenController.java | 9 ++++ .../safetyeval/app/executor/WpsExecutor.java | 54 +++++++++++++++++-- .../qinan/safetyeval/client/api/WpsApi.java | 10 ++++ 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/H5OpenController.java b/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/H5OpenController.java index af4b41aa..61e400e6 100644 --- a/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/H5OpenController.java +++ b/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/H5OpenController.java @@ -10,6 +10,7 @@ import org.qinan.safetyeval.client.co.WpsDocOpenCO; import org.qinan.safetyeval.infrastructure.dataobject.base.Req; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -162,6 +163,14 @@ public class H5OpenController { return SingleResponse.of(wpsApi.createBlank(data.getOrDefault("docxUrl", ""), Long.parseLong(data.getOrDefault("projectId", "0")))); } + @ApiOperation("上传已有Word文件并创建文档,返回可打开的WPS文档信息") + @PostMapping(value = "/doc/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public SingleResponse uploadDoc(@RequestPart("file") MultipartFile file, + @RequestParam("projectId") Long projectId) throws IOException { + log.info("wps upload doc, name={}, size={}, projectId={}", file.getOriginalFilename(), file.getSize(), projectId); + return SingleResponse.of(wpsApi.uploadDoc(file.getInputStream(), file.getOriginalFilename(), projectId)); + } + @ApiOperation("模版文档(固定)") @PostMapping(value = "/doc/template") public SingleResponse> template() { diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/WpsExecutor.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/WpsExecutor.java index dc4ec21e..90dbf849 100644 --- a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/WpsExecutor.java +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/WpsExecutor.java @@ -2,6 +2,7 @@ package org.qinan.safetyeval.app.executor; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.jjb.saas.framework.auth.utils.AuthContext; import lombok.extern.slf4j.Slf4j; import org.dromara.x.file.storage.core.FileInfo; import org.dromara.x.file.storage.core.FileStorageService; @@ -364,6 +365,38 @@ public class WpsExecutor implements WpsApi { } } + @Override + public WpsDocOpenCO uploadDoc(InputStream inputStream, String fileName, Long projectId) { + try { + Long userId = requireUserId(); + if (Objects.isNull(projectId)) { + throw new BizException(ErrorCode.EVAL_PROJECT_ERROR); + } + String docName = StringUtils.hasText(fileName) ? fileName : "未命名文档.docx"; + Long orgId = AuthContext.getOrgId(); + + FileStorage saved; + try { + FileInfo ossFileInfo = fileStorageService.of(inputStream, docName).upload(); + FileStorage fileStorage = FileStorageHelper.buildResource(ossFileInfo, docName, true); + saved = fileStorageDomainService.saveResource(fileStorage); + } catch (BizException e) { + throw e; + } catch (Exception e) { + log.error("upload docx failed, name={}", docName, e); + throw new BizException(ErrorCode.FILE_UPLOAD_FAILED, e); + } + + WpsDocEntity created = createInitialDoc(userId, orgId, docName, saved, projectId); + return toOpenCO(created, true); + } catch (BizException e) { + throw e; + } catch (Exception e) { + log.error("wps uploadDoc failed, name={}", fileName, e); + throw new BizException(ErrorCode.UNKNOWN_ERROR); + } + } + @Override public WpsDocOpenCO getDocByProjectId(String projectId) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); @@ -388,10 +421,7 @@ public class WpsExecutor implements WpsApi { throw new BizException(ErrorCode.WPS_BLANK_DOCX_URL_EMPTY); } Long orgId = requireOrgId(); - String creatorId = String.valueOf(userId); - String fileId = generateFileId(); String docName = "未命名文档.docx"; - long nowEpoch = System.currentTimeMillis() / 1000; FileStorage saved; try (InputStream inputStream = new URL(resDocxUrl).openStream()) { @@ -405,6 +435,24 @@ public class WpsExecutor implements WpsApi { throw new BizException(ErrorCode.WPS_BLANK_DOCX_DOWNLOAD_FAILED, e); } + return createInitialDoc(userId, orgId, docName, saved, projectId); + } + + /** + * 根据已落存储的文件资源创建文档主记录与初始版本 + * + * @param userId 创建人id + * @param orgId 组织id + * @param docName 文档名 + * @param saved 已保存的文件资源 + * @param projectId 项目id + * @return 创建后的文档实体 + */ + private WpsDocEntity createInitialDoc(Long userId, Long orgId, String docName, FileStorage saved, Long projectId) { + String creatorId = String.valueOf(userId); + String fileId = generateFileId(); + long nowEpoch = System.currentTimeMillis() / 1000; + WpsDocEntity doc = new WpsDocEntity(); doc.setFileId(fileId); doc.setOrgId(orgId); diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/api/WpsApi.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/api/WpsApi.java index 00ed6a77..d3c18b19 100644 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/api/WpsApi.java +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/api/WpsApi.java @@ -47,5 +47,15 @@ public interface WpsApi { */ WpsDocOpenCO createBlank(String docxUrl, Long projectId); + /** + * 上传已有 Word 文件,落存储后创建文档记录(用于 WPS 打开) + * + * @param inputStream 文件流 + * @param fileName 原始文件名 + * @param projectId 项目id + * @return 打开文档信息 + */ + WpsDocOpenCO uploadDoc(InputStream inputStream, String fileName, Long projectId); + WpsDocOpenCO getDocByProjectId(String projectId); }