@@ -7,11 +7,13 @@ import java.util.Map;
import com.srs.common.core.domain.AjaxResult ;
import com.srs.common.doman.dto.ProcessResultDto ;
import com.srs.common.doman.vo.TeacherVo ;
import com.srs.common.exception.ServiceException ;
import com.srs.common.utils.DateUtils ;
import com.srs.common.utils.SecurityUtils ;
import com.srs.flowable.service.IFlowDefinitionService ;
import lombok.extern.slf4j.Slf4j ;
import com.srs.routine.mapper.RtStuLeaveApplicationMapper ;
import org.apache.commons.lang3.StringUtils ;
import org.flowable.engine.IdentityService ;
import org.flowable.engine.TaskService ;
import org.flowable.task.api.Task ;
@@ -33,8 +35,8 @@ public class RtEnlistmentReserveServiceImpl extends ServiceImpl<RtEnlistmentRese
@Autowired
private RtEnlistmentReserveMapper rtEnlistmentReserveMapper ;
@Autowired
private RtStuLeaveApplicationMapper rtStuLeaveApplicationMapper ;
// @Autowired
// private RtStuLeaveApplicationMapper rtStuLeaveApplicationMapper;
@Autowired
IFlowDefinitionService flowDefinitionService ;
@@ -75,18 +77,46 @@ public class RtEnlistmentReserveServiceImpl extends ServiceImpl<RtEnlistmentRese
*/
@Override
public int insertRtEnlistmentReserve ( RtEnlistmentReserve rtEnlistmentReserve ) {
rtEnlistmentReserve . setCreateTime ( DateUtils . getNowDate ( ) ) ;
// if (rtEnlistmentReserve.getApplyStatus() != null && rtEnlistmentReserve.getApplyStatus().equals("1")) {
rtEnlistmentReserve . setCreateTime ( DateUtils . getNowDate ( ) ) ;
// 先插入申请表数据,获取自增 ID( 数据库自动为 applyStatus 赋值 0 若未传值)
int insertCount = rtEnlistmentReserveMapper . insertRtEnlistmentReserve ( rtEnlistmentReserve ) ;
if ( insertCount < = 0 ) {
throw new ServiceException ( " 申请表插入失败 " , 500 ) ;
}
Long applyId = rtEnlistmentReserve . getId ( ) ;
if ( applyId = = null ) {
throw new ServiceException ( " 申请表 ID 生成失败,无法继续操作 " , 500 ) ;
}
// 仅当 applyStatus = 1 时, 启动流程( 1=提交申请,进入审批)
// 注意:若前端未传 applyStatus, 数据库默认 0, 不会触发流程
if ( 1 = = rtEnlistmentReserve . getApplyStatus ( ) ) {
// 绑定当前学生 ID( 提交人即学生本人, 确保流程变量准确)
rtEnlistmentReserve . setStudentId ( SecurityUtils . getUserId ( ) ) ;
// 启动流程(此时 applyId 已存在,可正常传递)
ProcessResultDto processResultDto = startEnlistmentReserveProcess ( rtEnlistmentReserve ) ;
if ( processResultDto ! = null ) {
rtEnlistmentReserve . setProcessInstanceId ( processResultDto . getProcessInstanceId ( ) ) ;
// r tEnlistmentReserve.setDeployId(processResultDto.getDeploymentId()) ;
// rtEnlistmentReserveMapper.updateRtEnlistmentReserve(rtEnlistmentReserve) ;
// 3.3 同步更新流程实例 ID + 申请状态为“审批中”( 2) , 形成业务闭环
if ( processResultDto ! = null & & StringUtils . isNotBlank ( processResultDto . getProcessInstanceId ( ) ) ) {
R tEnlistmentReserve updateEntity = new RtEnlistmentReserve ( ) ;
updateEntity . setId ( applyId ) ;
updateEntity . setProcessInstanceId ( processResultDto . getProcessInstanceId ( ) ) ;
updateEntity . setApplyStatus ( 1L ) ; // 审批中状态(根据实际枚举调整)
rtEnlistmentReserveMapper . updateRtEnlistmentReserve ( updateEntity ) ;
System . out . println ( " 申请表[ " + applyId + " ]已启动流程, 实例ID: " + processResultDto . getProcessInstanceId ( ) + " ,状态更新为审批中 " ) ;
} else {
throw new ServiceException ( " 流程启动失败,请重试 " , 500 ) ;
}
// }
return rtEnlistmentReserveMapper . insertRtEnlistmentReserve ( rtEnlistmentReserve ) ;
} else {
// 若 applyStatus 为 0( 数据库默认) 或其他值, 仅保存表单, 不启动流程
String statusDesc = rtEnlistmentReserve . getApplyStatus ( ) = = 0 ? " 草稿 " : " 非提交状态 " ;
System . out . println ( " 申请表[ " + applyId + " ]状态为 " + rtEnlistmentReserve . getApplyStatus ( ) + " ( " + statusDesc + " ),暂不启动流程 " ) ;
}
return insertCount ;
}
/**
@@ -97,17 +127,50 @@ public class RtEnlistmentReserveServiceImpl extends ServiceImpl<RtEnlistmentRese
*/
@Override
public int updateRtEnlistmentReserve ( RtEnlistmentReserve rtEnlistmentReserve ) {
if ( rtEnlistmentReserve . getId ( ) = = null ) {
throw new ServiceException ( " 申请表ID不能为空, 无法更新 " , 500 ) ;
}
rtEnlistmentReserve . setUpdateTime ( DateUtils . getNowDate ( ) ) ;
rtEnlistmentReserve . setUpdateBy ( SecurityUtils . getUsername ( ) ) ;
// if (rtEnlistmentReserve.getApplyStatus().equals("1")) {
ProcessResultDto processResultDto = startEnlistmentReserveProcess ( rtEnlistmentReserve ) ;
// 查询当前申请表的已有状态(判断流程是否已启动)
RtEnlistmentReserve existing = rtEnlistmentReserveMapper . selectRtEnlistmentReserveById ( rtEnlistmentReserve . getId ( ) ) ;
if ( existing = = null ) {
throw new ServiceException ( " 未查询到申请表数据,无法更新 " , 500 ) ;
}
if ( processResultDto ! = null ) {
// 判断流程是否已启动(存在 processInstanceId 即为已启动)
boolean isProcessStarted = StringUtils . isNotBlank ( existing . getProcessInstanceId ( ) ) ;
if ( isProcessStarted ) {
// 流程已启动:仅更新数据库,不操作流程(避免重复启动)
System . out . println ( " 申请表[ " + rtEnlistmentReserve . getId ( ) + " ]流程已启动( 实例ID: " + existing . getProcessInstanceId ( ) + " ),仅更新数据 " ) ;
// 注意:若需更新流程相关变量,需调用 Flowable 的 runtimeService.setVariables(),此处仅更新业务表
return rtEnlistmentReserveMapper . updateRtEnlistmentReserve ( rtEnlistmentReserve ) ;
} else {
// 流程未启动:仅当 applyStatus=1 时启动流程,否则仅更新数据
Long applyStatus = rtEnlistmentReserve . getApplyStatus ( ) ;
if ( 1L = = applyStatus ) {
// 绑定当前学生ID, 启动流程
rtEnlistmentReserve . setStudentId ( SecurityUtils . getUserId ( ) ) ;
ProcessResultDto processResultDto = startEnlistmentReserveProcess ( rtEnlistmentReserve ) ;
if ( processResultDto = = null | | StringUtils . isBlank ( processResultDto . getProcessInstanceId ( ) ) ) {
throw new ServiceException ( " 流程启动失败,请重试 " , 500 ) ;
}
// 关联流程实例ID, 更新为“审批中”状态
rtEnlistmentReserve . setProcessInstanceId ( processResultDto . getProcessInstanceId ( ) ) ;
rtEnlistmentReserve . setApplyStatus ( 1L ) ; // 审批中
System . out . println ( " 申请表[ " + rtEnlistmentReserve . getId ( ) + " ]启动流程成功, 实例ID: " + processResultDto . getProcessInstanceId ( ) ) ;
} else {
// 非提交状态:仅更新基础数据(如草稿修改)
String statusDesc = applyStatus = = null ? " 未指定状态 " : ( applyStatus = = 0 ? " 草稿 " : " 其他状态 " ) ;
System . out . println ( " 申请表[ " + rtEnlistmentReserve . getId ( ) + " ]状态为 " + statusDesc + " ,流程未启动,仅更新数据 " ) ;
}
// }
return rtEnlistmentReserveMapper . updateRtEnlistmentReserve ( rtEnlistmentReserve ) ;
// 执行数据库更新( 含流程实例ID绑定或基础数据更新)
return rtEnlistmentReserveMapper . updateRtEnlistmentReserve ( rtEnlistmentReserve ) ;
}
}
/**
@@ -116,53 +179,72 @@ public class RtEnlistmentReserveServiceImpl extends ServiceImpl<RtEnlistmentRese
* @param rtEnlistmentReserve
*/
private ProcessResultDto startEnlistmentReserveProcess ( RtEnlistmentReserve rtEnlistmentReserve ) {
Map < String , Object > variables = new HashMap < > ( ) ;
variables . put ( " applyNo " , rtEnlistmentReserve . getApplyNo ( ) . toString ( ) ) ;
// variables.put("applyNo", rtEnlistmentReserve.getReserveNo());
// 1. 传递关键变量(申请编号+主键ID, 用于任务匹配)
String applyNo = rtEnlistmentReserve . getApplyNo ( ) ; // 申请编号( 如RY2024001)
Long enlistmentId = rtEnlistmentReserve . getId ( ) ; // 申请表主键ID
variables . put ( " applyNo " , applyNo ) ;
variables . put ( " enlistmentId " , enlistmentId ) ; // 新增:用于任务匹配的主键变量
variables . put ( " stuId " , rtEnlistmentReserve . getStudentId ( ) ) ;
TeacherVo counselorInfo = rtStuLeaveApplicationMapper . getCounselorInfo ( rtEnlistmentReserve . getStudentId ( ) ) ;
// 把辅导员的userId放到approval中
variables . put ( " approval " , counselorInfo . getUserId ( ) ) ;
// 2. 查询辅导员信息
TeacherVo counselorInfo = rtEnlistmentReserveMapper . getCounselorInfo ( rtEnlistmentReserve . getStudentNo ( ) ) ;
if ( counselorInfo = = null ) {
throw new ServiceException ( " 该学生暂无辅导员 " , 500 ) ;
}
variables . put ( " approval " , counselorInfo . getUserId ( ) ) ; // 下一节点:辅导员
variables . put ( " deptId " , counselorInfo . getDeptId ( ) ) ;
//flow_m4npextk:28:257686 flow_m4npextk:31:755004
AjaxResult ajaxResult = flowDefinitionService . startProcessInstanceById ( " flow_r064jfpz:3 :1027504 " , variables ) ;
// 3. 启动流程
AjaxResult ajaxResult = flowDefinitionService . startProcessInstanceById ( " flow_r064jfpz:4 :1032511 " , variables ) ;
String code = ajaxResult . get ( " code " ) . toString ( ) ;
if ( code . equals ( " 200 " ) ) {
System . out . println ( " 流程启动成功 " ) ;
Object obj = ajaxResult . get ( " data " ) ;
ProcessResultDto dto = ( ProcessResultDto ) obj ;
// 操作工作流
// 设置当前用户
identityService . setAuthenticatedUserId ( SecurityUtils . getUserId ( ) . toString ( ) ) ;
// 查询待办任务列表
List < Task > tasks = taskService . createTaskQuery ( )
. processInstanceId ( dto . getProcessInstanceId ( ) )
. taskAssignee ( SecurityUtils . getUserId ( ) . toString ( ) )
. active ( )
. list ( ) ;
// 保存审核结果到任务变量中
variables . put ( " approved " , true ) ;
// 完成待办任务列表
for ( Task task : tasks ) {
String taskId = task . getId ( ) ;
String leaveId = taskService . getVariable ( taskId , " enlistmentReserveId " ) . toString ( ) ;
if ( leaveId . equals ( rtEnlistmentReserve . getId ( ) . toString ( ) ) ) {
taskService . complete ( task . getId ( ) , variables ) ;
}
}
// todo 企业微信推送消息
return dto ;
} else {
return null ;
if ( ! " 200 " . equals ( code ) ) {
throw new ServiceException ( " 流程启动失败,错误码: " + code , 500 ) ;
}
ProcessResultDto dto = ( ProcessResultDto ) ajaxResult . get ( " data " ) ;
System . out . println ( " 流程启动成功, 实例ID: " + dto . getProcessInstanceId ( ) ) ;
// 4. 学生自动完成自己的待办任务
identityService . setAuthenticatedUserId ( SecurityUtils . getUserId ( ) . toString ( ) ) ;
// 精准查询当前流程中属于学生的待办任务
List < Task > tasks = taskService . createTaskQuery ( )
. processInstanceId ( dto . getProcessInstanceId ( ) )
. taskAssignee ( SecurityUtils . getUserId ( ) . toString ( ) )
. active ( )
. list ( ) ;
if ( tasks . isEmpty ( ) ) {
throw new ServiceException ( " 未查询到学生的待办任务,请检查流程设计 " , 500 ) ;
}
// 5. 完成任务( 匹配主键ID, 避免错误)
variables . put ( " approved " , true ) ; // 学生提交确认
for ( Task task : tasks ) {
// 安全获取变量: 先判断是否为null, 再转换类型
Object varValue = taskService . getVariable ( task . getId ( ) , " enlistmentId " ) ;
if ( varValue = = null ) {
continue ;
}
// 转换为Long类型( 与主键ID匹配)
Long taskEnlistmentId ;
try {
taskEnlistmentId = Long . parseLong ( varValue . toString ( ) ) ;
} catch ( NumberFormatException e ) {
continue ; // 类型不匹配,跳过
}
// 匹配当前申请表的主键ID
if ( taskEnlistmentId . equals ( enlistmentId ) ) {
taskService . complete ( task . getId ( ) , variables ) ;
System . out . println ( " 学生已完成待办任务, 任务ID: " + task . getId ( ) ) ;
break ; // 完成后退出循环,避免重复处理
}
}
// 6. 推送消息给辅导员(待办提醒)
// todo: 企业微信推送逻辑
return dto ;
}
/**