应征入伍保留学籍工作流监听器

This commit is contained in:
2025-11-13 17:19:33 +08:00
parent 52de1dda74
commit 5c1dcbf343
13 changed files with 927 additions and 29 deletions

View File

@@ -0,0 +1,203 @@
package com.srs.flowable.domain;
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.fasterxml.jackson.annotation.JsonFormat;
import com.srs.common.annotation.Excel;
import com.srs.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import java.util.Date;
/**
* 应征入伍保留学籍申请对象 rt_enlistment_reserve
*
* @author srs
* @date 2025-10-31
*/
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ApiModel(value = "RtEnlistmentReserve对象" , description = "应征入伍保留学籍申请表")
@TableName("rt_enlistment_reserve")
public class EnlistmentReserve extends BaseEntity{
private static final long serialVersionUID=1L;
/**
* 主键
*/
@ApiModelProperty("主键")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 申请编号规则RY+年份+6位序号如RY2024000001
*/
@ApiModelProperty("申请编号规则RY+年份+6位序号如RY2024000001")
@TableField("apply_no")
@Excel(name = "申请编号" , readConverterExp = "规=则RY+年份+6位序号如RY2024000001")
private String applyNo;
/**
* 学生ID关联sys_user
*/
@ApiModelProperty("学生ID关联sys_user")
@TableField("student_id")
@Excel(name = "学生ID" , readConverterExp = "关=联sys_user")
private Long studentId;
/**
* 辅导员姓名
*/
@ApiModelProperty("辅导员姓名")
@TableField("teacher_name")
@Excel(name = "辅导员姓名")
private String teacherName;
/**
* 姓名
*/
@ApiModelProperty("姓名")
@TableField("student_name")
@Excel(name = "姓名")
private String studentName;
/**
* 性别0-男
*/
@ApiModelProperty("性别1-男 0-女)")
@TableField("gender")
@Excel(name = "性别" , readConverterExp = "性别1-男 0-女)")
private String gender;
/**
* 民族
*/
@ApiModelProperty("民族")
@TableField("nation")
@Excel(name = "民族")
private String nation;
/**
* 年级
*/
@ApiModelProperty("年级")
@TableField("grade")
@Excel(name = "年级")
private String grade;
/**
* 学号
*/
@ApiModelProperty("学号")
@TableField("student_no")
@Excel(name = "学号")
private String studentNo;
/**
* 班级
*/
@ApiModelProperty("班级")
@TableField("class_name")
@Excel(name = "班级")
private String className;
/**
* 专业名称
*/
@ApiModelProperty("专业名称")
@TableField("major")
@Excel(name = "专业名称")
private String major;
/**
* 家庭地址
*/
@ApiModelProperty("家庭地址")
@TableField("family_address")
@Excel(name = "家庭地址")
private String familyAddress;
/**
* 家长联系电话
*/
@ApiModelProperty("家长联系电话")
@TableField("parent_phone")
@Excel(name = "家长联系电话")
private String parentPhone;
/**
* 申请理由(含入伍时间、服役期限)
*/
@ApiModelProperty("申请理由(含入伍时间、服役期限)")
@TableField("apply_reason")
@Excel(name = "申请理由" , readConverterExp = "含=入伍时间、服役期限")
private String applyReason;
/**
* 申请状态0-草稿
*/
@ApiModelProperty("申请状态0-草稿 1-审批中 2-通过 3-驳回)")
@TableField("apply_status")
@Excel(name = "申请状态" , readConverterExp = "申请状态0-草稿 1-审批中 2-通过 3-驳回)")
private Long applyStatus;
/**
* Flowable流程实例ID
*/
@ApiModelProperty("Flowable流程实例ID")
@TableField("process_instance_id")
@Excel(name = "Flowable流程实例ID")
private String processInstanceId;
/**
* 保留学籍编号(审批通过后生成)
*/
@ApiModelProperty("保留学籍编号(审批通过后生成)")
@TableField("reserve_no")
@Excel(name = "保留学籍编号" , readConverterExp = "审=批通过后生成")
private String reserveNo;
/**
* 保留学籍开始日期
*/
@ApiModelProperty("保留学籍开始日期")
@TableField("reserve_start_date")
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "保留学籍开始日期" , width = 30, dateFormat = "yyyy-MM-dd")
private Date reserveStartDate;
/**
* 保留学籍结束日期(入伍时间+服役期限)
*/
@ApiModelProperty("保留学籍结束日期(入伍时间+服役期限)")
@TableField("reserve_end_date")
@Excel(name = "保留学籍结束日期" , readConverterExp = "入=伍时间+服役期限")
private Date reserveEndDate;
/**
* 批文号
*/
@ApiModelProperty("批文号")
@TableField("approval_no")
@Excel(name = "批文号")
private String approvalNo;
@ApiModelProperty("申请日期")
@TableField("create_time")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date createTime;
@ApiModelProperty("更新日期")
@TableField("update_time")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date updateTime;
}

