Merge remote-tracking branch 'origin/feature/REQ-3540' into feature/REQ-3540

This commit is contained in:
yanglin 2025-03-11 18:13:23 +08:00
commit 278e848224
20 changed files with 872 additions and 14 deletions

View File

@ -40,6 +40,10 @@
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.framework</groupId>
<artifactId>axzo-common-domain</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,14 +0,0 @@
package cn.axzo.nanopart.doc.api.wps;
import org.springframework.cloud.openfeign.FeignClient;
/**
* @author xudawei
* @date 2025/03/07
* @desc wps对接
*/
@FeignClient(name = "nanopart", url = "${axzo.service.nanopart:http://nanopart:8080}")
public interface WpsApi {
}

View File

@ -0,0 +1,59 @@
package cn.axzo.nanopart.doc.api.wps;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.nanopart.doc.api.wps.request.WpsFetchDownloadRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsFetchFileRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsPermissionRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsUsersRequest;
import cn.axzo.nanopart.doc.api.wps.response.WpsFetchDownloadResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsFetchFileResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsPermissionResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsUsersResp;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* @author xudawei
* @date 2025/03/07
* @desc wps对接
*/
@FeignClient(name = "nanopart", url = "${axzo.service.nanopart:http://nanopart:8080}")
public interface WpsBaseApi {
/**
* 获取文件信息
* 本节介绍文档预览相关的接口接入方必须全部实现才能正常打开并预览文档
*
*/
@PostMapping(value = "/v3/3rd/fetchFile")
ApiResult<WpsFetchFileResp> fetchFile(@Validated @RequestBody WpsFetchFileRequest request);
/**
* 获取文件下载地址
* 说明在线协同系统需要下载文件原件以提供协同服务该接口需要返回指定文件 ID 所对应的下载地址
*
*/
@PostMapping(value = "/v3/3rd/fetchDownload")
ApiResult<WpsFetchDownloadResp> fetchDownload(@Validated @RequestBody WpsFetchDownloadRequest request);
/**
* 文档用户权限
* 说明任何需要用户鉴权的行为都会触发该接口的调用并且 WebOffice 会根据指定的权限位来限定特定的操作
* download 指定该用户是否具有下载文档权限 此接口用于标识用户具备哪些操作权限具体的功能支持还需您的服务实现相关回调
*
*/
@PostMapping(value = "/v3/3rd/permission")
ApiResult<WpsPermissionResp> permission(@Validated @RequestBody WpsPermissionRequest request);
/**
* 用户信息
* 该组接口用于获取协同场景下的用户信息如查看历史改动在线协同用户头像等
*
*/
@PostMapping(value = "/v3/3rd/users")
ApiResult<WpsUsersResp> users(@Validated @RequestBody WpsUsersRequest request);
}

View File

@ -0,0 +1,59 @@
package cn.axzo.nanopart.doc.api.wps;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.nanopart.doc.api.wps.request.WpsEditUploadAddressRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsEditUploadCompleteRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsEditUploadPrepareRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsFetchDownloadRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsFetchFileRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsPermissionRequest;
import cn.axzo.nanopart.doc.api.wps.response.WpsEditUploadAddressResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsEditUploadCompleteResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsEditUploadPrepareResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsFetchDownloadResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsFetchFileResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsPermissionResp;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* @author xudawei
* @date 2025/03/07
* @desc wps对接
*/
@FeignClient(name = "nanopart", url = "${axzo.service.nanopart:http://nanopart:8080}")
public interface WpsEditApi {
/**
* 文档编辑
* 三阶段保存三阶段保存在对接协议上较为复杂但是对于一些较为复杂的系统如多数据中心就近接入等
* 三阶段的实现反而能较为灵活的满足接入方需求
*
* 1 准备上传阶段
* 说明三阶段保存的第一步主要用于 WebOffice 与接入方进行参数协商目前主要协商摘要算法
*
*/
@PostMapping(value = "/v3/3rd/files/upload/prepare")
ApiResult<WpsEditUploadPrepareResp> uploadPrepare(@Validated @RequestBody WpsEditUploadPrepareRequest request);
/**
* 文档编辑
* 2 获取上传地址
* 说明三阶段保存第二步主要用于获取上传地址WebOffice 将上传保存后的文档到该地址
* 此外回调中也会带上本次保存的一些额外信息如文档大小手动/自动保存等
*/
@PostMapping(value = "/v3/3rd/files/upload/address")
ApiResult<WpsEditUploadAddressResp> uploadAddress(@Validated @RequestBody WpsEditUploadAddressRequest request);
/**
* 文档编辑
* 3 上传完成后回调通知上传结果
* 说明WebOffice 在将新版本文件上传到指定地址后将会回调通知接入方
*/
@PostMapping(value = "/v3/3rd/files/upload/complete")
ApiResult<WpsEditUploadCompleteResp> uploadComplete(@Validated @RequestBody WpsEditUploadCompleteRequest request);
}

