From d333edb0ba4f5f82344135586b868f6cef1f7888 Mon Sep 17 00:00:00 2001 From: Kris <2893855659@qq.com> Date: Fri, 21 Feb 2025 15:16:56 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90feat=E3=80=91=E5=A2=9E=E5=8A=A0OA?= =?UTF-8?q?=E5=AE=A1=E6=89=B9=E4=B8=9A=E5=8A=A1=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oaLeave/TestLeaveController.java | 136 ++++++++ .../czsj/oaLeave/config/WarmFlowConfig.java | 41 +++ .../com/czsj/oaLeave/domain/TestLeave.java | 211 ++++++++++++ .../java/com/czsj/oaLeave/enums/FlowType.java | 55 ++++ .../oaLeave/handle/CustomDataFillHandler.java | 44 +++ .../handle/CustomPermissionHandler.java | 49 +++ .../oaLeave/handle/CustomTenantHandler.java | 18 ++ .../listener/AssignmentExpListener.java | 56 ++++ .../oaLeave/listener/AssignmentListener.java | 58 ++++ .../czsj/oaLeave/listener/CreateListener.java | 34 ++ .../listener/CustomGlobalListener.java | 76 +++++ .../listener/DefAssignmentListener.java | 58 ++++ .../oaLeave/listener/DefCreateListener.java | 39 +++ .../oaLeave/listener/DefFinishListener.java | 85 +++++ .../oaLeave/listener/DefStartListener.java | 61 ++++ .../czsj/oaLeave/listener/FinishListener.java | 34 ++ .../listener/LeaveEditFormHandleListener.java | 59 ++++ .../listener/LeaveFormLoadListener.java | 48 +++ .../czsj/oaLeave/listener/StartListener.java | 25 ++ .../czsj/oaLeave/mapper/TestLeaveMapper.java | 70 ++++ .../service/HandlerSelectServiceImpl.java | 166 ++++++++++ .../oaLeave/service/ITestLeaveService.java | 92 ++++++ .../java/com/czsj/oaLeave/service/User.java | 42 +++ .../service/impl/TestLeaveServiceImpl.java | 304 ++++++++++++++++++ .../mapper/oaLeave/TestLeaveMapper.xml | 127 ++++++++ 25 files changed, 1988 insertions(+) create mode 100644 czsj-admin/src/main/java/com/czsj/web/controller/oaLeave/TestLeaveController.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/config/WarmFlowConfig.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/domain/TestLeave.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/enums/FlowType.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/handle/CustomDataFillHandler.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/handle/CustomPermissionHandler.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/handle/CustomTenantHandler.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/listener/AssignmentExpListener.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/listener/AssignmentListener.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/listener/CreateListener.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/listener/CustomGlobalListener.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/listener/DefAssignmentListener.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/listener/DefCreateListener.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/listener/DefFinishListener.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/listener/DefStartListener.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/listener/FinishListener.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/listener/LeaveEditFormHandleListener.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/listener/LeaveFormLoadListener.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/listener/StartListener.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/mapper/TestLeaveMapper.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/service/HandlerSelectServiceImpl.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/service/ITestLeaveService.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/service/User.java create mode 100644 czsj-system/src/main/java/com/czsj/oaLeave/service/impl/TestLeaveServiceImpl.java create mode 100644 czsj-system/src/main/resources/mapper/oaLeave/TestLeaveMapper.xml diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/oaLeave/TestLeaveController.java b/czsj-admin/src/main/java/com/czsj/web/controller/oaLeave/TestLeaveController.java new file mode 100644 index 0000000..690e9f5 --- /dev/null +++ b/czsj-admin/src/main/java/com/czsj/web/controller/oaLeave/TestLeaveController.java @@ -0,0 +1,136 @@ +package com.czsj.web.controller.oaLeave; + +import com.czsj.common.annotation.Log; +import com.czsj.common.core.controller.BaseController; +import com.czsj.common.core.domain.AjaxResult; +import com.czsj.common.core.page.TableDataInfo; +import com.czsj.common.enums.BusinessType; +import com.czsj.common.utils.poi.ExcelUtil; +import com.czsj.oaLeave.domain.TestLeave; +import com.czsj.oaLeave.service.ITestLeaveService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * OA 请假申请Controller + * + * @author czsj + * @date 2024-03-07 + */ +@RestController +@RequestMapping("/system/leave") +public class TestLeaveController extends BaseController +{ + @Autowired + private ITestLeaveService testLeaveService; + + /** + * 查询OA 请假申请列表 + */ + @PreAuthorize("@ss.hasPermi('system:leave:list')") + @GetMapping("/list") + public TableDataInfo list(TestLeave testLeave) + { + startPage(); + List list = testLeaveService.selectTestLeaveList(testLeave); + return getDataTable(list); + } + + /** + * 导出OA 请假申请列表 + */ + @PreAuthorize("@ss.hasPermi('system:leave:export')") + @Log(title = "OA 请假申请", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, TestLeave testLeave) + { + List list = testLeaveService.selectTestLeaveList(testLeave); + ExcelUtil util = new ExcelUtil(TestLeave.class); + util.exportExcel(response, list, "OA 请假申请数据"); + } + + /** + * 获取OA 请假申请详细信息 + */ + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) + { + return success(testLeaveService.selectTestLeaveById(id)); + } + + /** + * 新增OA 请假申请 + */ + @PreAuthorize("@ss.hasPermi('system:leave:add')") + @Log(title = "OA 请假申请", businessType = BusinessType.INSERT) + @PostMapping + @Transactional(rollbackFor = Exception.class) + public AjaxResult add(@RequestBody TestLeave testLeave, String flowStatus) + { + return toAjax(testLeaveService.insertTestLeave(testLeave, flowStatus)); + } + + /** + * 修改OA 请假申请 + */ + @PreAuthorize("@ss.hasPermi('system:leave:edit')") + @Log(title = "OA 请假申请", businessType = BusinessType.UPDATE) + @PutMapping + @Transactional(rollbackFor = Exception.class) + public AjaxResult edit(@RequestBody TestLeave testLeave) + { + return toAjax(testLeaveService.updateTestLeave(testLeave)); + } + + /** + * 删除OA 请假申请 + */ + @PreAuthorize("@ss.hasPermi('system:leave:remove')") + @Log(title = "OA 请假申请", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + @Transactional(rollbackFor = Exception.class) + public AjaxResult remove(@PathVariable String[] ids) + { + return toAjax(testLeaveService.deleteTestLeaveByIds(ids)); + } + + /** + * 提交审批 + */ + @PreAuthorize("@ss.hasPermi('system:leave:submit')") + @Log(title = "OA 请假申请", businessType = BusinessType.OTHER) + @GetMapping(value = "/submit") + @Transactional(rollbackFor = Exception.class) + public AjaxResult submit(String id, String flowStatus) { + return toAjax(testLeaveService.submit(id, flowStatus)); + } + + /** + * 办理 + */ + @Log(title = "流程实例", businessType = BusinessType.OTHER) + @PostMapping("/handle") + @Transactional(rollbackFor = Exception.class) + public AjaxResult handle(@RequestBody TestLeave testLeave, Long taskId, String skipType, String message + , String nodeCode, String flowStatus) { + return toAjax(testLeaveService.handle(testLeave, taskId, skipType, message, nodeCode, flowStatus)); + } + + /** + * 终止流程,提前结束 + * + * @param testLeave + * @return + */ + @PostMapping("/termination") + @Transactional(rollbackFor = Exception.class) + public AjaxResult termination(@RequestBody TestLeave testLeave) { + return toAjax(testLeaveService.termination(testLeave)); + } + +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/config/WarmFlowConfig.java b/czsj-system/src/main/java/com/czsj/oaLeave/config/WarmFlowConfig.java new file mode 100644 index 0000000..8329b67 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/config/WarmFlowConfig.java @@ -0,0 +1,41 @@ +package com.czsj.oaLeave.config; + +import com.czsj.oaLeave.handle.CustomDataFillHandler; +import com.czsj.oaLeave.handle.CustomPermissionHandler; +import org.dromara.warm.flow.core.handler.DataFillHandler; +import org.dromara.warm.flow.core.handler.PermissionHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * warm-flow配置文件 + * + * @author warm + */ +@Configuration +public class WarmFlowConfig { + + /** + * 自定义填充 (可配置文件注入,也可用@Bean/@Component方式) + */ + @Bean + public DataFillHandler dataFillHandler() { + return new CustomDataFillHandler(); + } + + /** + * 权限校验器 (可配置文件注入,也可用@Bean/@Component方式) + */ + @Bean + public PermissionHandler permissionHandler() { + return new CustomPermissionHandler(); + } + +// /** +// * 全局租户处理器(可配置文件注入,也可用@Bean/@Component方式) +// */ +// @Bean +// public TenantHandler tenantHandler() { +// return new CustomTenantHandler(); +// } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/domain/TestLeave.java b/czsj-system/src/main/java/com/czsj/oaLeave/domain/TestLeave.java new file mode 100644 index 0000000..286bdb0 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/domain/TestLeave.java @@ -0,0 +1,211 @@ +package com.czsj.oaLeave.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.czsj.common.annotation.Excel; +import com.czsj.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.Date; +import java.util.List; + +/** + * OA 请假申请对象 test_leave + * + * @author czsj + * @date 2024-03-07 + */ +public class TestLeave extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private String id; + + /** 请假类型 */ + @Excel(name = "请假类型") + private Long type; + + /** 请假原因 */ + private String reason; + + /** 开始时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date startTime; + + /** 结束时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date endTime; + + /** 请假天数 */ + @Excel(name = "请假天数") + private Long day; + + /** 流程实例的id */ + private Long instanceId; + + /** 节点编码 */ + private String nodeCode; + + /** 流程节点名称 */ + @Excel(name = "流程节点名称") + private String nodeName; + + /** + * 节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关) + */ + private Integer nodeType; + + /** 流程状态(0待提交 1审批中 2 审批通过 3自动通过 4终止 5作废 6撤销 7取回 8已完成 9已退回 10失效) */ + @Excel(name = "流程状态", readConverterExp = "0=待提交,1=审批中,2=,审=批通过,8=已完成,9=已退回,1=0失效") + private String flowStatus; + + /**抄送人*/ + private List additionalHandler; + + /** 删除标志(0代表存在 2代表删除) */ + private String delFlag; + + public void setId(String id) + { + this.id = id; + } + + public String getId() + { + return id; + } + public void setType(Long type) + { + this.type = type; + } + + public Long getType() + { + return type; + } + public void setReason(String reason) + { + this.reason = reason; + } + + public String getReason() + { + return reason; + } + public void setStartTime(Date startTime) + { + this.startTime = startTime; + } + + public Date getStartTime() + { + return startTime; + } + public void setEndTime(Date endTime) + { + this.endTime = endTime; + } + + public Date getEndTime() + { + return endTime; + } + public void setDay(Long day) + { + this.day = day; + } + + public Long getDay() + { + return day; + } + public void setInstanceId(Long instanceId) + { + this.instanceId = instanceId; + } + + public Long getInstanceId() + { + return instanceId; + } + public void setNodeCode(String nodeCode) + { + this.nodeCode = nodeCode; + } + + public String getNodeCode() + { + return nodeCode; + } + public void setNodeName(String nodeName) + { + this.nodeName = nodeName; + } + + public String getNodeName() + { + return nodeName; + } + + public Integer getNodeType() { + return nodeType; + } + + public TestLeave setNodeType(Integer nodeType) { + this.nodeType = nodeType; + return this; + } + + public void setFlowStatus(String flowStatus) + { + this.flowStatus = flowStatus; + } + + public String getFlowStatus() + { + return flowStatus; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public List getAdditionalHandler() + { + return additionalHandler; + } + public void setAdditionalHandler(List additionalHandler) + { + this.additionalHandler=additionalHandler; + } + public String getDelFlag() + { + return delFlag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("type", getType()) + .append("reason", getReason()) + .append("startTime", getStartTime()) + .append("endTime", getEndTime()) + .append("day", getDay()) + .append("instanceId", getInstanceId()) + .append("nodeCode", getNodeCode()) + .append("nodeName", getNodeName()) + .append("nodeType", getNodeType()) + .append("flowStatus", getFlowStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .toString(); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/enums/FlowType.java b/czsj-system/src/main/java/com/czsj/oaLeave/enums/FlowType.java new file mode 100644 index 0000000..1c97e84 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/enums/FlowType.java @@ -0,0 +1,55 @@ +package com.czsj.oaLeave.enums; + +/** + * 流程类型枚举 + * + * @author warm + * @since 2023/3/31 12:16 + */ +public enum FlowType { + /** + * 请假流程 + */ + TEST_LEAVE_SERIAL1("leaveFlow-serial1", "串行-简单"), + TEST_LEAVE_FORM1("leaveFlow-form1", "表单-简单"), + TEST_LEAVE_SERIAL2("leaveFlow-serial2", "串行-通过互斥"), + TEST_LEAVE_SERIAL3("leaveFlow-serial3", "串行-退回互斥"), + TEST_LEAVE_PARALLEL1("leaveFlow-parallel1", "并行-汇聚"), + TEST_LEAVE_PARALLEL2("leaveFlow-parallel2", "并行-分开"), + leaveFlow_meet_sign("leaveFlow-meet-sign", "会签"), + leaveFlow_vote_sign("leaveFlow-vote-sign", "票签"); + + private String key; + private String value; + + FlowType(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public String getValue() { + return value; + } + + public static String getKeyByValue(String value) { + for (FlowType item : FlowType.values()) { + if (item.getValue().equals(value)) { + return item.getKey(); + } + } + return null; + } + + public static String getValueByKey(String key) { + for (FlowType item : FlowType.values()) { + if (item.getKey().equals(key)) { + return item.getValue(); + } + } + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/handle/CustomDataFillHandler.java b/czsj-system/src/main/java/com/czsj/oaLeave/handle/CustomDataFillHandler.java new file mode 100644 index 0000000..dc634c3 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/handle/CustomDataFillHandler.java @@ -0,0 +1,44 @@ +package com.czsj.oaLeave.handle; + +import org.dromara.warm.flow.core.entity.RootEntity; +import org.dromara.warm.flow.core.handler.DataFillHandler; +import org.dromara.warm.flow.core.utils.IdUtils; +import org.dromara.warm.flow.core.utils.ObjectUtil; + +import java.util.Date; +import java.util.Objects; + +/** + * 填充器 (可通过配置文件注入,也可用@Bean/@Component方式) + * + * @author warm + */ +public class CustomDataFillHandler implements DataFillHandler { + + @Override + public void idFill(Object object) { + RootEntity entity = (RootEntity) object; + if (ObjectUtil.isNotNull(entity)) { + if (Objects.isNull(entity.getId())) { + entity.setId(IdUtils.nextId()); + } + } + } + + @Override + public void insertFill(Object object) { + RootEntity entity = (RootEntity) object; + if (ObjectUtil.isNotNull(entity)) { + entity.setCreateTime(ObjectUtil.isNotNull(entity.getCreateTime()) ? entity.getCreateTime() : new Date()); + entity.setUpdateTime(ObjectUtil.isNotNull(entity.getUpdateTime()) ? entity.getUpdateTime() : new Date()); + } + } + + @Override + public void updateFill(Object object) { + RootEntity entity = (RootEntity) object; + if (ObjectUtil.isNotNull(entity)) { + entity.setUpdateTime(ObjectUtil.isNotNull(entity.getUpdateTime()) ? entity.getUpdateTime() : new Date()); + } + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/handle/CustomPermissionHandler.java b/czsj-system/src/main/java/com/czsj/oaLeave/handle/CustomPermissionHandler.java new file mode 100644 index 0000000..f5b43e0 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/handle/CustomPermissionHandler.java @@ -0,0 +1,49 @@ +package com.czsj.oaLeave.handle; + +import com.czsj.common.core.domain.entity.SysRole; +import com.czsj.common.core.domain.entity.SysUser; +import com.czsj.common.utils.SecurityUtils; +import org.dromara.warm.flow.core.handler.PermissionHandler; +import org.dromara.warm.flow.core.utils.StreamUtils; + +import java.util.List; + +/** + * 办理人权限处理器(可通过配置文件注入,也可用@Bean/@Component方式) + * + * @author shadow + */ +public class CustomPermissionHandler implements PermissionHandler { + + /** + * 获取当前操作用户所有权限 + */ + @Override + public List permissions() { + // 办理人权限标识,比如用户,角色,部门等, 流程设计时未设置办理人或者ignore为true可不传 [按需传输] + SysUser sysUser = SecurityUtils.getLoginUser().getUser(); + List roles = sysUser.getRoles(); + List permissionList = StreamUtils.toList(roles, role -> "role:" + role.getRoleId()); + if (sysUser.getUserId() != null) { + permissionList.add(String.valueOf(sysUser.getUserId())); + } + if (sysUser.getDeptId() != null) { + permissionList.add("dept:" + sysUser.getDeptId()); + } + return permissionList; + } + + /** + * 获取当前办理人 + * @return 当前办理人 + */ + @Override + public String getHandler() { + SysUser sysUser = SecurityUtils.getLoginUser().getUser(); + if (sysUser.getUserId() != null) { + return String.valueOf(sysUser.getUserId()); + } + return null; + } + +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/handle/CustomTenantHandler.java b/czsj-system/src/main/java/com/czsj/oaLeave/handle/CustomTenantHandler.java new file mode 100644 index 0000000..91dc206 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/handle/CustomTenantHandler.java @@ -0,0 +1,18 @@ +package com.czsj.oaLeave.handle; + +import org.dromara.warm.flow.core.handler.TenantHandler; + +/** + * 全局租户处理器(可通过配置文件注入,也可用@Bean/@Component方式 + * + * @author warm + */ +public class CustomTenantHandler implements TenantHandler { + + + @Override + public String getTenantId() { + // 这里返回系统中的当前办理人的租户ID,一般会有工具类获取 + return "000000"; + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/listener/AssignmentExpListener.java b/czsj-system/src/main/java/com/czsj/oaLeave/listener/AssignmentExpListener.java new file mode 100644 index 0000000..789300f --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/listener/AssignmentExpListener.java @@ -0,0 +1,56 @@ +/* + * Copyright 2024-2025, Warm-Flow (290631660@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.czsj.oaLeave.listener; + +import org.dromara.warm.flow.core.constant.FlowCons; +import org.dromara.warm.flow.core.entity.Instance; +import org.dromara.warm.flow.core.entity.Task; +import org.dromara.warm.flow.core.listener.ListenerVariable; +import org.dromara.warm.flow.core.utils.CollUtil; +import org.dromara.warm.flow.core.utils.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 分派监听器表达式 + */ +@Component +public class AssignmentExpListener { + + private static final Logger log = LoggerFactory.getLogger(AssignmentExpListener.class); + + public void notify(ListenerVariable listenerVariable) { + log.info("分派监听器表达式开始执行......"); + List tasks = listenerVariable.getNextTasks(); + Instance instance = listenerVariable.getInstance(); + if (CollUtil.isNotEmpty(tasks)) { + for (Task task : tasks) { + List permissionList = task.getPermissionList(); + // 如果设置了发起人审批,则需要动态替换权限标识 + for (int i = 0; i < permissionList.size(); i++) { + String permission = permissionList.get(i); + if (StringUtils.isNotEmpty(permission) && permission.contains(FlowCons.WARMFLOWINITIATOR)) { + permissionList.set(i, permission.replace(FlowCons.WARMFLOWINITIATOR, instance.getCreateBy())); + } + } + } + } + log.info("分派监听器表达式执行结束......"); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/listener/AssignmentListener.java b/czsj-system/src/main/java/com/czsj/oaLeave/listener/AssignmentListener.java new file mode 100644 index 0000000..7d98ed2 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/listener/AssignmentListener.java @@ -0,0 +1,58 @@ +/* + * Copyright 2024-2025, Warm-Flow (290631660@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.czsj.oaLeave.listener; + +import org.dromara.warm.flow.core.constant.FlowCons; +import org.dromara.warm.flow.core.entity.Instance; +import org.dromara.warm.flow.core.entity.Task; +import org.dromara.warm.flow.core.listener.Listener; +import org.dromara.warm.flow.core.listener.ListenerVariable; +import org.dromara.warm.flow.core.utils.CollUtil; +import org.dromara.warm.flow.core.utils.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 分派监听器 + */ +@Component +public class AssignmentListener implements Listener { + + private static final Logger log = LoggerFactory.getLogger(AssignmentListener.class); + + @Override + public void notify(ListenerVariable listenerVariable) { + log.info("分派监听器开始执行......"); + List tasks = listenerVariable.getNextTasks(); + Instance instance = listenerVariable.getInstance(); + if (CollUtil.isNotEmpty(tasks)) { + for (Task task : tasks) { + List permissionList = task.getPermissionList(); + // 如果设置了发起人审批,则需要动态替换权限标识 + for (int i = 0; i < permissionList.size(); i++) { + String permission = permissionList.get(i); + if (StringUtils.isNotEmpty(permission) && permission.contains(FlowCons.WARMFLOWINITIATOR)) { + permissionList.set(i, permission.replace(FlowCons.WARMFLOWINITIATOR, instance.getCreateBy())); + } + } + } + } + log.info("分派监听器执行结束......"); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/listener/CreateListener.java b/czsj-system/src/main/java/com/czsj/oaLeave/listener/CreateListener.java new file mode 100644 index 0000000..8788c9b --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/listener/CreateListener.java @@ -0,0 +1,34 @@ +package com.czsj.oaLeave.listener; + +import com.czsj.common.utils.StringUtils; +import com.czsj.oaLeave.mapper.TestLeaveMapper; +import org.dromara.warm.flow.core.entity.Instance; +import org.dromara.warm.flow.core.listener.Listener; +import org.dromara.warm.flow.core.listener.ListenerVariable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Map; + +@Component +public class CreateListener implements Listener { + + @Resource + private TestLeaveMapper testLeaveMapper; + + private static final Logger log = LoggerFactory.getLogger(CreateListener.class); + + @Override + public void notify(ListenerVariable listenerVariable) { + log.info("创建监听器......"); + Instance instance = listenerVariable.getInstance(); + Map variable = listenerVariable.getVariable(); + if (StringUtils.isNotNull(variable)) { + String businessId = instance.getBusinessId(); + Object businessType = variable.get("businessType"); + } + log.info("创建监听器结束......"); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/listener/CustomGlobalListener.java b/czsj-system/src/main/java/com/czsj/oaLeave/listener/CustomGlobalListener.java new file mode 100644 index 0000000..82976df --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/listener/CustomGlobalListener.java @@ -0,0 +1,76 @@ +/* + * Copyright 2024-2025, Warm-Flow (290631660@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.czsj.oaLeave.listener; + +import org.dromara.warm.flow.core.listener.GlobalListener; +import org.dromara.warm.flow.core.listener.ListenerVariable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * 全局监听器: 整个系统只有一个,任务开始、分派、完成和创建时期执行 + * + * @author warm + * @since 2024/11/17 + */ +@Component +public class CustomGlobalListener implements GlobalListener { + + private static final Logger log = LoggerFactory.getLogger(CustomGlobalListener.class); + + /** + * 开始监听器,任务开始办理时执行 + * @param listenerVariable 监听器变量 + */ + public void start(ListenerVariable listenerVariable) { + log.info("全局开始监听器开始执行......"); + + log.info("全局开始监听器执行结束......"); + + } + + /** + * 分派监听器,动态修改代办任务信息 + * @param listenerVariable 监听器变量 + */ + public void assignment(ListenerVariable listenerVariable) { + log.info("全局分派监听器开始执行......"); + + log.info("全局分派监听器执行结束......"); + } + + /** + * 完成监听器,当前任务完成后执行 + * @param listenerVariable 监听器变量 + */ + public void finish(ListenerVariable listenerVariable) { + log.info("全局完成监听器开始执行......"); + + log.info("全局完成监听器执行结束......"); + } + + /** + * 创建监听器,任务创建时执行 + * @param listenerVariable 监听器变量 + */ + public void create(ListenerVariable listenerVariable) { + log.info("全局创建监听器开始执行......"); + + log.info("全局创建监听器执行结束......"); + } + +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/listener/DefAssignmentListener.java b/czsj-system/src/main/java/com/czsj/oaLeave/listener/DefAssignmentListener.java new file mode 100644 index 0000000..72bd6e3 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/listener/DefAssignmentListener.java @@ -0,0 +1,58 @@ +/* + * Copyright 2024-2025, Warm-Flow (290631660@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.czsj.oaLeave.listener; + +import org.dromara.warm.flow.core.constant.FlowCons; +import org.dromara.warm.flow.core.entity.Instance; +import org.dromara.warm.flow.core.entity.Task; +import org.dromara.warm.flow.core.listener.Listener; +import org.dromara.warm.flow.core.listener.ListenerVariable; +import org.dromara.warm.flow.core.utils.CollUtil; +import org.dromara.warm.flow.core.utils.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 流程分派监听器 + */ +@Component +public class DefAssignmentListener implements Listener { + + private static final Logger log = LoggerFactory.getLogger(DefAssignmentListener.class); + + @Override + public void notify(ListenerVariable listenerVariable) { + log.info("流程分派监听器开始执行......"); + List tasks = listenerVariable.getNextTasks(); + Instance instance = listenerVariable.getInstance(); + if (CollUtil.isNotEmpty(tasks)) { + for (Task task : tasks) { + List permissionList = task.getPermissionList(); + // 如果设置了发起人审批,则需要动态替换权限标识 + for (int i = 0; i < permissionList.size(); i++) { + String permission = permissionList.get(i); + if (StringUtils.isNotEmpty(permission) && permission.contains(FlowCons.WARMFLOWINITIATOR)) { + permissionList.set(i, permission.replace(FlowCons.WARMFLOWINITIATOR, instance.getCreateBy())); + } + } + } + } + log.info("流程分派监听器执行结束......"); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/listener/DefCreateListener.java b/czsj-system/src/main/java/com/czsj/oaLeave/listener/DefCreateListener.java new file mode 100644 index 0000000..ec92cdb --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/listener/DefCreateListener.java @@ -0,0 +1,39 @@ +/* + * Copyright 2024-2025, Warm-Flow (290631660@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.czsj.oaLeave.listener; + +import org.dromara.warm.flow.core.entity.Instance; +import org.dromara.warm.flow.core.listener.Listener; +import org.dromara.warm.flow.core.listener.ListenerVariable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +public class DefCreateListener implements Listener { + + private static final Logger log = LoggerFactory.getLogger(DefCreateListener.class); + + @Override + public void notify(ListenerVariable listenerVariable) { + log.info("流程创建监听器......"); + Instance instance = listenerVariable.getInstance(); + Map variable = listenerVariable.getVariable(); + log.info("流程创建监听器结束......"); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/listener/DefFinishListener.java b/czsj-system/src/main/java/com/czsj/oaLeave/listener/DefFinishListener.java new file mode 100644 index 0000000..10859c8 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/listener/DefFinishListener.java @@ -0,0 +1,85 @@ +/* + * Copyright 2024-2025, Warm-Flow (290631660@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.czsj.oaLeave.listener; + +import com.czsj.common.utils.StringUtils; +import com.czsj.oaLeave.mapper.TestLeaveMapper; +import org.dromara.warm.flow.core.entity.Instance; +import org.dromara.warm.flow.core.listener.Listener; +import org.dromara.warm.flow.core.listener.ListenerVariable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Map; + +@Component +public class DefFinishListener implements Listener { + + + private static final Logger log = LoggerFactory.getLogger(DefFinishListener.class); + + @Resource + private TestLeaveMapper testLeaveMapper; + + /** + * 组件办理完成后,通常需要业务表新增或者更新操作 + * 也可以放到业务代码中办理完成后,或者节点监听器 + * @param listenerVariable 监听器变量 + */ + @Override + public void notify(ListenerVariable listenerVariable) { + log.info("流程完成监听器......"); + + Instance instance = listenerVariable.getInstance(); + Map variable = listenerVariable.getVariable(); + if (StringUtils.isNotNull(variable)) { + String businessId = instance.getBusinessId(); + Object businessType = variable.get("businessType"); +// /** 如果{@link com.czsj.system.service.impl.TestLeaveServiceImpl}中更新了,这里就不用更新了*/ +// // 更新业务数据 +// if ("testLeave".equals(businessType)) { +// // 可以统一使用一个流程监听器,不同实体类,不同的操作 +// TestLeave testLeave = testLeaveMapper.selectTestLeaveById(businessId); +// if (ObjectUtil.isNull(testLeave)) { +// testLeave = (TestLeave) variable.get("businessData"); +// } +// testLeave.setNodeCode(instance.getNodeCode()); +// testLeave.setNodeName(instance.getNodeName()); +// testLeave.setNodeType(instance.getNodeType()); +// testLeave.setFlowStatus(instance.getFlowStatus()); +// // 如果没有实例id,说明是新增 +// if (ObjectUtil.isNull(testLeave.getInstanceId())) { +// testLeave.setInstanceId(instance.getId()); +// testLeaveMapper.insertTestLeave(testLeave); +// testLeave.setCreateTime(DateUtils.getNowDate()); +// // 新增抄送人方法,也可发送通知 +// if (StringUtils.isNotNull(testLeave.getAdditionalHandler())) { +// List users = FlowEngine.userService().structureUser(instance.getId() +// , testLeave.getAdditionalHandler(), "4"); +// FlowEngine.userService().saveBatch(users); +// } +// } else { +// testLeave.setUpdateTime(DateUtils.getNowDate()); +// testLeaveMapper.updateTestLeave(testLeave); +// } +// } + } + + log.info("流程完成监听器结束......"); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/listener/DefStartListener.java b/czsj-system/src/main/java/com/czsj/oaLeave/listener/DefStartListener.java new file mode 100644 index 0000000..218875b --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/listener/DefStartListener.java @@ -0,0 +1,61 @@ +/* + * Copyright 2024-2025, Warm-Flow (290631660@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.czsj.oaLeave.listener; + +import org.dromara.warm.flow.core.listener.Listener; +import org.dromara.warm.flow.core.listener.ListenerVariable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class DefStartListener implements Listener { + + + private static final Logger log = LoggerFactory.getLogger(DefStartListener.class); + + /** + * 在开始监听器中预先设置办理人id、所拥有的权限等操作,减少重复代码 + * 也可以放到业务代码中办理前设置,或者节点监听器 + * @param listenerVariable 监听器变量 + */ + @Override + public void notify(ListenerVariable listenerVariable) { + log.info("流程开始监听器......"); + +// /** 如果{@link com.czsj.system.service.impl.TestLeaveServiceImpl}中传值了,这里就不用设置*/ +// FlowParams flowParams = listenerVariable.getFlowParams(); +// LoginUser user = SecurityUtils.getLoginUser(); +// // 设置当前办理人id +// flowParams.handler(user.getUser().getUserId().toString()); +// +// // 设置办理人所拥有的权限,比如角色、部门、用户等 +// List permissionList = flowParams.getPermissionFlag(); +// if (StringUtils.isEmpty(permissionList)) { +// permissionList = new ArrayList<>(); +// } +// +// List roles = user.getUser().getRoles(); +// if (Objects.nonNull(roles)) { +// permissionList.addAll(roles.stream().map(role -> "role:" + role.getRoleId()).collect(Collectors.toList())); +// } +// permissionList.add("dept:" + SecurityUtils.getLoginUser().getUser().getDeptId()); +// permissionList.add(user.getUser().getUserId().toString()); +// flowParams.permissionFlag(permissionList); + + log.info("流程开始监听器结束......"); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/listener/FinishListener.java b/czsj-system/src/main/java/com/czsj/oaLeave/listener/FinishListener.java new file mode 100644 index 0000000..d45eeab --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/listener/FinishListener.java @@ -0,0 +1,34 @@ +package com.czsj.oaLeave.listener; + +import com.czsj.common.utils.StringUtils; +import com.czsj.oaLeave.mapper.TestLeaveMapper; +import org.dromara.warm.flow.core.entity.Instance; +import org.dromara.warm.flow.core.listener.Listener; +import org.dromara.warm.flow.core.listener.ListenerVariable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Map; + +@Component +public class FinishListener implements Listener { + + @Resource + private TestLeaveMapper testLeaveMapper; + + private static final Logger log = LoggerFactory.getLogger(FinishListener.class); + + @Override + public void notify(ListenerVariable listenerVariable) { + log.info("完成监听器......"); + Instance instance = listenerVariable.getInstance(); + Map variable = listenerVariable.getVariable(); + if (StringUtils.isNotNull(variable)) { + String businessId = instance.getBusinessId(); + Object businessType = variable.get("businessType"); + } + log.info("完成监听器结束......"); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/listener/LeaveEditFormHandleListener.java b/czsj-system/src/main/java/com/czsj/oaLeave/listener/LeaveEditFormHandleListener.java new file mode 100644 index 0000000..27c8807 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/listener/LeaveEditFormHandleListener.java @@ -0,0 +1,59 @@ +package com.czsj.oaLeave.listener; + +import com.czsj.oaLeave.domain.TestLeave; +import com.czsj.oaLeave.service.ITestLeaveService; +import org.apache.commons.lang3.time.DateUtils; +import org.dromara.warm.flow.core.listener.Listener; +import org.dromara.warm.flow.core.listener.ListenerVariable; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.text.ParseException; +import java.util.Map; + +/** + * @author vanlin + * @className LeaveEditFormHandleListener + * @description 用于流程表单项目保存数据演示 属于 完成监听器 + * @since 2024-11-2 17:01 + */ +@Component +public class LeaveEditFormHandleListener implements Listener { + @Resource + private ITestLeaveService testLeaveService; + + @Override + public void notify(ListenerVariable listenerVariable) { + // 获取请假详情 + // 表单处理监听器,修改业务参数 + String businessId = listenerVariable.getInstance().getBusinessId(); + + TestLeave testLeave = testLeaveService.selectTestLeaveById(businessId); + + Map formData = listenerVariable.getVariable(); + // reason 请假原因 + // startTime 开始时间 + // endTime 结束时间 + // day 天数 + try { + testLeave.setReason(formData.get("reason").toString()); + testLeave.setStartTime(DateUtils.parseDate(formData.get("startTime").toString(), "yyyy-MM-dd")); + testLeave.setEndTime(DateUtils.parseDate(formData.get("endTime").toString(), "yyyy-MM-dd")); + testLeave.setDay(Long.valueOf(formData.get("day").toString())); + } catch (ParseException e) { + throw new RuntimeException(e); + } + + // 更新请假表,以下字段需要在 formHandleAfter处理??? +// testLeave.setNodeCode(listenerVariable.getInstance().getNodeCode()); +// testLeave.setNodeName(listenerVariable.getInstance().getNodeName()); +// testLeave.setNodeType(listenerVariable.getInstance().getNodeType()); +// testLeave.setFlowStatus(listenerVariable.getInstance().getFlowStatus()); + testLeaveService.updateTestLeave(testLeave); + + // 流程变量传递业务数据,按实际业务需求传递 【按需传】 + listenerVariable.getFlowParams().getVariable().put("businessData", testLeave); + // 办理人变量表达式替换 【按需传】 + listenerVariable.getFlowParams().getVariable().put("flag", String.valueOf(testLeave.getDay())); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/listener/LeaveFormLoadListener.java b/czsj-system/src/main/java/com/czsj/oaLeave/listener/LeaveFormLoadListener.java new file mode 100644 index 0000000..3c43c97 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/listener/LeaveFormLoadListener.java @@ -0,0 +1,48 @@ +package com.czsj.oaLeave.listener; + +import com.czsj.oaLeave.domain.TestLeave; +import com.czsj.oaLeave.service.ITestLeaveService; +import org.dromara.warm.flow.core.constant.FlowCons; +import org.dromara.warm.flow.core.listener.Listener; +import org.dromara.warm.flow.core.listener.ListenerVariable; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author vanlin + * @className LeaveFormLoadListener + * @description 用于流程表单从业务功能加载数据演示 + * @since 2024-11-2 17:01 + */ +@Component +public class LeaveFormLoadListener implements Listener { + @Resource + private ITestLeaveService testLeaveService; + + @Override + public void notify(ListenerVariable listenerVariable) { + // 获取请假详情 + // 全局表单加载器,加载表单业务数据,按map返回 + String businessId = listenerVariable.getInstance().getBusinessId(); + + TestLeave testLeave = testLeaveService.selectTestLeaveById(businessId); + final Map formData = new HashMap(); + // reason 请假原因 + // startTime 开始时间 + // endTime 结束时间 + // day 天数 + formData.put("reason", testLeave.getReason()); + List time = new ArrayList(); + time.add(String.valueOf(testLeave.getStartTime())); + time.add(String.valueOf(testLeave.getEndTime())); + formData.put("time", time); + formData.put("day", testLeave.getDay()); + + listenerVariable.getInstance().getVariableMap().put(FlowCons.FORM_DATA, formData); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/listener/StartListener.java b/czsj-system/src/main/java/com/czsj/oaLeave/listener/StartListener.java new file mode 100644 index 0000000..7351ad2 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/listener/StartListener.java @@ -0,0 +1,25 @@ +package com.czsj.oaLeave.listener; + +import org.dromara.warm.flow.core.entity.Instance; +import org.dromara.warm.flow.core.listener.Listener; +import org.dromara.warm.flow.core.listener.ListenerVariable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +public class StartListener implements Listener { + + private static final Logger log = LoggerFactory.getLogger(StartListener.class); + + @Override + public void notify(ListenerVariable listenerVariable) { + log.info("开始监听器......"); + Instance instance = listenerVariable.getInstance(); + Map variableMap = listenerVariable.getVariable(); + + log.info("开始监听器结束......"); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/mapper/TestLeaveMapper.java b/czsj-system/src/main/java/com/czsj/oaLeave/mapper/TestLeaveMapper.java new file mode 100644 index 0000000..67fc899 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/mapper/TestLeaveMapper.java @@ -0,0 +1,70 @@ +package com.czsj.oaLeave.mapper; + +import com.czsj.oaLeave.domain.TestLeave; + +import java.util.List; + +/** + * OA 请假申请Mapper接口 + * + * @author czsj + * @date 2024-03-07 + */ +public interface TestLeaveMapper +{ + /** + * 查询OA 请假申请 + * + * @param id OA 请假申请主键 + * @return OA 请假申请 + */ + public TestLeave selectTestLeaveById(String id); + + /** + * 查询OA 请假申请 + * + * @param ids OA 请假申请主键s + * @return OA 请假申请 + */ + public List selectTestLeaveByIds(String[] ids); + + /** + * 查询OA 请假申请列表 + * + * @param testLeave OA 请假申请 + * @return OA 请假申请集合 + */ + public List selectTestLeaveList(TestLeave testLeave); + + /** + * 新增OA 请假申请 + * + * @param testLeave OA 请假申请 + * @return 结果 + */ + public int insertTestLeave(TestLeave testLeave); + + /** + * 修改OA 请假申请 + * + * @param testLeave OA 请假申请 + * @return 结果 + */ + public int updateTestLeave(TestLeave testLeave); + + /** + * 删除OA 请假申请 + * + * @param id OA 请假申请主键 + * @return 结果 + */ + public int deleteTestLeaveById(String id); + + /** + * 批量删除OA 请假申请 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteTestLeaveByIds(String[] ids); +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/service/HandlerSelectServiceImpl.java b/czsj-system/src/main/java/com/czsj/oaLeave/service/HandlerSelectServiceImpl.java new file mode 100644 index 0000000..1eafa5a --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/service/HandlerSelectServiceImpl.java @@ -0,0 +1,166 @@ +package com.czsj.oaLeave.service; + +import com.github.pagehelper.PageInfo; +import com.czsj.common.core.domain.entity.SysDept; +import com.czsj.common.core.domain.entity.SysRole; +import com.czsj.common.core.domain.entity.SysUser; +import com.czsj.common.utils.DateUtils; +import com.czsj.system.mapper.SysDeptMapper; +import com.czsj.system.mapper.SysRoleMapper; +import com.czsj.system.mapper.SysUserMapper; +import org.dromara.warm.flow.core.utils.MathUtil; +import org.dromara.warm.flow.ui.dto.HandlerFunDto; +import org.dromara.warm.flow.ui.dto.HandlerQuery; +import org.dromara.warm.flow.ui.dto.TreeFunDto; +import org.dromara.warm.flow.ui.service.HandlerSelectService; +import org.dromara.warm.flow.ui.vo.HandlerSelectVo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + +import static com.czsj.common.utils.PageUtils.startPage; + +/** + * 流程设计器-获取办理人权限设置列表接口实现类 + * + * @author warm + */ +@Component +public class HandlerSelectServiceImpl implements HandlerSelectService { + @Autowired + private SysUserMapper userMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysDeptMapper deptMapper; + + /** + * 获取办理人权限设置列表tabs页签,如:用户、角色和部门等,可以返回其中一种或者多种,按业务需求决定 + * @return tabs页签 + */ + @Override + public List getHandlerType() { + return Arrays.asList("用户", "角色", "部门"); + } + + /** + * 获取用户列表、角色列表、部门列表等,可以返回其中一种或者多种,按业务需求决定 + * @param query 查询参数 + * @return 结果 + */ + @Override + public HandlerSelectVo getHandlerSelect(HandlerQuery query) { + + if ("角色".equals(query.getHandlerType())) { + return getRole(query); + } + + if ("部门".equals(query.getHandlerType())) { + return getDept(query); + } + + if ("用户".equals(query.getHandlerType())) { + return getUser(query); + } + + return new HandlerSelectVo(); + } + + /** + * 获取角色列表 + * + * @param query 查询条件 + * @return HandlerSelectVo + */ + private HandlerSelectVo getRole(HandlerQuery query) { + startPage(); + SysRole sysRole = new SysRole(); + sysRole.setRoleKey(query.getHandlerCode()); + sysRole.setRoleName(query.getHandlerName()); + sysRole.getParams().put("beginTime", query.getBeginTime()); + sysRole.getParams().put("endTime", query.getEndTime()); + // 查询角色列表 + List roleList = roleMapper.selectRoleList(sysRole); + long total = new PageInfo<>(roleList).getTotal(); + + // 业务系统数据,转成组件内部能够显示的数据, total是业务数据总数,用于分页显示 + HandlerFunDto handlerFunDto = new HandlerFunDto<>(roleList, total) + // 以下设置获取内置变量的Function + .setStorageId(role -> "role:" + role.getRoleId()) // 前面拼接role: 是为了防止用户、角色的主键重复 + .setHandlerCode(SysRole::getRoleKey) // 权限编码 + .setHandlerName(SysRole::getRoleName) // 权限名称 + .setCreateTime(role -> DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, role.getCreateTime())); + + return getHandlerSelectVo(handlerFunDto); + } + + /** + * 获取用户列表 + * + * @param query 查询条件 + * @return HandlerSelectVo + */ + private HandlerSelectVo getDept(HandlerQuery query) { + startPage(); + SysDept sysDept = new SysDept(); + sysDept.setDeptName(query.getHandlerName()); + sysDept.getParams().put("beginTime", query.getBeginTime()); + sysDept.getParams().put("endTime", query.getEndTime()); + // 查询部门列表 + List deptList = deptMapper.selectDeptList(sysDept); + long total = new PageInfo<>(deptList).getTotal(); + + // 业务系统数据,转成组件内部能够显示的数据, total是业务数据总数,用于分页显示 + HandlerFunDto handlerFunDto = new HandlerFunDto<>(deptList, total) + .setStorageId(dept -> "dept:" + dept.getDeptId()) // 前面拼接dept: 是为了防止用户、部门的主键重复 + .setHandlerName(SysDept::getDeptName) // 权限名称 + .setCreateTime(dept -> DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, dept.getCreateTime())); + + return getHandlerSelectVo(handlerFunDto); + + } + + /** + * 获取用户列表, 同时构建左侧部门树状结构 + * + * @param query 查询条件 + * @return HandlerSelectVo + */ + private HandlerSelectVo getUser(HandlerQuery query) { + startPage(); + SysUser sysUser = new SysUser(); + sysUser.setUserName(query.getHandlerCode()); + sysUser.setNickName(query.getHandlerName()); + // 办理人用户选择列表,需要展示左侧树状部门,所以可能会通过部门id + if (MathUtil.isNumeric(query.getGroupId())) { + sysUser.setDeptId(Long.valueOf(query.getGroupId())); + } + sysUser.getParams().put("beginTime", query.getBeginTime()); + sysUser.getParams().put("endTime", query.getEndTime()); + // 查询用户列表 + List userList = userMapper.selectUserList(sysUser); + long total = new PageInfo<>(userList).getTotal(); + // 查询部门列表,构建树状结构 + List deptList = deptMapper.selectDeptList(new SysDept()); + + // 业务系统数据,转成组件内部能够显示的数据, total是业务数据总数,用于分页显示 + HandlerFunDto handlerFunDto = new HandlerFunDto<>(userList, total) + .setStorageId(user -> user.getUserId().toString()) + .setHandlerCode(SysUser::getUserName) // 权限编码 + .setHandlerName(SysUser::getNickName) // 权限名称 + .setCreateTime(user -> DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, user.getCreateTime())) + .setGroupName(user -> user.getDept() != null ? user.getDept().getDeptName() : ""); + + // 业务系统机构,转成组件内部左侧树列表能够显示的数据 + TreeFunDto treeFunDto = new TreeFunDto<>(deptList) + .setId(dept -> dept.getDeptId().toString()) // 左侧树ID + .setName(SysDept::getDeptName) // 左侧树名称 + .setParentId(dept -> dept.getParentId().toString()); // 左侧树父级ID + + return getHandlerSelectVo(handlerFunDto, treeFunDto); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/service/ITestLeaveService.java b/czsj-system/src/main/java/com/czsj/oaLeave/service/ITestLeaveService.java new file mode 100644 index 0000000..4a02b3f --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/service/ITestLeaveService.java @@ -0,0 +1,92 @@ +package com.czsj.oaLeave.service; + +import com.czsj.oaLeave.domain.TestLeave; + +import java.util.List; + +/** + * OA 请假申请Service接口 + * + * @author czsj + * @date 2024-03-07 + */ +public interface ITestLeaveService +{ + /** + * 查询OA 请假申请 + * + * @param id OA 请假申请主键 + * @return OA 请假申请 + */ + public TestLeave selectTestLeaveById(String id); + + /** + * 查询OA 请假申请列表 + * + * @param testLeave OA 请假申请 + * @return OA 请假申请集合 + */ + public List selectTestLeaveList(TestLeave testLeave); + + /** + * 新增OA 请假申请 + * + * @param testLeave OA 请假申请 + * @param flowStatus 自定义流程状态扩展 + * @return 结果 + */ + public int insertTestLeave(TestLeave testLeave, String flowStatus); + + /** + * 修改OA 请假申请 + * + * @param testLeave OA 请假申请 + * @return 结果 + */ + public int updateTestLeave(TestLeave testLeave); + + /** + * 批量删除OA 请假申请 + * + * @param ids 需要删除的OA 请假申请主键集合 + * @return 结果 + */ + public int deleteTestLeaveByIds(String[] ids); + + /** + * 删除OA 请假申请信息 + * + * @param id OA 请假申请主键 + * @return 结果 + */ + public int deleteTestLeaveById(String id); + + /** + * 提交审批 + * + * @param id + * @param flowStatus 自定义流程状态扩展 + * @return + */ + public int submit(String id, String flowStatus); + + /** + * 办理 + * + * @param testLeave + * @param taskId + * @param skipType + * @param message + * @param nodeCode + * @param flowStatus 自定义流程状态扩展 + * @return + */ + int handle(TestLeave testLeave, Long taskId, String skipType, String message, String nodeCode, String flowStatus); + + /** + * 终止流程,提前结束 + * @param testLeave + * @return + */ + int termination(TestLeave testLeave); +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/service/User.java b/czsj-system/src/main/java/com/czsj/oaLeave/service/User.java new file mode 100644 index 0000000..e08dbdc --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/service/User.java @@ -0,0 +1,42 @@ +package com.czsj.oaLeave.service; + +import org.dromara.warm.flow.core.entity.Task; +import org.springframework.stereotype.Component; + +import java.math.BigDecimal; + +/** + * 用户类 + */ +@Component("user") +public class User { + + /** + * spel条件表达:判断大于等4 + * @param flag 待判断的字符串 + * @return boolean + */ + public boolean eval(String flag) { + BigDecimal a = new BigDecimal(flag); + BigDecimal b = new BigDecimal("4"); + return a.compareTo(b) > 0; + } + + /** + * spel办理人变量表达式 + * @param handler 办理人 + * @return String + */ + public Object evalVar(Object handler) { + return handler; + } + + /** + * spel办理人变量表达式 + * @param handler 办理人 + * @return String + */ + public Long evalVarEntity(Task handler) { + return handler.getId(); + } +} diff --git a/czsj-system/src/main/java/com/czsj/oaLeave/service/impl/TestLeaveServiceImpl.java b/czsj-system/src/main/java/com/czsj/oaLeave/service/impl/TestLeaveServiceImpl.java new file mode 100644 index 0000000..dc5c59a --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/oaLeave/service/impl/TestLeaveServiceImpl.java @@ -0,0 +1,304 @@ +package com.czsj.oaLeave.service.impl; + +import com.alibaba.fastjson2.JSON; +import com.czsj.common.core.domain.entity.SysDictData; +import com.czsj.common.core.domain.entity.SysRole; +import com.czsj.common.core.domain.model.LoginUser; +import com.czsj.common.exception.ServiceException; +import com.czsj.common.utils.DateUtils; +import com.czsj.common.utils.SecurityUtils; +import com.czsj.common.utils.StringUtils; +import com.czsj.oaLeave.domain.TestLeave; +import com.czsj.oaLeave.mapper.TestLeaveMapper; +import com.czsj.system.service.ISysDictTypeService; +import com.czsj.oaLeave.service.ITestLeaveService; +import org.dromara.warm.flow.core.FlowEngine; +import org.dromara.warm.flow.core.dto.FlowParams; +import org.dromara.warm.flow.core.entity.Instance; +import org.dromara.warm.flow.core.entity.Task; +import org.dromara.warm.flow.core.entity.User; +import org.dromara.warm.flow.core.enums.SkipType; +import org.dromara.warm.flow.core.service.InsService; +import org.dromara.warm.flow.core.service.TaskService; +import org.dromara.warm.flow.core.utils.CollUtil; +import org.dromara.warm.flow.core.utils.IdUtils; +import org.dromara.warm.flow.core.utils.StreamUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +/** + * OA 请假申请Service业务层处理 + * + * @author czsj + * @date 2024-03-07 + */ +@Service +public class TestLeaveServiceImpl implements ITestLeaveService +{ + @Resource + private TestLeaveMapper testLeaveMapper; + + @Resource + private InsService insService; + + @Resource + private TaskService taskService; + + @Resource + private ISysDictTypeService sysDictTypeService; + + /** + * 查询OA 请假申请 + * + * @param id OA 请假申请主键 + * @return OA 请假申请 + */ + @Override + public TestLeave selectTestLeaveById(String id) + { + TestLeave testLeave = testLeaveMapper.selectTestLeaveById(id); + List permission = FlowEngine.userService().getPermission(testLeave.getInstanceId(), "4"); + if (CollUtil.isNotEmpty(permission)) { + testLeave.setAdditionalHandler(permission); + }else { + testLeave.setAdditionalHandler(new ArrayList<>()); + } + return testLeave; + } + + /** + * 查询OA 请假申请列表 + * + * @param testLeave OA 请假申请 + * @return OA 请假申请 + */ + @Override + public List selectTestLeaveList(TestLeave testLeave) + { + return testLeaveMapper.selectTestLeaveList(testLeave); + } + + /** + * 新增OA 请假申请 + * + * @param testLeave OA 请假申请 + * @return 结果 + */ + @Override + public int insertTestLeave(TestLeave testLeave, String flowStatus) + { + // 设置流转参数 + String id = IdUtils.nextIdStr(); + testLeave.setId(id); + LoginUser user = SecurityUtils.getLoginUser(); + // 从字典表中获取流程编码 + String flowCode = getFlowType(testLeave); + // 传递流程编码,绑定流程定义 【必传】 + FlowParams flowParams = FlowParams.build().flowCode(flowCode); + // 设置办理人唯一标识,保存为流程实例的创建人 【必传】 + flowParams.handler(user.getUser().getUserId().toString()); + // 流程变量 + Map variable = new HashMap<>(); + // 流程变量传递业务数据,按实际业务需求传递 【按需传】 + variable.put("businessData", testLeave); + variable.put("businessType", "testLeave"); + // 条件表达式替换,判断是否满足某个任务的跳转条件 【按需传】 + variable.put("flag", String.valueOf(testLeave.getDay())); + // 办理人变量表达式替换 【按需传】 + variable.put("handler1", Arrays.asList(4, "5", 100L)); + variable.put("handler2", 12L); + variable.put("handler3", new Object[] {9, "10", 102L}); + variable.put("handler4", "15"); + Task task = FlowEngine.newTask().setId(55L); + variable.put("handler5", task); + variable.put("handler6", 77L); + + flowParams.variable(variable); + // 自定义流程状态扩展 + if (StringUtils.isNotEmpty(flowStatus)) { + flowParams.flowStatus(flowStatus).hisStatus(flowStatus); + } + + // 新增请假表 + Instance instance = insService.start(id, flowParams); + testLeave.setInstanceId(instance.getId()); + testLeave.setNodeCode(instance.getNodeCode()); + testLeave.setNodeName(instance.getNodeName()); + testLeave.setNodeType(instance.getNodeType()); + testLeave.setFlowStatus(instance.getFlowStatus()); + testLeave.setCreateTime(DateUtils.getNowDate()); + // 新增抄送人方法 【按需】 + if (StringUtils.isNotNull(testLeave.getAdditionalHandler())) { + List users = FlowEngine.userService().structureUser(instance.getId() + , testLeave.getAdditionalHandler(), "4"); + FlowEngine.userService().saveBatch(users); + } + // 此处可以发送消息通知,比如短信通知,邮件通知等,代码自己实现 + + return testLeaveMapper.insertTestLeave(testLeave); + } + + /** + * 修改OA 请假申请 + * + * @param testLeave OA 请假申请 + * @return 结果 + */ + @Override + public int updateTestLeave(TestLeave testLeave) + { + testLeave.setUpdateTime(DateUtils.getNowDate()); + return testLeaveMapper.updateTestLeave(testLeave); + } + + /** + * 批量删除OA 请假申请 + * + * @param ids 需要删除的OA 请假申请主键 + * @return 结果 + */ + @Override + public int deleteTestLeaveByIds(String[] ids) + { + List testLeaveList = testLeaveMapper.selectTestLeaveByIds(ids); + if (testLeaveMapper.deleteTestLeaveByIds(ids) > 0) { + List instanceIds = testLeaveList.stream().map(TestLeave::getInstanceId).collect(Collectors.toList()); + return insService.remove(instanceIds) ? 1: 0; + } + return 0; + } + + /** + * 删除OA 请假申请信息 + * + * @param id OA 请假申请主键 + * @return 结果 + */ + @Override + public int deleteTestLeaveById(String id) + { + return testLeaveMapper.deleteTestLeaveById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int submit(String id, String flowStatus) { + // 设置流转参数 + TestLeave testLeave = testLeaveMapper.selectTestLeaveById(id); + LoginUser user = SecurityUtils.getLoginUser(); + // 是通过流程还是退回流程 【必传】 + FlowParams flowParams = FlowParams.build().skipType(SkipType.PASS.getKey()); + // 作为办理人保存到历史记录表 【必传】 + flowParams.handler(user.getUser().getUserId().toString()); + // 设置办理人拥有的权限,办理中需要校验是否有权限办理 【必传】 + List roles = user.getUser().getRoles(); + List permissionList = new ArrayList<>(); + if (Objects.nonNull(roles)) { + permissionList = roles.stream().map(role -> "role:" + role.getRoleId()).collect(Collectors.toList()); + } + permissionList.add("dept:" + SecurityUtils.getLoginUser().getUser().getDeptId()); + permissionList.add(user.getUser().getUserId().toString()); + flowParams.permissionFlag(permissionList); + // 自定义流程状态扩展 【按需传】 + if (StringUtils.isNotEmpty(flowStatus)) { + flowParams.flowStatus(flowStatus).hisStatus(flowStatus); + } + // 流程变量 + Map variable = new HashMap<>(); + // 流程变量传递业务数据,按实际业务需求传递 【按需传】 + variable.put("businessType", "testLeave"); + // 办理人变量表达式替换 【按需传】 + variable.put("flag", String.valueOf(testLeave.getDay())); + flowParams.variable(variable); + + // 更新请假表 + Instance instance = insService.skipByInsId(testLeave.getInstanceId(), flowParams); + testLeave.setNodeCode(instance.getNodeCode()); + testLeave.setNodeName(instance.getNodeName()); + testLeave.setNodeType(instance.getNodeType()); + testLeave.setFlowStatus(instance.getFlowStatus()); + testLeave.setUpdateTime(DateUtils.getNowDate()); + return testLeaveMapper.updateTestLeave(testLeave); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int handle(TestLeave testLeave, Long taskId, String skipType, String message, String nodeCode, String flowStatus) { + // 设置流转参数 + LoginUser user = SecurityUtils.getLoginUser(); + // 是通过流程还是退回流程 【必传】 + FlowParams flowParams = FlowParams.build().skipType(skipType); + // 作为办理人保存到历史记录表 【必传】 + flowParams.handler(user.getUser().getUserId().toString()); + // 如果需要任意跳转流程,传入此参数 【按需传】 + flowParams.nodeCode(nodeCode); + // 作为审批意见保存到历史记录表 【按需传】 + flowParams.message(message); + + // 流程变量 + Map variable = new HashMap<>(); + // 流程变量传递业务数据,按实际业务需求传递 【按需传】 + variable.put("businessType", "testLeave"); + // 办理人变量表达式替换 【按需传】 + variable.put("flag", String.valueOf(testLeave.getDay())); + flowParams.variable(variable); + // 自定义流程状态扩展 【按需传】 + if (StringUtils.isNotEmpty(flowStatus)) { + flowParams.flowStatus(flowStatus).hisStatus(flowStatus); + } + // 请假信息存入flowParams,方便查看历史审批数据 【按需传】 + flowParams.hisTaskExt(JSON.toJSONString(testLeave)); + Instance instance = taskService.skip(taskId, flowParams); + + // 更新请假表 + testLeave.setNodeCode(instance.getNodeCode()); + testLeave.setNodeName(instance.getNodeName()); + testLeave.setNodeType(instance.getNodeType()); + testLeave.setFlowStatus(instance.getFlowStatus()); + return testLeaveMapper.updateTestLeave(testLeave); + } + + @Override + public int termination(TestLeave testLeave) { + // 设置流转参数 + FlowParams flowParams = new FlowParams(); + LoginUser user = SecurityUtils.getLoginUser(); + // 作为审批意见保存到历史记录表 【按需传】 + flowParams.message("终止流程"); + // 作为办理人保存到历史记录表 【必传】 + flowParams.handler(user.getUserId().toString()); + + Map variable = new HashMap<>(); + // 流程变量传递业务数据,按实际业务需求传递 【按需传】 + variable.put("businessType", "testLeave"); + flowParams.variable(variable); + + Instance instance = insService.termination(testLeave.getInstanceId(), flowParams); + if (instance == null) { + throw new ServiceException("流程实例不存在"); + } + + // 更新请假表 + testLeave.setNodeCode(instance.getNodeCode()); + testLeave.setNodeName(instance.getNodeName()); + testLeave.setNodeType(instance.getNodeType()); + testLeave.setFlowStatus(instance.getFlowStatus()); + return testLeaveMapper.updateTestLeave(testLeave); + } + + /** + * 从字典表中获取流程编码 + * @param testLeave 请假信息 + * @return 流程编码 + */ + private String getFlowType(TestLeave testLeave) { + List leaveType = sysDictTypeService.selectDictDataByType("leave_type"); + Map map = StreamUtils.toMap(leaveType, SysDictData::getDictValue, SysDictData::getRemark); + return map.get(testLeave.getType().toString()); + } + +} diff --git a/czsj-system/src/main/resources/mapper/oaLeave/TestLeaveMapper.xml b/czsj-system/src/main/resources/mapper/oaLeave/TestLeaveMapper.xml new file mode 100644 index 0000000..dbbec23 --- /dev/null +++ b/czsj-system/src/main/resources/mapper/oaLeave/TestLeaveMapper.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select id, type, reason, start_time, end_time, day, instance_id, node_code, node_name, node_type, flow_status, create_by, create_time, update_by, update_time, del_flag from test_leave + + + + + + + + + + insert into test_leave + + id, + type, + reason, + start_time, + end_time, + day, + instance_id, + node_code, + node_name, + node_type, + flow_status, + create_by, + create_time, + update_by, + update_time, + del_flag, + + + #{id}, + #{type}, + #{reason}, + #{startTime}, + #{endTime}, + #{day}, + #{instanceId}, + #{nodeCode}, + #{nodeName}, + #{nodeType}, + #{flowStatus}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + + + + + update test_leave + + type = #{type}, + reason = #{reason}, + start_time = #{startTime}, + end_time = #{endTime}, + day = #{day}, + instance_id = #{instanceId}, + node_code = #{nodeCode}, + node_name = #{nodeName}, + node_type = #{nodeType}, + flow_status = #{flowStatus}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + + where id = #{id} + + + + delete from test_leave where id = #{id} + + + + delete from test_leave where id in + + #{id} + + + \ No newline at end of file