审批流程抄送详解:提升工作效率的关键步骤
1042 字大约 3 分钟2024年12月2日
1. 设计抄送功能的数据结构
抄送配置表(CC_Config)
存储各流程或任务的抄送配置。
CREATE TABLE CC_Config (
CC_Config_ID INT PRIMARY KEY AUTO_INCREMENT,
Process_Definition_ID INT,
Task_ID INT,
CC_User VARCHAR(255),
Created_At TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (Process_Definition_ID) REFERENCES Process_Definitions(Process_Definition_ID),
FOREIGN KEY (Task_ID) REFERENCES Approval_Tasks(Task_ID)
);
抄送记录表(CC_Logs)
存储实际执行的抄送记录。
CREATE TABLE CC_Logs (
CC_Log_ID INT PRIMARY KEY AUTO_INCREMENT,
Process_Instance_ID INT,
Task_ID INT,
CC_User VARCHAR(255),
CC_Timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
Message TEXT,
FOREIGN KEY (Process_Instance_ID) REFERENCES Process_Instances(Process_Instance_ID),
FOREIGN KEY (Task_ID) REFERENCES Approval_Tasks(Task_ID)
);
2. 实现抄送功能
根据抄送配置,编写逻辑在流程执行时触发抄送操作。
触发点
- 流程启动时:在一个新的流程实例启动时,可以触发抄送通知,以便相关人员知道流程已经开始。
- 任务创建时:当一个新的审批任务创建时,可以触发抄送通知,通知相关人员该任务的存在。
- 任务完成时:当一个审批任务完成时,可以触发抄送通知,通知相关人员任务的结果。
- 流程结束时:当整个流程实例完成时,可以触发抄送通知,通知相关人员流程的最终结果。
以下是具体的实现步骤,以 Activiti 为例:
1. 创建事件监听器
首先,创建一个事件监听器,用于捕获流程中的各种事件:
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.impl.context.Context;
public class CcEventListener implements ActivitiEventListener {
@Override
public void onEvent(ActivitiEvent event) {
switch (event.getType()) {
case PROCESS_STARTED:
handleCc(event, "流程启动");
break;
case TASK_CREATED:
handleCc(event, "任务创建");
break;
case TASK_COMPLETED:
handleCc(event, "任务完成");
break;
case PROCESS_COMPLETED:
handleCc(event, "流程结束");
break;
default:
break;
}
}
private void handleCc(ActivitiEvent event, String message) {
// 获取相关信息
String processInstanceId = event.getProcessInstanceId();
String taskId = event.getExecutionId();
List<String> ccUsers = getCcUsers(taskId);
// 发送抄送通知
for (String ccUser : ccUsers) {
sendCcNotification(ccUser, message);
recordCcLog(processInstanceId, taskId, ccUser, message);
}
}
}
2. 注册事件监听器
在流程引擎启动时,将事件监听器注册到流程引擎:
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRuntimeService().addEventListener(new CcEventListener());
3. 获取抄送人员列表
实现获取抄送人员列表的逻辑,查询抄送配置表(CC_Config)获取抄送人员:
public List<String> getCcUsers(String taskId) {
// 查询抄送配置表,获取配置的抄送人员列表
String sql = "SELECT CC_User FROM CC_Config WHERE Task_ID = ?";
// 执行查询逻辑,返回抄送人员列表
List<String> ccUsers = new ArrayList<>();
// 假设通过JDBC查询
try (Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, taskId);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
ccUsers.add(rs.getString("CC_User"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return ccUsers;
}
4. 发送抄送通知和记录日志
实现发送抄送通知和记录抄送日志的逻辑:
public void sendCcNotification(String ccUser, String message) {
// 发送通知逻辑,例如通过邮件或消息系统
System.out.println("通知用户 " + ccUser + ": " + message);
}
public void recordCcLog(String processInstanceId, String taskId, String ccUser, String message) {
// 插入抄送记录表,记录抄送信息
String sql = "INSERT INTO CC_Logs (Process_Instance_ID, Task_ID, CC_User, Message) VALUES (?, ?, ?, ?)";
// 执行插入逻辑
try (Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, processInstanceId);
pstmt.setString(2, taskId);
pstmt.setString(3, ccUser);
pstmt.setString(4, message);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
3. 更新数据库表
在实际应用中,需要确保每次抄送操作都有新的记录,以便审计和追踪。以下是更新数据库表的 SQL 操作示例:
插入抄送配置
INSERT INTO CC_Config (Process_Definition_ID, Task_ID, CC_User)
VALUES (?, ?, ?);
插入抄送日志
INSERT INTO CC_Logs (Process_Instance_ID, Task_ID, CC_User, Message)
VALUES (?, ?, ?, ?);