Compare commits
81 Commits
44b57eb461
...
65d879acb4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65d879acb4 | ||
|
|
5039cd9375 | ||
|
|
65970b5107 | ||
|
|
c33deb72eb | ||
|
|
7a4f05aca4 | ||
|
|
fd7d79b260 | ||
|
|
5b49d57da9 | ||
|
|
e25bda3fa2 | ||
|
|
6ca353c221 | ||
|
|
3cf2f063d0 | ||
|
|
3e673fbad4 | ||
|
|
e9c6b561fe | ||
|
|
d2a2857625 | ||
|
|
d368c706f7 | ||
|
|
7dbfd68a30 | ||
|
|
e06aecc51d | ||
|
|
a44c0f533e | ||
|
|
c079f6767a | ||
|
|
d4e4c138be | ||
|
|
d7dc42a8f9 | ||
|
|
a5a1319316 | ||
|
|
ef4cfaf2ac | ||
|
|
59a645c71a | ||
|
|
3dd5791854 | ||
|
|
7afce22389 | ||
|
|
38504f73aa | ||
|
|
63c42907b7 | ||
|
|
df28fb582d | ||
|
|
9997b11f51 | ||
|
|
9fbed2eaf4 | ||
|
|
6bc47ae13d | ||
|
|
2495f31a7a | ||
|
|
5c16e55f6a | ||
|
|
f0335657ba | ||
|
|
aa6b0d537d | ||
|
|
01e8ee15bf | ||
|
|
97446ffb8e | ||
|
|
6ff07072b9 | ||
|
|
88c3a22c20 | ||
|
|
c8995af6d0 | ||
|
|
8f1ae5aba2 | ||
|
|
8efeef9431 | ||
|
|
8ce7fda35f | ||
|
|
942883652f | ||
|
|
5aa151981e | ||
|
|
092215037e | ||
|
|
df62fa31cf | ||
|
|
ee1413586d | ||
|
|
126032175f | ||
|
|
d0288e5757 | ||
|
|
7a00e9173f | ||
|
|
736cb827f7 | ||
|
|
04db71f324 | ||
|
|
483e23ecf4 | ||
|
|
cb56ef42b2 | ||
|
|
eafa5e9626 | ||
|
|
a7e4c9c6f5 | ||
|
|
9584032c23 | ||
|
|
1e29852d96 | ||
|
|
1cba0eebfc | ||
|
|
8d79eca184 | ||
|
|
938ab42353 | ||
|
|
df64dcb265 | ||
|
|
5e9cd3a7ed | ||
|
|
2422e2bc43 | ||
|
|
4268e158ef | ||
|
|
7a41675862 | ||
|
|
33b8004b05 | ||
|
|
29b41bbc85 | ||
|
|
729d04866a | ||
|
|
f08f754f71 | ||
|
|
ebef16b5c2 | ||
|
|
ff7f093d68 | ||
|
|
f94c1fa81b | ||
|
|
da6f66e10a | ||
|
|
9fb6aa82e9 | ||
| cf5b11d61c | |||
| 45aa2b9515 | |||
| 2e0d4ef253 | |||
| c5e23cc7cd | |||
| 6913a23b25 |
@ -3,6 +3,8 @@ package cn.axzo.nanopart.doc.api.anonymous;
|
|||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
import cn.axzo.nanopart.doc.api.domain.IndexNodeInfo;
|
||||||
|
import cn.axzo.nanopart.doc.api.index.request.BatchGetNodeInfoRequest;
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
@ -10,9 +12,15 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||||||
import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousCreateDirRequest;
|
import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousCreateDirRequest;
|
||||||
import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousCreateFileRequest;
|
import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousCreateFileRequest;
|
||||||
import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousUploadFileRequest;
|
import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousUploadFileRequest;
|
||||||
|
import cn.axzo.nanopart.doc.api.domain.IndexNodeInfo;
|
||||||
import cn.axzo.nanopart.doc.api.index.request.CopyNodeRequest;
|
import cn.axzo.nanopart.doc.api.index.request.CopyNodeRequest;
|
||||||
|
import cn.axzo.nanopart.doc.api.index.request.DeleteNodeRequest;
|
||||||
|
import cn.axzo.nanopart.doc.api.index.request.GetNodeInfoRequest;
|
||||||
|
import cn.axzo.nanopart.doc.api.index.request.RenameNodeRequest;
|
||||||
import cn.azxo.framework.common.model.CommonResponse;
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yanglin
|
* @author yanglin
|
||||||
*/
|
*/
|
||||||
@ -35,6 +43,14 @@ public interface DocAnonymousDatabaseApi {
|
|||||||
@PostMapping("/api/anonymous/createFile")
|
@PostMapping("/api/anonymous/createFile")
|
||||||
CommonResponse<String> createFile(@RequestBody @Valid AnonymousCreateFileRequest request);
|
CommonResponse<String> createFile(@RequestBody @Valid AnonymousCreateFileRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建新文件
|
||||||
|
*
|
||||||
|
* @return 文件编码, 需要由业务存储
|
||||||
|
*/
|
||||||
|
@PostMapping("/api/anonymous/createFile2")
|
||||||
|
CommonResponse<IndexNodeInfo> createFile2(@RequestBody @Valid AnonymousCreateFileRequest request);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传文件
|
* 上传文件
|
||||||
*
|
*
|
||||||
@ -43,6 +59,14 @@ public interface DocAnonymousDatabaseApi {
|
|||||||
@PostMapping("/api/anonymous/uploadFile")
|
@PostMapping("/api/anonymous/uploadFile")
|
||||||
CommonResponse<String> uploadFile(@RequestBody @Valid AnonymousUploadFileRequest request);
|
CommonResponse<String> uploadFile(@RequestBody @Valid AnonymousUploadFileRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
*
|
||||||
|
* @return 文件编码, 需要由业务存储
|
||||||
|
*/
|
||||||
|
@PostMapping("/api/anonymous/uploadFile2")
|
||||||
|
CommonResponse<IndexNodeInfo> uploadFile2(@RequestBody @Valid AnonymousUploadFileRequest request);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拷贝节点 (文件)
|
* 拷贝节点 (文件)
|
||||||
*
|
*
|
||||||
@ -51,4 +75,28 @@ public interface DocAnonymousDatabaseApi {
|
|||||||
@PostMapping("/api/anonymous/copy")
|
@PostMapping("/api/anonymous/copy")
|
||||||
CommonResponse<String> copy(@RequestBody @Valid CopyNodeRequest request);
|
CommonResponse<String> copy(@RequestBody @Valid CopyNodeRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除节点 (文件)
|
||||||
|
*/
|
||||||
|
@PostMapping("/api/anonymous/delete")
|
||||||
|
CommonResponse<Void> delete(@RequestBody @Valid DeleteNodeRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重命名节点 (文件)
|
||||||
|
*/
|
||||||
|
@PostMapping("/api/anonymous/rename")
|
||||||
|
CommonResponse<Void> rename(@RequestBody @Valid RenameNodeRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取节点信息
|
||||||
|
*/
|
||||||
|
@PostMapping("/api/anonymous/getNodeInfo")
|
||||||
|
CommonResponse<IndexNodeInfo> getNodeInfo(@RequestBody @Valid GetNodeInfoRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量获取节点信息集合
|
||||||
|
*/
|
||||||
|
@PostMapping("/api/anonymous/batchGetNodeInfo")
|
||||||
|
CommonResponse<Map<String, IndexNodeInfo>> batchGetNodeInfo(@RequestBody @Valid BatchGetNodeInfoRequest request);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,6 +38,7 @@ abstract class NodeCreateAnonymous implements NodeCreate, IndexNodeScope {
|
|||||||
/**
|
/**
|
||||||
* 业务编码
|
* 业务编码
|
||||||
*/
|
*/
|
||||||
|
@NotBlank(message = "bizCode不能为空")
|
||||||
private String bizCode;
|
private String bizCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -55,6 +55,11 @@ public class SearchNodeBizAttributesResponse {
|
|||||||
*/
|
*/
|
||||||
private Long createAtTime;
|
private Long createAtTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private String createAt;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(DrawMaterial o) {
|
public int compareTo(DrawMaterial o) {
|
||||||
Long first = this.getCreateAtTime();
|
Long first = this.getCreateAtTime();
|
||||||
@ -106,6 +111,11 @@ public class SearchNodeBizAttributesResponse {
|
|||||||
*/
|
*/
|
||||||
private Long createAtTime;
|
private Long createAtTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private String createAt;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(Content o) {
|
public int compareTo(Content o) {
|
||||||
Long first = this.getCreateAtTime();
|
Long first = this.getCreateAtTime();
|
||||||
|
|||||||
@ -89,6 +89,11 @@ public class IndexNodeInfo implements NodeValue, ValueContainer<IndexNodeInfo> {
|
|||||||
*/
|
*/
|
||||||
private String icon;
|
private String icon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件的大小(bytes), 只有文件才存这个字段
|
||||||
|
*/
|
||||||
|
private Integer size;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态. VALID: 有效的
|
* 状态. VALID: 有效的
|
||||||
*/
|
*/
|
||||||
@ -125,6 +130,10 @@ public class IndexNodeInfo implements NodeValue, ValueContainer<IndexNodeInfo> {
|
|||||||
|
|
||||||
private IndexNodeAttributes attributes;
|
private IndexNodeAttributes attributes;
|
||||||
|
|
||||||
|
private String ossFileKey;
|
||||||
|
|
||||||
|
private String ossFileUrl;
|
||||||
|
|
||||||
public Path path() {
|
public Path path() {
|
||||||
return Path.wrap(path);
|
return Path.wrap(path);
|
||||||
}
|
}
|
||||||
@ -145,6 +154,12 @@ public class IndexNodeInfo implements NodeValue, ValueContainer<IndexNodeInfo> {
|
|||||||
return fileTemplateNodeInfo;
|
return fileTemplateNodeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@JSONField(serialize = false, deserialize = false)
|
||||||
|
public FileAttributes getOrCreateFileAttributes() {
|
||||||
|
return getOrCreateAttributes().getOrCreateFileAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long id() {
|
public Long id() {
|
||||||
return id;
|
return id;
|
||||||
|
|||||||
@ -4,7 +4,6 @@ package cn.axzo.nanopart.doc.api.domain;
|
|||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
|
|
||||||
import cn.axzo.nanopart.doc.api.enums.FileFormat;
|
import cn.axzo.nanopart.doc.api.enums.FileFormat;
|
||||||
import cn.axzo.nanopart.doc.api.util.BizAssertions;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
@ -41,13 +40,6 @@ public class OssFile {
|
|||||||
return ossFile;
|
return ossFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validate() {
|
|
||||||
BizAssertions.assertNotNull(format, "format不能为空");
|
|
||||||
BizAssertions.assertTrue(size > 0, "size必须大于0");
|
|
||||||
BizAssertions.assertNotBlank(ossFileKey, "ossFileKey不能为空");
|
|
||||||
BizAssertions.assertNotBlank(extension, "后缀不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return JSON.toJSONString(this);
|
return JSON.toJSONString(this);
|
||||||
|
|||||||
@ -26,6 +26,10 @@ public enum DatabaseScope {
|
|||||||
private final Boolean childNameDuplicatable;
|
private final Boolean childNameDuplicatable;
|
||||||
private final Boolean limitChildrenCount;
|
private final Boolean limitChildrenCount;
|
||||||
|
|
||||||
|
public boolean isFeeAware() {
|
||||||
|
return databaseType != DatabaseType.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getWorkspaceType() {
|
public Integer getWorkspaceType() {
|
||||||
if (this == ENT_DATABASE)
|
if (this == ENT_DATABASE)
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@ -17,7 +17,7 @@ public enum FileFormat {
|
|||||||
EXCEL(true, "Excel", "xlsx"),
|
EXCEL(true, "Excel", "xlsx"),
|
||||||
WORD(true, "Word", "docx"),
|
WORD(true, "Word", "docx"),
|
||||||
PDF(false, "PDF", "pdf"),
|
PDF(false, "PDF", "pdf"),
|
||||||
PPT(false, "PPT", "pptx");
|
PPT(true, "PPT", "pptx");
|
||||||
|
|
||||||
private final boolean creatable;
|
private final boolean creatable;
|
||||||
private final String readableName;
|
private final String readableName;
|
||||||
|
|||||||
@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
package cn.axzo.nanopart.doc.api.enums;
|
||||||
|
|
||||||
|
import cn.axzo.nanopart.doc.api.wps.response.WpsPermissionResponse;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author xudawei
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Accessors(fluent = true)
|
||||||
|
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public enum WpsPermissionStatusEnum {
|
||||||
|
|
||||||
|
EDIT("edit", "编辑"),
|
||||||
|
PREVIEW("preview", "预览"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static final Map<String, WpsPermissionStatusEnum> map = Stream.of(WpsPermissionStatusEnum.values()).collect(Collectors.toMap(key -> key.code, key -> key));
|
||||||
|
|
||||||
|
|
||||||
|
public static WpsPermissionStatusEnum getByCode(String code) {
|
||||||
|
return map.get(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
WpsPermissionStatusEnum preview = WpsPermissionStatusEnum.getByCode("preview");
|
||||||
|
System.out.println("preview = " + preview);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预览
|
||||||
|
* @param personId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static WpsPermissionResponse preview(String personId) {
|
||||||
|
return WpsPermissionResponse.builder()
|
||||||
|
.personId(personId)
|
||||||
|
.read(1)
|
||||||
|
.update(0)
|
||||||
|
.download(0)
|
||||||
|
.rename(0)
|
||||||
|
.history(0)
|
||||||
|
.copy(1)
|
||||||
|
.print(0)
|
||||||
|
.saveas(0)
|
||||||
|
.comment(0)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*/
|
||||||
|
public static WpsPermissionResponse edit(String personId) {
|
||||||
|
return WpsPermissionResponse.builder()
|
||||||
|
.personId(personId)
|
||||||
|
.read(1)
|
||||||
|
.update(1)
|
||||||
|
.download(0)
|
||||||
|
.rename(0)
|
||||||
|
.history(0)
|
||||||
|
.copy(1)
|
||||||
|
.print(0)
|
||||||
|
.saveas(0)
|
||||||
|
.comment(0)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package cn.axzo.nanopart.doc.api.file;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
import cn.axzo.nanopart.doc.api.domain.IndexNodeInfo;
|
||||||
|
import cn.axzo.nanopart.doc.api.index.request.GetNodeInfoRequest;
|
||||||
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yanglin
|
||||||
|
*/
|
||||||
|
@FeignClient(name = "nanopart", url = "${axzo.service.nanopart:http://nanopart:8080}")
|
||||||
|
public interface IndexNodeApi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取节点信息
|
||||||
|
*/
|
||||||
|
@PostMapping("/api/indexNode/getNodeInfo")
|
||||||
|
CommonResponse<IndexNodeInfo> getNodeInfo(@RequestBody @Valid GetNodeInfoRequest request);
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,9 +1,11 @@
|
|||||||
|
|
||||||
package cn.axzo.nanopart.doc.api.filedb.response;
|
package cn.axzo.nanopart.doc.api.filedb.response;
|
||||||
|
|
||||||
import cn.axzo.nanopart.doc.api.enums.DatabaseType;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
|
|
||||||
|
import cn.axzo.nanopart.doc.api.enums.DatabaseType;
|
||||||
import cn.axzo.nanopart.doc.api.enums.FileDatabaseState;
|
import cn.axzo.nanopart.doc.api.enums.FileDatabaseState;
|
||||||
import cn.axzo.nanopart.doc.api.templatedb.domain.TemplateDatabaseInfo;
|
import cn.axzo.nanopart.doc.api.templatedb.domain.TemplateDatabaseInfo;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -79,7 +81,7 @@ public class FileDatabaseInfoResponse {
|
|||||||
/**
|
/**
|
||||||
* 已使用的容量, 单位GB
|
* 已使用的容量, 单位GB
|
||||||
*/
|
*/
|
||||||
private Integer usedCapacity;
|
private BigDecimal usedCapacity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 资料库信息
|
* 资料库信息
|
||||||
|
|||||||
@ -0,0 +1,32 @@
|
|||||||
|
package cn.axzo.nanopart.doc.api.index.request;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author xudawei@axzo.cn
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class BatchGetNodeInfoRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点编码集合
|
||||||
|
*/
|
||||||
|
@NotEmpty(message = "节点编码集合不能为空")
|
||||||
|
private List<String> codes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否需要fileUrl,true:需要,false:不需要
|
||||||
|
* 默认false
|
||||||
|
*/
|
||||||
|
private Boolean needFileUrl = false;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package cn.axzo.nanopart.doc.api.index.request;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yanglin
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class GetNodeInfoRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点编码
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "节点编码不能为空")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
}
|
||||||
@ -33,4 +33,19 @@ public class Constants {
|
|||||||
*/
|
*/
|
||||||
public static final String WPS_UPLOAD_PREPARE_SHA1 = "sha1";
|
public static final String WPS_UPLOAD_PREPARE_SHA1 = "sha1";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http开头
|
||||||
|
*/
|
||||||
|
public static final String WPS_HTTP_START = "http://";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https开头
|
||||||
|
*/
|
||||||
|
public static final String WPS_HTTPS_START = "https://";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wps默认用户Id
|
||||||
|
*/
|
||||||
|
public static final String WPS_DEFAULT_USER_ID = "0";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,4 +22,9 @@ public class WpsFetchFileRequest {
|
|||||||
*/
|
*/
|
||||||
private String docCode;
|
private String docCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户Id
|
||||||
|
*/
|
||||||
|
private String personId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
package cn.axzo.nanopart.doc.api.wps.request;
|
package cn.axzo.nanopart.doc.api.wps.request;
|
||||||
|
|
||||||
|
import cn.axzo.nanopart.doc.api.enums.WpsPermissionStatusEnum;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -27,4 +28,9 @@ public class WpsPermissionRequest {
|
|||||||
*/
|
*/
|
||||||
private String personId;
|
private String personId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限状态
|
||||||
|
*/
|
||||||
|
private WpsPermissionStatusEnum wpsPermissionStatus;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,22 +67,4 @@ public class WpsPermissionResponse {
|
|||||||
*/
|
*/
|
||||||
private Integer comment;
|
private Integer comment;
|
||||||
|
|
||||||
/**
|
|
||||||
* 预览文档权限
|
|
||||||
*/
|
|
||||||
public static WpsPermissionResponse preview(String personId) {
|
|
||||||
return WpsPermissionResponse.builder()
|
|
||||||
.personId(personId)
|
|
||||||
.read(1)
|
|
||||||
.update(0)
|
|
||||||
.download(0)
|
|
||||||
.rename(0)
|
|
||||||
.history(0)
|
|
||||||
.copy(0)
|
|
||||||
.print(0)
|
|
||||||
.saveas(0)
|
|
||||||
.comment(0)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
package cn.axzo.nanopart.doc.dao;
|
package cn.axzo.nanopart.doc.dao;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
@ -19,9 +20,10 @@ import cn.axzo.nanopart.doc.mapper.FileDatabaseMapper;
|
|||||||
@Repository
|
@Repository
|
||||||
public class FileDatabaseDao extends ServiceImpl<FileDatabaseMapper, FileDatabase> {
|
public class FileDatabaseDao extends ServiceImpl<FileDatabaseMapper, FileDatabase> {
|
||||||
|
|
||||||
public FileDatabase findForUpdateOrNull(DatabaseScope scope, String scopeUniqueCode) {
|
public FileDatabase findForUpdateOrNull(DatabaseScope scope, String templateDatabaseCode, String scopeUniqueCode) {
|
||||||
return lambdaQuery() //
|
return lambdaQuery() //
|
||||||
.eq(FileDatabase::getScope, scope) //
|
.eq(FileDatabase::getScope, scope) //
|
||||||
|
.eq(FileDatabase::getTemplateDatabaseCode, templateDatabaseCode) //
|
||||||
.eq(FileDatabase::getScopeUniqueCode, scopeUniqueCode) //
|
.eq(FileDatabase::getScopeUniqueCode, scopeUniqueCode) //
|
||||||
.last("FOR UPDATE") //
|
.last("FOR UPDATE") //
|
||||||
.one();
|
.one();
|
||||||
@ -61,10 +63,11 @@ public class FileDatabaseDao extends ServiceImpl<FileDatabaseMapper, FileDatabas
|
|||||||
.remove();
|
.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateUsedCapacity(String code, int usedFileSize) {
|
public void updateUsedCapacity(String code, int usedFileSizeKb, BigDecimal usedFileSizeGb) {
|
||||||
lambdaUpdate() //
|
lambdaUpdate() //
|
||||||
.eq(FileDatabase::getCode, code) //
|
.eq(FileDatabase::getCode, code) //
|
||||||
.set(FileDatabase::getUsedCapacity, usedFileSize) //
|
.set(FileDatabase::getUsedCapacity, usedFileSizeGb) //
|
||||||
|
.set(FileDatabase::getUsedCapacityKb, usedFileSizeKb) //
|
||||||
.update();
|
.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,4 +85,13 @@ public class FileDatabaseDao extends ServiceImpl<FileDatabaseMapper, FileDatabas
|
|||||||
.update();
|
.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void expire() {
|
||||||
|
lambdaUpdate() //
|
||||||
|
.eq(FileDatabase::getState, FileDatabaseState.ACTIVATED) //
|
||||||
|
.isNotNull(FileDatabase::getExpireDate)
|
||||||
|
.le(FileDatabase::getExpireDate, new Date()) //
|
||||||
|
.set(FileDatabase::getState, FileDatabaseState.EXPIRED)
|
||||||
|
.update();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
|
|
||||||
package cn.axzo.nanopart.doc.dao;
|
package cn.axzo.nanopart.doc.dao;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import cn.axzo.nanopart.doc.api.enums.DatabaseScope;
|
import cn.axzo.nanopart.doc.api.enums.DatabaseScope;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@ -14,6 +17,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||||||
|
|
||||||
import cn.axzo.nanopart.doc.api.domain.IndexNodeParentScope;
|
import cn.axzo.nanopart.doc.api.domain.IndexNodeParentScope;
|
||||||
import cn.axzo.nanopart.doc.api.domain.IndexNodeScope;
|
import cn.axzo.nanopart.doc.api.domain.IndexNodeScope;
|
||||||
|
import cn.axzo.nanopart.doc.api.enums.DatabaseScope;
|
||||||
import cn.axzo.nanopart.doc.api.enums.IndexNodeState;
|
import cn.axzo.nanopart.doc.api.enums.IndexNodeState;
|
||||||
import cn.axzo.nanopart.doc.api.enums.IndexNodeType;
|
import cn.axzo.nanopart.doc.api.enums.IndexNodeType;
|
||||||
import cn.axzo.nanopart.doc.api.util.BizAssertions;
|
import cn.axzo.nanopart.doc.api.util.BizAssertions;
|
||||||
@ -53,6 +57,15 @@ public class IndexNodeDao extends ServiceImpl<IndexNodeMapper, IndexNode> {
|
|||||||
.one();
|
.one();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<IndexNode> findByCodes(List<String> codes) {
|
||||||
|
if (CollectionUtils.isEmpty(codes)) {
|
||||||
|
return Lists.newArrayList();
|
||||||
|
}
|
||||||
|
return lambdaQuery() //
|
||||||
|
.in(IndexNode::getCode, codes) //
|
||||||
|
.list();
|
||||||
|
}
|
||||||
|
|
||||||
public void updatePath(String code, String path) {
|
public void updatePath(String code, String path) {
|
||||||
lambdaUpdate() //
|
lambdaUpdate() //
|
||||||
.eq(IndexNode::getCode, code) //
|
.eq(IndexNode::getCode, code) //
|
||||||
@ -92,10 +105,11 @@ public class IndexNodeDao extends ServiceImpl<IndexNodeMapper, IndexNode> {
|
|||||||
.update();
|
.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IndexNode> collectValidSubtreeNodes(IndexNode indexNode) {
|
public List<IndexNode> collectValidSubtreeNodes(IndexNode indexNode, IndexNodeType... nodeTypes) {
|
||||||
return lambdaQuery() //
|
return lambdaQuery() //
|
||||||
.likeRight(IndexNode::getPath, indexNode.getPath()) //
|
.likeRight(IndexNode::getPath, indexNode.getPath()) //
|
||||||
.eq(IndexNode::getState, IndexNodeState.VALID) //
|
.eq(IndexNode::getState, IndexNodeState.VALID) //
|
||||||
|
.in(nodeTypes.length > 0, IndexNode::getNodeType, Arrays.asList(nodeTypes)) //
|
||||||
.list();
|
.list();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package cn.axzo.nanopart.doc.dao;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import cn.axzo.nanopart.doc.api.util.BizAssertions;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@ -18,6 +19,12 @@ import cn.axzo.nanopart.doc.mapper.TemplateDatabaseMapper;
|
|||||||
@Repository
|
@Repository
|
||||||
public class TemplateDatabaseDao extends ServiceImpl<TemplateDatabaseMapper, TemplateDatabase> {
|
public class TemplateDatabaseDao extends ServiceImpl<TemplateDatabaseMapper, TemplateDatabase> {
|
||||||
|
|
||||||
|
public TemplateDatabase getOrThrow(String code) {
|
||||||
|
TemplateDatabase templateDb = findOrNull(code);
|
||||||
|
BizAssertions.assertNotNull(templateDb, "找不到资料库: {}", code);
|
||||||
|
return templateDb;
|
||||||
|
}
|
||||||
|
|
||||||
public TemplateDatabase findOrNull(String code) {
|
public TemplateDatabase findOrNull(String code) {
|
||||||
return lambdaQuery().eq(TemplateDatabase::getCode, code).one();
|
return lambdaQuery().eq(TemplateDatabase::getCode, code).one();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
package cn.axzo.nanopart.doc.entity;
|
package cn.axzo.nanopart.doc.entity;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
@ -76,7 +77,12 @@ public class FileDatabase extends BaseEntity<FileDatabase> implements IndexNodeS
|
|||||||
/**
|
/**
|
||||||
* 已使用的容量, 单位GB
|
* 已使用的容量, 单位GB
|
||||||
*/
|
*/
|
||||||
private Integer usedCapacity;
|
private BigDecimal usedCapacity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已使用的容量, 单位kb
|
||||||
|
*/
|
||||||
|
private Integer usedCapacityKb;
|
||||||
|
|
||||||
public boolean isActivated() {
|
public boolean isActivated() {
|
||||||
return state == FileDatabaseState.ACTIVATED;
|
return state == FileDatabaseState.ACTIVATED;
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
package cn.axzo.nanopart.doc.entity;
|
package cn.axzo.nanopart.doc.entity;
|
||||||
|
|
||||||
|
import cn.axzo.nanopart.doc.api.enums.FileFeeType;
|
||||||
|
import cn.axzo.nanopart.doc.api.enums.FileTemplateFeeType;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
@ -56,6 +58,10 @@ public class TemplateDatabase extends BaseEntity<TemplateDatabase> implements In
|
|||||||
@TableField(typeHandler = FastjsonTypeHandler.class)
|
@TableField(typeHandler = FastjsonTypeHandler.class)
|
||||||
private DatabaseAccessConfig accessConfig;
|
private DatabaseAccessConfig accessConfig;
|
||||||
|
|
||||||
|
public FileTemplateFeeType getFeeType() {
|
||||||
|
return feeConfig == null ? null : feeConfig.getFeeType();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String indexNodeCode() {
|
public String indexNodeCode() {
|
||||||
return code;
|
return code;
|
||||||
|
|||||||
@ -25,7 +25,6 @@ public class BizCodeGenerator {
|
|||||||
.append(create.nodeScope().scope() == DatabaseScope.ENT_DATABASE ? "ent" : "pro") //
|
.append(create.nodeScope().scope() == DatabaseScope.ENT_DATABASE ? "ent" : "pro") //
|
||||||
.append(nodeType == IndexNodeType.DATABASE ? "space" : "folder") //
|
.append(nodeType == IndexNodeType.DATABASE ? "space" : "folder") //
|
||||||
.append(create.nodeScope().context() == IndexNodeContext.TEMPLATE_DATABASE ? "oms" : workspaceId) //
|
.append(create.nodeScope().context() == IndexNodeContext.TEMPLATE_DATABASE ? "oms" : workspaceId) //
|
||||||
.append("") //
|
|
||||||
.build();
|
.build();
|
||||||
create.setBizCode(bizCode);
|
create.setBizCode(bizCode);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,35 @@
|
|||||||
|
|
||||||
package cn.axzo.nanopart.doc.file.anonymous;
|
package cn.axzo.nanopart.doc.file.anonymous;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import cn.axzo.nanopart.doc.api.domain.IndexNodeInfo;
|
||||||
|
import cn.axzo.nanopart.doc.api.index.request.BatchGetNodeInfoRequest;
|
||||||
|
import cn.axzo.nanopart.doc.integration.OssClient;
|
||||||
|
import cn.axzo.oss.http.model.ApiSignUrlDownloadResponse;
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import cn.axzo.basics.common.BeanMapper;
|
||||||
import cn.axzo.nanopart.doc.api.anonymous.DocAnonymousDatabaseApi;
|
import cn.axzo.nanopart.doc.api.anonymous.DocAnonymousDatabaseApi;
|
||||||
import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousCreateDirRequest;
|
import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousCreateDirRequest;
|
||||||
import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousCreateFileRequest;
|
import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousCreateFileRequest;
|
||||||
import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousUploadFileRequest;
|
import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousUploadFileRequest;
|
||||||
|
import cn.axzo.nanopart.doc.api.domain.IndexNodeInfo;
|
||||||
import cn.axzo.nanopart.doc.api.domain.OssFile;
|
import cn.axzo.nanopart.doc.api.domain.OssFile;
|
||||||
import cn.axzo.nanopart.doc.api.index.request.CopyNodeRequest;
|
import cn.axzo.nanopart.doc.api.index.request.CopyNodeRequest;
|
||||||
|
import cn.axzo.nanopart.doc.api.index.request.DeleteNodeRequest;
|
||||||
|
import cn.axzo.nanopart.doc.api.index.request.GetNodeInfoRequest;
|
||||||
|
import cn.axzo.nanopart.doc.api.index.request.RenameNodeRequest;
|
||||||
import cn.axzo.nanopart.doc.entity.IndexNode;
|
import cn.axzo.nanopart.doc.entity.IndexNode;
|
||||||
import cn.axzo.nanopart.doc.file.index.IndexManager;
|
import cn.axzo.nanopart.doc.file.index.IndexManager;
|
||||||
import cn.axzo.nanopart.doc.utils.AsyncUtils;
|
import cn.axzo.nanopart.doc.utils.AsyncUtils;
|
||||||
@ -28,6 +47,7 @@ public class DocAnonymousDatabaseApiController implements DocAnonymousDatabaseAp
|
|||||||
|
|
||||||
private final IndexManager indexManager;
|
private final IndexManager indexManager;
|
||||||
private final AsyncUtils asyncUtils;
|
private final AsyncUtils asyncUtils;
|
||||||
|
private final OssClient ossClient;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResponse<String> createDir(AnonymousCreateDirRequest request) {
|
public CommonResponse<String> createDir(AnonymousCreateDirRequest request) {
|
||||||
@ -42,13 +62,26 @@ public class DocAnonymousDatabaseApiController implements DocAnonymousDatabaseAp
|
|||||||
return CommonResponse.success(indexManager.createFile(request, ossFile).getCode());
|
return CommonResponse.success(indexManager.createFile(request, ossFile).getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<IndexNodeInfo> createFile2(AnonymousCreateFileRequest request) {
|
||||||
|
OssFile ossFile = indexManager.prepareEmptyOssFile(request, request.getFormat());
|
||||||
|
IndexNode fileNode = indexManager.createFile(request, ossFile);
|
||||||
|
return CommonResponse.success(BeanMapper.map(fileNode, IndexNodeInfo.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResponse<String> uploadFile(AnonymousUploadFileRequest request) {
|
public CommonResponse<String> uploadFile(AnonymousUploadFileRequest request) {
|
||||||
log.info("upload file request:{}", request);
|
log.info("upload file request:{}", request);
|
||||||
request.getOssFile().validate();
|
|
||||||
return CommonResponse.success(indexManager.uploadFile(request, request.getOssFile()).getCode());
|
return CommonResponse.success(indexManager.uploadFile(request, request.getOssFile()).getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<IndexNodeInfo> uploadFile2(AnonymousUploadFileRequest request) {
|
||||||
|
log.info("upload file2 request:{}", request);
|
||||||
|
IndexNode fileNode = indexManager.uploadFile(request, request.getOssFile());
|
||||||
|
return CommonResponse.success(BeanMapper.map(fileNode, IndexNodeInfo.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResponse<String> copy(CopyNodeRequest request) {
|
public CommonResponse<String> copy(CopyNodeRequest request) {
|
||||||
log.info("copy request:{}", request);
|
log.info("copy request:{}", request);
|
||||||
@ -56,4 +89,66 @@ public class DocAnonymousDatabaseApiController implements DocAnonymousDatabaseAp
|
|||||||
return CommonResponse.success(asyncUtils.getOrTimeout(future, 60, "克隆").getCode());
|
return CommonResponse.success(asyncUtils.getOrTimeout(future, 60, "克隆").getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> delete(DeleteNodeRequest request) {
|
||||||
|
log.info("delete request:{}", request);
|
||||||
|
indexManager.delete(request.getCode());
|
||||||
|
return CommonResponse.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Void> rename(RenameNodeRequest request) {
|
||||||
|
log.info("rename request:{}", request);
|
||||||
|
indexManager.rename(request.getCode(), request.getNewName());
|
||||||
|
return CommonResponse.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<IndexNodeInfo> getNodeInfo(GetNodeInfoRequest request) {
|
||||||
|
IndexNode indexNode = indexManager.getOrThrow(request.getCode());
|
||||||
|
return CommonResponse.success(BeanMapper.copyBean(indexNode, IndexNodeInfo.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量获取节点信息集合
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CommonResponse<Map<String, IndexNodeInfo>> batchGetNodeInfo(BatchGetNodeInfoRequest request) {
|
||||||
|
if (Objects.isNull(request) || CollectionUtils.isEmpty(request.getCodes())) {
|
||||||
|
return CommonResponse.success(Collections.emptyMap());
|
||||||
|
}
|
||||||
|
List<IndexNode> indexNodes = indexManager.findByCodes(request.getCodes());
|
||||||
|
if (CollectionUtils.isEmpty(indexNodes)) {
|
||||||
|
return CommonResponse.success(Collections.emptyMap());
|
||||||
|
}
|
||||||
|
List<IndexNodeInfo> indexNodeInfos = BeanUtil.copyToList(indexNodes, IndexNodeInfo.class);
|
||||||
|
|
||||||
|
//填充对象中的fileKey/fileUrl
|
||||||
|
this.fillFileKeyUrl(request, indexNodeInfos);
|
||||||
|
|
||||||
|
Map<String, IndexNodeInfo> nodeInfoMap = indexNodeInfos.stream()
|
||||||
|
.collect(Collectors.toMap(item -> item.getCode(), Function.identity(), (x, y) -> x));
|
||||||
|
return CommonResponse.success(nodeInfoMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充对象中的fileKey/fileUrl
|
||||||
|
*/
|
||||||
|
private void fillFileKeyUrl(BatchGetNodeInfoRequest request, List<IndexNodeInfo> indexNodeInfos) {
|
||||||
|
if (request.getNeedFileUrl()) {
|
||||||
|
Set<String> fileKeys = indexNodeInfos.stream().filter(item -> StringUtils.hasText(item.getOrCreateFileAttributes().getOssFileKey()))
|
||||||
|
.map(item -> item.getOrCreateFileAttributes().getOssFileKey())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
if (CollectionUtils.isNotEmpty(fileKeys)) {
|
||||||
|
List<ApiSignUrlDownloadResponse> urlResponses = ossClient.batchGetOssUrl(fileKeys);
|
||||||
|
Map<String, String> fileKeyAndUrlMap = urlResponses.stream().collect(Collectors.toMap(key -> key.getFileKey(), value -> value.getSignUrl(), (x, y) -> x));
|
||||||
|
indexNodeInfos.stream().filter(item -> StringUtils.hasText(item.getOrCreateFileAttributes().getOssFileKey()))
|
||||||
|
.forEach(item -> {
|
||||||
|
item.setOssFileKey(item.getOrCreateFileAttributes().getOssFileKey());
|
||||||
|
item.setOssFileUrl(fileKeyAndUrlMap.get(item.getOssFileKey()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,10 @@
|
|||||||
|
|
||||||
package cn.axzo.nanopart.doc.file.filedb;
|
package cn.axzo.nanopart.doc.file.filedb;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
import com.xxl.job.core.biz.model.ReturnT;
|
||||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
|
|
||||||
import cn.axzo.nanopart.doc.api.enums.FileDatabaseState;
|
|
||||||
import cn.axzo.nanopart.doc.dao.FileDatabaseDao;
|
|
||||||
import cn.axzo.nanopart.doc.entity.FileDatabase;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yanglin
|
* @author yanglin
|
||||||
@ -21,14 +14,11 @@ import lombok.RequiredArgsConstructor;
|
|||||||
@SuppressWarnings({ "unused", "used by job" })
|
@SuppressWarnings({ "unused", "used by job" })
|
||||||
public class FileDatabaseExpireJob {
|
public class FileDatabaseExpireJob {
|
||||||
|
|
||||||
private final FileDatabaseDao fileDatabaseDao;
|
private final FileDatabaseService fileDatabaseService;
|
||||||
|
|
||||||
@XxlJob("fileDatabaseExpireJob")
|
@XxlJob("fileDatabaseExpireJob")
|
||||||
public ReturnT<String> exec(String paramStr) {
|
public ReturnT<String> exec(String paramStr) {
|
||||||
fileDatabaseDao.lambdaUpdate() //
|
fileDatabaseService.expire();
|
||||||
.eq(FileDatabase::getState, FileDatabaseState.ACTIVATED) //
|
|
||||||
.le(FileDatabase::getExpireDate, new Date()) //
|
|
||||||
.update();
|
|
||||||
return ReturnT.SUCCESS;
|
return ReturnT.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,8 @@ package cn.axzo.nanopart.doc.file.filedb;
|
|||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -26,10 +28,13 @@ import cn.axzo.apollo.workspace.api.workspace.res.SimpleWorkspaceRes;
|
|||||||
import cn.axzo.apollo.workspace.common.enums.WorkspaceTypeEnum;
|
import cn.axzo.apollo.workspace.common.enums.WorkspaceTypeEnum;
|
||||||
import cn.axzo.maokai.api.vo.response.tree.ValueNode;
|
import cn.axzo.maokai.api.vo.response.tree.ValueNode;
|
||||||
import cn.axzo.maokai.api.vo.response.tree.WalkingDecision;
|
import cn.axzo.maokai.api.vo.response.tree.WalkingDecision;
|
||||||
|
import cn.axzo.nanopart.doc.api.domain.DatabaseFeeConfig;
|
||||||
import cn.axzo.nanopart.doc.api.domain.IndexNodeScope;
|
import cn.axzo.nanopart.doc.api.domain.IndexNodeScope;
|
||||||
import cn.axzo.nanopart.doc.api.enums.DatabaseScope;
|
import cn.axzo.nanopart.doc.api.enums.DatabaseScope;
|
||||||
import cn.axzo.nanopart.doc.api.enums.DatabaseType;
|
import cn.axzo.nanopart.doc.api.enums.DatabaseType;
|
||||||
import cn.axzo.nanopart.doc.api.enums.FileDatabaseState;
|
import cn.axzo.nanopart.doc.api.enums.FileDatabaseState;
|
||||||
|
import cn.axzo.nanopart.doc.api.enums.FileTemplateFeeType;
|
||||||
|
import cn.axzo.nanopart.doc.api.enums.IndexNodeContext;
|
||||||
import cn.axzo.nanopart.doc.api.enums.IndexNodeType;
|
import cn.axzo.nanopart.doc.api.enums.IndexNodeType;
|
||||||
import cn.axzo.nanopart.doc.api.filedb.request.FileDatabaseAbortRequest;
|
import cn.axzo.nanopart.doc.api.filedb.request.FileDatabaseAbortRequest;
|
||||||
import cn.axzo.nanopart.doc.api.filedb.request.FileDatabaseActiveRequest;
|
import cn.axzo.nanopart.doc.api.filedb.request.FileDatabaseActiveRequest;
|
||||||
@ -88,26 +93,26 @@ public class FileDatabaseService {
|
|||||||
|
|
||||||
private FileDatabase addWorkspace0(FileDatabaseAddWorkspaceRequest request) {
|
private FileDatabase addWorkspace0(FileDatabaseAddWorkspaceRequest request) {
|
||||||
String scopeUniqueCode = String.valueOf(request.getWorkspaceId());
|
String scopeUniqueCode = String.valueOf(request.getWorkspaceId());
|
||||||
TemplateDatabase templateDatabase = templateDatabaseQueryService.getOrThrow(request.getTemplateDatabaseCode());
|
TemplateDatabase templateDb = templateDatabaseQueryService.getOrThrow(request.getTemplateDatabaseCode());
|
||||||
FileDatabase savedDb = fileDatabaseDao.findForUpdateOrNull(templateDatabase.getScope(), scopeUniqueCode);
|
FileDatabase savedDb = fileDatabaseDao.findForUpdateOrNull(templateDb.getScope(), templateDb.getCode(),
|
||||||
|
scopeUniqueCode);
|
||||||
if (savedDb != null)
|
if (savedDb != null)
|
||||||
throw new FileDatabaseExistsException("无法重复创建, 请刷新页面查询已创建的记录");
|
throw new FileDatabaseExistsException("无法重复创建, 请刷新页面查询已创建的记录");
|
||||||
SimpleWorkspaceRes workspace = RpcExternalUtil.rpcApolloProcessor(
|
SimpleWorkspaceRes workspace = RpcExternalUtil.rpcApolloProcessor(
|
||||||
() -> workspaceApi.getOne(request.getWorkspaceId()), "查询租户", request.getWorkspaceId());
|
() -> workspaceApi.getOne(request.getWorkspaceId()), "查询租户", request.getWorkspaceId());
|
||||||
BizAssertions.assertNotNull(workspace, "找不到对应的租户");
|
BizAssertions.assertNotNull(workspace, "找不到对应的租户");
|
||||||
BizAssertions.assertEquals(workspace.getType(), templateDatabase.getScope().getWorkspaceType(),
|
BizAssertions.assertEquals(workspace.getType(), templateDb.getScope().getWorkspaceType(), "请求租户类型和资料库的租户类型不匹配");
|
||||||
"请求租户类型和资料库的租户类型不匹配");
|
|
||||||
FileDatabase db = new FileDatabase();
|
FileDatabase db = new FileDatabase();
|
||||||
db.setCode(UUIDUtil.uuidString());
|
db.setCode(UUIDUtil.uuidString());
|
||||||
db.setTemplateDatabaseCode(templateDatabase.getCode());
|
db.setTemplateDatabaseCode(templateDb.getCode());
|
||||||
db.setScope(templateDatabase.getScope());
|
db.setScope(templateDb.getScope());
|
||||||
db.setScopeUniqueCode(scopeUniqueCode);
|
db.setScopeUniqueCode(scopeUniqueCode);
|
||||||
db.setWorkspaceId(request.getWorkspaceId());
|
db.setWorkspaceId(request.getWorkspaceId());
|
||||||
db.setState(FileDatabaseState.ACTIVATING);
|
db.setState(FileDatabaseState.ACTIVATING);
|
||||||
if (request.getExpiredDateMs() != null)
|
if (templateDb.getFeeType() == FileTemplateFeeType.ANNUAL && request.getExpiredDateMs() != null)
|
||||||
db.setExpireDate(new Date(request.getExpiredDateMs()));
|
db.setExpireDate(new Date(request.getExpiredDateMs()));
|
||||||
db.setAllowedCapacity(request.getAllowedCapacity());
|
db.setAllowedCapacity(request.getAllowedCapacity());
|
||||||
db.setUsedCapacity(0);
|
db.setUsedCapacity(BigDecimal.ZERO);
|
||||||
db.setCreateAt(new Date());
|
db.setCreateAt(new Date());
|
||||||
db.setUpdateAt(new Date());
|
db.setUpdateAt(new Date());
|
||||||
fileDatabaseDao.save(db);
|
fileDatabaseDao.save(db);
|
||||||
@ -140,6 +145,7 @@ public class FileDatabaseService {
|
|||||||
public WalkingDecision visit(ValueNode<IndexNode> node) {
|
public WalkingDecision visit(ValueNode<IndexNode> node) {
|
||||||
WalkingDecision walkingDecision = super.visit(node);
|
WalkingDecision walkingDecision = super.visit(node);
|
||||||
IndexNode indexNode = node.getValue();
|
IndexNode indexNode = node.getValue();
|
||||||
|
if (indexNode.isDatabase() || indexNode.isDirectory())
|
||||||
BizCodeGenerator.gen(indexNode, indexNode.getNodeType(), db.getWorkspaceId());
|
BizCodeGenerator.gen(indexNode, indexNode.getNodeType(), db.getWorkspaceId());
|
||||||
return walkingDecision;
|
return walkingDecision;
|
||||||
}
|
}
|
||||||
@ -167,14 +173,16 @@ public class FileDatabaseService {
|
|||||||
@BizTransactional
|
@BizTransactional
|
||||||
public void fileSizeChanged(String indexNodeCode) {
|
public void fileSizeChanged(String indexNodeCode) {
|
||||||
IndexNode indexNode = indexManager.findOrNull(indexNodeCode);
|
IndexNode indexNode = indexManager.findOrNull(indexNodeCode);
|
||||||
if (indexNode == null || !indexNode.isFile())
|
if (indexNode == null || !indexNode.isFile() || indexNode.context() != IndexNodeContext.FILE_DATABASE)
|
||||||
return;
|
return;
|
||||||
FileDatabase db = fileDatabaseDao.findForUpdateOrNull(indexNode.scopeCode());
|
FileDatabase db = fileDatabaseDao.findForUpdateOrNull(indexNode.scopeCode());
|
||||||
if (db == null)
|
if (db == null)
|
||||||
return;
|
return;
|
||||||
int usedFileSize = indexQueryService.getUsedFileSize(db);
|
int sizeByte = indexQueryService.getUsedFileSize(db);
|
||||||
fileDatabaseDao.updateUsedCapacity(db.getCode(), usedFileSize);
|
BigDecimal sizeGb = BigDecimal.valueOf(sizeByte) //
|
||||||
if (db.isActivated() && db.getAllowedCapacity() <= usedFileSize)
|
.divide(BigDecimal.valueOf(1024 * 1024 * 1024), 2, RoundingMode.HALF_UP);
|
||||||
|
fileDatabaseDao.updateUsedCapacity(db.getCode(), sizeByte, sizeGb);
|
||||||
|
if (db.isActivated() && isCapacityExhausted(db.getAllowedCapacity(), sizeGb))
|
||||||
fileDatabaseDao.updateState(db.getCode(), FileDatabaseState.CAPACITY_EXHAUSTED);
|
fileDatabaseDao.updateState(db.getCode(), FileDatabaseState.CAPACITY_EXHAUSTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,21 +192,31 @@ public class FileDatabaseService {
|
|||||||
FileDatabase db = fileDatabaseDao.getForUpdateOrThrow(request.getCode());
|
FileDatabase db = fileDatabaseDao.getForUpdateOrThrow(request.getCode());
|
||||||
updateCapacity(request) //
|
updateCapacity(request) //
|
||||||
.set(FileDatabase::getState, //
|
.set(FileDatabase::getState, //
|
||||||
request.getAllowedCapacity() <= db.getUsedCapacity() //
|
isCapacityExhausted(request.getAllowedCapacity(), db.getUsedCapacity()) //
|
||||||
? FileDatabaseState.CAPACITY_EXHAUSTED //
|
? FileDatabaseState.CAPACITY_EXHAUSTED //
|
||||||
: FileDatabaseState.ACTIVATED) //
|
: FileDatabaseState.ACTIVATED) //
|
||||||
.update();
|
.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isCapacityExhausted(Integer allowedCapacity, BigDecimal usedCapacity) {
|
||||||
|
return BigDecimal.valueOf(allowedCapacity).compareTo(usedCapacity) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
@BizTransactional
|
@BizTransactional
|
||||||
public void expandCapacity(FileDatabaseExpandCapacityRequest request) {
|
public void expandCapacity(FileDatabaseExpandCapacityRequest request) {
|
||||||
docLogDao.logRequest("expandCapacity", request.getCode(), request);
|
docLogDao.logRequest("expandCapacity", request.getCode(), request);
|
||||||
FileDatabase db = fileDatabaseDao.getForUpdateOrThrow(request.getCode());
|
FileDatabase db = fileDatabaseDao.getForUpdateOrThrow(request.getCode());
|
||||||
BizAssertions.assertTrue(db.isActivated(), "只有激活状态的资料库才能扩容");
|
BizAssertions.assertTrue(db.isActivated(), "只有激活状态的资料库才能扩容");
|
||||||
|
DatabaseFeeConfig feeConfig = templateDatabaseQueryService.getOrThrow(
|
||||||
|
db.getTemplateDatabaseCode()).getFeeConfig();
|
||||||
|
if (feeConfig != null)
|
||||||
|
BizAssertions.assertTrue(feeConfig.getExtendable(), "资料库不支持扩容");
|
||||||
updateCapacity(request).update();
|
updateCapacity(request).update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private LambdaUpdateChainWrapper<FileDatabase> updateCapacity(FileDatabaseActiveRequest request) {
|
private LambdaUpdateChainWrapper<FileDatabase> updateCapacity(FileDatabaseActiveRequest request) {
|
||||||
|
FileDatabase db = fileDatabaseDao.getOrThrow(request.getCode());
|
||||||
|
TemplateDatabase templateDb = templateDatabaseQueryService.getOrThrow(db.getTemplateDatabaseCode());
|
||||||
Date expireDate = null;
|
Date expireDate = null;
|
||||||
if (request.getExpiredDateMs() != null && request.getExpiredDateMs() > 0)
|
if (request.getExpiredDateMs() != null && request.getExpiredDateMs() > 0)
|
||||||
expireDate = new Date(request.getExpiredDateMs());
|
expireDate = new Date(request.getExpiredDateMs());
|
||||||
@ -206,7 +224,8 @@ public class FileDatabaseService {
|
|||||||
.eq(FileDatabase::getCode, request.getCode()) //
|
.eq(FileDatabase::getCode, request.getCode()) //
|
||||||
.set(FileDatabase::getAllowedCapacity, request.getAllowedCapacity()) //
|
.set(FileDatabase::getAllowedCapacity, request.getAllowedCapacity()) //
|
||||||
.set(FileDatabase::getPurchaseDate, new Date()) //
|
.set(FileDatabase::getPurchaseDate, new Date()) //
|
||||||
.set(expireDate != null, FileDatabase::getExpireDate, expireDate);
|
.set(templateDb.getFeeType() == FileTemplateFeeType.ANNUAL && expireDate != null,
|
||||||
|
FileDatabase::getExpireDate, expireDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@BizTransactional
|
@BizTransactional
|
||||||
@ -294,4 +313,8 @@ public class FileDatabaseService {
|
|||||||
.collect(toList());
|
.collect(toList());
|
||||||
return Page.toPage(request.getPage(), request.getPageSize(), page.getTotal(), records);
|
return Page.toPage(request.getPage(), request.getPageSize(), page.getTotal(), records);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void expire() {
|
||||||
|
this.fileDatabaseDao.expire();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,7 +67,6 @@ public class FileTemplateApiController implements FileTemplateApi {
|
|||||||
@Override
|
@Override
|
||||||
public CommonResponse<String> uploadFile(FileTemplateUploadFileRequest request) {
|
public CommonResponse<String> uploadFile(FileTemplateUploadFileRequest request) {
|
||||||
log.info("upload file request:{}", request);
|
log.info("upload file request:{}", request);
|
||||||
request.getOssFile().validate();
|
|
||||||
return CommonResponse.success(fileTemplateManager.uploadFile(request));
|
return CommonResponse.success(fileTemplateManager.uploadFile(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
|
|
||||||
package cn.axzo.nanopart.doc.file.filetemplate;
|
package cn.axzo.nanopart.doc.file.filetemplate;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import cn.axzo.nanopart.doc.api.domain.OssFile;
|
import cn.axzo.nanopart.doc.api.domain.OssFile;
|
||||||
import cn.axzo.nanopart.doc.api.enums.FileTemplateState;
|
import cn.axzo.nanopart.doc.api.enums.FileTemplateState;
|
||||||
|
import cn.axzo.nanopart.doc.api.enums.IndexNodeContext;
|
||||||
import cn.axzo.nanopart.doc.api.enums.IndexNodeType;
|
import cn.axzo.nanopart.doc.api.enums.IndexNodeType;
|
||||||
import cn.axzo.nanopart.doc.api.filetemplate.request.FileTemplateCreateDirRequest;
|
import cn.axzo.nanopart.doc.api.filetemplate.request.FileTemplateCreateDirRequest;
|
||||||
import cn.axzo.nanopart.doc.api.filetemplate.request.FileTemplateCreateFileRequest;
|
import cn.axzo.nanopart.doc.api.filetemplate.request.FileTemplateCreateFileRequest;
|
||||||
@ -18,6 +21,7 @@ import cn.axzo.nanopart.doc.dao.FileTemplateDao;
|
|||||||
import cn.axzo.nanopart.doc.entity.FileTemplate;
|
import cn.axzo.nanopart.doc.entity.FileTemplate;
|
||||||
import cn.axzo.nanopart.doc.entity.IndexNode;
|
import cn.axzo.nanopart.doc.entity.IndexNode;
|
||||||
import cn.axzo.nanopart.doc.file.index.IndexManager;
|
import cn.axzo.nanopart.doc.file.index.IndexManager;
|
||||||
|
import cn.axzo.nanopart.doc.file.index.SubtreeCopyEventTransactional;
|
||||||
import cn.axzo.nanopart.doc.file.index.domain.IndexNodes;
|
import cn.axzo.nanopart.doc.file.index.domain.IndexNodes;
|
||||||
import cn.axzo.nanopart.doc.utils.BizTransactional;
|
import cn.axzo.nanopart.doc.utils.BizTransactional;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@ -27,11 +31,11 @@ import lombok.RequiredArgsConstructor;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class FileTemplateManager {
|
public class FileTemplateManager implements ApplicationListener<SubtreeCopyEventTransactional> {
|
||||||
|
|
||||||
private final IndexManager indexManager;
|
private final IndexManager indexManager;
|
||||||
private final FileTemplateDao fileTemplateDao;
|
private final FileTemplateDao fileTemplateDao;
|
||||||
private final TransactionTemplate transactionTemplate;
|
private final TransactionTemplate transaction;
|
||||||
|
|
||||||
public String createDir(FileTemplateCreateDirRequest request) {
|
public String createDir(FileTemplateCreateDirRequest request) {
|
||||||
return indexManager.createDir(request).getCode();
|
return indexManager.createDir(request).getCode();
|
||||||
@ -39,7 +43,7 @@ public class FileTemplateManager {
|
|||||||
|
|
||||||
public String createFile(FileTemplateCreateFileRequest request) {
|
public String createFile(FileTemplateCreateFileRequest request) {
|
||||||
OssFile ossFile = indexManager.prepareEmptyOssFile(request, request.getFormat());
|
OssFile ossFile = indexManager.prepareEmptyOssFile(request, request.getFormat());
|
||||||
return transactionTemplate.execute(unused -> createFileTemplate(indexManager.createFile(request, ossFile)));
|
return transaction.execute(unused -> createFileTemplate(indexManager.createFile(request, ossFile)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@BizTransactional
|
@BizTransactional
|
||||||
@ -48,11 +52,16 @@ public class FileTemplateManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String createFileTemplate(IndexNode fileNode) {
|
private String createFileTemplate(IndexNode fileNode) {
|
||||||
|
FileTemplate fileTemplate = buildFileTemplate(fileNode);
|
||||||
|
fileTemplateDao.save(fileTemplate);
|
||||||
|
return fileNode.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FileTemplate buildFileTemplate(IndexNode fileNode) {
|
||||||
FileTemplate fileTemplate = new FileTemplate();
|
FileTemplate fileTemplate = new FileTemplate();
|
||||||
fileTemplate.setCode(fileNode.getCode());
|
fileTemplate.setCode(fileNode.getCode());
|
||||||
fileTemplate.setState(FileTemplateState.UNPUBLISH);
|
fileTemplate.setState(FileTemplateState.UNPUBLISH);
|
||||||
fileTemplateDao.save(fileTemplate);
|
return fileTemplate;
|
||||||
return fileNode.getCode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@BizTransactional
|
@BizTransactional
|
||||||
@ -81,4 +90,16 @@ public class FileTemplateManager {
|
|||||||
.set(request.getState() != null, FileTemplate::getState, request.getState()) //
|
.set(request.getState() != null, FileTemplate::getState, request.getState()) //
|
||||||
.update();
|
.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(SubtreeCopyEventTransactional event) {
|
||||||
|
if (event.getCopiedRoot().getContext() != IndexNodeContext.FILE_TEMPLATE)
|
||||||
|
return;
|
||||||
|
ArrayList<FileTemplate> fileTemplates = new ArrayList<>();
|
||||||
|
for (IndexNode fileNode : indexManager.collectValidSubtreeNodes(event.getCopiedRoot(), IndexNodeType.FILE))
|
||||||
|
fileTemplates.add(buildFileTemplate(fileNode));
|
||||||
|
if (!fileTemplates.isEmpty())
|
||||||
|
fileTemplateDao.saveBatch(fileTemplates);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import java.util.concurrent.Future;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
@ -52,16 +53,17 @@ public class IndexManager {
|
|||||||
private final FileBroadcaster fileBroadcaster;
|
private final FileBroadcaster fileBroadcaster;
|
||||||
private final TransactionTemplate transaction;
|
private final TransactionTemplate transaction;
|
||||||
private final DocLogDao docLogDao;
|
private final DocLogDao docLogDao;
|
||||||
|
private final ApplicationContext applicationContext;
|
||||||
|
|
||||||
@BizTransactional
|
@BizTransactional
|
||||||
public IndexNode createDatabase(NodeCreate create) {
|
public IndexNode createDatabase(NodeCreate create) {
|
||||||
ensureChildNameNotUsed(create, IndexNodeType.DATABASE, true);
|
indexSupport.ensureChildNameNotUsed(create, IndexNodeType.DATABASE, true);
|
||||||
return indexSupport.createNode(create, IndexNodeType.DATABASE);
|
return indexSupport.createNode(create, IndexNodeType.DATABASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@BizTransactional
|
@BizTransactional
|
||||||
public IndexNode createDir(NodeCreate create) {
|
public IndexNode createDir(NodeCreate create) {
|
||||||
ensureChildNameNotUsed(create, IndexNodeType.DIRECTORY, true);
|
indexSupport.ensureChildNameNotUsed(create, IndexNodeType.DIRECTORY, true);
|
||||||
return indexSupport.createNode(create, IndexNodeType.DIRECTORY);
|
return indexSupport.createNode(create, IndexNodeType.DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +71,7 @@ public class IndexManager {
|
|||||||
BizAssertions.assertTrue(format.creatable(), "无法创建: {}", format.readableName());
|
BizAssertions.assertTrue(format.creatable(), "无法创建: {}", format.readableName());
|
||||||
BizAssertions.assertFalse(TransactionSynchronizationManager.isActualTransactionActive(), "不能在事务中使用");
|
BizAssertions.assertFalse(TransactionSynchronizationManager.isActualTransactionActive(), "不能在事务中使用");
|
||||||
// check without lock
|
// check without lock
|
||||||
ensureChildNameNotUsed(create, IndexNodeType.FILE, false);
|
indexSupport.ensureChildNameNotUsed(create, IndexNodeType.FILE, false);
|
||||||
String fullFileName = String.format("%s.%s", create.name(), format.createFileExtension());
|
String fullFileName = String.format("%s.%s", create.name(), format.createFileExtension());
|
||||||
String emptyOssFileKey = format == FileFormat.WORD //
|
String emptyOssFileKey = format == FileFormat.WORD //
|
||||||
? docProps.getCreateFileOssFileKeyWord() //
|
? docProps.getCreateFileOssFileKeyWord() //
|
||||||
@ -83,9 +85,10 @@ public class IndexManager {
|
|||||||
@BizTransactional
|
@BizTransactional
|
||||||
public IndexNode uploadFile(NodeCreate node, OssFile ossFile) {
|
public IndexNode uploadFile(NodeCreate node, OssFile ossFile) {
|
||||||
BizAssertions.assertNotNull(ossFile.getFormat(), "format不能为空");
|
BizAssertions.assertNotNull(ossFile.getFormat(), "format不能为空");
|
||||||
BizAssertions.assertTrue(ossFile.getSize() > 0, "size必须大于0");
|
|
||||||
BizAssertions.assertNotBlank(ossFile.getOssFileKey(), "oosFileKey不能为空");
|
BizAssertions.assertNotBlank(ossFile.getOssFileKey(), "oosFileKey不能为空");
|
||||||
BizAssertions.assertNotBlank(ossFile.getExtension(), "extension不能为空");
|
BizAssertions.assertNotBlank(ossFile.getExtension(), "extension不能为空");
|
||||||
|
if (node.nodeScope().scope().isFeeAware())
|
||||||
|
BizAssertions.assertTrue(ossFile.getSize() >= 0, "size必须大于等于0");
|
||||||
IndexNode fileNode = createFile(node, ossFile);
|
IndexNode fileNode = createFile(node, ossFile);
|
||||||
updateFileSize(fileNode, ossFile.getSize());
|
updateFileSize(fileNode, ossFile.getSize());
|
||||||
return fileNode;
|
return fileNode;
|
||||||
@ -93,7 +96,7 @@ public class IndexManager {
|
|||||||
|
|
||||||
@BizTransactional
|
@BizTransactional
|
||||||
public void updateFileSize(IndexNode fileNode, int size) {
|
public void updateFileSize(IndexNode fileNode, int size) {
|
||||||
if (fileNode == null || !fileNode.isFile())
|
if (fileNode == null || !fileNode.isFile() || size < 0)
|
||||||
return;
|
return;
|
||||||
indexNodeDao.updateFileSize(fileNode.getCode(), size);
|
indexNodeDao.updateFileSize(fileNode.getCode(), size);
|
||||||
fileBroadcaster.fireFileSizeChanged(fileNode.getCode());
|
fileBroadcaster.fireFileSizeChanged(fileNode.getCode());
|
||||||
@ -105,7 +108,7 @@ public class IndexManager {
|
|||||||
return transaction.execute(unused -> {
|
return transaction.execute(unused -> {
|
||||||
try {
|
try {
|
||||||
// check with lock
|
// check with lock
|
||||||
ensureChildNameNotUsed(create, IndexNodeType.FILE, true);
|
indexSupport.ensureChildNameNotUsed(create, IndexNodeType.FILE, true);
|
||||||
}
|
}
|
||||||
catch (NameUsedException e) {
|
catch (NameUsedException e) {
|
||||||
deleteOssFile.set(true);
|
deleteOssFile.set(true);
|
||||||
@ -128,14 +131,6 @@ public class IndexManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureChildNameNotUsed(NodeCreate create, IndexNodeType nodeType, boolean withLock) {
|
|
||||||
if (indexSupport.childrenNameDuplicatable(create))
|
|
||||||
return;
|
|
||||||
if (withLock)
|
|
||||||
indexSupport.lockParentAndReleaseOnCommit(create);
|
|
||||||
indexSupport.ensureChildNameNotUsed(create, nodeType, create.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
@BizTransactional
|
@BizTransactional
|
||||||
public void rename(String code, String newName) {
|
public void rename(String code, String newName) {
|
||||||
IndexNode indexNode = getOrThrow(code);
|
IndexNode indexNode = getOrThrow(code);
|
||||||
@ -158,7 +153,7 @@ public class IndexManager {
|
|||||||
public List<IndexNode> delete(String code) {
|
public List<IndexNode> delete(String code) {
|
||||||
IndexNode indexNode = getOrThrow(code);
|
IndexNode indexNode = getOrThrow(code);
|
||||||
docLogDao.log("indexNode:delete", code);
|
docLogDao.log("indexNode:delete", code);
|
||||||
List<IndexNode> subtree = indexNodeDao.collectValidSubtreeNodes(indexNode);
|
List<IndexNode> subtree = collectValidSubtreeNodes(indexNode);
|
||||||
indexNodeDao.stateDeleteSubtree(indexNode);
|
indexNodeDao.stateDeleteSubtree(indexNode);
|
||||||
return subtree;
|
return subtree;
|
||||||
}
|
}
|
||||||
@ -176,7 +171,7 @@ public class IndexManager {
|
|||||||
IndexNode srcNode = getOrThrow(srcCode);
|
IndexNode srcNode = getOrThrow(srcCode);
|
||||||
BizAssertions.assertTrue(indexNodeDao.validSubtreeFileCount(srcNode) <= docProps.getIndexNodeMaxCopyFileSize(),
|
BizAssertions.assertTrue(indexNodeDao.validSubtreeFileCount(srcNode) <= docProps.getIndexNodeMaxCopyFileSize(),
|
||||||
"拷贝文件数超过限制: {}", docProps.getIndexNodeMaxCopyFileSize());
|
"拷贝文件数超过限制: {}", docProps.getIndexNodeMaxCopyFileSize());
|
||||||
IndexNode destParentNode = determineDestParentNode(srcNode, destParentCode, "克隆");
|
IndexNode destParentNode = determineDestParentNode(srcNode, destParentCode, Op.COPY);
|
||||||
return async(() -> {
|
return async(() -> {
|
||||||
// don't inline in transaction
|
// don't inline in transaction
|
||||||
CopyFileVisitor copyNodeVisitor = new CopyFileVisitor(copySubtreeOssFiles(srcNode));
|
CopyFileVisitor copyNodeVisitor = new CopyFileVisitor(copySubtreeOssFiles(srcNode));
|
||||||
@ -193,7 +188,7 @@ public class IndexManager {
|
|||||||
*/
|
*/
|
||||||
public Future<IndexNode> asyncMove(String srcCode, @Nullable String destParentCode) {
|
public Future<IndexNode> asyncMove(String srcCode, @Nullable String destParentCode) {
|
||||||
IndexNode srcNode = getOrThrow(srcCode);
|
IndexNode srcNode = getOrThrow(srcCode);
|
||||||
IndexNode destParentNode = determineDestParentNode(srcNode, destParentCode, "移动");
|
IndexNode destParentNode = determineDestParentNode(srcNode, destParentCode, Op.MOVE);
|
||||||
return async(() -> transaction.execute(unused -> {
|
return async(() -> transaction.execute(unused -> {
|
||||||
docLogDao.log("indexNode:asyncMove", srcCode, "srcCode", srcCode, "destParentCode", destParentCode);
|
docLogDao.log("indexNode:asyncMove", srcCode, "srcCode", srcCode, "destParentCode", destParentCode);
|
||||||
if (docProps.isLockSubtreeWhenMove())
|
if (docProps.isLockSubtreeWhenMove())
|
||||||
@ -204,18 +199,20 @@ public class IndexManager {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private IndexNode determineDestParentNode(IndexNode srcNode, String destParentCode, String op) {
|
private IndexNode determineDestParentNode(IndexNode srcNode, String destParentCode, Op op) {
|
||||||
IndexNode parent = StringUtils.isBlank(destParentCode) ? null : getOrThrow(destParentCode);
|
IndexNode parent = StringUtils.isBlank(destParentCode) ? null : getOrThrow(destParentCode);
|
||||||
if (parent == null)
|
if (parent == null)
|
||||||
return null;
|
return null;
|
||||||
BizAssertions.assertFalse(srcNode.isDirectory() && parent.isFile(), "不能{}文件夹到文件下", op);
|
BizAssertions.assertFalse(srcNode.isDirectory() && parent.isFile(), "不能{}文件夹到文件下", op);
|
||||||
BizAssertions.assertFalse(srcNode.isSameNodeWith(parent), "不能{}到同一节点下", op);
|
|
||||||
BizAssertions.assertFalse(srcNode.isParentOf(parent), "不能{}到子节点下", op);
|
BizAssertions.assertFalse(srcNode.isParentOf(parent), "不能{}到子节点下", op);
|
||||||
|
if (op == Op.MOVE)
|
||||||
|
BizAssertions.assertFalse(srcNode.isSameNodeWith(parent), "不能{}到同一节点下", op);
|
||||||
List<IndexNode> subtreeNodes = indexSupport.collectValidSubtreeAsValueRoot(srcNode);
|
List<IndexNode> subtreeNodes = indexSupport.collectValidSubtreeAsValueRoot(srcNode);
|
||||||
int subtreeMaxDepth = IndexNodeTreeUtils.build(subtreeNodes).getChildren().stream() //
|
int subtreeMaxDepth = IndexNodeTreeUtils.build(subtreeNodes).getValueNodes().stream() //
|
||||||
.mapToInt(Node::getLevel) //
|
.mapToInt(Node::getLevel) //
|
||||||
.max() //
|
.max() //
|
||||||
.orElse(0);
|
.orElse(0);
|
||||||
|
// 这里不加1, 因为root node其实不是真实的值节点, 不用算在内
|
||||||
indexSupport.validateDepthWhenAddChild(parent.path().depth() + subtreeMaxDepth);
|
indexSupport.validateDepthWhenAddChild(parent.path().depth() + subtreeMaxDepth);
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
@ -226,7 +223,9 @@ public class IndexManager {
|
|||||||
RootNode<IndexNode> srcRoot = TreeUtils.transform(subtreeNodes, IndexNode.class, true);
|
RootNode<IndexNode> srcRoot = TreeUtils.transform(subtreeNodes, IndexNode.class, true);
|
||||||
srcRoot.walkDown(copyNodeVisitor);
|
srcRoot.walkDown(copyNodeVisitor);
|
||||||
indexNodeDao.saveBatch(TreeUtils.collectValues(srcRoot));
|
indexNodeDao.saveBatch(TreeUtils.collectValues(srcRoot));
|
||||||
return connectNodes(srcRoot, destParent);
|
IndexNode copiedRoot = connectNodes(srcRoot, destParent);
|
||||||
|
applicationContext.publishEvent(new SubtreeCopyEventTransactional(this, src, copiedRoot));
|
||||||
|
return copiedRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -244,6 +243,10 @@ public class IndexManager {
|
|||||||
return indexNodeDao.findOrNull(rootNode.getCode());
|
return indexNodeDao.findOrNull(rootNode.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<IndexNode> collectValidSubtreeNodes(IndexNode indexNode, IndexNodeType... nodeTypes) {
|
||||||
|
return indexNodeDao.collectValidSubtreeNodes(indexNode, nodeTypes);
|
||||||
|
}
|
||||||
|
|
||||||
public IndexNode findOrNull(String code) {
|
public IndexNode findOrNull(String code) {
|
||||||
if (StringUtils.isBlank(code))
|
if (StringUtils.isBlank(code))
|
||||||
return null;
|
return null;
|
||||||
@ -254,6 +257,10 @@ public class IndexManager {
|
|||||||
return indexNodeDao.getOrThrow(code);
|
return indexNodeDao.getOrThrow(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<IndexNode> findByCodes(List<String> codes) {
|
||||||
|
return indexNodeDao.findByCodes(codes);
|
||||||
|
}
|
||||||
|
|
||||||
public void updateBizInfo(String code, String bizCode, String description, String icon) {
|
public void updateBizInfo(String code, String bizCode, String description, String icon) {
|
||||||
if (StringUtils.isBlank(bizCode) && StringUtils.isBlank(description) && StringUtils.isBlank(icon))
|
if (StringUtils.isBlank(bizCode) && StringUtils.isBlank(description) && StringUtils.isBlank(icon))
|
||||||
return;
|
return;
|
||||||
@ -276,4 +283,14 @@ public class IndexManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
private enum Op {
|
||||||
|
MOVE("移动"), COPY("克隆");
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
package cn.axzo.nanopart.doc.file.index;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import cn.axzo.basics.common.BeanMapper;
|
||||||
|
import cn.axzo.nanopart.doc.api.domain.IndexNodeInfo;
|
||||||
|
import cn.axzo.nanopart.doc.api.file.IndexNodeApi;
|
||||||
|
import cn.axzo.nanopart.doc.api.index.request.GetNodeInfoRequest;
|
||||||
|
import cn.axzo.nanopart.doc.entity.IndexNode;
|
||||||
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yanglin
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class IndexNodeApiController implements IndexNodeApi {
|
||||||
|
|
||||||
|
private final IndexManager indexManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResponse<IndexNodeInfo> getNodeInfo(GetNodeInfoRequest request) {
|
||||||
|
IndexNode indexNode = indexManager.getOrThrow(request.getCode());
|
||||||
|
return CommonResponse.success(BeanMapper.copyBean(indexNode, IndexNodeInfo.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -100,8 +100,8 @@ public class IndexSupport {
|
|||||||
"创建失败, 子节点数量不能超过 {}", docProps.getIndexNodeMaxChildrenSize());
|
"创建失败, 子节点数量不能超过 {}", docProps.getIndexNodeMaxChildrenSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validateDepthWhenAddChild(int pendingDepth) {
|
public void validateDepthWhenAddChild(int targetDepth) {
|
||||||
BizAssertions.assertTrue(pendingDepth >= docProps.getIndexNodeMaxDepth(), //
|
BizAssertions.assertTrue(targetDepth <= docProps.getIndexNodeMaxDepth(), //
|
||||||
"节点深度超过限制{}, 无法再创建新节点", docProps.getIndexNodeMaxDepth());
|
"节点深度超过限制{}, 无法再创建新节点", docProps.getIndexNodeMaxDepth());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,6 +134,14 @@ public class IndexSupport {
|
|||||||
indexNodeDao.rename(rename.getCode(), newName);
|
indexNodeDao.rename(rename.getCode(), newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ensureChildNameNotUsed(NodeCreate create, IndexNodeType nodeType, boolean withLock) {
|
||||||
|
if (childrenNameDuplicatable(create))
|
||||||
|
return;
|
||||||
|
if (withLock)
|
||||||
|
lockParentAndReleaseOnCommit(create);
|
||||||
|
ensureChildNameNotUsed(create, nodeType, create.name());
|
||||||
|
}
|
||||||
|
|
||||||
void ensureChildNameNotUsed(IndexNodeParentScope parentScope, IndexNodeType nodeType, String childName) {
|
void ensureChildNameNotUsed(IndexNodeParentScope parentScope, IndexNodeType nodeType, String childName) {
|
||||||
IndexNode child = indexNodeDao.findValidChildByName(parentScope, nodeType, childName);
|
IndexNode child = indexNodeDao.findValidChildByName(parentScope, nodeType, childName);
|
||||||
// don't use BizAssertions.assertNull
|
// don't use BizAssertions.assertNull
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
package cn.axzo.nanopart.doc.file.index;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
import cn.axzo.nanopart.doc.entity.IndexNode;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yanglin
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class SubtreeCopyEventTransactional extends ApplicationEvent {
|
||||||
|
|
||||||
|
private final IndexNode srcNode;
|
||||||
|
private final IndexNode copiedRoot;
|
||||||
|
|
||||||
|
public SubtreeCopyEventTransactional(Object source, IndexNode srcNode, IndexNode copiedRoot) {
|
||||||
|
super(source);
|
||||||
|
this.srcNode = srcNode;
|
||||||
|
this.copiedRoot = copiedRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -29,6 +29,12 @@ public class IndexNodes {
|
|||||||
.collect(toList());
|
.collect(toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<IndexNode> collectNodes(IndexNodeType nodeType) {
|
||||||
|
return indexNodes.stream() //
|
||||||
|
.filter(node -> node.getNodeType() == nodeType) //
|
||||||
|
.collect(toList());
|
||||||
|
}
|
||||||
|
|
||||||
public IndexNode findOrNull(String code) {
|
public IndexNode findOrNull(String code) {
|
||||||
return indexNodes.stream() //
|
return indexNodes.stream() //
|
||||||
.filter(node -> node.getCode().equals(code)) //
|
.filter(node -> node.getCode().equals(code)) //
|
||||||
|
|||||||
@ -78,7 +78,6 @@ public class TemplateDatabaseApiController implements TemplateDatabaseApi {
|
|||||||
@Override
|
@Override
|
||||||
public CommonResponse<String> uploadFile(TemplateDatabaseUploadFileRequest request) {
|
public CommonResponse<String> uploadFile(TemplateDatabaseUploadFileRequest request) {
|
||||||
log.info("upload file request:{}", request);
|
log.info("upload file request:{}", request);
|
||||||
request.getOssFile().validate();
|
|
||||||
return CommonResponse.success(templateDatabaseManager.updateFile(request));
|
return CommonResponse.success(templateDatabaseManager.updateFile(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,11 +4,13 @@ package cn.axzo.nanopart.doc.file.templatedb;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
|
|
||||||
import cn.axzo.nanopart.doc.api.domain.OssFile;
|
import cn.axzo.nanopart.doc.api.domain.OssFile;
|
||||||
|
import cn.axzo.nanopart.doc.api.enums.IndexNodeContext;
|
||||||
import cn.axzo.nanopart.doc.api.enums.IndexNodeType;
|
import cn.axzo.nanopart.doc.api.enums.IndexNodeType;
|
||||||
import cn.axzo.nanopart.doc.api.index.request.DeleteNodeRequest;
|
import cn.axzo.nanopart.doc.api.index.request.DeleteNodeRequest;
|
||||||
import cn.axzo.nanopart.doc.api.templatedb.reqeust.NodeCreateTemplateDatabase;
|
import cn.axzo.nanopart.doc.api.templatedb.reqeust.NodeCreateTemplateDatabase;
|
||||||
@ -23,6 +25,7 @@ import cn.axzo.nanopart.doc.entity.IndexNode;
|
|||||||
import cn.axzo.nanopart.doc.entity.TemplateDatabase;
|
import cn.axzo.nanopart.doc.entity.TemplateDatabase;
|
||||||
import cn.axzo.nanopart.doc.file.BizCodeGenerator;
|
import cn.axzo.nanopart.doc.file.BizCodeGenerator;
|
||||||
import cn.axzo.nanopart.doc.file.index.IndexManager;
|
import cn.axzo.nanopart.doc.file.index.IndexManager;
|
||||||
|
import cn.axzo.nanopart.doc.file.index.SubtreeCopyEventTransactional;
|
||||||
import cn.axzo.nanopart.doc.file.index.domain.IndexNodes;
|
import cn.axzo.nanopart.doc.file.index.domain.IndexNodes;
|
||||||
import cn.axzo.nanopart.doc.utils.BizTransactional;
|
import cn.axzo.nanopart.doc.utils.BizTransactional;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@ -32,7 +35,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class TemplateDatabaseManager {
|
public class TemplateDatabaseManager implements ApplicationListener<SubtreeCopyEventTransactional> {
|
||||||
|
|
||||||
private final IndexManager indexManager;
|
private final IndexManager indexManager;
|
||||||
private final TemplateDatabaseDao templateDatabaseDao;
|
private final TemplateDatabaseDao templateDatabaseDao;
|
||||||
@ -110,4 +113,19 @@ public class TemplateDatabaseManager {
|
|||||||
.update();
|
.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(SubtreeCopyEventTransactional event) {
|
||||||
|
if (event.getCopiedRoot().getContext() != IndexNodeContext.TEMPLATE_DATABASE)
|
||||||
|
return;
|
||||||
|
if (event.getCopiedRoot().getNodeType() != IndexNodeType.DATABASE)
|
||||||
|
return;
|
||||||
|
TemplateDatabase templateDb = templateDatabaseDao.getOrThrow(event.getSrcNode().getCode());
|
||||||
|
TemplateDatabase db = new TemplateDatabase();
|
||||||
|
db.setCode(event.getCopiedRoot().getCode());
|
||||||
|
db.setScope(event.getCopiedRoot().getScope());
|
||||||
|
db.setCoopType(templateDb.getCoopType());
|
||||||
|
db.setCreateAt(new Date());
|
||||||
|
db.setUpdateAt(new Date());
|
||||||
|
templateDatabaseDao.save(db);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@ import cn.axzo.oss.http.model.ApiSignUrlDownloadRequest;
|
|||||||
import cn.axzo.oss.http.model.ApiSignUrlDownloadResponse;
|
import cn.axzo.oss.http.model.ApiSignUrlDownloadResponse;
|
||||||
import cn.axzo.oss.http.model.ApiSignUrlUploadRequest;
|
import cn.axzo.oss.http.model.ApiSignUrlUploadRequest;
|
||||||
import cn.axzo.oss.http.model.ApiSignUrlUploadResponse;
|
import cn.axzo.oss.http.model.ApiSignUrlUploadResponse;
|
||||||
|
import cn.axzo.oss.http.model.file.FetchFileInfoRequest;
|
||||||
|
import cn.axzo.oss.http.model.file.FetchFileInfoResponse;
|
||||||
import cn.axzo.oss.http.model.file.UpdateFileInfoRequest;
|
import cn.axzo.oss.http.model.file.UpdateFileInfoRequest;
|
||||||
import cn.axzo.oss.http.model.file.UpdateFileInfoResponse;
|
import cn.axzo.oss.http.model.file.UpdateFileInfoResponse;
|
||||||
import cn.azxo.framework.common.model.CommonResponse;
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
@ -82,4 +84,20 @@ public class DocOssGateway {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件基础信息
|
||||||
|
*/
|
||||||
|
public FetchFileInfoResponse fetchFileInfo(FetchFileInfoRequest request) {
|
||||||
|
try {
|
||||||
|
log.info("DocOssGateway-fetchFileInfo request:{}", JSON.toJSONString(request));
|
||||||
|
CommonResponse<FetchFileInfoResponse> response = serverFileServiceApi.fetchFileInfo(request);
|
||||||
|
log.info("DocOssGateway-fetchFileInfo result:{}", JSON.toJSONString(response));
|
||||||
|
return response.getData();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("DocOssGateway-fetchFileInfo exception", e);
|
||||||
|
throw new WpsException(WpsErrorCodeEnum.UPLOAD_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import java.util.HashMap;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -152,4 +153,21 @@ public class OssClient {
|
|||||||
docLogDao.log(context, subject, logContents);
|
docLogDao.log(context, subject, logContents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ApiSignUrlDownloadResponse> batchGetOssUrl(Set<String> ossFileKeys) {
|
||||||
|
if (CollectionUtils.isEmpty(ossFileKeys)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
ApiSignUrlDownloadRequest request = new ApiSignUrlDownloadRequest();
|
||||||
|
request.setFileKeys(Lists.newArrayList(ossFileKeys));
|
||||||
|
try {
|
||||||
|
log.info("OssClient-batchGetOssUrl params:{}", JSON.toJSONString(ossFileKeys));
|
||||||
|
CommonResponse<List<ApiSignUrlDownloadResponse>> response = serverFileServiceApi.signUrlFetchDownload(request);
|
||||||
|
log.info("OssClient-batchGetOssUrl params:{},result:{}", JSON.toJSONString(ossFileKeys), JSON.toJSONString(response));
|
||||||
|
return response.getData();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("OssClient-batchGetOssUrl exception, fileKeys:{}", JSON.toJSONString(ossFileKeys), e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,7 +35,7 @@ public class AsyncUtils {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch (CannotAcquireLockException e) {
|
catch (CannotAcquireLockException e) {
|
||||||
String message = String.format("%s等待超时, 可能正在移动节点, 请稍后刷新页面重试", op);
|
String message = String.format("%s等待超时, 请稍后重试", op);
|
||||||
log.warn(message, e);
|
log.warn(message, e);
|
||||||
throw fail(message);
|
throw fail(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,115 @@
|
|||||||
|
package cn.axzo.nanopart.doc.wps.support;
|
||||||
|
|
||||||
|
import cn.axzo.nanopart.doc.api.enums.WpsErrorCodeEnum;
|
||||||
|
import cn.axzo.nanopart.doc.api.util.Constants;
|
||||||
|
import cn.axzo.nanopart.doc.api.wps.response.WpsFetchDownloadResponse;
|
||||||
|
import cn.axzo.nanopart.doc.api.wps.response.WpsFetchFileResponse;
|
||||||
|
import cn.axzo.nanopart.doc.integration.DocOssGateway;
|
||||||
|
import cn.axzo.oss.http.model.ApiSignUrlDownloadRequest;
|
||||||
|
import cn.axzo.oss.http.model.ApiSignUrlDownloadResponse;
|
||||||
|
import cn.axzo.oss.http.model.file.FetchFileInfoRequest;
|
||||||
|
import cn.axzo.oss.http.model.file.FetchFileInfoResponse;
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author xudawei@axzo.cn
|
||||||
|
* @date 2025/3/21
|
||||||
|
* @description wps支持
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class OssSupport {
|
||||||
|
|
||||||
|
private final DocOssGateway docOssGateway;
|
||||||
|
|
||||||
|
public WpsFetchFileResponse fetchFileInfo(String fileKey, String personId) {
|
||||||
|
fileKey = url2FileKey(fileKey);
|
||||||
|
FetchFileInfoResponse response = docOssGateway.fetchFileInfo(FetchFileInfoRequest.builder().fileKey(fileKey).build());
|
||||||
|
if (Objects.isNull(response) || Objects.isNull(response.getId())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return WpsFetchFileResponse.builder()
|
||||||
|
.docCode(response.getFileUuid())
|
||||||
|
.name(response.getFileName())
|
||||||
|
.version(1)
|
||||||
|
.size(response.getStorageSize())
|
||||||
|
.createAt(response.getCreateAt())
|
||||||
|
.updateAt(response.getUpdateAt())
|
||||||
|
.creatorId(StringUtils.isNotBlank(response.getCreateBy()) ? response.getCreateBy() : personId)
|
||||||
|
.modifierId(StringUtils.isNotBlank(response.getUpdateBy()) ? response.getUpdateBy() : personId)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public WpsFetchDownloadResponse fetchDownload(String fileKey) {
|
||||||
|
fileKey = url2FileKey(fileKey);
|
||||||
|
FetchFileInfoResponse response = docOssGateway.fetchFileInfo(FetchFileInfoRequest.builder().fileKey(fileKey).build());
|
||||||
|
if (Objects.isNull(response) || Objects.isNull(response.getId())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WpsFetchDownloadResponse.builder()
|
||||||
|
.url(this.downloadUrl(response.getFileUuid()))
|
||||||
|
.digest("")
|
||||||
|
.digestType("")
|
||||||
|
.headers(null)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件下载地址
|
||||||
|
*/
|
||||||
|
public String downloadUrl(String fileKey) {
|
||||||
|
if (StringUtils.isEmpty(fileKey)) {
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
fileKey = url2FileKey(fileKey);
|
||||||
|
ApiSignUrlDownloadRequest request = new ApiSignUrlDownloadRequest();
|
||||||
|
request.setFileKeys(Lists.newArrayList(fileKey));
|
||||||
|
List<ApiSignUrlDownloadResponse> responseList = docOssGateway.signUrlFetchDownload(request);
|
||||||
|
|
||||||
|
WpsAssertUtil.isFalse(CollectionUtil.isEmpty(responseList) || StringUtils.isBlank(responseList.get(0).getSignUrl()), WpsErrorCodeEnum.UPLOAD_ERROR);
|
||||||
|
|
||||||
|
return responseList.get(0).getSignUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从链接中提取fileKey,比如如下链接,获取fileKey:b4148fbee6954c2fa3139471f18a2dcd
|
||||||
|
* https://xx/identity/b4148fbee6954c2fa3139471f18a2dcd.docx?AccessKeyId=xx&Expires=xx&response-content-disposition=xx&Signature=xx
|
||||||
|
* https://xx/identity/b4148fbee6954c2fa3139471f18a2dcd.doc?AccessKeyId=xx&Expires=xx&response-content-disposition=xx&Signature=xx
|
||||||
|
* https://xxx/app/app/b4148fbee6954c2fa3139471f18a2dcd.docx
|
||||||
|
* https://xxx/app/app/b4148fbee6954c2fa3139471f18a2dcd.doc
|
||||||
|
*/
|
||||||
|
public String url2FileKey(String url) {
|
||||||
|
if (!url.startsWith(Constants.WPS_HTTP_START) && !url.startsWith(Constants.WPS_HTTPS_START)) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.contains("/") && url.contains("?")) {
|
||||||
|
url = url.split("\\?")[0];
|
||||||
|
String fileName = url.substring(url.lastIndexOf("/") + 1);
|
||||||
|
if (fileName.contains(".")) {
|
||||||
|
return fileName.substring(0, fileName.indexOf("."));
|
||||||
|
}
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.contains("/") ) {
|
||||||
|
String fileName = url.substring(url.lastIndexOf("/") + 1);
|
||||||
|
if (fileName.contains(".")) {
|
||||||
|
return fileName.substring(0, fileName.indexOf("."));
|
||||||
|
}
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,6 +12,7 @@ import cn.axzo.nanopart.doc.api.wps.response.WpsFetchFileResponse;
|
|||||||
import cn.axzo.nanopart.doc.api.wps.response.WpsPermissionResponse;
|
import cn.axzo.nanopart.doc.api.wps.response.WpsPermissionResponse;
|
||||||
import cn.axzo.nanopart.doc.api.wps.response.WpsRenameResponse;
|
import cn.axzo.nanopart.doc.api.wps.response.WpsRenameResponse;
|
||||||
import cn.axzo.nanopart.doc.api.wps.response.WpsUsersResponse;
|
import cn.axzo.nanopart.doc.api.wps.response.WpsUsersResponse;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@ -37,7 +38,10 @@ public class WpsBaseController implements WpsBaseApi {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ApiResult<WpsFetchFileResponse> fetchFile(@Validated @RequestBody WpsFetchFileRequest request) {
|
public ApiResult<WpsFetchFileResponse> fetchFile(@Validated @RequestBody WpsFetchFileRequest request) {
|
||||||
return ApiResult.ok(wpsBaseManager.fetchFileBase(request.getDocCode()));
|
log.info("WpsBaseController-fetchFile-params: {}", JSON.toJSONString(request));
|
||||||
|
WpsFetchFileResponse wpsFetchFileResponse = wpsBaseManager.fetchFileBase(request.getDocCode(), request.getPersonId());
|
||||||
|
log.info("WpsBaseController-fetchFile-result: {}", JSON.toJSONString(wpsFetchFileResponse));
|
||||||
|
return ApiResult.ok(wpsFetchFileResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,7 +62,10 @@ public class WpsBaseController implements WpsBaseApi {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ApiResult<WpsPermissionResponse> permission(@Validated @RequestBody WpsPermissionRequest request) {
|
public ApiResult<WpsPermissionResponse> permission(@Validated @RequestBody WpsPermissionRequest request) {
|
||||||
return ApiResult.ok(wpsBaseManager.permission(request));
|
log.info("WpsBaseController-permission-params: {}", JSON.toJSONString(request));
|
||||||
|
WpsPermissionResponse permission = wpsBaseManager.permission(request);
|
||||||
|
log.info("WpsBaseController-permission-params:{},result: {}", JSON.toJSONString(request),JSON.toJSONString(permission));
|
||||||
|
return ApiResult.ok(permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,7 +75,10 @@ public class WpsBaseController implements WpsBaseApi {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ApiResult<WpsUsersResponse> users(@Validated @RequestBody WpsUsersRequest request) {
|
public ApiResult<WpsUsersResponse> users(@Validated @RequestBody WpsUsersRequest request) {
|
||||||
return ApiResult.ok(wpsBaseManager.users(request));
|
log.info("WpsBaseController-users-params: {}", JSON.toJSONString(request));
|
||||||
|
WpsUsersResponse users = wpsBaseManager.users(request);
|
||||||
|
log.info("WpsBaseController-users-params:{},result: {}", JSON.toJSONString(request), JSON.toJSONString(users));
|
||||||
|
return ApiResult.ok(users);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -3,6 +3,9 @@ package cn.axzo.nanopart.doc.wps.wpsbase;
|
|||||||
import cn.axzo.basics.common.util.AssertUtil;
|
import cn.axzo.basics.common.util.AssertUtil;
|
||||||
import cn.axzo.basics.profiles.dto.basic.PersonProfileDto;
|
import cn.axzo.basics.profiles.dto.basic.PersonProfileDto;
|
||||||
import cn.axzo.nanopart.doc.api.enums.WpsErrorCodeEnum;
|
import cn.axzo.nanopart.doc.api.enums.WpsErrorCodeEnum;
|
||||||
|
import cn.axzo.nanopart.doc.api.enums.WpsPermissionStatusEnum;
|
||||||
|
import cn.axzo.nanopart.doc.api.util.Constants;
|
||||||
|
import cn.axzo.nanopart.doc.api.wps.exception.WpsException;
|
||||||
import cn.axzo.nanopart.doc.api.wps.request.WpsPermissionRequest;
|
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.WpsRenameRequest;
|
||||||
import cn.axzo.nanopart.doc.api.wps.request.WpsUsersRequest;
|
import cn.axzo.nanopart.doc.api.wps.request.WpsUsersRequest;
|
||||||
@ -12,14 +15,14 @@ import cn.axzo.nanopart.doc.api.wps.response.WpsPermissionResponse;
|
|||||||
import cn.axzo.nanopart.doc.api.wps.response.WpsRenameResponse;
|
import cn.axzo.nanopart.doc.api.wps.response.WpsRenameResponse;
|
||||||
import cn.axzo.nanopart.doc.api.wps.response.WpsUsersResponse;
|
import cn.axzo.nanopart.doc.api.wps.response.WpsUsersResponse;
|
||||||
import cn.axzo.nanopart.doc.config.DocPermissionProps;
|
import cn.axzo.nanopart.doc.config.DocPermissionProps;
|
||||||
import cn.axzo.nanopart.doc.dao.IndexNodeDao;
|
|
||||||
import cn.axzo.nanopart.doc.entity.IndexNode;
|
import cn.axzo.nanopart.doc.entity.IndexNode;
|
||||||
|
import cn.axzo.nanopart.doc.file.index.IndexManager;
|
||||||
|
import cn.axzo.nanopart.doc.file.index.domain.NameUsedException;
|
||||||
import cn.axzo.nanopart.doc.integration.DocOssGateway;
|
import cn.axzo.nanopart.doc.integration.DocOssGateway;
|
||||||
import cn.axzo.nanopart.doc.integration.DocUserProfileGateway;
|
import cn.axzo.nanopart.doc.integration.DocUserProfileGateway;
|
||||||
|
import cn.axzo.nanopart.doc.wps.support.OssSupport;
|
||||||
import cn.axzo.nanopart.doc.wps.support.WpsAssertUtil;
|
import cn.axzo.nanopart.doc.wps.support.WpsAssertUtil;
|
||||||
import cn.axzo.nanopart.doc.wps.support.WpsSupport;
|
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;
|
import cn.axzo.oss.http.model.file.UpdateFileInfoRequest;
|
||||||
import cn.axzo.oss.http.model.file.UpdateFileInfoResponse;
|
import cn.axzo.oss.http.model.file.UpdateFileInfoResponse;
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
@ -41,18 +44,26 @@ import java.util.stream.Collectors;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class WpsBaseManager {
|
public class WpsBaseManager {
|
||||||
|
|
||||||
private final IndexNodeDao indexNodeDao;
|
private final IndexManager indexManager;
|
||||||
private final DocOssGateway docOssGateway;
|
private final DocOssGateway docOssGateway;
|
||||||
private final DocUserProfileGateway docUserProfileGateway;
|
private final DocUserProfileGateway docUserProfileGateway;
|
||||||
|
|
||||||
private final DocPermissionProps docPermissionProps;
|
private final DocPermissionProps docPermissionProps;
|
||||||
|
|
||||||
private final WpsSupport wpsSupport;
|
private final WpsSupport wpsSupport;
|
||||||
|
|
||||||
|
private final OssSupport ossSupport;
|
||||||
/**
|
/**
|
||||||
* 获取文件基础信息
|
* 获取文件基础信息
|
||||||
* @param docCode 文件编码
|
* @param docCode 文件编码
|
||||||
*/
|
*/
|
||||||
public WpsFetchFileResponse fetchFileBase(String docCode) {
|
public WpsFetchFileResponse fetchFileBase(String docCode, String personId) {
|
||||||
|
|
||||||
|
WpsFetchFileResponse wpsFetchFileResponse = ossSupport.fetchFileInfo(docCode, personId);
|
||||||
|
if (Objects.nonNull(wpsFetchFileResponse) && Objects.nonNull(wpsFetchFileResponse.getDocCode())) {
|
||||||
|
return wpsFetchFileResponse;
|
||||||
|
}
|
||||||
|
|
||||||
IndexNode node = wpsSupport.findAndCheckByCode(docCode);
|
IndexNode node = wpsSupport.findAndCheckByCode(docCode);
|
||||||
return WpsFetchFileResponse.builder()
|
return WpsFetchFileResponse.builder()
|
||||||
.docCode(docCode)
|
.docCode(docCode)
|
||||||
@ -71,41 +82,37 @@ public class WpsBaseManager {
|
|||||||
* @param docCode 文件编码
|
* @param docCode 文件编码
|
||||||
*/
|
*/
|
||||||
public WpsFetchDownloadResponse fetchDownload(String docCode) {
|
public WpsFetchDownloadResponse fetchDownload(String docCode) {
|
||||||
|
WpsFetchDownloadResponse wpsFetchDownloadResponse = ossSupport.fetchDownload(docCode);
|
||||||
|
if (Objects.nonNull(wpsFetchDownloadResponse) && StringUtils.isNotBlank(wpsFetchDownloadResponse.getUrl())) {
|
||||||
|
return wpsFetchDownloadResponse;
|
||||||
|
}
|
||||||
|
|
||||||
IndexNode node = wpsSupport.findAndCheckByCode(docCode);
|
IndexNode node = wpsSupport.findAndCheckByCode(docCode);
|
||||||
return WpsFetchDownloadResponse.builder()
|
return WpsFetchDownloadResponse.builder()
|
||||||
.url(this.downloadUrl(node.getAttributes().getFileAttributes().getOssFileKey()))
|
.url(ossSupport.downloadUrl(node.getAttributes().getFileAttributes().getOssFileKey()))
|
||||||
.digest("")
|
.digest("")
|
||||||
.digestType("")
|
.digestType("")
|
||||||
.headers(null)
|
.headers(null)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取文件下载地址
|
|
||||||
*/
|
|
||||||
private String downloadUrl(String fileKey) {
|
|
||||||
if (StringUtils.isEmpty(fileKey)) {
|
|
||||||
return StringUtils.EMPTY;
|
|
||||||
}
|
|
||||||
ApiSignUrlDownloadRequest request = new ApiSignUrlDownloadRequest();
|
|
||||||
request.setFileKeys(Lists.newArrayList(fileKey));
|
|
||||||
List<ApiSignUrlDownloadResponse> responseList = docOssGateway.signUrlFetchDownload(request);
|
|
||||||
|
|
||||||
WpsAssertUtil.isFalse(CollectionUtil.isEmpty(responseList) || StringUtils.isBlank(responseList.get(0).getSignUrl()), WpsErrorCodeEnum.UPLOAD_ERROR);
|
|
||||||
|
|
||||||
return responseList.get(0).getSignUrl();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文档权限
|
* 文档权限
|
||||||
* 暂时全部开放权限,REQ-35401期只是OMS没有文件权限功能,待REQ-3540的2期建立权限后,再对接
|
* 暂时全部开放权限,REQ-35401期只是OMS没有文件权限功能,待REQ-3540的2期建立权限后,再对接
|
||||||
*/
|
*/
|
||||||
public WpsPermissionResponse permission(WpsPermissionRequest request) {
|
public WpsPermissionResponse permission(WpsPermissionRequest request) {
|
||||||
IndexNode indexNode = indexNodeDao.findOrNull(request.getDocCode());
|
IndexNode indexNode = indexManager.findOrNull(request.getDocCode());
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(indexNode.getOrCreateFileAttributes().getFileExtension())
|
if (Objects.nonNull(indexNode) && StringUtils.isNotBlank(indexNode.getOrCreateFileAttributes().getFileExtension())
|
||||||
&& indexNode.getOrCreateFileAttributes().getFileExtension().equalsIgnoreCase("pdf")) {
|
&& indexNode.getOrCreateFileAttributes().getFileExtension().equalsIgnoreCase("pdf")) {
|
||||||
return WpsPermissionResponse.preview(request.getPersonId());
|
return WpsPermissionStatusEnum.preview(request.getPersonId());
|
||||||
|
}
|
||||||
|
if (Objects.nonNull(request.getWpsPermissionStatus())) {
|
||||||
|
if (request.getWpsPermissionStatus() == WpsPermissionStatusEnum.PREVIEW) {
|
||||||
|
return WpsPermissionStatusEnum.preview(request.getPersonId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return WpsPermissionResponse.builder()
|
return WpsPermissionResponse.builder()
|
||||||
@ -127,17 +134,52 @@ public class WpsBaseManager {
|
|||||||
*/
|
*/
|
||||||
public WpsUsersResponse users(WpsUsersRequest request) {
|
public WpsUsersResponse users(WpsUsersRequest request) {
|
||||||
WpsAssertUtil.isFalse(Objects.isNull(request) || CollectionUtil.isEmpty(request.getPersonIds()), WpsErrorCodeEnum.REQUEST_PARAMETER_ERROR);
|
WpsAssertUtil.isFalse(Objects.isNull(request) || CollectionUtil.isEmpty(request.getPersonIds()), WpsErrorCodeEnum.REQUEST_PARAMETER_ERROR);
|
||||||
//查询人员档案
|
|
||||||
List<PersonProfileDto> personProfiles = this.docUserProfileGateway.personProfileByPersonIds(request.getPersonIds().stream().map(Long::parseLong).collect(Collectors.toList()));
|
List<WpsUsersResponse.WpsUser> allWpsUsers = Lists.newArrayList();
|
||||||
WpsAssertUtil.isFalse(CollectionUtil.isEmpty(personProfiles), WpsErrorCodeEnum.USER_NOT_EXIST);
|
//构建默认用户信息
|
||||||
|
allWpsUsers.addAll(this.buildDefaultWpsUsers(request.getPersonIds()));
|
||||||
|
//构建正常用户信息
|
||||||
|
allWpsUsers.addAll(this.buildNormalWpsUsers(request.getPersonIds()));
|
||||||
|
|
||||||
return WpsUsersResponse.builder()
|
return WpsUsersResponse.builder()
|
||||||
.users(personProfiles.stream()
|
.users(allWpsUsers)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建正常用户信息
|
||||||
|
*/
|
||||||
|
private List<WpsUsersResponse.WpsUser> buildNormalWpsUsers(List<String> personIds) {
|
||||||
|
List<Long> normalUserList = personIds.stream().filter(item -> !item.equalsIgnoreCase(Constants.WPS_DEFAULT_USER_ID)).map(Long::parseLong).collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (CollectionUtil.isEmpty(normalUserList)) {
|
||||||
|
return Lists.newArrayList();
|
||||||
|
}
|
||||||
|
//查询人员档案
|
||||||
|
List<PersonProfileDto> personProfiles = this.docUserProfileGateway.personProfileByPersonIds(normalUserList);
|
||||||
|
WpsAssertUtil.isFalse(CollectionUtil.isEmpty(personProfiles), WpsErrorCodeEnum.USER_NOT_EXIST);
|
||||||
|
return personProfiles.stream()
|
||||||
.map(item -> WpsUsersResponse.WpsUser.builder()
|
.map(item -> WpsUsersResponse.WpsUser.builder()
|
||||||
.personId(item.getId().toString())
|
.personId(item.getId().toString())
|
||||||
.name(item.getRealName())
|
.name(item.getRealName())
|
||||||
.avatarUrl(item.getAvatarUrl()).build()).collect(Collectors.toList()))
|
.avatarUrl(item.getAvatarUrl()).build()).collect(Collectors.toList());
|
||||||
.build();
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建默认用户信息
|
||||||
|
*/
|
||||||
|
private List<WpsUsersResponse.WpsUser> buildDefaultWpsUsers(List<String> personIds) {
|
||||||
|
List<Long> defaultUserList = personIds.stream().filter(item -> item.equalsIgnoreCase(Constants.WPS_DEFAULT_USER_ID)).map(Long::parseLong).collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (CollectionUtil.isEmpty(defaultUserList)) {
|
||||||
|
return Lists.newArrayList();
|
||||||
|
}
|
||||||
|
return defaultUserList.stream().map(item ->
|
||||||
|
WpsUsersResponse.WpsUser.builder()
|
||||||
|
.personId(item.toString())
|
||||||
|
.name(StringUtils.EMPTY)
|
||||||
|
.avatarUrl(StringUtils.EMPTY).build()
|
||||||
|
).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,13 +194,11 @@ public class WpsBaseManager {
|
|||||||
|| StringUtils.isBlank(node.getAttributes().getFileAttributes().getOssFileKey())) {
|
|| StringUtils.isBlank(node.getAttributes().getFileAttributes().getOssFileKey())) {
|
||||||
return WpsRenameResponse.builder().updateFlag(false).build();
|
return WpsRenameResponse.builder().updateFlag(false).build();
|
||||||
}
|
}
|
||||||
//TODO: 文件名重复
|
try {
|
||||||
//try {
|
indexManager.rename(node.getCode(), request.getName());
|
||||||
// 调用IndexManager.rename();
|
} catch (NameUsedException e) {
|
||||||
//} catch (NameUsedException e) {
|
throw new WpsException(WpsErrorCodeEnum.FILE_NAME_CONFLICT);
|
||||||
// // 处理文件已被使用的情况
|
}
|
||||||
//}
|
|
||||||
indexNodeDao.rename(request.getDocCode(), request.getName());
|
|
||||||
UpdateFileInfoResponse response = this.docOssGateway.updateFileInfo(UpdateFileInfoRequest.builder().fileKey(node.getAttributes().getFileAttributes().getOssFileKey()).build());
|
UpdateFileInfoResponse response = this.docOssGateway.updateFileInfo(UpdateFileInfoRequest.builder().fileKey(node.getAttributes().getFileAttributes().getOssFileKey()).build());
|
||||||
return WpsRenameResponse.builder().updateFlag(response.isUpdateFlag()).build();
|
return WpsRenameResponse.builder().updateFlag(response.isUpdateFlag()).build();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,11 +62,10 @@ public class GuideTenantProcedureStatusServiceImpl extends ServiceImpl<GuideTena
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将租户操作步骤数量与模板操作步骤数量进行对比,如果模板操作步骤数量大于租户操作步骤数量,则根据模板为租户初始化新步骤点
|
// 将租户操作步骤数量与模板操作步骤数量进行对比,是否需要根据模板为租户初始化新步骤点
|
||||||
if (templateList.size() > procedureStatusList.size()) {
|
|
||||||
// 将该租户未初始化的步骤点进行初始化
|
// 将该租户未初始化的步骤点进行初始化
|
||||||
List<Long> procedureStatusIdList = procedureStatusList.stream().map(GuideTenantProcedureStatus::getProcedureId).collect(Collectors.toList());
|
List<Long> procedureStatusIdList = procedureStatusList.stream().map(GuideTenantProcedureStatus::getProcedureId).distinct().collect(Collectors.toList());
|
||||||
respList.addAll(templateList.stream()
|
List<GuideTenantProcedureStatusListResp> newInitProcedures = templateList.stream()
|
||||||
.filter(t -> !procedureStatusIdList.contains(t.getId()))
|
.filter(t -> !procedureStatusIdList.contains(t.getId()))
|
||||||
.map(t -> {
|
.map(t -> {
|
||||||
GuideTenantProcedureStatusCreateReq createReq = new GuideTenantProcedureStatusCreateReq();
|
GuideTenantProcedureStatusCreateReq createReq = new GuideTenantProcedureStatusCreateReq();
|
||||||
@ -78,15 +77,17 @@ public class GuideTenantProcedureStatusServiceImpl extends ServiceImpl<GuideTena
|
|||||||
create(createReq);
|
create(createReq);
|
||||||
return BeanUtil.copyProperties(createReq, GuideTenantProcedureStatusListResp.class);
|
return BeanUtil.copyProperties(createReq, GuideTenantProcedureStatusListResp.class);
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList());
|
||||||
} else if (templateList.size() < procedureStatusList.size()) {
|
if (CollUtil.isNotEmpty(newInitProcedures)) {
|
||||||
log.warn("操作步骤模板:{},租户&分类:{},租户操作步骤状态:{}", JSONUtil.toJsonStr(templateList), JSONUtil.toJsonStr(req), JSONUtil.toJsonStr(procedureStatusList));
|
respList.addAll(newInitProcedures);
|
||||||
throw new ServiceException("数据异常,操作步骤不存在,请联系管理人员");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 对租户操作步骤的权限码和跳转链接进行补充
|
// 对租户操作步骤的权限码和跳转链接进行补充
|
||||||
Map<Long, GuideProcedureTemplateResp> templateMap = templateList.stream().collect(Collectors.toMap(GuideProcedureTemplateResp::getId, Function.identity(), (v1, v2) -> v1));
|
Map<Long, GuideProcedureTemplateResp> templateMap = templateList.stream().collect(Collectors.toMap(GuideProcedureTemplateResp::getId, Function.identity(), (v1, v2) -> v1));
|
||||||
respList.forEach(r -> {
|
return respList.stream()
|
||||||
|
.collect(Collectors.toMap(r -> r.getWorkspaceId() + "_" + r.getProcedureId(), Function.identity(), (v1, v2) -> v1))
|
||||||
|
.values().stream()
|
||||||
|
.peek(r -> {
|
||||||
GuideProcedureTemplateResp t = templateMap.get(r.getProcedureId());
|
GuideProcedureTemplateResp t = templateMap.get(r.getProcedureId());
|
||||||
r.setDescription(t.getDescription());
|
r.setDescription(t.getDescription());
|
||||||
r.setIsMust(t.getIsMust());
|
r.setIsMust(t.getIsMust());
|
||||||
@ -94,8 +95,8 @@ public class GuideTenantProcedureStatusServiceImpl extends ServiceImpl<GuideTena
|
|||||||
r.setJumpUrl(t.getJumpUrl());
|
r.setJumpUrl(t.getJumpUrl());
|
||||||
r.setJumpReport(t.getJumpReport());
|
r.setJumpReport(t.getJumpReport());
|
||||||
r.setSort(t.getSort());
|
r.setSort(t.getSort());
|
||||||
});
|
})
|
||||||
return respList;
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -127,12 +128,15 @@ public class GuideTenantProcedureStatusServiceImpl extends ServiceImpl<GuideTena
|
|||||||
log.info("步骤已完成,无需重复操作,workspaceId: {}, procedureId:{}", req.getWorkspaceId(), req.getProcedureId());
|
log.info("步骤已完成,无需重复操作,workspaceId: {}, procedureId:{}", req.getWorkspaceId(), req.getProcedureId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tenantProcedure.setStatus(req.getStatus());
|
lambdaUpdate()
|
||||||
updateById(tenantProcedure);
|
.eq(GuideTenantProcedureStatus::getWorkspaceId, req.getWorkspaceId())
|
||||||
|
.eq(GuideTenantProcedureStatus::getProcedureId, req.getProcedureId())
|
||||||
|
.set(GuideTenantProcedureStatus::getStatus, req.getStatus())
|
||||||
|
.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long create(GuideTenantProcedureStatusCreateReq req) {
|
public synchronized Long create(GuideTenantProcedureStatusCreateReq req) {
|
||||||
// 若操作所属分类或操作名称为空,则从对应模板获取
|
// 若操作所属分类或操作名称为空,则从对应模板获取
|
||||||
if (Objects.isNull(req.getCategoryCode()) || CharSequenceUtil.isBlank(req.getProcedureName())) {
|
if (Objects.isNull(req.getCategoryCode()) || CharSequenceUtil.isBlank(req.getProcedureName())) {
|
||||||
GuideProcedureTemplateResp byProcedureId = procedureTemplateService.getByProcedureId(req.getProcedureId());
|
GuideProcedureTemplateResp byProcedureId = procedureTemplateService.getByProcedureId(req.getProcedureId());
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import cn.axzo.framework.domain.web.result.ApiPageResult;
|
|||||||
import cn.axzo.framework.domain.web.result.ApiResult;
|
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||||
import cn.axzo.framework.domain.web.result.PageData;
|
import cn.axzo.framework.domain.web.result.PageData;
|
||||||
import cn.axzo.nanopart.visa.api.changerecord.ChangeRecordApi;
|
import cn.axzo.nanopart.visa.api.changerecord.ChangeRecordApi;
|
||||||
|
import cn.axzo.nanopart.visa.api.enums.VisaConfirmBizTypeEnum;
|
||||||
import cn.axzo.nanopart.visa.api.enums.VisaStatusEnum;
|
import cn.axzo.nanopart.visa.api.enums.VisaStatusEnum;
|
||||||
import cn.axzo.nanopart.visa.api.request.BizActivityAssigneeDecisionReq;
|
import cn.axzo.nanopart.visa.api.request.BizActivityAssigneeDecisionReq;
|
||||||
import cn.axzo.nanopart.visa.api.request.ChangeRecordButtonOperationReq;
|
import cn.axzo.nanopart.visa.api.request.ChangeRecordButtonOperationReq;
|
||||||
@ -30,6 +31,7 @@ import cn.axzo.nanopart.visa.server.service.ChangeRecordBillService;
|
|||||||
import cn.axzo.nanopart.visa.server.service.ChangeRecordConfirmService;
|
import cn.axzo.nanopart.visa.server.service.ChangeRecordConfirmService;
|
||||||
import cn.axzo.nanopart.visa.server.service.ChangeRecordService;
|
import cn.axzo.nanopart.visa.server.service.ChangeRecordService;
|
||||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
@ -147,7 +149,7 @@ public class ChangeRecordController implements ChangeRecordApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResult<List<VisaChangeApproveCreateReq.ApprovePersonInfo>> getVisaAllConfirm(FetchVisaAllConfirmReq req) {
|
public ApiResult<List<VisaChangeApproveCreateReq.ApprovePersonInfo>> getVisaAllConfirm(FetchVisaAllConfirmReq req) {
|
||||||
return ApiResult.ok(changeRecordConfirmService.listAllConfirmByVisaId(req.getVisaId()));
|
return ApiResult.ok(changeRecordConfirmService.listAllConfirmByVisaId(req.getVisaId(), Lists.newArrayList(VisaConfirmBizTypeEnum.CONFIRM)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -46,6 +46,8 @@ public class VisaConfirmDto {
|
|||||||
*/
|
*/
|
||||||
private VisaConfirmBizTypeEnum bizType;
|
private VisaConfirmBizTypeEnum bizType;
|
||||||
|
|
||||||
|
private List<VisaConfirmBizTypeEnum> bizTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 确认人
|
* 确认人
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
package cn.axzo.nanopart.visa.server.mq.listener.workflow.process;
|
package cn.axzo.nanopart.visa.server.mq.listener.workflow.process;
|
||||||
|
|
||||||
|
import cn.axzo.framework.jackson.utility.JSON;
|
||||||
import cn.axzo.framework.rocketmq.Event;
|
import cn.axzo.framework.rocketmq.Event;
|
||||||
import cn.axzo.framework.rocketmq.EventConsumer;
|
import cn.axzo.framework.rocketmq.EventConsumer;
|
||||||
import cn.axzo.framework.rocketmq.EventProducer;
|
import cn.axzo.framework.rocketmq.EventProducer;
|
||||||
import cn.axzo.msg.center.api.MessageAPIV3;
|
import cn.axzo.msg.center.api.MessageAPIV3;
|
||||||
import cn.axzo.msg.center.api.request.v3.MessageSendReqV3;
|
import cn.axzo.msg.center.api.request.v3.MessageSendReqV3;
|
||||||
|
import cn.axzo.msg.center.api.response.v3.MessageSendRespV3;
|
||||||
import cn.axzo.msg.center.service.dto.PersonV3DTO;
|
import cn.axzo.msg.center.service.dto.PersonV3DTO;
|
||||||
|
import cn.axzo.nanopart.visa.api.enums.VisaConfirmBizTypeEnum;
|
||||||
import cn.axzo.nanopart.visa.api.enums.VisaStampStatusEnum;
|
import cn.axzo.nanopart.visa.api.enums.VisaStampStatusEnum;
|
||||||
import cn.axzo.nanopart.visa.api.enums.VisaStatusEnum;
|
import cn.axzo.nanopart.visa.api.enums.VisaStatusEnum;
|
||||||
import cn.axzo.nanopart.visa.api.enums.VisaTypeEnum;
|
import cn.axzo.nanopart.visa.api.enums.VisaTypeEnum;
|
||||||
@ -18,14 +21,17 @@ import cn.axzo.nanopart.visa.server.mq.listener.workflow.BasicLogSupport;
|
|||||||
import cn.axzo.nanopart.visa.server.mq.producer.VisaChangeLogPayload;
|
import cn.axzo.nanopart.visa.server.mq.producer.VisaChangeLogPayload;
|
||||||
import cn.axzo.nanopart.visa.server.rpc.VisaOrganizationalNodeUserGateway;
|
import cn.axzo.nanopart.visa.server.rpc.VisaOrganizationalNodeUserGateway;
|
||||||
import cn.axzo.nanopart.visa.server.service.ChangeRecordBillService;
|
import cn.axzo.nanopart.visa.server.service.ChangeRecordBillService;
|
||||||
|
import cn.axzo.nanopart.visa.server.service.ChangeRecordConfirmService;
|
||||||
import cn.axzo.nanopart.visa.server.service.ChangeRecordRelationService;
|
import cn.axzo.nanopart.visa.server.service.ChangeRecordRelationService;
|
||||||
import cn.axzo.nanopart.visa.server.service.ChangeRecordService;
|
import cn.axzo.nanopart.visa.server.service.ChangeRecordService;
|
||||||
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
|
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
|
||||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||||
import cn.axzo.workflow.common.model.response.mq.ProcessInstanceDTO;
|
import cn.axzo.workflow.common.model.response.mq.ProcessInstanceDTO;
|
||||||
import cn.axzo.workflow.starter.handler.ProcessInstanceEventHandler;
|
import cn.axzo.workflow.starter.handler.ProcessInstanceEventHandler;
|
||||||
|
import cn.azxo.framework.common.model.CommonResponse;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.groovy.util.Maps;
|
import org.apache.groovy.util.Maps;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
@ -35,6 +41,7 @@ import java.util.Date;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static cn.axzo.nanopart.visa.api.constant.VisaConstant.FORM_FIELD_TOPIC;
|
import static cn.axzo.nanopart.visa.api.constant.VisaConstant.FORM_FIELD_TOPIC;
|
||||||
import static cn.axzo.nanopart.visa.api.constant.VisaConstant.FORM_FIELD_WORKSPACE_NAME;
|
import static cn.axzo.nanopart.visa.api.constant.VisaConstant.FORM_FIELD_WORKSPACE_NAME;
|
||||||
@ -54,11 +61,13 @@ import static cn.axzo.nanopart.visa.api.enums.VisaTypeEnum.TECHNOLOGY_APPROVED;
|
|||||||
* @author wangli
|
* @author wangli
|
||||||
* @since 2025-01-17 11:35
|
* @since 2025-01-17 11:35
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implements ProcessInstanceEventHandler {
|
public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implements ProcessInstanceEventHandler {
|
||||||
protected final ChangeRecordService changeRecordService;
|
protected final ChangeRecordService changeRecordService;
|
||||||
protected final ChangeRecordRelationService changeRecordRelationService;
|
protected final ChangeRecordRelationService changeRecordRelationService;
|
||||||
protected final ChangeRecordBillService changeRecordBillService;
|
protected final ChangeRecordBillService changeRecordBillService;
|
||||||
|
protected final ChangeRecordConfirmService changeRecordConfirmService;
|
||||||
protected final MessageAPIV3 noticeApi;
|
protected final MessageAPIV3 noticeApi;
|
||||||
public final static List<String> SUPPORTED_DEFINITION_KEYS = Lists.newArrayList(
|
public final static List<String> SUPPORTED_DEFINITION_KEYS = Lists.newArrayList(
|
||||||
DESIGN_CHANGE.getProcessDefinitionKey(),
|
DESIGN_CHANGE.getProcessDefinitionKey(),
|
||||||
@ -72,11 +81,14 @@ public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implem
|
|||||||
ChangeRecordService changeRecordService,
|
ChangeRecordService changeRecordService,
|
||||||
ChangeRecordRelationService changeRecordRelationService,
|
ChangeRecordRelationService changeRecordRelationService,
|
||||||
ChangeRecordBillService changeRecordBillService,
|
ChangeRecordBillService changeRecordBillService,
|
||||||
MessageAPIV3 noticeApi, RefreshableConfiguration refreshableConfiguration) {
|
ChangeRecordConfirmService changeRecordConfirmService,
|
||||||
|
MessageAPIV3 noticeApi,
|
||||||
|
RefreshableConfiguration refreshableConfiguration) {
|
||||||
super(eventProducer, visaOrganizationalNodeUserGateway);
|
super(eventProducer, visaOrganizationalNodeUserGateway);
|
||||||
this.changeRecordService = changeRecordService;
|
this.changeRecordService = changeRecordService;
|
||||||
this.changeRecordRelationService = changeRecordRelationService;
|
this.changeRecordRelationService = changeRecordRelationService;
|
||||||
this.changeRecordBillService = changeRecordBillService;
|
this.changeRecordBillService = changeRecordBillService;
|
||||||
|
this.changeRecordConfirmService = changeRecordConfirmService;
|
||||||
this.noticeApi = noticeApi;
|
this.noticeApi = noticeApi;
|
||||||
this.refreshableConfiguration = refreshableConfiguration;
|
this.refreshableConfiguration = refreshableConfiguration;
|
||||||
}
|
}
|
||||||
@ -105,6 +117,10 @@ public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implem
|
|||||||
public void onCompleted(ProcessInstanceDTO dto) {
|
public void onCompleted(ProcessInstanceDTO dto) {
|
||||||
String visaTypeDesc = parseVisaType(dto);
|
String visaTypeDesc = parseVisaType(dto);
|
||||||
|
|
||||||
|
log.info("send complete notice");
|
||||||
|
sendCompleteNotice(dto);
|
||||||
|
log.info("send complete notice success");
|
||||||
|
|
||||||
updateChangeRecordApprovalStatus(dto, BpmnProcessInstanceResultEnum.APPROVED);
|
updateChangeRecordApprovalStatus(dto, BpmnProcessInstanceResultEnum.APPROVED);
|
||||||
|
|
||||||
changeRecordService.lambdaUpdate()
|
changeRecordService.lambdaUpdate()
|
||||||
@ -112,15 +128,23 @@ public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implem
|
|||||||
.set(ChangeRecord::getStampStatus, VisaStampStatusEnum.UNPRINTED.name())
|
.set(ChangeRecord::getStampStatus, VisaStampStatusEnum.UNPRINTED.name())
|
||||||
.update();
|
.update();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendCompleteNotice(ProcessInstanceDTO dto) {
|
||||||
Map<String, Object> variables = dto.getVariables();
|
Map<String, Object> variables = dto.getVariables();
|
||||||
|
BpmnTaskDelegateAssigner initiator = dto.getInitiator();
|
||||||
MessageSendReqV3 completeNotice = new MessageSendReqV3();
|
MessageSendReqV3 completeNotice = new MessageSendReqV3();
|
||||||
completeNotice.setSender(PersonV3DTO.builder().build());
|
completeNotice.setSender(PersonV3DTO.builder().build());
|
||||||
completeNotice.setReceivers(Lists.newArrayList(PersonV3DTO.builder().build()));
|
completeNotice.setReceivers(queryConfirm(dto));
|
||||||
completeNotice.setBizEventMappingCode(refreshableConfiguration.getProcessInstanceCompleteMsgEventCode());
|
completeNotice.setBizEventMappingCode(refreshableConfiguration.getProcessInstanceCompleteMsgEventCode());
|
||||||
completeNotice.setBizCode(dto.getBusinessKey());
|
completeNotice.setBizCode(dto.getBusinessKey());
|
||||||
|
String visaType = (String) variables.getOrDefault(WORKFLOW_VAR_VISA_TYPE_KEY, "");
|
||||||
|
String VisaTypeDesc = StringUtils.hasText(visaType) ? VisaTypeEnum.valueOf(visaType).getDesc() : "";
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
completeNotice.setBizExtParams(new JSONObject(Maps.of(
|
completeNotice.setBizExtParams(new JSONObject(Maps.of(
|
||||||
|
"initiatorName", initiator.getAssignerName(),
|
||||||
"topic", variables.getOrDefault(FORM_FIELD_TOPIC, ""),
|
"topic", variables.getOrDefault(FORM_FIELD_TOPIC, ""),
|
||||||
|
"visaTypeDesc", VisaTypeDesc,
|
||||||
"workspaceName", variables.getOrDefault(FORM_FIELD_WORKSPACE_NAME, ""),
|
"workspaceName", variables.getOrDefault(FORM_FIELD_WORKSPACE_NAME, ""),
|
||||||
"time", sdf.format(new Date())
|
"time", sdf.format(new Date())
|
||||||
)));
|
)));
|
||||||
@ -129,7 +153,22 @@ public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implem
|
|||||||
"ouId", variables.getOrDefault(IM_GROUP_BIZ_INFO_INITIATOR_OU_ID, ""),
|
"ouId", variables.getOrDefault(IM_GROUP_BIZ_INFO_INITIATOR_OU_ID, ""),
|
||||||
"workspaceId", variables.getOrDefault(IM_GROUP_BIZ_INFO_INITIATOR_WORKSPACE_ID, "")
|
"workspaceId", variables.getOrDefault(IM_GROUP_BIZ_INFO_INITIATOR_WORKSPACE_ID, "")
|
||||||
)));
|
)));
|
||||||
noticeApi.send(completeNotice);
|
CommonResponse<MessageSendRespV3> response = noticeApi.send(completeNotice);
|
||||||
|
if (Objects.nonNull(response) && response.getCode() == 200) {
|
||||||
|
log.info("send complete notice result: {}", JSON.toJSONString(response.getData()));
|
||||||
|
} else {
|
||||||
|
log.error("send complete notice failed: {}", Objects.isNull(response) ? "response is null" : JSON.toJSONString(response.getMsg()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<PersonV3DTO> queryConfirm(ProcessInstanceDTO dto) {
|
||||||
|
Long visaId = Long.valueOf(dto.getBusinessKey());
|
||||||
|
return changeRecordConfirmService.listAllConfirmByVisaId(visaId, Lists.newArrayList(VisaConfirmBizTypeEnum.CREATE, VisaConfirmBizTypeEnum.CONFIRM))
|
||||||
|
.stream().map(e -> PersonV3DTO.builder()
|
||||||
|
.id(e.getPersonId())
|
||||||
|
.name(e.getRealName())
|
||||||
|
.imReceiveModel(new PersonV3DTO.ReceiveModel(e.getOuId(), e.getWorkspaceId()))
|
||||||
|
.build()).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -160,6 +199,10 @@ public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implem
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onRejected(ProcessInstanceDTO dto) {
|
public void onRejected(ProcessInstanceDTO dto) {
|
||||||
|
log.info("send reject notice");
|
||||||
|
sendRejectNotice(dto);
|
||||||
|
log.info("send reject notice success");
|
||||||
|
|
||||||
BpmnTaskDelegateAssigner lastOperationAssigner = dto.getLastOperationAssigner();
|
BpmnTaskDelegateAssigner lastOperationAssigner = dto.getLastOperationAssigner();
|
||||||
ChangeRecordLog log = ChangeRecordLog.builder()
|
ChangeRecordLog log = ChangeRecordLog.builder()
|
||||||
.visaId(Long.valueOf(dto.getBusinessKey()))
|
.visaId(Long.valueOf(dto.getBusinessKey()))
|
||||||
@ -171,14 +214,23 @@ public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implem
|
|||||||
|
|
||||||
updateChangeRecordApprovalStatus(dto, BpmnProcessInstanceResultEnum.REJECTED);
|
updateChangeRecordApprovalStatus(dto, BpmnProcessInstanceResultEnum.REJECTED);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendRejectNotice(ProcessInstanceDTO dto) {
|
||||||
Map<String, Object> variables = dto.getVariables();
|
Map<String, Object> variables = dto.getVariables();
|
||||||
|
BpmnTaskDelegateAssigner initiator = dto.getInitiator();
|
||||||
MessageSendReqV3 rejectNotice = new MessageSendReqV3();
|
MessageSendReqV3 rejectNotice = new MessageSendReqV3();
|
||||||
rejectNotice.setSender(PersonV3DTO.builder().build());
|
rejectNotice.setSender(PersonV3DTO.builder().build());
|
||||||
rejectNotice.setReceivers(Lists.newArrayList(PersonV3DTO.builder().build()));
|
rejectNotice.setReceivers(queryConfirm(dto));
|
||||||
rejectNotice.setBizEventMappingCode(refreshableConfiguration.getProcessInstanceCompleteMsgEventCode());
|
rejectNotice.setBizEventMappingCode(refreshableConfiguration.getProcessInstanceRejectMsgEventCode());
|
||||||
rejectNotice.setBizCode(dto.getBusinessKey());
|
rejectNotice.setBizCode(dto.getBusinessKey());
|
||||||
|
|
||||||
|
String visaType = (String) variables.getOrDefault(WORKFLOW_VAR_VISA_TYPE_KEY, "");
|
||||||
|
String VisaTypeDesc = StringUtils.hasText(visaType) ? VisaTypeEnum.valueOf(visaType).getDesc() : "";
|
||||||
rejectNotice.setBizExtParams(new JSONObject(Maps.of(
|
rejectNotice.setBizExtParams(new JSONObject(Maps.of(
|
||||||
|
"initiatorName", initiator.getAssignerName(),
|
||||||
"topic", variables.getOrDefault(FORM_FIELD_TOPIC, ""),
|
"topic", variables.getOrDefault(FORM_FIELD_TOPIC, ""),
|
||||||
|
"visaTypeDesc", VisaTypeDesc,
|
||||||
"workspaceName", variables.getOrDefault(FORM_FIELD_WORKSPACE_NAME, ""),
|
"workspaceName", variables.getOrDefault(FORM_FIELD_WORKSPACE_NAME, ""),
|
||||||
"reason", dto.getReason()
|
"reason", dto.getReason()
|
||||||
)));
|
)));
|
||||||
@ -187,7 +239,13 @@ public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implem
|
|||||||
"ouId", variables.getOrDefault(IM_GROUP_BIZ_INFO_INITIATOR_OU_ID, ""),
|
"ouId", variables.getOrDefault(IM_GROUP_BIZ_INFO_INITIATOR_OU_ID, ""),
|
||||||
"workspaceId", variables.getOrDefault(IM_GROUP_BIZ_INFO_INITIATOR_WORKSPACE_ID, "")
|
"workspaceId", variables.getOrDefault(IM_GROUP_BIZ_INFO_INITIATOR_WORKSPACE_ID, "")
|
||||||
)));
|
)));
|
||||||
noticeApi.send(rejectNotice);
|
|
||||||
|
CommonResponse<MessageSendRespV3> response = noticeApi.send(rejectNotice);
|
||||||
|
if (Objects.nonNull(response) && response.getCode() == 200) {
|
||||||
|
log.info("send reject notice result: {}", JSON.toJSONString(response.getData()));
|
||||||
|
} else {
|
||||||
|
log.error("send reject notice failed: {}", Objects.isNull(response) ? "response is null" : JSON.toJSONString(response.getMsg()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -76,7 +76,7 @@ public interface ChangeRecordConfirmService {
|
|||||||
* @param visaId
|
* @param visaId
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<VisaChangeApproveCreateReq.ApprovePersonInfo> listAllConfirmByVisaId(Long visaId);
|
List<VisaChangeApproveCreateReq.ApprovePersonInfo> listAllConfirmByVisaId(Long visaId, List<VisaConfirmBizTypeEnum> bizTypes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建公司的Map,orgIdAndNameMap,key:ouId,value:ouName
|
* 构建公司的Map,orgIdAndNameMap,key:ouId,value:ouName
|
||||||
|
|||||||
@ -418,6 +418,7 @@ public class ChangeRecordConfirmServiceImpl extends ServiceImpl<ChangeRecordConf
|
|||||||
.in(CollectionUtils.isNotEmpty(dto.getProjectIds()), ChangeRecordConfirm::getProjectId, dto.getProjectIds())
|
.in(CollectionUtils.isNotEmpty(dto.getProjectIds()), ChangeRecordConfirm::getProjectId, dto.getProjectIds())
|
||||||
.eq(Objects.nonNull(dto.getType()), ChangeRecordConfirm::getType, dto.getType())
|
.eq(Objects.nonNull(dto.getType()), ChangeRecordConfirm::getType, dto.getType())
|
||||||
.eq(Objects.nonNull(dto.getBizType()), ChangeRecordConfirm::getBizType, dto.getBizType())
|
.eq(Objects.nonNull(dto.getBizType()), ChangeRecordConfirm::getBizType, dto.getBizType())
|
||||||
|
.in(CollectionUtils.isNotEmpty(dto.getBizTypes()), ChangeRecordConfirm::getBizType, dto.getBizTypes())
|
||||||
.in(CollectionUtils.isNotEmpty(dto.getVisaTypes()), ChangeRecordConfirm::getVisaType, dto.getVisaTypes())
|
.in(CollectionUtils.isNotEmpty(dto.getVisaTypes()), ChangeRecordConfirm::getVisaType, dto.getVisaTypes())
|
||||||
.eq(ChangeRecordConfirm::getIsDelete, 0);
|
.eq(ChangeRecordConfirm::getIsDelete, 0);
|
||||||
}
|
}
|
||||||
@ -450,10 +451,10 @@ public class ChangeRecordConfirmServiceImpl extends ServiceImpl<ChangeRecordConf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<VisaChangeApproveCreateReq.ApprovePersonInfo> listAllConfirmByVisaId(Long visaId) {
|
public List<VisaChangeApproveCreateReq.ApprovePersonInfo> listAllConfirmByVisaId(Long visaId, List<VisaConfirmBizTypeEnum> bizTypes) {
|
||||||
VisaConfirmDto dto = VisaConfirmDto.builder()
|
VisaConfirmDto dto = VisaConfirmDto.builder()
|
||||||
.visaId(visaId)
|
.visaId(visaId)
|
||||||
.bizType(VisaConfirmBizTypeEnum.CONFIRM).build();
|
.bizTypes(bizTypes).build();
|
||||||
List<ChangeRecordConfirm> list = this.findByCondition(dto);
|
List<ChangeRecordConfirm> list = this.findByCondition(dto);
|
||||||
if (CollectionUtils.isEmpty(list)) {
|
if (CollectionUtils.isEmpty(list)) {
|
||||||
return Lists.newArrayList();
|
return Lists.newArrayList();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user