View File

@@ -0,0 +1,127 @@
package com.srs.flowable.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.srs.common.annotation.Excel;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import com.srs.common.core.domain.BaseEntity;
/**
* 保留学籍审批记录对象 rt_enlistment_reserve_approval
*
* @author srs
* @date 2025-11-13
*/
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ApiModel(value = "RtEnlistmentReserveApproval对象" , description = "保留学籍审批记录")
@TableName("rt_enlistment_reserve_approval")
public class EnlistmentReserveApproval extends BaseEntity{
private static final long serialVersionUID=1L;
/**
* 主键
*/
@ApiModelProperty("主键")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 申请表ID
*/
@ApiModelProperty("申请表ID")
@TableField("apply_id")
@Excel(name = "申请表ID")
private Long applyId;
/**
* 流程实例ID
*/
@ApiModelProperty("流程实例ID")
@TableField("process_instance_id")
@Excel(name = "流程实例ID")
private String processInstanceId;
/**
* Flowable任务ID
*/
@ApiModelProperty("Flowable任务ID")
@TableField("task_id")
@Excel(name = "Flowable任务ID")
private String taskId;
/**
* 审批节点(辅导员/学务等)
*/
@ApiModelProperty("审批节点(辅导员/学务等)")
@TableField("node_name")
@Excel(name = "审批节点" , readConverterExp = "辅=导员/学务等")
private String nodeName;
/**
* 审批人ID关联sys_user
*/
@ApiModelProperty("审批人ID关联sys_user")
@TableField("approver_id")
@Excel(name = "审批人ID" , readConverterExp = "关=联sys_user")
private Long approverId;
/**
* 审批人姓名
*/
@ApiModelProperty("审批人姓名")
@TableField("approver_name")
@Excel(name = "审批人姓名")
private String approverName;
/**
* 审批意见
*/
@ApiModelProperty("审批意见")
@TableField("approval_opinion")
@Excel(name = "审批意见")
private String approvalOpinion;
/**
* 审批结果1-通过
*/
@ApiModelProperty("审批结果1-通过")
@TableField("approval_result")
@Excel(name = "审批结果" , readConverterExp = "审批结果1-通过")
private Long approvalResult;
/**
* 审批时间
*/
@ApiModelProperty("审批时间")
@TableField("approval_time")
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "审批时间" , width = 30, dateFormat = "yyyy-MM-dd")
private Date approvalTime;
/**
* 姓名
*/
@ApiModelProperty("姓名")
@TableField("student_name")
@Excel(name = "姓名")
private String studentName;
/**
* 学号
*/
@ApiModelProperty("学号")
@TableField("student_no")
@Excel(name = "学号")
private String studentNo;
}

View File

