From 5bce6fa4728a9fb62b95e94828fddf8f3134a409 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期五, 14 八月 2026 15:55:31 +0800
Subject: [PATCH] feat(bpm): 添加业务附件配置功能
---
approval-detail-before.png | 0
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/vo/attach/BpmBusinessAttachRespVO.java | 33 +++
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/vo/attach/BpmBusinessAttachSaveReqVO.java | 36 ++++
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/attach/BpmBusinessAttachMapper.java | 32 +++
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/attach/BpmBusinessAttachServiceImpl.java | 119 +++++++++++++
approval-detail-v2.jpeg | 0
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/BpmBusinessAttachController.java | 72 ++++++++
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java | 13 +
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/vo/attach/BpmBusinessAttachPageReqVO.java | 37 ++++
approval-detail-before-full.png | 0
contract-approve-detail.png | 0
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java | 4
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java | 13 +
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmBusinessAttachDO.java | 55 ++++++
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/attach/BpmBusinessAttachService.java | 75 ++++++++
15 files changed, 485 insertions(+), 4 deletions(-)
diff --git a/approval-detail-before-full.png b/approval-detail-before-full.png
new file mode 100644
index 0000000..8173a54
--- /dev/null
+++ b/approval-detail-before-full.png
Binary files differ
diff --git a/approval-detail-before.png b/approval-detail-before.png
new file mode 100644
index 0000000..d7d7e55
--- /dev/null
+++ b/approval-detail-before.png
Binary files differ
diff --git a/approval-detail-v2.jpeg b/approval-detail-v2.jpeg
new file mode 100644
index 0000000..6c26c21
--- /dev/null
+++ b/approval-detail-v2.jpeg
Binary files differ
diff --git a/contract-approve-detail.png b/contract-approve-detail.png
new file mode 100644
index 0000000..723c4c5
--- /dev/null
+++ b/contract-approve-detail.png
Binary files differ
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/BpmBusinessAttachController.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/BpmBusinessAttachController.java
new file mode 100644
index 0000000..5e783ea
--- /dev/null
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/BpmBusinessAttachController.java
@@ -0,0 +1,72 @@
+package cn.iocoder.yudao.module.bpm.controller.admin.attach;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.bpm.controller.admin.attach.vo.attach.BpmBusinessAttachPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.attach.vo.attach.BpmBusinessAttachRespVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.attach.vo.attach.BpmBusinessAttachSaveReqVO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmBusinessAttachDO;
+import cn.iocoder.yudao.module.bpm.service.attach.BpmBusinessAttachService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "绠$悊鍚庡彴 - BPM 涓氬姟闄勪欢閰嶇疆")
+@RestController
+@RequestMapping("/bpm/business-attach")
+@Validated
+public class BpmBusinessAttachController {
+
+ @Resource
+ private BpmBusinessAttachService businessAttachService;
+
+ @PostMapping("/create")
+ @Operation(summary = "鍒涘缓涓氬姟闄勪欢閰嶇疆")
+ @PreAuthorize("@ss.hasPermission('bpm:business-attach:create')")
+ public CommonResult<Long> createBusinessAttach(@Valid @RequestBody BpmBusinessAttachSaveReqVO createReqVO) {
+ return success(businessAttachService.createBusinessAttach(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "鏇存柊涓氬姟闄勪欢閰嶇疆")
+ @PreAuthorize("@ss.hasPermission('bpm:business-attach:update')")
+ public CommonResult<Boolean> updateBusinessAttach(@Valid @RequestBody BpmBusinessAttachSaveReqVO updateReqVO) {
+ businessAttachService.updateBusinessAttach(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "鍒犻櫎涓氬姟闄勪欢閰嶇疆")
+ @Parameter(name = "id", description = "缂栧彿", required = true)
+ @PreAuthorize("@ss.hasPermission('bpm:business-attach:delete')")
+ public CommonResult<Boolean> deleteBusinessAttach(@RequestParam("id") Long id) {
+ businessAttachService.deleteBusinessAttach(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "鑾峰緱涓氬姟闄勪欢閰嶇疆")
+ @Parameter(name = "id", description = "缂栧彿", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('bpm:business-attach:query')")
+ public CommonResult<BpmBusinessAttachRespVO> getBusinessAttach(@RequestParam("id") Long id) {
+ BpmBusinessAttachDO attach = businessAttachService.getBusinessAttach(id);
+ return success(BeanUtils.toBean(attach, BpmBusinessAttachRespVO.class));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "鑾峰緱涓氬姟闄勪欢閰嶇疆鍒嗛〉")
+ @PreAuthorize("@ss.hasPermission('bpm:business-attach:query')")
+ public CommonResult<PageResult<BpmBusinessAttachRespVO>> getBusinessAttachPage(@Valid BpmBusinessAttachPageReqVO pageReqVO) {
+ PageResult<BpmBusinessAttachDO> pageResult = businessAttachService.getBusinessAttachPage(pageReqVO);
+ return success(BeanUtils.toBean(pageResult, BpmBusinessAttachRespVO.class));
+ }
+
+}
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/vo/attach/BpmBusinessAttachPageReqVO.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/vo/attach/BpmBusinessAttachPageReqVO.java
new file mode 100644
index 0000000..2790b99
--- /dev/null
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/vo/attach/BpmBusinessAttachPageReqVO.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.bpm.controller.admin.attach.vo.attach;
+
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.validation.InEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "绠$悊鍚庡彴 - BPM 涓氬姟闄勪欢閰嶇疆鍒嗛〉 Request VO")
+@Data
+public class BpmBusinessAttachPageReqVO extends PageParam {
+
+ @Schema(description = "娴佺▼瀹氫箟鐨� Key", example = "purchase_approve")
+ private String processDefinitionKey;
+
+ @Schema(description = "涓氬姟绫诲瀷锛屼緥濡� erp_purchase_order", example = "erp_purchase_order")
+ private String businessType;
+
+ @Schema(description = "涓氬姟璇︽儏缁勪欢璺緞锛屼緥濡� /erp/purchase/order/detail/index.vue")
+ private String componentPath;
+
+ @Schema(description = "鐘舵�侊紝鍙傝 CommonStatusEnum 鏋氫妇", example = "1")
+ @InEnum(CommonStatusEnum.class)
+ private Integer status;
+
+ @Schema(description = "鍒涘缓鏃堕棿")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime[] createTime;
+
+}
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/vo/attach/BpmBusinessAttachRespVO.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/vo/attach/BpmBusinessAttachRespVO.java
new file mode 100644
index 0000000..7778dd1
--- /dev/null
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/vo/attach/BpmBusinessAttachRespVO.java
@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.bpm.controller.admin.attach.vo.attach;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "绠$悊鍚庡彴 - BPM 涓氬姟闄勪欢閰嶇疆 Response VO")
+@Data
+public class BpmBusinessAttachRespVO {
+
+ @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "娴佺▼瀹氫箟鐨� Key", requiredMode = Schema.RequiredMode.REQUIRED, example = "purchase_approve")
+ private String processDefinitionKey;
+
+ @Schema(description = "涓氬姟绫诲瀷锛屼緥濡� erp_purchase_order", example = "erp_purchase_order")
+ private String businessType;
+
+ @Schema(description = "涓氬姟璇︽儏缁勪欢璺緞锛屼緥濡� /erp/purchase/order/detail/index.vue", requiredMode = Schema.RequiredMode.REQUIRED)
+ private String componentPath;
+
+ @Schema(description = "鐘舵�侊紝鍙傝 CommonStatusEnum 鏋氫妇", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Integer status;
+
+ @Schema(description = "澶囨敞", example = "閲囪喘璁㈠崟瀹℃壒灞曠ず閲囪喘璁㈠崟璇︽儏")
+ private String remark;
+
+ @Schema(description = "鍒涘缓鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
+ private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/vo/attach/BpmBusinessAttachSaveReqVO.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/vo/attach/BpmBusinessAttachSaveReqVO.java
new file mode 100644
index 0000000..0e659a1
--- /dev/null
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/attach/vo/attach/BpmBusinessAttachSaveReqVO.java
@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.bpm.controller.admin.attach.vo.attach;
+
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.validation.InEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "绠$悊鍚庡彴 - BPM 涓氬姟闄勪欢閰嶇疆鏂板/淇敼 Request VO")
+@Data
+public class BpmBusinessAttachSaveReqVO {
+
+ @Schema(description = "缂栧彿", example = "1024")
+ private Long id;
+
+ @Schema(description = "娴佺▼瀹氫箟鐨� Key", requiredMode = Schema.RequiredMode.REQUIRED, example = "purchase_approve")
+ @NotEmpty(message = "娴佺▼瀹氫箟鐨� Key 涓嶈兘涓虹┖")
+ private String processDefinitionKey;
+
+ @Schema(description = "涓氬姟绫诲瀷锛屼緥濡� erp_purchase_order", example = "erp_purchase_order")
+ private String businessType;
+
+ @Schema(description = "涓氬姟璇︽儏缁勪欢璺緞锛屼緥濡� /erp/purchase/order/detail/index.vue", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotEmpty(message = "涓氬姟璇︽儏缁勪欢璺緞涓嶈兘涓虹┖")
+ private String componentPath;
+
+ @Schema(description = "鐘舵�侊紝鍙傝 CommonStatusEnum 鏋氫妇", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "鐘舵�佷笉鑳戒负绌�")
+ @InEnum(CommonStatusEnum.class)
+ private Integer status;
+
+ @Schema(description = "澶囨敞", example = "閲囪喘璁㈠崟瀹℃壒灞曠ず閲囪喘璁㈠崟璇︽儏")
+ private String remark;
+
+}
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
index add6f20..7d5705b 100644
--- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
@@ -11,6 +11,7 @@
import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
+import cn.iocoder.yudao.module.bpm.service.attach.BpmBusinessAttachService;
import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
@@ -56,6 +57,8 @@
private BpmProcessDefinitionService processDefinitionService;
@Resource
private BpmCategoryService categoryService;
+ @Resource
+ private BpmBusinessAttachService businessAttachService;
@Resource
private AdminUserApi adminUserApi;
@@ -217,10 +220,16 @@
List<HistoricTaskInstance> tasks = taskService.getFinishedTaskListByProcessInstanceIdWithoutCancel(processInstanceId);
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
convertSet(tasks, item -> Long.valueOf(item.getAssignee())));
- return success(BpmProcessInstanceConvert.INSTANCE.buildProcessInstancePrintData(historicProcessInstance,
+ BpmProcessPrintDataRespVO printData = BpmProcessInstanceConvert.INSTANCE.buildProcessInstancePrintData(
+ historicProcessInstance,
processDefinitionService.getProcessDefinitionInfo(historicProcessInstance.getProcessDefinitionId()),
tasks, userMap,
- new UserSimpleBaseVO().setNickname(startUser.getNickname()).setDeptName(dept.getName())));
+ new UserSimpleBaseVO().setNickname(startUser.getNickname()).setDeptName(dept.getName()));
+ // 濉厖涓氬姟闄勪欢閰嶇疆锛屽疄鐜版墦鍗拌嚜鍔ㄥ睍绀哄閮ㄤ笟鍔′俊鎭�
+ businessAttachService.fillBusinessForm(printData.getProcessInstance().getProcessDefinition(),
+ processDefinitionService.getProcessDefinition(historicProcessInstance.getProcessDefinitionId()).getKey(),
+ historicProcessInstance.getBusinessKey());
+ return success(printData);
}
}
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmBusinessAttachDO.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmBusinessAttachDO.java
new file mode 100644
index 0000000..b35ec32
--- /dev/null
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmBusinessAttachDO.java
@@ -0,0 +1,55 @@
+package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * BPM 涓氬姟闄勪欢閰嶇疆 DO
+ *
+ * 鐢ㄤ簬寤虹珛銆屾祦绋嬪畾涔� Key -> 涓氬姟璇︽儏缁勪欢銆嶇殑鏄犲皠锛屽疄鐜板鎵硅鎯呰嚜鍔ㄥ睍绀哄閮ㄤ笟鍔′俊鎭�
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@TableName("bpm_business_attach")
+@KeySequence("bpm_business_attach_seq") // 鐢ㄤ簬 Oracle銆丳ostgreSQL銆並ingbase銆丏B2銆丠2 鏁版嵁搴撶殑涓婚敭鑷銆傚鏋滄槸 MySQL 绛夋暟鎹簱锛屽彲涓嶅啓銆�
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BpmBusinessAttachDO extends BaseDO {
+
+ /**
+ * 缂栧彿
+ */
+ @TableId
+ private Long id;
+ /**
+ * 娴佺▼瀹氫箟鐨� Key
+ */
+ private String processDefinitionKey;
+ /**
+ * 涓氬姟绫诲瀷锛屼緥濡� erp_purchase_order
+ */
+ private String businessType;
+ /**
+ * 涓氬姟璇︽儏缁勪欢璺緞锛屼緥濡� /erp/purchase/order/detail/index.vue
+ */
+ private String componentPath;
+ /**
+ * 鐘舵��
+ *
+ * 鏋氫妇 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
+ */
+ private Integer status;
+ /**
+ * 澶囨敞
+ */
+ private String remark;
+
+}
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/attach/BpmBusinessAttachMapper.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/attach/BpmBusinessAttachMapper.java
new file mode 100644
index 0000000..05cc9fe
--- /dev/null
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/attach/BpmBusinessAttachMapper.java
@@ -0,0 +1,32 @@
+package cn.iocoder.yudao.module.bpm.dal.mysql.attach;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.bpm.controller.admin.attach.vo.attach.BpmBusinessAttachPageReqVO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmBusinessAttachDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * BPM 涓氬姟闄勪欢閰嶇疆 Mapper
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Mapper
+public interface BpmBusinessAttachMapper extends BaseMapperX<BpmBusinessAttachDO> {
+
+ default PageResult<BpmBusinessAttachDO> selectPage(BpmBusinessAttachPageReqVO reqVO) {
+ return selectPage(reqVO, new LambdaQueryWrapperX<BpmBusinessAttachDO>()
+ .likeIfPresent(BpmBusinessAttachDO::getProcessDefinitionKey, reqVO.getProcessDefinitionKey())
+ .likeIfPresent(BpmBusinessAttachDO::getBusinessType, reqVO.getBusinessType())
+ .likeIfPresent(BpmBusinessAttachDO::getComponentPath, reqVO.getComponentPath())
+ .eqIfPresent(BpmBusinessAttachDO::getStatus, reqVO.getStatus())
+ .betweenIfPresent(BpmBusinessAttachDO::getCreateTime, reqVO.getCreateTime())
+ .orderByDesc(BpmBusinessAttachDO::getId));
+ }
+
+ default BpmBusinessAttachDO selectByProcessDefinitionKey(String processDefinitionKey) {
+ return selectOne(BpmBusinessAttachDO::getProcessDefinitionKey, processDefinitionKey);
+ }
+
+}
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
index 0537fe3..a598ff5 100644
--- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
@@ -89,4 +89,8 @@
// ========== BPM 娴佺▼琛ㄨ揪寮� 1-009-014-000 ==========
ErrorCode PROCESS_EXPRESSION_NOT_EXISTS = new ErrorCode(1_009_014_000, "娴佺▼琛ㄨ揪寮忎笉瀛樺湪");
+ // ========== BPM 涓氬姟闄勪欢閰嶇疆 1-009-015-000 ==========
+ ErrorCode BUSINESS_ATTACH_NOT_EXISTS = new ErrorCode(1_009_015_000, "涓氬姟闄勪欢閰嶇疆涓嶅瓨鍦�");
+ ErrorCode BUSINESS_ATTACH_PROCESS_DEFINITION_KEY_DUPLICATE = new ErrorCode(1_009_015_001, "娴佺▼瀹氫箟鐨� Key({})宸插瓨鍦�");
+
}
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/attach/BpmBusinessAttachService.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/attach/BpmBusinessAttachService.java
new file mode 100644
index 0000000..734d37f
--- /dev/null
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/attach/BpmBusinessAttachService.java
@@ -0,0 +1,75 @@
+package cn.iocoder.yudao.module.bpm.service.attach;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.bpm.controller.admin.attach.vo.attach.BpmBusinessAttachPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.attach.vo.attach.BpmBusinessAttachSaveReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmBusinessAttachDO;
+import jakarta.validation.Valid;
+
+/**
+ * BPM 涓氬姟闄勪欢閰嶇疆 Service 鎺ュ彛
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+public interface BpmBusinessAttachService {
+
+ /**
+ * 鍒涘缓涓氬姟闄勪欢閰嶇疆
+ *
+ * @param createReqVO 鍒涘缓淇℃伅
+ * @return 缂栧彿
+ */
+ Long createBusinessAttach(@Valid BpmBusinessAttachSaveReqVO createReqVO);
+
+ /**
+ * 鏇存柊涓氬姟闄勪欢閰嶇疆
+ *
+ * @param updateReqVO 鏇存柊淇℃伅
+ */
+ void updateBusinessAttach(@Valid BpmBusinessAttachSaveReqVO updateReqVO);
+
+ /**
+ * 鍒犻櫎涓氬姟闄勪欢閰嶇疆
+ *
+ * @param id 缂栧彿
+ */
+ void deleteBusinessAttach(Long id);
+
+ /**
+ * 鑾峰緱涓氬姟闄勪欢閰嶇疆
+ *
+ * @param id 缂栧彿
+ * @return 涓氬姟闄勪欢閰嶇疆
+ */
+ BpmBusinessAttachDO getBusinessAttach(Long id);
+
+ /**
+ * 鑾峰緱涓氬姟闄勪欢閰嶇疆鍒嗛〉
+ *
+ * @param pageReqVO 鍒嗛〉鏌ヨ
+ * @return 涓氬姟闄勪欢閰嶇疆鍒嗛〉
+ */
+ PageResult<BpmBusinessAttachDO> getBusinessAttachPage(BpmBusinessAttachPageReqVO pageReqVO);
+
+ /**
+ * 鑾峰緱涓氬姟闄勪欢閰嶇疆锛屽熀浜庢祦绋嬪畾涔� Key
+ *
+ * @param processDefinitionKey 娴佺▼瀹氫箟 Key
+ * @return 涓氬姟闄勪欢閰嶇疆
+ */
+ BpmBusinessAttachDO getBusinessAttachByProcessDefinitionKey(String processDefinitionKey);
+
+ /**
+ * 濉厖涓氬姟琛ㄥ崟淇℃伅鍒版祦绋嬪畾涔� Response
+ *
+ * 鑻ヨ娴佺▼瀹氫箟閰嶇疆浜嗕笟鍔¢檮浠讹紙涓斿凡鍚敤銆佸綋鍓嶆槸 NORMAL 娴佺▼琛ㄥ崟銆佸瓨鍦ㄤ笟鍔′富閿級锛�
+ * 鍒欏皢 formType 瑕嗙洊涓� CUSTOM 骞舵敞鍏ヤ笟鍔¤鎯呯粍浠惰矾寰勶紝瀹炵幇瀹℃壒璇︽儏鑷姩灞曠ず涓氬姟淇℃伅
+ *
+ * @param definitionResp 娴佺▼瀹氫箟 Response
+ * @param processDefinitionKey 娴佺▼瀹氫箟 Key
+ * @param businessKey 涓氬姟鐨勫敮涓�鏍囪瘑锛堟湭鍙戣捣鏃朵负 null锛�
+ */
+ void fillBusinessForm(BpmProcessDefinitionRespVO definitionResp, String processDefinitionKey, String businessKey);
+
+}
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/attach/BpmBusinessAttachServiceImpl.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/attach/BpmBusinessAttachServiceImpl.java
new file mode 100644
index 0000000..2d14ef5
--- /dev/null
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/attach/BpmBusinessAttachServiceImpl.java
@@ -0,0 +1,119 @@
+package cn.iocoder.yudao.module.bpm.service.attach;
+
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.bpm.controller.admin.attach.vo.attach.BpmBusinessAttachPageReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.attach.vo.attach.BpmBusinessAttachSaveReqVO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmBusinessAttachDO;
+import cn.iocoder.yudao.module.bpm.dal.mysql.attach.BpmBusinessAttachMapper;
+import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import java.util.Objects;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.BUSINESS_ATTACH_NOT_EXISTS;
+import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.BUSINESS_ATTACH_PROCESS_DEFINITION_KEY_DUPLICATE;
+
+/**
+ * BPM 涓氬姟闄勪欢閰嶇疆 Service 瀹炵幇绫�
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Service
+@Validated
+public class BpmBusinessAttachServiceImpl implements BpmBusinessAttachService {
+
+ @Resource
+ private BpmBusinessAttachMapper businessAttachMapper;
+
+ @Override
+ public Long createBusinessAttach(BpmBusinessAttachSaveReqVO createReqVO) {
+ // 鏍¢獙娴佺▼瀹氫箟 Key 鍞竴
+ validateProcessDefinitionKeyUnique(createReqVO);
+ // 鎻掑叆
+ BpmBusinessAttachDO attach = BeanUtils.toBean(createReqVO, BpmBusinessAttachDO.class);
+ businessAttachMapper.insert(attach);
+ return attach.getId();
+ }
+
+ @Override
+ public void updateBusinessAttach(BpmBusinessAttachSaveReqVO updateReqVO) {
+ // 鏍¢獙瀛樺湪
+ validateBusinessAttachExists(updateReqVO.getId());
+ // 鏍¢獙娴佺▼瀹氫箟 Key 鍞竴
+ validateProcessDefinitionKeyUnique(updateReqVO);
+ // 鏇存柊
+ BpmBusinessAttachDO updateObj = BeanUtils.toBean(updateReqVO, BpmBusinessAttachDO.class);
+ businessAttachMapper.updateById(updateObj);
+ }
+
+ private void validateProcessDefinitionKeyUnique(BpmBusinessAttachSaveReqVO reqVO) {
+ BpmBusinessAttachDO attach = businessAttachMapper.selectByProcessDefinitionKey(reqVO.getProcessDefinitionKey());
+ if (attach == null || ObjUtil.equal(attach.getId(), reqVO.getId())) {
+ return;
+ }
+ throw exception(BUSINESS_ATTACH_PROCESS_DEFINITION_KEY_DUPLICATE, reqVO.getProcessDefinitionKey());
+ }
+
+ @Override
+ public void deleteBusinessAttach(Long id) {
+ // 鏍¢獙瀛樺湪
+ validateBusinessAttachExists(id);
+ // 鍒犻櫎
+ businessAttachMapper.deleteById(id);
+ }
+
+ private BpmBusinessAttachDO validateBusinessAttachExists(Long id) {
+ BpmBusinessAttachDO attach = businessAttachMapper.selectById(id);
+ if (attach == null) {
+ throw exception(BUSINESS_ATTACH_NOT_EXISTS);
+ }
+ return attach;
+ }
+
+ @Override
+ public BpmBusinessAttachDO getBusinessAttach(Long id) {
+ return businessAttachMapper.selectById(id);
+ }
+
+ @Override
+ public PageResult<BpmBusinessAttachDO> getBusinessAttachPage(BpmBusinessAttachPageReqVO pageReqVO) {
+ return businessAttachMapper.selectPage(pageReqVO);
+ }
+
+ @Override
+ public BpmBusinessAttachDO getBusinessAttachByProcessDefinitionKey(String processDefinitionKey) {
+ return businessAttachMapper.selectByProcessDefinitionKey(processDefinitionKey);
+ }
+
+ @Override
+ public void fillBusinessForm(BpmProcessDefinitionRespVO definitionResp, String processDefinitionKey, String businessKey) {
+ // 鏈彂璧� / 鏃犱笟鍔′富閿細涓嶆敞鍏�
+ if (definitionResp == null || StrUtil.isBlank(businessKey)) {
+ return;
+ }
+ // 闈� NORMAL 娴佺▼琛ㄥ崟锛堝凡鎵嬪姩閰嶇疆 CUSTOM锛夛細涓嶈鐩�
+ if (!Objects.equals(definitionResp.getFormType(), BpmModelFormTypeEnum.NORMAL.getType())) {
+ return;
+ }
+ // 鏈懡涓厤缃� / 閰嶇疆琚鐢細淇濇寔鍘熸牱
+ BpmBusinessAttachDO attach = getBusinessAttachByProcessDefinitionKey(processDefinitionKey);
+ if (attach == null || !Objects.equals(attach.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
+ return;
+ }
+ // 瑕嗙洊涓� CUSTOM锛屾敞鍏ヤ笟鍔¤鎯呯粍浠惰矾寰�
+ definitionResp.setFormType(BpmModelFormTypeEnum.CUSTOM.getType());
+ definitionResp.setFormCustomViewPath(attach.getComponentPath());
+ // 娓呯┖鏅�氳〃鍗曞瓧娈碉細璇︽儏椤� CUSTOM 鍒嗘敮涓嶈锛涙墦鍗伴〉鎸� formFields.length == 0 鍒ゆ柇娓叉煋涓氬姟缁勪欢
+ definitionResp.setFormFields(null);
+ definitionResp.setFormConf(null);
+ }
+
+}
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
index f7d2dd5..85ff097 100644
--- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
@@ -37,6 +37,7 @@
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils;
+import cn.iocoder.yudao.module.bpm.service.attach.BpmBusinessAttachService;
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
@@ -123,6 +124,9 @@
@Resource
private BpmProcessIdRedisDAO processIdRedisDAO;
+
+ @Resource
+ private BpmBusinessAttachService businessAttachService;
// ========== Query 鏌ヨ鐩稿叧鏂规硶 ==========
@@ -389,9 +393,14 @@
Map<String, String> formFieldsPermission = getFormFieldsPermission(bpmnModel, reqVO.getActivityId(), taskId);
// 3. 鎷兼帴鏁版嵁
- return BpmProcessInstanceConvert.INSTANCE.buildApprovalDetail(bpmnModel, processDefinition,
- processDefinitionInfo, processInstance,
+ BpmApprovalDetailRespVO detailRespVO = BpmProcessInstanceConvert.INSTANCE.buildApprovalDetail(bpmnModel,
+ processDefinition, processDefinitionInfo, processInstance,
processInstanceStatus, approveNodes, todoTask, formFieldsPermission, userMap, deptMap);
+
+ // 4. 濉厖涓氬姟闄勪欢閰嶇疆锛屽疄鐜板鎵硅鎯呰嚜鍔ㄥ睍绀哄閮ㄤ笟鍔′俊鎭�
+ businessAttachService.fillBusinessForm(detailRespVO.getProcessDefinition(), processDefinition.getKey(),
+ processInstance != null ? processInstance.getBusinessKey() : null);
+ return detailRespVO;
}
/**
--
Gitblit v1.9.3