diff --git a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/anonymous/DocAnonymousDatabaseApi.java b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/anonymous/DocAnonymousDatabaseApi.java index 93f83c8d..f49c1c98 100644 --- a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/anonymous/DocAnonymousDatabaseApi.java +++ b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/anonymous/DocAnonymousDatabaseApi.java @@ -12,7 +12,11 @@ import org.springframework.web.bind.annotation.RequestBody; 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.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.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 java.util.Map; @@ -39,6 +43,14 @@ public interface DocAnonymousDatabaseApi { @PostMapping("/api/anonymous/createFile") CommonResponse createFile(@RequestBody @Valid AnonymousCreateFileRequest request); + /** + * 创建新文件 + * + * @return 文件编码, 需要由业务存储 + */ + @PostMapping("/api/anonymous/createFile2") + CommonResponse createFile2(@RequestBody @Valid AnonymousCreateFileRequest request); + /** * 上传文件 * @@ -47,6 +59,14 @@ public interface DocAnonymousDatabaseApi { @PostMapping("/api/anonymous/uploadFile") CommonResponse uploadFile(@RequestBody @Valid AnonymousUploadFileRequest request); + /** + * 上传文件 + * + * @return 文件编码, 需要由业务存储 + */ + @PostMapping("/api/anonymous/uploadFile2") + CommonResponse uploadFile2(@RequestBody @Valid AnonymousUploadFileRequest request); + /** * 拷贝节点 (文件) * @@ -55,6 +75,24 @@ public interface DocAnonymousDatabaseApi { @PostMapping("/api/anonymous/copy") CommonResponse copy(@RequestBody @Valid CopyNodeRequest request); + /** + * 删除节点 (文件) + */ + @PostMapping("/api/anonymous/delete") + CommonResponse delete(@RequestBody @Valid DeleteNodeRequest request); + + /** + * 重命名节点 (文件) + */ + @PostMapping("/api/anonymous/rename") + CommonResponse rename(@RequestBody @Valid RenameNodeRequest request); + + /** + * 获取节点信息 + */ + @PostMapping("/api/anonymous/getNodeInfo") + CommonResponse getNodeInfo(@RequestBody @Valid GetNodeInfoRequest request); + /** * 批量获取节点信息集合 */ diff --git a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/anonymous/request/NodeCreateAnonymous.java b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/anonymous/request/NodeCreateAnonymous.java index 9cb6fefa..3a58ae07 100644 --- a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/anonymous/request/NodeCreateAnonymous.java +++ b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/anonymous/request/NodeCreateAnonymous.java @@ -38,6 +38,7 @@ abstract class NodeCreateAnonymous implements NodeCreate, IndexNodeScope { /** * 业务编码 */ + @NotBlank(message = "bizCode不能为空") private String bizCode; /** diff --git a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/domain/IndexNodeInfo.java b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/domain/IndexNodeInfo.java index 493aa1a9..170c9357 100644 --- a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/domain/IndexNodeInfo.java +++ b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/domain/IndexNodeInfo.java @@ -89,6 +89,11 @@ public class IndexNodeInfo implements NodeValue, ValueContainer { */ private String icon; + /** + * 文件的大小(bytes), 只有文件才存这个字段 + */ + private Integer size; + /** * 状态. VALID: 有效的 */ diff --git a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/domain/OssFile.java b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/domain/OssFile.java index 790a51a5..51e432df 100644 --- a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/domain/OssFile.java +++ b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/domain/OssFile.java @@ -4,7 +4,6 @@ package cn.axzo.nanopart.doc.api.domain; import com.alibaba.fastjson.JSON; import cn.axzo.nanopart.doc.api.enums.FileFormat; -import cn.axzo.nanopart.doc.api.util.BizAssertions; import lombok.Getter; import lombok.Setter; @@ -41,13 +40,6 @@ public class OssFile { return ossFile; } - public void validate() { - BizAssertions.assertNotNull(format, "format不能为空"); - BizAssertions.assertTrue(size > 0, "size必须大于0"); - BizAssertions.assertNotBlank(ossFileKey, "ossFileKey不能为空"); - BizAssertions.assertNotBlank(extension, "后缀不能为空"); - } - @Override public String toString() { return JSON.toJSONString(this); diff --git a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/enums/DatabaseScope.java b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/enums/DatabaseScope.java index 7d26433f..83fb55d4 100644 --- a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/enums/DatabaseScope.java +++ b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/enums/DatabaseScope.java @@ -26,6 +26,10 @@ public enum DatabaseScope { private final Boolean childNameDuplicatable; private final Boolean limitChildrenCount; + public boolean isFeeAware() { + return databaseType != DatabaseType.NONE; + } + public Integer getWorkspaceType() { if (this == ENT_DATABASE) return 1; diff --git a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/enums/FileFormat.java b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/enums/FileFormat.java index eff63b69..0e193663 100644 --- a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/enums/FileFormat.java +++ b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/enums/FileFormat.java @@ -17,7 +17,7 @@ public enum FileFormat { EXCEL(true, "Excel", "xlsx"), WORD(true, "Word", "docx"), PDF(false, "PDF", "pdf"), - PPT(false, "PPT", "pptx"); + PPT(true, "PPT", "pptx"); private final boolean creatable; private final String readableName; diff --git a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/file/IndexNodeApi.java b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/file/IndexNodeApi.java new file mode 100644 index 00000000..0b3aa53a --- /dev/null +++ b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/file/IndexNodeApi.java @@ -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 getNodeInfo(@RequestBody @Valid GetNodeInfoRequest request); + +} diff --git a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/filedb/response/FileDatabaseInfoResponse.java b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/filedb/response/FileDatabaseInfoResponse.java index 59b0ffc1..d7e89725 100644 --- a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/filedb/response/FileDatabaseInfoResponse.java +++ b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/filedb/response/FileDatabaseInfoResponse.java @@ -1,9 +1,11 @@ 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 cn.axzo.nanopart.doc.api.enums.DatabaseType; import cn.axzo.nanopart.doc.api.enums.FileDatabaseState; import cn.axzo.nanopart.doc.api.templatedb.domain.TemplateDatabaseInfo; import lombok.Getter; @@ -79,7 +81,7 @@ public class FileDatabaseInfoResponse { /** * 已使用的容量, 单位GB */ - private Integer usedCapacity; + private BigDecimal usedCapacity; /** * 资料库信息 diff --git a/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/index/request/GetNodeInfoRequest.java b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/index/request/GetNodeInfoRequest.java new file mode 100644 index 00000000..00813931 --- /dev/null +++ b/doc/doc-api/src/main/java/cn/axzo/nanopart/doc/api/index/request/GetNodeInfoRequest.java @@ -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; + +} diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/dao/FileDatabaseDao.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/dao/FileDatabaseDao.java index 6c27210b..9711b852 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/dao/FileDatabaseDao.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/dao/FileDatabaseDao.java @@ -1,6 +1,7 @@ package cn.axzo.nanopart.doc.dao; +import java.math.BigDecimal; import java.util.Date; import org.springframework.stereotype.Repository; @@ -19,9 +20,10 @@ import cn.axzo.nanopart.doc.mapper.FileDatabaseMapper; @Repository public class FileDatabaseDao extends ServiceImpl { - public FileDatabase findForUpdateOrNull(DatabaseScope scope, String scopeUniqueCode) { + public FileDatabase findForUpdateOrNull(DatabaseScope scope, String templateDatabaseCode, String scopeUniqueCode) { return lambdaQuery() // .eq(FileDatabase::getScope, scope) // + .eq(FileDatabase::getTemplateDatabaseCode, templateDatabaseCode) // .eq(FileDatabase::getScopeUniqueCode, scopeUniqueCode) // .last("FOR UPDATE") // .one(); @@ -61,10 +63,11 @@ public class FileDatabaseDao extends ServiceImpl { .update(); } - public List collectValidSubtreeNodes(IndexNode indexNode) { + public List collectValidSubtreeNodes(IndexNode indexNode, IndexNodeType... nodeTypes) { return lambdaQuery() // .likeRight(IndexNode::getPath, indexNode.getPath()) // .eq(IndexNode::getState, IndexNodeState.VALID) // + .in(nodeTypes.length > 0, IndexNode::getNodeType, Arrays.asList(nodeTypes)) // .list(); } diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/dao/TemplateDatabaseDao.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/dao/TemplateDatabaseDao.java index 7a4c670f..670af545 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/dao/TemplateDatabaseDao.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/dao/TemplateDatabaseDao.java @@ -3,6 +3,7 @@ package cn.axzo.nanopart.doc.dao; import java.util.List; +import cn.axzo.nanopart.doc.api.util.BizAssertions; import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Repository; @@ -18,6 +19,12 @@ import cn.axzo.nanopart.doc.mapper.TemplateDatabaseMapper; @Repository public class TemplateDatabaseDao extends ServiceImpl { + public TemplateDatabase getOrThrow(String code) { + TemplateDatabase templateDb = findOrNull(code); + BizAssertions.assertNotNull(templateDb, "找不到资料库: {}", code); + return templateDb; + } + public TemplateDatabase findOrNull(String code) { return lambdaQuery().eq(TemplateDatabase::getCode, code).one(); } diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/entity/FileDatabase.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/entity/FileDatabase.java index e67140a3..9de5abd8 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/entity/FileDatabase.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/entity/FileDatabase.java @@ -1,6 +1,7 @@ package cn.axzo.nanopart.doc.entity; +import java.math.BigDecimal; import java.util.Date; import com.alibaba.fastjson.JSON; @@ -76,7 +77,12 @@ public class FileDatabase extends BaseEntity implements IndexNodeS /** * 已使用的容量, 单位GB */ - private Integer usedCapacity; + private BigDecimal usedCapacity; + + /** + * 已使用的容量, 单位kb + */ + private Integer usedCapacityKb; public boolean isActivated() { return state == FileDatabaseState.ACTIVATED; diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/entity/TemplateDatabase.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/entity/TemplateDatabase.java index 87f5bba6..b890d0e4 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/entity/TemplateDatabase.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/entity/TemplateDatabase.java @@ -1,6 +1,8 @@ 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.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; @@ -56,6 +58,10 @@ public class TemplateDatabase extends BaseEntity implements In @TableField(typeHandler = FastjsonTypeHandler.class) private DatabaseAccessConfig accessConfig; + public FileTemplateFeeType getFeeType() { + return feeConfig == null ? null : feeConfig.getFeeType(); + } + @Override public String indexNodeCode() { return code; diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/BizCodeGenerator.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/BizCodeGenerator.java index fa649810..bc1beef5 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/BizCodeGenerator.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/BizCodeGenerator.java @@ -25,7 +25,6 @@ public class BizCodeGenerator { .append(create.nodeScope().scope() == DatabaseScope.ENT_DATABASE ? "ent" : "pro") // .append(nodeType == IndexNodeType.DATABASE ? "space" : "folder") // .append(create.nodeScope().context() == IndexNodeContext.TEMPLATE_DATABASE ? "oms" : workspaceId) // - .append("") // .build(); create.setBizCode(bizCode); } diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/anonymous/DocAnonymousDatabaseApiController.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/anonymous/DocAnonymousDatabaseApiController.java index af725866..38ad7894 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/anonymous/DocAnonymousDatabaseApiController.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/anonymous/DocAnonymousDatabaseApiController.java @@ -19,12 +19,17 @@ import org.apache.commons.collections4.CollectionUtils; import org.springframework.util.StringUtils; 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.request.AnonymousCreateDirRequest; import cn.axzo.nanopart.doc.api.anonymous.request.AnonymousCreateFileRequest; 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.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.file.index.IndexManager; import cn.axzo.nanopart.doc.utils.AsyncUtils; @@ -57,13 +62,26 @@ public class DocAnonymousDatabaseApiController implements DocAnonymousDatabaseAp return CommonResponse.success(indexManager.createFile(request, ossFile).getCode()); } + @Override + public CommonResponse 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 public CommonResponse uploadFile(AnonymousUploadFileRequest request) { log.info("upload file request:{}", request); - request.getOssFile().validate(); return CommonResponse.success(indexManager.uploadFile(request, request.getOssFile()).getCode()); } + @Override + public CommonResponse 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 public CommonResponse copy(CopyNodeRequest request) { log.info("copy request:{}", request); @@ -71,6 +89,26 @@ public class DocAnonymousDatabaseApiController implements DocAnonymousDatabaseAp return CommonResponse.success(asyncUtils.getOrTimeout(future, 60, "克隆").getCode()); } + @Override + public CommonResponse delete(DeleteNodeRequest request) { + log.info("delete request:{}", request); + indexManager.delete(request.getCode()); + return CommonResponse.success(); + } + + @Override + public CommonResponse rename(RenameNodeRequest request) { + log.info("rename request:{}", request); + indexManager.rename(request.getCode(), request.getNewName()); + return CommonResponse.success(); + } + + @Override + public CommonResponse getNodeInfo(GetNodeInfoRequest request) { + IndexNode indexNode = indexManager.getOrThrow(request.getCode()); + return CommonResponse.success(BeanMapper.copyBean(indexNode, IndexNodeInfo.class)); + } + /** * 批量获取节点信息集合 */ diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filedb/FileDatabaseExpireJob.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filedb/FileDatabaseExpireJob.java index d6781eb2..4368ac71 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filedb/FileDatabaseExpireJob.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filedb/FileDatabaseExpireJob.java @@ -1,17 +1,10 @@ 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.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 org.springframework.stereotype.Component; /** * @author yanglin @@ -21,14 +14,11 @@ import lombok.RequiredArgsConstructor; @SuppressWarnings({ "unused", "used by job" }) public class FileDatabaseExpireJob { - private final FileDatabaseDao fileDatabaseDao; + private final FileDatabaseService fileDatabaseService; @XxlJob("fileDatabaseExpireJob") public ReturnT exec(String paramStr) { - fileDatabaseDao.lambdaUpdate() // - .eq(FileDatabase::getState, FileDatabaseState.ACTIVATED) // - .le(FileDatabase::getExpireDate, new Date()) // - .update(); + fileDatabaseService.expire(); return ReturnT.SUCCESS; } diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filedb/FileDatabaseService.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filedb/FileDatabaseService.java index 0bc1372a..067269c5 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filedb/FileDatabaseService.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filedb/FileDatabaseService.java @@ -3,6 +3,8 @@ package cn.axzo.nanopart.doc.file.filedb; import static java.util.stream.Collectors.toList; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.Arrays; import java.util.Date; 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.maokai.api.vo.response.tree.ValueNode; 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.enums.DatabaseScope; import cn.axzo.nanopart.doc.api.enums.DatabaseType; 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.filedb.request.FileDatabaseAbortRequest; import cn.axzo.nanopart.doc.api.filedb.request.FileDatabaseActiveRequest; @@ -88,26 +93,26 @@ public class FileDatabaseService { private FileDatabase addWorkspace0(FileDatabaseAddWorkspaceRequest request) { String scopeUniqueCode = String.valueOf(request.getWorkspaceId()); - TemplateDatabase templateDatabase = templateDatabaseQueryService.getOrThrow(request.getTemplateDatabaseCode()); - FileDatabase savedDb = fileDatabaseDao.findForUpdateOrNull(templateDatabase.getScope(), scopeUniqueCode); + TemplateDatabase templateDb = templateDatabaseQueryService.getOrThrow(request.getTemplateDatabaseCode()); + FileDatabase savedDb = fileDatabaseDao.findForUpdateOrNull(templateDb.getScope(), templateDb.getCode(), + scopeUniqueCode); if (savedDb != null) throw new FileDatabaseExistsException("无法重复创建, 请刷新页面查询已创建的记录"); SimpleWorkspaceRes workspace = RpcExternalUtil.rpcApolloProcessor( () -> workspaceApi.getOne(request.getWorkspaceId()), "查询租户", request.getWorkspaceId()); BizAssertions.assertNotNull(workspace, "找不到对应的租户"); - BizAssertions.assertEquals(workspace.getType(), templateDatabase.getScope().getWorkspaceType(), - "请求租户类型和资料库的租户类型不匹配"); + BizAssertions.assertEquals(workspace.getType(), templateDb.getScope().getWorkspaceType(), "请求租户类型和资料库的租户类型不匹配"); FileDatabase db = new FileDatabase(); db.setCode(UUIDUtil.uuidString()); - db.setTemplateDatabaseCode(templateDatabase.getCode()); - db.setScope(templateDatabase.getScope()); + db.setTemplateDatabaseCode(templateDb.getCode()); + db.setScope(templateDb.getScope()); db.setScopeUniqueCode(scopeUniqueCode); db.setWorkspaceId(request.getWorkspaceId()); db.setState(FileDatabaseState.ACTIVATING); - if (request.getExpiredDateMs() != null) + if (templateDb.getFeeType() == FileTemplateFeeType.ANNUAL && request.getExpiredDateMs() != null) db.setExpireDate(new Date(request.getExpiredDateMs())); db.setAllowedCapacity(request.getAllowedCapacity()); - db.setUsedCapacity(0); + db.setUsedCapacity(BigDecimal.ZERO); db.setCreateAt(new Date()); db.setUpdateAt(new Date()); fileDatabaseDao.save(db); @@ -140,7 +145,8 @@ public class FileDatabaseService { public WalkingDecision visit(ValueNode node) { WalkingDecision walkingDecision = super.visit(node); IndexNode indexNode = node.getValue(); - BizCodeGenerator.gen(indexNode, indexNode.getNodeType(), db.getWorkspaceId()); + if (indexNode.isDatabase() || indexNode.isDirectory()) + BizCodeGenerator.gen(indexNode, indexNode.getNodeType(), db.getWorkspaceId()); return walkingDecision; } }); @@ -167,14 +173,16 @@ public class FileDatabaseService { @BizTransactional public void fileSizeChanged(String indexNodeCode) { IndexNode indexNode = indexManager.findOrNull(indexNodeCode); - if (indexNode == null || !indexNode.isFile()) + if (indexNode == null || !indexNode.isFile() || indexNode.context() != IndexNodeContext.FILE_DATABASE) return; FileDatabase db = fileDatabaseDao.findForUpdateOrNull(indexNode.scopeCode()); if (db == null) return; - int usedFileSize = indexQueryService.getUsedFileSize(db); - fileDatabaseDao.updateUsedCapacity(db.getCode(), usedFileSize); - if (db.isActivated() && db.getAllowedCapacity() <= usedFileSize) + int sizeByte = indexQueryService.getUsedFileSize(db); + BigDecimal sizeGb = BigDecimal.valueOf(sizeByte) // + .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); } @@ -184,21 +192,31 @@ public class FileDatabaseService { FileDatabase db = fileDatabaseDao.getForUpdateOrThrow(request.getCode()); updateCapacity(request) // .set(FileDatabase::getState, // - request.getAllowedCapacity() <= db.getUsedCapacity() // + isCapacityExhausted(request.getAllowedCapacity(), db.getUsedCapacity()) // ? FileDatabaseState.CAPACITY_EXHAUSTED // : FileDatabaseState.ACTIVATED) // .update(); } + private boolean isCapacityExhausted(Integer allowedCapacity, BigDecimal usedCapacity) { + return BigDecimal.valueOf(allowedCapacity).compareTo(usedCapacity) <= 0; + } + @BizTransactional public void expandCapacity(FileDatabaseExpandCapacityRequest request) { docLogDao.logRequest("expandCapacity", request.getCode(), request); FileDatabase db = fileDatabaseDao.getForUpdateOrThrow(request.getCode()); BizAssertions.assertTrue(db.isActivated(), "只有激活状态的资料库才能扩容"); + DatabaseFeeConfig feeConfig = templateDatabaseQueryService.getOrThrow( + db.getTemplateDatabaseCode()).getFeeConfig(); + if (feeConfig != null) + BizAssertions.assertTrue(feeConfig.getExtendable(), "资料库不支持扩容"); updateCapacity(request).update(); } private LambdaUpdateChainWrapper updateCapacity(FileDatabaseActiveRequest request) { + FileDatabase db = fileDatabaseDao.getOrThrow(request.getCode()); + TemplateDatabase templateDb = templateDatabaseQueryService.getOrThrow(db.getTemplateDatabaseCode()); Date expireDate = null; if (request.getExpiredDateMs() != null && request.getExpiredDateMs() > 0) expireDate = new Date(request.getExpiredDateMs()); @@ -206,7 +224,8 @@ public class FileDatabaseService { .eq(FileDatabase::getCode, request.getCode()) // .set(FileDatabase::getAllowedCapacity, request.getAllowedCapacity()) // .set(FileDatabase::getPurchaseDate, new Date()) // - .set(expireDate != null, FileDatabase::getExpireDate, expireDate); + .set(templateDb.getFeeType() == FileTemplateFeeType.ANNUAL && expireDate != null, + FileDatabase::getExpireDate, expireDate); } @BizTransactional @@ -294,4 +313,8 @@ public class FileDatabaseService { .collect(toList()); return Page.toPage(request.getPage(), request.getPageSize(), page.getTotal(), records); } + + public void expire() { + this.fileDatabaseDao.expire(); + } } diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filetemplate/FileTemplateApiController.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filetemplate/FileTemplateApiController.java index 9c024b83..808da5ba 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filetemplate/FileTemplateApiController.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filetemplate/FileTemplateApiController.java @@ -67,7 +67,6 @@ public class FileTemplateApiController implements FileTemplateApi { @Override public CommonResponse uploadFile(FileTemplateUploadFileRequest request) { log.info("upload file request:{}", request); - request.getOssFile().validate(); return CommonResponse.success(fileTemplateManager.uploadFile(request)); } diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filetemplate/FileTemplateManager.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filetemplate/FileTemplateManager.java index 7f575b3e..b4e1f2fb 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filetemplate/FileTemplateManager.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/filetemplate/FileTemplateManager.java @@ -1,13 +1,16 @@ package cn.axzo.nanopart.doc.file.filetemplate; +import java.util.ArrayList; import java.util.List; +import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; import org.springframework.transaction.support.TransactionTemplate; import cn.axzo.nanopart.doc.api.domain.OssFile; 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.filetemplate.request.FileTemplateCreateDirRequest; 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.IndexNode; 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.utils.BizTransactional; import lombok.RequiredArgsConstructor; @@ -27,11 +31,11 @@ import lombok.RequiredArgsConstructor; */ @Component @RequiredArgsConstructor -public class FileTemplateManager { +public class FileTemplateManager implements ApplicationListener { private final IndexManager indexManager; private final FileTemplateDao fileTemplateDao; - private final TransactionTemplate transactionTemplate; + private final TransactionTemplate transaction; public String createDir(FileTemplateCreateDirRequest request) { return indexManager.createDir(request).getCode(); @@ -39,7 +43,7 @@ public class FileTemplateManager { public String createFile(FileTemplateCreateFileRequest request) { 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 @@ -48,11 +52,16 @@ public class FileTemplateManager { } 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.setCode(fileNode.getCode()); fileTemplate.setState(FileTemplateState.UNPUBLISH); - fileTemplateDao.save(fileTemplate); - return fileNode.getCode(); + return fileTemplate; } @BizTransactional @@ -81,4 +90,16 @@ public class FileTemplateManager { .set(request.getState() != null, FileTemplate::getState, request.getState()) // .update(); } + + @Override + public void onApplicationEvent(SubtreeCopyEventTransactional event) { + if (event.getCopiedRoot().getContext() != IndexNodeContext.FILE_TEMPLATE) + return; + ArrayList fileTemplates = new ArrayList<>(); + for (IndexNode fileNode : indexManager.collectValidSubtreeNodes(event.getCopiedRoot(), IndexNodeType.FILE)) + fileTemplates.add(buildFileTemplate(fileNode)); + if (!fileTemplates.isEmpty()) + fileTemplateDao.saveBatch(fileTemplates); + } + } diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/IndexManager.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/IndexManager.java index 1b7bf93f..5fdd76c4 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/IndexManager.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/IndexManager.java @@ -8,6 +8,7 @@ import java.util.concurrent.Future; import javax.annotation.Nullable; import org.apache.commons.lang3.StringUtils; +import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.transaction.support.TransactionTemplate; @@ -52,16 +53,17 @@ public class IndexManager { private final FileBroadcaster fileBroadcaster; private final TransactionTemplate transaction; private final DocLogDao docLogDao; + private final ApplicationContext applicationContext; @BizTransactional public IndexNode createDatabase(NodeCreate create) { - ensureChildNameNotUsed(create, IndexNodeType.DATABASE, true); + indexSupport.ensureChildNameNotUsed(create, IndexNodeType.DATABASE, true); return indexSupport.createNode(create, IndexNodeType.DATABASE); } @BizTransactional public IndexNode createDir(NodeCreate create) { - ensureChildNameNotUsed(create, IndexNodeType.DIRECTORY, true); + indexSupport.ensureChildNameNotUsed(create, IndexNodeType.DIRECTORY, true); return indexSupport.createNode(create, IndexNodeType.DIRECTORY); } @@ -69,7 +71,7 @@ public class IndexManager { BizAssertions.assertTrue(format.creatable(), "无法创建: {}", format.readableName()); BizAssertions.assertFalse(TransactionSynchronizationManager.isActualTransactionActive(), "不能在事务中使用"); // 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 emptyOssFileKey = format == FileFormat.WORD // ? docProps.getCreateFileOssFileKeyWord() // @@ -83,9 +85,10 @@ public class IndexManager { @BizTransactional public IndexNode uploadFile(NodeCreate node, OssFile ossFile) { BizAssertions.assertNotNull(ossFile.getFormat(), "format不能为空"); - BizAssertions.assertTrue(ossFile.getSize() > 0, "size必须大于0"); BizAssertions.assertNotBlank(ossFile.getOssFileKey(), "oosFileKey不能为空"); BizAssertions.assertNotBlank(ossFile.getExtension(), "extension不能为空"); + if (node.nodeScope().scope().isFeeAware()) + BizAssertions.assertTrue(ossFile.getSize() >= 0, "size必须大于等于0"); IndexNode fileNode = createFile(node, ossFile); updateFileSize(fileNode, ossFile.getSize()); return fileNode; @@ -93,7 +96,7 @@ public class IndexManager { @BizTransactional public void updateFileSize(IndexNode fileNode, int size) { - if (fileNode == null || !fileNode.isFile()) + if (fileNode == null || !fileNode.isFile() || size < 0) return; indexNodeDao.updateFileSize(fileNode.getCode(), size); fileBroadcaster.fireFileSizeChanged(fileNode.getCode()); @@ -105,7 +108,7 @@ public class IndexManager { return transaction.execute(unused -> { try { // check with lock - ensureChildNameNotUsed(create, IndexNodeType.FILE, true); + indexSupport.ensureChildNameNotUsed(create, IndexNodeType.FILE, true); } catch (NameUsedException e) { 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 public void rename(String code, String newName) { IndexNode indexNode = getOrThrow(code); @@ -158,7 +153,7 @@ public class IndexManager { public List delete(String code) { IndexNode indexNode = getOrThrow(code); docLogDao.log("indexNode:delete", code); - List subtree = indexNodeDao.collectValidSubtreeNodes(indexNode); + List subtree = collectValidSubtreeNodes(indexNode); indexNodeDao.stateDeleteSubtree(indexNode); return subtree; } @@ -176,7 +171,7 @@ public class IndexManager { IndexNode srcNode = getOrThrow(srcCode); BizAssertions.assertTrue(indexNodeDao.validSubtreeFileCount(srcNode) <= docProps.getIndexNodeMaxCopyFileSize(), "拷贝文件数超过限制: {}", docProps.getIndexNodeMaxCopyFileSize()); - IndexNode destParentNode = determineDestParentNode(srcNode, destParentCode, "克隆"); + IndexNode destParentNode = determineDestParentNode(srcNode, destParentCode, Op.COPY); return async(() -> { // don't inline in transaction CopyFileVisitor copyNodeVisitor = new CopyFileVisitor(copySubtreeOssFiles(srcNode)); @@ -193,7 +188,7 @@ public class IndexManager { */ public Future asyncMove(String srcCode, @Nullable String destParentCode) { IndexNode srcNode = getOrThrow(srcCode); - IndexNode destParentNode = determineDestParentNode(srcNode, destParentCode, "移动"); + IndexNode destParentNode = determineDestParentNode(srcNode, destParentCode, Op.MOVE); return async(() -> transaction.execute(unused -> { docLogDao.log("indexNode:asyncMove", srcCode, "srcCode", srcCode, "destParentCode", destParentCode); 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); if (parent == null) return null; BizAssertions.assertFalse(srcNode.isDirectory() && parent.isFile(), "不能{}文件夹到文件下", op); - BizAssertions.assertFalse(srcNode.isSameNodeWith(parent), "不能{}到同一节点下", op); BizAssertions.assertFalse(srcNode.isParentOf(parent), "不能{}到子节点下", op); + if (op == Op.MOVE) + BizAssertions.assertFalse(srcNode.isSameNodeWith(parent), "不能{}到同一节点下", op); List subtreeNodes = indexSupport.collectValidSubtreeAsValueRoot(srcNode); - int subtreeMaxDepth = IndexNodeTreeUtils.build(subtreeNodes).getChildren().stream() // + int subtreeMaxDepth = IndexNodeTreeUtils.build(subtreeNodes).getValueNodes().stream() // .mapToInt(Node::getLevel) // .max() // .orElse(0); + // 这里不加1, 因为root node其实不是真实的值节点, 不用算在内 indexSupport.validateDepthWhenAddChild(parent.path().depth() + subtreeMaxDepth); return parent; } @@ -226,7 +223,9 @@ public class IndexManager { RootNode srcRoot = TreeUtils.transform(subtreeNodes, IndexNode.class, true); srcRoot.walkDown(copyNodeVisitor); 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()); } + public List collectValidSubtreeNodes(IndexNode indexNode, IndexNodeType... nodeTypes) { + return indexNodeDao.collectValidSubtreeNodes(indexNode, nodeTypes); + } + public IndexNode findOrNull(String code) { if (StringUtils.isBlank(code)) return null; @@ -280,4 +283,14 @@ public class IndexManager { }); } + @RequiredArgsConstructor + private enum Op { + MOVE("移动"), COPY("克隆"); + private final String name; + + @Override + public String toString() { + return name; + } + } } diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/IndexNodeApiController.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/IndexNodeApiController.java new file mode 100644 index 00000000..166a40c8 --- /dev/null +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/IndexNodeApiController.java @@ -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 getNodeInfo(GetNodeInfoRequest request) { + IndexNode indexNode = indexManager.getOrThrow(request.getCode()); + return CommonResponse.success(BeanMapper.copyBean(indexNode, IndexNodeInfo.class)); + } + +} diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/IndexSupport.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/IndexSupport.java index c9435f11..ee37d3ff 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/IndexSupport.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/IndexSupport.java @@ -100,8 +100,8 @@ public class IndexSupport { "创建失败, 子节点数量不能超过 {}", docProps.getIndexNodeMaxChildrenSize()); } - public void validateDepthWhenAddChild(int pendingDepth) { - BizAssertions.assertTrue(pendingDepth >= docProps.getIndexNodeMaxDepth(), // + public void validateDepthWhenAddChild(int targetDepth) { + BizAssertions.assertTrue(targetDepth <= docProps.getIndexNodeMaxDepth(), // "节点深度超过限制{}, 无法再创建新节点", docProps.getIndexNodeMaxDepth()); } @@ -134,6 +134,14 @@ public class IndexSupport { 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) { IndexNode child = indexNodeDao.findValidChildByName(parentScope, nodeType, childName); // don't use BizAssertions.assertNull diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/SubtreeCopyEventTransactional.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/SubtreeCopyEventTransactional.java new file mode 100644 index 00000000..e1a0c8ed --- /dev/null +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/SubtreeCopyEventTransactional.java @@ -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; + } + +} diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/domain/IndexNodes.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/domain/IndexNodes.java index bd29479a..f3e3af5c 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/domain/IndexNodes.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/index/domain/IndexNodes.java @@ -29,6 +29,12 @@ public class IndexNodes { .collect(toList()); } + public List collectNodes(IndexNodeType nodeType) { + return indexNodes.stream() // + .filter(node -> node.getNodeType() == nodeType) // + .collect(toList()); + } + public IndexNode findOrNull(String code) { return indexNodes.stream() // .filter(node -> node.getCode().equals(code)) // diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/templatedb/TemplateDatabaseApiController.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/templatedb/TemplateDatabaseApiController.java index 98dde3d0..f7927601 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/templatedb/TemplateDatabaseApiController.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/templatedb/TemplateDatabaseApiController.java @@ -78,7 +78,6 @@ public class TemplateDatabaseApiController implements TemplateDatabaseApi { @Override public CommonResponse uploadFile(TemplateDatabaseUploadFileRequest request) { log.info("upload file request:{}", request); - request.getOssFile().validate(); return CommonResponse.success(templateDatabaseManager.updateFile(request)); } diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/templatedb/TemplateDatabaseManager.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/templatedb/TemplateDatabaseManager.java index d4be996a..091691b8 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/templatedb/TemplateDatabaseManager.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/file/templatedb/TemplateDatabaseManager.java @@ -4,11 +4,13 @@ package cn.axzo.nanopart.doc.file.templatedb; import java.util.Date; import org.apache.commons.lang3.StringUtils; +import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSON; 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.index.request.DeleteNodeRequest; 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.file.BizCodeGenerator; 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.utils.BizTransactional; import lombok.RequiredArgsConstructor; @@ -32,7 +35,7 @@ import lombok.RequiredArgsConstructor; */ @Component @RequiredArgsConstructor -public class TemplateDatabaseManager { +public class TemplateDatabaseManager implements ApplicationListener { private final IndexManager indexManager; private final TemplateDatabaseDao templateDatabaseDao; @@ -110,4 +113,19 @@ public class TemplateDatabaseManager { .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); + } } diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/utils/AsyncUtils.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/utils/AsyncUtils.java index f7cac92a..c4cec7da 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/utils/AsyncUtils.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/utils/AsyncUtils.java @@ -35,7 +35,7 @@ public class AsyncUtils { return result; } catch (CannotAcquireLockException e) { - String message = String.format("%s等待超时, 可能正在移动节点, 请稍后刷新页面重试", op); + String message = String.format("%s等待超时, 请稍后重试", op); log.warn(message, e); throw fail(message); } diff --git a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/wpsbase/WpsBaseManager.java b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/wpsbase/WpsBaseManager.java index 89359ffe..80be71cc 100644 --- a/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/wpsbase/WpsBaseManager.java +++ b/doc/doc-server/src/main/java/cn/axzo/nanopart/doc/wps/wpsbase/WpsBaseManager.java @@ -1,8 +1,18 @@ package cn.axzo.nanopart.doc.wps.wpsbase; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import com.google.common.collect.Lists; + import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.basics.profiles.dto.basic.PersonProfileDto; import cn.axzo.nanopart.doc.api.enums.WpsErrorCodeEnum; +import cn.axzo.nanopart.doc.api.wps.exception.WpsException; import cn.axzo.nanopart.doc.api.wps.request.WpsPermissionRequest; import cn.axzo.nanopart.doc.api.wps.request.WpsRenameRequest; import cn.axzo.nanopart.doc.api.wps.request.WpsUsersRequest; @@ -12,8 +22,9 @@ 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.WpsUsersResponse; 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.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.DocUserProfileGateway; import cn.axzo.nanopart.doc.wps.support.WpsAssertUtil; @@ -23,14 +34,7 @@ import cn.axzo.oss.http.model.ApiSignUrlDownloadResponse; import cn.axzo.oss.http.model.file.UpdateFileInfoRequest; import cn.axzo.oss.http.model.file.UpdateFileInfoResponse; import cn.hutool.core.collection.CollectionUtil; -import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.StringUtils; -import org.springframework.stereotype.Component; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; /** * wps对接基础信息 @@ -41,7 +45,7 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class WpsBaseManager { - private final IndexNodeDao indexNodeDao; + private final IndexManager indexManager; private final DocOssGateway docOssGateway; private final DocUserProfileGateway docUserProfileGateway; @@ -101,7 +105,7 @@ public class WpsBaseManager { * 暂时全部开放权限,REQ-35401期只是OMS没有文件权限功能,待REQ-3540的2期建立权限后,再对接 */ public WpsPermissionResponse permission(WpsPermissionRequest request) { - IndexNode indexNode = indexNodeDao.findOrNull(request.getDocCode()); + IndexNode indexNode = indexManager.findOrNull(request.getDocCode()); if (StringUtils.isNotBlank(indexNode.getOrCreateFileAttributes().getFileExtension()) && indexNode.getOrCreateFileAttributes().getFileExtension().equalsIgnoreCase("pdf")) { @@ -152,13 +156,11 @@ public class WpsBaseManager { || StringUtils.isBlank(node.getAttributes().getFileAttributes().getOssFileKey())) { return WpsRenameResponse.builder().updateFlag(false).build(); } - //TODO: 文件名重复 - //try { - // 调用IndexManager.rename(); - //} catch (NameUsedException e) { - // // 处理文件已被使用的情况 - //} - indexNodeDao.rename(request.getDocCode(), request.getName()); + try { + indexManager.rename(node.getCode(), request.getName()); + } catch (NameUsedException e) { + throw new WpsException(WpsErrorCodeEnum.FILE_NAME_CONFLICT); + } UpdateFileInfoResponse response = this.docOssGateway.updateFileInfo(UpdateFileInfoRequest.builder().fileKey(node.getAttributes().getFileAttributes().getOssFileKey()).build()); return WpsRenameResponse.builder().updateFlag(response.isUpdateFlag()).build(); } diff --git a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/GuideTenantProcedureStatusServiceImpl.java b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/GuideTenantProcedureStatusServiceImpl.java index d51afc66..a2c8a34a 100644 --- a/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/GuideTenantProcedureStatusServiceImpl.java +++ b/op/op-server/src/main/java/cn/axzo/nanopart/server/service/impl/GuideTenantProcedureStatusServiceImpl.java @@ -62,40 +62,41 @@ public class GuideTenantProcedureStatusServiceImpl extends ServiceImpl procedureStatusList.size()) { - // 将该租户未初始化的步骤点进行初始化 - List procedureStatusIdList = procedureStatusList.stream().map(GuideTenantProcedureStatus::getProcedureId).collect(Collectors.toList()); - respList.addAll(templateList.stream() - .filter(t -> !procedureStatusIdList.contains(t.getId())) - .map(t -> { - GuideTenantProcedureStatusCreateReq createReq = new GuideTenantProcedureStatusCreateReq(); - createReq.setWorkspaceId(req.getWorkspaceId()); - createReq.setCategoryCode(t.getCategoryCode()); - createReq.setProcedureId(t.getId()); - createReq.setProcedureName(t.getName()); - createReq.setStatus(GuideProcedureStatus.TODO); - create(createReq); - return BeanUtil.copyProperties(createReq, GuideTenantProcedureStatusListResp.class); - }) - .collect(Collectors.toList())); - } else if (templateList.size() < procedureStatusList.size()) { - log.warn("操作步骤模板:{},租户&分类:{},租户操作步骤状态:{}", JSONUtil.toJsonStr(templateList), JSONUtil.toJsonStr(req), JSONUtil.toJsonStr(procedureStatusList)); - throw new ServiceException("数据异常,操作步骤不存在,请联系管理人员"); + // 将租户操作步骤数量与模板操作步骤数量进行对比,是否需要根据模板为租户初始化新步骤点 + // 将该租户未初始化的步骤点进行初始化 + List procedureStatusIdList = procedureStatusList.stream().map(GuideTenantProcedureStatus::getProcedureId).distinct().collect(Collectors.toList()); + List newInitProcedures = templateList.stream() + .filter(t -> !procedureStatusIdList.contains(t.getId())) + .map(t -> { + GuideTenantProcedureStatusCreateReq createReq = new GuideTenantProcedureStatusCreateReq(); + createReq.setWorkspaceId(req.getWorkspaceId()); + createReq.setCategoryCode(t.getCategoryCode()); + createReq.setProcedureId(t.getId()); + createReq.setProcedureName(t.getName()); + createReq.setStatus(GuideProcedureStatus.TODO); + create(createReq); + return BeanUtil.copyProperties(createReq, GuideTenantProcedureStatusListResp.class); + }) + .collect(Collectors.toList()); + if (CollUtil.isNotEmpty(newInitProcedures)) { + respList.addAll(newInitProcedures); } // 对租户操作步骤的权限码和跳转链接进行补充 Map templateMap = templateList.stream().collect(Collectors.toMap(GuideProcedureTemplateResp::getId, Function.identity(), (v1, v2) -> v1)); - respList.forEach(r -> { - GuideProcedureTemplateResp t = templateMap.get(r.getProcedureId()); - r.setDescription(t.getDescription()); - r.setIsMust(t.getIsMust()); - r.setAuthCode(t.getAuthCode()); - r.setJumpUrl(t.getJumpUrl()); - r.setJumpReport(t.getJumpReport()); - r.setSort(t.getSort()); - }); - return respList; + 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()); + r.setDescription(t.getDescription()); + r.setIsMust(t.getIsMust()); + r.setAuthCode(t.getAuthCode()); + r.setJumpUrl(t.getJumpUrl()); + r.setJumpReport(t.getJumpReport()); + r.setSort(t.getSort()); + }) + .collect(Collectors.toList()); } @Override @@ -127,12 +128,15 @@ public class GuideTenantProcedureStatusServiceImpl extends ServiceImpl> getVisaAllConfirm(FetchVisaAllConfirmReq req) { - return ApiResult.ok(changeRecordConfirmService.listAllConfirmByVisaId(req.getVisaId())); + return ApiResult.ok(changeRecordConfirmService.listAllConfirmByVisaId(req.getVisaId(), Lists.newArrayList(VisaConfirmBizTypeEnum.CONFIRM))); } @Override diff --git a/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/dto/VisaConfirmDto.java b/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/dto/VisaConfirmDto.java index 23edf2f1..c54b48cc 100644 --- a/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/dto/VisaConfirmDto.java +++ b/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/dto/VisaConfirmDto.java @@ -46,6 +46,8 @@ public class VisaConfirmDto { */ private VisaConfirmBizTypeEnum bizType; + private List bizTypes; + /** * 确认人 */ diff --git a/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/mq/listener/workflow/process/ProcessInstanceOfVisaAllEventHandler.java b/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/mq/listener/workflow/process/ProcessInstanceOfVisaAllEventHandler.java index dcd78529..6c465b29 100644 --- a/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/mq/listener/workflow/process/ProcessInstanceOfVisaAllEventHandler.java +++ b/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/mq/listener/workflow/process/ProcessInstanceOfVisaAllEventHandler.java @@ -1,11 +1,14 @@ 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.EventConsumer; import cn.axzo.framework.rocketmq.EventProducer; import cn.axzo.msg.center.api.MessageAPIV3; 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.nanopart.visa.api.enums.VisaConfirmBizTypeEnum; import cn.axzo.nanopart.visa.api.enums.VisaStampStatusEnum; import cn.axzo.nanopart.visa.api.enums.VisaStatusEnum; 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.rpc.VisaOrganizationalNodeUserGateway; 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.ChangeRecordService; import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.common.model.response.mq.ProcessInstanceDTO; import cn.axzo.workflow.starter.handler.ProcessInstanceEventHandler; +import cn.azxo.framework.common.model.CommonResponse; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; import org.apache.groovy.util.Maps; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; @@ -35,6 +41,7 @@ import java.util.Date; import java.util.List; import java.util.Map; 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_WORKSPACE_NAME; @@ -54,11 +61,13 @@ import static cn.axzo.nanopart.visa.api.enums.VisaTypeEnum.TECHNOLOGY_APPROVED; * @author wangli * @since 2025-01-17 11:35 */ +@Slf4j @Component public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implements ProcessInstanceEventHandler { protected final ChangeRecordService changeRecordService; protected final ChangeRecordRelationService changeRecordRelationService; protected final ChangeRecordBillService changeRecordBillService; + protected final ChangeRecordConfirmService changeRecordConfirmService; protected final MessageAPIV3 noticeApi; public final static List SUPPORTED_DEFINITION_KEYS = Lists.newArrayList( DESIGN_CHANGE.getProcessDefinitionKey(), @@ -72,11 +81,14 @@ public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implem ChangeRecordService changeRecordService, ChangeRecordRelationService changeRecordRelationService, ChangeRecordBillService changeRecordBillService, - MessageAPIV3 noticeApi, RefreshableConfiguration refreshableConfiguration) { + ChangeRecordConfirmService changeRecordConfirmService, + MessageAPIV3 noticeApi, + RefreshableConfiguration refreshableConfiguration) { super(eventProducer, visaOrganizationalNodeUserGateway); this.changeRecordService = changeRecordService; this.changeRecordRelationService = changeRecordRelationService; this.changeRecordBillService = changeRecordBillService; + this.changeRecordConfirmService = changeRecordConfirmService; this.noticeApi = noticeApi; this.refreshableConfiguration = refreshableConfiguration; } @@ -105,6 +117,10 @@ public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implem public void onCompleted(ProcessInstanceDTO dto) { String visaTypeDesc = parseVisaType(dto); + log.info("send complete notice"); + sendCompleteNotice(dto); + log.info("send complete notice success"); + updateChangeRecordApprovalStatus(dto, BpmnProcessInstanceResultEnum.APPROVED); changeRecordService.lambdaUpdate() @@ -112,15 +128,23 @@ public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implem .set(ChangeRecord::getStampStatus, VisaStampStatusEnum.UNPRINTED.name()) .update(); + } + + private void sendCompleteNotice(ProcessInstanceDTO dto) { Map variables = dto.getVariables(); + BpmnTaskDelegateAssigner initiator = dto.getInitiator(); MessageSendReqV3 completeNotice = new MessageSendReqV3(); completeNotice.setSender(PersonV3DTO.builder().build()); - completeNotice.setReceivers(Lists.newArrayList(PersonV3DTO.builder().build())); + completeNotice.setReceivers(queryConfirm(dto)); completeNotice.setBizEventMappingCode(refreshableConfiguration.getProcessInstanceCompleteMsgEventCode()); 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"); completeNotice.setBizExtParams(new JSONObject(Maps.of( + "initiatorName", initiator.getAssignerName(), "topic", variables.getOrDefault(FORM_FIELD_TOPIC, ""), + "visaTypeDesc", VisaTypeDesc, "workspaceName", variables.getOrDefault(FORM_FIELD_WORKSPACE_NAME, ""), "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, ""), "workspaceId", variables.getOrDefault(IM_GROUP_BIZ_INFO_INITIATOR_WORKSPACE_ID, "") ))); - noticeApi.send(completeNotice); + CommonResponse 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 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 public void onRejected(ProcessInstanceDTO dto) { + log.info("send reject notice"); + sendRejectNotice(dto); + log.info("send reject notice success"); + BpmnTaskDelegateAssigner lastOperationAssigner = dto.getLastOperationAssigner(); ChangeRecordLog log = ChangeRecordLog.builder() .visaId(Long.valueOf(dto.getBusinessKey())) @@ -171,14 +214,23 @@ public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implem updateChangeRecordApprovalStatus(dto, BpmnProcessInstanceResultEnum.REJECTED); + } + + private void sendRejectNotice(ProcessInstanceDTO dto) { Map variables = dto.getVariables(); + BpmnTaskDelegateAssigner initiator = dto.getInitiator(); MessageSendReqV3 rejectNotice = new MessageSendReqV3(); rejectNotice.setSender(PersonV3DTO.builder().build()); - rejectNotice.setReceivers(Lists.newArrayList(PersonV3DTO.builder().build())); - rejectNotice.setBizEventMappingCode(refreshableConfiguration.getProcessInstanceCompleteMsgEventCode()); + rejectNotice.setReceivers(queryConfirm(dto)); + rejectNotice.setBizEventMappingCode(refreshableConfiguration.getProcessInstanceRejectMsgEventCode()); 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( + "initiatorName", initiator.getAssignerName(), "topic", variables.getOrDefault(FORM_FIELD_TOPIC, ""), + "visaTypeDesc", VisaTypeDesc, "workspaceName", variables.getOrDefault(FORM_FIELD_WORKSPACE_NAME, ""), "reason", dto.getReason() ))); @@ -187,7 +239,13 @@ public class ProcessInstanceOfVisaAllEventHandler extends BasicLogSupport implem "ouId", variables.getOrDefault(IM_GROUP_BIZ_INFO_INITIATOR_OU_ID, ""), "workspaceId", variables.getOrDefault(IM_GROUP_BIZ_INFO_INITIATOR_WORKSPACE_ID, "") ))); - noticeApi.send(rejectNotice); + + CommonResponse 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 diff --git a/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/service/ChangeRecordConfirmService.java b/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/service/ChangeRecordConfirmService.java index 7a5f46f9..615f2df7 100644 --- a/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/service/ChangeRecordConfirmService.java +++ b/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/service/ChangeRecordConfirmService.java @@ -76,7 +76,7 @@ public interface ChangeRecordConfirmService { * @param visaId * @return */ - List listAllConfirmByVisaId(Long visaId); + List listAllConfirmByVisaId(Long visaId, List bizTypes); /** * 构建公司的Map,orgIdAndNameMap,key:ouId,value:ouName diff --git a/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/service/impl/ChangeRecordConfirmServiceImpl.java b/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/service/impl/ChangeRecordConfirmServiceImpl.java index 53dcfdd0..4101b8f5 100644 --- a/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/service/impl/ChangeRecordConfirmServiceImpl.java +++ b/visa/visa-server/src/main/java/cn/axzo/nanopart/visa/server/service/impl/ChangeRecordConfirmServiceImpl.java @@ -418,6 +418,7 @@ public class ChangeRecordConfirmServiceImpl extends ServiceImpl listAllConfirmByVisaId(Long visaId) { + public List listAllConfirmByVisaId(Long visaId, List bizTypes) { VisaConfirmDto dto = VisaConfirmDto.builder() .visaId(visaId) - .bizType(VisaConfirmBizTypeEnum.CONFIRM).build(); + .bizTypes(bizTypes).build(); List list = this.findByCondition(dto); if (CollectionUtils.isEmpty(list)) { return Lists.newArrayList();