diff --git a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/enums/WpsErrorCodeEnum.java b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/enums/WpsErrorCodeEnum.java new file mode 100644 index 00000000..c530bdfd --- /dev/null +++ b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/enums/WpsErrorCodeEnum.java @@ -0,0 +1,34 @@ + +package cn.axzo.nanopart.doc.api.enums; + +import cn.axzo.framework.domain.web.code.IRespCode; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author xudawei@axzo.cn + * @date 2025/03/21 + * @description wps错误码枚举 + */ +@Getter +@AllArgsConstructor +public enum WpsErrorCodeEnum implements IRespCode { + + TOKEN_INVALID("40002", "用户凭证,即x-weboffice-token头, 无效"), + NO_PERMISSION("40003", "用户操作权限不足"), + FILE_NOT_EXIST("40004", "文档不存在"), + REQUEST_PARAMETER_ERROR("40005", "请求参数错误"), + STORAGE_SPACE_IS_FULL("40006", "存储空间已满"), + CUSTOM_ERROR("40007", "自定义错误,可以用来返回自定义错误信息"), + FILE_NAME_CONFLICT("40008", "文档名称冲突,例如重命名文档时"), + FILE_VERSION_NOT_EXIST("40009", "文档版本不存在"), + USER_NOT_EXIST("40010", "用户不存在"), + UPLOAD_ERROR("41001", "文件未正确上传"), + SYSTEM_ERROR("50001", "系统错误导致的请求不能正常响应"), + ; + + private String code; + + private String message; + +} diff --git a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/util/Constants.java b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/util/Constants.java new file mode 100644 index 00000000..59cc4d22 --- /dev/null +++ b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/util/Constants.java @@ -0,0 +1,36 @@ +package cn.axzo.nanopart.doc.api.util; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/21 + * @description 静态类 + */ +public class Constants { + + /** + * WPS-上传地址的content-type + */ + public static final String WPS_UPLOAD_ADDRESS_CONTENT_TYPE = "Content-Type"; + + /** + * WPS-上传地址的form-data + */ + public static final String WPS_UPLOAD_ADDRESS_FORM_DATA = "multipart/form-data"; + + /** + * WPS-上传地址的Host + */ + public static final String WPS_UPLOAD_ADDRESS_HOST = "Host"; + + /** + * WPS-上传地址的PUT + */ + public static final String WPS_UPLOAD_ADDRESS_PUT = "PUT"; + + + /** + * WPS-准备上传摘要算法-sha1 + */ + public static final String WPS_UPLOAD_PREPARE_SHA1 = "sha1"; + +} diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/integration/DocOssGateway.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/integration/DocOssGateway.java index 70bd1a7d..06a85f85 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/integration/DocOssGateway.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/integration/DocOssGateway.java @@ -1,6 +1,8 @@ package cn.axzo.nanopart.doc.integration; +import cn.axzo.nanopart.doc.api.enums.WpsErrorCodeEnum; +import cn.axzo.nanopart.doc.wps.support.WpsException; import cn.axzo.oss.http.api.ServerFileServiceApi; import cn.axzo.oss.http.model.ApiSignUrlDownloadRequest; import cn.axzo.oss.http.model.ApiSignUrlDownloadResponse; @@ -42,7 +44,7 @@ public class DocOssGateway { } catch (Exception e) { log.warn("DocOssGateway-signUrlFetchDownload exception", e); - throw e; + throw new WpsException(WpsErrorCodeEnum.UPLOAD_ERROR); } } @@ -75,7 +77,7 @@ public class DocOssGateway { return response.getData(); } catch (Exception e) { log.warn("DocOssGateway-signUrlFetchUpload exception", e); - throw e; + throw new WpsException(WpsErrorCodeEnum.UPLOAD_ERROR); } } diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/support/WpsAssertUtil.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/support/WpsAssertUtil.java new file mode 100644 index 00000000..86192e3d --- /dev/null +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/support/WpsAssertUtil.java @@ -0,0 +1,37 @@ +package cn.axzo.nanopart.doc.wps.support; + +import cn.axzo.framework.domain.web.code.IRespCode; +import org.apache.commons.lang3.StringUtils; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/21 + * @description TODO + */ +public class WpsAssertUtil { + + + public static void notNull(Object object, IRespCode code) { + if (object == null) { + fail(code); + } + } + + public static void notEmpty(String object, IRespCode code) { + if (StringUtils.isEmpty(object)) { + fail(code); + } + } + + public static void isFalse(boolean condition, IRespCode code) { + if (condition) { + fail(code); + } + + } + + public static void fail(IRespCode code) { + throw new WpsException(Integer.parseInt(code.getCode()), code.getMessage()); + } + +} diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/support/WpsException.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/support/WpsException.java new file mode 100644 index 00000000..57f8d8c2 --- /dev/null +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/support/WpsException.java @@ -0,0 +1,28 @@ +package cn.axzo.nanopart.doc.wps.support; + +import cn.axzo.framework.domain.web.code.IRespCode; +import lombok.Data; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/21 + * @description Wps异常 + */ +@Data +public class WpsException extends RuntimeException { + + private Integer errorCode; + private String errorMessage; + + public WpsException(Integer code, String msg) { + super(msg); + this.errorCode = code; + this.errorMessage = msg; + } + + public WpsException(IRespCode code) { + super(code.getMessage()); + this.errorCode = Integer.parseInt(code.getCode()); + this.errorMessage = code.getMessage(); + } +} diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/support/WpsSupport.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/support/WpsSupport.java new file mode 100644 index 00000000..18981050 --- /dev/null +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/support/WpsSupport.java @@ -0,0 +1,34 @@ +package cn.axzo.nanopart.doc.wps.support; + +import cn.axzo.nanopart.doc.api.enums.WpsErrorCodeEnum; +import cn.axzo.nanopart.doc.dao.IndexNodeDao; +import cn.axzo.nanopart.doc.entity.IndexNode; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/21 + * @description wps支持 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class WpsSupport { + + private final IndexNodeDao indexNodeDao; + + public IndexNode findAndCheckByCode(String docCode) { + IndexNode node = indexNodeDao.findOrNull(docCode); + WpsAssertUtil.notNull(node, WpsErrorCodeEnum.FILE_NOT_EXIST); + return node; + } + + public IndexNode findAndCheckForUpdateByCode(String docCode) { + IndexNode node = indexNodeDao.findForUpdateOrNull(docCode); + WpsAssertUtil.notNull(node, WpsErrorCodeEnum.FILE_NOT_EXIST); + return node; + } + +} diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/wpsbase/WpsBaseManager.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/wpsbase/WpsBaseManager.java index ee397acd..1d1666cb 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/wpsbase/WpsBaseManager.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/wpsbase/WpsBaseManager.java @@ -2,6 +2,7 @@ package cn.axzo.nanopart.doc.wps.wpsbase; import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.basics.profiles.dto.basic.PersonProfileDto; +import cn.axzo.nanopart.doc.api.enums.WpsErrorCodeEnum; import cn.axzo.nanopart.doc.api.wps.request.WpsPermissionRequest; import cn.axzo.nanopart.doc.api.wps.request.WpsRenameRequest; import cn.axzo.nanopart.doc.api.wps.request.WpsUsersRequest; @@ -15,6 +16,8 @@ import cn.axzo.nanopart.doc.dao.IndexNodeDao; import cn.axzo.nanopart.doc.entity.IndexNode; import cn.axzo.nanopart.doc.integration.DocOssGateway; import cn.axzo.nanopart.doc.integration.DocUserProfileGateway; +import cn.axzo.nanopart.doc.wps.support.WpsAssertUtil; +import cn.axzo.nanopart.doc.wps.support.WpsSupport; import cn.axzo.oss.http.model.ApiSignUrlDownloadRequest; import cn.axzo.oss.http.model.ApiSignUrlDownloadResponse; import cn.axzo.oss.http.model.file.UpdateFileInfoRequest; @@ -43,13 +46,14 @@ public class WpsBaseManager { private final DocUserProfileGateway docUserProfileGateway; private final DocPermissionProps docPermissionProps; + + private final WpsSupport wpsSupport; /** * 获取文件基础信息 * @param docCode 文件编码 */ public WpsFetchFileResponse fetchFileBase(String docCode) { - IndexNode node = indexNodeDao.findOrNull(docCode); - + IndexNode node = wpsSupport.findAndCheckByCode(docCode); return WpsFetchFileResponse.builder() .docCode(docCode) .name(node.getFullFileName()) @@ -67,7 +71,7 @@ public class WpsBaseManager { * @param docCode 文件编码 */ public WpsFetchDownloadResponse fetchDownload(String docCode) { - IndexNode node = indexNodeDao.findOrNull(docCode); + IndexNode node = wpsSupport.findAndCheckByCode(docCode); return WpsFetchDownloadResponse.builder() .url(this.downloadUrl(node.getAttributes().getFileAttributes().getOssFileKey())) .digest("") @@ -85,8 +89,11 @@ public class WpsBaseManager { } ApiSignUrlDownloadRequest request = new ApiSignUrlDownloadRequest(); request.setFileKeys(Lists.newArrayList(fileKey)); - List apiSignUrlDownloadResponses = docOssGateway.signUrlFetchDownload(request); - return apiSignUrlDownloadResponses.get(0).getSignUrl(); + List responseList = docOssGateway.signUrlFetchDownload(request); + + WpsAssertUtil.isFalse(CollectionUtil.isEmpty(responseList) || StringUtils.isBlank(responseList.get(0).getSignUrl()), WpsErrorCodeEnum.UPLOAD_ERROR); + + return responseList.get(0).getSignUrl(); } /** @@ -113,14 +120,11 @@ public class WpsBaseManager { * 用户信息 */ public WpsUsersResponse users(WpsUsersRequest request) { - AssertUtil.isFalse(Objects.isNull(request) || CollectionUtil.isEmpty(request.getPersonIds()), "入参错误"); - + WpsAssertUtil.isFalse(Objects.isNull(request) || CollectionUtil.isEmpty(request.getPersonIds()), WpsErrorCodeEnum.REQUEST_PARAMETER_ERROR); //查询人员档案 List personProfiles = this.docUserProfileGateway.personProfileByPersonIds(request.getPersonIds().stream().map(Long::parseLong).collect(Collectors.toList())); + WpsAssertUtil.isFalse(CollectionUtil.isEmpty(personProfiles), WpsErrorCodeEnum.USER_NOT_EXIST); - if (CollectionUtil.isEmpty(personProfiles)) { - return WpsUsersResponse.builder().build(); - } return WpsUsersResponse.builder() .users(personProfiles.stream() .map(item -> WpsUsersResponse.WpsUser.builder() @@ -135,7 +139,7 @@ public class WpsBaseManager { */ public WpsRenameResponse rename(WpsRenameRequest request) { AssertUtil.isFalse(Objects.isNull(request) || StringUtils.isEmpty(request.getDocCode()) || StringUtils.isEmpty(request.getName()), "参数错误"); - IndexNode node = indexNodeDao.findOrNull(request.getDocCode()); + IndexNode node = wpsSupport.findAndCheckByCode(request.getDocCode()); if (Objects.isNull(node) || Objects.isNull(node.getAttributes()) || Objects.isNull(node.getAttributes().getFileAttributes()) diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/wpsedit/WpsEditManager.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/wpsedit/WpsEditManager.java index 990c0c23..bd2b28a7 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/wpsedit/WpsEditManager.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/wpsedit/WpsEditManager.java @@ -4,6 +4,9 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; +import cn.axzo.nanopart.doc.api.domain.FileAttributes; +import cn.axzo.nanopart.doc.api.util.Constants; +import cn.axzo.nanopart.doc.wps.support.WpsSupport; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Component; @@ -46,6 +49,7 @@ public class WpsEditManager { private final DocOssGateway docOssGateway; private final FileBroadcaster fileBroadcaster; private final DocProps docProps; + private final WpsSupport wpsSupport; /** * 文档编辑 @@ -54,7 +58,7 @@ public class WpsEditManager { * */ public WpsEditUploadPrepareResponse uploadPrepare(WpsEditUploadPrepareRequest request) { - return WpsEditUploadPrepareResponse.builder().digestTypes(new String[]{"sha1"}).build(); + return WpsEditUploadPrepareResponse.builder().digestTypes(new String[]{Constants.WPS_UPLOAD_PREPARE_SHA1}).build(); } /** @@ -64,7 +68,7 @@ public class WpsEditManager { * 此外,回调中也会带上本次保存的一些额外信息,如文档大小,手动/自动保存等。 */ public WpsEditUploadAddressResponse uploadAddress(WpsEditUploadAddressRequest request) { - IndexNode node = indexNodeDao.findOrNull(request.getDocCode()); + IndexNode node = wpsSupport.findAndCheckByCode(request.getDocCode()); String fileKey = StringUtils.EMPTY; if (Objects.nonNull(node) @@ -81,11 +85,9 @@ public class WpsEditManager { .fileKey(fileKey) .build()); - - return WpsEditUploadAddressResponse.builder() .url(response.getSignUrl()) - .method("PUT") //上传文档的 HTTP Method,(WPS)暂只支持 PUT,文件实体将在 Body 传递 + .method(Constants.WPS_UPLOAD_ADDRESS_PUT) //上传文档的 HTTP Method,(WPS)暂只支持 PUT,文件实体将在 Body 传递 .headers(this.buildUploadAddressHost(response))//构建请求上传地址的header信息 .params(null) .sendBackParams(null) @@ -97,8 +99,8 @@ public class WpsEditManager { */ private Map buildUploadAddressHost(ApiSignUrlUploadResponse response) { Map header = new HashMap<>(); - header.put("Content-Type", "multipart/form-data"); - header.put("Host", response.getHost()); + header.put(Constants.WPS_UPLOAD_ADDRESS_CONTENT_TYPE, Constants.WPS_UPLOAD_ADDRESS_FORM_DATA); + header.put(Constants.WPS_UPLOAD_ADDRESS_HOST, response.getHost()); return header; } @@ -111,7 +113,7 @@ public class WpsEditManager { public WpsEditUploadCompleteResponse uploadComplete(WpsEditUploadCompleteRequest request) { log.info("wpsEditManager-uploadComplete-params,request:{}", request); //加锁 - IndexNode node = indexNodeDao.getForUpdateOrThrow(request.getDocCode()); + IndexNode node = wpsSupport.findAndCheckForUpdateByCode(request.getDocCode()); //当上传完成后,更新文件基础信息 this.updateIndexNodeWhenUploadComplete(node, request); diff --git a/nanopart-server/src/main/java/cn/axzo/nanopart/config/exception/ExceptionAdviceHandler.java b/nanopart-server/src/main/java/cn/axzo/nanopart/config/exception/ExceptionAdviceHandler.java index b24e462e..3ca5417f 100644 --- a/nanopart-server/src/main/java/cn/axzo/nanopart/config/exception/ExceptionAdviceHandler.java +++ b/nanopart-server/src/main/java/cn/axzo/nanopart/config/exception/ExceptionAdviceHandler.java @@ -1,6 +1,7 @@ package cn.axzo.nanopart.config.exception; import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.nanopart.doc.wps.support.WpsException; import cn.axzo.pokonyan.exception.BusinessException; import cn.axzo.workflow.common.exception.WorkflowEngineException; import lombok.extern.slf4j.Slf4j; @@ -71,5 +72,10 @@ public class ExceptionAdviceHandler { log.warn("业务异常", e); return ApiResult.err(e.getMessage()); } + @ExceptionHandler(WpsException.class) + public ApiResult wpsExceptionHandler(WpsException e) { + log.warn("wps业务异常", e); + return ApiResult.err(e.getErrorCode(), e.getErrorMessage()); + } }