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 4cbba04..7629dec 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 @@ -14,7 +14,6 @@ public class XiSpeakConfig { */ private XiSpeakProperties xiSpeak; - @Data public static class XiSpeakProperties { /** 对应 bg-dept-id */ @@ -36,5 +35,7 @@ public class XiSpeakConfig { /** 对应impl-dept-key-underscore-key*/ private String implDeptKeyUnderscoreKey; private String deptWorkerKey; + private String xiSpeakFbFlowCode; + private String formUrl; } } 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 1645eda..12a6fe5 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 @@ -24,6 +24,7 @@ public class XiSpeakFlow { private final ISysBaseAPI iSysBaseAPI; private final RuntimeService runtimeService; + //流程表达式内用法 ${xiSpeakFlow.getBgDeptLdUserIdList()} public List getBgDeptLdUserIdList() { // 1. 安全获取配置,防止 NPE XiSpeakConfig.XiSpeakProperties props = xiSpeakConfig.getXiSpeak(); @@ -61,7 +62,7 @@ public class XiSpeakFlow { return this.getSDWLeader().size(); } - + //流程表达式内用法 ${xiSpeakFlow.getBgDeptLdUserIdListLength()} public int getBgDeptLdUserIdListLength() { return getBgDeptLdUserIdList().size(); } 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 index 0a302bb..c40f381 100644 --- 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 @@ -37,61 +37,6 @@ public class AfterImplDeptLeaderApproveListener implements TaskListener { 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. 获取基础数据 diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeakfb/XiSpeakFeedbackConfig.java b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeakfb/XiSpeakFeedbackConfig.java new file mode 100644 index 0000000..40d4e28 --- /dev/null +++ b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeakfb/XiSpeakFeedbackConfig.java @@ -0,0 +1,26 @@ +package org.jeecg.xispeakfb; + +import lombok.Data; +import org.jeecg.xispeak.XiSpeakConfig; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Data +@Component +@ConfigurationProperties(prefix = "flow-biz") +public class XiSpeakFeedbackConfig { + /** + * 复用 xi-speak 配置节点 + * 两个模块共用同一份配置 + */ + private XiSpeakFeedbackConfig.XiSpeakPropertiesFb xiSpeakFb; + + @Data + public static class XiSpeakPropertiesFb { + String deptId; + String businessId; + String jjDeptId; + String jjWorkerRoleId; + String jjLeaderRoleId; + } +} diff --git a/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeakfb/XiSpeakFeedbackFlow.java b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeakfb/XiSpeakFeedbackFlow.java new file mode 100644 index 0000000..da2b60c --- /dev/null +++ b/jeecg-boot-module/jeecg-module-flow/src/main/java/org/jeecg/xispeakfb/XiSpeakFeedbackFlow.java @@ -0,0 +1,290 @@ +package org.jeecg.xispeakfb; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import org.apache.commons.lang3.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.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.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.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Component("XiSpeakFeedbackFlow") +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class XiSpeakFeedbackFlow { + + private final XiSpeakFeedbackConfig xiSpeakFeedbackConfig; + private final ISysBaseAPI iSysBaseAPI; + private final RuntimeService runtimeService; + private final IBgXiSpeakService bgXiSpeakService; + private final ITaskTaskService taskTaskService; + + + // 流程表达式内用法 ${XiSpeakFeedbackFlow.getImplDeptList()} + public List getImplDeptList(DelegateExecution execution) { + String processInstId = execution.getProcessInstanceId(); + String businessKey = execution.getProcessInstanceBusinessKey(); + + if (StringUtils.isAnyBlank(processInstId, businessKey)) { + log.warn("流程上下文中业务关键信息缺失![ProcessInstanceId: {}, BusinessKey: {}, ExecutionId: {}, ActivityId: {}]", + processInstId, businessKey, execution.getId(), execution.getCurrentActivityId()); + return Collections.emptyList(); + } + + BgXiSpeak xiSpeak = bgXiSpeakService.getById(businessKey); + if (xiSpeak == null) { + log.warn("根据查询到的业务表单id无法获取业务数据行![BusinessKey: {}]", businessKey); + return Collections.emptyList(); + } + + Map approveInfoMap = xiSpeak.getApproveInfo(); + if (approveInfoMap == null || approveInfoMap.isEmpty()) { + log.warn("根据查询到的业务表单数据无法获取对应的审批信息![BgXiSpeak: {}]", xiSpeak); + return Collections.emptyList(); + } + + List deptIdList = approveInfoMap.keySet().stream() + .filter(StringUtils::isNotBlank) // 可选:过滤掉空的Key + .collect(Collectors.toList()); + + return deptIdList; + } + + // 流程表达式内用法 ${XiSpeakFeedbackFlow.getImplDeptListLength()} + public int getImplDeptListLength(DelegateExecution execution) { + List implDeptList = this.getImplDeptList(execution); + if (implDeptList.isEmpty() || implDeptList == null) { + log.warn("当前节点无经办部门{}!", execution); + return 0; + } + return implDeptList.size(); + } + + public String getImplDeptApprove(DelegateExecution execution) { + String businessKey = execution.getProcessInstanceBusinessKey(); + + // 1. 基础校验 + if (StringUtils.isBlank(businessKey)) { + log.warn("流程 BusinessKey 缺失,ExecutionId: {}", execution.getId()); + return StringUtils.EMPTY; + } + + // 2. 获取任务主表数据 + TaskTask taskTask = taskTaskService.getById(businessKey); + if (taskTask == null || StringUtils.isBlank(taskTask.getBusinessId())) { + log.warn("无法获取任务数据或业务关联ID![taskTaskId: {}]", businessKey); + return StringUtils.EMPTY; + } + + // 3. 获取业务表单数据 + BgXiSpeak xiSpeak = bgXiSpeakService.getById(taskTask.getBusinessId()); + if (xiSpeak == null || xiSpeak.getApproveInfo() == null) { + log.warn("业务表单数据或审批配置缺失![xiBusinessId: {}]", taskTask.getBusinessId()); + return StringUtils.EMPTY; + } + + // 4. 获取匹配参数 + String handlerName = taskTask.getDeptHandlerName(); + if (StringUtils.isBlank(handlerName)) { + return StringUtils.EMPTY; + } + + // --- 核心修复部分 --- + // 从 DB 或缓存取出的 Map,其 Value 在运行时往往是 LinkedHashMap + Map approveInfoMap = xiSpeak.getApproveInfo(); + + // 建议将 ObjectMapper 定义为静态常量或通过 Spring 注入,此处为演示保持局部定义 + ObjectMapper mapper = new ObjectMapper(); + + return approveInfoMap.values().stream() + // 重点 1: 强制声明为 Object 接收,跳过隐式的 (DeptApproveDetail) 强转 + .map((Object obj) -> { + try { + // 重点 2: 如果已经是对象则直接转,否则进行 Jackson 转换 + if (obj instanceof DeptApproveDetail) { + return (DeptApproveDetail) obj; + } + return mapper.convertValue(obj, DeptApproveDetail.class); + } catch (Exception e) { + log.error("审批明细类型转换失败: {}", obj, e); + return null; + } + }) + .filter(Objects::nonNull) // 过滤掉转换失败的元素 + .filter(detail -> detail.getImplUserNameList() != null && detail.getImplUserNameList().contains(handlerName)) + .map(DeptApproveDetail::getApproverName) + .findFirst() + .orElse(""); + } + + /** + * 获取当前流程的经办部门的经办人。 + *

用于流程表达式判断,通过 BusinessKey 关联业务主键,获取当前经办人。

+ * + * @param execution 流程执行上下文 + * @return 经办部门经办人 + * @example 表达式用法: ${XiSpeakFeedbackFlow.getImplDeptWorker()} + */ + public List getImplDeptWorker(DelegateExecution execution) { + String businessKey = execution.getProcessInstanceBusinessKey(); + + // 1. 基础校验 + if (StringUtils.isBlank(businessKey)) { + log.warn("流程 BusinessKey 缺失,ExecutionId: {}", execution.getId()); + return Collections.emptyList(); + } + + // 2. 获取任务主表数据并判空 + TaskTask taskTask = taskTaskService.getById(businessKey); + if (taskTask == null || StringUtils.isBlank(taskTask.getBusinessId())) { + log.warn("无法获取任务数据或业务关联ID![taskTaskId: {}]", businessKey); + return Collections.emptyList(); + } + + String implDeptWorker = taskTask.getDeptHandlerName(); + if (StringUtils.isBlank(implDeptWorker)) { + log.warn("中间表taskTask[id={}]没有经办人数据", businessKey); + return Collections.emptyList(); + } + + // 将 "张三, 李四 " 转换为 ["张三", "李四"] + return Arrays.stream(implDeptWorker.split(",")) + .map(String::trim) // 去掉前后空格 + .filter(StringUtils::isNotBlank) // 过滤掉空字符串(防止出现 "张三,,李四") + .collect(Collectors.toList()); + } + + /** + * 经办部门经办人数量 + *

经办部门经办人数量

+ * + * @param execution 流程执行上下文 + * @return 经办部门经办人数量 + * @example 表达式用法: ${XiSpeakFeedbackFlow.getImplDeptWorkerLength()} + */ + public int getImplDeptWorkerLength(DelegateExecution execution) { + List implDeptWorkerList = this.getImplDeptWorker(execution); + if (implDeptWorkerList == null || implDeptWorkerList.isEmpty()) { + log.warn("{}流程经办部门经办人数量为0",execution.getProcessInstanceId()); + return 0; + } + return implDeptWorkerList.size(); + } + + /** + * 获取jj部门经办人 + *

jj部门经办人

+ * + * @return jj部门经办人 + * @example 表达式用法: ${XiSpeakFeedbackFlow.JJDeptWorkerList()} + */ + public List getJJDeptWorkerList() { + // 1. 安全获取配置对象 + XiSpeakFeedbackConfig.XiSpeakPropertiesFb config = xiSpeakFeedbackConfig.getXiSpeakFb(); + if (config == null) { + log.error("xiSpeakFb 配置对象加载失败,请检查配置文件!"); + return Collections.emptyList(); + } + + String deptId = config.getJjDeptId(); + String roleId = config.getJjWorkerRoleId(); + + // 2. 参数合法性拦截 + if (StringUtils.isAnyBlank(deptId, roleId)) { + log.warn("xiSpeakFb 配置项不完整: deptId={}, roleId={}", deptId, roleId); + return Collections.emptyList(); + } + + // 3. 调用接口并处理结果 + List workerList = iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi(deptId, roleId); + + if (CollectionUtils.isEmpty(workerList)) { + log.warn("未查找到匹配的部门经办人 [deptId: {}, roleId: {}]", deptId, roleId); + return Collections.emptyList(); + } + + return workerList; + } + + /** + * 获取jj部门经办人列表长度 + *

获取jj部门经办人列表长度

+ * + * @return jj部门经办人列表长度 + * @example 表达式用法: ${XiSpeakFeedbackFlow.getJJDeptWorkerListLength()} + */ + public int getJJDeptWorkerListLength() { + List jjDeptWorkerList = this.getJJDeptWorkerList(); + if (jjDeptWorkerList == null || jjDeptWorkerList.isEmpty()) { + log.warn("获取jj部经办人数量为0"); + return 0; + } + return jjDeptWorkerList.size(); + } + + /** + * 获取jj部门审核人 + *

获取jj部门审核人

+ * + * @return jj部门审核人 + * @example 表达式用法: ${XiSpeakFeedbackFlow.getJjDeptLeaderList()} + */ + public List getJJDeptLeaderList() { + // 1. 安全获取配置对象 + XiSpeakFeedbackConfig.XiSpeakPropertiesFb config = xiSpeakFeedbackConfig.getXiSpeakFb(); + if (config == null) { + log.error("xiSpeakFb 配置对象加载失败,请检查配置文件!"); + return Collections.emptyList(); + } + + String deptId = config.getJjDeptId(); + String roleId = config.getJjLeaderRoleId (); + + // 2. 参数合法性拦截 + if (StringUtils.isAnyBlank(deptId, roleId)) { + log.warn("xiSpeakFb 配置项不完整: deptId={}, roleId={}", deptId, roleId); + return Collections.emptyList(); + } + + // 3. 调用接口并处理结果 + List workerList = iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi(deptId, roleId); + + if (CollectionUtils.isEmpty(workerList)) { + log.warn("未查找到匹配的部门审核人 [deptId: {}, roleId: {}]", deptId, roleId); + return Collections.emptyList(); + } + return workerList; + } + + /** + * 获取jj部门审核人列表长度 + *

获取jj部门审核人列表长度

+ * + * @return jj部门审核人列表长度 + * @example 表达式用法: ${XiSpeakFeedbackFlow.getJJDeptLeaderListLength()} + */ + public int getJJDeptLeaderListLength() { + List jjDeptWorkerList = this.getJJDeptLeaderList(); + if (jjDeptWorkerList == null || jjDeptWorkerList.isEmpty()) { + log.warn("[获取JJ部审批人数量为0]"); + return 0; + } + return jjDeptWorkerList.size(); + } +} 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 d6111c3..c4adcbf 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 @@ -10,5 +10,14 @@ flow-biz: sdw-role-id: "2044676455280570370" business-key: "business_id" dept-worker-key: "subApproveUser" + xi-speak-fb-flowcode: "process_1778315114392" + form-url: "bg/xispeak/components/BgXiSpeakBPMForm" + xi-speak-fb: + dept-id: "x" + business-id: "business_id" + jj-dept-id: "2054466800692432898" + jj-worker-role-id: "2047511967494213633" + jj-leader-role-id: "2044680793306591234" + 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 3b071cc..db74797 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 @@ -169,4 +169,15 @@ public class BgXiSpeak implements Serializable { @TableField(typeHandler = JacksonTypeHandler.class) private Map approveInfo; + + /**督办次数*/ + @Excel(name = "发起类型", width = 15) + @Schema(description = "0收集后直接发起,1收集后按照反馈时间周期性发起") + private java.lang.Integer launchType; + + /**周期类型 1日 2周 3两周 4月 5季*/ + @Excel(name = "周期类型", width = 15) + @Schema(description = "周期类型 1日 2周 3两周 4月 5季") + private java.lang.Integer intervalType; + } diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeakFeedback.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeakFeedback.java index 2fe8368..0dea1c1 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeakFeedback.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/entity/BgXiSpeakFeedback.java @@ -2,10 +2,14 @@ package org.jeecg.modules.bg.xispeak.entity; import java.io.Serializable; import java.util.Date; +import java.util.Map; + 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.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import lombok.Data; import com.fasterxml.jackson.annotation.JsonFormat; import org.springframework.format.annotation.DateTimeFormat; @@ -19,7 +23,7 @@ import io.swagger.v3.oas.annotations.media.Schema; * @Version: V1.0 */ @Data -@TableName("bg_xi_speak_feedback") +@TableName(value = "bg_xi_speak_feedback", autoResultMap = true) @Schema(description="习总书记重要讲话反馈表") public class BgXiSpeakFeedback implements Serializable { private static final long serialVersionUID = 1L; @@ -81,4 +85,83 @@ public class BgXiSpeakFeedback implements Serializable { @Excel(name = "外键", width = 15) @Schema(description = "外键") private java.lang.String mainId; + + @Excel(name = "序号", width = 15) + @Schema(description = "序号") + private java.lang.Integer num; + + /**措施内容*/ + @Excel(name = "措施内容", width = 15) + @Schema(description = "措施内容") + private java.lang.String method; + + /**完成期限*/ + @Excel(name = "完成期限", width = 15, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "完成期限") + private java.util.Date deadline; + + /**成果形式*/ + @Excel(name = "成果形式", width = 15) + @Schema(description = "成果形式") + private java.lang.String outcomeForm; + + /**进展情况*/ + @Excel(name = "进展情况", width = 15) + @Schema(description = "进展情况") + private java.lang.String progress; + + + @Excel(name = "落实计划", width = 15) + @Schema(description = "落实计划") + private java.lang.String completionPlan; + + @Excel(name = "总措施号", width = 15) + @Schema(description = "总措施号") + private java.lang.String sumMethodNum; + + @Excel(name = "检查情况", width = 15) + @Schema(description = "检查情况") + private java.lang.String checkStatus; + + @Excel(name = "监督意见", width = 15) + @Schema(description = "监督意见") + private java.lang.String inspectionAdvice; + + @Excel(name = "措施数量", width = 15) + @Schema(description = "措施数量") + private java.lang.Integer measureNum; + + /**流程引擎状态字段*/ + @Excel(name = "流程引擎状态字段", width = 15) + @Schema(description = "流程引擎状态字段") + private java.lang.Integer bpmStatus; + + /**审批信息Map*/ + @TableField(typeHandler = JacksonTypeHandler.class) + private Map approveInfo; + +// /**发起类型 0立即 1周期*/ +// @Excel(name = "发起类型 0立即 1周期", width = 15) +// @Schema(description = "发起类型 0立即 1周期") +// private java.lang.Integer launchType; +// +// /**周期类型 1日 2周 3两周 4月 5季*/ +// @Excel(name = "周期类型", width = 15) +// @Schema(description = "周期类型 1日 2周 3两周 4月 5季") +// private java.lang.Integer intervalType; +// +// /**周期任务数量*/ +// @Excel(name = "周期任务数量", width = 15) +// @Schema(description = "周期任务数量") +// private java.lang.Integer startCount; +// +// /**周期开始时间*/ +// @Excel(name = "周期开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") +// @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") +// @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") +// @Schema(description = "周期开始时间") +// private java.util.Date startTime; + } \ No newline at end of file diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakFeedbackService.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakFeedbackService.java index 3861ba1..2d04b0f 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakFeedbackService.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/IBgXiSpeakFeedbackService.java @@ -11,4 +11,11 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface IBgXiSpeakFeedbackService extends IService { + /** + * 使用行锁查询,确保数据一致性 + * + * @param id 主键ID + * @return 实体对象 + */ + BgXiSpeakFeedback getByIdForUpdate(String id); } \ No newline at end of file diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakFeedbackServiceImpl.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakFeedbackServiceImpl.java index d68a1e7..4531f2d 100644 --- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakFeedbackServiceImpl.java +++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/bg/xispeak/service/impl/BgXiSpeakFeedbackServiceImpl.java @@ -1,5 +1,6 @@ package org.jeecg.modules.bg.xispeak.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.jeecg.modules.bg.xispeak.entity.BgXiSpeakFeedback; import org.jeecg.modules.bg.xispeak.mapper.BgXiSpeakFeedbackMapper; import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakFeedbackService; @@ -16,4 +17,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @Service public class BgXiSpeakFeedbackServiceImpl extends ServiceImpl implements IBgXiSpeakFeedbackService { + @Override + public BgXiSpeakFeedback getByIdForUpdate(String id) { + return this.getOne(new LambdaQueryWrapper() + .eq(BgXiSpeakFeedback::getId, id) + .last("for update")); + } } \ No newline at end of file