LiteFlow 是一个轻量级的规则引擎,专注于解决复杂的业务流程编排问题。它允许开发者通过配置文件或注解来定义组件和规则链,从而实现高度灵活的业务逻辑处理。相比于传统的状态机或其他复杂的工作流引擎,LiteFlow 提供了更加简洁、易于维护的解决方案。
liteflow-leave-system/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/demo/
│ │ │ ├── DemoApplication.java
│ │ │ ├── controller/
│ │ │ │ └── LeaveController.java
│ │ │ ├── service/
│ │ │ │ └── LeaveService.java
│ │ │ ├── component/
│ │ │ │ ├── EmployeeSubmitComponent.java
│ │ │ │ ├── ManagerApprovalComponent.java
│ │ │ │ ├── SupervisorApprovalComponent.java
│ │ │ │ ├── HrArchivingComponent.java
│ │ │ │ └── RejectNoticeComponent.java
│ │ │ ├── repository/
│ │ │ │ └── LeaveRequestRepository.java
│ │ │ ├── entity/
│ │ │ │ └── LeaveRequest.java
│ │ │ └── context/
│ │ │ └── LeaveRequestContext.java
│ │ └── resources/
│ │ ├── application.yml
│ │ └── flow.el.xml
│ └── test/
└── pom.xml
pom.xml
)<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>liteflow-leave-system</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>17</java.version>
<spring.boot.version>3.2.5</spring.boot.version>
<liteflow.version>2.11.3</liteflow.version>
<mysql.connector.version>8.0.33</mysql.connector.version>
<spring.data.jpa.version>3.1.5</spring.data.jpa.version>
</properties>
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- LiteFlow Core -->
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>liteflow-core</artifactId>
<version>${liteflow.version}</version>
</dependency>
<!-- LiteFlow Spring Boot Starter -->
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>liteflow-spring-boot-starter</artifactId>
<version>${liteflow.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
entity/LeaveRequest.java
)package com.example.demo.entity;
import jakarta.persistence.*;
@Entity
public class LeaveRequest {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private int days;
private String status; // pending, manager_approved, supervisor_approved, rejected
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getDays() {
return days;
}
public void setDays(int days) {
this.days = days;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
repository/LeaveRequestRepository.java
)package com.example.demo.repository;
import com.example.demo.entity.LeaveRequest;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface LeaveRequestRepository extends JpaRepository<LeaveRequest, Long> {
}
context/LeaveRequestContext.java
)package com.example.demo.context;
import com.yomahub.liteflow.slot.DefaultContext;
public class LeaveRequestContext extends DefaultContext {
private int days;
private boolean rejectByManager;
private boolean rejectBySupervisor;
private boolean isRejected = false;
public int getDays() {
return days;
}
public void setDays(int days) {
this.days = days;
}
public boolean isRejectByManager() {
return rejectByManager;
}
public void setRejectByManager(boolean rejectByManager) {
this.rejectByManager = rejectByManager;
}
public boolean isRejectBySupervisor() {
return rejectBySupervisor;
}
public void setRejectBySupervisor(boolean rejectBySupervisor) {
this.rejectBySupervisor = rejectBySupervisor;
}
public boolean isRejected() {
return isRejected;
}
public void setRejected(boolean rejected) {
isRejected = rejected;
}
}
service/LeaveService.java
)package com.example.demo.service;
import com.example.demo.context.LeaveRequestContext;
import com.example.demo.entity.LeaveRequest;
import com.example.demo.repository.LeaveRequestRepository;
import com.yomahub.liteflow.core.FlowExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class LeaveService {
@Autowired
private FlowExecutor flowExecutor;
@Autowired
private LeaveRequestRepository leaveRequestRepository;
public LeaveRequest submitLeave(int days) {
LeaveRequest request = new LeaveRequest();
request.setDays(days);
request.setStatus("pending");
leaveRequestRepository.save(request);
LeaveRequestContext context = new LeaveRequestContext();
context.setDays(days);
try {
flowExecutor.execute2Void("leaveRequestChain", context, request.getId());
} catch (Exception e) {
request.setStatus("error");
leaveRequestRepository.save(request);
}
return request;
}
public void approveByManager(Long requestId, boolean isReject) {
LeaveRequest request = leaveRequestRepository.findById(requestId).orElseThrow(() -> new RuntimeException("Leave request not found"));
LeaveRequestContext context = new LeaveRequestContext();
context.setDays(request.getDays());
context.setRejectByManager(isReject);
if (isReject) {
request.setStatus("rejected");
} else {
request.setStatus("manager_approved");
}
leaveRequestRepository.save(request);
try {
flowExecutor.execute2Void("leaveRequestChain", context, requestId);
} catch (Exception e) {
request.setStatus("error");
leaveRequestRepository.save(request);
}
}
public void approveBySupervisor(Long requestId, boolean isReject) {
LeaveRequest request = leaveRequestRepository.findById(requestId).orElseThrow(() -> new RuntimeException("Leave request not found"));
LeaveRequestContext context = new LeaveRequestContext();
context.setDays(request.getDays());
context.setRejectBySupervisor(isReject);
if (isReject) {
request.setStatus("rejected");
} else {
request.setStatus("supervisor_approved");
}
leaveRequestRepository.save(request);
try {
flowExecutor.execute2Void("leaveRequestChain", context, requestId);
} catch (Exception e) {
request.setStatus("error");
leaveRequestRepository.save(request);
}
}
}
component/*.java
)EmployeeSubmitComponent.java
package com.example.demo.component;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("employeeSubmit")
public class EmployeeSubmitComponent extends NodeComponent {
@Override
public void process() throws Exception {
System.out.println("员工提交了请假申请");
}
}
ManagerApprovalComponent.java
package com.example.demo.component;
import com.example.demo.context.LeaveRequestContext;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("managerApproval")
public class ManagerApprovalComponent extends NodeComponent {
@Override
public void process() throws Exception {
LeaveRequestContext context = this.getContextBean(LeaveRequestContext.class);
if (context.isRejectByManager()) {
System.out.println("经理拒绝了请假申请");
context.setRejected(true);
return;
}
System.out.println("经理正在审批...");
}
}
SupervisorApprovalComponent.java
package com.example.demo.component;
import com.example.demo.context.LeaveRequestContext;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("supervisorApproval")
public class SupervisorApprovalComponent extends NodeComponent {
@Override
public void process() throws Exception {
LeaveRequestContext context = this.getContextBean(LeaveRequestContext.class);
if (context.isRejectBySupervisor()) {
System.out.println("主管拒绝了请假申请");
context.setRejected(true);
return;
}
System.out.println("主管正在审批...");
}
}
HrArchivingComponent.java
package com.example.demo.component;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("hrArchiving")
public class HrArchivingComponent extends NodeComponent {
@Override
public void process() throws Exception {
System.out.println("HR正在进行归档...");
}
}
RejectNoticeComponent.java
package com.example.demo.component;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("rejectNotice")
public class RejectNoticeComponent extends NodeComponent {
@Override
public void process() throws Exception {
System.out.println("已发送拒绝通知给员工");
}
}
controller/LeaveController.java
)package com.example.demo.controller;
import com.example.demo.entity.LeaveRequest;
import com.example.demo.service.LeaveService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/leave")
public class LeaveController {
@Autowired
private LeaveService leaveService;
@PostMapping("/apply")
public LeaveRequest apply(@RequestParam int days) {
return leaveService.submitLeave(days);
}
@PostMapping("/approval/manager")
public void approveByManager(@RequestParam Long id, @RequestParam boolean reject) {
leaveService.approveByManager(id, reject);
}
@PostMapping("/approval/supervisor")
public void approveBySupervisor(@RequestParam Long id, @RequestParam boolean reject) {
leaveService.approveBySupervisor(id, reject);
}
@GetMapping("/status/{id}")
public LeaveRequest getStatus(@PathVariable Long id) {
return leaveService.leaveRequestRepository.findById(id).orElseThrow(() -> new RuntimeException("Leave request not found"));
}
}
application.yml
)server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/leave_system?useSSL=false&serverTimezone=UTC
username: root
password: your_password
jpa:
hibernate:
ddl-auto: update
show-sql: true
liteflow:
config-location: classpath:flow.el.xml
enable-shutdown-hook: true
flow.el.xml
)<?xml version="1.0" encoding="UTF-8"?>
<flow>
<!-- 判断是否是长假 -->
<slot name="isLongLeave">
WHEN(request.getDays() > 3)
</slot>
<!-- 判断是否已被拒绝 -->
<slot name="isRejected">
WHEN(request.isRejected())
</slot>
<!-- 主流程链 -->
<chain name="leaveRequestChain">
THEN(
employeeSubmit,
IF(isLongLeave).THEN(managerApproval).ELSE(),
supervisorApproval,
IF(isRejected).THEN(rejectNotice).ELSE(hrArchiving)
);
</chain>
</flow>
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。