!101 feat(fixcontact): 新增部门领导与经办人审批监听器

* feat(fixcontact): 新增部门领导与经办人审批监听器
* feat(fixcontact): 新增部门并行子流程流程表达式方法与常量
* feat(fixcontact): 反馈列表联表查询反馈人与反馈部门名称
* feat(fixcontact): 部门审批信息落库approve_info并新增保存接口
This commit is contained in:
wsm
2026-08-03 10:43:49 +00:00
parent 51a693c363
commit a965427ce3
10 changed files with 492 additions and 2 deletions
@@ -15,6 +15,8 @@ public final class FixContactConstant {
public static final String SLD_ROLE_ID = "2062794430936240130"; public static final String SLD_ROLE_ID = "2062794430936240130";
/** 部门负责人 */ /** 部门负责人 */
public static final String DEPT_LEADER_ID = "2044680793306591234"; public static final String DEPT_LEADER_ID = "2044680793306591234";
/** 部门负责人角色编码 */
public static final String DEPT_LEADER_ROLE_CODE = "ld";
} }
/** 角色编码 */ /** 角色编码 */
@@ -28,6 +30,14 @@ public final class FixContactConstant {
public static final class FlowVarName { public static final class FlowVarName {
/** 业务表单ID */ /** 业务表单ID */
public static final String BUSINESS_KEY = "businessKey"; public static final String BUSINESS_KEY = "businessKey";
/** 子流程当前部门ID(多实例局部变量) */
public static final String IMPL_DEPT_ID = "impl_dept_id";
/** 部门领导(子流程局部变量) */
public static final String TEM_IMPL_LEADER = "tem_impl_leader";
/** 部门经办人(子流程局部变量) */
public static final String TEM_IMPL_WORKER = "tem_impl_worker";
/** 部门经办人(流程变量,前端写入) */
public static final String SUB_APPROVE_USER = "sub_approve_user";
} }
/** 业务状态 */ /** 业务状态 */
@@ -37,4 +47,10 @@ public final class FixContactConstant {
/** 未办结 */ /** 未办结 */
public static final String UNFINISHED = "0"; public static final String UNFINISHED = "0";
} }
/** 业务状态 */
public static final class fieldKey {
/** 已办结 */
public static final String IS_END_KEY = "is_end";
}
} }
@@ -179,6 +179,23 @@ public class FixedContact20260730Controller extends JeecgController<FixedContact
return Result.OK("保存成功"); return Result.OK("保存成功");
} }
@AutoLog(value = "定点联系单-保存部门审批信息")
@Operation(summary = "保存部门审批信息到业务表单")
@PostMapping(value = "/saveSubApprove")
public Result<String> saveSubApprove(@RequestBody Map<String, Object> params) {
String mainId = (String) params.get("mainId");
String deptId = (String) params.get("deptId");
Integer isEnd = params.get("isEnd") != null ? Integer.valueOf(params.get("isEnd").toString()) : null;
String implWorker = (String) params.get("implWorker");
@SuppressWarnings("unchecked")
List<String> implUserNameList = (List<String>) params.get("implUserNameList");
if (oConvertUtils.isEmpty(mainId) || oConvertUtils.isEmpty(deptId)) {
return Result.error("主表ID和部门ID不能为空");
}
fixedContact20260730Service.saveSubApprove(mainId, deptId, isEnd, implWorker, implUserNameList);
return Result.OK("保存成功");
}
@AutoLog(value = "反馈子表-添加") @AutoLog(value = "反馈子表-添加")
@Operation(summary = "反馈子表-添加") @Operation(summary = "反馈子表-添加")
@PostMapping(value = "/addFixedContactFeedback20260730") @PostMapping(value = "/addFixedContactFeedback20260730")
@@ -3,8 +3,10 @@ package org.jeecg.modules.bg.fixcontact.entity;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel; import org.jeecgframework.poi.excel.annotation.Excel;
@@ -14,9 +16,10 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict; import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetailMap;
@Data @Data
@TableName("fixed_contact_20260730") @TableName(value = "fixed_contact_20260730", autoResultMap = true)
@Accessors(chain = true) @Accessors(chain = true)
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@Schema(description = "定点联系单") @Schema(description = "定点联系单")
@@ -132,4 +135,8 @@ public class FixedContact20260730 implements Serializable {
@Schema(description = "所办领导ID,多个逗号分隔") @Schema(description = "所办领导ID,多个逗号分隔")
private java.lang.String supDeptleaderid; private java.lang.String supDeptleaderid;
@TableField(typeHandler = JacksonTypeHandler.class)
@Schema(description = "部门审批信息Map(按部门ID存是否办结与部门经办人)")
private DeptApproveDetailMap approveInfo;
} }
@@ -3,6 +3,7 @@ package org.jeecg.modules.bg.fixcontact.entity;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
@@ -25,6 +26,7 @@ public class FixedContactFeedback20260730 implements Serializable {
private java.lang.String id; private java.lang.String id;
@Schema(description = "主表ID(外键)") @Schema(description = "主表ID(外键)")
@TableField("fixed_contact_20260730_id")
private java.lang.String fixedContact20260730Id; private java.lang.String fixedContact20260730Id;
@Schema(description = "创建人") @Schema(description = "创建人")
@@ -73,4 +75,12 @@ public class FixedContactFeedback20260730 implements Serializable {
@Schema(description = "反馈部门") @Schema(description = "反馈部门")
private java.lang.String feedbackDept; private java.lang.String feedbackDept;
@TableField(exist = false)
@Schema(description = "反馈人姓名")
private java.lang.String feedbackUserName;
@TableField(exist = false)
@Schema(description = "反馈部门名称")
private java.lang.String feedbackDeptName;
} }
@@ -13,6 +13,8 @@ import org.jeecg.modules.bg.fixcontact.entity.FixedContact20260730;
import org.jeecg.modules.bg.fixcontact.entity.FixedContactFeedback20260730; import org.jeecg.modules.bg.fixcontact.entity.FixedContactFeedback20260730;
import org.jeecg.modules.bg.fixcontact.service.IFixedContact20260730Service; import org.jeecg.modules.bg.fixcontact.service.IFixedContact20260730Service;
import org.jeecg.modules.bg.fixcontact.service.IFixedContactFeedback20260730Service; import org.jeecg.modules.bg.fixcontact.service.IFixedContactFeedback20260730Service;
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetail;
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetailMap;
import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression; import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -126,6 +128,28 @@ public class FixContactFlow {
return entity.getCoDept(); return entity.getCoDept();
} }
// ${fixContactFlow.getIsNeedBgLdApprove(execution)}
public String getIsNeedBgLdApprove(DelegateExecution execution) {
FixedContact20260730 entity = this.getFixedContact(execution);
if (entity == null) {
log.error("【定点联系-流程表达式】未获取到定点联系单, processInstanceId: {}",
execution.getProcessInstanceId());
return null;
}
return entity.getIsNeedAppro();
}
// ${fixContactFlow.getBgLd(execution)}
public String getBgLd(DelegateExecution execution) {
FixedContact20260730 entity = this.getFixedContact(execution);
if (entity == null) {
log.error("【定点联系-流程表达式】未获取到定点联系单, processInstanceId: {}",
execution.getProcessInstanceId());
return null;
}
return entity.getSupDeptleaderid();
}
// ${fixContactFlow.getContactDept(execution)} // ${fixContactFlow.getContactDept(execution)}
public String getContactDept(DelegateExecution execution) { public String getContactDept(DelegateExecution execution) {
FixedContact20260730 entity = this.getFixedContact(execution); FixedContact20260730 entity = this.getFixedContact(execution);
@@ -155,6 +179,25 @@ public class FixContactFlow {
return this.getOfficeLeaderList(execution).size(); return this.getOfficeLeaderList(execution).size();
} }
// 流程表达式内用法:${fixContactFlow.getIsEnd(execution, dept_id)}
public String getIsEnd(DelegateExecution execution, String deptId) {
if (StringUtils.isBlank(deptId)) {
log.error("【定点联系-流程表达式】传入部门ID为空,无法读取办结状态, processInstanceId: {}",
execution.getProcessInstanceId());
return null;
}
FixedContact20260730 entity = this.getFixedContact(execution);
if (entity == null || entity.getApproveInfo() == null || entity.getApproveInfo().isEmpty()) {
log.warn("【定点联系-流程表达式】未获取到部门审批信息, processInstanceId: {}",
execution.getProcessInstanceId());
return null;
}
DeptApproveDetail detail = entity.getApproveInfo().get(deptId);
Integer isEnd = detail != null ? detail.getIsEnd() : null;
log.info("【定点联系-流程表达式】读取部门办结状态, deptId: {}, isEnd: {}", deptId, isEnd);
return isEnd != null ? isEnd.toString() : null;
}
// ${fixContactFlow.getUsersByDeptAndRole(deptId, roleId)} // ${fixContactFlow.getUsersByDeptAndRole(deptId, roleId)}
public List<String> getUsersByDeptAndRole(String deptId, String roleId) { public List<String> getUsersByDeptAndRole(String deptId, String roleId) {
log.info("【定点联系-流程表达式】查询部门角色用户列表, deptId: {}, roleId: {}", deptId, roleId); log.info("【定点联系-流程表达式】查询部门角色用户列表, deptId: {}, roleId: {}", deptId, roleId);
@@ -201,6 +244,45 @@ public class FixContactFlow {
return this.getHostDeptLeaderList(execution).size(); return this.getHostDeptLeaderList(execution).size();
} }
// ${fixContactFlow.getCurrentDeptId(execution)}
public String getCurrentDeptId(DelegateExecution execution) {
if (execution == null) {
return null;
}
Object deptVar = execution.getVariableLocal(FixContactConstant.FlowVarName.IMPL_DEPT_ID);
if (deptVar == null) {
deptVar = execution.getVariable(FixContactConstant.FlowVarName.IMPL_DEPT_ID);
}
if (deptVar == null) {
log.warn("【定点联系-流程表达式】未获取到子流程当前部门ID, processInstanceId: {}",
execution.getProcessInstanceId());
return null;
}
return deptVar.toString().replace("[", "").replace("]", "").trim();
}
// ${fixContactFlow.getCurrentDeptLeaderList(execution, deptId)}
public List<String> getCurrentDeptLeaderList(DelegateExecution execution, String deptId) {
if (StringUtils.isBlank(deptId)) {
log.error("【定点联系-流程表达式】传入部门ID为空,无法查询部门领导, processInstanceId: {}",
execution.getProcessInstanceId());
return Collections.emptyList();
}
List<String> leaderList = this.getUsersByDeptAndRole(deptId, FixContactConstant.RoleCode.DEPT_LEADER_ROLE_CODE);
if (CollectionUtils.isEmpty(leaderList)) {
log.warn("【定点联系-流程表达式】部门: {} 下未配置角色为 {} 的用户,领导列表为空",
deptId, FixContactConstant.RoleCode.DEPT_LEADER_ROLE_CODE);
return Collections.emptyList();
}
log.info("【定点联系-流程表达式】查询到部门: {} 的领导列表: {}", deptId, leaderList);
return leaderList;
}
// ${fixContactFlow.getCurrentDeptLeaderListCount(execution, deptId)}
public int getCurrentDeptLeaderListCount(DelegateExecution execution, String deptId) {
return this.getCurrentDeptLeaderList(execution, deptId).size();
}
// =================================================================== // ===================================================================
// 反馈子表相关 // 反馈子表相关
// =================================================================== // ===================================================================
@@ -355,10 +437,111 @@ public class FixContactFlow {
return getUsersByDeptAndRole(coDept, "ld"); return getUsersByDeptAndRole(coDept, "ld");
} }
// ${fixContactFlow.getDeptIdList(execution)}
public List<String> getDeptIdList(DelegateExecution execution) {
FixedContact20260730 entity = this.getFixedContact(execution);
if (entity == null) {
log.error("【定点联系-流程表达式】未获取到定点联系单,无法组装部门列表, processInstanceId: {}",
execution.getProcessInstanceId());
return Collections.emptyList();
}
List<String> deptList = new ArrayList<>();
if (StringUtils.isNotBlank(entity.getHostDept())) {
deptList.add(entity.getHostDept());
}
if (StringUtils.isNotBlank(entity.getCoDept())) {
deptList.add(entity.getCoDept());
}
log.info("【定点联系-流程表达式】已组装主办+协办部门列表: {}, businessKey: {}",
deptList, entity.getId());
return deptList;
}
// ${fixContactFlow.getDeptIdListCount(execution)}
public int getDeptIdListCount(DelegateExecution execution) {
return this.getDeptIdList(execution).size();
}
// ${fixContactFlow.getTodoUserList(execution)}
public List<String> getTodoUserList(DelegateExecution execution) {
FixedContact20260730 entity = this.getFixedContact(execution);
if (entity == null) {
log.error("【定点联系-流程表达式】未获取到定点联系单,无法获取待办人, processInstanceId: {}",
execution.getProcessInstanceId());
return Collections.emptyList();
}
DeptApproveDetailMap approveInfo = entity.getApproveInfo();
if (approveInfo == null || approveInfo.isEmpty()) {
log.warn("【定点联系-流程表达式】部门审批信息为空,待办人为空, businessKey: {}", entity.getId());
return Collections.emptyList();
}
List<String> deptList = this.getDeptIdList(execution);
// LinkedHashSet 去重并保持插入顺序(主办部门经办人优先)
Set<String> todoUserSet = new LinkedHashSet<>();
for (String deptId : deptList) {
DeptApproveDetail detail = approveInfo.get(deptId);
if (detail == null) {
continue;
}
// isEnd=0 时取多选经办人 implUserNameListisEnd=1 时取单选经办人 implWorker
if (detail.getImplUserNameList() != null && !detail.getImplUserNameList().isEmpty()) {
todoUserSet.addAll(detail.getImplUserNameList());
} else if (StringUtils.isNotBlank(detail.getImplWorker())) {
todoUserSet.add(detail.getImplWorker());
}
}
List<String> todoUserList = new ArrayList<>(todoUserSet);
log.info("【定点联系-流程表达式】已获取部门领导分配的待办人: {}, businessKey: {}",
todoUserList, entity.getId());
return todoUserList;
}
// ${fixContactFlow.getTodoUserListLength(execution)}
public int getTodoUserListLength(DelegateExecution execution) {
return this.getTodoUserList(execution).size();
}
// ${fixContactFlow.getCurrentDeptWorkerList(execution, deptId)}
public List<String> getCurrentDeptWorkerList(DelegateExecution execution, String deptId) {
DeptApproveDetail detail = this.getDeptApproveDetail(execution, deptId);
if (detail == null) {
log.warn("【定点联系-流程表达式】部门: {} 审批信息为空,经办人为空, processInstanceId: {}",
deptId, execution.getProcessInstanceId());
return Collections.emptyList();
}
// isEnd=0 时取多选经办人 implUserNameListisEnd=1 时取单选经办人 implWorker
if (detail.getImplUserNameList() != null && !detail.getImplUserNameList().isEmpty()) {
return detail.getImplUserNameList();
}
if (StringUtils.isNotBlank(detail.getImplWorker())) {
return Collections.singletonList(detail.getImplWorker());
}
return Collections.emptyList();
}
// ${fixContactFlow.getCurrentDeptWorkerListCount(execution, deptId)}
public int getCurrentDeptWorkerListCount(DelegateExecution execution, String deptId) {
return this.getCurrentDeptWorkerList(execution, deptId).size();
}
// =================================================================== // ===================================================================
// 通用工具方法 // 通用工具方法
// =================================================================== // ===================================================================
private DeptApproveDetail getDeptApproveDetail(DelegateExecution execution, String deptId) {
if (execution == null) {
return null;
}
FixedContact20260730 entity = this.getFixedContact(execution);
if (entity == null || entity.getApproveInfo() == null) {
return null;
}
if (StringUtils.isBlank(deptId)) {
return null;
}
return entity.getApproveInfo().get(deptId);
}
private String getStringFromData(Object jsonData, String codeName, String logLabel) { private String getStringFromData(Object jsonData, String codeName, String logLabel) {
if (jsonData == null || StringUtils.isBlank(codeName)) { if (jsonData == null || StringUtils.isBlank(codeName)) {
return null; return null;
@@ -0,0 +1,79 @@
package org.jeecg.modules.bg.fixcontact.listener;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.engine.runtime.Execution;
import org.flowable.task.service.delegate.DelegateTask;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.modules.bg.fixcontact.constant.FixContactConstant;
import org.springframework.stereotype.Component;
/**
* 部门领导审批完成监听器:将部门领导(assignee)写入上两级执行实例局部变量,
* 供子流程内后续节点(如经办人会签、网关判断)读取当前部门的领导。
*/
@Slf4j
@Component("FixContactDeptLeaderApproveListener")
public class FixContactDeptLeaderApproveListener implements TaskListener {
private static final long serialVersionUID = 1L;
private static final String VARIABLE_NAME = FixContactConstant.FlowVarName.TEM_IMPL_LEADER;
private static RuntimeService runtimeService;
static {
runtimeService = SpringContextUtils.getBean(RuntimeService.class);
}
@Override
public void notify(DelegateTask delegateTask) {
if (delegateTask == null) {
return;
}
String assignee = delegateTask.getAssignee();
if (StringUtils.isBlank(assignee)) {
log.warn("【定点联系-部门领导审批监听器】任务办理人为空,跳过写入领导变量, taskId: {}", delegateTask.getId());
return;
}
String currentExecutionId = delegateTask.getExecutionId();
if (StringUtils.isBlank(currentExecutionId)) {
log.warn("【定点联系-部门领导审批监听器】获取执行实例ID失败,跳过写入领导变量, taskId: {}", delegateTask.getId());
return;
}
Execution currentExecution = runtimeService.createExecutionQuery()
.executionId(currentExecutionId)
.singleResult();
if (currentExecution == null) {
return;
}
// 向上寻找第一层父级(内层会签容器/子流程)
String parentId = currentExecution.getParentId();
if (StringUtils.isBlank(parentId)) {
log.warn("【定点联系-部门领导审批监听器】未找到父级执行实例,当前已是顶层, executionId: {}", currentExecutionId);
return;
}
// 通过第一层父级实体对象向上爬取第二层 ID
Execution parentExecution = runtimeService.createExecutionQuery()
.executionId(parentId)
.singleResult();
if (parentExecution == null) {
return;
}
String grandParentId = parentExecution.getParentId();
// 有第二层父级则存入第二层(大会签容器/外层作用域),否则存入第一层
String targetId = StringUtils.isNotBlank(grandParentId) ? grandParentId : parentId;
try {
runtimeService.setVariableLocal(targetId, VARIABLE_NAME, assignee);
log.info("【定点联系-部门领导审批监听器】已存入上两级局部变量, targetExecutionId: {}, variableName: {}, assignee: {}",
targetId, VARIABLE_NAME, assignee);
} catch (Exception e) {
log.error("【定点联系-部门领导审批监听器】设置嵌套局部变量失败, targetExecutionId: {}, assignee: {}",
targetId, assignee, e);
}
}
}
@@ -0,0 +1,114 @@
package org.jeecg.modules.bg.fixcontact.listener;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;
import org.jeecg.modules.bg.fixcontact.constant.FixContactConstant;
import org.jeecg.modules.bg.fixcontact.entity.FixedContact20260730;
import org.jeecg.modules.bg.fixcontact.service.IFixedContact20260730Service;
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetail;
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetailMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* 部门经办人会签任务监听器:经办人办理完成后,将当前经办人写入子流程执行实例局部变量
* tem_impl_worker),并记录到业务表单 approveInfo 对应部门的经办人列表,供会签统计与展示使用。
*/
@Slf4j
@Component("FixContactWorkerApproveListener")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class FixContactWorkerApproveListener implements TaskListener {
private static final long serialVersionUID = 1L;
private final IFixedContact20260730Service fixedContact20260730Service;
private final RuntimeService runtimeService;
@Override
@Transactional(rollbackFor = Exception.class)
public void notify(DelegateTask delegateTask) {
if (delegateTask == null) {
return;
}
String currentWorker = delegateTask.getAssignee();
if (StringUtils.isBlank(currentWorker)) {
log.warn("【定点联系-经办人会签监听器】任务办理人为空,跳过写入经办人变量, taskId: {}", delegateTask.getId());
return;
}
// 1. 将当前经办人写入子流程执行实例局部变量
String executionId = delegateTask.getExecutionId();
if (StringUtils.isNotBlank(executionId)) {
try {
runtimeService.setVariableLocal(executionId, FixContactConstant.FlowVarName.TEM_IMPL_WORKER, currentWorker);
log.info("【定点联系-经办人会签监听器】已写入经办人局部变量, executionId: {}, variableName: {}, worker: {}",
executionId, FixContactConstant.FlowVarName.TEM_IMPL_WORKER, currentWorker);
} catch (Exception e) {
log.error("【定点联系-经办人会签监听器】写入经办人局部变量失败, executionId: {}, worker: {}",
executionId, currentWorker, e);
}
} else {
log.warn("【定点联系-经办人会签监听器】获取执行实例ID失败,跳过写入经办人变量, taskId: {}", delegateTask.getId());
}
// 2. 记录经办人到业务表单 approveInfo 对应部门
Object rawBusinessKey = delegateTask.getVariable(FixContactConstant.FlowVarName.BUSINESS_KEY);
if (rawBusinessKey == null || StringUtils.isBlank(rawBusinessKey.toString())) {
log.warn("【定点联系-经办人会签监听器】未获取到业务表单ID,跳过记录经办人, taskId: {}", delegateTask.getId());
return;
}
Object rawDeptVar = delegateTask.getVariableLocal(FixContactConstant.FlowVarName.IMPL_DEPT_ID);
if (rawDeptVar == null) {
rawDeptVar = delegateTask.getVariable(FixContactConstant.FlowVarName.IMPL_DEPT_ID);
}
if (rawDeptVar == null || StringUtils.isBlank(rawDeptVar.toString())) {
log.warn("【定点联系-经办人会签监听器】未获取到子流程当前部门ID,跳过记录经办人, taskId: {}", delegateTask.getId());
return;
}
String deptId = rawDeptVar.toString().replace("[", "").replace("]", "").trim();
FixedContact20260730 fixedContact = fixedContact20260730Service.getByIdForUpdate(rawBusinessKey.toString());
if (fixedContact == null) {
log.error("【定点联系-经办人会签监听器】未查询到业务表单记录, businessKey: {}", rawBusinessKey);
return;
}
DeptApproveDetailMap approveMap = fixedContact.getApproveInfo();
if (approveMap == null) {
approveMap = new DeptApproveDetailMap();
}
DeptApproveDetail detail = approveMap.get(deptId);
if (detail == null) {
detail = new DeptApproveDetail();
detail.setDeptId(deptId);
detail.setImplUserNameList(new ArrayList<>());
approveMap.put(deptId, detail);
}
// 更新该部门经办人列表
List<String> workerList = detail.getImplUserNameList();
if (workerList == null) {
workerList = new ArrayList<>();
detail.setImplUserNameList(workerList);
}
if (!workerList.contains(currentWorker)) {
workerList.add(currentWorker);
fixedContact.setApproveInfo(approveMap);
fixedContact20260730Service.updateById(fixedContact);
log.info("【定点联系-经办人会签监听器】部门: {} 经办人已记录, worker: {}, businessKey: {}",
deptId, currentWorker, fixedContact.getId());
} else {
log.info("【定点联系-经办人会签监听器】部门: {} 经办人 {} 已在列表中,跳过更新", deptId, currentWorker);
}
}
}
@@ -12,6 +12,13 @@ public interface FixedContactFeedback20260730Mapper extends BaseMapper<FixedCont
@Delete("DELETE FROM fixed_contact_feedback_20260730 WHERE fixed_contact_20260730_id = #{mainId}") @Delete("DELETE FROM fixed_contact_feedback_20260730 WHERE fixed_contact_20260730_id = #{mainId}")
boolean deleteByMainId(@Param("mainId") String mainId); boolean deleteByMainId(@Param("mainId") String mainId);
@Select("SELECT * FROM fixed_contact_feedback_20260730 WHERE fixed_contact_20260730_id = #{mainId}") @Select("SELECT f.*, " +
"COALESCE(u1.realname, u2.realname) AS feedback_user_name, " +
"d.depart_name AS feedback_dept_name " +
"FROM fixed_contact_feedback_20260730 f " +
"LEFT JOIN sys_user u1 ON u1.id = f.feedback_user " +
"LEFT JOIN sys_user u2 ON u2.username = f.feedback_user " +
"LEFT JOIN sys_depart d ON d.id = f.feedback_dept " +
"WHERE f.fixed_contact_20260730_id = #{mainId}")
List<FixedContactFeedback20260730> selectByMainId(@Param("mainId") String mainId); List<FixedContactFeedback20260730> selectByMainId(@Param("mainId") String mainId);
} }
@@ -16,4 +16,11 @@ public interface IFixedContact20260730Service extends IService<FixedContact20260
void delMain(String id); void delMain(String id);
void delBatchMain(Collection<? extends Serializable> idList); void delBatchMain(Collection<? extends Serializable> idList);
void saveSubApprove(String mainId, String deptId, Integer isEnd, String implWorker, List<String> implUserNameList);
/**
* 悲观锁查询(for update),需在事务中使用
*/
FixedContact20260730 getByIdForUpdate(String id);
} }
@@ -1,19 +1,26 @@
package org.jeecg.modules.bg.fixcontact.service.impl; package org.jeecg.modules.bg.fixcontact.service.impl;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.bg.fixcontact.entity.FixedContact20260730; import org.jeecg.modules.bg.fixcontact.entity.FixedContact20260730;
import org.jeecg.modules.bg.fixcontact.entity.FixedContactFeedback20260730; import org.jeecg.modules.bg.fixcontact.entity.FixedContactFeedback20260730;
import org.jeecg.modules.bg.fixcontact.mapper.FixedContact20260730Mapper; import org.jeecg.modules.bg.fixcontact.mapper.FixedContact20260730Mapper;
import org.jeecg.modules.bg.fixcontact.mapper.FixedContactFeedback20260730Mapper; import org.jeecg.modules.bg.fixcontact.mapper.FixedContactFeedback20260730Mapper;
import org.jeecg.modules.bg.fixcontact.service.IFixedContact20260730Service; import org.jeecg.modules.bg.fixcontact.service.IFixedContact20260730Service;
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetail;
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetailMap;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@Service @Service
@Slf4j
public class FixedContact20260730ServiceImpl extends ServiceImpl<FixedContact20260730Mapper, FixedContact20260730> implements IFixedContact20260730Service { public class FixedContact20260730ServiceImpl extends ServiceImpl<FixedContact20260730Mapper, FixedContact20260730> implements IFixedContact20260730Service {
@Autowired @Autowired
@@ -59,4 +66,47 @@ public class FixedContact20260730ServiceImpl extends ServiceImpl<FixedContact202
baseMapper.deleteById(id); baseMapper.deleteById(id);
} }
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void saveSubApprove(String mainId, String deptId, Integer isEnd, String implWorker, List<String> implUserNameList) {
FixedContact20260730 fixedContact = this.getById(mainId);
if (fixedContact == null) {
throw new JeecgBootException("业务表单不存在");
}
DeptApproveDetailMap approveMap = fixedContact.getApproveInfo();
if (approveMap == null) {
approveMap = new DeptApproveDetailMap();
}
DeptApproveDetail detail = approveMap.get(deptId);
if (detail == null) {
detail = new DeptApproveDetail();
detail.setDeptId(deptId);
detail.setImplUserNameList(new ArrayList<>());
approveMap.put(deptId, detail);
}
detail.setIsEnd(isEnd);
if (isEnd != null && isEnd == 1) {
detail.setImplWorker(implWorker);
detail.setImplUserNameList(null);
} else {
detail.setImplWorker(null);
detail.setImplUserNameList(implUserNameList != null ? implUserNameList : new ArrayList<>());
}
fixedContact.setApproveInfo(approveMap);
this.updateById(fixedContact);
log.info("【定点联系-部门审批保存】部门审批信息保存成功, mainId: {}, deptId: {}, isEnd: {}, implWorker: {}, implUserNameList: {}",
mainId, deptId, isEnd, implWorker, implUserNameList);
}
@Override
public FixedContact20260730 getByIdForUpdate(String id) {
return this.getOne(new LambdaQueryWrapper<FixedContact20260730>()
.eq(FixedContact20260730::getId, id)
.last("for update"));
}
} }