违纪处分申报工作流完全打通ㄟ( ▔, ▔ )ㄏ
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package com.srs.flowable.listener.disciplinary;
|
||||
|
||||
import com.srs.common.utils.WeChatUtil;
|
||||
import com.srs.common.utils.spring.SpringUtils;
|
||||
import com.srs.flowable.mapper.DisciplinaryMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.delegate.ExecutionListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 执行监听器:在“学生教育管理科审批归档”节点开始时, 知无涯
|
||||
* 向负责归档的角色发送企业微信通知。
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ArchivingNotifyListener implements ExecutionListener {
|
||||
|
||||
@Override
|
||||
public void notify(DelegateExecution delegateExecution) {
|
||||
log.info("流程实例 [{}]: 已进入学生教育管理科审批归档节点,准备发送通知。", delegateExecution.getProcessInstanceId());
|
||||
|
||||
try {
|
||||
DisciplinaryMapper disciplinaryMapper = SpringUtils.getBean(DisciplinaryMapper.class);
|
||||
|
||||
// 1. 【核心】定义负责归档的角色的 role_key。
|
||||
final String ARCHIVING_ROLE_KEY = "xsjyglkspgd";
|
||||
|
||||
// 2. 根据角色Key查询用户ID列表
|
||||
List<Long> userIdList = disciplinaryMapper.getApprovalByRoleKey(ARCHIVING_ROLE_KEY);
|
||||
|
||||
if (userIdList == null || userIdList.isEmpty()) {
|
||||
log.warn("根据角色Key '{}' 未找到任何归档人员,无法发送通知。", ARCHIVING_ROLE_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 批量查询 userName 并发送通知
|
||||
List<String> userNameList = disciplinaryMapper.getUserNamesByUserIdList(userIdList);
|
||||
if (!userNameList.isEmpty()) {
|
||||
String toUser = String.join("|", userNameList);
|
||||
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||
String content = "您有一条新的学生违纪归档任务待处理,<a href='http://zhxg.gxsdxy.cn/web/#/pages/Approval/index'>请点击前往处理</a>。";
|
||||
|
||||
weChatUtil.sendTextMessage(toUser, content);
|
||||
log.info("已成功向归档角色 ({}) 发送通知。接收人: {}", ARCHIVING_ROLE_KEY, toUser);
|
||||
} else {
|
||||
log.warn("角色 '{}' 中找到了 {} 个用户,但无人配置企业微信账号,未发送任何通知。", ARCHIVING_ROLE_KEY, userIdList.size());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("向归档角色发送企业微信通知时出现异常。流程将继续。错误详情: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -9,7 +9,7 @@ import org.flowable.engine.delegate.ExecutionListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 根据辅导员部门id获取二级学院书记
|
||||
* 根据辅导员部门id获取二级学院书记 知无涯
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
|
@@ -0,0 +1,61 @@
|
||||
package com.srs.flowable.listener.disciplinary;
|
||||
|
||||
import com.srs.common.utils.WeChatUtil;
|
||||
import com.srs.common.utils.spring.SpringUtils;
|
||||
import com.srs.flowable.mapper.DisciplinaryMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.delegate.ExecutionListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 执行监听器:在“申请人(辅导员)接收”节点开始时, 知无涯
|
||||
* 向流程发起人发送企业微信通知,告知其结果已出。
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class InitiatorResultListener implements ExecutionListener {
|
||||
|
||||
@Override
|
||||
public void notify(DelegateExecution delegateExecution) {
|
||||
log.info("流程实例 [{}]: 已进入辅导员接收结果节点,准备向发起人发送通知。", delegateExecution.getProcessInstanceId());
|
||||
|
||||
try {
|
||||
DisciplinaryMapper disciplinaryMapper = SpringUtils.getBean(DisciplinaryMapper.class);
|
||||
|
||||
// 1. 从流程变量中获取发起人的ID。Flowable会自动将发起人ID存入名为 "INITIATOR" 的变量中。
|
||||
// 这个变量通常是 String 类型。
|
||||
Object initiatorObj = delegateExecution.getVariable("INITIATOR");
|
||||
if (initiatorObj == null) {
|
||||
log.warn("在流程实例 [{}] 中未找到发起人(INITIATOR)变量,无法发送通知。", delegateExecution.getProcessInstanceId());
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 将发起人ID转换为 Long 类型,以便查询数据库
|
||||
Long initiatorUserId;
|
||||
try {
|
||||
initiatorUserId = Long.parseLong(initiatorObj.toString());
|
||||
} catch (NumberFormatException e) {
|
||||
log.error("发起人(INITIATOR)变量 '{}' 无法转换为Long类型,无法发送通知。", initiatorObj);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 使用 initiatorUserId 查询对应的企业微信 userName
|
||||
String initiatorUserName = disciplinaryMapper.getUserNameByUserId(initiatorUserId);
|
||||
|
||||
if (initiatorUserName != null && !initiatorUserName.isEmpty()) {
|
||||
// 4. 发送通知
|
||||
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||
String content = "您提交的学生违纪处分申请已有最终处理结果,<a href='http://zhxg.gxsdxy.cn/web/#/pages/Approval/index'>请点击前往处理</a>。\"";
|
||||
|
||||
weChatUtil.sendTextMessage(initiatorUserName, content);
|
||||
log.info("已成功向流程发起人 ({}) 发送结果通知。", initiatorUserName);
|
||||
} else {
|
||||
log.warn("找到了发起人(userId:{}),但其对应的企业微信账号(userName)为空,未发送通知。", initiatorUserId);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("向流程发起人发送结果通知时出现异常。流程将继续。错误详情: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
package com.srs.flowable.listener.disciplinary;
|
||||
|
||||
import com.srs.common.utils.WeChatUtil;
|
||||
import com.srs.common.utils.spring.SpringUtils;
|
||||
import com.srs.flowable.mapper.DisciplinaryMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.delegate.ExecutionListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 执行监听器:在“校领导审批”节点开始时,向校领导发送企业微信通知。 知无涯
|
||||
* (简化版:因为流程能到达此节点,即表示前序节点已全票通过)
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SchoolLeaderApprovalListener implements ExecutionListener {
|
||||
|
||||
@Override
|
||||
public void notify(DelegateExecution delegateExecution) {
|
||||
log.info("流程实例 [{}]: 已进入校领导审批节点,准备发送通知。", delegateExecution.getProcessInstanceId());
|
||||
|
||||
try {
|
||||
DisciplinaryMapper disciplinaryMapper = SpringUtils.getBean(DisciplinaryMapper.class);
|
||||
|
||||
// 1. 【核心】定义“校领导”这个角色的 role_key
|
||||
final String LEADER_ROLE_KEY = "xldsp";
|
||||
|
||||
// 2. 根据角色Key查询用户ID列表
|
||||
List<Long> userIdList = disciplinaryMapper.getApprovalByRoleKey(LEADER_ROLE_KEY);
|
||||
|
||||
if (userIdList == null || userIdList.isEmpty()) {
|
||||
log.warn("根据角色Key '{}' 未找到任何校领导用户,无法发送通知。", LEADER_ROLE_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 批量查询 userName 并发送通知
|
||||
List<String> userNameList = disciplinaryMapper.getUserNamesByUserIdList(userIdList);
|
||||
if (!userNameList.isEmpty()) {
|
||||
String toUser = String.join("|", userNameList);
|
||||
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||
String content = "校领导您有一条新的学生违纪审批任务待处理,<a href='http://zhxg.gxsdxy.cn/web/#/pages/Approval/index'>请点击前往处理</a>。";
|
||||
|
||||
weChatUtil.sendTextMessage(toUser, content);
|
||||
log.info("已成功向校领导 (角色: {}) 发送通知。接收人: {}", LEADER_ROLE_KEY, toUser);
|
||||
} else {
|
||||
log.warn("角色 '{}' 中找到了 {} 个用户,但无人配置企业微信账号,未发送任何通知。", LEADER_ROLE_KEY, userIdList.size());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("向校领导发送企业微信通知时出现异常。流程将继续。错误详情: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,12 +1,17 @@
|
||||
package com.srs.flowable.listener.disciplinary;
|
||||
|
||||
import com.srs.common.utils.WeChatUtil;
|
||||
import com.srs.common.utils.spring.SpringUtils;
|
||||
import com.srs.flowable.mapper.DisciplinaryMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.delegate.ExecutionListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* 设置处分学生审批参数
|
||||
* 流程结束监听器。
|
||||
* 在流程的最终节点,向当事学生发送处理结果的通知。 知无涯
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -14,10 +19,41 @@ public class StuInfoListener implements ExecutionListener {
|
||||
|
||||
@Override
|
||||
public void notify(DelegateExecution delegateExecution) {
|
||||
Long stuId = (Long)delegateExecution.getVariable("stuId");
|
||||
// 1. 从流程变量中获取学生ID
|
||||
Object stuIdObj = delegateExecution.getVariable("stuId");
|
||||
|
||||
log.info("学生信息:{}",stuId);
|
||||
delegateExecution.setVariable("approval",stuId);
|
||||
// todo 企业微信推送消息
|
||||
// 安全检查:确保stuId存在且类型正确
|
||||
if (!(stuIdObj instanceof Long)) {
|
||||
log.error("流程实例 [{}] 在结束时未能获取到有效的 'stuId' 变量,无法发送最终通知。", delegateExecution.getProcessInstanceId());
|
||||
return;
|
||||
}
|
||||
Long stuId = (Long) stuIdObj;
|
||||
log.info("流程实例 [{}] 即将结束,准备向学生ID: {} 发送最终通知。", delegateExecution.getProcessInstanceId(), stuId);
|
||||
|
||||
// 2. 向该学生发送企业微信通知
|
||||
try {
|
||||
DisciplinaryMapper disciplinaryMapper = SpringUtils.getBean(DisciplinaryMapper.class);
|
||||
|
||||
// 根据学生ID查询其对应的企业微信账号(userName)
|
||||
String userName = disciplinaryMapper.getUserNameByUserId(stuId);
|
||||
|
||||
// 检查是否找到了对应的企业微信账号
|
||||
if (!StringUtils.hasText(userName)) {
|
||||
log.warn("流程实例 [{}]: 根据学生ID '{}' 未找到对应的企业微信账号,无法发送最终通知。", delegateExecution.getProcessInstanceId(), stuId);
|
||||
return; // 中止发送逻辑
|
||||
}
|
||||
|
||||
// 3. 构建并发送通知内容
|
||||
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||
String content = "您好,关于您的违纪处理流程已办结,最终结果已生成。<a href='http://zhxg.gxsdxy.cn/web/#/pages/Disciplinary/MyDisciplinary'>请点击登录系统查看详情</a>。";
|
||||
|
||||
weChatUtil.sendTextMessage(userName, content);
|
||||
log.info("流程实例 [{}]: 已成功向学生ID '{}' (企业微信账号: {}) 发送了流程办结通知。", delegateExecution.getProcessInstanceId(), stuId, userName);
|
||||
|
||||
} catch (Exception e) {
|
||||
// 即使通知失败,也不应影响流程的正常结束
|
||||
log.error("流程实例 [{}]: 在向学生ID '{}' 发送最终通知时出现异常。错误详情: {}",
|
||||
delegateExecution.getProcessInstanceId(), stuId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -10,7 +10,7 @@ import org.springframework.stereotype.Component;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 学生教育管理科审核节点的执行监听器。
|
||||
* 学生教育管理科审核节点的执行监听器。 知无涯
|
||||
* 向“学生教育管理科”角色发送企业微信通知。
|
||||
*/
|
||||
@Component
|
||||
|
@@ -15,7 +15,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
/**
|
||||
* 根据辅导员的部门id,查询该部门的学无干事人员
|
||||
* 根据辅导员的部门id,查询该部门的学无干事人员 知无涯
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
|
@@ -1,55 +1,72 @@
|
||||
package com.srs.flowable.listener.disciplinary;
|
||||
|
||||
import com.srs.common.utils.WeChatUtil;
|
||||
import com.srs.common.utils.spring.SpringUtils;
|
||||
import com.srs.flowable.mapper.DisciplinaryMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 学院违纪处理委员会审批
|
||||
* 【线上监听器】为“学院违纪处理委员会”多实例任务准备数据并发送通知 知无涯
|
||||
*/
|
||||
@Component
|
||||
@Component("xywjclwyhListener")
|
||||
@Slf4j
|
||||
public class XYWJCLWYHListener implements ExecutionListener {
|
||||
|
||||
// 推荐:使用依赖注入,而不是SpringUtils
|
||||
@Autowired
|
||||
private DisciplinaryMapper disciplinaryMapper;
|
||||
|
||||
@Autowired
|
||||
private WeChatUtil weChatUtil;
|
||||
|
||||
@Override
|
||||
public void notify(DelegateExecution delegateExecution) {
|
||||
DisciplinaryMapper disciplinaryMapper = SpringUtils.getBean("disciplinaryMapper");
|
||||
// 步骤 1: 根据角色Key获取审批人ID列表 (第1次DB查询)
|
||||
public void notify(DelegateExecution execution) {
|
||||
log.info("流程实例 [{}]: 在进入'学院违纪处理委员会'节点前,开始准备审批数据...", execution.getProcessInstanceId());
|
||||
|
||||
// 步骤 1: 单一数据库查询,获取所有需要的审批人信息 (ID和企微账号)
|
||||
// List<DisciplinaryMapper.UserInfo> userInfos = disciplinaryMapper.getUserInfoByRoleKey("xywjclwyh");
|
||||
// 注意:如果您不方便修改Mapper,这里可以保持原来的两次查询,逻辑依然正确。
|
||||
// 我们先用原始的两次查询来演示,更具普适性。
|
||||
|
||||
List<Long> userIdList = disciplinaryMapper.getApprovalByRoleKey("xywjclwyh");
|
||||
if (userIdList == null || userIdList.isEmpty()){
|
||||
log.error("未找到角色相关信息");
|
||||
|
||||
if (userIdList == null || userIdList.isEmpty()) {
|
||||
log.error("角色 'xywjclwyh' 未配置或未找到任何有效用户,流程无法继续。");
|
||||
throw new RuntimeException("学院违纪处理委员会审批人员未设置");
|
||||
}else{
|
||||
delegateExecution.setVariable("userList",userIdList);
|
||||
// todo 企业微信推送消息
|
||||
// --- 企业微信推送消息模块 ---
|
||||
try {
|
||||
// 步骤 2: 一次性批量查询所有有效的userName (第2次DB查询,性能最优)
|
||||
List<String> userNameList = disciplinaryMapper.getUserNamesByUserIdList(userIdList);
|
||||
|
||||
if (!userNameList.isEmpty()) {
|
||||
// 步骤 3: 将 userName 列表用 "|" 连接成一个字符串
|
||||
String toUser = String.join("|", userNameList);
|
||||
|
||||
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||
String content = "您有一条新的学生违纪审批任务待处理,<a href='http://zhxg.gxsdxy.cn/web/#/pages/Approval/index'>请点击前往处理</a>。";
|
||||
|
||||
weChatUtil.sendTextMessage(toUser, content);
|
||||
log.info("已成功向学院违纪处理委员会发送群组通知。接收人: {}", toUser);
|
||||
} else {
|
||||
log.warn("角色 'xywjclwyh' 存在审批人,但无人配置企业微信账号,未发送任何通知。");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 保证即使通知失败,流程也能继续
|
||||
log.error("向学院违纪处理委员会发送企业微信通知时出现异常。流程将继续。错误详情: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// 步骤 2: 设置多实例任务需要的流程变量 (这是“线上”为“节点”准备的核心数据)
|
||||
execution.setVariable("userList", userIdList);
|
||||
log.info("流程实例 [{}]: 已成功设置'userList'变量,包含 {} 个审批人。", execution.getProcessInstanceId(), userIdList.size());
|
||||
|
||||
// 步骤 3: 发送企业微信通知
|
||||
sendWeChatNotification(userIdList, execution.getProcessInstanceId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 封装并执行企业微信通知逻辑
|
||||
*/
|
||||
private void sendWeChatNotification(List<Long> userIdList, String processInstanceId) {
|
||||
try {
|
||||
List<String> userNameList = disciplinaryMapper.getUserNamesByUserIdList(userIdList);
|
||||
if (userNameList == null || userNameList.isEmpty()) {
|
||||
log.warn("流程实例 [{}]: 角色'xywjclwyh'存在审批人ID,但无人配置企微账号,未发送通知。", processInstanceId);
|
||||
return;
|
||||
}
|
||||
|
||||
String toUser = String.join("|", userNameList);
|
||||
String content = "您有一条新的学生违纪审批任务待处理,<a href='http://zhxg.gxsdxy.cn/web/#/pages/Approval/index'>请点击前往处理</a>。";
|
||||
|
||||
weChatUtil.sendTextMessage(toUser, content);
|
||||
log.info("流程实例 [{}]: 已成功向学院违纪处理委员会发送通知。接收人: {}", processInstanceId, toUser);
|
||||
} catch (Exception e) {
|
||||
log.error("流程实例 [{}]: 发送企微通知时出现异常,但不影响主流程。错误: {}", processInstanceId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -23,7 +23,7 @@ public interface DisciplinaryMapper {
|
||||
*/
|
||||
String getUserNameByUserId(@Param("userId") Long userId);
|
||||
/**
|
||||
* 知无涯新增:根据用户ID列表批量查询用户名列表
|
||||
* 知无涯 根据用户ID列表批量查询用户名列表
|
||||
* @param userIdList 用户ID列表
|
||||
* @return 用户的username列表
|
||||
*/
|
||||
|
@@ -265,7 +265,7 @@ public class RtStuDisciplinaryApplicationServiceImpl extends ServiceImpl<RtStuDi
|
||||
|
||||
// todo 企业微信推送消息
|
||||
|
||||
AjaxResult ajaxResult = flowDefinitionService.startProcessInstanceById("flow_n27gxm4k:8:610039", variables);
|
||||
AjaxResult ajaxResult = flowDefinitionService.startProcessInstanceById("flow_n27gxm4k:16:672598", variables);
|
||||
String code = ajaxResult.get("code").toString();
|
||||
if (code.equals("200")) {
|
||||
|
||||
|
Reference in New Issue
Block a user