!33 fix(supervision): 实际完成时间日期格式由日期时间改为仅日期

* fix(supervision): 实际完成时间日期格式由日期时间改为仅日期
* refactor(flow): 分管所领导字段重命名为 chargeLeaderId 并在分页VO中补充字典映射
* fix(flow): 统一所有流程表达式日志格式并重构 getSDWSJ 增加唯一性校验
* fix(flow): 统一流程表达式日志前缀并补充 businessKey 便于排查
* feat(flow): 新增分管所领导字段及流程变量读取方法
* refactor(flow): 监听器组件名添加 Inspect 前缀统一命名
* refactor(flow): 提取 LeaderApproveHelper 消除领导审批监听器重复代码
* refactor(flow): 将部门领导审批监听器调整为党群领导,新增 DQ_DEPT_LEADER_KEY 常量
* feat(flow): 新增部门领导审批通过后写入流程变量监听器
This commit is contained in:
new_new_new
2026-06-05 09:19:44 +00:00
parent 335890b699
commit 21aa457996
8 changed files with 190 additions and 10 deletions
@@ -5,4 +5,11 @@ import org.jeecg.modules.demo.dqinspecttask.entity.DqInspectTask;
public class InspectConstant {
public static final String NEED_APPROVE_STR = "1";
public static final String NOT_NEED_APPROVE_STR = "0";
public static final String IMPL_DEPT_LEADER_KEY = "impl_dept_leader";
public static final String DQ_DEPT_LEADER_KEY = "dq_dept_leader";
public static final String IS_END_KEY = "is_end";
public static final String SUB_APPROVE_USER_KEY = "sub_approve_user";
public static final String SLD_DEPT_ID = "2044677562460508161";
public static final String SDWSJ_ROLE_ID = "2062796937607499777";
public static final int ZERO_INDEX = 0;
}
@@ -1,9 +1,11 @@
package org.jeecg.inspectimprove;
import com.alibaba.fastjson.JSONObject;
import com.jeecg.weibo.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.modules.demo.dqinspecttask.entity.DqInspectTask;
@@ -14,6 +16,7 @@ import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression;
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;
@@ -29,31 +32,64 @@ public class InspectImproveFlow {
private final XiSpeakConfig xiSpeakConfig;
private final ISysBaseAPI iSysBaseAPI;
private final IDqInspectTaskService dqInspectTaskService;
private final RuntimeService runtimeService;
//流程表达式内用法 ${inspectImproveFlow.getDqDeptLdUserIdList()}
public List<String> getDqDeptLdUserIdList() {
InspectImproveConfig.InspectImproveProperties props = inspectImproveConfig.getInspectImprove();
if (props == null || !org.apache.shiro.util.StringUtils.hasText(props.getDqDeptId())) {
log.error("流程配置缺失: [flow-biz.inspect-improve.dq-dept-id] 未在 YAML 中定义");
log.error("【巡视整改-流程表达式】流程配置缺失, key: flow-biz.inspect-improve.dq-dept-id");
return Collections.emptyList();
}
log.info("正在查询部门: {} 下的角色: {} 的用户列表", props.getDqDeptId(), props.getLdRoleId());
log.info("【巡视整改-流程表达式】查询部门角色用户列表, deptId: {}, roleId: {}", props.getDqDeptId(), props.getLdRoleId());
List<String> userList = iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi(
props.getDqDeptId(),
props.getLdRoleId()
);
log.info("查询到用户为: {}", userList);
log.info("【巡视整改-流程表达式】查询到用户列表, userList: {}", userList);
return userList;
}
// 流程表达式内用法 ${inspectImproveFlow.getSDWSJ()}
public String getSDWSJ() {
String deptId = InspectConstant.SLD_DEPT_ID;
String roleId = InspectConstant.SDWSJ_ROLE_ID;
log.info("【巡视整改-流程表达式】开始查询所党委书记用户, deptId: {}, roleId: {}", deptId, roleId);
List<String> userList = iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi(deptId, roleId);
// 1. 强校验:未查询到任何用户
if (CollectionUtils.isEmpty(userList)) {
log.error("【巡视整改-流程表达式getSDWSJ】异常:未查询到所党委书记用户!deptId: {}, roleId: {}", deptId, roleId);
throw new BusinessException("流程流转失败:未配置所党委书记用户,请联系管理员!");
}
// 2. 强校验:查询到多个用户(不唯一)
if (userList.size() > 1) {
log.error("【巡视整改-流程表达式getSDWSJ】严重异常:期望唯一用户,但查询到多个党委书记用户!数量: {}, 用户列表: {}", userList.size(), userList);
throw new BusinessException("流程流转失败:系统检测到存在多个党委书记用户,数据不唯一,请检查系统角色配置!");
}
// 3. 唯一性通过,校验提取出的值是否有效
String targetUser = userList.get(InspectConstant.ZERO_INDEX);
if (StringUtils.isEmpty(targetUser)) {
log.error("【巡视整改-流程表达式getSDWSJ】异常:查询到的党委书记用户名为空字符串!");
throw new BusinessException("流程流转失败:党委书记用户名数据非法!");
}
log.info("【巡视整改-流程表达式getSDWSJ】成功匹配到唯一的所党委书记用户: {}", targetUser);
return targetUser;
}
//流程表达式内用法 ${inspectImproveFlow.getDqDeptLdUserIdListLength()}
public int getDqDeptLdUserIdListLength() {
List<String> dqDeptLdUserIdList = this.getDqDeptLdUserIdList();
if (dqDeptLdUserIdList != null && !dqDeptLdUserIdList.isEmpty()) {
return dqDeptLdUserIdList.size();
}
log.warn("dq部门ld角色没有对应用户");
log.warn("【巡视整改-流程表达式】dq部门ld角色没有对应用户");
return 0;
}
@@ -112,19 +148,62 @@ public class InspectImproveFlow {
return this.getImplDeptLeaderList(execution).size();
}
// 流程表达式内用法:${inspectImproveFlow.getIsEnd(execution)}
public String getIsEnd(DelegateExecution execution) {
Object value = runtimeService.getVariable(execution.getProcessInstanceId(), InspectConstant.IS_END_KEY);
return value != null ? value.toString() : null;
}
// 流程表达式内用法:${inspectImproveFlow.getSubApproveUser(execution)}
public String getSubApproveUser(DelegateExecution execution) {
Object value = runtimeService.getVariable(execution.getProcessInstanceId(), InspectConstant.SUB_APPROVE_USER_KEY);
return value != null ? value.toString() : null;
}
// 流程表达式内用法:${inspectImproveFlow.getDqDeptLeader(execution)}
public String getDqDeptLeader(DelegateExecution execution) {
Object value = runtimeService.getVariable(execution.getProcessInstanceId(), InspectConstant.DQ_DEPT_LEADER_KEY);
return value != null ? value.toString() : null;
}
// 流程表达式内用法:${inspectImproveFlow.getImplDeptLeader(execution)}
public String getImplDeptLeader(DelegateExecution execution) {
Object value = runtimeService.getVariable(execution.getProcessInstanceId(), InspectConstant.IMPL_DEPT_LEADER_KEY);
return value != null ? value.toString() : null;
}
// 流程表达式内用法:${inspectImproveFlow.getSLD(execution)}
public String getSLD(DelegateExecution execution) {
DqInspectTask tempDqInspectTask = this.getDqInspectTask(execution);
if (tempDqInspectTask == null) {
log.error("【巡视整改-流程表达式】未获取到巡视整改任务, businessKey: {}", execution.getProcessInstanceBusinessKey());
return null;
}
String sldUserStr = tempDqInspectTask.getChargeLeaderId();
if (StringUtils.isBlank(sldUserStr)) {
log.error("【巡视整改-流程表达式】未获取到所领导, businessKey: {}", execution.getProcessInstanceBusinessKey());
return null;
}
return sldUserStr;
}
private DqInspectTask getDqInspectTask(DelegateExecution execution) {
Object inspectTaskId = execution.getVariable(inspectImproveConfig.getInspectImprove().getBusinessKey());
// 统一校验 null 和空字符串
if (inspectTaskId == null || StringUtils.isBlank(inspectTaskId.toString())) {
log.error("流程异常】流程实例id为 {} 的流程内未获取到有效的业务表单id", execution.getProcessInstanceId());
log.error("巡视整改-流程表达式】未获取到有效的业务表单ID, processInstanceId: {}, businessKey: {}", execution.getProcessInstanceId(), inspectTaskId);
return null; // 明确返回 null,不给上游返回空壳对象
}
// 如果 getById 没查到,MyBatis-Plus 也会返回 null
DqInspectTask task = dqInspectTaskService.getById(inspectTaskId.toString());
if (task == null) {
log.error("数据异常】通过业务表单id {} 未查询到数据库中的任务记录", inspectTaskId);
log.error("巡视整改-流程表达式】未查询到业务表单记录, businessKey: {}, processInstanceId: {}", inspectTaskId, execution.getProcessInstanceId());
} else {
log.info("【巡视整改-流程表达式】已查询到业务表单, businessKey: {}", inspectTaskId);
}
return task;
}
@@ -0,0 +1,30 @@
package org.jeecg.inspectimprove.listener;
import lombok.RequiredArgsConstructor;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;
import org.jeecg.inspectimprove.InspectConstant;
import org.jeecg.modules.dj.inspectimprove.service.IDjInspectImproveService;
import org.jeecg.inspectimprove.InspectImproveConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 巡视整改流程党群领导审批通过后,将党群领导写入流程变量
*/
@Component("InspectAfterDqLeaderApproveListener")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class AfterDqLeaderApproveListener implements TaskListener {
private static final long serialVersionUID = 1L;
private final InspectImproveConfig inspectImproveConfig;
private final IDjInspectImproveService djInspectImproveService;
private final RuntimeService runtimeService;
@Override
public void notify(DelegateTask delegateTask) {
LeaderApproveHelper.handle(delegateTask, runtimeService,
InspectConstant.DQ_DEPT_LEADER_KEY, "【巡视整改-党群领导审批监听器】");
}
}
@@ -0,0 +1,30 @@
package org.jeecg.inspectimprove.listener;
import lombok.RequiredArgsConstructor;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;
import org.jeecg.inspectimprove.InspectConstant;
import org.jeecg.modules.dj.inspectimprove.service.IDjInspectImproveService;
import org.jeecg.inspectimprove.InspectImproveConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 巡视整改流程部门领导审批通过后,将部门领导写入流程变量
*/
@Component("InspectAfterImplDeptLeaderApproveListener")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class AfterImplDeptLeaderApproveListener implements TaskListener {
private static final long serialVersionUID = 1L;
private final InspectImproveConfig inspectImproveConfig;
private final IDjInspectImproveService djInspectImproveService;
private final RuntimeService runtimeService;
@Override
public void notify(DelegateTask delegateTask) {
LeaderApproveHelper.handle(delegateTask, runtimeService,
InspectConstant.IMPL_DEPT_LEADER_KEY, "【巡视整改-部门领导审批监听器】");
}
}
@@ -0,0 +1,24 @@
package org.jeecg.inspectimprove.listener;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.RuntimeService;
import org.flowable.task.service.delegate.DelegateTask;
@Slf4j
public final class LeaderApproveHelper {
private LeaderApproveHelper() {}
public static void handle(DelegateTask delegateTask, RuntimeService runtimeService,
String variableKey, String logPrefix) {
String assignee = delegateTask.getAssignee();
if (StringUtils.isEmpty(assignee)) {
log.error("{}未获取到审批人, taskId: {}", logPrefix, delegateTask.getId());
return;
}
runtimeService.setVariable(delegateTask.getProcessInstanceId(), variableKey, assignee);
log.info("{}将审批人 {} 写入流程变量, processInstanceId: {}, 变量名: {}",
logPrefix, assignee, delegateTask.getProcessInstanceId(), variableKey);
}
}
@@ -67,9 +67,9 @@ public class DqInspectProgress implements Serializable {
@Schema(description = "反馈人姓名")
private java.lang.String feedbackPersonName;
/**实际完成时间*/
@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")
@Excel(name = "实际完成时间", width = 20, format = "yyyy-MM-dd")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@Schema(description = "实际完成时间")
private java.util.Date actualTime;
/**工作进展*/
@@ -104,6 +104,11 @@ public class DqInspectTask implements Serializable {
@Dict(dictTable = "sys_user", dicText = "realname", dicCode = "username")
@Schema(description = "党群领导")
private java.lang.String supDeptleaderid;
/**分管所领导*/
@Excel(name = "分管所领导", width = 15, dictTable = "sys_user", dicText = "realname", dicCode = "username")
@Dict(dictTable = "sys_user", dicText = "realname", dicCode = "username")
@Schema(description = "分管所领导")
private java.lang.String chargeLeaderId;
/**检查情况*/
@Excel(name = "检查情况", width = 15)
@Schema(description = "检查情况")
@@ -82,6 +82,11 @@ public class DqInspectTaskPage {
@Dict(dictTable = "sys_depart", dicText = "depart_name", dicCode = "id")
@Schema(description = "措施责任部门")
private java.lang.String measureResDept;
/**分管所领导*/
@Excel(name = "分管所领导", width = 15, dictTable = "sys_user", dicText = "realname", dicCode = "username")
@Dict(dictTable = "sys_user", dicText = "realname", dicCode = "username")
@Schema(description = "分管所领导")
private java.lang.String chargeLeaderId;
/**整改交付成果*/
@Excel(name = "整改交付成果", width = 15)
@Schema(description = "整改交付成果")