From beb085064453f779a432ac233837c7ed6c0da46c Mon Sep 17 00:00:00 2001 From: b2894lxlx <517289602@qq.com> Date: Tue, 29 Sep 2026 02:23:19 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E8=A7=A3=E8=80=A6MK=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E5=AE=9E=E4=BE=8B=E4=B8=8E=E4=B8=9A=E5=8A=A1ID?= =?UTF-8?q?=EF=BC=8C=E5=85=AC=E5=BC=80=E9=A1=B5=E6=8C=89formInstanceId?= =?UTF-8?q?=E5=8F=8D=E6=9F=A5=E4=B8=9A=E5=8A=A1=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- .../process/feign/IBusinessProcessClient.java | 11 + .../process/pojo/entity/BusinessProcess.java | 6 + .../process/pojo/entity/MkFormBind.java | 94 ++++++ .../process/pojo/vo/MkFormBindVO.java | 61 ++++ .../controller/BusinessProcessController.java | 12 +- .../process/feign/BusinessProcessClient.java | 8 + .../process/mapper/BusinessProcessMapper.xml | 1 + .../process/mapper/MkFormBindMapper.java | 38 +++ .../process/mapper/MkFormBindMapper.xml | 17 ++ .../service/IBusinessProcessService.java | 18 +- .../process/service/IMkFormBindService.java | 80 +++++ .../impl/BusinessProcessServiceImpl.java | 96 ++++-- .../service/impl/MkFormBindServiceImpl.java | 174 +++++++++++ .../springblade/system/mapper/DeptMapper.java | 13 + .../springblade/system/mapper/DeptMapper.xml | 41 +++ .../system/service/IDeptService.java | 8 +- .../system/service/impl/DeptServiceImpl.java | 156 +++++++++- .../CustomerArchivePublicController.java | 29 +- .../controller/MkProcessPublicController.java | 30 +- .../transport/mk/MkProcessBizHandlers.java | 287 ++++++++++++++---- .../service/impl/CommonCargoServiceImpl.java | 12 +- .../support/TransportBusinessSupport.java | 26 ++ .../mk/pojo/dto/MKProcessCreateDTO.java | 7 +- .../changelog/mk-form-bind-202609290215.sql | 43 +++ 24 files changed, 1172 insertions(+), 96 deletions(-) create mode 100644 blade-service-api/blade-process-api/src/main/java/org/springblade/process/pojo/entity/MkFormBind.java create mode 100644 blade-service-api/blade-process-api/src/main/java/org/springblade/process/pojo/vo/MkFormBindVO.java create mode 100644 blade-service/blade-system/src/main/java/org/springblade/process/mapper/MkFormBindMapper.java create mode 100644 blade-service/blade-system/src/main/java/org/springblade/process/mapper/MkFormBindMapper.xml create mode 100644 blade-service/blade-system/src/main/java/org/springblade/process/service/IMkFormBindService.java create mode 100644 blade-service/blade-system/src/main/java/org/springblade/process/service/impl/MkFormBindServiceImpl.java create mode 100644 doc/sql/changelog/mk-form-bind-202609290215.sql diff --git a/blade-service-api/blade-process-api/src/main/java/org/springblade/process/feign/IBusinessProcessClient.java b/blade-service-api/blade-process-api/src/main/java/org/springblade/process/feign/IBusinessProcessClient.java index ecbdf0c6..ddbd4897 100644 --- a/blade-service-api/blade-process-api/src/main/java/org/springblade/process/feign/IBusinessProcessClient.java +++ b/blade-service-api/blade-process-api/src/main/java/org/springblade/process/feign/IBusinessProcessClient.java @@ -7,6 +7,7 @@ import org.springblade.process.pojo.dto.BusinessProcessDeleteDTO; import org.springblade.process.pojo.dto.BusinessProcessSubmitDTO; import org.springblade.process.pojo.dto.BusinessProcessUpdateDTO; import org.springblade.process.pojo.vo.BusinessProcessVO; +import org.springblade.process.pojo.vo.MkFormBindVO; import org.springblade.process.pojo.vo.ProcessApprovedRecordVO; import org.springblade.process.pojo.vo.ProcessTodoVO; import org.springframework.cloud.openfeign.FeignClient; @@ -40,6 +41,7 @@ public interface IBusinessProcessClient { String QUERY_APPROVED_RECORD_LIST = API_PREFIX + "/queryApprovedRecordsNoAttachments"; String GET_CURRENT_NODES = API_PREFIX + "/getCurrentNodes"; String GET_PROCESS_INFO = API_PREFIX + "/getProcessInfo"; + String RESOLVE_BY_FORM_INSTANCE_ID = API_PREFIX + "/resolveByFormInstanceId"; /** * 提交业务流程 @@ -126,4 +128,13 @@ public interface IBusinessProcessClient { @GetMapping(GET_PROCESS_INFO) FR getProcessInfo(@RequestParam("processInstanceId") String processInstanceId, @RequestParam(value = "loginName", required = false) String loginName); + + /** + * 按表单实例id解析业务绑定 + * + * @param formInstanceId 表单实例id + * @return 绑定信息(含业务主键) + */ + @GetMapping(RESOLVE_BY_FORM_INSTANCE_ID) + FR resolveByFormInstanceId(@RequestParam("formInstanceId") Long formInstanceId); } diff --git a/blade-service-api/blade-process-api/src/main/java/org/springblade/process/pojo/entity/BusinessProcess.java b/blade-service-api/blade-process-api/src/main/java/org/springblade/process/pojo/entity/BusinessProcess.java index bac2329d..45329958 100644 --- a/blade-service-api/blade-process-api/src/main/java/org/springblade/process/pojo/entity/BusinessProcess.java +++ b/blade-service-api/blade-process-api/src/main/java/org/springblade/process/pojo/entity/BusinessProcess.java @@ -65,6 +65,12 @@ public class BusinessProcess implements Serializable { */ @Schema(description = "业务id") private Long bizId; + /** + * MK表单实例id + */ + @JsonSerialize(using = ToStringSerializer.class) + @Schema(description = "MK表单实例id") + private Long formInstanceId; /** * 流程实例id */ diff --git a/blade-service-api/blade-process-api/src/main/java/org/springblade/process/pojo/entity/MkFormBind.java b/blade-service-api/blade-process-api/src/main/java/org/springblade/process/pojo/entity/MkFormBind.java new file mode 100644 index 00000000..03499c83 --- /dev/null +++ b/blade-service-api/blade-process-api/src/main/java/org/springblade/process/pojo/entity/MkFormBind.java @@ -0,0 +1,94 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.process.pojo.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springblade.core.tool.utils.DateUtil; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * MK表单实例绑定表 实体类 + * + * @author BladeX + */ +@Data +@TableName("blade_mk_form_bind") +@Schema(description = "MkFormBind对象") +public class MkFormBind implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @JsonSerialize(using = ToStringSerializer.class) + @Schema(description = "主键") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + @Schema(description = "租户ID") + private String tenantId; + + @Schema(description = "业务类型") + private String bizType; + + @JsonSerialize(using = ToStringSerializer.class) + @Schema(description = "业务主键") + private Long bizId; + + @JsonSerialize(using = ToStringSerializer.class) + @Schema(description = "MK表单实例id") + private Long formInstanceId; + + @Schema(description = "MK流程实例id") + private String processInstanceId; + + @Schema(description = "是否当前生效(1是0否)") + private Integer isCurrent; + + @DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME) + @JsonFormat(pattern = DateUtil.PATTERN_DATETIME) + @Schema(description = "创建时间", hidden = true) + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + @DateTimeFormat(pattern = DateUtil.PATTERN_DATETIME) + @JsonFormat(pattern = DateUtil.PATTERN_DATETIME) + @Schema(description = "更新时间", hidden = true) + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; +} diff --git a/blade-service-api/blade-process-api/src/main/java/org/springblade/process/pojo/vo/MkFormBindVO.java b/blade-service-api/blade-process-api/src/main/java/org/springblade/process/pojo/vo/MkFormBindVO.java new file mode 100644 index 00000000..a1623972 --- /dev/null +++ b/blade-service-api/blade-process-api/src/main/java/org/springblade/process/pojo/vo/MkFormBindVO.java @@ -0,0 +1,61 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.process.pojo.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * MK表单实例绑定 VO + * + * @author BladeX + */ +@Data +@Schema(description = "MkFormBindVO") +public class MkFormBindVO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @JsonSerialize(using = ToStringSerializer.class) + @Schema(description = "业务主键") + private Long bizId; + + @Schema(description = "业务类型") + private String bizType; + + @JsonSerialize(using = ToStringSerializer.class) + @Schema(description = "MK表单实例id") + private Long formInstanceId; + + @Schema(description = "MK流程实例id") + private String processInstanceId; +} diff --git a/blade-service/blade-system/src/main/java/org/springblade/process/controller/BusinessProcessController.java b/blade-service/blade-system/src/main/java/org/springblade/process/controller/BusinessProcessController.java index 5566fe9a..f65cc45e 100644 --- a/blade-service/blade-system/src/main/java/org/springblade/process/controller/BusinessProcessController.java +++ b/blade-service/blade-system/src/main/java/org/springblade/process/controller/BusinessProcessController.java @@ -13,6 +13,7 @@ import org.springblade.core.mp.support.Condition; import org.springblade.core.mp.support.Query; import org.springblade.core.secure.utils.AuthUtil; import org.springblade.core.tool.api.R; +import org.springblade.core.tool.utils.StringUtil; import org.springblade.process.pojo.dto.ApprovalDTO; import org.springblade.process.pojo.vo.ApprovalVO; import org.springblade.process.pojo.vo.ProcessApprovedRecordVO; @@ -55,22 +56,27 @@ public class BusinessProcessController extends BladeController { @PostMapping("/processSubmit") @ApiOperationSupport(order = 2) - @Operation(summary = "提交MK审核流", description = "调用mk processSubmit,传入templateCode/submitIdentity/formInstanceId") + @Operation(summary = "提交MK审核流", description = "传入bizId/bizType/templateCode,后端生成或复用formInstanceId后调用mk processSubmit") public R processSubmit(@Validated @RequestBody MKProcessCreateDTO param) { return R.data(businessProcessService.processSubmit(param)); } @GetMapping("/hasMkProcessInstance") @ApiOperationSupport(order = 8) - @Operation(summary = "查询MK流程实例是否存在", description = "传入业务id(formInstanceId),有数据则无需删除/重新提交") + @Operation(summary = "查询MK流程实例是否存在", description = "传入业务主键bizId,有数据则无需删除/重新提交") public R hasMkProcessInstance(@Valid @NotBlank(message = "业务id不能为空") String bizId) { return R.data(businessProcessService.hasMkProcessInstance(bizId)); } @PostMapping("/processDelete") @ApiOperationSupport(order = 7) + @Operation(summary = "删除MK审核流", description = "传入bizId,删除当前业务对应MK流程实例") public R processDelete(@RequestBody MKProcessCreateDTO param) { - return R.data(businessProcessService.processDelete(param == null ? null : param.getFormInstanceId())); + String bizId = null; + if (param != null) { + bizId = StringUtil.isNotBlank(param.getBizId()) ? param.getBizId() : param.getFormInstanceId(); + } + return R.data(businessProcessService.processDelete(bizId)); } @GetMapping("/isEditView") diff --git a/blade-service/blade-system/src/main/java/org/springblade/process/feign/BusinessProcessClient.java b/blade-service/blade-system/src/main/java/org/springblade/process/feign/BusinessProcessClient.java index fa87f975..cc94ba25 100644 --- a/blade-service/blade-system/src/main/java/org/springblade/process/feign/BusinessProcessClient.java +++ b/blade-service/blade-system/src/main/java/org/springblade/process/feign/BusinessProcessClient.java @@ -11,6 +11,7 @@ import org.springblade.process.pojo.dto.BusinessProcessDeleteDTO; import org.springblade.process.pojo.dto.BusinessProcessSubmitDTO; import org.springblade.process.pojo.dto.BusinessProcessUpdateDTO; import org.springblade.process.pojo.vo.BusinessProcessVO; +import org.springblade.process.pojo.vo.MkFormBindVO; import org.springblade.process.pojo.vo.ProcessApprovedRecordVO; import org.springblade.process.pojo.vo.ProcessTodoVO; import org.springblade.process.service.IBusinessProcessService; @@ -94,4 +95,11 @@ public class BusinessProcessClient implements IBusinessProcessClient { @RequestParam(value = "loginName", required = false) String loginName) { return FR.data(businessProcessService.getProcessInfo(processInstanceId, loginName)); } + + @PreAuth(AuthConstant.PERMIT_ALL) + @GetMapping(RESOLVE_BY_FORM_INSTANCE_ID) + @Override + public FR resolveByFormInstanceId(@RequestParam("formInstanceId") Long formInstanceId) { + return FR.data(businessProcessService.resolveByFormInstanceId(formInstanceId)); + } } diff --git a/blade-service/blade-system/src/main/java/org/springblade/process/mapper/BusinessProcessMapper.xml b/blade-service/blade-system/src/main/java/org/springblade/process/mapper/BusinessProcessMapper.xml index 47b45b79..4aa5df53 100644 --- a/blade-service/blade-system/src/main/java/org/springblade/process/mapper/BusinessProcessMapper.xml +++ b/blade-service/blade-system/src/main/java/org/springblade/process/mapper/BusinessProcessMapper.xml @@ -6,6 +6,7 @@ + diff --git a/blade-service/blade-system/src/main/java/org/springblade/process/mapper/MkFormBindMapper.java b/blade-service/blade-system/src/main/java/org/springblade/process/mapper/MkFormBindMapper.java new file mode 100644 index 00000000..23e701f4 --- /dev/null +++ b/blade-service/blade-system/src/main/java/org/springblade/process/mapper/MkFormBindMapper.java @@ -0,0 +1,38 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.process.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.springblade.process.pojo.entity.MkFormBind; + +/** + * MK表单实例绑定表 Mapper 接口 + * + * @author BladeX + */ +public interface MkFormBindMapper extends BaseMapper { + +} diff --git a/blade-service/blade-system/src/main/java/org/springblade/process/mapper/MkFormBindMapper.xml b/blade-service/blade-system/src/main/java/org/springblade/process/mapper/MkFormBindMapper.xml new file mode 100644 index 00000000..b19c1df2 --- /dev/null +++ b/blade-service/blade-system/src/main/java/org/springblade/process/mapper/MkFormBindMapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/blade-service/blade-system/src/main/java/org/springblade/process/service/IBusinessProcessService.java b/blade-service/blade-system/src/main/java/org/springblade/process/service/IBusinessProcessService.java index fd25cbb5..866f9341 100644 --- a/blade-service/blade-system/src/main/java/org/springblade/process/service/IBusinessProcessService.java +++ b/blade-service/blade-system/src/main/java/org/springblade/process/service/IBusinessProcessService.java @@ -29,7 +29,7 @@ public interface IBusinessProcessService extends IService { /** * 直接调用 MK processSubmit 提交流程 * - * @param param MK 流程创建参数 + * @param param MK 流程创建参数(传 bizId+bizType,后端生成/复用 formInstanceId) * @return 流程实例 id */ String processSubmit(MKProcessCreateDTO param); @@ -37,18 +37,26 @@ public interface IBusinessProcessService extends IService { /** * 按业务 id 查询 MK 流程实例是否仍有数据(本地有 processInstanceId 且 MK getProcessInfo 有返回) * - * @param bizId 业务 id(如客商 id / formInstanceId) + * @param bizId 业务主键 * @return true=流程实例仍存在 */ boolean hasMkProcessInstance(String bizId); /** - * 按业务表单实例 id 删除 MK 流程(不删除本地业务流程记录,供驳回后重新提交使用) + * 按业务主键删除 MK 流程(不删除本地业务流程记录与表单绑定,供驳回后重新提交使用) * - * @param formInstanceId 业务表单实例 id + * @param bizId 业务主键 * @return 是否成功 */ - boolean processDelete(String formInstanceId); + boolean processDelete(String bizId); + + /** + * 按表单实例id解析业务绑定 + * + * @param formInstanceId 表单实例id + * @return 绑定信息 + */ + MkFormBindVO resolveByFormInstanceId(Long formInstanceId); /** * 获取流程当前节点详情 diff --git a/blade-service/blade-system/src/main/java/org/springblade/process/service/IMkFormBindService.java b/blade-service/blade-system/src/main/java/org/springblade/process/service/IMkFormBindService.java new file mode 100644 index 00000000..81a7178a --- /dev/null +++ b/blade-service/blade-system/src/main/java/org/springblade/process/service/IMkFormBindService.java @@ -0,0 +1,80 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.process.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.springblade.process.pojo.entity.MkFormBind; +import org.springblade.process.pojo.vo.MkFormBindVO; + +/** + * MK表单实例绑定表 服务类 + * + * @author BladeX + */ +public interface IMkFormBindService extends IService { + + /** + * 查询业务当前生效的表单实例绑定 + * + * @param bizType 业务类型(可空,空时仅按业务id查) + * @param bizId 业务主键 + * @return 当前绑定,不存在返回 null + */ + MkFormBind getCurrentBind(String bizType, Long bizId); + + /** + * 按表单实例id查询绑定 + * + * @param formInstanceId 表单实例id + * @return 绑定记录 + */ + MkFormBind getByFormInstanceId(Long formInstanceId); + + /** + * 按表单实例id解析业务主键等信息 + * + * @param formInstanceId 表单实例id + * @return 绑定 VO + */ + MkFormBindVO resolveByFormInstanceId(Long formInstanceId); + + /** + * 解析或生成表单实例id:无当前绑定则新建;当前流程已审批通过则新建;否则复用 + * + * @param bizType 业务类型 + * @param bizId 业务主键 + * @return 本次应使用的表单实例id + */ + Long resolveOrCreateFormInstanceId(String bizType, Long bizId); + + /** + * 回写流程实例id到当前绑定 + * + * @param formInstanceId 表单实例id + * @param processInstanceId 流程实例id + */ + void updateProcessInstanceId(Long formInstanceId, String processInstanceId); +} diff --git a/blade-service/blade-system/src/main/java/org/springblade/process/service/impl/BusinessProcessServiceImpl.java b/blade-service/blade-system/src/main/java/org/springblade/process/service/impl/BusinessProcessServiceImpl.java index fe45212a..5cba67dc 100644 --- a/blade-service/blade-system/src/main/java/org/springblade/process/service/impl/BusinessProcessServiceImpl.java +++ b/blade-service/blade-system/src/main/java/org/springblade/process/service/impl/BusinessProcessServiceImpl.java @@ -25,6 +25,7 @@ import org.springblade.process.pojo.entity.BusinessProcess; import org.springblade.process.pojo.enums.TodoStatus; import org.springblade.process.pojo.vo.*; import org.springblade.process.service.IBusinessProcessService; +import org.springblade.process.service.IMkFormBindService; import org.springblade.system.pojo.entity.User; import org.springblade.system.service.IUserService; import org.springblade.thirdparty.mk.config.MKProperties; @@ -72,6 +73,7 @@ public class BusinessProcessServiceImpl extends ServiceImpllambdaQuery() .eq(BusinessProcess::getBizId, bizId) + .orderByDesc(BusinessProcess::getUpdateTime) + .last("limit 1") ); // 已有流程实例且 MK 仍能查到详情时,不再删除、不再重新创建提交 - if (businessProcess != null && StringUtil.isNotBlank(businessProcess.getProcessInstanceId())) { + if (businessProcess != null && StringUtil.isNotBlank(businessProcess.getProcessInstanceId()) + && Objects.equals(formInstanceId, businessProcess.getFormInstanceId())) { String existingProcessInstanceId = businessProcess.getProcessInstanceId(); Object existingProcessInfo = this.getProcessInfo(existingProcessInstanceId, loginName); if (hasProcessInfoData(existingProcessInfo)) { - log.info("MK流程实例已存在,跳过创建并提交流程 formInstanceId={} processInstanceId={}", - param.getFormInstanceId(), existingProcessInstanceId); + log.info("MK流程实例已存在,跳过创建并提交流程 bizId={} formInstanceId={} processInstanceId={}", + bizId, formInstanceIdText, existingProcessInstanceId); businessProcess.setApproveStatus(ApproveStatusEnum.APPROVING.getValue()); if (StringUtil.isNotBlank(param.getSubject())) { businessProcess.setSubject(param.getSubject()); } businessProcess.setPromoterLoginName(loginName); + businessProcess.setFormInstanceId(formInstanceId); this.updateById(businessProcess); this.getCurrentNodes(existingProcessInstanceId, loginName); - this.syncBizFromProcessInfo(bizType, param.getFormInstanceId(), existingProcessInfo); + this.syncBizFromProcessInfo(bizType, String.valueOf(bizId), existingProcessInfo); return existingProcessInstanceId; } } MKProcessCreateDTO mkParam = new MKProcessCreateDTO(); - mkParam.setFormInstanceId(param.getFormInstanceId()); + mkParam.setFormInstanceId(formInstanceIdText); mkParam.setSubject(param.getSubject()); mkParam.setSubmitIdentity(loginName); mkParam.setLoginName(loginName); @@ -197,15 +201,35 @@ public class BusinessProcessServiceImpl extends ServiceImpllambdaQuery() .eq(BusinessProcess::getBizId, id) + .orderByDesc(BusinessProcess::getUpdateTime) .last("limit 1") ); if (businessProcess == null || StringUtil.isBlank(businessProcess.getProcessInstanceId())) { return false; } + // 审批通过后允许再次提交新表单实例,视为当前无有效待办流程 + if (Objects.equals(ApproveStatusEnum.APPROVED.getValue(), businessProcess.getApproveStatus())) { + return false; + } String loginName = businessProcess.getPromoterLoginName(); if (StringUtil.isBlank(loginName)) { loginName = resolveCurrentUserPhone(); @@ -257,18 +286,20 @@ public class BusinessProcessServiceImpl extends ServiceImpllambdaQuery() .eq(BusinessProcess::getBizId, bizId) + .orderByDesc(BusinessProcess::getUpdateTime) + .last("limit 1") ); if (businessProcess == null || StringUtil.isBlank(businessProcess.getProcessInstanceId())) { - log.warn("客商驳回后删除流程跳过,未找到流程实例 formInstanceId={}", formInstanceId); + log.warn("驳回后删除流程跳过,未找到流程实例 bizId={}", bizId); return true; } String loginName = businessProcess.getPromoterLoginName(); @@ -276,8 +307,8 @@ public class BusinessProcessServiceImpl extends ServiceImpllambdaQuery() + .eq(BusinessProcess::getBizId, formInstanceId) + .last("limit 1") + ); + if (businessProcess == null) { + businessProcess = this.getOne(Wrappers.lambdaQuery() + .eq(BusinessProcess::getFormInstanceId, formInstanceId) + .last("limit 1") + ); + } + if (businessProcess == null) { + return null; + } + MkFormBindVO fallback = new MkFormBindVO(); + fallback.setBizId(businessProcess.getBizId()); + fallback.setFormInstanceId(businessProcess.getFormInstanceId() != null + ? businessProcess.getFormInstanceId() : businessProcess.getBizId()); + fallback.setProcessInstanceId(businessProcess.getProcessInstanceId()); + return fallback; + } + @Override public List getCurrentNodes(String processInstanceId, String loginName) { if (StringUtils.isBlank(processInstanceId)) { diff --git a/blade-service/blade-system/src/main/java/org/springblade/process/service/impl/MkFormBindServiceImpl.java b/blade-service/blade-system/src/main/java/org/springblade/process/service/impl/MkFormBindServiceImpl.java new file mode 100644 index 00000000..21fee54d --- /dev/null +++ b/blade-service/blade-system/src/main/java/org/springblade/process/service/impl/MkFormBindServiceImpl.java @@ -0,0 +1,174 @@ +/** + * BladeX Commercial License Agreement + * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved. + *

+ * Use of this software is governed by the Commercial License Agreement + * obtained after purchasing a license from BladeX. + *

+ * 1. This software is for development use only under a valid license + * from BladeX. + *

+ * 2. Redistribution of this software's source code to any third party + * without a commercial license is strictly prohibited. + *

+ * 3. Licensees may copyright their own code but cannot use segments + * from this software for such purposes. Copyright of this software + * remains with BladeX. + *

+ * Using this software signifies agreement to this License, and the software + * must not be used for illegal purposes. + *

+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is + * not liable for any claims arising from secondary or illegal development. + *

+ * Author: Chill Zhuang (bladejava@qq.com) + */ +package org.springblade.process.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springblade.core.log.exception.ServiceException; +import org.springblade.core.log.utils.AssertUtils; +import org.springblade.core.secure.utils.AuthUtil; +import org.springblade.core.tool.utils.StringUtil; +import org.springblade.process.mapper.BusinessProcessMapper; +import org.springblade.process.mapper.MkFormBindMapper; +import org.springblade.process.pojo.entity.BusinessProcess; +import org.springblade.process.pojo.entity.MkFormBind; +import org.springblade.process.pojo.enums.ApproveStatusEnum; +import org.springblade.process.pojo.vo.MkFormBindVO; +import org.springblade.process.service.IMkFormBindService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.Objects; + +/** + * MK表单实例绑定表 服务实现类 + * + * @author BladeX + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class MkFormBindServiceImpl extends ServiceImpl implements IMkFormBindService { + + private final BusinessProcessMapper businessProcessMapper; + + @Override + public MkFormBind getCurrentBind(String bizType, Long bizId) { + AssertUtils.notNull(bizId, "业务id不能为空"); + MkFormBind bind = null; + if (StringUtil.isNotBlank(bizType)) { + bind = this.getOne(Wrappers.lambdaQuery() + .eq(MkFormBind::getBizType, bizType) + .eq(MkFormBind::getBizId, bizId) + .eq(MkFormBind::getIsCurrent, 1) + .orderByDesc(MkFormBind::getCreateTime) + .last("limit 1") + ); + } + if (bind == null) { + // 兼容历史迁移数据 biz_type 为空,或未传 bizType + bind = this.getOne(Wrappers.lambdaQuery() + .eq(MkFormBind::getBizId, bizId) + .eq(MkFormBind::getIsCurrent, 1) + .orderByDesc(MkFormBind::getCreateTime) + .last("limit 1") + ); + } + return bind; + } + + @Override + public MkFormBind getByFormInstanceId(Long formInstanceId) { + AssertUtils.notNull(formInstanceId, "表单实例id不能为空"); + return this.getOne(Wrappers.lambdaQuery() + .eq(MkFormBind::getFormInstanceId, formInstanceId) + .last("limit 1") + ); + } + + @Override + public MkFormBindVO resolveByFormInstanceId(Long formInstanceId) { + MkFormBind bind = this.getByFormInstanceId(formInstanceId); + if (bind == null) { + return null; + } + MkFormBindVO vo = new MkFormBindVO(); + vo.setBizId(bind.getBizId()); + vo.setBizType(bind.getBizType()); + vo.setFormInstanceId(bind.getFormInstanceId()); + vo.setProcessInstanceId(bind.getProcessInstanceId()); + return vo; + } + + @Transactional(rollbackFor = Exception.class) + @Override + public Long resolveOrCreateFormInstanceId(String bizType, Long bizId) { + AssertUtils.notNull(bizId, "业务id不能为空"); + MkFormBind current = this.getCurrentBind(bizType, bizId); + if (current == null) { + return this.createNewBind(bizType, bizId); + } + BusinessProcess businessProcess = businessProcessMapper.selectOne(Wrappers.lambdaQuery() + .eq(BusinessProcess::getBizId, bizId) + .orderByDesc(BusinessProcess::getUpdateTime) + .last("limit 1") + ); + boolean approvedPass = businessProcess != null + && Objects.equals(ApproveStatusEnum.APPROVED.getValue(), businessProcess.getApproveStatus()); + if (approvedPass) { + log.info("审核通过后再次提交,生成新表单实例 bizType={} bizId={} oldFormInstanceId={}", + bizType, bizId, current.getFormInstanceId()); + this.lambdaUpdate() + .eq(MkFormBind::getBizId, bizId) + .eq(MkFormBind::getIsCurrent, 1) + .set(MkFormBind::getIsCurrent, 0) + .set(MkFormBind::getUpdateTime, new Date()) + .update(); + return this.createNewBind(bizType, bizId); + } + log.info("复用当前表单实例 bizType={} bizId={} formInstanceId={}", + bizType, bizId, current.getFormInstanceId()); + if (StringUtil.isNotBlank(bizType) && StringUtil.isBlank(current.getBizType())) { + current.setBizType(bizType); + current.setUpdateTime(new Date()); + this.updateById(current); + } + return current.getFormInstanceId(); + } + + @Override + public void updateProcessInstanceId(Long formInstanceId, String processInstanceId) { + AssertUtils.notNull(formInstanceId, "表单实例id不能为空"); + this.lambdaUpdate() + .eq(MkFormBind::getFormInstanceId, formInstanceId) + .set(MkFormBind::getProcessInstanceId, processInstanceId) + .set(MkFormBind::getUpdateTime, new Date()) + .update(); + } + + private Long createNewBind(String bizType, Long bizId) { + Long formInstanceId = IdWorker.getId(); + MkFormBind bind = new MkFormBind(); + bind.setId(IdWorker.getId()); + bind.setTenantId(StringUtil.isBlank(AuthUtil.getTenantId()) ? "000000" : AuthUtil.getTenantId()); + bind.setBizType(StringUtil.isBlank(bizType) ? "" : bizType); + bind.setBizId(bizId); + bind.setFormInstanceId(formInstanceId); + bind.setIsCurrent(1); + bind.setCreateTime(new Date()); + bind.setUpdateTime(new Date()); + boolean saved = this.save(bind); + if (!saved) { + throw new ServiceException("保存表单实例绑定失败"); + } + log.info("创建表单实例绑定 bizType={} bizId={} formInstanceId={}", bizType, bizId, formInstanceId); + return formInstanceId; + } +} diff --git a/blade-service/blade-system/src/main/java/org/springblade/system/mapper/DeptMapper.java b/blade-service/blade-system/src/main/java/org/springblade/system/mapper/DeptMapper.java index 55661a6a..6176e472 100644 --- a/blade-service/blade-system/src/main/java/org/springblade/system/mapper/DeptMapper.java +++ b/blade-service/blade-system/src/main/java/org/springblade/system/mapper/DeptMapper.java @@ -26,6 +26,7 @@ package org.springblade.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; import org.springblade.system.pojo.entity.Dept; import org.springblade.system.pojo.vo.DeptVO; @@ -66,6 +67,18 @@ public interface DeptMapper extends BaseMapper { */ List lazyTree(String tenantId, Long parentId); + /** + * 按组织 ID 集合查询树节点(用于数据权限过滤后的根节点回显) + * + * @param tenantId 租户ID,空表示不限 + * @param ids 需要返回的组织 ID + * @param childIds 计算 hasChildren 时允许计入的子组织 ID;为空则 hasChildren 恒为 false + * @return 树节点列表 + */ + List treeNodesByIds(@Param("tenantId") String tenantId, + @Param("ids") List ids, + @Param("childIds") List childIds); + /** * 获取部门名 * diff --git a/blade-service/blade-system/src/main/java/org/springblade/system/mapper/DeptMapper.xml b/blade-service/blade-system/src/main/java/org/springblade/system/mapper/DeptMapper.xml index baef84dc..85508294 100644 --- a/blade-service/blade-system/src/main/java/org/springblade/system/mapper/DeptMapper.xml +++ b/blade-service/blade-system/src/main/java/org/springblade/system/mapper/DeptMapper.xml @@ -115,6 +115,47 @@ ORDER BY dept.sort + +