View File

@ -0,0 +1,60 @@
package cn.axzo.nanopart.doc.api.wps.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 获取上传地址
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsEditUploadAddressRequest {
/**
* 文档编码
*/
private String docCode;
/**
* 文档名称
*/
private String name;
/**
* 文档大小单位 byte
*/
private Integer size;
/**
* 文档校验和key 为算法value 为结果值
*/
private Map<String, String> digest;
/**
* 是否手动保存即用户手动 ctrl/cmd + s 或点击保存版本触发的保存区别于定时触发的自动保存
*/
private Boolean isManual;
/**
* 文档内包含的附件的大小单位 byte
*/
private Integer attachmentSize;
/**
* 文档的 MIME 类型
*/
private String contentType;
}

View File

@ -0,0 +1,84 @@
package cn.axzo.nanopart.doc.api.wps.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 获取文件请求
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsEditUploadCompleteRequest {
/**
* 文档编码
*/
private String docCode;
/**
* 获取上传地址时相同的请求
*/
private Object request;
/**
* 文档名称
*/
private String name;
/**
* 文档大小单位 byte
*/
private Integer size;
/**
* 文档校验和key 为算法value 为结果值
*/
private Map<String, String> digest;
/**
* 是否手动保存即用户手动 ctrl/cmd + s 或点击保存版本触发的保存区别于定时触发的自动保存
*/
private Boolean isManual;
/**
* 文档内包含的附件的大小单位 byte
*/
private Integer attachmentSize;
/**
* 文档的 MIME 类型
*/
private String contentType;
/**
* 上传文档完成后存储服务返回的 HTTP Response
*/
private Object response;
/**
* 上传文档时存储服务返回的 HTTP Response Status
*/
private Integer statusCode;
/**
* 上传文档时存储服务返回的 HTTP Response Header
*/
private Map<String, String> headers;
/**
* 上传文档时存储服务返回的 HTTP Response Body base64 编码
*/
private Byte[] body;
/**
* 获取上传地址时要求原样带回的额外参数
*/
private Map<String, String> sendBackParams;
}

View File

@ -0,0 +1,25 @@
package cn.axzo.nanopart.doc.api.wps.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 获取文件请求
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsEditUploadPrepareRequest {
/**
* 文档编码
*/
private String docCode;
}

View File

@ -0,0 +1,26 @@
package cn.axzo.nanopart.doc.api.wps.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 获取文件下载地址
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsFetchDownloadRequest {
/**
* 文档编码
*/
private String docCode;
}

View File

@ -0,0 +1,25 @@
package cn.axzo.nanopart.doc.api.wps.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 获取文件请求
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsFetchFileRequest {
/**
* 文档编码
*/
private String docCode;
}

View File

@ -0,0 +1,25 @@
package cn.axzo.nanopart.doc.api.wps.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 获取文件请求
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsPermissionRequest {
/**
* 文档编码
*/
private String docCode;
}

View File

@ -0,0 +1,27 @@
package cn.axzo.nanopart.doc.api.wps.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 获取文件请求
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsUsersRequest {
/**
* 用户Id集合
*/
private List<String> userIds;
}

View File

@ -0,0 +1,48 @@
package cn.axzo.nanopart.doc.api.wps.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 文档用户权限
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsEditUploadAddressResp {
/**
* 上传文档的 URL
*/
private String url;
/**
* 上传文档的 HTTP Method暂只支持 PUT文件实体将在 Body 传递
*/
private String method;
/**
* 上传文档时需要携带的额外请求头
*/
private Map<String, String> headers;
/**
* 上传文档时需要携带的额外参数PUT 方式下在 Query 传递
*/
private Map<String, String> params;
/**
* 上传文档后请求完成上传接口需要原样带回的额外参数
*/
private Map<String, String> sendBackParams;
}

