From c6abc87555094148a5eb1581a9c8686dd88458ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=81=92=E6=88=90?= <962704835@qq.com> Date: Mon, 8 Dec 2025 17:28:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=96=E5=AE=BF=E7=94=B3=E8=AF=B7-=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E7=9B=91=E5=90=AC=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DmsOutsideAccommodationApplyMapper.java | 23 ++ .../IDmsOutsideAccommodationApplyService.java | 8 + ...sOutsideAccommodationApplyServiceImpl.java | 5 + .../DmsOutsideAccommodationApplyMapper.xml | 32 ++ ...msOutsideAccommodationApplyController.java | 12 +- .../RtEnlistmentReserveController.java | 26 ++ .../domain/OutsideAccommodationApply.java | 356 +++++++++++++++++ .../domain/OutsideAccommodationApproval.java | 139 +++++++ .../OutsideAccommodationEndListener.java | 128 ++++++ .../OutsideAccommodationStartListener.java | 169 ++++++++ .../OutsideAccommodationApplyMapper.java | 85 ++++ .../OutsideAccommodationApprovalMapper.java | 71 ++++ .../OutsideAccommodationApplyMapper.xml | 374 ++++++++++++++++++ .../OutsideAccommodationApprovalMapper.xml | 127 ++++++ .../service/IRtEnlistmentReserveService.java | 18 + .../impl/RtEnlistmentReserveServiceImpl.java | 237 ++++++++++- 16 files changed, 1806 insertions(+), 4 deletions(-) create mode 100644 srs-flowable/src/main/java/com/srs/flowable/domain/OutsideAccommodationApply.java create mode 100644 srs-flowable/src/main/java/com/srs/flowable/domain/OutsideAccommodationApproval.java create mode 100644 srs-flowable/src/main/java/com/srs/flowable/listener/outsideAccommodation/OutsideAccommodationEndListener.java create mode 100644 srs-flowable/src/main/java/com/srs/flowable/listener/outsideAccommodation/OutsideAccommodationStartListener.java create mode 100644 srs-flowable/src/main/java/com/srs/flowable/mapper/OutsideAccommodationApplyMapper.java create mode 100644 srs-flowable/src/main/java/com/srs/flowable/mapper/OutsideAccommodationApprovalMapper.java create mode 100644 srs-flowable/src/main/resources/mapper/OutsideAccommodationApplyMapper.xml create mode 100644 srs-flowable/src/main/resources/mapper/OutsideAccommodationApprovalMapper.xml diff --git a/dms-dormitory/src/main/java/com/srs/dormitory/mapper/DmsOutsideAccommodationApplyMapper.java b/dms-dormitory/src/main/java/com/srs/dormitory/mapper/DmsOutsideAccommodationApplyMapper.java index a877d31..241bdf3 100644 --- a/dms-dormitory/src/main/java/com/srs/dormitory/mapper/DmsOutsideAccommodationApplyMapper.java +++ b/dms-dormitory/src/main/java/com/srs/dormitory/mapper/DmsOutsideAccommodationApplyMapper.java @@ -2,8 +2,11 @@ package com.srs.dormitory.mapper; import java.util.List; +import com.srs.common.doman.vo.TeacherVo; import com.srs.dormitory.domain.DmsOutsideAccommodationApply; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Options; +import org.apache.ibatis.annotations.Param; /** * 外宿申请Mapper接口 @@ -20,6 +23,14 @@ public interface DmsOutsideAccommodationApplyMapper extends BaseMapper selectDmsOutsideAccommodationApplyList(DmsOutsideAccommodationApply dmsOutsideAccommodationApply); + // + public TeacherVo getCounselorInfo(String stuNo); + + /** + * 查询外宿申请 + * + * @param studentName 学生姓名 + * @return 应征入伍保留学籍申请 + */ + public DmsOutsideAccommodationApply getAccommodationByStuNameAndStuNo(@Param("studentName") String studentName, @Param("studentNo") String studentNo); + /** * 新增外宿申请 * * @param dmsOutsideAccommodationApply 外宿申请 * @return 结果 */ + @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") int insertDmsOutsideAccommodationApply(DmsOutsideAccommodationApply dmsOutsideAccommodationApply); /** diff --git a/dms-dormitory/src/main/java/com/srs/dormitory/service/IDmsOutsideAccommodationApplyService.java b/dms-dormitory/src/main/java/com/srs/dormitory/service/IDmsOutsideAccommodationApplyService.java index 411db75..10dfecc 100644 --- a/dms-dormitory/src/main/java/com/srs/dormitory/service/IDmsOutsideAccommodationApplyService.java +++ b/dms-dormitory/src/main/java/com/srs/dormitory/service/IDmsOutsideAccommodationApplyService.java @@ -20,6 +20,14 @@ public interface IDmsOutsideAccommodationApplyService extends IService + + + + + + + + + + insert into dms_outside_accommodation_apply diff --git a/srs-admin/src/main/java/com/srs/web/controller/dormitory/DmsOutsideAccommodationApplyController.java b/srs-admin/src/main/java/com/srs/web/controller/dormitory/DmsOutsideAccommodationApplyController.java index e4f32f5..2aa8c7f 100644 --- a/srs-admin/src/main/java/com/srs/web/controller/dormitory/DmsOutsideAccommodationApplyController.java +++ b/srs-admin/src/main/java/com/srs/web/controller/dormitory/DmsOutsideAccommodationApplyController.java @@ -72,6 +72,16 @@ public class DmsOutsideAccommodationApplyController extends BaseController { return success(dmsOutsideAccommodationApplyService.selectDmsOutsideAccommodationApplyById(id)); } + /** + * 获取外宿申请详细信息 + */ + @PreAuthorize("@ss.hasPermi('dormitory:enlistmentReserve:query')") + @GetMapping(value = "/process/{processInstanceId}") + @ApiOperation("获取应征入伍保留学籍申请详细信息") + public AjaxResult getInfoByProcessInstanceId(@PathVariable("processInstanceId") String processInstanceId) { + return success(dmsOutsideAccommodationApplyService.selectDmsOutsideAccommodationApplyByProcessInstanceId(processInstanceId)); + } + /** * 新增外宿申请 */ @@ -81,7 +91,7 @@ public class DmsOutsideAccommodationApplyController extends BaseController { @ApiOperation("新增外宿申请") public AjaxResult add(@RequestBody DmsOutsideAccommodationApply dmsOutsideAccommodationApply) { - return toAjax(dmsOutsideAccommodationApplyService.insertDmsOutsideAccommodationApply(dmsOutsideAccommodationApply)); + return success(dmsOutsideAccommodationApplyService.insertDmsOutsideAccommodationApply(dmsOutsideAccommodationApply)); } /** diff --git a/srs-admin/src/main/java/com/srs/web/controller/routine/RtEnlistmentReserveController.java b/srs-admin/src/main/java/com/srs/web/controller/routine/RtEnlistmentReserveController.java index 6808230..669acb8 100644 --- a/srs-admin/src/main/java/com/srs/web/controller/routine/RtEnlistmentReserveController.java +++ b/srs-admin/src/main/java/com/srs/web/controller/routine/RtEnlistmentReserveController.java @@ -3,6 +3,7 @@ package com.srs.web.controller.routine; import java.util.List; import javax.servlet.http.HttpServletResponse; +import com.srs.dormitory.domain.DmsOutsideAccommodationApply; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -112,4 +113,29 @@ public class RtEnlistmentReserveController extends BaseController { public AjaxResult remove(@PathVariable Long[] ids) { return toAjax(rtEnlistmentReserveService.deleteRtEnlistmentReserveByIds(ids)); } + + + /** + * 新增外宿申请 + */ + @PreAuthorize("@ss.hasPermi('dormitory:outsideAccommodationApply:add')") + @Log(title = "外宿申请", businessType = BusinessType.INSERT) + @PostMapping("/outsideAccommodationApply/add") + @ApiOperation("新增外宿申请") + public AjaxResult add(@RequestBody DmsOutsideAccommodationApply dmsOutsideAccommodationApply) + { + return success(rtEnlistmentReserveService.insertDmsOutsideAccommodationApply(dmsOutsideAccommodationApply)); + } + + /** + * 修改外宿申请 + */ + @PreAuthorize("@ss.hasPermi('dormitory:outsideAccommodationApply:edit')") + @Log(title = "外宿申请", businessType = BusinessType.UPDATE) + @PostMapping("/outsideAccommodationApply/update") + @ApiOperation("修改外宿申请") + public AjaxResult edit(@RequestBody DmsOutsideAccommodationApply dmsOutsideAccommodationApply) + { + return toAjax(rtEnlistmentReserveService.updateDmsOutsideAccommodationApply(dmsOutsideAccommodationApply)); + } } diff --git a/srs-flowable/src/main/java/com/srs/flowable/domain/OutsideAccommodationApply.java b/srs-flowable/src/main/java/com/srs/flowable/domain/OutsideAccommodationApply.java new file mode 100644 index 0000000..b426748 --- /dev/null +++ b/srs-flowable/src/main/java/com/srs/flowable/domain/OutsideAccommodationApply.java @@ -0,0 +1,356 @@ +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; + + +/** + * 外宿申请对象 dms_outside_accommodation_apply + * + * @author srs + * @date 2025-12-06 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@AllArgsConstructor +@Builder +@ApiModel(value = "DmsOutsideAccommodationApply对象", description = "外宿申请表") +@TableName("dms_outside_accommodation_apply") +public class OutsideAccommodationApply extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ApiModelProperty("主键ID") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 申请编号(唯一,如WS20240001) + */ + @ApiModelProperty("申请编号(唯一,如WS20240001)") + @TableField("apply_no") + @Excel(name = "申请编号", readConverterExp = "唯=一,如WS20240001") + private String applyNo; + + /** + * 学生ID(关联学生表) + */ + @ApiModelProperty("学生ID(关联学生表)") + @TableField("student_id") + @Excel(name = "学生ID", readConverterExp = "关=联学生表") + private Long studentId; + + /** + * 学号 + */ + @ApiModelProperty("学号") + @TableField("student_no") + @Excel(name = "学号") + private String studentNo; + + /** + * 学生姓名 + */ + @ApiModelProperty("学生姓名") + @TableField("student_name") + @Excel(name = "学生姓名") + private String studentName; + + /** + * 性别(男/女) + */ + @ApiModelProperty("性别(男/女)") + @TableField("gender") + @Excel(name = "性别", readConverterExp = "男=/女") + private String gender; + + /** + * 出生年月 + */ + @ApiModelProperty("出生年月") + @TableField("birth_date") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "出生年月", width = 30, dateFormat = "yyyy-MM-dd") + private Date birthDate; + + /** + * 学院ID + */ + @ApiModelProperty("学院ID") + @TableField("dept_id") + @Excel(name = "学院ID") + private Long deptId; + + /** + * 学院名称 + */ + @ApiModelProperty("学院名称") + @TableField("dept_name") + @Excel(name = "学院名称") + private String deptName; + + /** + * 专业ID + */ + @ApiModelProperty("专业ID") + @TableField("major_id") + @Excel(name = "专业ID") + private Long majorId; + + /** + * 专业名称 + */ + @ApiModelProperty("专业名称") + @TableField("major_name") + @Excel(name = "专业名称") + private String majorName; + + /** + * 班级ID + */ + @ApiModelProperty("班级ID") + @TableField("class_id") + @Excel(name = "班级ID") + private Long classId; + + /** + * 班级名称 + */ + @ApiModelProperty("班级名称") + @TableField("class_name") + @Excel(name = "班级名称") + private String className; + + /** + * 原宿舍号(如:1栋302) + */ + @ApiModelProperty("原宿舍号(如:1栋302)") + @TableField("original_dormitory") + @Excel(name = "原宿舍号", readConverterExp = "如=:1栋302") + private String originalDormitory; + + /** + * 住宿费缴纳 + */ + @ApiModelProperty("住宿费缴纳") + @TableField("accommodation_fee") + @Excel(name = "住宿费缴纳") + private String accommodationFee; + + /** + * 住宿费缴纳状态(1=已交,0=未交) + */ + @ApiModelProperty("住宿费缴纳状态(1=已交,0=未交)") + @TableField("accommodation_fee_status") + @Excel(name = "住宿费缴纳状态", readConverterExp = "1==已交,0=未交") + private Long accommodationFeeStatus; + + /** + * 外宿原因 + */ + @ApiModelProperty("外宿原因") + @TableField("apply_reason") + @Excel(name = "外宿原因") + private String applyReason; + + /** + * 外宿详细地址(精确至门牌号) + */ + @ApiModelProperty("外宿详细地址(精确至门牌号)") + @TableField("outside_address") + @Excel(name = "外宿详细地址", readConverterExp = "精=确至门牌号") + private String outsideAddress; + + /** + * 外宿地址-省市区/县 + */ + @ApiModelProperty("外宿地址-省市区/县") + @TableField("address") + @Excel(name = "外宿地址-省市区/县") + private String address; + + /** + * 紧急联系人电话 + */ + @ApiModelProperty("紧急联系人电话") + @TableField("emergency_phone") + @Excel(name = "紧急联系人电话") + private String emergencyPhone; + + /** + * 外宿紧急联系人 + */ + @ApiModelProperty("外宿紧急联系人") + @TableField("emergency_contact") + @Excel(name = "外宿紧急联系人") + private String emergencyContact; + + /** + * 家长意见(1=同意,0=不同意) + */ + @ApiModelProperty("家长意见(1=同意,0=不同意)") + @TableField("parent_opinion") + @Excel(name = "家长意见", readConverterExp = "1==同意,0=不同意") + private Long parentOpinion; + + /** + * 家长签字附件URL + */ + @ApiModelProperty("家长签字附件URL") + @TableField("parent_sign_attachment") + @Excel(name = "家长签字附件URL") + private String parentSignAttachment; + + /** + * 家长联系电话 + */ + @ApiModelProperty("家长联系电话") + @TableField("parent_phone") + @Excel(name = "家长联系电话") + private String parentPhone; + + /** + * 家长通讯地址-省市区/县 + */ + @ApiModelProperty("家长通讯地址-省市区/县") + @TableField("parent_address") + @Excel(name = "家长通讯地址-省市区/县") + private String parentAddress; + + /** + * 家长通讯地址-详细地址 + */ + @ApiModelProperty("家长通讯地址-详细地址") + @TableField("parent_detail_address") + @Excel(name = "家长通讯地址-详细地址") + private String parentDetailAddress; + + /** + * 学生承诺电子签URL + */ + @ApiModelProperty("学生承诺电子签URL") + @TableField("student_promise_sign") + @Excel(name = "学生承诺电子签URL") + private String studentPromiseSign; + + /** + * 承诺签署日期 + */ + @ApiModelProperty("承诺签署日期") + @TableField("promise_date") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "承诺签署日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date promiseDate; + + /** + * 外宿开始时间 + */ + @ApiModelProperty("外宿开始时间") + @TableField("start_date") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "外宿开始时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date startDate; + + /** + * 外宿结束时间(默认次年8月31日) + */ + @ApiModelProperty("外宿结束时间(默认次年8月31日)") + @TableField("end_date") + @Excel(name = "外宿结束时间", readConverterExp = "默=认次年8月31日") + private Date endDate; + + /** + * 申请状态(0=草稿,1=待辅导员审批,2=待学院书记审批,3=待学工处审批,4=待学校领导审批,5=审批通过,6=审批驳回) + */ + @ApiModelProperty("申请状态(0=草稿,1=待辅导员审批,2=待学院书记审批,3=待学工处审批,4=待学校领导审批,5=审批通过,6=审批驳回)") + @TableField("status") + @Excel(name = "申请状态", readConverterExp = "0==草稿,1=待辅导员审批,2=待学院书记审批,3=待学工处审批,4=待学校领导审批,5=审批通过,6=审批驳回") + private Long status; + + /** + * 驳回原因 + */ + @ApiModelProperty("驳回原因") + @TableField("reject_reason") + @Excel(name = "驳回原因") + private String rejectReason; + + /** + * 是否有效(1=有效,0=失效/到期) + */ + @ApiModelProperty("是否有效(1=有效,0=失效/到期)") + @TableField("is_valid") + @Excel(name = "是否有效", readConverterExp = "1==有效,0=失效/到期") + private Long isValid; + + /** + * 辅导员姓名 + */ + @ApiModelProperty("辅导员姓名") + @TableField("teacher_name") + @Excel(name = "辅导员姓名") + private String teacherName; + + /** + * 附件id + */ + @ApiModelProperty("附件id") + @TableField("affix_id") + @Excel(name = "附件id") + private String affixId; + + /** + * 流程部署编号 + */ + @ApiModelProperty("流程部署编号") + @TableField("deploy_id") + @Excel(name = "流程部署编号") + private String deployId; + + /** + * Flowable流程实例ID + */ + @ApiModelProperty("Flowable流程实例ID") + @TableField("process_instance_id") + @Excel(name = "Flowable流程实例ID") + private String processInstanceId; + + /** + * 身份证号码 + */ + @ApiModelProperty("身份证号码") + @TableField("idCard") + @Excel(name = "身份证号码") + private String idCard; + + /** + * 学生手机号码 + */ + @ApiModelProperty("学生手机号码") + @TableField("studentPhone") + @Excel(name = "学生手机号码") + private String studentPhone; + + /** + * 外宿原因学生签名URL + */ + @ApiModelProperty("外宿原因学生签名URL") + @TableField("student_signature") + @Excel(name = "外宿原因学生签名URL") + private String studentSignature; + + +} diff --git a/srs-flowable/src/main/java/com/srs/flowable/domain/OutsideAccommodationApproval.java b/srs-flowable/src/main/java/com/srs/flowable/domain/OutsideAccommodationApproval.java new file mode 100644 index 0000000..dbadaab --- /dev/null +++ b/srs-flowable/src/main/java/com/srs/flowable/domain/OutsideAccommodationApproval.java @@ -0,0 +1,139 @@ +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; + + + +/** + * 外宿申请审批记录对象 dms_outside_accommodation_approval + * + * @author srs + * @date 2025-12-05 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@AllArgsConstructor +@Builder +@ApiModel(value = "DmsOutsideAccommodationApproval对象" , description = "外宿申请审批记录表") +@TableName("dms_outside_accommodation_approval") +public class OutsideAccommodationApproval extends BaseEntity{ +private static final long serialVersionUID=1L; + + /** + * 主键ID + */ + @ApiModelProperty("主键ID") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 外宿申请ID(关联申请表) + */ + @ApiModelProperty("外宿申请ID(关联申请表)") + @TableField("apply_id") + @Excel(name = "外宿申请ID" , readConverterExp = "关=联申请表") + private Long applyId; + + /** + * 申请编号 + */ + @ApiModelProperty("申请编号") + @TableField("apply_no") + @Excel(name = "申请编号") + private String applyNo; + + /** + * 审批节点 + */ + @ApiModelProperty("审批节点") + @TableField("approval_node") + @Excel(name = "审批节点") + private String approvalNode; + + /** + * 审批人ID + */ + @ApiModelProperty("审批人ID") + @TableField("approver_id") + @Excel(name = "审批人ID") + private Long approverId; + + /** + * 审批人姓名 + */ + @ApiModelProperty("审批人姓名") + @TableField("approver_name") + @Excel(name = "审批人姓名") + private String approverName; + + /** + * 审批人角色 + */ + @ApiModelProperty("审批人角色") + @TableField("approver_role") + @Excel(name = "审批人角色") + private String approverRole; + + /** + * 审批意见 + */ + @ApiModelProperty("审批意见") + @TableField("approval_opinion") + @Excel(name = "审批意见") + private String approvalOpinion; + + /** + * 审批结果(1=同意,0=驳回) + */ + @ApiModelProperty("审批结果(1=同意,0=驳回)") + @TableField("approval_result") + @Excel(name = "审批结果" , readConverterExp = "1==同意,0=驳回") + private Long approvalResult; + + /** + * 审批时间 + */ + @ApiModelProperty("审批时间") + @TableField("approval_time") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "审批时间" , width = 30, dateFormat = "yyyy-MM-dd") + private Date approvalTime; + + /** + * 流程实例ID + */ + @ApiModelProperty("流程实例ID") + @TableField("process_instance_id") + @Excel(name = "流程实例ID") + private String processInstanceId; + + /** + * 学生姓名 + */ + @ApiModelProperty("学生姓名") + @TableField("student_name") + @Excel(name = "学生姓名") + private String studentName; + + /** + * 学生学号 + */ + @ApiModelProperty("学生学号") + @TableField("student_no") + @Excel(name = "学生学号") + private String studentNo; + + +} diff --git a/srs-flowable/src/main/java/com/srs/flowable/listener/outsideAccommodation/OutsideAccommodationEndListener.java b/srs-flowable/src/main/java/com/srs/flowable/listener/outsideAccommodation/OutsideAccommodationEndListener.java new file mode 100644 index 0000000..04a2974 --- /dev/null +++ b/srs-flowable/src/main/java/com/srs/flowable/listener/outsideAccommodation/OutsideAccommodationEndListener.java @@ -0,0 +1,128 @@ +package com.srs.flowable.listener.outsideAccommodation; + + +import com.srs.common.utils.SecurityUtils; +import com.srs.common.utils.spring.SpringUtils; +import com.srs.dormitory.domain.DmsOutsideAccommodationApply; +import com.srs.flowable.domain.EnlistmentReserve; +import com.srs.flowable.domain.EnlistmentReserveApproval; +import com.srs.flowable.domain.OutsideAccommodationApply; +import com.srs.flowable.domain.OutsideAccommodationApproval; +import com.srs.flowable.mapper.EnlistmentReserveApprovalMapper; +import com.srs.flowable.mapper.EnlistmentReserveMapper; +import com.srs.flowable.mapper.OutsideAccommodationApplyMapper; +import com.srs.flowable.mapper.OutsideAccommodationApprovalMapper; +import com.srs.system.service.ISysUserService; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.FlowNode; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.ExecutionListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Date; + + +/** + * 审批流程负责人自动流转监听器 + * 用于节点审批通过时,添加审批记录 + */ +@Component("OutsideAccommodationEndListener") // Spring Bean名称,与BPMN表达式对应 +public class OutsideAccommodationEndListener implements ExecutionListener { + + // 用于查询流程定义中的节点信息 + @Autowired + private RepositoryService repositoryService; + + @Override + public void notify(DelegateExecution execution) { + // 1. 获取当前节点ID和流程定义ID + String currentActivityId = execution.getCurrentActivityId(); // 当前节点ID(兼容所有版本) + String processDefinitionId = execution.getProcessDefinitionId(); // 流程定义ID + + // 2. 根据节点ID查询节点名称(核心修正:通过流程定义获取名称) + String currentNodeName = getNodeNameByActivityId(processDefinitionId, currentActivityId); + if (currentNodeName == null) { + throw new RuntimeException("未找到节点ID=" + currentActivityId + "的名称"); + } + + // 获取申请表id + Long accommodationId = Long.valueOf(execution.getVariable("accommodationId").toString()); + + // 获取审核意见 + String approvalOpinion = (String) execution.getVariable("approvalOpinion"); + + // 获取审核状态(兼容Integer/Long类型) + Object approvalResultObj = execution.getVariable("approvalResult"); + Long approvalResult = null; + if (approvalResultObj != null) { + // 先转为数字,再获取long值 + Number num = (Number) approvalResultObj; + approvalResult = num.longValue(); + } + + // 添加审批记录 + OutsideAccommodationApplyMapper outsideAccommodationApplyMapper = SpringUtils.getBean(OutsideAccommodationApplyMapper.class); + // 根据Id查询外宿申请记录 + OutsideAccommodationApply outsideAccommodationApply = outsideAccommodationApplyMapper.selectDmsOutsideAccommodationApplyById(accommodationId); + saveApprovalRecord(outsideAccommodationApply.getId(), outsideAccommodationApply.getProcessInstanceId(),outsideAccommodationApply.getApplyNo(),currentNodeName, outsideAccommodationApply.getStudentName(), outsideAccommodationApply.getStudentNo(), approvalOpinion, approvalResult); + + // 如果到了最后一个审批人,则修改申请表审核状态 + if (currentNodeName.equals("学校领导审批")){ + // 改变申请表中的审核状态(审核通过) + outsideAccommodationApply.setStatus(5L); + outsideAccommodationApplyMapper.updateDmsOutsideAccommodationApply(outsideAccommodationApply); + } + } + + /** + * 根据节点ID和流程定义ID,查询节点名称(兼容所有版本的核心方法) + */ + private String getNodeNameByActivityId(String processDefinitionId, String activityId) { + // 获取流程模型 + BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); + if (bpmnModel == null) { + throw new RuntimeException("未找到流程定义ID=" + processDefinitionId + "的模型"); + } + + // 从模型中获取节点信息(FlowNode包含用户任务、网关等节点) + FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(activityId); + return flowNode != null ? flowNode.getName() : null; + } + + /** + * 通用审批记录保存方法 + */ + private void saveApprovalRecord(Long ApplyId,String processInstanceId, String applyNo, String nodeName, String studentName, String studentNo, String approvalOpinion, Long approvalResult) { + OutsideAccommodationApproval outsideAccommodationApproval = new OutsideAccommodationApproval(); + // 赋值 + outsideAccommodationApproval.setApplyId(ApplyId); + outsideAccommodationApproval.setProcessInstanceId(processInstanceId); + outsideAccommodationApproval.setApplyNo(applyNo); + outsideAccommodationApproval.setApprovalNode(nodeName); + outsideAccommodationApproval.setApproverId(SecurityUtils.getLoginUser().getUser().getUserId()); + // SecurityUtils.getUserName()是工号 + outsideAccommodationApproval.setApproverName(SecurityUtils.getLoginUser().getUser().getNickName()); + System.out.println(SecurityUtils.getLoginUser().getUser()); + // 若变量未传递,直接用默认值“同意”(前端点击同意按钮的默认意见) + outsideAccommodationApproval.setApprovalOpinion(approvalOpinion); + + // 审核状态 + outsideAccommodationApproval.setApprovalResult(approvalResult == null ? 0L : approvalResult); + + // 审批时间:当前系统时间 + outsideAccommodationApproval.setApprovalTime(new Date()); + outsideAccommodationApproval.setStudentName(studentName); + outsideAccommodationApproval.setStudentNo(studentNo); + OutsideAccommodationApprovalMapper outsideAccommodationApprovalMapper = (OutsideAccommodationApprovalMapper) SpringUtils.getBean(OutsideAccommodationApprovalMapper.class); + // 查询审批记录是否存在 + OutsideAccommodationApproval approval = outsideAccommodationApprovalMapper.selectOutsideAccommodationApprovalByStuName(studentName, studentNo, SecurityUtils.getLoginUser().getUser().getUserId()); + if (approval == null) { + outsideAccommodationApprovalMapper.insertDmsOutsideAccommodationApproval(approval); + } else { + approval.setId(approval.getId()); + outsideAccommodationApprovalMapper.insertDmsOutsideAccommodationApproval(approval); + } + } +} \ No newline at end of file diff --git a/srs-flowable/src/main/java/com/srs/flowable/listener/outsideAccommodation/OutsideAccommodationStartListener.java b/srs-flowable/src/main/java/com/srs/flowable/listener/outsideAccommodation/OutsideAccommodationStartListener.java new file mode 100644 index 0000000..165bbc3 --- /dev/null +++ b/srs-flowable/src/main/java/com/srs/flowable/listener/outsideAccommodation/OutsideAccommodationStartListener.java @@ -0,0 +1,169 @@ +package com.srs.flowable.listener.outsideAccommodation; + +import com.srs.common.core.domain.entity.SysUser; +import com.srs.common.doman.vo.TeacherVo; +import com.srs.common.utils.spring.SpringUtils; +import com.srs.dormitory.domain.DmsOutsideAccommodationApply; +import com.srs.flowable.domain.EnlistmentReserve; +import com.srs.flowable.domain.OutsideAccommodationApply; +import com.srs.flowable.mapper.EnlistmentReserveMapper; +import com.srs.flowable.mapper.OutsideAccommodationApplyMapper; +import com.srs.system.service.ISysUserService; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.FlowNode; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.ExecutionListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + + +/** + * 审批流程负责人自动流转监听器 + * 用于节点审批之前时,更新下一个节点的负责人变量(approval) + */ +@Component("OutsideAccommodationStartListener") // Spring Bean名称,与BPMN表达式对应 +public class OutsideAccommodationStartListener implements ExecutionListener { + + @Autowired + private ISysUserService sysUserService; // 用户服务(查询部门/学院负责人) + + // 用于查询流程定义中的节点信息 + @Autowired + private RepositoryService repositoryService; + + @Override + public void notify(DelegateExecution execution) { + // 1. 获取当前节点ID和流程定义ID + String currentActivityId = execution.getCurrentActivityId(); // 当前节点ID(兼容所有版本) + String processDefinitionId = execution.getProcessDefinitionId(); // 流程定义ID + + // 2. 根据节点ID查询节点名称(核心修正:通过流程定义获取名称) + String currentNodeName = getNodeNameByActivityId(processDefinitionId, currentActivityId); + if (currentNodeName == null) { + throw new RuntimeException("未找到节点ID=" + currentActivityId + "的名称"); + } + + // 获取申请表id + Long accommodationId = Long.valueOf(execution.getVariable("accommodationId").toString()); + + + // 后续逻辑不变:查询下一个节点负责人并更新变量 + Long nextAssigneeId = getNextAssignee(currentNodeName, accommodationId); + if (nextAssigneeId != null) { + execution.setVariable("approval", nextAssigneeId); + execution.setVariable("currentNode", currentNodeName); + } + } + + /** + * 根据节点ID和流程定义ID,查询节点名称(兼容所有版本的核心方法) + */ + private String getNodeNameByActivityId(String processDefinitionId, String activityId) { + // 获取流程模型 + BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); + if (bpmnModel == null) { + throw new RuntimeException("未找到流程定义ID=" + processDefinitionId + "的模型"); + } + + // 从模型中获取节点信息(FlowNode包含用户任务、网关等节点) + FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(activityId); + return flowNode != null ? flowNode.getName() : null; + } + + /** + * 根据当前节点查询下一个节点的负责人 + */ + private Long getNextAssignee(String currentNodeName, Long accommodationId) { + OutsideAccommodationApplyMapper outsideAccommodationApplyMapper = SpringUtils.getBean(OutsideAccommodationApplyMapper.class); + // 根据Id查询外宿申请记录 + OutsideAccommodationApply outsideAccommodationApply = outsideAccommodationApplyMapper.selectDmsOutsideAccommodationApplyById(accommodationId); + // 根据学生学号来获取对应辅导员的信息 + TeacherVo counselorInfo = outsideAccommodationApplyMapper.getCounselorInfo(outsideAccommodationApply.getStudentNo()); + // 获取辅导员的部门id + Long currentDeptId = counselorInfo.getDeptId(); + if (currentDeptId == null) { + throw new RuntimeException("未分配部门,无法匹配负责人"); + } + // 注意:节点名称需与BPMN模型中完全一致(区分大小写) + switch (currentNodeName) { + case "辅导员审批": + // 辅导员开始审批前 → 找到对应辅导员 + // 返回匹配的辅导员用户ID(作为当前节点负责人) + return counselorInfo.getUserId(); + + case "二级学院书记审批": + + // 二级学院书记开始审批前 → 找到对应二级学院书记 + // 查询角色ID=106(二级学院书记)的所有用户 + SysUser queryUser = new SysUser(); + queryUser.setRoleId(106L); // 学务角色固定ID + List academicAffairsUsers = sysUserService.selectAllocatedList(queryUser); + if (academicAffairsUsers.isEmpty()) { + throw new RuntimeException("未查询到角色(二级学院书记)的用户"); + } + + // 从学务用户中筛选出部门ID与当前二级学院书记部门一致的用户 + SysUser targetAcademic = academicAffairsUsers.stream() + .filter(user -> currentDeptId.equals(user.getDeptId())) // 部门ID匹配 + .findFirst() // 取第一个匹配的二级学院书记(若有多个,可根据排序或优先级调整) + .orElseThrow(() -> new RuntimeException("未找到部门ID=" + currentDeptId + "的二级学院书记负责人")); + + + // 返回匹配的二级学院书记用户ID(作为当前节点负责人) + return targetAcademic.getUserId(); + + case "学工处审批": + + // 学工处审批前 → 找到对应学工处 + // 查询角色ID=100(学工处)的所有用户 + SysUser qUser = new SysUser(); + qUser.setRoleId(100L); // 学工处角色固定ID=112 + List collegeUsers = sysUserService.selectAllocatedList(qUser); + if (collegeUsers.isEmpty()) { + throw new RuntimeException("未查询到角色(学工处)的用户"); + } + + // 筛选出部门ID(学院ID)与登录用户所属学院一致的学工处负责人 + SysUser targetCollegeLeader = collegeUsers.stream() + .filter(user -> currentDeptId.equals(user.getDeptId())) // 学院ID匹配(部门ID即学院ID) + .findFirst() + .orElseThrow(() -> new RuntimeException("未找到学院ID=" + currentDeptId + "的学工处负责人")); + + + // 返回匹配的学工处负责人ID + return targetCollegeLeader.getUserId(); + + case "学校领导审批": + // 学校领导审批前 → 找到对应学校领导 + // 查询角色ID=107(学校领导)的所有用户 + SysUser sysUser = new SysUser(); + sysUser.setRoleId(107L); // 学校领导角色固定ID=107 + List sysUsers = sysUserService.selectAllocatedList(sysUser); + if (sysUsers.isEmpty()) { + throw new RuntimeException("未查询到角色(学校领导)的用户"); + } + + // 筛选出部门ID(学院ID)与登录用户所属学院一致的学校领导负责人 + // 改造:findFirst() 找不到则取列表第一个,而非直接抛异常 + SysUser userByDeptId = sysUsers.stream() + .filter(user -> currentDeptId.equals(user.getDeptId())) // 学院ID匹配(部门ID即学院ID) + .findFirst() + // 找不到匹配的则取列表第一个用户 + .orElse(sysUsers.get(0)); + + // 兜底校验(防止极端情况,理论上sysUsers非空,sysUsers.get(0)不会为null) + if (userByDeptId == null) { + throw new RuntimeException("学校领导用户数据异常,无可用负责人"); + } + + // 返回匹配的学校领导负责人ID(优先匹配学院,无匹配则取第一个) + return userByDeptId.getUserId(); + + default: + throw new RuntimeException("未配置节点[" + currentNodeName + "]的当前负责人规则"); + } + } +} \ No newline at end of file diff --git a/srs-flowable/src/main/java/com/srs/flowable/mapper/OutsideAccommodationApplyMapper.java b/srs-flowable/src/main/java/com/srs/flowable/mapper/OutsideAccommodationApplyMapper.java new file mode 100644 index 0000000..b34697e --- /dev/null +++ b/srs-flowable/src/main/java/com/srs/flowable/mapper/OutsideAccommodationApplyMapper.java @@ -0,0 +1,85 @@ +package com.srs.flowable.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.srs.common.doman.vo.TeacherVo; +import com.srs.flowable.domain.OutsideAccommodationApply; +import org.apache.ibatis.annotations.Options; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 外宿申请Mapper接口 + * + * @author srs + * @date 2025-12-05 + */ +public interface OutsideAccommodationApplyMapper extends BaseMapper { + /** + * 查询外宿申请 + * + * @param id 外宿申请主键 + * @return 外宿申请 + */ + public OutsideAccommodationApply selectDmsOutsideAccommodationApplyById(Long id); + + /** + * 查询外宿申请列表 + * + * @param outsideAccommodationApply 外宿申请 + * @return 外宿申请集合 + */ + List selectDmsOutsideAccommodationApplyList(OutsideAccommodationApply outsideAccommodationApply); + + // + public TeacherVo getCounselorInfo(String stuNo); + + /** + * 获取审批用户信息 + * @param roleName + * @return + * 邵政文 + */ + List getShenDataInfo(String roleName); + + /** + * 查询外宿申请 + * + * @param studentName 学生姓名 + * @return 应征入伍保留学籍申请 + */ + public OutsideAccommodationApply getAccommodationByStuNameAndStuNo(@Param("studentName") String studentName, @Param("studentNo") String studentNo); + + /** + * 新增外宿申请 + * + * @param outsideAccommodationApply 外宿申请 + * @return 结果 + */ + @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") + int insertDmsOutsideAccommodationApply(OutsideAccommodationApply outsideAccommodationApply); + + /** + * 修改外宿申请 + * + * @param dmsOutsideAccommodationApply 外宿申请 + * @return 结果 + */ + int updateDmsOutsideAccommodationApply(OutsideAccommodationApply outsideAccommodationApply); + + /** + * 删除外宿申请 + * + * @param id 外宿申请主键 + * @return 结果 + */ + int deleteDmsOutsideAccommodationApplyById(Long id); + + /** + * 批量删除外宿申请 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteDmsOutsideAccommodationApplyByIds(Long[] ids); +} diff --git a/srs-flowable/src/main/java/com/srs/flowable/mapper/OutsideAccommodationApprovalMapper.java b/srs-flowable/src/main/java/com/srs/flowable/mapper/OutsideAccommodationApprovalMapper.java new file mode 100644 index 0000000..8ca8428 --- /dev/null +++ b/srs-flowable/src/main/java/com/srs/flowable/mapper/OutsideAccommodationApprovalMapper.java @@ -0,0 +1,71 @@ +package com.srs.flowable.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.srs.flowable.domain.OutsideAccommodationApproval; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 外宿申请审批记录Mapper接口 + * + * @author srs + * @date 2025-12-05 + */ +public interface OutsideAccommodationApprovalMapper extends BaseMapper { + /** + * 查询外宿申请审批记录 + * + * @param id 外宿申请审批记录主键 + * @return 外宿申请审批记录 + */ + public OutsideAccommodationApproval selectDmsOutsideAccommodationApprovalById(Long id); + + /** + * 根据学生姓名学号和审批人id查询保留学籍审批记录 + * + * @param + * @return 结果 + */ + OutsideAccommodationApproval selectOutsideAccommodationApprovalByStuName(@Param("studentName") String studentName, @Param("studentNo") String studentNo, @Param("approverId") Long approverId); + + /** + * 查询外宿申请审批记录列表 + * + * @param dmsOutsideAccommodationApproval 外宿申请审批记录 + * @return 外宿申请审批记录集合 + */ + List selectDmsOutsideAccommodationApprovalList(OutsideAccommodationApproval dmsOutsideAccommodationApproval); + + /** + * 新增外宿申请审批记录 + * + * @param dmsOutsideAccommodationApproval 外宿申请审批记录 + * @return 结果 + */ + int insertDmsOutsideAccommodationApproval(OutsideAccommodationApproval dmsOutsideAccommodationApproval); + + /** + * 修改外宿申请审批记录 + * + * @param dmsOutsideAccommodationApproval 外宿申请审批记录 + * @return 结果 + */ + int updateDmsOutsideAccommodationApproval(OutsideAccommodationApproval dmsOutsideAccommodationApproval); + + /** + * 删除外宿申请审批记录 + * + * @param id 外宿申请审批记录主键 + * @return 结果 + */ + int deleteDmsOutsideAccommodationApprovalById(Long id); + + /** + * 批量删除外宿申请审批记录 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + int deleteDmsOutsideAccommodationApprovalByIds(Long[] ids); +} diff --git a/srs-flowable/src/main/resources/mapper/OutsideAccommodationApplyMapper.xml b/srs-flowable/src/main/resources/mapper/OutsideAccommodationApplyMapper.xml new file mode 100644 index 0000000..0bac24a --- /dev/null +++ b/srs-flowable/src/main/resources/mapper/OutsideAccommodationApplyMapper.xml @@ -0,0 +1,374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, + apply_no, + student_id, + student_no, + student_name, + gender, + birth_date, + dept_id, + dept_name, + major_id, + major_name, + class_id, + class_name, + original_dormitory, + accommodation_fee, + accommodation_fee_status, + apply_reason, + outside_address, + address, + emergency_phone, + emergency_contact, + parent_opinion, + parent_sign_attachment, + parent_phone, + parent_address, + parent_detail_address, + student_promise_sign, + promise_date, + start_date, + end_date, + status, + reject_reason, + create_time, + create_by, + update_time, + update_by, + is_valid, + teacher_name, + affix_id, + deploy_id, + process_instance_id, + idCard, + studentPhone, + student_signature + from dms_outside_accommodation_apply + + + + + + + + + + + + + + + + + + + insert into dms_outside_accommodation_apply + + apply_no, + student_id, + student_no, + student_name, + gender, + birth_date, + dept_id, + dept_name, + major_id, + major_name, + class_id, + class_name, + original_dormitory, + accommodation_fee, + accommodation_fee_status, + apply_reason, + outside_address, + address, + emergency_phone, + emergency_contact, + parent_opinion, + parent_sign_attachment, + parent_phone, + parent_address, + parent_detail_address, + student_promise_sign, + promise_date, + start_date, + end_date, + status, + reject_reason, + create_time, + create_by, + update_time, + update_by, + is_valid, + teacher_name, + affix_id, + deploy_id, + process_instance_id, + idCard, + studentPhone, + student_signature, + + + #{applyNo}, + #{studentId}, + #{studentNo}, + #{studentName}, + #{gender}, + #{birthDate}, + #{deptId}, + #{deptName}, + #{majorId}, + #{majorName}, + #{classId}, + #{className}, + #{originalDormitory}, + #{accommodationFee}, + #{accommodationFeeStatus}, + #{applyReason}, + #{outsideAddress}, + #{address}, + #{emergencyPhone}, + #{emergencyContact}, + #{parentOpinion}, + #{parentSignAttachment}, + #{parentPhone}, + #{parentAddress}, + #{parentDetailAddress}, + #{studentPromiseSign}, + #{promiseDate}, + #{startDate}, + #{endDate}, + #{status}, + #{rejectReason}, + #{createTime}, + #{createBy}, + #{updateTime}, + #{updateBy}, + #{isValid}, + #{teacherName}, + #{affixId}, + #{deployId}, + #{processInstanceId}, + #{idCard}, + #{studentPhone}, + #{studentSignature}, + + + + + update dms_outside_accommodation_apply + + apply_no = #{applyNo}, + student_id = #{studentId}, + student_no = #{studentNo}, + student_name = #{studentName}, + gender = #{gender}, + birth_date = #{birthDate}, + dept_id = #{deptId}, + dept_name = #{deptName}, + major_id = #{majorId}, + major_name = #{majorName}, + class_id = #{classId}, + class_name = #{className}, + original_dormitory = + #{originalDormitory}, + + accommodation_fee = #{accommodationFee}, + accommodation_fee_status = #{accommodationFeeStatus}, + apply_reason = #{applyReason}, + outside_address = #{outsideAddress}, + address = #{address}, + emergency_phone = #{emergencyPhone}, + emergency_contact = #{emergencyContact}, + parent_opinion = #{parentOpinion}, + parent_sign_attachment = + #{parentSignAttachment}, + + parent_phone = #{parentPhone}, + parent_address = #{parentAddress}, + parent_detail_address = + #{parentDetailAddress}, + + student_promise_sign = + #{studentPromiseSign}, + + promise_date = #{promiseDate}, + start_date = #{startDate}, + end_date = #{endDate}, + status = #{status}, + reject_reason = #{rejectReason}, + create_time = #{createTime}, + create_by = #{createBy}, + update_time = #{updateTime}, + update_by = #{updateBy}, + is_valid = #{isValid}, + teacher_name = #{teacherName}, + affix_id = #{affixId}, + deploy_id = #{deployId}, + process_instance_id = #{processInstanceId}, + idCard = #{idCard}, + studentPhone = #{studentPhone}, + student_signature = #{studentSignature}, + + where id = #{id} + + + + delete + from dms_outside_accommodation_apply + where id = #{id} + + + + delete from dms_outside_accommodation_apply where id in + + #{id} + + + \ No newline at end of file diff --git a/srs-flowable/src/main/resources/mapper/OutsideAccommodationApprovalMapper.xml b/srs-flowable/src/main/resources/mapper/OutsideAccommodationApprovalMapper.xml new file mode 100644 index 0000000..cc4d0d9 --- /dev/null +++ b/srs-flowable/src/main/resources/mapper/OutsideAccommodationApprovalMapper.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + select id, apply_id, apply_no, approval_node, approver_id, approver_name, approver_role, approval_opinion, approval_result, approval_time, process_instance_id, student_name, student_no from dms_outside_accommodation_approval + + + + + + + + + + insert into dms_outside_accommodation_approval + + apply_id, + apply_no, + approval_node, + approver_id, + approver_name, + approver_role, + approval_opinion, + approval_result, + approval_time, + process_instance_id, + student_name, + student_no, + + + #{applyId}, + #{applyNo}, + #{approvalNode}, + #{approverId}, + #{approverName}, + #{approverRole}, + #{approvalOpinion}, + #{approvalResult}, + #{approvalTime}, + #{processInstanceId}, + #{studentName}, + #{studentNo}, + + + + + update dms_outside_accommodation_approval + + apply_id = #{applyId}, + apply_no = #{applyNo}, + approval_node = #{approvalNode}, + approver_id = #{approverId}, + approver_name = #{approverName}, + approver_role = #{approverRole}, + approval_opinion = #{approvalOpinion}, + approval_result = #{approvalResult}, + approval_time = #{approvalTime}, + process_instance_id = #{processInstanceId}, + student_name = #{studentName}, + student_no = #{studentNo}, + + where id = #{id} + + + + delete from dms_outside_accommodation_approval where id = #{id} + + + + delete from dms_outside_accommodation_approval where id in + + #{id} + + + \ No newline at end of file diff --git a/srs-routine/src/main/java/com/srs/routine/service/IRtEnlistmentReserveService.java b/srs-routine/src/main/java/com/srs/routine/service/IRtEnlistmentReserveService.java index 24f4908..2424e9f 100644 --- a/srs-routine/src/main/java/com/srs/routine/service/IRtEnlistmentReserveService.java +++ b/srs-routine/src/main/java/com/srs/routine/service/IRtEnlistmentReserveService.java @@ -3,6 +3,7 @@ package com.srs.routine.service; import java.util.List; import com.baomidou.mybatisplus.extension.service.IService; +import com.srs.dormitory.domain.DmsOutsideAccommodationApply; import com.srs.routine.domain.RtEnlistmentReserve; /** @@ -67,4 +68,21 @@ public interface IRtEnlistmentReserveService extends IService studentTaskList = taskService.createTaskQuery() + .processInstanceId(processInstanceId) + .taskAssignee(studentUserId) // 学生作为任务负责人 + .active() // 仅查询活跃任务 + .taskName("学生申请") + .list(); + + if (!studentTaskList.isEmpty()) { + for (Task studentTask : studentTaskList) { + // 补充完成任务的流程变量(如审批意见、结果,根据你的流程需求设置) + Map completeVariables = new HashMap<>(); + completeVariables.put("approvalResult", "AGREE"); // 学生提交(默认同意) + completeVariables.put("approvalOpinion", "学生自动提交申请,等待辅导员审批"); + completeVariables.put("operator", "student"); // 操作人类型 + // 添加任务分配的备注(便于流程追溯) + taskService.addComment( + studentTask.getId(), + processInstanceId, + "自动分配负责人", + "学生已经重新修改提交申请" + ); + // 2. 学生自动完成待办任务 + taskService.complete(studentTask.getId(), completeVariables); + System.out.println("学生[" + studentUserId + "]已自动完成待办任务,任务ID:" + studentTask.getId()); + } + + // 3. 分配下一节点(辅导员)的待办任务负责人【不再复用监听器,独立实现】 + assignCounselorTask(processInstanceId, existing.getId(), existing.getStudentNo()); + } else { + System.out.println("流程实例[" + processInstanceId + "]中未查询到学生[" + studentUserId + "]的待办任务,无需自动完成"); + } + + // 同步更新流程变量(将业务表状态同步到流程中) + runtimeService.setVariable(processInstanceId, "applyStatus", dmsOutsideAccommodationApply.getStatus()); + // 注意:若需更新流程相关变量,需调用 Flowable 的 runtimeService.setVariables(),此处仅更新业务表 + return dmsOutsideAccommodationApplyMapper.updateDmsOutsideAccommodationApply(dmsOutsideAccommodationApply); + } else { + // 流程未启动:仅当 applyStatus=1 时启动流程,否则仅更新数据 + Long applyStatus = dmsOutsideAccommodationApply.getStatus(); + if (1L == applyStatus) { + // 绑定当前学生ID,启动流程 + dmsOutsideAccommodationApply.setStudentId(SecurityUtils.getUserId()); + ProcessResultDto processResultDto = startOutsideAccommodationProcess(dmsOutsideAccommodationApply); + if (processResultDto == null || StringUtils.isBlank(processResultDto.getProcessInstanceId())) { + throw new ServiceException("流程启动失败,请重试", 500); + } + + // 关联流程实例ID,更新为“审批中”状态 + dmsOutsideAccommodationApply.setProcessInstanceId(processResultDto.getProcessInstanceId()); + dmsOutsideAccommodationApply.setDeployId(processResultDto.getDeploymentId()); + dmsOutsideAccommodationApply.setStatus(1L); // 审批中 + System.out.println("申请表[" + dmsOutsideAccommodationApply.getId() + "]启动流程成功,实例ID:" + processResultDto.getProcessInstanceId()); + } else { + // 非提交状态:仅更新基础数据(如草稿修改) + String statusDesc = applyStatus == null ? "未指定状态" : (applyStatus == 0 ? "草稿" : "其他状态"); + System.out.println("申请表[" + dmsOutsideAccommodationApply.getId() + "]状态为" + statusDesc + ",流程未启动,仅更新数据"); + } + + // 执行数据库更新(含流程实例ID绑定或基础数据更新) + return dmsOutsideAccommodationApplyMapper.updateDmsOutsideAccommodationApply(dmsOutsideAccommodationApply); + } + + } + + + /** + * 开启外宿申请工作流 + * + * @param dmsOutsideAccommodationApply + */ + private ProcessResultDto startOutsideAccommodationProcess(DmsOutsideAccommodationApply + dmsOutsideAccommodationApply) { + Map variables = new HashMap<>(); + // 1. 传递关键变量(申请编号+主键ID,用于任务匹配) + String applyNo = dmsOutsideAccommodationApply.getApplyNo(); // 申请编号(如RY2024001) + Long enlistmentId = dmsOutsideAccommodationApply.getId(); // 申请表主键ID + variables.put("applyNo", applyNo); + variables.put("accommodationId", enlistmentId); // 新增:用于任务匹配的主键变量 + variables.put("stuId", dmsOutsideAccommodationApply.getStudentId()); + + // 2. 查询辅导员信息 + TeacherVo counselorInfo = dmsOutsideAccommodationApplyMapper.getCounselorInfo(dmsOutsideAccommodationApply.getStudentNo()); + if (counselorInfo == null) { + throw new ServiceException("该学生暂无辅导员", 500); + } + variables.put("approval", counselorInfo.getUserId()); // 下一节点:辅导员 + variables.put("deptId", counselorInfo.getDeptId()); + + // 3. 启动流程 + AjaxResult ajaxResult = flowDefinitionService.startProcessInstanceById("flow_dre1txpk:11:1375008", variables); + String code = ajaxResult.get("code").toString(); + 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 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(), "accommodationId"); + 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; + } }