From d26a081e99514ed3b14e8df78e9433e15091aa56 Mon Sep 17 00:00:00 2001
From: wsm <2746563060@侵权。>
Date: Tue, 12 May 2026 15:34:52 +0800
Subject: [PATCH] =?UTF-8?q?wsm-=E4=BF=AE=E6=94=B9xispeak=E7=9D=A3=E5=8A=9E?=
=?UTF-8?q?=E8=AE=A1=E5=88=92=E6=B5=81=E7=A8=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
jeecg-boot-module/jeecg-module-flow/pom.xml | 4 +
.../java/org/jeecg/xispeak/XiSpeakConfig.java | 5 +
.../java/org/jeecg/xispeak/XiSpeakFlow.java | 48 ++++++-
.../AfterImplDeptLeaderApproveListener.java | 131 ++++++++++++++++++
.../AfterImplWorkerApproveListener.java | 119 ++++++++++++++++
.../listener/AfterSDWApproveHqListener.java | 2 +-
.../src/main/resources/application-flow.yml | 5 +
jeecg-boot-module/pom.xml | 1 +
.../modules/bg/xispeak/entity/BgXiSpeak.java | 14 +-
.../bg/xispeak/entity/DeptApproveDetail.java | 17 +++
.../bg/xispeak/service/IBgXiSpeakService.java | 1 +
.../service/impl/BgXiSpeakServiceImpl.java | 6 +
12 files changed, 345 insertions(+), 8 deletions(-)
create mode 100644 jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterImplDeptLeaderApproveListener.java
create mode 100644 jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterImplWorkerApproveListener.java
create mode 100644 jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/DeptApproveDetail.java
diff --git a/jeecg-boot-module/jeecg-module-flow/pom.xml b/jeecg-boot-module/jeecg-module-flow/pom.xml
index 608b87b..4512356 100644
--- a/jeecg-boot-module/jeecg-module-flow/pom.xml
+++ b/jeecg-boot-module/jeecg-module-flow/pom.xml
@@ -36,6 +36,10 @@
org.jeecgframework.boot
jeecg-system-biz
+
+ org.jeecgframework.boot
+ jeecg-module-supervision
+
\ No newline at end of file
diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakConfig.java b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakConfig.java
index d5f6ef8..4cbba04 100644
--- a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakConfig.java
+++ b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakConfig.java
@@ -31,5 +31,10 @@ public class XiSpeakConfig {
private String implDeptCollectionUsedKey;
/** 对应sdw-role-id*/
private String sdwRoleId;
+ /** 对应business-key*/
+ private String businessKey;
+ /** 对应impl-dept-key-underscore-key*/
+ private String implDeptKeyUnderscoreKey;
+ private String deptWorkerKey;
}
}
diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakFlow.java b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakFlow.java
index 61576fd..1645eda 100644
--- a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakFlow.java
+++ b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/XiSpeakFlow.java
@@ -6,6 +6,8 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.util.StringUtils;
import org.flowable.engine.RuntimeService;
+import org.flowable.engine.delegate.DelegateExecution;
+import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -83,8 +85,12 @@ public class XiSpeakFlow {
} else {
data = JSONObject.parseObject(JSONObject.toJSONString(jsonData));
}
- log.info("needSdwApproval结果为{}", data.getInteger(codeName));
- return data == null ? 0 : data.getInteger(codeName);
+ int finalResult = Optional.ofNullable(data)
+ .map(d -> d.getInteger(codeName))
+ .orElse(0);
+
+ log.info("needSdwApproval结果为{}", finalResult);
+ return finalResult;
} catch (Exception e) {
log.warn("getJsondata parse failed, codeName={}, jsonData={}", codeName, jsonData, e);
return 0;
@@ -154,4 +160,42 @@ public class XiSpeakFlow {
return resultList.size();
}
+
+ public List getDeptWorkerList(DelegateExecution execution) {
+ String variableName = xiSpeakConfig.getXiSpeak().getDeptWorkerKey();
+ if (execution == null || org.apache.commons.lang.StringUtils.isBlank(variableName)) {
+ return Collections.emptyList();
+ }
+
+ try {
+ // 1. 优先尝试从当前 Execution 的局部作用域获取
+ // 在多实例(会签)中,每个分支特有的变量(如 item 变量)通常存储在这里
+ Object value = execution.getVariableLocal(variableName);
+
+ // 2. 如果局部没有,直接使用 getVariable 获取
+ // 该方法会自动向上追溯:当前 Execution -> 父 Execution -> 流程实例(Global)
+ if (value == null) {
+ value = execution.getVariable(variableName);
+ }
+
+ // 3. 结果处理
+ if (value != null) {
+ return splitUsernames(value);
+ }
+ } catch (Exception e) {
+ log.warn("getSonProcessVariable 失败, executionId={}, variableName={}",
+ execution.getId(), variableName, e);
+ }
+
+ return Collections.emptyList();
+ }
+ private List splitUsernames(Object value) {
+ if (value == null) {
+ return Collections.emptyList();
+ }
+ return Arrays.stream(String.valueOf(value).split(SymbolConstant.COMMA))
+ .map(String::trim)
+ .filter(org.apache.commons.lang.StringUtils::isNotBlank)
+ .collect(Collectors.toList());
+ }
}
diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterImplDeptLeaderApproveListener.java b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterImplDeptLeaderApproveListener.java
new file mode 100644
index 0000000..0a302bb
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterImplDeptLeaderApproveListener.java
@@ -0,0 +1,131 @@
+package org.jeecg.xispeak.listener;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.flowable.engine.delegate.TaskListener;
+import org.flowable.task.service.delegate.DelegateTask;
+import org.jeecg.modules.bg.xispeak.entity.BgXiSpeak;
+import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetail;
+import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakService;
+import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression;
+import lombok.RequiredArgsConstructor;
+import org.flowable.engine.RuntimeService;
+import org.flowable.engine.delegate.DelegateExecution;
+import org.flowable.engine.delegate.ExecutionListener;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.extbpm.process.common.WorkFlowGlobals;
+import org.jeecg.modules.tasktask.entity.TaskTask;
+import org.jeecg.modules.tasktask.service.ITaskTaskService;
+import org.jeecg.xispeak.XiSpeakConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component("AfterImplDeptLeaderApproveListener")
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+public class AfterImplDeptLeaderApproveListener implements TaskListener {
+
+ private static final long serialVersionUID = 1L;
+ private final FlowNodeExpression flowNodeExpression;
+ private final RuntimeService runtimeService;
+ private final XiSpeakConfig xiSpeakConfig;
+ private final ITaskTaskService taskTaskService;
+ private final IBgXiSpeakService bgXiSpeakService;
+
+// @Override
+// @Transactional(rollbackFor = Exception.class)
+// public void notify(DelegateTask delegateTask) {
+//
+// // 1. 获取审批人
+// String currentAssignee = delegateTask.getAssignee();
+// if (StringUtils.isEmpty(currentAssignee)) {
+// // 使用你给出的正确获取方式:扫描 Execution 树获取局部变量
+// return;
+// }
+//
+// // 2. 获取业务主键:通常业务 ID 是全局变量,可以直接 getVariable
+// Object rawTaskTaskId = delegateTask.getVariable(xiSpeakConfig.getXiSpeak().getBusinessKey());
+//
+// if (StringUtils.isEmpty(currentAssignee) || rawTaskTaskId == null) {
+// log.warn("无法获取有效的审批人或业务ID,ExecutionId: {}, TaskId: {}",
+// delegateTask.getExecutionId(), delegateTask.getId());
+// return;
+// }
+//
+// // 3. 获取业务实体
+// BgXiSpeak xiSpeak = bgXiSpeakService.getById(rawTaskTaskId.toString());
+// if (xiSpeak == null) return;
+//
+// // 4. 处理数据结构
+// Map deptApproveDetailMap = Optional.ofNullable(xiSpeak.getApproveInfo())
+// .orElse(new HashMap<>());
+//
+// // 5. 获取实施部门 ID:同样使用全路径搜索,确保在嵌套会签中能精准定位局部变量
+// String implDeptKey = xiSpeakConfig.getXiSpeak().getImplDeptCollectionUsedKey();
+// String rawDeptVar = delegateTask.getVariable(implDeptKey).toString();
+//
+// if (StringUtils.isBlank(rawDeptVar)) {
+// throw new RuntimeException("流程数据异常:未找到实施部门ID变量: " + implDeptKey);
+// }
+//
+// // 清洗字符串(处理 [id1, id2] 格式)
+// String cleanDeptId = rawDeptVar.replace("[", "").replace("]", "").trim();
+//
+// // computeIfAbsent 的特性:如果 key 存在,返回 value;如果不存在,运行 lambda 并存入再返回。
+// DeptApproveDetail detail = deptApproveDetailMap.computeIfAbsent(cleanDeptId, k -> new DeptApproveDetail());
+//
+// // 2. 只有当 approverName 为空时(即该对象是刚新建的,或者之前没存过审批人),才进行赋值
+// if (StringUtils.isBlank(detail.getApproverName())) {
+// detail.setApproverName(currentAssignee);
+//
+// // 3. 只有发生了赋值,才执行数据库更新(可选,为了性能)
+// xiSpeak.setApproveInfo(deptApproveDetailMap);
+// bgXiSpeakService.updateById(xiSpeak);
+// log.info("部门 {} 首次审批,已记录审批人: {}", cleanDeptId, currentAssignee);
+// } else {
+// log.info("部门 {} 已存在审批记录: {},跳过本次回写", cleanDeptId, detail.getApproverName());
+// }
+// }
+
+ @Transactional(rollbackFor = Exception.class)
+ public void notify(DelegateTask delegateTask) {
+ // 1. 获取基础数据
+ String currentAssignee = delegateTask.getAssignee();
+ Object rawTaskTaskId = delegateTask.getVariable(xiSpeakConfig.getXiSpeak().getBusinessKey());
+ String implDeptKey = xiSpeakConfig.getXiSpeak().getImplDeptCollectionUsedKey();
+ String rawDeptVar = delegateTask.getVariable(implDeptKey).toString();
+ String cleanDeptId = rawDeptVar.replace("[", "").replace("]", "").trim();
+
+ // 2. 【核心】使用行锁查询,确保拿到的是数据库此刻最真实、最新的数据
+ // 同时也让其他并发的审批线程在这里“排队”等待
+ BgXiSpeak xiSpeak = bgXiSpeakService.getByIdForUpdate(rawTaskTaskId.toString());
+ if (xiSpeak == null) return;
+
+ // 3. 操作 Map
+ Map map = xiSpeak.getApproveInfo();
+ if (map == null) map = new HashMap<>();
+
+ // 4. 获取或创建详情对象
+ // 使用你定义的 POJO
+ DeptApproveDetail detail = map.getOrDefault(cleanDeptId, new DeptApproveDetail());
+
+ // 只有没审批过才记录(防止重复触发覆盖已有数据)
+ if (StringUtils.isBlank(detail.getApproverName())) {
+ detail.setDeptId(cleanDeptId);
+ detail.setApproverName(currentAssignee);
+ // 这里可以根据需要设置其他字段,比如 detail.setApproverId(...)
+
+ map.put(cleanDeptId, detail);
+ xiSpeak.setApproveInfo(map);
+
+ // 5. 写回数据库
+ // 因为有了 FOR UPDATE,这里的更新绝对是基于最新数据的增量合并
+ bgXiSpeakService.updateById(xiSpeak);
+ }
+ }
+}
\ No newline at end of file
diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterImplWorkerApproveListener.java b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterImplWorkerApproveListener.java
new file mode 100644
index 0000000..017011e
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterImplWorkerApproveListener.java
@@ -0,0 +1,119 @@
+package org.jeecg.xispeak.listener;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.flowable.engine.delegate.TaskListener;
+import org.flowable.task.service.delegate.DelegateTask;
+import org.jeecg.modules.bg.xispeak.entity.BgXiSpeak;
+import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetail;
+import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakService;
+import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression;
+import lombok.RequiredArgsConstructor;
+import org.flowable.engine.RuntimeService;
+import org.flowable.engine.delegate.DelegateExecution;
+import org.flowable.engine.delegate.ExecutionListener;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.extbpm.process.common.WorkFlowGlobals;
+import org.jeecg.modules.tasktask.entity.TaskTask;
+import org.jeecg.modules.tasktask.service.ITaskTaskService;
+import org.jeecg.xispeak.XiSpeakConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+@Slf4j
+@Component("AfterImplWorkerApproveListener")
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+public class AfterImplWorkerApproveListener implements TaskListener {
+
+ private static final long serialVersionUID = 1L;
+ private final XiSpeakConfig xiSpeakConfig;
+ private final IBgXiSpeakService bgXiSpeakService;
+
+ // 引入 Jackson 的 ObjectMapper 用于处理类型转换失败的情况
+ private final com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void notify(DelegateTask delegateTask) {
+ String currentWorkerName = delegateTask.getAssignee();
+ Object rawBusinessKey = delegateTask.getVariable(xiSpeakConfig.getXiSpeak().getBusinessKey());
+
+ if (StringUtils.isEmpty(currentWorkerName) || rawBusinessKey == null) {
+ log.warn("无法获取有效的审批人或业务ID,略过处理");
+ return;
+ }
+
+ BgXiSpeak xiSpeak = bgXiSpeakService.getByIdForUpdate(rawBusinessKey.toString());
+ if (xiSpeak == null) {
+ log.error("业务数据不存在: {}", rawBusinessKey);
+ return;
+ }
+
+ String implDeptKey = xiSpeakConfig.getXiSpeak().getImplDeptCollectionUsedKey();
+ Object rawDeptVar = delegateTask.getVariableLocal(implDeptKey);
+ if (rawDeptVar == null) {
+ rawDeptVar = delegateTask.getVariable(implDeptKey);
+ }
+
+ if (rawDeptVar == null) {
+ log.error("流程数据异常:未找到实施部门ID变量: {}", implDeptKey);
+ return;
+ }
+
+ String cleanDeptId = rawDeptVar.toString().replace("[", "").replace("]", "").trim();
+
+ // --- 修改开始:处理复杂的 Map 转换问题 ---
+
+ // 1. 获取原始 Map (这里使用通配符,避免直接强转报错)
+ Map rawApproveMap = (Map) xiSpeak.getApproveInfo();
+ if (rawApproveMap == null) {
+ rawApproveMap = new HashMap<>();
+ }
+
+ // 2. 获取该部门对应的详情,并进行安全类型检查
+ Object rawDetail = rawApproveMap.get(cleanDeptId);
+ DeptApproveDetail detail;
+
+ if (rawDetail == null) {
+ // 情况 A: 部门记录不存在,新建
+ detail = new DeptApproveDetail();
+ detail.setDeptId(cleanDeptId);
+ detail.setImplUserNameList(new ArrayList<>());
+ rawApproveMap.put(cleanDeptId, detail);
+ } else if (rawDetail instanceof DeptApproveDetail) {
+ // 情况 B: 类型正确,直接使用
+ detail = (DeptApproveDetail) rawDetail;
+ } else {
+ // 情况 C: 就是你遇到的报错点!类型是 LinkedHashMap,需要转换
+ log.debug("检测到 LinkedHashMap 类型,执行手动转换...");
+ detail = objectMapper.convertValue(rawDetail, DeptApproveDetail.class);
+ // 转换后放回 Map,防止后续逻辑再次触发转换
+ rawApproveMap.put(cleanDeptId, detail);
+ }
+
+ // --- 修改结束 ---
+
+ // 5. 更新落实人列表
+ List workerList = detail.getImplUserNameList();
+ if (workerList == null) {
+ workerList = new ArrayList<>();
+ }
+
+ if (!workerList.contains(currentWorkerName)) {
+ workerList.add(currentWorkerName);
+ detail.setImplUserNameList(workerList);
+
+ // 重新写回 Map 并保存
+ // 声明:虽然 rawApproveMap 里的 Value 是 Object,但写回数据库时 TypeHandler 会处理它
+ xiSpeak.setApproveInfo((Map) rawApproveMap);
+ bgXiSpeakService.updateById(xiSpeak);
+ log.info("部门 {} 经办人审批记录更新成功: {}", cleanDeptId, currentWorkerName);
+ } else {
+ log.info("部门 {} 经办人 {} 已在列表中,跳过更新", cleanDeptId, currentWorkerName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterSDWApproveHqListener.java b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterSDWApproveHqListener.java
index 9d13a44..17557d5 100644
--- a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterSDWApproveHqListener.java
+++ b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeak/listener/AfterSDWApproveHqListener.java
@@ -1,4 +1,4 @@
-package org.jeecg.modules.extbpm.listener.execution;
+package org.jeecg.xispeak.listener;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression;
diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/resources/application-flow.yml b/jeecg-boot-module/jeecg-module-flow/src/main/resources/application-flow.yml
index b4b7d1d..d6111c3 100644
--- a/jeecg-boot-module/jeecg-module-flow/src/main/resources/application-flow.yml
+++ b/jeecg-boot-module/jeecg-module-flow/src/main/resources/application-flow.yml
@@ -5,5 +5,10 @@ flow-biz:
need-sdw-approve-code: "needSdwApproval"
json-data-key: "json_data"
impl-dept-key: "implDept"
+ impl-dept-key-underscore-key: "impl_dept"
impl-dept-collection-used-key: "impl_dept_id"
sdw-role-id: "2044676455280570370"
+ business-key: "business_id"
+ dept-worker-key: "subApproveUser"
+
+
diff --git a/jeecg-boot-module/pom.xml b/jeecg-boot-module/pom.xml
index dcfafbc..09f9d60 100644
--- a/jeecg-boot-module/pom.xml
+++ b/jeecg-boot-module/pom.xml
@@ -18,6 +18,7 @@
jeecg-boot-module-airag
+ jeecg-module-flow
diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeak.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeak.java
index 511c5b8..3b071cc 100644
--- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeak.java
+++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeak.java
@@ -3,10 +3,9 @@ package org.jeecg.modules.bg.xispeak.entity;
import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.annotation.TableLogic;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import org.jeecg.common.constant.ProvinceCityArea;
import org.jeecg.common.util.SpringContextUtils;
import lombok.Data;
@@ -17,6 +16,8 @@ import org.jeecg.common.aspect.annotation.Dict;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Map;
/**
* @Description: 习总书记重要讲话指示批示情况
@@ -25,7 +26,7 @@ import java.io.UnsupportedEncodingException;
* @Version: V1.0
*/
@Data
-@TableName("bg_xi_speak")
+@TableName(value = "bg_xi_speak", autoResultMap = true)
@Schema(description="习总书记重要讲话指示批示情况")
public class BgXiSpeak implements Serializable {
private static final long serialVersionUID = 1L;
@@ -165,4 +166,7 @@ public class BgXiSpeak implements Serializable {
@Excel(name = "是否需要sdw审批", width = 15)
@Schema(description = "是否需要sdw审批")
private java.lang.Integer needSdwApproval;
+
+ @TableField(typeHandler = JacksonTypeHandler.class)
+ private Map approveInfo;
}
diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/DeptApproveDetail.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/DeptApproveDetail.java
new file mode 100644
index 0000000..217ba1d
--- /dev/null
+++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/DeptApproveDetail.java
@@ -0,0 +1,17 @@
+package org.jeecg.modules.bg.xispeak.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+@Data
+@NoArgsConstructor // 必须确保有这个
+@AllArgsConstructor
+public class DeptApproveDetail {
+ private String deptId; // 部门ID
+ private String approverId; // 审批人ID(从监听器获取的)
+ private String approverName; // 审批人姓名(可选)
+ private List implUserIdList; // 落实人Id
+ private List implUserNameList; // 落实人姓名
+}
\ No newline at end of file
diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakService.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakService.java
index 688714a..a12cff5 100644
--- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakService.java
+++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakService.java
@@ -71,4 +71,5 @@ public interface IBgXiSpeakService extends IService {
*/
List queryListByPid(String pid);
+ BgXiSpeak getByIdForUpdate(String id);
}
diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakServiceImpl.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakServiceImpl.java
index 1166be2..c8a6c60 100644
--- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakServiceImpl.java
+++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakServiceImpl.java
@@ -216,4 +216,10 @@ public class BgXiSpeakServiceImpl extends ServiceImpl()
+ .eq(BgXiSpeak::getId, id)
+ .last("for update"));
+ }
}