From f6e4aa704f7661add2b64d47a350da2f85336ad9 Mon Sep 17 00:00:00 2001
From: zhongrj <646384940@qq.com>
Date: Thu, 03 Aug 2023 15:00:22 +0800
Subject: [PATCH] 新增警车设备信息插入(通过upd服务接收信息),并移除flowable工作流

---
 src/main/java/org/springblade/modules/netty/event/StartupEvent.java                                  |   38 +
 src/main/java/org/springblade/modules/netty/config/SysConfig.java                                    |   26 
 src/main/java/org/springblade/modules/netty/server/UdpServer.java                                    |   86 ++
 src/main/java/org/springblade/modules/netty/business/mapper/PoliceCarEquipmentMapper.xml             |   73 ++
 src/main/java/org/springblade/modules/netty/util/Hex.java                                            |  552 ++++++++++++++++++
 src/main/java/org/springblade/modules/netty/config/MyDecoder.java                                    |  132 ++++
 src/main/java/org/springblade/modules/netty/business/mapper/PoliceCarEquipmentMapper.java            |   42 +
 src/main/resources/application-prod.yml                                                              |    4 
 src/main/resources/application-test.yml                                                              |    8 
 pom.xml                                                                                              |    8 
 /dev/null                                                                                            |   46 -
 src/main/java/org/springblade/modules/netty/business/service/impl/PoliceCarEquipmentServiceImpl.java |   60 ++
 src/main/java/org/springblade/modules/netty/util/HexStringTool.java                                  |  303 ++++++++++
 src/main/java/org/springblade/modules/netty/handle/UdpServerHandler.java                             |  160 +++++
 src/main/java/org/springblade/modules/netty/business/entity/PoliceCarEquipmentRecord.java            |   87 ++
 src/main/resources/application-dev.yml                                                               |    6 
 src/main/java/org/springblade/modules/netty/business/entity/PoliceCarEquipment.java                  |  104 +++
 src/main/java/org/springblade/modules/netty/business/service/PoliceCarEquipmentService.java          |   19 
 18 files changed, 1,701 insertions(+), 53 deletions(-)

diff --git a/pom.xml b/pom.xml
index 24bec6b..e5ab5be 100644
--- a/pom.xml
+++ b/pom.xml
@@ -120,10 +120,10 @@
             <artifactId>blade-starter-report</artifactId>
         </dependency>
         <!-- 工作流 -->
-        <dependency>
-            <groupId>org.springblade</groupId>
-            <artifactId>blade-starter-flowable</artifactId>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.springblade</groupId>-->
+<!--            <artifactId>blade-starter-flowable</artifactId>-->
+<!--        </dependency>-->
         <!-- 验证码 -->
         <dependency>
             <groupId>com.github.whvcse</groupId>