View File

@ -0,0 +1,59 @@
package cn.axzo.nanopart.doc.api.wps.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 文档用户权限
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsEditUploadCompleteResp {
/**
* 文档编码
*/
private String docCode;
/**
* 文档名称
*/
private String name;
/**
* 文档版本号 1 开始每次保存后递增
*/
private Integer version;
/**
* 文档大小单位 byte
*/
private Integer size;
/**
* 文档创建时间戳单位纪元秒
*/
private Long createTime;
/**
* 文档最后修改时间戳单位纪元秒
*/
private Long modifyTime;
/**
* 文档创建者 Id
*/
private String creatorId;
/**
* 文档最后修改者 Id
*/
private String modifierId;
}

View File

@ -0,0 +1,24 @@
package cn.axzo.nanopart.doc.api.wps.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 文档用户权限
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsEditUploadPrepareResp {
/**
* 文档校验和算法 md5 sha1 sha256
*/
private String[] digestTypes;
}

View File

@ -0,0 +1,41 @@
package cn.axzo.nanopart.doc.api.wps.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 获取文件下载地址
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsFetchDownloadResp {
/**
* 文档下载地址该地址需确保外网可访问且排除访问时防火墙的限制
*/
private String url;
/**
* 文档校验和 (checksum)
*/
private String digest;
/**
* 文档校验和算法 md5 或者 sha1
*/
private String digestType;
/**
* 请求文档下载地址所需要的额外请求头例如某些云存储商会要求额外的签名头等
*/
private Map<String, String> headers;
}

View File

@ -0,0 +1,61 @@
package cn.axzo.nanopart.doc.api.wps.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 获取文件请求
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsFetchFileResp {
/**
* 文档编码
*/
private String docCode;
/**
* 文档名称最大长度 240不能包含下列特殊字符\/|":*?<>
*/
private String name;
/**
* 文档版本号无符号 int32
* 1 开始每次保存后递增如果已经迭代了多个版本这里您需要返回最新的版本号
*/
private Integer version;
/**
* 文档创建时间戳单位纪元秒
*/
private Integer size;
/**
* 文档创建时间戳单位纪元秒
*/
private Long createAt;
/**
* 文档最后修改时间戳单位纪元秒
*/
private Long updateAt;
/**
* 文档创建者 Id
*/
private String creatorId;
/**
* 文档最后修改者 Id
*/
private String modifierId;
}

View File

@ -0,0 +1,69 @@
package cn.axzo.nanopart.doc.api.wps.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 文档用户权限
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsPermissionResp {
/**
* 当前用户 Id update=1print=1时必须返回当前用户的 user_id
*/
private String personId;
/**
* 是否具有预览权限0- 1-
*/
private Integer read;
/**
* 是否具有编辑权限0- 1-
*/
private Integer update;
/**
* 是否具有下载文档权限0- 1-
*/
private Integer download;
/**
* 是否具有重命名文档权限0- 1-
*/
private Integer rename;
/**
* 是否具有查看文档历史记录权限0- 1-
*/
private Integer history;
/**
* 是否具有拷贝文档内容权限0- 1-
*/
private Integer copy;
/**
* 是否具有打印文档权限0- 1-
*/
private Integer print;
/**
* 是否具有另存当前文档权限0- 1-该属性现阶段暂无相关入口开发者可不用关注
*/
private Integer saveas;
/**
* 是否具有评论文档权限0- 1-
*/
private Integer comment;
}

View File

@ -0,0 +1,34 @@
package cn.axzo.nanopart.doc.api.wps.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author xudawei@axzo.cn
* @date 2025/3/11
* @description 文档用户权限
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WpsUsersResp {
/**
* 当前用户 ID
*/
private String personId;
/**
* 用户昵称
*/
private String name;
/**
* 用户头像 URL需要是https链接
*/
private String avatarUrl;
}

View File

