Introduction: This technology point is mainly for the class approval business process modeling, there can be: task release (i.e., the beginning of the process) to a level of approval to the final end (i.e., the end of the process) a complete set of models
1、idea download activiti plugin
- Previous versions of ider downloaded actiBPM, but the new version of ider this plugin is obsolete and has been replaced by the following one
2. Start a separate activiti service.
3. Add the dependency in the activiti service:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.0.0.Beta2</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
4, Addition arrangement
I have a service structure here:
a. activiti.cfg.xml configuration (direct paste, need to modify to their own database):
<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:context=”http://www.springframework.org/schema/context”
xmlns:tx=”http://www.springframework.org/schema/tx”
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd”>
<!– default (setting)idThe corresponding value isprocessEngineConfiguration –>
<!– processEngine Activitiprocess engine–>
<bean id=”processEngineConfiguration”
class=”org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration”>
<property name=”jdbcDriver” value=”com.mysql.cj.jdbc.Driver”/>
<property name=”jdbcUrl” value=”jdbc:mysql://*****:3306/activiti”/>
<property name=”jdbcUsername” value=”root”/>
<property name=”jdbcPassword” value=”*****”/>
<!– activitiDatabase table handling strategy Create table if it doesn’t exist–>
<property name=”databaseSchemaUpdate” value=”true”/>
</bean>
</beans>
Configuration Explained:
b. Add log4j configuration (no need to modify, directly stick):
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x – %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\XX\activiti.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x – %m\n
- Create a flowchart file:
Right-click anywhere in the created file and select View BPMN Diagram to open the visualization interface (the interface for process definition).
Arbitrarily right-click and select Define Process:
Solve the problem of garbled pictures
1. Open the IDEA installation path and find the following installation directory
Additional one-article instruction: -Dfile.encoding=UTF-8
as shown below
This is the end of the activiti preparation, the next is the code part:
I. demo code example:
public class TestCreateTable {
/**
* generatingactivitidatabase tables
*/
@Test
public void testCreateDbTable() {
//utilizationclasspathloweractiviti.cfg.xmlThe configuration in theprocessEngine
//If you use the default, you need the aboveactiviti.cfg.xmldeployment
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
System.out.println(processEngine);
}
//deployments
@Test
public void test01() {
//1CreateProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2GetRepositoryServicean actual example
RepositoryService repositoryService = processEngine.getRepositoryService();
//3Use ofRepositoryServicedeploy
Deployment deploy = repositoryService.createDeployment().addClasspathResource(“bpmn/chuchai.bpmn20.xml”)
.addClasspathResource(“bpmn/diagram.png”)
.name(“Group Purchase Applicationv1.0″)
.deploy();
//4The output of the deployment information
System.out.println(“deploymentsid:“+deploy.getId());
System.out.println(“The name of the deployed task:“+deploy.getName());
}
//Startup process
@Test
public void testDeploy() {
//1.establishProcessEngineboyfriend
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//establishTaskService
TaskService taskService = processEngine.getTaskService();
Map<String, Object> variables = new HashMap<>();
//Zhang San is the one inbpmnIn theAssigneeConfigured parameters
variables.put(“John Doe“, “aaa”);
//3.Creating a Process Instance The process definition of thekeyneed to know holiday
ProcessInstance processInstance = ProcessEngines.getDefaultProcessEngine()
.getRuntimeService()
.startProcessInstanceByKey(“chuchai”, variables);
Task tmp = taskService.createTaskQuery()
.processInstanceId(processInstance.getProcessInstanceId()).singleResult();
tmp.setAssignee(“John Doe“);
//Complete this node. Approved by the next node. Completedact_ru_taskwill create a piece of data that will be approved by the next node
taskService.complete(tmp.getId(),variables);
//4.Information about the output example
System.out.println( “Process DeploymentID:” + processInstance.getDeploymentId() );
System.out.println( “Process DefinitionID:” + processInstance.getProcessDefinitionId());
System.out.println( “Process ExamplesID:” + processInstance.getId() );
System.out.println( “maneuverID:” + processInstance.getActivityId() );
}
@Test
//Query Tasks
public void test(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//establishTaskService
TaskService taskService = processEngine.getTaskService();
//Based on the processkey and mandate holders Querying of mandates
List<Task> list = taskService.createTaskQuery()
.processDefinitionKey(“chuchai”) //workflowsKey
.taskAssignee(“John Doe“)//Query only the tasks of this task manager
.list();
for (Task task : list) {
System.out.println(“Process Examplesid:” + task.getProcessInstanceId());
System.out.println(“mandatesid:” + task.getId());
System.out.println(“Mandate holders:” + task.getAssignee());
System.out.println(“Task Name:” + task.getName());
}
}
//Approval Process
@Test
public void test1(){
//1.establishProcessEngineboyfriend
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//establishTaskService
TaskService taskService = processEngine.getTaskService();
//Get your own to-do list based on role information
List<Task> T = taskService.createTaskQuery().taskAssignee(“zs”).list();
if(!ObjectUtils.isEmpty(T)) {
for (Task item : T) {
Map<String, Object> variables = new HashMap<>();
variables.put(“John Doe“, “zs”);
variables.put(“isSuccess”, true);
item.setAssignee(“the fourth child in the family“);
//Addition of Approval Remarks
taskService.addComment(item.getId(),item.getProcessInstanceId(),“Department Manager Agreed“);
//Complete this approval. Approval by the next node
taskService.complete(item.getId(), variables);
}
}
}
// Closing process
@Test
public void test02() {
//1.establishProcessEngineboyfriend
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// establishTaskService
TaskService taskService = processEngine.getTaskService();
//act_re_execution id
String taskId = “42503”;
// Mandate holders
String assingee = “the fourth child in the family“;
Task task = taskService.createTaskQuery()
.taskId(taskId)
.taskAssignee(assingee)
.singleResult();
if (task != null) {
HashMap<String, Object> map = new HashMap<>();
map.put(“agree”, 1);
taskService.complete(taskId, map);
System.out.println(“finalize one’s mission“);
}
}
}
Second, the project code example: controller layer code (here is applied to the project code)
@RestController
@RequestMapping(“/activiti”)
@Slf4j
public class ActivitiController {
@Autowired
private IActivitiService iActivitiService;
//generating25Sheets
@GetMapping
public Result getTables(){
log.info(“Start generating tables……………………………………………………….”);
Result result = iActivitiService.getTable();
return result;
}
//Process Deployment
@GetMapping(“/bushu”)
public Result bushu(){
log.info(“deployments “);
return Result.success(“ok”);
}
//Querying an individual’s pending tasks
@GetMapping(“/list”)
public Result list(){
log.info(“Querying an individual’s pending tasks“);
Result result = iActivitiService.list();
return result;
}
//close
@GetMapping(“/complete”)
public Result complete(){
log.info(“close“);
Result result = iActivitiService.complete();
return result;
}
}
Service layer code:
@Service
@Repository
@Slf4j
public class ActivitiServiceImpl implements IActivitiService {
@Autowired
public IActivitiMapper iActivitiMapper;
@Override
public Result getTable() {
//utilizationclasspathloweractiviti.cfg.xmlThe configuration in theprocessEngine
//If you use the default, you need the aboveactiviti.cfg.xmldeployment
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
return Result.success(“Generate Table Success“);
}
@Override
public Result bushu() {
//1CreateProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2GetRepositoryServicean actual example
RepositoryService repositoryService = processEngine.getRepositoryService();
//3Use ofRepositoryServicedeploy
Deployment deploy = repositoryService.createDeployment().addClasspathResource(“activiti/groupactiviti.bpmn20.xml”)
.addClasspathResource(“activiti/groupactiviti.png”)
.name(“Group Purchase Application Approval“)
.deploy();
//4The output of the deployment information
log.info(“deploymentsid:“+deploy.getId());
log.info(“The name of the deployed task:“+deploy.getName());
//5The process definition is initiated according to the process definition of theidStartup process key:act_re_procdefhit the nail on the headKEY
//establishTaskService
TaskService taskService = processEngine.getTaskService();
Map<String, Object> variables = new HashMap<>();
String username = SecurityUtils.getLoginUser().getSysUser().getUserName();
// String username = “admin”;
//userpreciselybpmnIn theAssigneeConfigured parameters
variables.put(“admin”, username);
//3.Creating a Process Instance The process definition of thekeyneed to know holiday
ProcessInstance processInstance = ProcessEngines.getDefaultProcessEngine()
.getRuntimeService()
.startProcessInstanceByKey(“groupactiviti”, variables);
System.out.println(processInstance+“=============================================”);
Task tmp = taskService.createTaskQuery()
.processInstanceId(processInstance.getProcessInstanceId()).singleResult();
tmp.setAssignee(“ry”);
//Complete this node. Approved by the next node. Completedact_ru_taskwill create a piece of data that will be approved by the next node
taskService.complete(tmp.getId(),variables);
//4.Information about the output example
log.info(“Process DeploymentID:” + processInstance.getDeploymentId() );
log.info(“Process DefinitionID:” + processInstance.getProcessDefinitionId());
log.info(“Process ExamplesID:” + processInstance.getId());
log.info(“maneuverID:” + processInstance.getActivityId());
return Result.success(true,“Application submitted“);
}
//Individual pending missions
@Override
public Result list() {
ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = defaultProcessEngine.getTaskService();
// Query the tasks of the current registrant.
String username= SecurityUtils.getLoginUser().getSysUser().getUserName();
System.out.println(“Currently logged in“+username);
if (username == null){
throw new CheckedException(“The current login is empty“);
}
List<Task> task = taskService.createTaskQuery()
.processDefinitionKey(“groupactiviti”)
.taskAssignee(username)
.list();
System.out.println(“===================”+task);
if(!ObjectUtils.isEmpty(task)) {
for (Task item : task) {
Map<String, Object> variables = new HashMap<>();
if (username.equals(“ry”)){
variables.put(“ry”, username);
variables.put(“isSuccess”, true);
item.setAssignee(“aaa”);
//Addition of Approval Remarks
taskService.addComment(item.getId(),item.getProcessInstanceId(),“The line manager has agreed“);
//Complete this approval. Approval by the next node act_hi_taskinstWill change the time
taskService.complete(item.getId(), variables);
}
if (username.equals(“aaa”)){
variables.put(“aaa”, username);
variables.put(“isSuccess”, true);
item.setAssignee(“aaa”);
//Addition of Approval Remarks
taskService.addComment(item.getId(),item.getProcessInstanceId(),“Finance has been agreed“);
//Complete this approval. Approval by the next node act_hi_taskinstWill change the time
taskService.complete(item.getId(), variables);
}
}
}
return Result.success(true,“Audit Success“);
}
// close
@Override
public Result complete() {
//1.establishProcessEngineboyfriend
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//establishTaskService
TaskService taskService = processEngine.getTaskService();
// Get the current login Judge yesadminIt’s the end of the mission.
String username = SecurityUtils.getLoginUser().getSysUser().getUserName();
// String username = “aaa”;
if (username == null) {
throw new CheckedException(“The current login is empty“);
}
if (username.equals(“aaa”)) {
//act_re_execution mandatesid
Task task = taskService.createTaskQuery()
.processDefinitionKey(“groupactiviti”)
.taskAssignee(username)
.singleResult();
if (task != null) {
HashMap<String, Object> map = new HashMap<>();
map.put(“agree”, 1);
taskService.complete(task.getId(), map);
System.out.println(“finalize one’s mission“);
}
}
return Result.success(true,“Audit Success“);
}
}
Define a remote call remote for other services to call.
Structure:
- ActivitiRemoteFallback code:
/**
* activitiService Degradation Processing
*
* @author
*/
@Component
public class ActivitiRemoteFallback implements FallbackFactory<ActivitiRemoteService>
{
private static final Logger log = LoggerFactory.getLogger(ActivitiRemoteFallback.class);
@Override
public ActivitiRemoteService create(Throwable cause) {
log.error(“Workflow invocation failure:{}”, cause.getMessage());
return new ActivitiRemoteService(){
@Override
public Result getTables() {
return null;
}
@Override
public Result bushu() {
return Result.error(“Remote Invocation Workflow Deployment Failure“);
}
@Override
public Result list() {
return Result.error(“Remote invocation workflow audit failed“);
}
@Override
public Result complete() {
return Result.error(“Remote Call Workflow End Audit Failure“);
}
};
}
}
- ActivitiRemoteServiceCode:
/**
* customer service
*
* @author bawei
*/
@FeignClient(contextId = “rctivitiRemoteService”,
value = ServiceNameConstants.**** own filename,
fallbackFactory = ActivitiRemoteFallback.class,path = “/activiti”)
public interface ActivitiRemoteService {
//generating25Sheets
@GetMapping
public Result getTables();
//Process Deployment
@GetMapping(“/bushu”)
public Result bushu();
//Querying an individual’s pending tasks
@GetMapping(“/list”)
public Result list();
//close
@GetMapping(“/complete”)
public Result complete();
}
- org.springframework.boot.autoconfigure.AutoConfiguration.importsConfigured code
Finally: Inject the service directly into Activiti wherever it is needed.