@@ -3,7 +3,13 @@ package com.srs.flowable.listener.enlistmentReserve;
import com.srs.common.core.domain.entity.SysUser;
import com.srs.common.doman.vo.TeacherVo;
import com.srs.common.utils.SecurityUtils;
import com.srs.common.utils.spring.SpringUtils;
import com.srs.flowable.domain.EnlistmentReserve;
import com.srs.flowable.domain.EnlistmentReserveApproval;
import com.srs.flowable.mapper.EnlistmentReserveApprovalMapper;
import com.srs.flowable.mapper.EnlistmentReserveMapper;
import com.srs.system.service.ISysUserService;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowNode;
@@ -15,6 +21,7 @@ import org.flowable.engine.delegate.ExecutionListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
@@ -53,8 +60,14 @@ public class ApprovalAssigneeListener implements ExecutionListener {
// 3. 获取流程实例ID
String processInstanceId = execution.getProcessInstanceId();
// 获取申请表id
Long enlistmentId = Long.valueOf(execution.getVariable("enlistmentId").toString());
// 获取审核意见
String approvalOpinion = (String) execution.getVariable("comment");
// 4. 后续逻辑不变:查询下一个节点负责人并更新变量
Long nextAssigneeId = getNextAssignee(currentNodeName, processInstanceId);
Long nextAssigneeId = getNextAssignee(currentNodeName, processInstanceId, enlistmentId, currentActivityId, approvalOpinion);
if (nextAssigneeId != null) {
execution.setVariable("approval", nextAssigneeId);
execution.setVariable("currentNode", currentNodeName);
@@ -79,11 +92,16 @@ public class ApprovalAssigneeListener implements ExecutionListener {
/**
* 根据当前节点查询下一个节点的负责人
*/
private Long getNextAssignee(String currentNodeName, String processInstanceId) {
// 获取当前登录用户的部门id
Long currentDeptId = SecurityUtils.getDeptId();
private Long getNextAssignee(String currentNodeName, String processInstanceId, Long enlistmentId, String currentActivityId, String approvalOpinion) {
EnlistmentReserveMapper rtEnlistmentReserveMapper = (EnlistmentReserveMapper) SpringUtils.getBean(EnlistmentReserveMapper.class);
// 根据Id查询入伍申请记录
EnlistmentReserve enlistmentReserve = rtEnlistmentReserveMapper.selectRtEnlistmentReserveById(enlistmentId);
// 根据学生学号来获取对应辅导员的信息
TeacherVo counselorInfo = rtEnlistmentReserveMapper.getCounselorInfo(enlistmentReserve.getStudentNo());
// 获取辅导员的部门id
Long currentDeptId = counselorInfo.getDeptId();
if (currentDeptId == null) {
throw new RuntimeException("当前登录用户未分配部门,无法匹配学务负责人");
throw new RuntimeException("未分配部门,无法匹配负责人");
}
// 注意节点名称需与BPMN模型中完全一致区分大小写
switch (currentNodeName) {
@@ -97,13 +115,16 @@ public class ApprovalAssigneeListener implements ExecutionListener {
throw new RuntimeException("未查询到角色ID=105学务的用户");
}
// 3. 从学务用户中筛选出部门ID与当前辅导员部门一致的用户
// 从学务用户中筛选出部门ID与当前辅导员部门一致的用户
SysUser targetAcademic = academicAffairsUsers.stream()
.filter(user -> currentDeptId.equals(user.getDeptId())) // 部门ID匹配
.findFirst() // 取第一个匹配的学务(若有多个,可根据排序或优先级调整)
.orElseThrow(() -> new RuntimeException("未找到部门ID=" + currentDeptId + "的学务负责人"));
// 4. 返回匹配的学务用户ID作为下一个节点负责人
// 添加审批记录
saveApprovalRecord(enlistmentReserve.getId(), enlistmentReserve.getProcessInstanceId(),currentActivityId,currentNodeName, enlistmentReserve.getStudentName(), enlistmentReserve.getStudentNo(), approvalOpinion);
// 返回匹配的学务用户ID作为下一个节点负责人
return targetAcademic.getUserId();
case "学务审批":
@@ -128,23 +149,79 @@ public class ApprovalAssigneeListener implements ExecutionListener {
.findFirst()
.orElseThrow(() -> new RuntimeException("未找到学院ID=" + currentDeptId + "的二级学院负责人角色ID=106"));
// 添加审批记录
saveApprovalRecord(enlistmentReserve.getId(), enlistmentReserve.getProcessInstanceId(),currentActivityId,currentNodeName, enlistmentReserve.getStudentName(), enlistmentReserve.getStudentNo(), approvalOpinion);
// 4. 返回匹配的二级学院负责人ID
return targetCollegeLeader.getUserId();
case "二级学院审批":
// 二级学院通过后 → 下一个节点学籍管理科假设部门ID=30
// 添加审批记录
saveApprovalRecord(enlistmentReserve.getId(), enlistmentReserve.getProcessInstanceId(),currentActivityId,currentNodeName, enlistmentReserve.getStudentName(), enlistmentReserve.getStudentNo(), approvalOpinion);
return 30L;
case "学籍管理科审批":
// 学籍管理科通过后 → 下一个节点教务处假设部门ID=40
// 添加审批记录
saveApprovalRecord(enlistmentReserve.getId(), enlistmentReserve.getProcessInstanceId(),currentActivityId,currentNodeName, enlistmentReserve.getStudentName(), enlistmentReserve.getStudentNo(), approvalOpinion);
return 40L;
case "教务处主管领导审批":
// 最后一个节点通过后 → 流程结束(无需设置负责人)
// 添加审批记录
saveApprovalRecord(enlistmentReserve.getId(), enlistmentReserve.getProcessInstanceId(),currentActivityId,currentNodeName, enlistmentReserve.getStudentName(), enlistmentReserve.getStudentNo(), approvalOpinion);
// 改变申请表中的审核状态(审核通过)
enlistmentReserve.setApplyStatus(2L);
rtEnlistmentReserveMapper.updateRtEnlistmentReserve(enlistmentReserve);
return null;
default:
throw new RuntimeException("未配置节点[" + currentNodeName + "]的下一个负责人规则");
}
}
/**
* 通用审批记录保存方法
*/
private void saveApprovalRecord(Long ApplyId,String processInstanceId, String taskId, String nodeName, String studentName, String studentNo, String approvalOpinion) {
EnlistmentReserveApproval enlistmentReserveApproval = new EnlistmentReserveApproval();
// 赋值
enlistmentReserveApproval.setApplyId(ApplyId);
enlistmentReserveApproval.setProcessInstanceId(processInstanceId);
enlistmentReserveApproval.setTaskId(taskId);
enlistmentReserveApproval.setNodeName(nodeName);
enlistmentReserveApproval.setApproverId(SecurityUtils.getLoginUser().getUser().getUserId());
// SecurityUtils.getUserName()是工号
enlistmentReserveApproval.setApproverName(SecurityUtils.getLoginUser().getUser().getNickName());
// 若变量未传递,直接用默认值“同意”(前端点击同意按钮的默认意见)
enlistmentReserveApproval.setApprovalOpinion(approvalOpinion != null ? approvalOpinion : "同意");
if (approvalOpinion != null) {
enlistmentReserveApproval.setApprovalResult(!approvalOpinion.equals("同意") ? 0L : 1L); // 1-通过,若有驳回场景需根据变量调整
}
// 审批时间:当前系统时间
enlistmentReserveApproval.setApprovalTime(new Date());
enlistmentReserveApproval.setStudentName(studentName);
enlistmentReserveApproval.setStudentNo(studentNo);
System.out.println(SecurityUtils.getLoginUser().getUser());
EnlistmentReserveApprovalMapper rtEnlistmentReserveApprovalMapper = (EnlistmentReserveApprovalMapper) SpringUtils.getBean(EnlistmentReserveApprovalMapper.class);
// 查询审批记录是否存在
EnlistmentReserveApproval enlistmentReserveApproval1 = rtEnlistmentReserveApprovalMapper.selectRtEnlistmentReserveApprovalByStuName(studentName, studentNo, SecurityUtils.getLoginUser().getUser().getUserId());
if (enlistmentReserveApproval1 == null) {
rtEnlistmentReserveApprovalMapper.insertRtEnlistmentReserveApproval(enlistmentReserveApproval);
} else {
enlistmentReserveApproval.setId(enlistmentReserveApproval1.getId());
rtEnlistmentReserveApprovalMapper.updateRtEnlistmentReserveApproval(enlistmentReserveApproval);
}
}
}

View File

@@ -0,0 +1,72 @@
package com.srs.flowable.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.srs.flowable.domain.EnlistmentReserveApproval;
import org.apache.ibatis.annotations.Param;
/**
* 保留学籍审批记录Mapper接口
*
* @author srs
* @date 2025-11-13
*/
public interface EnlistmentReserveApprovalMapper extends BaseMapper<EnlistmentReserveApproval> {
/**
* 查询保留学籍审批记录
*
* @param id 保留学籍审批记录主键
* @return 保留学籍审批记录
*/
public EnlistmentReserveApproval selectRtEnlistmentReserveApprovalById(Long id);
/**
* 根据学生姓名学号和审批人id查询保留学籍审批记录
*
* @param
* @return 结果
*/
EnlistmentReserveApproval selectRtEnlistmentReserveApprovalByStuName(@Param("studentName") String studentName, @Param("studentNo") String studentNo, @Param("approverId") Long approverId);
/**
* 查询保留学籍审批记录列表
*
* @param enlistmentReserveApproval 保留学籍审批记录
* @return 保留学籍审批记录集合
*/
List<EnlistmentReserveApproval> selectRtEnlistmentReserveApprovalList(EnlistmentReserveApproval enlistmentReserveApproval);
/**
* 新增保留学籍审批记录
*
* @param enlistmentReserveApproval 保留学籍审批记录
* @return 结果
*/
int insertRtEnlistmentReserveApproval(EnlistmentReserveApproval enlistmentReserveApproval);
/**
* 修改保留学籍审批记录
*
* @param enlistmentReserveApproval 保留学籍审批记录
* @return 结果
*/
int updateRtEnlistmentReserveApproval(EnlistmentReserveApproval enlistmentReserveApproval);
/**
* 删除保留学籍审批记录
*
* @param id 保留学籍审批记录主键
* @return 结果
*/
int deleteRtEnlistmentReserveApprovalById(Long id);
/**
* 批量删除保留学籍审批记录
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
int deleteRtEnlistmentReserveApprovalByIds(Long[] ids);
}

View File

@@ -0,0 +1,77 @@
package com.srs.flowable.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.srs.common.doman.vo.TeacherVo;
import com.srs.flowable.domain.EnlistmentReserve;
import org.apache.ibatis.annotations.Options;
import java.util.List;
/**
* 应征入伍保留学籍申请Mapper接口
*
* @author srs
* @date 2025-10-31
*/
public interface EnlistmentReserveMapper extends BaseMapper<EnlistmentReserve> {
/**
* 查询应征入伍保留学籍申请
*
* @param id 应征入伍保留学籍申请主键
* @return 应征入伍保留学籍申请
*/
public EnlistmentReserve selectRtEnlistmentReserveById(Long id);
/**
* 查询应征入伍保留学籍申请
*
* @param processInstanceId Flowable流程实例ID
* @return 应征入伍保留学籍申请
*/
public EnlistmentReserve selectRtEnlistmentReserveByProcessInstanceId(String processInstanceId);
// <!-- 根据学号查询辅导员信息 -->
public TeacherVo getCounselorInfo(String stuNo);
/**
* 查询应征入伍保留学籍申请列表
*
* @param rtEnlistmentReserve 应征入伍保留学籍申请
* @return 应征入伍保留学籍申请集合
*/
List<EnlistmentReserve> selectRtEnlistmentReserveList(EnlistmentReserve rtEnlistmentReserve);
/**
* 新增应征入伍保留学籍申请
*
* @param enlistmentReserve 应征入伍保留学籍申请
* @return 结果
*/
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
int insertRtEnlistmentReserve(EnlistmentReserve enlistmentReserve);
/**
* 修改应征入伍保留学籍申请
*
* @param enlistmentReserve 应征入伍保留学籍申请
* @return 结果
*/
int updateRtEnlistmentReserve(EnlistmentReserve enlistmentReserve);
/**
* 删除应征入伍保留学籍申请
*
* @param id 应征入伍保留学籍申请主键
* @return 结果
*/
int deleteRtEnlistmentReserveById(Long id);
/**
* 批量删除应征入伍保留学籍申请
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
int deleteRtEnlistmentReserveByIds(Long[] ids);
}