@ -0,0 +1,71 @@
package cn.axzo.nanopart.doc.wps;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.nanopart.doc.api.wps.WpsBaseApi;
import cn.axzo.nanopart.doc.api.wps.request.WpsFetchDownloadRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsFetchFileRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsPermissionRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsUsersRequest;
import cn.axzo.nanopart.doc.api.wps.response.WpsFetchDownloadResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsFetchFileResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsPermissionResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsUsersResp;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author xudawei
* @date 2025/03/11
* @desc wps对接服务
*/
@Slf4j
@RestController
@RequiredArgsConstructor
public class WpsBaseController implements WpsBaseApi {
/**
* 获取文件信息
* <p> 公有云wps回调接口
*
*/
@Override
public ApiResult<WpsFetchFileResp> fetchFile(@Validated @RequestBody WpsFetchFileRequest request) {
return ApiResult.ok();
}
/**
* 获取文件下载地址
* 说明在线协同系统需要下载文件原件以提供协同服务该接口需要返回指定文件 ID 所对应的下载地址
*
*/
@Override
public ApiResult<WpsFetchDownloadResp> fetchDownload(@Validated @RequestBody WpsFetchDownloadRequest request) {
return ApiResult.ok();
}
/**
* 文档用户权限
* 说明任何需要用户鉴权的行为都会触发该接口的调用并且 WebOffice 会根据指定的权限位来限定特定的操作
* download 指定该用户是否具有下载文档权限 此接口用于标识用户具备哪些操作权限具体的功能支持还需您的服务实现相关回调
*
*/
@Override
public ApiResult<WpsPermissionResp> permission(@Validated @RequestBody WpsPermissionRequest request) {
return ApiResult.ok();
}
/**
* 用户信息
* 该组接口用于获取协同场景下的用户信息如查看历史改动在线协同用户头像等
*
*/
@Override
public ApiResult<WpsUsersResp> users(@Validated @RequestBody WpsUsersRequest request) {
return ApiResult.ok();
}
}

View File

@ -0,0 +1,71 @@
package cn.axzo.nanopart.doc.wps;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.nanopart.doc.api.wps.WpsBaseApi;
import cn.axzo.nanopart.doc.api.wps.WpsEditApi;
import cn.axzo.nanopart.doc.api.wps.request.WpsEditUploadAddressRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsEditUploadCompleteRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsEditUploadPrepareRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsFetchDownloadRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsFetchFileRequest;
import cn.axzo.nanopart.doc.api.wps.request.WpsPermissionRequest;
import cn.axzo.nanopart.doc.api.wps.response.WpsEditUploadAddressResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsEditUploadCompleteResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsEditUploadPrepareResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsFetchDownloadResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsFetchFileResp;
import cn.axzo.nanopart.doc.api.wps.response.WpsPermissionResp;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author xudawei
* @date 2025/03/11
* @desc wps对接服务
* 文档编辑
* 三阶段保存三阶段保存在对接协议上较为复杂但是对于一些较为复杂的系统如多数据中心就近接入等
* 三阶段的实现反而能较为灵活的满足接入方需求
*/
@Slf4j
@RestController
@RequiredArgsConstructor
public class WpsEditController implements WpsEditApi {
/**
* 文档编辑
* 1 准备上传阶段
* 说明三阶段保存的第一步主要用于 WebOffice 与接入方进行参数协商目前主要协商摘要算法
*
*/
@Override
public ApiResult<WpsEditUploadPrepareResp> uploadPrepare(@Validated @RequestBody WpsEditUploadPrepareRequest request) {
return ApiResult.ok();
}
/**
* 文档编辑
* 2 获取上传地址
* 说明三阶段保存第二步主要用于获取上传地址WebOffice 将上传保存后的文档到该地址
* 此外回调中也会带上本次保存的一些额外信息如文档大小手动/自动保存等
*/
@Override
public ApiResult<WpsEditUploadAddressResp> uploadAddress(@Validated @RequestBody WpsEditUploadAddressRequest request) {
return ApiResult.ok();
}
/**
* 文档编辑
* 3 上传完成后回调通知上传结果
* 说明WebOffice 在将新版本文件上传到指定地址后将会回调通知接入方
*/
@Override
public ApiResult<WpsEditUploadCompleteResp> uploadComplete(@Validated @RequestBody WpsEditUploadCompleteRequest request) {
return ApiResult.ok();
}
}