diff --git a/src/main/java/org/springblade/flow/business/controller/WorkController.java b/src/main/java/org/springblade/flow/business/controller/WorkController.java
deleted file mode 100644
index 21addaf..0000000
--- a/src/main/java/org/springblade/flow/business/controller/WorkController.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.business.controller;
-
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import lombok.AllArgsConstructor;
-import org.flowable.engine.TaskService;
-import org.springblade.core.launch.constant.AppConstant;
-import org.springblade.core.mp.support.Condition;
-import org.springblade.core.mp.support.Query;
-import org.springblade.core.tool.api.R;
-import org.springblade.flow.business.service.FlowBusinessService;
-import org.springblade.flow.core.entity.BladeFlow;
-import org.springblade.flow.core.utils.TaskUtil;
-import org.springblade.flow.engine.entity.FlowProcess;
-import org.springblade.flow.engine.service.FlowEngineService;
-import org.springframework.web.bind.annotation.*;
-
-/**
- * 流程事务通用接口
- *
- * @author Chill
- */
-@RestController
-@AllArgsConstructor
-@RequestMapping(AppConstant.APPLICATION_FLOW_NAME + "/work")
-@Api(value = "流程事务通用接口", tags = "流程事务通用接口")
-public class WorkController {
-
-	private final TaskService taskService;
-	private final FlowEngineService flowEngineService;
-	private final FlowBusinessService flowBusinessService;
-
-	/**
-	 * 发起事务列表页
-	 */
-	@GetMapping("start-list")
-	@ApiOperationSupport(order = 1)
-	@ApiOperation(value = "发起事务列表页", notes = "传入流程类型")
-	public R<IPage<FlowProcess>> startList(@ApiParam("流程类型") String category, Query query, @RequestParam(required = false, defaultValue = "1") Integer mode) {
-		IPage<FlowProcess> pages = flowEngineService.selectProcessPage(Condition.getPage(query), category, mode);
-		return R.data(pages);
-	}
-
-	/**
-	 * 待签事务列表页
-	 */
-	@GetMapping("claim-list")
-	@ApiOperationSupport(order = 2)
-	@ApiOperation(value = "待签事务列表页", notes = "传入流程信息")
-	public R<IPage<BladeFlow>> claimList(@ApiParam("流程信息") BladeFlow bladeFlow, Query query) {
-		IPage<BladeFlow> pages = flowBusinessService.selectClaimPage(Condition.getPage(query), bladeFlow);
-		return R.data(pages);
-	}
-
-	/**
-	 * 待办事务列表页
-	 */
-	@GetMapping("todo-list")
-	@ApiOperationSupport(order = 3)
-	@ApiOperation(value = "待办事务列表页", notes = "传入流程信息")
-	public R<IPage<BladeFlow>> todoList(@ApiParam("流程信息") BladeFlow bladeFlow, Query query) {
-		IPage<BladeFlow> pages = flowBusinessService.selectTodoPage(Condition.getPage(query), bladeFlow);
-		return R.data(pages);
-	}
-
-	/**
-	 * 已发事务列表页
-	 */
-	@GetMapping("send-list")
-	@ApiOperationSupport(order = 4)
-	@ApiOperation(value = "已发事务列表页", notes = "传入流程信息")
-	public R<IPage<BladeFlow>> sendList(@ApiParam("流程信息") BladeFlow bladeFlow, Query query) {
-		IPage<BladeFlow> pages = flowBusinessService.selectSendPage(Condition.getPage(query), bladeFlow);
-		return R.data(pages);
-	}
-
-	/**
-	 * 办结事务列表页
-	 */
-	@GetMapping("done-list")
-	@ApiOperationSupport(order = 5)
-	@ApiOperation(value = "办结事务列表页", notes = "传入流程信息")
-	public R<IPage<BladeFlow>> doneList(@ApiParam("流程信息") BladeFlow bladeFlow, Query query) {
-		IPage<BladeFlow> pages = flowBusinessService.selectDonePage(Condition.getPage(query), bladeFlow);
-		return R.data(pages);
-	}
-
-	/**
-	 * 签收事务
-	 *
-	 * @param taskId 任务id
-	 */
-	@PostMapping("claim-task")
-	@ApiOperationSupport(order = 6)
-	@ApiOperation(value = "签收事务", notes = "传入流程信息")
-	public R claimTask(@ApiParam("任务id") String taskId) {
-		taskService.claim(taskId, TaskUtil.getTaskUser());
-		return R.success("签收事务成功");
-	}
-
-	/**
-	 * 完成任务
-	 *
-	 * @param flow 请假信息
-	 */
-	@PostMapping("complete-task")
-	@ApiOperationSupport(order = 7)
-	@ApiOperation(value = "完成任务", notes = "传入流程信息")
-	public R completeTask(@ApiParam("任务信息") @RequestBody BladeFlow flow) {
-		return R.status(flowBusinessService.completeTask(flow));
-	}
-
-	/**
-	 * 删除任务
-	 *
-	 * @param taskId 任务id
-	 * @param reason 删除原因
-	 */
-	@PostMapping("delete-task")
-	@ApiOperationSupport(order = 8)
-	@ApiOperation(value = "删除任务", notes = "传入流程信息")
-	public R deleteTask(@ApiParam("任务id") String taskId, @ApiParam("删除原因") String reason) {
-		taskService.deleteTask(taskId, reason);
-		return R.success("删除任务成功");
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/business/service/FlowBusinessService.java b/src/main/java/org/springblade/flow/business/service/FlowBusinessService.java
deleted file mode 100644
index 8fb4227..0000000
--- a/src/main/java/org/springblade/flow/business/service/FlowBusinessService.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.business.service;
-
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import org.springblade.flow.core.entity.BladeFlow;
-
-/**
- * 流程业务类
- *
- * @author Chill
- */
-public interface FlowBusinessService {
-
-	/**
-	 * 流程待签列表
-	 *
-	 * @param page      分页工具
-	 * @param bladeFlow 流程类
-	 * @return
-	 */
-	IPage<BladeFlow> selectClaimPage(IPage<BladeFlow> page, BladeFlow bladeFlow);
-
-	/**
-	 * 流程待办列表
-	 *
-	 * @param page      分页工具
-	 * @param bladeFlow 流程类
-	 * @return
-	 */
-	IPage<BladeFlow> selectTodoPage(IPage<BladeFlow> page, BladeFlow bladeFlow);
-
-	/**
-	 * 流程已发列表
-	 *
-	 * @param page      分页工具
-	 * @param bladeFlow 流程类
-	 * @return
-	 */
-	IPage<BladeFlow> selectSendPage(IPage<BladeFlow> page, BladeFlow bladeFlow);
-
-	/**
-	 * 流程办结列表
-	 *
-	 * @param page      分页工具
-	 * @param bladeFlow 流程类
-	 * @return
-	 */
-	IPage<BladeFlow> selectDonePage(IPage<BladeFlow> page, BladeFlow bladeFlow);
-
-	/**
-	 * 完成任务
-	 *
-	 * @param leave 请假信息
-	 * @return boolean
-	 */
-	boolean completeTask(BladeFlow leave);
-}
diff --git a/src/main/java/org/springblade/flow/business/service/IFlowService.java b/src/main/java/org/springblade/flow/business/service/IFlowService.java
deleted file mode 100644
index 60aafb3..0000000
--- a/src/main/java/org/springblade/flow/business/service/IFlowService.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.business.service;
-
-import org.springblade.flow.core.entity.BladeFlow;
-
-import java.util.Map;
-
-/**
- * 工作流调用接口.
- *
- * @author Chill
- */
-public interface IFlowService {
-
-	/**
-	 * 开启流程
-	 *
-	 * @param processDefinitionId 流程id
-	 * @param businessKey         业务key
-	 * @param variables           参数
-	 * @return BladeFlow
-	 */
-	BladeFlow startProcessInstanceById(String processDefinitionId, String businessKey, Map<String, Object> variables);
-
-	/**
-	 * 开启流程
-	 *
-	 * @param processDefinitionKey 流程标识
-	 * @param businessKey          业务key
-	 * @param variables            参数
-	 * @return BladeFlow
-	 */
-	BladeFlow startProcessInstanceByKey(String processDefinitionKey, String businessKey, Map<String, Object> variables);
-
-	/**
-	 * 完成任务
-	 *
-	 * @param taskId            任务id
-	 * @param processInstanceId 流程实例id
-	 * @param comment           评论
-	 * @param variables         参数
-	 * @return R
-	 */
-	boolean completeTask(String taskId, String processInstanceId, String comment, Map<String, Object> variables);
-
-	/**
-	 * 获取流程变量
-	 *
-	 * @param taskId       任务id
-	 * @param variableName 变量名
-	 * @return R
-	 */
-	Object taskVariable(String taskId, String variableName);
-
-	/**
-	 * 获取流程变量集合
-	 *
-	 * @param taskId 任务id
-	 * @return R
-	 */
-	Map<String, Object> taskVariables(String taskId);
-}
diff --git a/src/main/java/org/springblade/flow/business/service/impl/FlowBusinessServiceImpl.java b/src/main/java/org/springblade/flow/business/service/impl/FlowBusinessServiceImpl.java
deleted file mode 100644
index 0db6bba..0000000
--- a/src/main/java/org/springblade/flow/business/service/impl/FlowBusinessServiceImpl.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.business.service.impl;
-
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import lombok.AllArgsConstructor;
-import org.flowable.engine.HistoryService;
-import org.flowable.engine.TaskService;
-import org.flowable.engine.history.HistoricProcessInstance;
-import org.flowable.engine.history.HistoricProcessInstanceQuery;
-import org.flowable.task.api.TaskQuery;
-import org.flowable.task.api.history.HistoricTaskInstance;
-import org.flowable.task.api.history.HistoricTaskInstanceQuery;
-import org.springblade.core.secure.utils.AuthUtil;
-import org.springblade.core.tool.support.Kv;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.StringPool;
-import org.springblade.core.tool.utils.StringUtil;
-import org.springblade.flow.business.service.FlowBusinessService;
-import org.springblade.flow.core.constant.ProcessConstant;
-import org.springblade.flow.core.entity.BladeFlow;
-import org.springblade.flow.core.utils.TaskUtil;
-import org.springblade.flow.engine.constant.FlowEngineConstant;
-import org.springblade.flow.engine.entity.FlowProcess;
-import org.springblade.flow.engine.utils.FlowCache;
-import org.springframework.stereotype.Service;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 流程业务实现类
- *
- * @author Chill
- */
-@Service
-@AllArgsConstructor
-public class FlowBusinessServiceImpl implements FlowBusinessService {
-
-	private final TaskService taskService;
-	private final HistoryService historyService;
-
-	@Override
-	public IPage<BladeFlow> selectClaimPage(IPage<BladeFlow> page, BladeFlow bladeFlow) {
-		String taskUser = TaskUtil.getTaskUser();
-		String taskGroup = TaskUtil.getCandidateGroup();
-		List<BladeFlow> flowList = new LinkedList<>();
-
-		// 个人等待签收的任务
-		TaskQuery claimUserQuery = taskService.createTaskQuery().taskCandidateUser(taskUser)
-			.includeProcessVariables().active().orderByTaskCreateTime().desc();
-		// 定制流程等待签收的任务
-		TaskQuery claimRoleWithTenantIdQuery = taskService.createTaskQuery().taskTenantId(AuthUtil.getTenantId()).taskCandidateGroupIn(Func.toStrList(taskGroup))
-			.includeProcessVariables().active().orderByTaskCreateTime().desc();
-		// 通用流程等待签收的任务
-		TaskQuery claimRoleWithoutTenantIdQuery = taskService.createTaskQuery().taskWithoutTenantId().taskCandidateGroupIn(Func.toStrList(taskGroup))
-			.includeProcessVariables().active().orderByTaskCreateTime().desc();
-
-		// 构建列表数据
-		buildFlowTaskList(bladeFlow, flowList, claimUserQuery, FlowEngineConstant.STATUS_CLAIM);
-		buildFlowTaskList(bladeFlow, flowList, claimRoleWithTenantIdQuery, FlowEngineConstant.STATUS_CLAIM);
-		buildFlowTaskList(bladeFlow, flowList, claimRoleWithoutTenantIdQuery, FlowEngineConstant.STATUS_CLAIM);
-
-		// 计算总数
-		long count = claimUserQuery.count() + claimRoleWithTenantIdQuery.count() + claimRoleWithoutTenantIdQuery.count();
-		// 设置页数
-		page.setSize(count);
-		// 设置总数
-		page.setTotal(count);
-		// 设置数据
-		page.setRecords(flowList);
-		return page;
-	}
-
-	@Override
-	public IPage<BladeFlow> selectTodoPage(IPage<BladeFlow> page, BladeFlow bladeFlow) {
-		String taskUser = TaskUtil.getTaskUser();
-		List<BladeFlow> flowList = new LinkedList<>();
-
-		// 已签收的任务
-		TaskQuery todoQuery = taskService.createTaskQuery().taskAssignee(taskUser).active()
-			.includeProcessVariables().orderByTaskCreateTime().desc();
-
-		// 构建列表数据
-		buildFlowTaskList(bladeFlow, flowList, todoQuery, FlowEngineConstant.STATUS_TODO);
-
-		// 计算总数
-		long count = todoQuery.count();
-		// 设置页数
-		page.setSize(count);
-		// 设置总数
-		page.setTotal(count);
-		// 设置数据
-		page.setRecords(flowList);
-		return page;
-	}
-
-	@Override
-	public IPage<BladeFlow> selectSendPage(IPage<BladeFlow> page, BladeFlow bladeFlow) {
-		String taskUser = TaskUtil.getTaskUser();
-		List<BladeFlow> flowList = new LinkedList<>();
-
-		HistoricProcessInstanceQuery historyQuery = historyService.createHistoricProcessInstanceQuery().startedBy(taskUser).orderByProcessInstanceStartTime().desc();
-
-		if (bladeFlow.getCategory() != null) {
-			historyQuery.processDefinitionCategory(bladeFlow.getCategory());
-		}
-		if (bladeFlow.getProcessDefinitionName() != null) {
-			historyQuery.processDefinitionName(bladeFlow.getProcessDefinitionName());
-		}
-		if (bladeFlow.getBeginDate() != null) {
-			historyQuery.startedAfter(bladeFlow.getBeginDate());
-		}
-		if (bladeFlow.getEndDate() != null) {
-			historyQuery.startedBefore(bladeFlow.getEndDate());
-		}
-
-		// 查询列表
-		List<HistoricProcessInstance> historyList = historyQuery.listPage(Func.toInt((page.getCurrent() - 1) * page.getSize()), Func.toInt(page.getSize()));
-
-		historyList.forEach(historicProcessInstance -> {
-			BladeFlow flow = new BladeFlow();
-			// historicProcessInstance
-			flow.setCreateTime(historicProcessInstance.getStartTime());
-			flow.setEndTime(historicProcessInstance.getEndTime());
-			flow.setVariables(historicProcessInstance.getProcessVariables());
-			String[] businessKey = Func.toStrArray(StringPool.COLON, historicProcessInstance.getBusinessKey());
-			if (businessKey.length > 1) {
-				flow.setBusinessTable(businessKey[0]);
-				flow.setBusinessId(businessKey[1]);
-			}
-			flow.setHistoryActivityName(historicProcessInstance.getName());
-			flow.setProcessInstanceId(historicProcessInstance.getId());
-			flow.setHistoryProcessInstanceId(historicProcessInstance.getId());
-			// ProcessDefinition
-			FlowProcess processDefinition = FlowCache.getProcessDefinition(historicProcessInstance.getProcessDefinitionId());
-			flow.setProcessDefinitionId(processDefinition.getId());
-			flow.setProcessDefinitionName(processDefinition.getName());
-			flow.setProcessDefinitionVersion(processDefinition.getVersion());
-			flow.setProcessDefinitionKey(processDefinition.getKey());
-			flow.setCategory(processDefinition.getCategory());
-			flow.setCategoryName(FlowCache.getCategoryName(processDefinition.getCategory()));
-			flow.setProcessInstanceId(historicProcessInstance.getId());
-			// HistoricTaskInstance
-			List<HistoricTaskInstance> historyTasks = historyService.createHistoricTaskInstanceQuery().processInstanceId(historicProcessInstance.getId()).orderByHistoricTaskInstanceEndTime().desc().list();
-			if (Func.isNotEmpty(historyTasks)) {
-				HistoricTaskInstance historyTask = historyTasks.iterator().next();
-				flow.setTaskId(historyTask.getId());
-				flow.setTaskName(historyTask.getName());
-				flow.setTaskDefinitionKey(historyTask.getTaskDefinitionKey());
-			}
-			// Status
-			if (historicProcessInstance.getEndActivityId() != null) {
-				flow.setProcessIsFinished(FlowEngineConstant.STATUS_FINISHED);
-			} else {
-				flow.setProcessIsFinished(FlowEngineConstant.STATUS_UNFINISHED);
-			}
-			flow.setStatus(FlowEngineConstant.STATUS_FINISH);
-			flowList.add(flow);
-		});
-
-		// 计算总数
-		long count = historyQuery.count();
-		// 设置总数
-		page.setTotal(count);
-		page.setRecords(flowList);
-		return page;
-	}
-
-	@Override
-	public IPage<BladeFlow> selectDonePage(IPage<BladeFlow> page, BladeFlow bladeFlow) {
-		String taskUser = TaskUtil.getTaskUser();
-		List<BladeFlow> flowList = new LinkedList<>();
-
-		HistoricTaskInstanceQuery doneQuery = historyService.createHistoricTaskInstanceQuery().taskAssignee(taskUser).finished()
-			.includeProcessVariables().orderByHistoricTaskInstanceEndTime().desc();
-
-		if (bladeFlow.getCategory() != null) {
-			doneQuery.processCategoryIn(Func.toStrList(bladeFlow.getCategory()));
-		}
-		if (bladeFlow.getProcessDefinitionName() != null) {
-			doneQuery.processDefinitionName(bladeFlow.getProcessDefinitionName());
-		}
-		if (bladeFlow.getBeginDate() != null) {
-			doneQuery.taskCompletedAfter(bladeFlow.getBeginDate());
-		}
-		if (bladeFlow.getEndDate() != null) {
-			doneQuery.taskCompletedBefore(bladeFlow.getEndDate());
-		}
-
-		// 查询列表
-		List<HistoricTaskInstance> doneList = doneQuery.listPage(Func.toInt((page.getCurrent() - 1) * page.getSize()), Func.toInt(page.getSize()));
-		doneList.forEach(historicTaskInstance -> {
-			BladeFlow flow = new BladeFlow();
-			flow.setTaskId(historicTaskInstance.getId());
-			flow.setTaskDefinitionKey(historicTaskInstance.getTaskDefinitionKey());
-			flow.setTaskName(historicTaskInstance.getName());
-			flow.setAssignee(historicTaskInstance.getAssignee());
-			flow.setCreateTime(historicTaskInstance.getCreateTime());
-			flow.setExecutionId(historicTaskInstance.getExecutionId());
-			flow.setHistoryTaskEndTime(historicTaskInstance.getEndTime());
-			flow.setVariables(historicTaskInstance.getProcessVariables());
-
-			FlowProcess processDefinition = FlowCache.getProcessDefinition(historicTaskInstance.getProcessDefinitionId());
-			flow.setProcessDefinitionId(processDefinition.getId());
-			flow.setProcessDefinitionName(processDefinition.getName());
-			flow.setProcessDefinitionKey(processDefinition.getKey());
-			flow.setProcessDefinitionVersion(processDefinition.getVersion());
-			flow.setCategory(processDefinition.getCategory());
-			flow.setCategoryName(FlowCache.getCategoryName(processDefinition.getCategory()));
-
-			flow.setProcessInstanceId(historicTaskInstance.getProcessInstanceId());
-			flow.setHistoryProcessInstanceId(historicTaskInstance.getProcessInstanceId());
-			HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance((historicTaskInstance.getProcessInstanceId()));
-			if (Func.isNotEmpty(historicProcessInstance)) {
-				String[] businessKey = Func.toStrArray(StringPool.COLON, historicProcessInstance.getBusinessKey());
-				flow.setBusinessTable(businessKey[0]);
-				flow.setBusinessId(businessKey[1]);
-				if (historicProcessInstance.getEndActivityId() != null) {
-					flow.setProcessIsFinished(FlowEngineConstant.STATUS_FINISHED);
-				} else {
-					flow.setProcessIsFinished(FlowEngineConstant.STATUS_UNFINISHED);
-				}
-			}
-			flow.setStatus(FlowEngineConstant.STATUS_FINISH);
-			flowList.add(flow);
-		});
-		// 计算总数
-		long count = doneQuery.count();
-		// 设置总数
-		page.setTotal(count);
-		page.setRecords(flowList);
-		return page;
-	}
-
-	@Override
-	public boolean completeTask(BladeFlow flow) {
-		String taskId = flow.getTaskId();
-		String processInstanceId = flow.getProcessInstanceId();
-		String comment = Func.toStr(flow.getComment(), ProcessConstant.PASS_COMMENT);
-		// 增加评论
-		if (StringUtil.isNoneBlank(processInstanceId, comment)) {
-			taskService.addComment(taskId, processInstanceId, comment);
-		}
-		// 创建变量
-		Map<String, Object> variables = flow.getVariables();
-		if (variables == null) {
-			variables = Kv.create();
-		}
-		variables.put(ProcessConstant.PASS_KEY, flow.isPass());
-		// 完成任务
-		taskService.complete(taskId, variables);
-		return true;
-	}
-
-	/**
-	 * 构建流程
-	 *
-	 * @param bladeFlow 流程通用类
-	 * @param flowList  流程列表
-	 * @param taskQuery 任务查询类
-	 * @param status    状态
-	 */
-	private void buildFlowTaskList(BladeFlow bladeFlow, List<BladeFlow> flowList, TaskQuery taskQuery, String status) {
-		if (bladeFlow.getCategory() != null) {
-			taskQuery.processCategoryIn(Func.toStrList(bladeFlow.getCategory()));
-		}
-		if (bladeFlow.getProcessDefinitionName() != null) {
-			taskQuery.processDefinitionName(bladeFlow.getProcessDefinitionName());
-		}
-		if (bladeFlow.getBeginDate() != null) {
-			taskQuery.taskCreatedAfter(bladeFlow.getBeginDate());
-		}
-		if (bladeFlow.getEndDate() != null) {
-			taskQuery.taskCreatedBefore(bladeFlow.getEndDate());
-		}
-		taskQuery.list().forEach(task -> {
-			BladeFlow flow = new BladeFlow();
-			flow.setTaskId(task.getId());
-			flow.setTaskDefinitionKey(task.getTaskDefinitionKey());
-			flow.setTaskName(task.getName());
-			flow.setAssignee(task.getAssignee());
-			flow.setCreateTime(task.getCreateTime());
-			flow.setClaimTime(task.getClaimTime());
-			flow.setExecutionId(task.getExecutionId());
-			flow.setVariables(task.getProcessVariables());
-
-			HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(task.getProcessInstanceId());
-			if (Func.isNotEmpty(historicProcessInstance)) {
-				String[] businessKey = Func.toStrArray(StringPool.COLON, historicProcessInstance.getBusinessKey());
-				flow.setBusinessTable(businessKey[0]);
-				flow.setBusinessId(businessKey[1]);
-			}
-
-			FlowProcess processDefinition = FlowCache.getProcessDefinition(task.getProcessDefinitionId());
-			flow.setCategory(processDefinition.getCategory());
-			flow.setCategoryName(FlowCache.getCategoryName(processDefinition.getCategory()));
-			flow.setProcessDefinitionId(processDefinition.getId());
-			flow.setProcessDefinitionName(processDefinition.getName());
-			flow.setProcessDefinitionKey(processDefinition.getKey());
-			flow.setProcessDefinitionVersion(processDefinition.getVersion());
-			flow.setProcessInstanceId(task.getProcessInstanceId());
-			flow.setStatus(status);
-			flowList.add(flow);
-		});
-	}
-
-	/**
-	 * 获取历史流程
-	 *
-	 * @param processInstanceId 流程实例id
-	 * @return HistoricProcessInstance
-	 */
-	private HistoricProcessInstance getHistoricProcessInstance(String processInstanceId) {
-		return historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/business/service/impl/FlowServiceImpl.java b/src/main/java/org/springblade/flow/business/service/impl/FlowServiceImpl.java
deleted file mode 100644
index dcd160f..0000000
--- a/src/main/java/org/springblade/flow/business/service/impl/FlowServiceImpl.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.business.service.impl;
-
-import lombok.AllArgsConstructor;
-import org.flowable.engine.IdentityService;
-import org.flowable.engine.RuntimeService;
-import org.flowable.engine.TaskService;
-import org.flowable.engine.runtime.ProcessInstance;
-import org.springblade.core.tool.api.R;
-import org.springblade.core.tool.support.Kv;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.StringUtil;
-import org.springblade.flow.business.service.IFlowService;
-import org.springblade.flow.core.entity.BladeFlow;
-import org.springblade.flow.core.utils.TaskUtil;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.Map;
-
-/**
- * 流程实现类
- *
- * @author Chill
- */
-@RestController
-@AllArgsConstructor
-public class FlowServiceImpl implements IFlowService {
-
-	private final RuntimeService runtimeService;
-	private final IdentityService identityService;
-	private final TaskService taskService;
-
-	@Override
-	public BladeFlow startProcessInstanceById(String processDefinitionId, String businessKey, Map<String, Object> variables) {
-		// 设置流程启动用户
-		identityService.setAuthenticatedUserId(TaskUtil.getTaskUser());
-		// 开启流程
-		ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, businessKey, variables);
-		// 组装流程通用类
-		BladeFlow flow = new BladeFlow();
-		flow.setProcessInstanceId(processInstance.getId());
-		return flow;
-	}
-
-	@Override
-	public BladeFlow startProcessInstanceByKey(String processDefinitionKey, String businessKey, Map<String, Object> variables) {
-		// 设置流程启动用户
-		identityService.setAuthenticatedUserId(TaskUtil.getTaskUser());
-		// 开启流程
-		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);
-		// 组装流程通用类
-		BladeFlow flow = new BladeFlow();
-		flow.setProcessInstanceId(processInstance.getId());
-		return flow;
-	}
-
-	@Override
-	public boolean completeTask(String taskId, String processInstanceId, String comment, Map<String, Object> variables) {
-		// 增加评论
-		if (StringUtil.isNoneBlank(processInstanceId, comment)) {
-			taskService.addComment(taskId, processInstanceId, comment);
-		}
-		// 非空判断
-		if (Func.isEmpty(variables)) {
-			variables = Kv.create();
-		}
-		// 完成任务
-		taskService.complete(taskId, variables);
-		return true;
-	}
-
-	@Override
-	public Object taskVariable(String taskId, String variableName) {
-		return R.data(taskService.getVariable(taskId, variableName));
-	}
-
-	@Override
-	public Map<String, Object> taskVariables(String taskId) {
-		return taskService.getVariables(taskId);
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/core/constant/ProcessConstant.java b/src/main/java/org/springblade/flow/core/constant/ProcessConstant.java
deleted file mode 100644
index 8657f7b..0000000
--- a/src/main/java/org/springblade/flow/core/constant/ProcessConstant.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.core.constant;
-
-/**
- * 流程常量.
- *
- * @author Chill
- */
-public interface ProcessConstant {
-
-	/**
-	 * 请假流程标识
-	 */
-	String LEAVE_KEY = "Leave";
-
-	/**
-	 * 报销流程标识
-	 */
-	String EXPENSE_KEY = "Expense";
-
-	/**
-	 * 同意标识
-	 */
-	String PASS_KEY = "pass";
-
-	/**
-	 * 同意代号
-	 */
-	String PASS_ALIAS = "ok";
-
-	/**
-	 * 同意默认批复
-	 */
-	String PASS_COMMENT = "同意";
-
-	/**
-	 * 驳回默认批复
-	 */
-	String NOT_PASS_COMMENT = "驳回";
-
-	/**
-	 * 创建人变量名
-	 */
-	String TASK_VARIABLE_CREATE_USER = "createUser";
-
-}
diff --git a/src/main/java/org/springblade/flow/core/entity/BladeFlow.java b/src/main/java/org/springblade/flow/core/entity/BladeFlow.java
deleted file mode 100644
index 0492844..0000000
--- a/src/main/java/org/springblade/flow/core/entity/BladeFlow.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.core.entity;
-
-import lombok.Data;
-import org.springblade.flow.core.constant.ProcessConstant;
-
-import java.io.Serializable;
-import java.util.Date;
-import java.util.Map;
-
-/**
- * 工作流通用实体类
- *
- * @author Chill
- */
-@Data
-public class BladeFlow implements Serializable {
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * 任务编号
-	 */
-	private String taskId;
-	/**
-	 * 任务名称
-	 */
-	private String taskName;
-	/**
-	 * 任务定义Key
-	 */
-	private String taskDefinitionKey;
-	/**
-	 * 任务执行人编号
-	 */
-	private String assignee;
-	/**
-	 * 任务执行人名称
-	 */
-	private String assigneeName;
-	/**
-	 * 流程分类
-	 */
-	private String category;
-	/**
-	 * 流程分类名
-	 */
-	private String categoryName;
-	/**
-	 * 创建时间
-	 */
-	private Date createTime;
-	/**
-	 * 结束时间
-	 */
-	private Date endTime;
-	/**
-	 * 签收时间
-	 */
-	private Date claimTime;
-	/**
-	 * 历史任务结束时间
-	 */
-	private Date historyTaskEndTime;
-	/**
-	 * 执行ID
-	 */
-	private String executionId;
-	/**
-	 * 流程实例ID
-	 */
-	private String processInstanceId;
-	/**
-	 * 流程ID
-	 */
-	private String processDefinitionId;
-	/**
-	 * 流程标识
-	 */
-	private String processDefinitionKey;
-	/**
-	 * 流程名
-	 */
-	private String processDefinitionName;
-	/**
-	 * 流程版本
-	 */
-	private int processDefinitionVersion;
-	/**
-	 * 流程说明
-	 */
-	private String processDefinitionDesc;
-	/**
-	 * 流程简图名
-	 */
-	private String processDefinitionDiagramResName;
-	/**
-	 * 流程重命名
-	 */
-	private String processDefinitionResName;
-	/**
-	 * 历史任务流程实例ID 查看流程图会用到
-	 */
-	private String historyProcessInstanceId;
-	/**
-	 * 流程实例是否结束
-	 */
-	private String processIsFinished;
-	/**
-	 * 历史活动ID
-	 */
-	private String historyActivityId;
-	/**
-	 * 历史活动流程
-	 */
-	private String historyActivityName;
-	/**
-	 * 历史活动耗时
-	 */
-	private String historyActivityDurationTime;
-	/**
-	 * 业务绑定Table
-	 */
-	private String businessTable;
-	/**
-	 * 业务绑定ID
-	 */
-	private String businessId;
-	/**
-	 * 任务状态
-	 */
-	private String status;
-	/**
-	 * 任务意见
-	 */
-	private String comment;
-	/**
-	 * 是否通过
-	 */
-	private boolean isPass;
-	/**
-	 * 是否通过代号
-	 */
-	private String flag;
-	/**
-	 * 开始查询日期
-	 */
-	private Date beginDate;
-	/**
-	 * 结束查询日期
-	 */
-	private Date endDate;
-	/**
-	 * 流程参数
-	 */
-	private Map<String, Object> variables;
-
-	/**
-	 * 获取是否通过
-	 */
-	public boolean isPass() {
-		return ProcessConstant.PASS_ALIAS.equals(flag) || ProcessConstant.PASS_COMMENT.equals(comment);
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/core/entity/FlowEntity.java b/src/main/java/org/springblade/flow/core/entity/FlowEntity.java
deleted file mode 100644
index bedc62e..0000000
--- a/src/main/java/org/springblade/flow/core/entity/FlowEntity.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.core.entity;
-
-import com.baomidou.mybatisplus.annotation.TableField;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import org.springblade.core.mp.base.BaseEntity;
-
-/**
- * FlowEntity
- *
- * @author Chill
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-public class FlowEntity extends BaseEntity {
-
-	@TableField(exist = false)
-	private BladeFlow flow;
-
-	public BladeFlow getFlow() {
-		if (flow == null) {
-			flow = new BladeFlow();
-		}
-		return flow;
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/core/enums/FlowModeEnum.java b/src/main/java/org/springblade/flow/core/enums/FlowModeEnum.java
deleted file mode 100644
index c5ab5c7..0000000
--- a/src/main/java/org/springblade/flow/core/enums/FlowModeEnum.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.core.enums;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 流程类型枚举
- *
- * @author Chill
- */
-@Getter
-@AllArgsConstructor
-public enum FlowModeEnum {
-
-	/**
-	 * 通用流程
-	 */
-	COMMON("common", 1),
-
-	/**
-	 * 定制流程
-	 */
-	CUSTOM("custom", 2),
-	;
-
-	final String name;
-	final int mode;
-
-}
diff --git a/src/main/java/org/springblade/flow/core/utils/FlowUtil.java b/src/main/java/org/springblade/flow/core/utils/FlowUtil.java
deleted file mode 100644
index fd1b28e..0000000
--- a/src/main/java/org/springblade/flow/core/utils/FlowUtil.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.core.utils;
-
-import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.StringUtil;
-import org.springblade.flow.core.constant.ProcessConstant;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 工作流工具类
- *
- * @author Chill
- */
-public class FlowUtil {
-
-	/**
-	 * 定义流程key对应的表名
-	 */
-	private final static Map<String, String> BUSINESS_TABLE = new HashMap<>();
-
-	static {
-		BUSINESS_TABLE.put(ProcessConstant.LEAVE_KEY, "blade_process_leave");
-	}
-
-	/**
-	 * 通过流程key获取业务表名
-	 *
-	 * @param key 流程key
-	 */
-	public static String getBusinessTable(String key) {
-		String businessTable = BUSINESS_TABLE.get(key);
-		if (Func.isEmpty(businessTable)) {
-			throw new RuntimeException("流程启动失败,未找到相关业务表");
-		}
-		return businessTable;
-	}
-
-	/**
-	 * 获取业务标识
-	 *
-	 * @param businessTable 业务表
-	 * @param businessId    业务表主键
-	 * @return businessKey
-	 */
-	public static String getBusinessKey(String businessTable, String businessId) {
-		return StringUtil.format("{}:{}", businessTable, businessId);
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/core/utils/TaskUtil.java b/src/main/java/org/springblade/flow/core/utils/TaskUtil.java
deleted file mode 100644
index 3366224..0000000
--- a/src/main/java/org/springblade/flow/core/utils/TaskUtil.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.core.utils;
-
-import org.springblade.core.secure.utils.AuthUtil;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.StringUtil;
-
-import static org.springblade.core.launch.constant.FlowConstant.TASK_USR_PREFIX;
-
-/**
- * 工作流任务工具类
- *
- * @author Chill
- */
-public class TaskUtil {
-
-	/**
-	 * 获取任务用户格式
-	 *
-	 * @return taskUser
-	 */
-	public static String getTaskUser() {
-		return StringUtil.format("{}{}", TASK_USR_PREFIX, AuthUtil.getUserId());
-	}
-
-	/**
-	 * 获取任务用户格式
-	 *
-	 * @param userId 用户id
-	 * @return taskUser
-	 */
-	public static String getTaskUser(String userId) {
-		return StringUtil.format("{}{}", TASK_USR_PREFIX, userId);
-	}
-
-
-	/**
-	 * 获取用户主键
-	 *
-	 * @param taskUser 任务用户
-	 * @return userId
-	 */
-	public static Long getUserId(String taskUser) {
-		return Func.toLong(StringUtil.removePrefix(taskUser, TASK_USR_PREFIX));
-	}
-
-	/**
-	 * 获取用户组格式
-	 *
-	 * @return candidateGroup
-	 */
-	public static String getCandidateGroup() {
-		return AuthUtil.getUserRole();
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/demo/leave/controller/LeaveController.java b/src/main/java/org/springblade/flow/demo/leave/controller/LeaveController.java
deleted file mode 100644
index edc52a4..0000000
--- a/src/main/java/org/springblade/flow/demo/leave/controller/LeaveController.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.demo.leave.controller;
-
-import lombok.AllArgsConstructor;
-import org.springblade.common.cache.UserCache;
-import org.springblade.core.launch.constant.AppConstant;
-import org.springblade.core.tenant.annotation.NonDS;
-import org.springblade.core.tool.api.R;
-import org.springblade.flow.demo.leave.entity.ProcessLeave;
-import org.springblade.flow.demo.leave.service.ILeaveService;
-import org.springframework.web.bind.annotation.*;
-import springfox.documentation.annotations.ApiIgnore;
-
-/**
- * 控制器
- *
- * @author Chill
- */
-@NonDS
-@ApiIgnore
-@RestController
-@RequestMapping(AppConstant.APPLICATION_DESK_NAME + "/process/leave")
-@AllArgsConstructor
-public class LeaveController {
-
-	private final ILeaveService leaveService;
-
-	/**
-	 * 详情
-	 *
-	 * @param businessId 主键
-	 */
-	@GetMapping("detail")
-	public R<ProcessLeave> detail(Long businessId) {
-		ProcessLeave detail = leaveService.getById(businessId);
-		detail.getFlow().setAssigneeName(UserCache.getUser(detail.getCreateUser()).getName());
-		return R.data(detail);
-	}
-
-	/**
-	 * 新增或修改
-	 *
-	 * @param leave 请假信息
-	 */
-	@PostMapping("start-process")
-	public R startProcess(@RequestBody ProcessLeave leave) {
-		return R.status(leaveService.startProcess(leave));
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/demo/leave/entity/ProcessLeave.java b/src/main/java/org/springblade/flow/demo/leave/entity/ProcessLeave.java
deleted file mode 100644
index a5319de..0000000
--- a/src/main/java/org/springblade/flow/demo/leave/entity/ProcessLeave.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.demo.leave.entity;
-
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import org.springblade.flow.core.entity.FlowEntity;
-
-import java.util.Date;
-
-/**
- * 请假流程实体类
- *
- * @author Chill
- */
-@Data
-@TableName("blade_process_leave")
-@EqualsAndHashCode(callSuper = true)
-public class ProcessLeave extends FlowEntity {
-
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * 流程定义id
-	 */
-	private String processDefinitionId;
-	/**
-	 * 流程实例id
-	 */
-	private String processInstanceId;
-	/**
-	 * 请假开始时间
-	 */
-	private Date startTime;
-	/**
-	 * 请假结束时间
-	 */
-	private Date endTime;
-	/**
-	 * 请假理由
-	 */
-	private String reason;
-	/**
-	 * 审批人
-	 */
-	private String taskUser;
-	/**
-	 * 流程申请时间
-	 */
-	private Date applyTime;
-
-}
diff --git a/src/main/java/org/springblade/flow/demo/leave/mapper/LeaveMapper.java b/src/main/java/org/springblade/flow/demo/leave/mapper/LeaveMapper.java
deleted file mode 100644
index f343be8..0000000
--- a/src/main/java/org/springblade/flow/demo/leave/mapper/LeaveMapper.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.demo.leave.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import org.springblade.flow.demo.leave.entity.ProcessLeave;
-
-/**
- * Mapper 接口
- *
- * @author Chill
- */
-public interface LeaveMapper extends BaseMapper<ProcessLeave> {
-
-}
diff --git a/src/main/java/org/springblade/flow/demo/leave/mapper/LeaveMapper.xml b/src/main/java/org/springblade/flow/demo/leave/mapper/LeaveMapper.xml
deleted file mode 100644
index 64ad626..0000000
--- a/src/main/java/org/springblade/flow/demo/leave/mapper/LeaveMapper.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.springblade.flow.demo.leave.mapper.LeaveMapper">
-
-
-</mapper>
diff --git a/src/main/java/org/springblade/flow/demo/leave/service/ILeaveService.java b/src/main/java/org/springblade/flow/demo/leave/service/ILeaveService.java
deleted file mode 100644
index d52fab9..0000000
--- a/src/main/java/org/springblade/flow/demo/leave/service/ILeaveService.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.demo.leave.service;
-
-import org.springblade.core.mp.base.BaseService;
-import org.springblade.flow.demo.leave.entity.ProcessLeave;
-
-/**
- * 服务类
- *
- * @author Chill
- */
-public interface ILeaveService extends BaseService<ProcessLeave> {
-
-	/**
-	 * 开启流程
-	 *
-	 * @param leave 请假实体
-	 * @return boolean
-	 */
-	boolean startProcess(ProcessLeave leave);
-
-}
diff --git a/src/main/java/org/springblade/flow/demo/leave/service/impl/LeaveServiceImpl.java b/src/main/java/org/springblade/flow/demo/leave/service/impl/LeaveServiceImpl.java
deleted file mode 100644
index ff64a58..0000000
--- a/src/main/java/org/springblade/flow/demo/leave/service/impl/LeaveServiceImpl.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.demo.leave.service.impl;
-
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springblade.core.log.exception.ServiceException;
-import org.springblade.core.mp.base.BaseServiceImpl;
-import org.springblade.core.secure.utils.AuthUtil;
-import org.springblade.core.tool.support.Kv;
-import org.springblade.core.tool.utils.DateUtil;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.flow.business.service.IFlowService;
-import org.springblade.flow.core.constant.ProcessConstant;
-import org.springblade.flow.core.entity.BladeFlow;
-import org.springblade.flow.core.utils.FlowUtil;
-import org.springblade.flow.core.utils.TaskUtil;
-import org.springblade.flow.demo.leave.entity.ProcessLeave;
-import org.springblade.flow.demo.leave.mapper.LeaveMapper;
-import org.springblade.flow.demo.leave.service.ILeaveService;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * 服务实现类
- *
- * @author Chill
- */
-@Slf4j
-@Service
-@AllArgsConstructor
-public class LeaveServiceImpl extends BaseServiceImpl<LeaveMapper, ProcessLeave> implements ILeaveService {
-
-	private final IFlowService flowService;
-
-	@Override
-	@Transactional(rollbackFor = Exception.class)
-	public boolean startProcess(ProcessLeave leave) {
-		String businessTable = FlowUtil.getBusinessTable(ProcessConstant.LEAVE_KEY);
-		if (Func.isEmpty(leave.getId())) {
-			// 保存leave
-			leave.setApplyTime(DateUtil.now());
-			save(leave);
-			// 启动流程
-			Kv variables = Kv.create()
-				.set(ProcessConstant.TASK_VARIABLE_CREATE_USER, AuthUtil.getUserName())
-				.set("taskUser", TaskUtil.getTaskUser(leave.getTaskUser()))
-				.set("days", DateUtil.between(leave.getStartTime(), leave.getEndTime()).toDays());
-			BladeFlow flow = flowService.startProcessInstanceById(leave.getProcessDefinitionId(), FlowUtil.getBusinessKey(businessTable, String.valueOf(leave.getId())), variables);
-			if (Func.isNotEmpty(flow)) {
-				log.debug("流程已启动,流程ID:" + flow.getProcessInstanceId());
-				// 返回流程id写入leave
-				leave.setProcessInstanceId(flow.getProcessInstanceId());
-				updateById(leave);
-			} else {
-				throw new ServiceException("开启流程失败");
-			}
-		} else {
-
-			updateById(leave);
-		}
-		return true;
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/demo/package-info.java b/src/main/java/org/springblade/flow/demo/package-info.java
deleted file mode 100644
index 281e074..0000000
--- a/src/main/java/org/springblade/flow/demo/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Created by Blade.
- *
- * @author zhuangqian
- */
-package org.springblade.flow.demo;
diff --git a/src/main/java/org/springblade/flow/engine/config/FlowableConfiguration.java b/src/main/java/org/springblade/flow/engine/config/FlowableConfiguration.java
deleted file mode 100644
index f0aff2b..0000000
--- a/src/main/java/org/springblade/flow/engine/config/FlowableConfiguration.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.config;
-
-import lombok.AllArgsConstructor;
-import org.flowable.spring.SpringProcessEngineConfiguration;
-import org.flowable.spring.boot.EngineConfigurationConfigurer;
-import org.flowable.spring.boot.FlowableProperties;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Flowable配置类
- *
- * @author Chill
- */
-@Configuration(proxyBeanMethods = false)
-@AllArgsConstructor
-@EnableConfigurationProperties(FlowableProperties.class)
-public class FlowableConfiguration implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
-	private final FlowableProperties flowableProperties;
-
-	@Override
-	public void configure(SpringProcessEngineConfiguration engineConfiguration) {
-		engineConfiguration.setActivityFontName(flowableProperties.getActivityFontName());
-		engineConfiguration.setLabelFontName(flowableProperties.getLabelFontName());
-		engineConfiguration.setAnnotationFontName(flowableProperties.getAnnotationFontName());
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/engine/constant/FlowEngineConstant.java b/src/main/java/org/springblade/flow/engine/constant/FlowEngineConstant.java
deleted file mode 100644
index bb660ab..0000000
--- a/src/main/java/org/springblade/flow/engine/constant/FlowEngineConstant.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.constant;
-
-/**
- * 流程常量.
- *
- * @author zhuangqian
- */
-public interface FlowEngineConstant {
-
-	String FLOWABLE_BASE_PACKAGES = "org.flowable.ui";
-
-	String SUFFIX = ".bpmn20.xml";
-
-	String ACTIVE = "active";
-
-	String SUSPEND = "suspend";
-
-	String STATUS_TODO = "todo";
-
-	String STATUS_CLAIM = "claim";
-
-	String STATUS_SEND = "send";
-
-	String STATUS_DONE = "done";
-
-	String STATUS_FINISHED = "finished";
-
-	String STATUS_UNFINISHED = "unfinished";
-
-	String STATUS_FINISH = "finish";
-
-	String START_EVENT = "startEvent";
-
-	String END_EVENT = "endEvent";
-
-}
diff --git a/src/main/java/org/springblade/flow/engine/controller/FlowFollowController.java b/src/main/java/org/springblade/flow/engine/controller/FlowFollowController.java
deleted file mode 100644
index 3693d50..0000000
--- a/src/main/java/org/springblade/flow/engine/controller/FlowFollowController.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.controller;
-
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import lombok.AllArgsConstructor;
-import org.springblade.core.launch.constant.AppConstant;
-import org.springblade.core.mp.support.Condition;
-import org.springblade.core.mp.support.Query;
-import org.springblade.core.secure.annotation.PreAuth;
-import org.springblade.core.tenant.annotation.NonDS;
-import org.springblade.core.tool.api.R;
-import org.springblade.core.tool.constant.RoleConstant;
-import org.springblade.flow.engine.entity.FlowExecution;
-import org.springblade.flow.engine.service.FlowEngineService;
-import org.springframework.web.bind.annotation.*;
-import springfox.documentation.annotations.ApiIgnore;
-
-/**
- * 流程状态控制器
- *
- * @author Chill
- */
-@NonDS
-@RestController
-@RequestMapping(AppConstant.APPLICATION_FLOW_NAME + "/follow")
-@AllArgsConstructor
-@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
-@ApiIgnore
-public class FlowFollowController {
-
-	private final FlowEngineService flowEngineService;
-
-	/**
-	 * 流程状态列表
-	 */
-	@GetMapping("list")
-	@ApiOperationSupport(order = 1)
-	@ApiOperation(value = "分页", notes = "传入notice")
-	public R<IPage<FlowExecution>> list(Query query, @ApiParam(value = "流程实例id") String processInstanceId, @ApiParam(value = "流程key") String processDefinitionKey) {
-		IPage<FlowExecution> pages = flowEngineService.selectFollowPage(Condition.getPage(query), processInstanceId, processDefinitionKey);
-		return R.data(pages);
-	}
-
-	/**
-	 * 删除流程实例
-	 */
-	@PostMapping("delete-process-instance")
-	@ApiOperationSupport(order = 2)
-	@ApiOperation(value = "删除", notes = "传入主键集合")
-	public R deleteProcessInstance(@ApiParam(value = "流程实例id") @RequestParam String processInstanceId, @ApiParam(value = "删除原因") @RequestParam String deleteReason) {
-		boolean temp = flowEngineService.deleteProcessInstance(processInstanceId, deleteReason);
-		return R.status(temp);
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/engine/controller/FlowManagerController.java b/src/main/java/org/springblade/flow/engine/controller/FlowManagerController.java
deleted file mode 100644
index 70b03bc..0000000
--- a/src/main/java/org/springblade/flow/engine/controller/FlowManagerController.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.controller;
-
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import lombok.AllArgsConstructor;
-import org.springblade.core.launch.constant.AppConstant;
-import org.springblade.core.mp.support.Condition;
-import org.springblade.core.mp.support.Query;
-import org.springblade.core.secure.annotation.PreAuth;
-import org.springblade.core.tenant.annotation.NonDS;
-import org.springblade.core.tool.api.R;
-import org.springblade.core.tool.constant.RoleConstant;
-import org.springblade.core.tool.support.Kv;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.flow.engine.constant.FlowEngineConstant;
-import org.springblade.flow.engine.entity.FlowProcess;
-import org.springblade.flow.engine.service.FlowEngineService;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-import springfox.documentation.annotations.ApiIgnore;
-
-import java.util.List;
-import java.util.Objects;
-
-/**
- * 流程管理接口
- *
- * @author Chill
- */
-@NonDS
-@RestController
-@RequestMapping(AppConstant.APPLICATION_FLOW_NAME + "/manager")
-@AllArgsConstructor
-@Api(value = "流程管理接口", tags = "流程管理接口")
-@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
-@ApiIgnore
-public class FlowManagerController {
-
-	private final FlowEngineService flowEngineService;
-
-	/**
-	 * 分页
-	 */
-	@GetMapping("list")
-	@ApiOperationSupport(order = 1)
-	@ApiOperation(value = "分页", notes = "传入流程类型")
-	public R<IPage<FlowProcess>> list(@ApiParam("流程类型") String category, Query query, @RequestParam(required = false, defaultValue = "1") Integer mode) {
-		IPage<FlowProcess> pages = flowEngineService.selectProcessPage(Condition.getPage(query), category, mode);
-		return R.data(pages);
-	}
-
-	/**
-	 * 变更流程状态
-	 *
-	 * @param state     状态
-	 * @param processId 流程id
-	 */
-	@PostMapping("change-state")
-	@ApiOperationSupport(order = 2)
-	@ApiOperation(value = "变更流程状态", notes = "传入state,processId")
-	public R changeState(@RequestParam String state, @RequestParam String processId) {
-		String msg = flowEngineService.changeState(state, processId);
-		return R.success(msg);
-	}
-
-	/**
-	 * 删除部署流程
-	 *
-	 * @param deploymentIds 部署流程id集合
-	 */
-	@PostMapping("delete-deployment")
-	@ApiOperationSupport(order = 3)
-	@ApiOperation(value = "删除部署流程", notes = "部署流程id集合")
-	public R deleteDeployment(String deploymentIds) {
-		return R.status(flowEngineService.deleteDeployment(deploymentIds));
-	}
-
-	/**
-	 * 检查流程文件格式
-	 *
-	 * @param file 流程文件
-	 */
-	@PostMapping("check-upload")
-	@ApiOperationSupport(order = 4)
-	@ApiOperation(value = "上传部署流程文件", notes = "传入文件")
-	public R checkUpload(@RequestParam MultipartFile file) {
-		boolean temp = Objects.requireNonNull(file.getOriginalFilename()).endsWith(FlowEngineConstant.SUFFIX);
-		return R.data(Kv.create().set("name", file.getOriginalFilename()).set("success", temp));
-	}
-
-	/**
-	 * 上传部署流程文件
-	 *
-	 * @param files    流程文件
-	 * @param category 类型
-	 */
-	@PostMapping("deploy-upload")
-	@ApiOperationSupport(order = 5)
-	@ApiOperation(value = "上传部署流程文件", notes = "传入文件")
-	public R deployUpload(@RequestParam List<MultipartFile> files,
-						  @RequestParam String category,
-						  @RequestParam(required = false, defaultValue = "") String tenantIds) {
-		return R.status(flowEngineService.deployUpload(files, category, Func.toStrList(tenantIds)));
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/engine/controller/FlowModelController.java b/src/main/java/org/springblade/flow/engine/controller/FlowModelController.java
deleted file mode 100644
index 73f31d9..0000000
--- a/src/main/java/org/springblade/flow/engine/controller/FlowModelController.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.controller;
-
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import lombok.AllArgsConstructor;
-import org.springblade.core.launch.constant.AppConstant;
-import org.springblade.core.mp.support.Condition;
-import org.springblade.core.mp.support.Query;
-import org.springblade.core.secure.annotation.PreAuth;
-import org.springblade.core.tenant.annotation.NonDS;
-import org.springblade.core.tool.api.R;
-import org.springblade.core.tool.constant.RoleConstant;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.flow.engine.entity.FlowModel;
-import org.springblade.flow.engine.service.FlowEngineService;
-import org.springframework.web.bind.annotation.*;
-import springfox.documentation.annotations.ApiIgnore;
-
-import java.util.Map;
-
-/**
- * 流程模型控制器
- *
- * @author Chill
- */
-@NonDS
-@RestController
-@RequestMapping(AppConstant.APPLICATION_FLOW_NAME + "/model")
-@AllArgsConstructor
-@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
-@ApiIgnore
-public class FlowModelController {
-
-	private final FlowEngineService flowEngineService;
-
-	/**
-	 * 分页
-	 */
-	@GetMapping("/list")
-	@ApiImplicitParams({
-		@ApiImplicitParam(name = "modelKey", value = "模型标识", paramType = "query", dataType = "string"),
-		@ApiImplicitParam(name = "name", value = "模型名称", paramType = "query", dataType = "string")
-	})
-	@ApiOperationSupport(order = 1)
-	@ApiOperation(value = "分页", notes = "传入notice")
-	public R<IPage<FlowModel>> list(@ApiIgnore @RequestParam Map<String, Object> flow, Query query) {
-		IPage<FlowModel> pages = flowEngineService.page(Condition.getPage(query), Condition.getQueryWrapper(flow, FlowModel.class)
-			.select("id,model_key modelKey,name,description,version,created,last_updated lastUpdated")
-			.orderByDesc("last_updated"));
-		return R.data(pages);
-	}
-
-	/**
-	 * 删除
-	 */
-	@PostMapping("/remove")
-	@ApiOperationSupport(order = 2)
-	@ApiOperation(value = "删除", notes = "传入主键集合")
-	public R remove(@ApiParam(value = "主键集合") @RequestParam String ids) {
-		boolean temp = flowEngineService.removeByIds(Func.toStrList(ids));
-		return R.status(temp);
-	}
-
-	/**
-	 * 部署
-	 */
-	@PostMapping("/deploy")
-	@ApiOperationSupport(order = 3)
-	@ApiOperation(value = "部署", notes = "传入模型id和分类")
-	public R deploy(@ApiParam(value = "模型id") @RequestParam String modelId,
-					@ApiParam(value = "工作流分类") @RequestParam String category,
-					@ApiParam(value = "租户ID") @RequestParam(required = false, defaultValue = "") String tenantIds) {
-		boolean temp = flowEngineService.deployModel(modelId, category, Func.toStrList(tenantIds));
-		return R.status(temp);
-	}
-
-	@PostMapping("submit")
-	@ApiOperationSupport(order = 4)
-	@ApiOperation(value = "保存/编辑")
-	@ApiImplicitParams({
-		@ApiImplicitParam(name = "id", value = "模型id"),
-		@ApiImplicitParam(name = "name", value = "模型名称", required = true),
-		@ApiImplicitParam(name = "modelKey", value = "模型key", required = true),
-		@ApiImplicitParam(name = "description", value = "模型描述"),
-		@ApiImplicitParam(name = "xml", value = "模型xml", required = true),
-	})
-	public R<FlowModel> submit(@RequestBody @ApiIgnore FlowModel model) {
-		return R.data(flowEngineService.submitModel(model));
-	}
-
-	@GetMapping("detail")
-	@ApiOperation(value = "详情")
-	@ApiOperationSupport(order = 5)
-	@ApiImplicitParams({
-		@ApiImplicitParam(name = "id", value = "模型id", required = true),
-	})
-	public R<FlowModel> detail(String id) {
-		return R.data(flowEngineService.getById(id));
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/engine/controller/FlowProcessController.java b/src/main/java/org/springblade/flow/engine/controller/FlowProcessController.java
deleted file mode 100644
index 616ba67..0000000
--- a/src/main/java/org/springblade/flow/engine/controller/FlowProcessController.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.controller;
-
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springblade.core.launch.constant.AppConstant;
-import org.springblade.core.tenant.annotation.NonDS;
-import org.springblade.core.tool.api.R;
-import org.springblade.flow.core.entity.BladeFlow;
-import org.springblade.flow.engine.service.FlowEngineService;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-import springfox.documentation.annotations.ApiIgnore;
-
-import javax.servlet.http.HttpServletResponse;
-import java.util.List;
-
-/**
- * 流程通用控制器
- *
- * @author Chill
- */
-@NonDS
-@Slf4j
-@RestController
-@AllArgsConstructor
-@RequestMapping(AppConstant.APPLICATION_FLOW_NAME + "/process")
-@ApiIgnore
-public class FlowProcessController {
-
-	private static final String IMAGE_NAME = "image";
-	private final FlowEngineService flowEngineService;
-
-	/**
-	 * 获取流转历史列表
-	 *
-	 * @param processInstanceId 流程实例id
-	 * @param startActivityId   开始节点id
-	 * @param endActivityId     结束节点id
-	 */
-	@GetMapping(value = "history-flow-list")
-	public R<List<BladeFlow>> historyFlowList(@RequestParam String processInstanceId, String startActivityId, String endActivityId) {
-		return R.data(flowEngineService.historyFlowList(processInstanceId, startActivityId, endActivityId));
-	}
-
-	/**
-	 * 流程节点进程图
-	 *
-	 * @param processDefinitionId 流程id
-	 * @param processInstanceId 流程实例id
-	 */
-	@GetMapping(value = "model-view")
-	public R modelView(String processDefinitionId, String processInstanceId) {
-		return R.data(flowEngineService.modelView(processDefinitionId, processInstanceId));
-	}
-
-	/**
-	 * 流程节点进程图
-	 *
-	 * @param processInstanceId   流程实例id
-	 * @param httpServletResponse http响应
-	 */
-	@GetMapping(value = "diagram-view")
-	public void diagramView(String processInstanceId, HttpServletResponse httpServletResponse) {
-		flowEngineService.diagramView(processInstanceId, httpServletResponse);
-	}
-
-	/**
-	 * 流程图展示
-	 *
-	 * @param processDefinitionId 流程id
-	 * @param processInstanceId   实例id
-	 * @param resourceType        资源类型
-	 * @param response            响应
-	 */
-	@GetMapping("resource-view")
-	public void resourceView(@RequestParam String processDefinitionId, String processInstanceId, @RequestParam(defaultValue = IMAGE_NAME) String resourceType, HttpServletResponse response) {
-		flowEngineService.resourceView(processDefinitionId, processInstanceId, resourceType, response);
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/engine/entity/FlowExecution.java b/src/main/java/org/springblade/flow/engine/entity/FlowExecution.java
deleted file mode 100644
index f8ed862..0000000
--- a/src/main/java/org/springblade/flow/engine/entity/FlowExecution.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.entity;
-
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * 运行实体类
- *
- * @author Chill
- */
-@Data
-public class FlowExecution implements Serializable {
-
-	private static final long serialVersionUID = 1L;
-
-	private String id;
-	private String name;
-	private String startUserId;
-	private String startUser;
-	private Date startTime;
-	private String taskDefinitionId;
-	private String taskDefinitionKey;
-	private String category;
-	private String categoryName;
-	private String processInstanceId;
-	private String processDefinitionId;
-	private String processDefinitionKey;
-	private String activityId;
-	private int suspensionState;
-	private String executionId;
-
-}
diff --git a/src/main/java/org/springblade/flow/engine/entity/FlowModel.java b/src/main/java/org/springblade/flow/engine/entity/FlowModel.java
deleted file mode 100644
index b37109a..0000000
--- a/src/main/java/org/springblade/flow/engine/entity/FlowModel.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.entity;
-
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * 流程模型
- *
- * @author Chill
- */
-@Data
-@TableName("ACT_DE_MODEL")
-public class FlowModel implements Serializable {
-
-	private static final long serialVersionUID = 1L;
-
-	public static final int MODEL_TYPE_BPMN = 0;
-	public static final int MODEL_TYPE_FORM = 2;
-	public static final int MODEL_TYPE_APP = 3;
-	public static final int MODEL_TYPE_DECISION_TABLE = 4;
-	public static final int MODEL_TYPE_CMMN = 5;
-
-	private String id;
-	private String name;
-	private String modelKey;
-	private String description;
-	private Date created;
-	private Date lastUpdated;
-	private String createdBy;
-	private String lastUpdatedBy;
-	private Integer version;
-	private String modelEditorJson;
-	private String modelComment;
-	private Integer modelType;
-	private String tenantId;
-	private byte[] thumbnail;
-	private String modelEditorXml;
-
-}
diff --git a/src/main/java/org/springblade/flow/engine/entity/FlowProcess.java b/src/main/java/org/springblade/flow/engine/entity/FlowProcess.java
deleted file mode 100644
index f9df6d9..0000000
--- a/src/main/java/org/springblade/flow/engine/entity/FlowProcess.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.entity;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntityImpl;
-import org.springblade.flow.engine.utils.FlowCache;
-
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * FlowProcess
- *
- * @author Chill
- */
-@Data
-@NoArgsConstructor
-public class FlowProcess implements Serializable {
-
-	private String id;
-	private String tenantId;
-	private String name;
-	private String key;
-	private String category;
-	private String categoryName;
-	private Integer version;
-	private String deploymentId;
-	private String resourceName;
-	private String diagramResourceName;
-	private Integer suspensionState;
-	private Date deploymentTime;
-
-	public FlowProcess(ProcessDefinitionEntityImpl entity) {
-		if (entity != null) {
-			this.id = entity.getId();
-			this.tenantId = entity.getTenantId();
-			this.name = entity.getName();
-			this.key = entity.getKey();
-			this.category = entity.getCategory();
-			this.categoryName = FlowCache.getCategoryName(entity.getCategory());
-			this.version = entity.getVersion();
-			this.deploymentId = entity.getDeploymentId();
-			this.resourceName = entity.getResourceName();
-			this.diagramResourceName = entity.getDiagramResourceName();
-			this.suspensionState = entity.getSuspensionState();
-		}
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/engine/mapper/FlowMapper.java b/src/main/java/org/springblade/flow/engine/mapper/FlowMapper.java
deleted file mode 100644
index 681b385..0000000
--- a/src/main/java/org/springblade/flow/engine/mapper/FlowMapper.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import org.springblade.flow.engine.entity.FlowModel;
-
-import java.util.List;
-
-/**
- * FlowMapper.
- *
- * @author Chill
- */
-public interface FlowMapper extends BaseMapper<FlowModel> {
-
-	/**
-	 * 自定义分页
-	 * @param page
-	 * @param flowModel
-	 * @return
-	 */
-	List<FlowModel> selectFlowPage(IPage page, FlowModel flowModel);
-
-	/**
-	 * 获取模型
-	 * @param parentModelId
-	 * @return
-	 */
-	List<FlowModel> findByParentModelId(String parentModelId);
-}
diff --git a/src/main/java/org/springblade/flow/engine/mapper/FlowMapper.xml b/src/main/java/org/springblade/flow/engine/mapper/FlowMapper.xml
deleted file mode 100644
index a7af970..0000000
--- a/src/main/java/org/springblade/flow/engine/mapper/FlowMapper.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.springblade.flow.engine.mapper.FlowMapper">
-
-    <!-- 通用查询映射结果 -->
-    <resultMap id="flowModelResultMap" type="org.springblade.flow.engine.entity.FlowModel">
-        <result column="id" property="id"/>
-        <result column="name" property="name"/>
-        <result column="model_key" property="modelKey"/>
-        <result column="description" property="description"/>
-        <result column="model_comment" property="modelComment"/>
-        <result column="created" property="created"/>
-        <result column="created_by" property="createdBy"/>
-        <result column="last_updated" property="lastUpdated"/>
-        <result column="last_updated_by" property="lastUpdatedBy"/>
-        <result column="version" property="version"/>
-        <result column="model_editor_json" property="modelEditorJson"/>
-        <result column="thumbnail" property="thumbnail"/>
-        <result column="model_type" property="modelType"/>
-        <result column="tenant_id" property="tenantId"/>
-    </resultMap>
-
-    <select id="selectFlowPage" resultMap="flowModelResultMap">
-        SELECT
-            a.id,
-            a.name,
-            a.model_key,
-            a.description,
-            a.model_comment,
-            a.created,
-            a.created_by,
-            a.last_updated,
-            a.last_updated_by,
-            a.version,
-            a.model_editor_json,
-            a.thumbnail,
-            a.model_type,
-            a.tenant_id
-        FROM
-            ACT_DE_MODEL a
-        WHERE
-            1 = 1
-        ORDER BY
-            a.created DESC
-    </select>
-
-    <select id="findByParentModelId" parameterType="string" resultMap="flowModelResultMap">
-        select model.* from ACT_DE_MODEL_RELATION modelrelation
-                                inner join ACT_DE_MODEL model on modelrelation.model_id = model.id
-        where modelrelation.parent_model_id = #{_parameter}
-    </select>
-
-</mapper>
diff --git a/src/main/java/org/springblade/flow/engine/service/FlowEngineService.java b/src/main/java/org/springblade/flow/engine/service/FlowEngineService.java
deleted file mode 100644
index 19a2929..0000000
--- a/src/main/java/org/springblade/flow/engine/service/FlowEngineService.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.service;
-
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.service.IService;
-import org.springblade.flow.core.entity.BladeFlow;
-import org.springblade.flow.engine.entity.FlowExecution;
-import org.springblade.flow.engine.entity.FlowModel;
-import org.springblade.flow.engine.entity.FlowProcess;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.http.HttpServletResponse;
-import java.util.List;
-import java.util.Map;
-
-/**
- * FlowEngineService
- *
- * @author Chill
- */
-public interface FlowEngineService extends IService<FlowModel> {
-
-	/**
-	 * 自定义分页
-	 *
-	 * @param page      分页工具
-	 * @param flowModel 流程模型
-	 * @return
-	 */
-	IPage<FlowModel> selectFlowPage(IPage<FlowModel> page, FlowModel flowModel);
-
-	/**
-	 * 流程管理列表
-	 *
-	 * @param page     分页工具
-	 * @param category 分类
-	 * @param mode     形态
-	 * @return
-	 */
-	IPage<FlowProcess> selectProcessPage(IPage<FlowProcess> page, String category, Integer mode);
-
-	/**
-	 * 流程管理列表
-	 *
-	 * @param page                 分页工具
-	 * @param processInstanceId    流程实例id
-	 * @param processDefinitionKey 流程key
-	 * @return
-	 */
-	IPage<FlowExecution> selectFollowPage(IPage<FlowExecution> page, String processInstanceId, String processDefinitionKey);
-
-	/**
-	 * 获取流转历史列表
-	 *
-	 * @param processInstanceId 流程实例id
-	 * @param startActivityId   开始节点id
-	 * @param endActivityId     结束节点id
-	 * @return
-	 */
-	List<BladeFlow> historyFlowList(String processInstanceId, String startActivityId, String endActivityId);
-
-	/**
-	 * 变更流程状态
-	 *
-	 * @param state     状态
-	 * @param processId 流程ID
-	 * @return
-	 */
-	String changeState(String state, String processId);
-
-	/**
-	 * 删除部署流程
-	 *
-	 * @param deploymentIds 部署流程id集合
-	 * @return
-	 */
-	boolean deleteDeployment(String deploymentIds);
-
-	/**
-	 * 上传部署流程
-	 *
-	 * @param files        流程配置文件
-	 * @param category     流程分类
-	 * @param tenantIdList 租户id集合
-	 * @return
-	 */
-	boolean deployUpload(List<MultipartFile> files, String category, List<String> tenantIdList);
-
-	/**
-	 * 部署流程
-	 *
-	 * @param modelId      模型id
-	 * @param category     分类
-	 * @param tenantIdList 租户id集合
-	 * @return
-	 */
-	boolean deployModel(String modelId, String category, List<String> tenantIdList);
-
-	/**
-	 * 删除流程实例
-	 *
-	 * @param processInstanceId 流程实例id
-	 * @param deleteReason      删除原因
-	 * @return
-	 */
-	boolean deleteProcessInstance(String processInstanceId, String deleteReason);
-
-	/**
-	 * 保存/更新模型
-	 *
-	 * @param model 模型
-	 * @return 模型
-	 */
-	FlowModel submitModel(FlowModel model);
-
-	/**
-	 * 流程节点进程图
-	 *
-	 * @param processDefinitionId
-	 * @param processInstanceId
-	 * @return
-	 */
-	Map<String, Object> modelView(String processDefinitionId, String processInstanceId);
-
-	/**
-	 * 流程节点进程图
-	 *
-	 * @param processInstanceId
-	 * @param httpServletResponse
-	 */
-	void diagramView(String processInstanceId, HttpServletResponse httpServletResponse);
-
-	/**
-	 * 流程图展示
-	 *
-	 * @param processDefinitionId
-	 * @param processInstanceId
-	 * @param resourceType
-	 * @param response
-	 */
-	void resourceView(String processDefinitionId, String processInstanceId, String resourceType, HttpServletResponse response);
-
-	/**
-	 * 获取XML
-	 *
-	 * @param model
-	 * @return
-	 */
-	byte[] getModelEditorXML(FlowModel model);
-}
diff --git a/src/main/java/org/springblade/flow/engine/service/impl/FlowEngineServiceImpl.java b/src/main/java/org/springblade/flow/engine/service/impl/FlowEngineServiceImpl.java
deleted file mode 100644
index c72948f..0000000
--- a/src/main/java/org/springblade/flow/engine/service/impl/FlowEngineServiceImpl.java
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.service.impl;
-
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.flowable.bpmn.converter.BpmnXMLConverter;
-import org.flowable.bpmn.model.BpmnModel;
-import org.flowable.bpmn.model.Process;
-import org.flowable.common.engine.impl.util.IoUtil;
-import org.flowable.common.engine.impl.util.io.StringStreamSource;
-import org.flowable.editor.language.json.converter.BpmnJsonConverter;
-import org.flowable.engine.*;
-import org.flowable.engine.history.HistoricActivityInstance;
-import org.flowable.engine.history.HistoricProcessInstance;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
-import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntityImpl;
-import org.flowable.engine.repository.Deployment;
-import org.flowable.engine.repository.ProcessDefinition;
-import org.flowable.engine.repository.ProcessDefinitionQuery;
-import org.flowable.engine.runtime.ProcessInstance;
-import org.flowable.engine.runtime.ProcessInstanceQuery;
-import org.flowable.engine.task.Comment;
-import org.flowable.image.ProcessDiagramGenerator;
-import org.springblade.common.cache.UserCache;
-import org.springblade.core.log.exception.ServiceException;
-import org.springblade.core.secure.utils.AuthUtil;
-import org.springblade.core.tool.utils.DateUtil;
-import org.springblade.core.tool.utils.FileUtil;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.StringUtil;
-import org.springblade.flow.core.entity.BladeFlow;
-import org.springblade.flow.core.enums.FlowModeEnum;
-import org.springblade.flow.core.utils.TaskUtil;
-import org.springblade.flow.engine.constant.FlowEngineConstant;
-import org.springblade.flow.engine.entity.FlowExecution;
-import org.springblade.flow.engine.entity.FlowModel;
-import org.springblade.flow.engine.entity.FlowProcess;
-import org.springblade.flow.engine.mapper.FlowMapper;
-import org.springblade.flow.engine.service.FlowEngineService;
-import org.springblade.flow.engine.utils.FlowCache;
-import org.springblade.modules.system.entity.User;
-import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.*;
-
-/**
- * 工作流服务实现类
- *
- * @author Chill
- */
-@Slf4j
-@Service
-@AllArgsConstructor
-public class FlowEngineServiceImpl extends ServiceImpl<FlowMapper, FlowModel> implements FlowEngineService {
-	private static final String ALREADY_IN_STATE = "already in state";
-	private static final String USR_TASK = "userTask";
-	private static final String IMAGE_NAME = "image";
-	private static final String XML_NAME = "xml";
-	private static final Integer INT_1024 = 1024;
-	private static final BpmnJsonConverter BPMN_JSON_CONVERTER = new BpmnJsonConverter();
-	private static final BpmnXMLConverter BPMN_XML_CONVERTER = new BpmnXMLConverter();
-	private final ObjectMapper objectMapper;
-	private final RepositoryService repositoryService;
-	private final RuntimeService runtimeService;
-	private final HistoryService historyService;
-	private final TaskService taskService;
-	private final ProcessEngine processEngine;
-
-	@Override
-	public IPage<FlowModel> selectFlowPage(IPage<FlowModel> page, FlowModel flowModel) {
-		return page.setRecords(baseMapper.selectFlowPage(page, flowModel));
-	}
-
-	@Override
-	public IPage<FlowProcess> selectProcessPage(IPage<FlowProcess> page, String category, Integer mode) {
-		ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery().latestVersion().orderByProcessDefinitionKey().asc();
-		// 通用流程
-		if (mode == FlowModeEnum.COMMON.getMode()) {
-			processDefinitionQuery.processDefinitionWithoutTenantId();
-		}
-		// 定制流程
-		else if (!AuthUtil.isAdministrator()) {
-			processDefinitionQuery.processDefinitionTenantId(AuthUtil.getTenantId());
-		}
-		if (StringUtils.isNotEmpty(category)) {
-			processDefinitionQuery.processDefinitionCategory(category);
-		}
-		List<ProcessDefinition> processDefinitionList = processDefinitionQuery.listPage(Func.toInt((page.getCurrent() - 1) * page.getSize()), Func.toInt(page.getSize()));
-		List<FlowProcess> flowProcessList = new ArrayList<>();
-		processDefinitionList.forEach(processDefinition -> {
-			String deploymentId = processDefinition.getDeploymentId();
-			Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
-			FlowProcess flowProcess = new FlowProcess((ProcessDefinitionEntityImpl) processDefinition);
-			flowProcess.setDeploymentTime(deployment.getDeploymentTime());
-			flowProcessList.add(flowProcess);
-		});
-		page.setTotal(processDefinitionQuery.count());
-		page.setRecords(flowProcessList);
-		return page;
-	}
-
-	@Override
-	public IPage<FlowExecution> selectFollowPage(IPage<FlowExecution> page, String processInstanceId, String processDefinitionKey) {
-		ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
-		if (StringUtil.isNotBlank(processInstanceId)) {
-			processInstanceQuery.processInstanceId(processInstanceId);
-		}
-		if (StringUtil.isNotBlank(processDefinitionKey)) {
-			processInstanceQuery.processDefinitionKey(processDefinitionKey);
-		}
-		List<FlowExecution> flowList = new ArrayList<>();
-		List<ProcessInstance> procInsList = processInstanceQuery.listPage(Func.toInt((page.getCurrent() - 1) * page.getSize()), Func.toInt(page.getSize()));
-		procInsList.forEach(processInstance -> {
-			ExecutionEntityImpl execution = (ExecutionEntityImpl) processInstance;
-			FlowExecution flowExecution = new FlowExecution();
-			flowExecution.setId(execution.getId());
-			flowExecution.setName(execution.getName());
-			flowExecution.setStartUserId(execution.getStartUserId());
-			User taskUser = UserCache.getUserByTaskUser(execution.getStartUserId());
-			if (taskUser != null) {
-				flowExecution.setStartUser(taskUser.getName());
-			}
-			flowExecution.setStartTime(execution.getStartTime());
-			flowExecution.setExecutionId(execution.getId());
-			flowExecution.setProcessInstanceId(execution.getProcessInstanceId());
-			flowExecution.setProcessDefinitionId(execution.getProcessDefinitionId());
-			flowExecution.setProcessDefinitionKey(execution.getProcessDefinitionKey());
-			flowExecution.setSuspensionState(execution.getSuspensionState());
-			FlowProcess processDefinition = FlowCache.getProcessDefinition(execution.getProcessDefinitionId());
-			flowExecution.setCategory(processDefinition.getCategory());
-			flowExecution.setCategoryName(FlowCache.getCategoryName(processDefinition.getCategory()));
-			flowList.add(flowExecution);
-		});
-		page.setTotal(processInstanceQuery.count());
-		page.setRecords(flowList);
-		return page;
-	}
-
-	@Override
-	public List<BladeFlow> historyFlowList(String processInstanceId, String startActivityId, String endActivityId) {
-		List<BladeFlow> flowList = new LinkedList<>();
-		List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().orderByHistoricActivityInstanceEndTime().asc().list();
-		boolean start = false;
-		Map<String, Integer> activityMap = new HashMap<>(16);
-		for (int i = 0; i < historicActivityInstanceList.size(); i++) {
-			HistoricActivityInstance historicActivityInstance = historicActivityInstanceList.get(i);
-			// 过滤开始节点前的节点
-			if (StringUtil.isNotBlank(startActivityId) && startActivityId.equals(historicActivityInstance.getActivityId())) {
-				start = true;
-			}
-			if (StringUtil.isNotBlank(startActivityId) && !start) {
-				continue;
-			}
-			// 显示开始节点和结束节点,并且执行人不为空的任务
-			if (StringUtils.equals(USR_TASK, historicActivityInstance.getActivityType())
-				|| FlowEngineConstant.START_EVENT.equals(historicActivityInstance.getActivityType())
-				|| FlowEngineConstant.END_EVENT.equals(historicActivityInstance.getActivityType())) {
-				// 给节点增加序号
-				Integer activityNum = activityMap.get(historicActivityInstance.getActivityId());
-				if (activityNum == null) {
-					activityMap.put(historicActivityInstance.getActivityId(), activityMap.size());
-				}
-				BladeFlow flow = new BladeFlow();
-				flow.setHistoryActivityId(historicActivityInstance.getActivityId());
-				flow.setHistoryActivityName(historicActivityInstance.getActivityName());
-				flow.setCreateTime(historicActivityInstance.getStartTime());
-				flow.setEndTime(historicActivityInstance.getEndTime());
-				String durationTime = DateUtil.secondToTime(Func.toLong(historicActivityInstance.getDurationInMillis(), 0L) / 1000);
-				flow.setHistoryActivityDurationTime(durationTime);
-				// 获取流程发起人名称
-				if (FlowEngineConstant.START_EVENT.equals(historicActivityInstance.getActivityType())) {
-					List<HistoricProcessInstance> processInstanceList = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).orderByProcessInstanceStartTime().asc().list();
-					if (processInstanceList.size() > 0) {
-						if (StringUtil.isNotBlank(processInstanceList.get(0).getStartUserId())) {
-							String taskUser = processInstanceList.get(0).getStartUserId();
-							User user = UserCache.getUser(TaskUtil.getUserId(taskUser));
-							if (user != null) {
-								flow.setAssignee(historicActivityInstance.getAssignee());
-								flow.setAssigneeName(user.getName());
-							}
-						}
-					}
-				}
-				// 获取任务执行人名称
-				if (StringUtil.isNotBlank(historicActivityInstance.getAssignee())) {
-					User user = UserCache.getUser(TaskUtil.getUserId(historicActivityInstance.getAssignee()));
-					if (user != null) {
-						flow.setAssignee(historicActivityInstance.getAssignee());
-						flow.setAssigneeName(user.getName());
-					}
-				}
-				// 获取意见评论内容
-				if (StringUtil.isNotBlank(historicActivityInstance.getTaskId())) {
-					List<Comment> commentList = taskService.getTaskComments(historicActivityInstance.getTaskId());
-					if (commentList.size() > 0) {
-						flow.setComment(commentList.get(0).getFullMessage());
-					}
-				}
-				flowList.add(flow);
-			}
-			// 过滤结束节点后的节点
-			if (StringUtils.isNotBlank(endActivityId) && endActivityId.equals(historicActivityInstance.getActivityId())) {
-				boolean temp = false;
-				Integer activityNum = activityMap.get(historicActivityInstance.getActivityId());
-				// 该活动节点,后续节点是否在结束节点之前,在后续节点中是否存在
-				for (int j = i + 1; j < historicActivityInstanceList.size(); j++) {
-					HistoricActivityInstance hi = historicActivityInstanceList.get(j);
-					Integer activityNumA = activityMap.get(hi.getActivityId());
-					boolean numberTemp = activityNumA != null && activityNumA < activityNum;
-					boolean equalsTemp = StringUtils.equals(hi.getActivityId(), historicActivityInstance.getActivityId());
-					if (numberTemp || equalsTemp) {
-						temp = true;
-					}
-				}
-				if (!temp) {
-					break;
-				}
-			}
-		}
-		return flowList;
-	}
-
-	@Override
-	public String changeState(String state, String processId) {
-		try {
-			if (state.equals(FlowEngineConstant.ACTIVE)) {
-				repositoryService.activateProcessDefinitionById(processId, true, null);
-				return StringUtil.format("激活ID为 [{}] 的流程成功", processId);
-			} else if (state.equals(FlowEngineConstant.SUSPEND)) {
-				repositoryService.suspendProcessDefinitionById(processId, true, null);
-				return StringUtil.format("挂起ID为 [{}] 的流程成功", processId);
-			} else {
-				return "暂无流程变更";
-			}
-		} catch (Exception e) {
-			if (e.getMessage().contains(ALREADY_IN_STATE)) {
-				return StringUtil.format("ID为 [{}] 的流程已是此状态,无需操作", processId);
-			}
-			return e.getMessage();
-		}
-	}
-
-	@Override
-	public boolean deleteDeployment(String deploymentIds) {
-		Func.toStrList(deploymentIds).forEach(deploymentId -> repositoryService.deleteDeployment(deploymentId, true));
-		return true;
-	}
-
-	@Override
-	public boolean deployUpload(List<MultipartFile> files, String category, List<String> tenantIdList) {
-		files.forEach(file -> {
-			try {
-				String fileName = file.getOriginalFilename();
-				InputStream fileInputStream = file.getInputStream();
-				byte[] bytes = FileUtil.copyToByteArray(fileInputStream);
-				if (Func.isNotEmpty(tenantIdList)) {
-					tenantIdList.forEach(tenantId -> {
-						Deployment deployment = repositoryService.createDeployment().addBytes(fileName, bytes).tenantId(tenantId).deploy();
-						deploy(deployment, category);
-					});
-				} else {
-					Deployment deployment = repositoryService.createDeployment().addBytes(fileName, bytes).deploy();
-					deploy(deployment, category);
-				}
-			} catch (IOException e) {
-				e.printStackTrace();
-			}
-		});
-		return true;
-	}
-
-	@Override
-	public boolean deployModel(String modelId, String category, List<String> tenantIdList) {
-		FlowModel model = this.getById(modelId);
-		if (model == null) {
-			throw new ServiceException("未找到模型 id: " + modelId);
-		}
-		byte[] bytes = getBpmnXML(model);
-		String processName = model.getName();
-		if (!StringUtil.endsWithIgnoreCase(processName, FlowEngineConstant.SUFFIX)) {
-			processName += FlowEngineConstant.SUFFIX;
-		}
-		String finalProcessName = processName;
-		if (Func.isNotEmpty(tenantIdList)) {
-			tenantIdList.forEach(tenantId -> {
-				Deployment deployment = repositoryService.createDeployment().addBytes(finalProcessName, bytes).name(model.getName()).key(model.getModelKey()).tenantId(tenantId).deploy();
-				deploy(deployment, category);
-			});
-		} else {
-			Deployment deployment = repositoryService.createDeployment().addBytes(finalProcessName, bytes).name(model.getName()).key(model.getModelKey()).deploy();
-			deploy(deployment, category);
-		}
-		return true;
-	}
-
-	@Override
-	public boolean deleteProcessInstance(String processInstanceId, String deleteReason) {
-		runtimeService.deleteProcessInstance(processInstanceId, deleteReason);
-		return true;
-	}
-
-	private void deploy(Deployment deployment, String category) {
-		log.debug("流程部署--------deploy:  " + deployment + "  分类---------->" + category);
-		List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).list();
-		StringBuilder logBuilder = new StringBuilder(500);
-		List<Object> logArgs = new ArrayList<>();
-		// 设置流程分类
-		for (ProcessDefinition processDefinition : list) {
-			if (StringUtil.isNotBlank(category)) {
-				repositoryService.setProcessDefinitionCategory(processDefinition.getId(), category);
-			}
-			logBuilder.append("部署成功,流程ID={} \n");
-			logArgs.add(processDefinition.getId());
-		}
-		if (list.size() == 0) {
-			throw new ServiceException("部署失败,未找到流程");
-		} else {
-			log.info(logBuilder.toString(), logArgs.toArray());
-		}
-	}
-
-	@Override
-	public FlowModel submitModel(FlowModel model) {
-		FlowModel flowModel = new FlowModel();
-		flowModel.setId(model.getId());
-		flowModel.setVersion(Func.toInt(model.getVersion(), 0) + 1);
-		flowModel.setName(model.getName());
-		flowModel.setModelKey(model.getModelKey());
-		flowModel.setModelType(FlowModel.MODEL_TYPE_BPMN);
-		flowModel.setCreatedBy(TaskUtil.getTaskUser());
-		flowModel.setDescription(model.getDescription());
-		flowModel.setLastUpdated(Calendar.getInstance().getTime());
-		flowModel.setLastUpdatedBy(TaskUtil.getTaskUser());
-		flowModel.setTenantId(AuthUtil.getTenantId());
-		flowModel.setModelEditorXml(model.getModelEditorXml());
-		if (StringUtil.isBlank(model.getId())) {
-			flowModel.setCreated(Calendar.getInstance().getTime());
-		}
-		if (StringUtil.isNotBlank(model.getModelEditorXml())) {
-			flowModel.setModelEditorJson(getBpmnJson(model.getModelEditorXml()));
-		}
-		this.saveOrUpdate(flowModel);
-		return flowModel;
-	}
-
-	@Override
-	public Map<String, Object> modelView(String processDefinitionId, String processInstanceId) {
-		Map<String, Object> result = new HashMap<>();
-		// 节点标记
-		if (StringUtil.isNotBlank(processInstanceId)) {
-			result.put("flow", this.historyFlowList(processInstanceId, null, null));
-			HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
-				.processInstanceId(processInstanceId)
-				.singleResult();
-			processDefinitionId = processInstance.getProcessDefinitionId();
-		}
-		BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
-		// 流程图展示
-		result.put("xml", new String(new BpmnXMLConverter().convertToXML(bpmnModel)));
-		return result;
-	}
-
-	@Override
-	public void diagramView(String processInstanceId, HttpServletResponse httpServletResponse) {
-		// 获得当前活动的节点
-		String processDefinitionId;
-		// 如果流程已经结束,则得到结束节点
-		if (this.isFinished(processInstanceId)) {
-			HistoricProcessInstance pi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
-			processDefinitionId = pi.getProcessDefinitionId();
-		} else {
-			// 如果流程没有结束,则取当前活动节点
-			// 根据流程实例ID获得当前处于活动状态的ActivityId合集
-			ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
-			processDefinitionId = pi.getProcessDefinitionId();
-		}
-		List<String> highLightedActivities = new ArrayList<>();
-
-		// 获得活动的节点
-		List<HistoricActivityInstance> highLightedActivityList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list();
-
-		for (HistoricActivityInstance tempActivity : highLightedActivityList) {
-			String activityId = tempActivity.getActivityId();
-			highLightedActivities.add(activityId);
-		}
-
-		List<String> flows = new ArrayList<>();
-		// 获取流程图
-		BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
-		ProcessEngineConfiguration engConf = processEngine.getProcessEngineConfiguration();
-
-		ProcessDiagramGenerator diagramGenerator = engConf.getProcessDiagramGenerator();
-		InputStream in = diagramGenerator.generateDiagram(bpmnModel, "bmp", highLightedActivities, flows, engConf.getActivityFontName(),
-			engConf.getLabelFontName(), engConf.getAnnotationFontName(), engConf.getClassLoader(), 1.0, true);
-		OutputStream out = null;
-		byte[] buf = new byte[1024];
-		int length;
-		try {
-			out = httpServletResponse.getOutputStream();
-			while ((length = in.read(buf)) != -1) {
-				out.write(buf, 0, length);
-			}
-		} catch (IOException e) {
-			log.error("操作异常", e);
-		} finally {
-			IoUtil.closeSilently(out);
-			IoUtil.closeSilently(in);
-		}
-	}
-
-	@Override
-	public void resourceView(String processDefinitionId, String processInstanceId, String resourceType, HttpServletResponse response) {
-		if (StringUtil.isAllBlank(processDefinitionId, processInstanceId)) {
-			return;
-		}
-		if (StringUtil.isBlank(processDefinitionId)) {
-			ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
-			processDefinitionId = processInstance.getProcessDefinitionId();
-		}
-		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
-		String resourceName = "";
-		if (resourceType.equals(IMAGE_NAME)) {
-			resourceName = processDefinition.getDiagramResourceName();
-		} else if (resourceType.equals(XML_NAME)) {
-			resourceName = processDefinition.getResourceName();
-		}
-		try {
-			InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
-			byte[] b = new byte[1024];
-			int len;
-			while ((len = resourceAsStream.read(b, 0, INT_1024)) != -1) {
-				response.getOutputStream().write(b, 0, len);
-			}
-		} catch (Exception exception) {
-			exception.printStackTrace();
-		}
-	}
-
-	@Override
-	public byte[] getModelEditorXML(FlowModel model) {
-		return getBpmnXML(model);
-	}
-
-	/**
-	 * 是否已完结
-	 *
-	 * @param processInstanceId 流程实例id
-	 * @return bool
-	 */
-	private boolean isFinished(String processInstanceId) {
-		return historyService.createHistoricProcessInstanceQuery().finished()
-			.processInstanceId(processInstanceId).count() > 0;
-	}
-
-
-	/**
-	 * xml转bpmn json
-	 *
-	 * @param xml xml
-	 * @return json
-	 */
-	private String getBpmnJson(String xml) {
-		return BPMN_JSON_CONVERTER.convertToJson(getBpmnModel(xml)).toString();
-	}
-
-	/**
-	 * xml转bpmnModel
-	 *
-	 * @param xml xml
-	 * @return bpmnModel
-	 */
-	private BpmnModel getBpmnModel(String xml) {
-		return BPMN_XML_CONVERTER.convertToBpmnModel(new StringStreamSource(xml), false, false);
-	}
-
-	private byte[] getBpmnXML(FlowModel model) {
-		BpmnModel bpmnModel = getBpmnModel(model);
-		return getBpmnXML(bpmnModel);
-	}
-
-	private byte[] getBpmnXML(BpmnModel bpmnModel) {
-		for (Process process : bpmnModel.getProcesses()) {
-			if (StringUtils.isNotEmpty(process.getId())) {
-				char firstCharacter = process.getId().charAt(0);
-				if (Character.isDigit(firstCharacter)) {
-					process.setId("a" + process.getId());
-				}
-			}
-		}
-		return BPMN_XML_CONVERTER.convertToXML(bpmnModel);
-	}
-
-	private BpmnModel getBpmnModel(FlowModel model) {
-		BpmnModel bpmnModel;
-		try {
-			Map<String, FlowModel> formMap = new HashMap<>(16);
-			Map<String, FlowModel> decisionTableMap = new HashMap<>(16);
-
-			List<FlowModel> referencedModels = baseMapper.findByParentModelId(model.getId());
-			for (FlowModel childModel : referencedModels) {
-				if (FlowModel.MODEL_TYPE_FORM == childModel.getModelType()) {
-					formMap.put(childModel.getId(), childModel);
-
-				} else if (FlowModel.MODEL_TYPE_DECISION_TABLE == childModel.getModelType()) {
-					decisionTableMap.put(childModel.getId(), childModel);
-				}
-			}
-			bpmnModel = getBpmnModel(model, formMap, decisionTableMap);
-		} catch (Exception e) {
-			log.error("Could not generate BPMN 2.0 model for {}", model.getId(), e);
-			throw new ServiceException("Could not generate BPMN 2.0 model");
-		}
-		return bpmnModel;
-	}
-
-	private BpmnModel getBpmnModel(FlowModel model, Map<String, FlowModel> formMap, Map<String, FlowModel> decisionTableMap) {
-		try {
-			ObjectNode editorJsonNode = (ObjectNode) objectMapper.readTree(model.getModelEditorJson());
-			Map<String, String> formKeyMap = new HashMap<>(16);
-			for (FlowModel formModel : formMap.values()) {
-				formKeyMap.put(formModel.getId(), formModel.getModelKey());
-			}
-			Map<String, String> decisionTableKeyMap = new HashMap<>(16);
-			for (FlowModel decisionTableModel : decisionTableMap.values()) {
-				decisionTableKeyMap.put(decisionTableModel.getId(), decisionTableModel.getModelKey());
-			}
-			return BPMN_JSON_CONVERTER.convertToBpmnModel(editorJsonNode, formKeyMap, decisionTableKeyMap);
-		} catch (Exception e) {
-			log.error("Could not generate BPMN 2.0 model for {}", model.getId(), e);
-			throw new ServiceException("Could not generate BPMN 2.0 model");
-		}
-	}
-
-}
diff --git a/src/main/java/org/springblade/flow/engine/utils/FlowCache.java b/src/main/java/org/springblade/flow/engine/utils/FlowCache.java
deleted file mode 100644
index bb23baf..0000000
--- a/src/main/java/org/springblade/flow/engine/utils/FlowCache.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.engine.utils;
-
-import org.flowable.engine.RepositoryService;
-import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntityImpl;
-import org.flowable.engine.repository.ProcessDefinition;
-import org.springblade.common.cache.DictCache;
-import org.springblade.core.cache.utils.CacheUtil;
-import org.springblade.core.tool.utils.BeanUtil;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.SpringUtil;
-import org.springblade.core.tool.utils.StringPool;
-import org.springblade.flow.engine.entity.FlowProcess;
-
-/**
- * 流程缓存
- *
- * @author Chill
- */
-public class FlowCache {
-
-	private static final String FLOW_CACHE = "flow:process";
-	private static final String FLOW_DEFINITION_ID = "definition:id";
-	private static RepositoryService repositoryService;
-
-	private static RepositoryService getRepositoryService() {
-		if (repositoryService == null) {
-			repositoryService = SpringUtil.getBean(RepositoryService.class);
-		}
-		return repositoryService;
-	}
-
-	/**
-	 * 获得流程定义对象
-	 *
-	 * @param processDefinitionId 流程对象id
-	 * @return
-	 */
-	public static FlowProcess getProcessDefinition(String processDefinitionId) {
-		return CacheUtil.get(FLOW_CACHE, FLOW_DEFINITION_ID, processDefinitionId, () -> {
-			ProcessDefinition processDefinition = getRepositoryService().createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
-			ProcessDefinitionEntityImpl processDefinitionEntity = BeanUtil.copy(processDefinition, ProcessDefinitionEntityImpl.class);
-			return new FlowProcess(processDefinitionEntity);
-		});
-	}
-
-	/**
-	 * 获取流程类型名
-	 *
-	 * @param category 流程类型
-	 * @return
-	 */
-	public static String getCategoryName(String category) {
-		if (Func.isEmpty(category)) {
-			return StringPool.EMPTY;
-		}
-		String[] categoryArr = category.split(StringPool.UNDERSCORE);
-		if (categoryArr.length <= 1) {
-			return StringPool.EMPTY;
-		} else {
-			return DictCache.getValue(category.split(StringPool.UNDERSCORE)[0], Func.toInt(category.split(StringPool.UNDERSCORE)[1]));
-		}
-	}
-
-}
diff --git a/src/main/java/org/springblade/modules/netty/business/entity/PoliceCarEquipment.java b/src/main/java/org/springblade/modules/netty/business/entity/PoliceCarEquipment.java
new file mode 100644
index 0000000..6f4e4dd
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/business/entity/PoliceCarEquipment.java
@@ -0,0 +1,104 @@
+package org.springblade.modules.netty.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 对接设备信息表 实体类
+ *
+ * @author zhongrj
+ * @since 2023-02-23
+ */
+@Data
+@TableName("sys_police_car_equipment")
+public class PoliceCarEquipment implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 主键id
+	 */
+	private Long id;
+
+	/**
+	 * 设备名称
+	 */
+	private String name;
+
+	/**
+	 * 设备编号
+	 */
+	private String code;
+
+	/**
+	 * 设备状态 0:离线  1:在线
+	 */
+	private Integer status;
+
+	/**
+	 * 终端编号
+	 */
+	private String terminalNumber;
+
+	/**
+	 * 经度
+	 */
+	private String longitude;
+
+	/**
+	 * 纬度
+	 */
+	private String latitude;
+
+	/**
+	 * 速度,单位 米/秒
+	 */
+	private String speed;
+
+	/**
+	 * 方向,以正北方向为 0 角度,顺时针方向偏转
+	 */
+	private String direction;
+
+	/**
+	 * 高程,单位:米
+	 */
+	private String elevation;
+
+	/**
+	 * 精度
+	 */
+	private String precisions;
+
+	/**
+	 * 日期
+	 */
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date receiveTime;
+
+	/**
+	 * 创建时间
+	 */
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date createTime;
+
+	/**
+	 * 更新时间
+	 */
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date updateTime;
+
+	/**
+	 * 说明
+	 */
+//	@ApiModelProperty(value = "说明")
+//	private String remark;
+}
diff --git a/src/main/java/org/springblade/modules/netty/business/entity/PoliceCarEquipmentRecord.java b/src/main/java/org/springblade/modules/netty/business/entity/PoliceCarEquipmentRecord.java
new file mode 100644
index 0000000..e79744a
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/business/entity/PoliceCarEquipmentRecord.java
@@ -0,0 +1,87 @@
+package org.springblade.modules.netty.business.entity;
+
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 对接设备信息记录表 实体类
+ *
+ * @author zhongrj
+ * @since 2023-02-23
+ */
+@Data
+@TableName("sys_police_car_equipment_record")
+public class PoliceCarEquipmentRecord implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 主键id
+	 */
+	private Long id;
+
+	/**
+	 * 设备id
+	 */
+	private Long policeCarEquipmentId;
+
+	/**
+	 * 设备状态 0:离线  1:在线
+	 */
+	private Integer status;
+
+	/**
+	 * 终端编号
+	 */
+	private String terminalNumber;
+
+	/**
+	 * 经度
+	 */
+	private String longitude;
+
+	/**
+	 * 纬度
+	 */
+	private String latitude;
+
+	/**
+	 * 速度,单位 米/秒
+	 */
+	private String speed;
+
+	/**
+	 * 方向,以正北方向为 0 角度,顺时针方向偏转
+	 */
+	private String direction;
+
+	/**
+	 * 高程,单位:米
+	 */
+	private String elevation;
+
+	/**
+	 * 精度
+	 */
+	private String precisions;
+
+	/**
+	 * 日期
+	 */
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date receiveTime;
+
+	/**
+	 * 创建时间
+	 */
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date createTime;
+}
diff --git a/src/main/java/org/springblade/modules/netty/business/mapper/PoliceCarEquipmentMapper.java b/src/main/java/org/springblade/modules/netty/business/mapper/PoliceCarEquipmentMapper.java
new file mode 100644
index 0000000..e6574fb
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/business/mapper/PoliceCarEquipmentMapper.java
@@ -0,0 +1,42 @@
+package org.springblade.modules.netty.business.mapper;
+
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.springblade.modules.netty.business.entity.PoliceCarEquipment;
+import org.springblade.modules.netty.business.entity.PoliceCarEquipmentRecord;
+
+/**
+ * 对讲设备mapper映射层
+ * @author zhongrj
+ * @date 2023-03-02
+ */
+@Mapper
+public interface PoliceCarEquipmentMapper {
+
+    /**
+     * 新增对讲设备数据
+     * @param policeCarEquipment
+     */
+    void saveTalkBackEquipment(PoliceCarEquipment policeCarEquipment);
+
+    /**
+     * 新增对讲设备历史数据
+     * @param policeCarEquipmentRecord
+     */
+    void saveTalkBackEquipmentRecord(PoliceCarEquipmentRecord policeCarEquipmentRecord);
+
+    /**
+     * 查询设备信息
+     * @param code
+     * @return
+     */
+	PoliceCarEquipment getTalkBackEquipment(@Param("code") String code);
+
+    /**
+     * 修改对讲设备信息
+     * @param policeCarEquipment
+     */
+    void updateTalkBackEquipment(PoliceCarEquipment policeCarEquipment);
+}
diff --git a/src/main/java/org/springblade/modules/netty/business/mapper/PoliceCarEquipmentMapper.xml b/src/main/java/org/springblade/modules/netty/business/mapper/PoliceCarEquipmentMapper.xml
new file mode 100644
index 0000000..a7865c4
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/business/mapper/PoliceCarEquipmentMapper.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.modules.netty.business.mapper.PoliceCarEquipmentMapper">
+
+    <!--新增对讲设备信息-->
+    <insert id="saveTalkBackEquipment" useGeneratedKeys="true" keyProperty="id">
+        insert into sys_police_car_equipment
+        (
+        name,code,status,terminal_number,longitude,latitude,
+        speed,direction,elevation,precisions,receive_time,create_time,update_time
+        )
+        values
+        (
+        #{name},#{code},#{status},#{terminalNumber},#{longitude},#{latitude},
+        #{speed},#{direction},#{elevation},#{precisions},#{receiveTime},#{createTime},#{updateTime}
+        )
+    </insert>
+
+    <!--新增对接设备历史记录信息-->
+    <insert id="saveTalkBackEquipmentRecord">
+        insert into sys_police_car_equipment_record
+        (
+        police_car_equipment_id,status,terminal_number,
+        longitude,latitude,speed,direction,elevation,precisions,receive_time,create_time
+        )
+        values
+        (
+        #{policeCarEquipmentId},#{status},#{terminalNumber},
+        #{longitude},#{latitude},#{speed},#{direction},#{elevation},#{precisions},#{receiveTime},#{createTime}
+        )
+    </insert>
+
+    <!--查询设备信息-->
+    <select id="getTalkBackEquipment" resultType="org.springblade.modules.netty.business.entity.PoliceCarEquipment">
+        select * from sys_police_car_equipment where terminal_number = #{code}
+    </select>
+
+    <!--修改对讲设备信息-->
+    <update id="updateTalkBackEquipment">
+        update sys_police_car_equipment
+        set
+        code = #{code},
+        name = #{name},
+        status = #{status},
+        <if test="null!=terminalNumber and terminalNumber!=''">
+            terminal_number = #{terminalNumber},
+        </if>
+        <if test="null!=longitude and longitude!=''">
+            longitude = #{longitude},
+        </if>
+        <if test="null!=latitude and latitude!=''">
+            latitude = #{latitude},
+        </if>
+        <if test="null!=speed and speed!=''">
+            speed = #{speed},
+        </if>
+        <if test="null!=direction and direction!=''">
+            direction = #{direction},
+        </if>
+        <if test="null!=elevation and elevation!=''">
+            elevation = #{elevation},
+        </if>
+        <if test="null!=precisions and precisions!=''">
+            precisions = #{precisions},
+        </if>
+        <if test="null!=receiveTime">
+            receive_time = #{receiveTime},
+        </if>
+        update_time = #{updateTime}
+        where id = #{id}
+    </update>
+
+</mapper>
diff --git a/src/main/java/org/springblade/modules/netty/business/service/PoliceCarEquipmentService.java b/src/main/java/org/springblade/modules/netty/business/service/PoliceCarEquipmentService.java
new file mode 100644
index 0000000..cc173b2
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/business/service/PoliceCarEquipmentService.java
@@ -0,0 +1,19 @@
+package org.springblade.modules.netty.business.service;
+
+
+import org.springblade.modules.netty.business.entity.PoliceCarEquipment;
+
+/**
+ * 对讲设备信息表 服务类
+ *
+ * @author zhongrj
+ * @date 2023-03-02
+ */
+public interface PoliceCarEquipmentService {
+
+    /**
+     * 保存对讲设备数据
+     * @param talkBackEquipment
+     */
+    void save(PoliceCarEquipment talkBackEquipment);
+}
diff --git a/src/main/java/org/springblade/modules/netty/business/service/impl/PoliceCarEquipmentServiceImpl.java b/src/main/java/org/springblade/modules/netty/business/service/impl/PoliceCarEquipmentServiceImpl.java
new file mode 100644
index 0000000..8f7f017
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/business/service/impl/PoliceCarEquipmentServiceImpl.java
@@ -0,0 +1,60 @@
+package org.springblade.modules.netty.business.service.impl;
+
+import org.springblade.modules.netty.business.entity.PoliceCarEquipment;
+import org.springblade.modules.netty.business.entity.PoliceCarEquipmentRecord;
+import org.springblade.modules.netty.business.mapper.PoliceCarEquipmentMapper;
+import org.springblade.modules.netty.business.service.PoliceCarEquipmentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+
+/**
+ * 对讲设备服务实现层
+ * @author zhongrj
+ * @date 2023-03-02
+ */
+@Service
+public class PoliceCarEquipmentServiceImpl implements PoliceCarEquipmentService {
+
+    @Autowired
+    private PoliceCarEquipmentMapper policeCarEquipmentMapper;
+
+    /**
+     * 保存对讲设备数据
+     * @param talkBackEquipment
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void save(PoliceCarEquipment talkBackEquipment) {
+        //判断设备是否已存在,如果存在则更新,不存在则新增
+        PoliceCarEquipment backEquipment = policeCarEquipmentMapper.getTalkBackEquipment(talkBackEquipment.getTerminalNumber());
+        if (null==backEquipment) {
+            talkBackEquipment.setCreateTime(new Date());
+            //新增对接设备数据
+			policeCarEquipmentMapper.saveTalkBackEquipment(talkBackEquipment);
+        }else {
+            talkBackEquipment.setId(backEquipment.getId());
+            //修改
+			policeCarEquipmentMapper.updateTalkBackEquipment(talkBackEquipment);
+        }
+        //判断是否存在设备id
+        if (null != talkBackEquipment.getId()) {
+            PoliceCarEquipmentRecord equipmentRecord = new PoliceCarEquipmentRecord();
+            equipmentRecord.setPoliceCarEquipmentId(talkBackEquipment.getId());
+            equipmentRecord.setStatus(talkBackEquipment.getStatus());
+            equipmentRecord.setTerminalNumber(talkBackEquipment.getTerminalNumber());
+            equipmentRecord.setLongitude(talkBackEquipment.getLongitude());
+            equipmentRecord.setLatitude(talkBackEquipment.getLatitude());
+            equipmentRecord.setSpeed(talkBackEquipment.getSpeed());
+            equipmentRecord.setDirection(talkBackEquipment.getDirection());
+            equipmentRecord.setElevation(talkBackEquipment.getElevation());
+            equipmentRecord.setPrecisions(talkBackEquipment.getPrecisions());
+            equipmentRecord.setReceiveTime(talkBackEquipment.getReceiveTime());
+            equipmentRecord.setCreateTime(new Date());
+            //新增记录信息
+			policeCarEquipmentMapper.saveTalkBackEquipmentRecord(equipmentRecord);
+        }
+    }
+}
diff --git a/src/main/java/org/springblade/modules/netty/config/MyDecoder.java b/src/main/java/org/springblade/modules/netty/config/MyDecoder.java
new file mode 100644
index 0000000..ca7693c
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/config/MyDecoder.java
@@ -0,0 +1,132 @@
+package org.springblade.modules.netty.config;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 自定义解析
+ */
+@Component
+public class MyDecoder extends ByteToMessageDecoder {
+
+    @Override
+    protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
+        //创建字节数组,buffer.readableBytes可读字节长度
+        byte[] b = new byte[buffer.readableBytes()];
+        //复制内容到字节数组b
+        buffer.readBytes(b);
+        //字节数组转字符串
+        String str = new String(b);
+
+        System.out.println(str);
+
+        out.add(bytesToHexString(b));
+    }
+
+    public String bytesToHexString(byte[] bArray) {
+        StringBuffer sb = new StringBuffer(bArray.length);
+        String sTemp;
+        for (int i = 0; i < bArray.length; i++) {
+            sTemp = Integer.toHexString(0xFF & bArray[i]);
+            if (sTemp.length() < 2)
+                sb.append(0);
+            sb.append(sTemp.toUpperCase());
+        }
+        return sb.toString();
+    }
+
+    public static String toHexString1(byte[] b) {
+        StringBuffer buffer = new StringBuffer();
+        for (int i = 0; i < b.length; ++i) {
+            buffer.append(toHexString1(b[i]));
+        }
+        return buffer.toString();
+    }
+
+    public static String toHexString1(byte b) {
+        String s = Integer.toHexString(b & 0xFF);
+        if (s.length() == 1) {
+            return "0" + s;
+        } else {
+            return s;
+        }
+    }
+
+    /**
+     * 16进制字符串转换为字符串
+     *
+     * @param s
+     * @return
+     */
+    public static String hexStringToString(String s) {
+        if (s == null || s.equals("")) {
+            return null;
+        }
+        s = s.replace(" ", "");
+        byte[] baKeyword = new byte[s.length() / 2];
+        for (int i = 0; i < baKeyword.length; i++) {
+            try {
+                baKeyword[i] = (byte) (0xff & Integer.parseInt(
+                        s.substring(i * 2, i * 2 + 2), 16));
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        try {
+            s = new String(baKeyword, "gbk");
+            new String();
+        } catch (Exception e1) {
+            e1.printStackTrace();
+        }
+        return s;
+    }
+
+
+    /**
+     * Hex字符串转byte
+     * @param inHex 待转换的Hex字符串
+     * @return  转换后的byte
+     */
+    public static byte hexToByte(String inHex){
+        return (byte) Integer.parseInt(inHex,16);
+    }
+
+    /**
+     * Hex字符串转byte
+     * @param inHex 待转换的Hex字符串
+     * @return  转换后的byte
+     */
+    public static short hexTohort(String inHex){
+        return (short) Integer.parseInt(inHex,16);
+    }
+
+
+    /**
+     * hex字符串转byte数组
+     * @param inHex 待转换的Hex字符串
+     * @return  转换后的byte数组结果
+     */
+    public static byte[] hexToByteArray(String inHex){
+        int hexlen = inHex.length();
+        byte[] result;
+        if (hexlen % 2 == 1){
+            //奇数
+            hexlen++;
+            result = new byte[(hexlen/2)];
+            inHex="0"+inHex;
+        }else {
+            //偶数
+            result = new byte[(hexlen/2)];
+        }
+        int j=0;
+        for (int i = 0; i < hexlen; i+=2){
+            result[j]=hexToByte(inHex.substring(i,i+2));
+            j++;
+        }
+        return result;
+    }
+}
diff --git a/src/main/java/org/springblade/modules/netty/config/SysConfig.java b/src/main/java/org/springblade/modules/netty/config/SysConfig.java
new file mode 100644
index 0000000..858174e
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/config/SysConfig.java
@@ -0,0 +1,26 @@
+package org.springblade.modules.netty.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * netty 相关配置信息
+ * @author zhongrj
+ * @date 2023-02-21
+ */
+@Component
+@ConfigurationProperties(prefix="syscfg")
+public class SysConfig {
+    /**
+     * UDP消息接收端口
+     */
+    private int UdpReceivePort;
+
+    public int getUdpReceivePort() {
+        return UdpReceivePort;
+    }
+
+    public void setUdpReceivePort(int udpReceivePort) {
+        UdpReceivePort = udpReceivePort;
+    }
+}
diff --git a/src/main/java/org/springblade/modules/netty/event/StartupEvent.java b/src/main/java/org/springblade/modules/netty/event/StartupEvent.java
new file mode 100644
index 0000000..a547d2f
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/event/StartupEvent.java
@@ -0,0 +1,38 @@
+package org.springblade.modules.netty.event;
+
+
+import org.springblade.modules.netty.config.SysConfig;
+import org.springblade.modules.netty.server.UdpServer;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.stereotype.Component;
+
+/**
+ * netty udp 服务启动监听
+ * @author zhongrj
+ * @date 2023-02-21
+ */
+@Component
+public class StartupEvent implements ApplicationListener<ContextRefreshedEvent> {
+
+    private static ApplicationContext context;
+
+    @Override
+    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
+        try {
+            context = contextRefreshedEvent.getApplicationContext();
+            SysConfig sysConfig = (SysConfig) context.getBean(SysConfig.class);
+            //获取 udpServer
+            UdpServer udpServer = (UdpServer) StartupEvent.getBean(UdpServer.class);
+            //开启
+            udpServer.run(sysConfig.getUdpReceivePort());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static Object getBean(Class beanName) {
+        return context != null ? context.getBean(beanName) : null;
+    }
+}
diff --git a/src/main/java/org/springblade/modules/netty/handle/UdpServerHandler.java b/src/main/java/org/springblade/modules/netty/handle/UdpServerHandler.java
new file mode 100644
index 0000000..cf60fd3
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/handle/UdpServerHandler.java
@@ -0,0 +1,160 @@
+package org.springblade.modules.netty.handle;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.channel.socket.DatagramPacket;
+import io.netty.util.CharsetUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springblade.modules.netty.business.entity.PoliceCarEquipment;
+import org.springblade.modules.netty.business.service.PoliceCarEquipmentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import javax.annotation.PostConstruct;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import static org.springblade.modules.netty.config.MyDecoder.hexToByte;
+import static org.springblade.modules.netty.config.MyDecoder.hexTohort;
+import static org.springblade.modules.netty.util.Hex.getDouble;
+import static org.springblade.modules.netty.util.Hex.hexStr2Str;
+
+/**
+ * updHandler udp 服务端数据接收处理
+ * @author zhongrj
+ * @date 2023-02-21
+ */
+@Component
+public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {
+	private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+	private static UdpServerHandler udpServerHandler;
+
+	@Autowired
+	private PoliceCarEquipmentService policeCarEquipmentService;
+
+	@PostConstruct
+	public void init() {
+		udpServerHandler = this;
+		udpServerHandler.policeCarEquipmentService = this.policeCarEquipmentService;
+	}
+
+	@Override
+	protected void channelRead0(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket) throws Exception {
+		// 读取收到的数据
+		ByteBuf buf = (ByteBuf) datagramPacket.copy().content();
+		byte[] req = new byte[buf.readableBytes()];
+		buf.readBytes(req);
+		String body = new String(req, CharsetUtil.UTF_8);
+		// 字节转16进制字符串
+		String s = bytesToHexString(req);
+		//获取字符串的长度
+		int length = s.length();
+//		System.out.println("数据长度>>>>>> = " + length);
+		//数据解析
+		dataHandler(s);
+	}
+
+	/**
+	 * 数据解析
+	 * @param s 16位字符串
+	 */
+	private void dataHandler(String s) {
+		s = "AAAACCCC220000000033373933343732393100000000000000000000000052D50451F77D5D406C04E275FD723C400000015F0000000507E70306103B0A";
+		//创建设备对象
+		PoliceCarEquipment backEquipment = new PoliceCarEquipment();
+		if (s.substring(4,8).equals("CCCC")) {
+			backEquipment.setStatus(1);
+		}
+		//断开连接
+		if (s.substring(4,8).equals("FFFF")) {
+			backEquipment.setStatus(0);
+		}
+		//截取字符串
+		backEquipment.setTerminalNumber(hexStr2Str(s.substring(20, 60)));
+
+		backEquipment.setLongitude(Double.toString(getDouble(s.substring(60, 76))));
+
+		backEquipment.setLatitude(Double.toString(getDouble(s.substring(76, 92))));
+
+		backEquipment.setSpeed(Short.toString(hexTohort(s.substring(92, 96))));
+		backEquipment.setDirection(Short.toString(hexTohort(s.substring(96, 100))));
+		backEquipment.setElevation(Short.toString(hexTohort(s.substring(100, 104))));
+		backEquipment.setPrecisions(Short.toString(hexTohort(s.substring(104, 108))));
+
+		String year = Short.toString(hexTohort(s.substring(108, 112)));
+
+		String month = Short.toString(hexToByte(s.substring(112, 114)));
+		if (Integer.parseInt(month)<10){
+			month = "0" + month;
+		}
+		String day = Short.toString(hexToByte(s.substring(114, 116)));
+		if (Integer.parseInt(day)<10){
+			day = "0" + day;
+		}
+		String hour = Short.toString(hexToByte(s.substring(116, 118)));
+		if (Integer.parseInt(hour)<10){
+			hour = "0" + hour;
+		}
+		String minute = Short.toString(hexToByte(s.substring(118, 120)));
+		if (Integer.parseInt(minute)<10){
+			minute = "0" + minute;
+		}
+		String second = Short.toString(hexToByte(s.substring(120, 122)));
+		if (Integer.parseInt(second)<10){
+			second = "0" + second;
+		}
+		String time = year + "-" + month + "-" + day +" " + hour + ":" + minute + ":" + second;
+		//时间拼接
+		try {
+			backEquipment.setReceiveTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(time));
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		backEquipment.setUpdateTime(new Date());
+		// 新增
+		udpServerHandler.policeCarEquipmentService.save(backEquipment);
+	}
+
+	/**
+	 * 转换
+	 * @param bArray
+	 * @return
+	 */
+	public String bytesToHexString(byte[] bArray) {
+		StringBuffer sb = new StringBuffer(bArray.length);
+		String sTemp;
+		for (int i = 0; i < bArray.length; i++) {
+			sTemp = Integer.toHexString(0xFF & bArray[i]);
+			if (sTemp.length() < 2)
+				sb.append(0);
+			sb.append(sTemp.toUpperCase());
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * 捕获异常
+	 * @param ctx
+	 * @param cause
+	 * @throws Exception
+	 */
+	@Override
+	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)throws Exception {
+		logger.error("UdpServerHandler exceptionCaught"+cause.getMessage());
+		System.out.println("UdpServerHandler exceptionCaught"+cause.getMessage());
+		cause.printStackTrace();
+		ctx.close();
+	}
+
+	/**
+	 * 消息没有结束的时候触发
+	 * @param ctx
+	 * @throws Exception
+	 */
+	@Override
+	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
+		ctx.flush();
+	}
+}
diff --git a/src/main/java/org/springblade/modules/netty/server/UdpServer.java b/src/main/java/org/springblade/modules/netty/server/UdpServer.java
new file mode 100644
index 0000000..cde24a0
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/server/UdpServer.java
@@ -0,0 +1,86 @@
+package org.springblade.modules.netty.server;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioDatagramChannel;
+import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
+import io.netty.util.concurrent.DefaultEventExecutorGroup;
+import io.netty.util.concurrent.EventExecutorGroup;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springblade.modules.netty.config.MyDecoder;
+import org.springblade.modules.netty.handle.UdpServerHandler;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * updServer udp服务端
+ *
+ * @author zhongrj
+ * @date 2023-02-21
+ */
+@Component
+public class UdpServer {
+
+    private static Logger LOG = LoggerFactory.getLogger(UdpServer.class);
+
+
+    //给管道抽象出接口,给Channel更多的能力和配置,例如Channel的状态,参数,IO操作
+    //使用ChannelPipeline实现自定义IO
+    //Channel channel;
+    @Async("taskExecutor")
+    public void run(int port) {
+        //启动服务
+        EventLoopGroup workerGroup = new NioEventLoopGroup();
+        //优化使用的线程
+        final EventExecutorGroup group = new DefaultEventExecutorGroup(16);
+
+        try {
+            //udp不能使用ServerBootstrap
+            Bootstrap b = new Bootstrap();
+            //设置UDP通道
+            b.group(workerGroup).channel(NioDatagramChannel.class)
+                    //设置udp的管道工厂
+                    .handler(new ChannelInitializer<NioDatagramChannel>() {
+                        //NioDatagramChannel标志着是UDP格式的
+                        @Override
+                        protected void initChannel(NioDatagramChannel ch)
+                                throws Exception {
+                            // TODO Auto-generated method stub
+                            //创建一个执行Handler的容器
+                            ChannelPipeline pipeline = ch.pipeline();
+//                            pipeline.addLast(new StringDecoder());
+                            pipeline.addLast("decoder",new MyDecoder());
+//                            pipeline.addLast(new StringEncoder());
+                            pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 4, 4, -8, 0));
+                            //执行具体的自定义处理器
+                            pipeline.addLast(group, "handler", new UdpServerHandler());
+                        }
+
+                    })//初始化处理器
+
+                    //true / false 多播模式(UDP适用),可以向多个主机发送消息
+                    .option(ChannelOption.SO_BROADCAST, true)
+                    // 设置UDP读缓冲区为2M
+                    .option(ChannelOption.SO_RCVBUF, 2048 * 1024)
+                    // 设置UDP写缓冲区为1M
+                    .option(ChannelOption.SO_SNDBUF, 1024 * 1024);
+
+            // 绑定端口,开始接收进来的连接
+            ChannelFuture f = b.bind(port).sync();
+            //获取channel通道
+            System.out.println("UDP Server 启动,端口:" + port);
+            // 等待服务器 socket 关闭 。
+            // 这不会发生,可以优雅地关闭服务器。
+            f.channel().closeFuture().sync();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } finally {
+            //优雅退出 释放线程池资源
+            group.shutdownGracefully();
+            workerGroup.shutdownGracefully();
+        }
+    }
+
+}
diff --git a/src/main/java/org/springblade/modules/netty/util/Hex.java b/src/main/java/org/springblade/modules/netty/util/Hex.java
new file mode 100644
index 0000000..bb3bb77
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/util/Hex.java
@@ -0,0 +1,552 @@
+package org.springblade.modules.netty.util;
+
+
+import java.nio.ByteBuffer;
+
+import static org.springblade.modules.netty.config.MyDecoder.hexToByte;
+import static org.springblade.modules.netty.config.MyDecoder.hexTohort;
+
+
+public class Hex {
+    /**
+     * 用于建立十六进制字符的输出的小写字符数组
+     */
+    private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5',
+            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+    /**
+     * 用于建立十六进制字符的输出的大写字符数组
+     */
+    private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5',
+            '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+
+    private static ByteBuffer buffer = ByteBuffer.allocate(8);
+
+    /**
+     * 字符串转换成十六进制字符串
+     *
+     * @param str 待转换的ASCII字符串
+     * @return String 每个Byte之间空格分隔,如: [61 6C 6B]
+     */
+    public static String str2HexStr(String str) {
+
+        char[] chars = "0123456789ABCDEF".toCharArray();
+        StringBuilder sb = new StringBuilder("");
+        byte[] bs = str.getBytes();
+        int bit;
+
+        for (int i = 0; i < bs.length; i++) {
+            bit = (bs[i] & 0x0f0) >> 4;
+            sb.append(chars[bit]);
+            bit = bs[i] & 0x0f;
+            sb.append(chars[bit]);
+            sb.append(' ');
+        }
+        return sb.toString().trim();
+    }
+
+    /**
+     * 十六进制转换字符串
+     *
+     * @param hexStr Byte字符串(Byte之间无分隔符 如:[616C6B])
+     * @return String 对应的字符串
+     */
+    public static String hexStr2Str(String hexStr) {
+        String str = "0123456789ABCDEF";
+        char[] hexs = hexStr.toCharArray();
+        byte[] bytes = new byte[hexStr.length() / 2];
+        int n;
+
+        for (int i = 0; i < bytes.length; i++) {
+            n = str.indexOf(hexs[2 * i]) * 16;
+            n += str.indexOf(hexs[2 * i + 1]);
+            bytes[i] = (byte) (n & 0xff);
+        }
+        return new String(bytes);
+    }
+
+    /**
+     * bytes转换成十六进制字符串
+     *
+     * @param b byte数组
+     * @return String 每个Byte值之间空格分隔
+     */
+    public static String byte2HexStr(byte[] b) {
+        String stmp = "";
+        StringBuilder sb = new StringBuilder("");
+        for (int n = 0; n < b.length; n++) {
+            stmp = Integer.toHexString(b[n] & 0xFF);
+            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
+//			sb.append(" ");
+        }
+        return sb.toString().toUpperCase().trim();
+    }
+
+
+    /**
+     * bytes字符串转换为Byte值
+     *
+     * @param src Byte字符串,每个Byte之间没有分隔符
+     * @return byte[]
+     */
+    public static byte[] hexStr2Bytes(String src) {
+        int m = 0, n = 0;
+        int l = src.length() / 2;
+        System.out.println(l);
+        byte[] ret = new byte[l];
+        for (int i = 0; i < l; i++) {
+            m = i * 2 + 1;
+            n = m + 1;
+            String tmp = "0x" + src.substring(i * 2, m) + src.substring(m, n);
+            ret[i] = Byte.decode(tmp);
+        }
+        return ret;
+    }
+
+    /**
+     * bytes字符串转换为Byte值
+     *
+     * @param hexString
+     * @return
+     */
+    public static byte[] hexToBytes(String hexString) {
+        if (hexString == null || hexString.equals("")) {
+            return null;
+        }
+
+        int length = hexString.length() / 2;
+        char[] hexChars = hexString.toCharArray();
+        byte[] bytes = new byte[length];
+//        String hexDigits = "0123456789abcdefABCDEF";
+        String hexDigits = "0123456789abcdef";
+        for (int i = 0; i < length; i++) {
+            int pos = i * 2; // 两个字符对应一个byte
+            int h = hexDigits.indexOf(hexChars[pos]) << 4; // 注1
+            int l = hexDigits.indexOf(hexChars[pos + 1]); // 注2
+            if (h == -1 || l == -1) { // 非16进制字符
+                return null;
+            }
+            bytes[i] = (byte) (h | l);
+        }
+        return bytes;
+    }
+
+    /**
+     * String的字符串转换成unicode的String
+     *
+     * @param strText 全角字符串
+     * @return String 每个unicode之间无分隔符
+     * @throws Exception
+     */
+    public static String strToUnicode(String strText) throws Exception {
+        char c;
+        StringBuilder str = new StringBuilder();
+        int intAsc;
+        String strHex;
+        for (int i = 0; i < strText.length(); i++) {
+            c = strText.charAt(i);
+            intAsc = (int) c;
+            strHex = Integer.toHexString(intAsc);
+            if (intAsc > 128)
+                str.append("\\u" + strHex);
+            else
+                // 低位在前面补00
+                str.append("\\u00" + strHex);
+        }
+        return str.toString();
+    }
+
+    /**
+     * unicode的String转换成String的字符串
+     *
+     * @param hex 16进制值字符串 (一个unicode为2byte)
+     * @return String 全角字符串
+     */
+    public static String unicodeToString(String hex) {
+        int t = hex.length() / 6;
+        StringBuilder str = new StringBuilder();
+        for (int i = 0; i < t; i++) {
+            String s = hex.substring(i * 6, (i + 1) * 6);
+            // 高位需要补上00再转
+            String s1 = s.substring(2, 4) + "00";
+            // 低位直接转
+            String s2 = s.substring(4);
+            // 将16进制的string转为int
+            int n = Integer.valueOf(s1, 16) + Integer.valueOf(s2, 16);
+            // 将int转换为字符
+            char[] chars = Character.toChars(n);
+            str.append(new String(chars));
+        }
+        return str.toString();
+    }
+
+
+    /**
+     * 将字节数组转换为十六进制字符数组
+     *
+     * @param data byte[]
+     * @return 十六进制char[]
+     */
+    public static char[] encodeHex(byte[] data) {
+        return encodeHex(data, true);
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符数组
+     *
+     * @param data        byte[]
+     * @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
+     * @return 十六进制char[]
+     */
+    public static char[] encodeHex(byte[] data, boolean toLowerCase) {
+        return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符数组
+     *
+     * @param data     byte[]
+     * @param toDigits 用于控制输出的char[]
+     * @return 十六进制char[]
+     */
+    protected static char[] encodeHex(byte[] data, char[] toDigits) {
+        int l = data.length;
+        char[] out = new char[l << 1];
+        // two characters form the hex value.
+        for (int i = 0, j = 0; i < l; i++) {
+            out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
+            out[j++] = toDigits[0x0F & data[i]];
+        }
+        return out;
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     *
+     * @param data byte[]
+     * @return 十六进制String
+     */
+    public static String encodeHexStr(byte[] data) {
+        return encodeHexStr(data, true);
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     *
+     * @param data        byte[]
+     * @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
+     * @return 十六进制String
+     */
+    public static String encodeHexStr(byte[] data, boolean toLowerCase) {
+        return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     *
+     * @param data     byte[]
+     * @param toDigits 用于控制输出的char[]
+     * @return 十六进制String
+     */
+    protected static String encodeHexStr(byte[] data, char[] toDigits) {
+        return new String(encodeHex(data, toDigits));
+    }
+
+    /**
+     * 将十六进制字符数组转换为字节数组
+     *
+     * @param data 十六进制char[]
+     * @return byte[]
+     * @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常
+     */
+    public static byte[] decodeHex(char[] data) {
+
+        int len = data.length;
+
+        if ((len & 0x01) != 0) {
+            throw new RuntimeException("Odd number of characters.");
+        }
+
+        byte[] out = new byte[len >> 1];
+
+        // two characters form the hex value.
+        for (int i = 0, j = 0; j < len; i++) {
+            int f = toDigit(data[j], j) << 4;
+            j++;
+            f = f | toDigit(data[j], j);
+            j++;
+            out[i] = (byte) (f & 0xFF);
+        }
+
+        return out;
+    }
+
+    /**
+     * 将十六进制字符转换成一个整数
+     *
+     * @param ch    十六进制char
+     * @param index 十六进制字符在字符数组中的位置
+     * @return 一个整数
+     * @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常
+     */
+    protected static int toDigit(char ch, int index) {
+        int digit = Character.digit(ch, 16);
+        if (digit == -1) {
+            throw new RuntimeException("Illegal hexadecimal character " + ch
+                    + " at index " + index);
+        }
+        return digit;
+    }
+
+    /**
+     * float -> byte[]
+     *
+     * @param data
+     * @return
+     */
+    public static byte[] getBytes(float data) {
+        int intBits = Float.floatToIntBits(data);
+        return intToByteArray(intBits);
+    }
+
+    /**
+     * double -> byte[]
+     *
+     * @param data
+     * @return
+     */
+    public static byte[] getBytes(double data) {
+        long longBits = Double.doubleToLongBits(data);
+        return longToBytes(longBits);
+    }
+
+    /**
+     * byte[] -> float
+     *
+     * @param bytes
+     * @return
+     */
+    public static float getFloat(byte[] bytes) {
+        return Float.intBitsToFloat(getInt(bytes));
+    }
+
+    public static int getInt(byte[] bytes) {
+        return (0xff & bytes[0]) | (0xff00 & (bytes[1] << 8)) | (0xff0000 & (bytes[2] << 16)) | (0xff000000 & (bytes[3] << 24));
+    }
+
+    /**
+     * byte[] -> double
+     *
+     * @return
+     */
+    public static double getDouble(byte[] b) {
+        long l;
+        l = b[0];
+        l &= 0xff;
+        l |= ((long) b[1] << 8);
+        l &= 0xffff;
+        l |= ((long) b[2] << 16);
+        l &= 0xffffff;
+        l |= ((long) b[3] << 24);
+        l &= 0xffffffffL;
+        l |= ((long) b[4] << 32);
+        l &= 0xffffffffffL;
+        l |= ((long) b[5] << 40);
+        l &= 0xffffffffffffL;
+        l |= ((long) b[6] << 48);
+        l &= 0xffffffffffffffL;
+        l |= ((long) b[7] << 56);
+        return Double.longBitsToDouble(l);
+    }
+
+    /**
+     * 字节数组字符串 -> double
+     *
+     * @param bytesStr
+     * @return
+     */
+    public static double getDouble(String bytesStr) {
+        byte[] aa = hexToBytes(bytesStr.toLowerCase());
+        return getDouble(aa);
+    }
+
+
+    /**
+     * 字节数组字符串 -> float
+     *
+     * @param bytesStr
+     * @return
+     */
+    public static float getFloat(String bytesStr) {
+        byte[] aa = hexToBytes(bytesStr.toLowerCase());
+
+        return getFloat(aa);
+    }
+
+    /**
+     * 16进制字符串 -> byte数组
+     */
+    public static byte[] str16ToByte(String str16) {
+
+        int len = str16.length();
+        if (len % 2 > 0) {
+            return null;
+        }
+
+        byte res[] = new byte[len / 2];
+
+        for (int i = 0; i < len / 2; i++) {
+            String tmp = str16.substring(i*2, (i + 1) * 2);
+            byte t[] = hexToBytes(tmp);
+            res[i] = t[0];
+        }
+        return res;
+    }
+
+
+    public static void main(String args[]) throws Exception {
+        String aa = "AAAACCCC220000000033373933343732393100000000000000000000000052D50451F77D5D406C04E275FD723C400000015F0000000507E70306103B0A";
+
+        String substring = aa.substring(20, 60);
+        String substring1 = aa.substring(60, 76);
+        String substring2 = aa.substring(76, 92);
+        // 编号
+        String a1 = "AAAACCCC2200000000333739333437323931000000000000000000000000";
+
+        // 编号
+        String a2 = "3739333437323931000000000000000000000000";
+        System.out.println("a2 = " + hexStr2Str(a2));
+
+        //经
+        String lng = "52D50451F77D5D40";
+        System.out.println("lng = " + getDouble(lng));
+
+        String lat = "6C04E275FD723C40";
+        System.out.println("lat = " + getDouble(lat));
+
+        //日
+        String str = "0000";
+        System.out.println("a = " + hexTohort(str));
+
+
+        String str1 = "015F";
+        System.out.println("b = " + hexTohort(str1));
+
+        //日
+        String str2 = "0000";
+        System.out.println("c = " + hexTohort(str2));
+
+
+        String str3 = "0005";
+        System.out.println("tr3 = " + hexTohort(str3));
+
+
+        String nian = "07E7";
+        System.out.println("nian = " + hexTohort(nian));
+
+        String yue = "03";
+        System.out.println("yue = " + hexToByte(yue));
+
+        String ri = "06";
+        System.out.println("ri = " + hexToByte(ri));
+
+        String h = "10";
+        System.out.println("h = " + hexToByte(h));
+
+        String f = "3B";
+        System.out.println("f = " + hexToByte(f));
+
+        String m = "0A";
+        System.out.println("m = " + hexToByte(m));
+
+    }
+
+    public static int toshort(String str) {
+        char[] in = str.toCharArray();
+        /*
+         * for(int i=0;i<in.length;i+=2) { int value= tohx16(in[i]); int value2=
+         * tohx16(in[i+1]); int value3=value<<4|value2;
+         *
+         * System.out.print(value3); }//这里可设计照规则进行转换
+         */
+        int j = 0;
+
+        for(int i=0;i<in.length;i+=2) {
+            int value= tohx16(in[i]);
+            int value2=tohx16(in[i+1]);
+            j=value<<4|value2;
+        }
+        return j;
+    }
+
+
+
+    public static int tohx16(char str) {
+        switch (str) {
+            case '0':
+                return 0;
+            case '1':
+                return '1';
+            case '2':
+                return 2;
+            case '3':
+                return 3;
+            case '4':
+                return 4;
+            case '5':
+                return 5;
+            case '6':
+                return 6;
+            case '7':
+                return 7;
+            case '8':
+                return 8;
+            case '9':
+                return 9;
+            case 'a':
+            case 'A':
+                return 10;
+            case 'b':
+            case 'B':
+                return 11;
+            case 'c':
+            case 'C':
+                return 12;
+            case 'd':
+            case 'D':
+                return 13;
+            case 'e':
+            case 'E':
+                return 14;
+            case 'f':
+            case 'F':
+                return 15;
+
+        }
+
+        return 0;
+    }
+
+    public static byte[] intToByteArray(int a) {
+        return new byte[]{
+                (byte) ((a >> 24) & 0xFF),
+                (byte) ((a >> 16) & 0xFF),
+                (byte) ((a >> 8) & 0xFF),
+                (byte) (a & 0xFF)
+        };
+    }
+
+    public static byte intToByte(int a) {
+        return (byte) (a & 0xFF);
+    }
+
+    public static byte[] longToBytes(long x) {
+        buffer.putLong(0, x);
+        return buffer.array();
+    }
+
+
+}
+
+
diff --git a/src/main/java/org/springblade/modules/netty/util/HexStringTool.java b/src/main/java/org/springblade/modules/netty/util/HexStringTool.java
new file mode 100644
index 0000000..2ab60c7
--- /dev/null
+++ b/src/main/java/org/springblade/modules/netty/util/HexStringTool.java
@@ -0,0 +1,303 @@
+package org.springblade.modules.netty.util;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+public class HexStringTool {
+
+
+    private static final char[] HEX_CHAR_ARR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+    private static final String HEX_STR = "0123456789abcdef";
+
+    //对字符串,进行分组,转化为List
+    public static List<String> getStrList(String str16, int frontLen, int size, int length) {
+        List<String> list = new ArrayList<String>();
+        String content = str16.substring(frontLen);
+        String tem = "";
+        for (int index = 0; index < size; index++) {
+            tem = content.substring(0, length);
+            content = content.substring(length);
+            list.add(tem);
+        }
+        return list;
+    }
+
+    //对字符串,进行分组,转化为List(字符串数据类型转化专用)
+    public static List<String> getStrList(String str16, int frontLen, int size, int totalLen, int lenLen) {
+        List<String> list = new ArrayList<>();
+        String content = str16.substring(frontLen);
+        String tem = "";
+        for (int index = 0; index < size; index++) {
+            String len16 = content.substring(totalLen * 2, (totalLen + lenLen) * 2);
+            int len = Integer.parseInt(len16, 16);
+            int length = (totalLen + lenLen + len) * 2;
+            tem = content.substring(0, length);
+            content = content.substring(length);
+            list.add(tem);
+        }
+        return list;
+    }
+
+    //字符串转换unicode
+    public static String string2Unicode(String string) {
+        StringBuffer unicode = new StringBuffer();
+        for (int i = 0; i < string.length(); i++) {
+            // 取出每一个字符
+            char c = string.charAt(i);
+            // 转换为unicode
+            unicode.append("\\u" + Integer.toHexString(c));
+        }
+        return unicode.toString();
+    }
+
+    //字符串转化成为16进制字符串
+    public static String strTo16(String s) {
+        String str = "";
+        for (int i = 0; i < s.length(); i++) {
+            int ch = (int) s.charAt(i);
+            String s4 = Integer.toHexString(ch);
+            str = str + s4;
+        }
+        return str;
+    }
+
+    //16进制转换成为string类型字符串
+    public static String hexStringToString(String s) {
+        if (s == null || s.equals("")) {
+            return null;
+        }
+        s = s.replace(" ", "");
+        byte[] baKeyword = new byte[s.length() / 2];
+        for (int i = 0; i < baKeyword.length; i++) {
+            try {
+                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        try {
+            s = new String(baKeyword, "UTF-8");
+            new String();
+        } catch (Exception e1) {
+            e1.printStackTrace();
+        }
+        return s;
+    }
+
+    //unicode 转字符串
+    public static String unicode2String(String unicode) {
+        StringBuffer string = new StringBuffer();
+        String[] hex = unicode.split("\\\\u");
+        for (int i = 1; i < hex.length; i++) {
+            // 转换出每一个代码点
+            int data = Integer.parseInt(hex[i], 16);
+            // 追加成string
+            string.append((char) data);
+        }
+        return string.toString();
+    }
+
+    //字符串转换成为16进制(无需Unicode编码)
+    public static String str2HexStr(String str) {
+        char[] chars = "0123456789ABCDEF".toCharArray();
+        StringBuilder sb = new StringBuilder("");
+        byte[] bs = str.getBytes();
+        int bit;
+        for (int i = 0; i < bs.length; i++) {
+            bit = (bs[i] & 0x0f0) >> 4;
+            sb.append(chars[bit]);
+            bit = bs[i] & 0x0f;
+            sb.append(chars[bit]);
+            // sb.append(' ');
+        }
+        return sb.toString().trim();
+    }
+
+    //16进制直接转换成为字符串(无需Unicode解码)
+    public static String hexStr2Str(String hexStr) {
+        String str = "0123456789ABCDEF";
+        char[] hexs = hexStr.toCharArray();
+        byte[] bytes = new byte[hexStr.length() / 2];
+        int n;
+        for (int i = 0; i < bytes.length; i++) {
+            n = str.indexOf(hexs[2 * i]) * 16;
+            n += str.indexOf(hexs[2 * i + 1]);
+            bytes[i] = (byte) (n & 0xff);
+        }
+        return new String(bytes);
+    }
+
+    /**
+     * int/long转16字节字符串(按所占字节数用0补齐)
+     *
+     * @param byteLen 所占字节长度
+     * @param b       需要转换的数字
+     * @return str16
+     */
+    public static String numToStr16(int byteLen, long b) {
+        return String.format("%0" + byteLen * 2 + "x", b);
+    }
+
+    /**
+     * float/double转16字节字符串(按所占字节数用0补齐)
+     *
+     * @param byteLen 所占字节长度
+     * @param b       需要转换的数字
+     * @return str16
+     */
+    public static String numToStr16(int byteLen, double b) {
+        byte[] bytes = Hex.getBytes(b);
+        int anInt = Hex.getInt(bytes);
+        return String.format("%0" + byteLen * 2 + "x", anInt);
+    }
+
+    /**
+     * 16进制字符串转字符串(ASCII)
+     *
+     * @param x16 十六进制字符串
+     * @return string
+     */
+    public static String x16toString(String x16) {
+        if (x16 == null || "".equals(x16.trim())) {
+            return "";
+        }
+        String tempStr = "";
+        byte[] b = new byte[x16.length() / 2];
+        for (int i = 0; i < x16.length() / 2; i++) {
+            tempStr = x16.substring(i * 2, i * 2 + 2);
+            int temp = Integer.parseInt(tempStr, 16);
+            b[i] = (byte) temp;
+        }
+        return new String(b, StandardCharsets.US_ASCII);
+    }
+
+    /**
+     * 16进制字符串转字符串(GBK)
+     *
+     * @param x16 十六进制字符串
+     * @return string
+     */
+    public static String x16toGbk(String x16) {
+        byte[] bytes = new byte[x16.length() / 2];
+        byte tempByte = 0;
+        byte tempHigh = 0;
+        byte tempLow = 0;
+        for (int i = 0, j = 0; i < x16.length(); i += 2, j++) {
+            tempByte = (byte) (((int) x16.charAt(i)) & 0xff);
+            if (tempByte >= 48 && tempByte <= 57) {
+                tempHigh = (byte) ((tempByte - 48) << 4);
+            } else if (tempByte >= 97 && tempByte <= 101) {
+                tempHigh = (byte) ((tempByte - 97 + 10) << 4);
+            }
+            tempByte = (byte) (((int) x16.charAt(i + 1)) & 0xff);
+            if (tempByte >= 48 && tempByte <= 57) {
+                tempLow = (byte) (tempByte - 48);
+            } else if (tempByte >= 97 && tempByte <= 101) {
+                tempLow = (byte) (tempByte - 97 + 10);
+            }
+            bytes[j] = (byte) (tempHigh | tempLow);
+        }
+        String result = null;
+        try {
+            result = new String(bytes, "GBK");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+
+    public static boolean isChinese(String s) {
+        boolean result = false;
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
+            if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
+                    || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
+                    || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
+                    || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
+                    || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
+                    || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
+                result = true;
+            }
+        }
+        return result;
+    }
+
+    private static String byteArrToHex(byte[] btArr) {
+        char[] strArr = new char[btArr.length * 2];
+        int i = 0;
+        for (byte bt : btArr) {
+            strArr[i++] = HEX_CHAR_ARR[bt >>> 4 & 0xf];
+            strArr[i++] = HEX_CHAR_ARR[bt & 0xf];
+        }
+        return new String(strArr);
+    }
+
+    private static byte[] hexToByteArr(String hexStr) {
+        char[] charArr = hexStr.toCharArray();
+        byte[] btArr = new byte[charArr.length / 2];
+        int index = 0;
+        for (int i = 0; i < charArr.length; i++) {
+            int highBit = HEX_STR.indexOf(charArr[i]);
+            int lowBit = HEX_STR.indexOf(charArr[++i]);
+            btArr[index] = (byte) (highBit << 4 | lowBit);
+            index++;
+        }
+        return btArr;
+    }
+
+    /**
+     * 字符串转16进制字符串(无汉字utf-8,有汉字gbk)
+     *
+     * @param str
+     * @return
+     */
+    public static String str2StrHex(String str) {
+        boolean chinese = isChinese(str);
+        if (chinese) {
+            try {
+                byte[] bytes1 = str.getBytes(StandardCharsets.UTF_8);
+                byte[] bytes2 = new String(bytes1, StandardCharsets.UTF_8).getBytes("gbk");
+                String gbk = new String(bytes2, "gbk");
+                byte[] gbkArr = gbk.getBytes();
+                return byteArrToHex(gbkArr);
+
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+                return null;
+            }
+        } else {
+            return strTo16(str);
+        }
+    }
+
+    /**
+     * 16进制字符串转字符串(无汉字utf-8,有汉字gbk)
+     *
+     * @param strHex
+     * @return
+     */
+    public static String strHex2Str(String strHex) {
+        byte[] bytes = hexToByteArr(strHex);
+        String s1 = new String(bytes, StandardCharsets.UTF_8);
+        boolean chinese = isChinese(s1);
+        if (!chinese) {
+            try {
+                return new String(bytes, "gbk");
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+                return null;
+            }
+        } else {
+            return s1;
+        }
+    }
+
+
+}
+
+
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index e92b09e..b060896 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -13,7 +13,7 @@
     #  commandTimeout: 5000
   datasource:
     # MySql
-    url: jdbc:mysql://10.141.11.7:3308/srjw?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
+    url: jdbc:mysql://10.141.11.7:3308/wvp?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
     username: root
     password: srjw@2023
     # PostgreSQL
@@ -52,3 +52,7 @@
     upload-domain: http://localhost:8999
     remote-path: /usr/share/nginx/html
 
+# 警车udp接收端口
+syscfg:
+  udpReceivePort: 9989
+
diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml
index fab7885..b433e28 100644
--- a/src/main/resources/application-prod.yml
+++ b/src/main/resources/application-prod.yml
@@ -38,3 +38,7 @@
     remote-mode: true
     upload-domain: http://localhost:8999
     remote-path: /usr/share/nginx/html
+
+# 警车udp接收端口
+syscfg:
+  udpReceivePort: 9989
diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml
index e53618f..deebd28 100644
--- a/src/main/resources/application-test.yml
+++ b/src/main/resources/application-test.yml
@@ -14,9 +14,9 @@
     #  nodes: 127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003
     #  commandTimeout: 5000
   datasource:
-    url: jdbc:mysql://106.225.193.35:3306/srjw?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
+    url: jdbc:mysql://127.0.0.1:3308/wvp?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
     username: root
-    password: HCyj@2022
+    password: 123456
 
 #第三方登陆
 social:
@@ -38,3 +38,7 @@
     remote-mode: true
     upload-domain: http://localhost:8999
     remote-path: /usr/share/nginx/html
+
+# 警车udp接收端口
+syscfg:
+  udpReceivePort: 9989
diff --git a/src/test/java/org/springblade/test/BladeTest.java b/src/test/java/org/springblade/test/BladeTest.java
deleted file mode 100644
index 600b816..0000000
--- a/src/test/java/org/springblade/test/BladeTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.springblade.test;
-
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.springblade.core.test.BladeBootTest;
-import org.springblade.core.test.BladeSpringExtension;
-import org.springblade.core.tool.utils.StringUtil;
-import org.springblade.flow.engine.entity.FlowModel;
-import org.springblade.flow.engine.service.FlowEngineService;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.util.List;
-
-/**
- * Blade单元测试
- *
- * @author Chill
- */
-@ExtendWith(BladeSpringExtension.class)
-@BladeBootTest(appName = "blade-runner", enableLoader = true)
-public class BladeTest {
-
-	@Autowired
-	private FlowEngineService service;
-
-	@Test
-	public void contextLoads() {
-		System.out.println("=====数据迁移启动=====");
-
-		// 获取 ACT_DE_MODEL 表需要转换的数据
-		List<FlowModel> list = service.list();
-		// 循环转换
-		list.forEach(flowModel -> {
-			if (StringUtil.isBlank(flowModel.getModelEditorXml())) {
-				service.update(Wrappers.<FlowModel>lambdaUpdate()
-					.set(FlowModel::getModelEditorXml, new String(service.getModelEditorXML(flowModel)))
-					.ge(FlowModel::getId, flowModel.getId())
-				);
-			}
-		});
-
-		System.out.println("=====数据迁移完毕=====");
-	}
-
-}

--
Gitblit v1.9.3