24282 11 ay önce
ebeveyn
işleme
e15dc8778f
26 değiştirilmiş dosya ile 1533 ekleme ve 10 silme
  1. 37 0
      jy-flow/pom.xml
  2. 44 0
      jy-flow/src/main/java/com/jy/flow/adapter/AbstractWarmFlowAdapter.java
  3. 32 0
      jy-flow/src/main/java/com/jy/flow/adapter/AddSignatureAdapter.java
  4. 33 0
      jy-flow/src/main/java/com/jy/flow/adapter/DeputeAdapter.java
  5. 33 0
      jy-flow/src/main/java/com/jy/flow/adapter/ReductionSignatureAdapter.java
  6. 33 0
      jy-flow/src/main/java/com/jy/flow/adapter/TransferAdapter.java
  7. 11 0
      jy-flow/src/main/java/com/jy/flow/adapter/WarmFlowAdapter.java
  8. 179 0
      jy-flow/src/main/java/com/jy/flow/controller/DefController.java
  9. 318 0
      jy-flow/src/main/java/com/jy/flow/controller/ExecuteController.java
  10. 28 0
      jy-flow/src/main/java/com/jy/flow/dto/FlowDefinitionDto.java
  11. 36 0
      jy-flow/src/main/java/com/jy/flow/dto/FlowHisTaskDto.java
  12. 36 0
      jy-flow/src/main/java/com/jy/flow/dto/FlowTaskDto.java
  13. 28 0
      jy-flow/src/main/java/com/jy/flow/mapper/WarmFlowMapper.java
  14. 171 0
      jy-flow/src/main/java/com/jy/flow/mapper/xml/WarmFLowMapper.xml
  15. 26 0
      jy-flow/src/main/java/com/jy/flow/service/ExecuteService.java
  16. 9 0
      jy-flow/src/main/java/com/jy/flow/service/HhDefService.java
  17. 34 0
      jy-flow/src/main/java/com/jy/flow/service/impl/ExecuteServiceImpl.java
  18. 42 0
      jy-flow/src/main/java/com/jy/flow/service/impl/HhDefServiceImpl.java
  19. 36 0
      jy-flow/src/main/java/com/jy/flow/vo/FlowTaskVo.java
  20. 34 0
      jy-flow/src/main/java/com/jy/flow/vo/WarmFlowInteractiveTypeVo.java
  21. 5 0
      jy-starter/pom.xml
  22. 3 3
      jy-system/src/main/java/com/jy/system/model/dto/SysUserSelectDto.java
  23. 22 0
      jy-ui/src/api/flow/definition.ts
  24. 9 0
      jy-ui/src/utils/request.ts
  25. 280 0
      jy-ui/src/views/flow/definition/index.vue
  26. 14 7
      pom.xml

+ 37 - 0
jy-flow/pom.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.jy</groupId>
+        <artifactId>jy</artifactId>
+        <version>4.0</version>
+    </parent>
+
+    <artifactId>jy-flow</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.jy</groupId>
+            <artifactId>jy-system</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.github.minliuhua</groupId>
+            <artifactId>warm-flow-mybatis-plus-sb-starter</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.baomidou</groupId>
+                    <artifactId>mybatis-plus</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+
+</project>

+ 44 - 0
jy-flow/src/main/java/com/jy/flow/adapter/AbstractWarmFlowAdapter.java

@@ -0,0 +1,44 @@
+package com.jy.flow.adapter;
+
+
+import com.jy.framework.satoken.LoginContext;
+import com.warm.flow.core.enums.CooperateType;
+import com.warm.flow.core.service.TaskService;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public abstract class AbstractWarmFlowAdapter {
+
+    @Resource
+    protected TaskService taskService;
+
+    /**
+     * 获取权限
+     *
+     * @return 权限列表
+     */
+    public static List<String> permissionList() {
+        List<String> permissionList = new ArrayList<>();
+        permissionList.add(LoginContext.getUserId().toString());
+        permissionList.add("dept:" + LoginContext.getDeptId());
+        for (Long roleId : LoginContext.getRoleIdSet()) {
+            permissionList.add("role:" + roleId);
+        }
+        return permissionList;
+    }
+
+    /**
+     * 根据类型获取描述
+     *
+     * @param type 流程类型
+     * @return value
+     */
+    protected String type(Integer type) {
+        return CooperateType.getValueByKey(type);
+    }
+
+}

+ 32 - 0
jy-flow/src/main/java/com/jy/flow/adapter/AddSignatureAdapter.java

@@ -0,0 +1,32 @@
+package com.jy.flow.adapter;
+
+import com.jy.flow.vo.WarmFlowInteractiveTypeVo;
+import com.jy.framework.satoken.LoginContext;
+import com.warm.flow.core.enums.CooperateType;
+import org.springframework.stereotype.Component;
+
+import java.util.Objects;
+
+/**
+ * 加签适配器
+ */
+@Component
+public class AddSignatureAdapter extends AbstractWarmFlowAdapter implements WarmFlowAdapter {
+
+    @Override
+    public boolean isAdapter(Integer warmFlowType) {
+        return Objects.equals(CooperateType.ADD_SIGNATURE.getKey(), warmFlowType);
+    }
+
+    @Override
+    public boolean adapter(WarmFlowInteractiveTypeVo obj) {
+        return super.taskService.addSignature(
+                obj.getTaskId(),
+                LoginContext.getUserId().toString(),
+                permissionList(),
+                obj.getAddHandlers(),
+                this.type(obj.getOperatorType())
+        );
+    }
+
+}

+ 33 - 0
jy-flow/src/main/java/com/jy/flow/adapter/DeputeAdapter.java

@@ -0,0 +1,33 @@
+package com.jy.flow.adapter;
+
+
+import com.jy.flow.vo.WarmFlowInteractiveTypeVo;
+import com.jy.framework.satoken.LoginContext;
+import com.warm.flow.core.enums.CooperateType;
+import org.springframework.stereotype.Component;
+
+import java.util.Objects;
+
+/**
+ * 委派适配器
+ */
+@Component
+public class DeputeAdapter extends AbstractWarmFlowAdapter implements WarmFlowAdapter {
+
+    @Override
+    public boolean isAdapter(Integer warmFlowType) {
+        return Objects.equals(CooperateType.DEPUTE.getKey(), warmFlowType);
+    }
+
+    @Override
+    public boolean adapter(WarmFlowInteractiveTypeVo obj) {
+        return super.taskService.depute(
+                obj.getTaskId(),
+                LoginContext.getUserId().toString(),
+                permissionList(),
+                obj.getAddHandlers(),
+                this.type(obj.getOperatorType())
+        );
+    }
+
+}

+ 33 - 0
jy-flow/src/main/java/com/jy/flow/adapter/ReductionSignatureAdapter.java

@@ -0,0 +1,33 @@
+package com.jy.flow.adapter;
+
+
+import com.jy.flow.vo.WarmFlowInteractiveTypeVo;
+import com.jy.framework.satoken.LoginContext;
+import com.warm.flow.core.enums.CooperateType;
+import org.springframework.stereotype.Component;
+
+import java.util.Objects;
+
+/**
+ * 减签适配器
+ */
+@Component
+public class ReductionSignatureAdapter extends AbstractWarmFlowAdapter implements WarmFlowAdapter {
+
+    @Override
+    public boolean isAdapter(Integer warmFlowType) {
+        return Objects.equals(CooperateType.REDUCTION_SIGNATURE.getKey(), warmFlowType);
+    }
+
+    @Override
+    public boolean adapter(WarmFlowInteractiveTypeVo obj) {
+        return super.taskService.depute(
+                obj.getTaskId(),
+                LoginContext.getUserId().toString(),
+                permissionList(),
+                obj.getAddHandlers(),
+                this.type(obj.getOperatorType())
+        );
+    }
+
+}

+ 33 - 0
jy-flow/src/main/java/com/jy/flow/adapter/TransferAdapter.java

@@ -0,0 +1,33 @@
+package com.jy.flow.adapter;
+
+
+import com.jy.flow.vo.WarmFlowInteractiveTypeVo;
+import com.jy.framework.satoken.LoginContext;
+import com.warm.flow.core.enums.CooperateType;
+import org.springframework.stereotype.Component;
+
+import java.util.Objects;
+
+/**
+ * 转办适配器
+ */
+@Component
+public class TransferAdapter extends AbstractWarmFlowAdapter implements WarmFlowAdapter {
+
+    @Override
+    public boolean isAdapter(Integer warmFlowType) {
+        return Objects.equals(CooperateType.TRANSFER.getKey(), warmFlowType);
+    }
+
+    @Override
+    public boolean adapter(WarmFlowInteractiveTypeVo obj) {
+        return super.taskService.depute(
+                obj.getTaskId(),
+                LoginContext.getUserId().toString(),
+                permissionList(),
+                obj.getAddHandlers(),
+                this.type(obj.getOperatorType())
+        );
+    }
+
+}

+ 11 - 0
jy-flow/src/main/java/com/jy/flow/adapter/WarmFlowAdapter.java

@@ -0,0 +1,11 @@
+package com.jy.flow.adapter;
+
+import com.jy.flow.vo.WarmFlowInteractiveTypeVo;
+
+public interface WarmFlowAdapter {
+
+    boolean isAdapter(Integer warmFlowType);
+
+    boolean adapter(WarmFlowInteractiveTypeVo obj);
+
+}

+ 179 - 0
jy-flow/src/main/java/com/jy/flow/controller/DefController.java

@@ -0,0 +1,179 @@
+package com.jy.flow.controller;
+
+import com.jy.flow.dto.FlowDefinitionDto;
+import com.warm.flow.core.entity.Definition;
+import com.warm.flow.core.service.DefService;
+import com.warm.flow.core.utils.page.Page;
+import com.warm.flow.orm.entity.FlowDefinition;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import org.dom4j.Document;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.List;
+
+@RestController
+@RequestMapping("/flow/definition")
+public class DefController {
+
+    @Resource
+    private DefService defService;
+
+    /**
+     * 分页查询流程定义列表
+     */
+    @GetMapping("/list")
+    public Page<Definition> list(FlowDefinitionDto flowDefinition) {
+        return defService.orderByCreateTime().desc()
+                .page(flowDefinition, Page.pageOf(flowDefinition.getPageNum(), flowDefinition.getPageSize()));
+    }
+
+    /**
+     * 获取流程定义详细信息
+     */
+    @GetMapping(value = "/{id}")
+    public Definition getInfo(@PathVariable("id") Long id) {
+        return defService.getById(id);
+    }
+
+    /**
+     * 新增流程定义
+     */
+    @PostMapping
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean add(@RequestBody FlowDefinition flowDefinition) {
+        return defService.checkAndSave(flowDefinition);
+    }
+
+    /**
+     * 修改流程定义
+     */
+    @PutMapping
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean edit(@RequestBody FlowDefinition flowDefinition) {
+        return defService.updateById(flowDefinition);
+    }
+
+    /**
+     * 发布流程定义
+     */
+    @GetMapping("/publish/{id}")
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean publish(@PathVariable("id") Long id) {
+        return defService.publish(id);
+    }
+
+    /**
+     * 取消发布流程定义
+     */
+    @GetMapping("/unPublish/{id}")
+    @Transactional(rollbackFor = Exception.class)
+    public void unPublish(@PathVariable("id") Long id) {
+        defService.unPublish(id);
+    }
+
+    /**
+     * 删除流程定义
+     */
+    @DeleteMapping("/{ids}")
+    @Transactional(rollbackFor = Exception.class)
+    public boolean remove(@PathVariable List<Long> ids) {
+        return defService.removeDef(ids);
+    }
+
+    /**
+     * 保存流程定义
+     */
+    @PostMapping("/saveXml")
+    @Transactional(rollbackFor = Exception.class)
+    public void saveXml(@RequestBody FlowDefinition def) throws Exception {
+        defService.saveXml(def);
+    }
+
+    /**
+     * 复制流程定义
+     */
+    @GetMapping("/copyDef/{id}")
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean copyDef(@PathVariable("id") Long id) {
+        return defService.copyDef(id);
+    }
+
+    @PostMapping("/importDefinition")
+    @Transactional(rollbackFor = Exception.class)
+    public void importDefinition(MultipartFile file) throws Exception {
+        defService.importXml(file.getInputStream());
+    }
+
+    @PostMapping("/exportDefinition/{id}")
+    public void exportDefinition(@PathVariable("id") Long id, HttpServletResponse response) throws Exception {
+        Document document = defService.exportXml(id);
+        // 设置生成xml的格式
+        OutputFormat of = OutputFormat.createPrettyPrint();
+        // 设置编码格式
+        of.setEncoding("UTF-8");
+        of.setIndent(true);
+        of.setIndent("    ");
+        of.setNewlines(true);
+
+        // 创建一个xml文档编辑器
+        XMLWriter writer = new XMLWriter(response.getOutputStream(), of);
+        writer.setEscapeText(false);
+        response.reset();
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType("application/x-msdownload");
+        response.setHeader("Content-Disposition", "attachment;");
+        writer.write(document);
+        writer.close();
+    }
+
+    @GetMapping("/xmlString/{id}")
+    public String xmlString(@PathVariable("id") Long id) {
+        return defService.xmlString(id);
+    }
+
+    /**
+     * 查询流程图
+     */
+    @GetMapping("/flowChartNoColor/{definitionId}")
+    public String flowChartNoColor(@PathVariable("definitionId") Long definitionId) throws IOException {
+        return defService.flowChartNoColor(definitionId);
+    }
+
+    /**
+     * 查询流程图
+     */
+    @GetMapping("/flowChart/{instanceId}")
+    public String flowChart(@PathVariable("instanceId") Long instanceId) throws IOException {
+        return defService.flowChart(instanceId);
+    }
+
+    /**
+     * 激活流程
+     */
+    @GetMapping("/active/{definitionId}")
+    public Boolean active(@PathVariable("definitionId") Long definitionId) {
+        return defService.active(definitionId);
+    }
+
+    /**
+     * 挂起流程
+     */
+    @GetMapping("/unActive/{definitionId}")
+    public Boolean unActive(@PathVariable("definitionId") Long definitionId) {
+        return defService.unActive(definitionId);
+    }
+
+}

+ 318 - 0
jy-flow/src/main/java/com/jy/flow/controller/ExecuteController.java

@@ -0,0 +1,318 @@
+package com.jy.flow.controller;
+
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jy.flow.adapter.AbstractWarmFlowAdapter;
+import com.jy.flow.dto.FlowHisTaskDto;
+import com.jy.flow.dto.FlowTaskDto;
+import com.jy.flow.service.ExecuteService;
+import com.jy.flow.service.HhDefService;
+import com.jy.flow.vo.FlowTaskVo;
+import com.jy.flow.vo.WarmFlowInteractiveTypeVo;
+import com.jy.framework.satoken.LoginContext;
+import com.jy.system.dao.SysDeptDao;
+import com.jy.system.dao.SysRoleDao;
+import com.jy.system.dao.SysUserDao;
+import com.jy.system.model.dto.SysUserSelectDto;
+import com.jy.system.model.entity.SysDept;
+import com.jy.system.model.entity.SysRole;
+import com.jy.system.model.entity.SysUser;
+import com.jy.system.model.vo.SysUserVo;
+import com.warm.flow.core.FlowFactory;
+import com.warm.flow.core.entity.HisTask;
+import com.warm.flow.core.entity.Instance;
+import com.warm.flow.core.entity.Node;
+import com.warm.flow.core.entity.Task;
+import com.warm.flow.core.entity.User;
+import com.warm.flow.core.enums.CooperateType;
+import com.warm.flow.core.enums.UserType;
+import com.warm.flow.core.service.HisTaskService;
+import com.warm.flow.core.service.InsService;
+import com.warm.flow.core.service.NodeService;
+import com.warm.flow.core.service.TaskService;
+import com.warm.flow.core.service.UserService;
+import com.warm.flow.core.utils.StreamUtils;
+import com.warm.flow.orm.entity.FlowHisTask;
+import jakarta.annotation.Resource;
+import org.springframework.beans.BeanUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("/flow/execute")
+public class ExecuteController {
+
+    @Resource
+    private SysUserDao sysUserDao;
+
+    @Resource
+    private SysDeptDao sysDeptDao;
+
+    @Resource
+    private SysRoleDao sysRoleDao;
+
+    @Resource
+    private HisTaskService hisTaskService;
+
+    @Resource
+    private TaskService taskService;
+
+    @Resource
+    private NodeService nodeService;
+
+    @Resource
+    private InsService insService;
+
+    @Resource
+    private UserService flowUserservice;
+
+    @Resource
+    private ExecuteService executeService;
+
+    @Resource
+    private HhDefService hhDefService;
+
+    /**
+     * 分页待办任务列表
+     */
+    @GetMapping("/toDoPage")
+    public Page<FlowTaskVo> toDoPage(FlowTaskDto dto) {
+        dto.setPermissionList(AbstractWarmFlowAdapter.permissionList());
+        Page<FlowTaskVo> page = executeService.toDoPage(dto);
+        List<FlowTaskVo> list = page.getRecords();
+
+        List<Long> taskIds = StreamUtils.toList(list, FlowTaskVo::getId);
+        List<User> userList = flowUserservice.getByAssociateds(taskIds);
+        Map<Long, List<User>> map = StreamUtils.groupByKey(userList, User::getAssociated);
+        for (FlowTaskVo taskVo : list) {
+            if (ObjectUtil.isNull(taskVo)) {
+                continue;
+            }
+            List<User> users = map.get(taskVo.getId());
+
+            if (ObjectUtil.isEmpty(users)) {
+                continue;
+            }
+
+            for (User user : users) {
+                if (UserType.APPROVAL.getKey().equals(user.getType())) {
+                    if (StrUtil.isEmpty(taskVo.getApprover())) {
+                        taskVo.setApprover("");
+                    }
+                    String name = getName(user.getProcessedBy());
+                    if (StrUtil.isNotEmpty(name))
+                        taskVo.setApprover(taskVo.getApprover().concat(name).concat(";"));
+
+                } else if (UserType.TRANSFER.getKey().equals(user.getType())) {
+                    if (StrUtil.isEmpty(taskVo.getTransferredBy())) {
+                        taskVo.setTransferredBy("");
+                    }
+                    String name = getName(user.getProcessedBy());
+                    if (StrUtil.isNotEmpty(name))
+                        taskVo.setTransferredBy(taskVo.getTransferredBy().concat(name).concat(";"));
+                } else if (UserType.DEPUTE.getKey().equals(user.getType())) {
+                    if (StrUtil.isEmpty(taskVo.getDelegate())) {
+                        taskVo.setDelegate("");
+                    }
+                    String name = getName(user.getProcessedBy());
+                    if (StrUtil.isNotEmpty(name))
+                        taskVo.setDelegate(taskVo.getDelegate().concat(name).concat(";"));
+                }
+            }
+
+        }
+        return page;
+    }
+
+    /**
+     * 分页抄送任务列表
+     */
+    @GetMapping("/copyPage")
+    public Page<FlowHisTask> copyPage(FlowTaskDto dto) {
+        dto.setPermissionList(AbstractWarmFlowAdapter.permissionList());
+        return executeService.copyPage(dto);
+    }
+
+    /**
+     * 分页已办任务列表
+     */
+    @GetMapping("/donePage")
+    public Page<FlowHisTask> donePage(FlowHisTaskDto dto) {
+        dto.setPermissionList(AbstractWarmFlowAdapter.permissionList());
+        Page<FlowHisTask> page = executeService.donePage(dto);
+        List<FlowHisTask> list = page.getRecords();
+        Map<Long, String> userMap = StreamUtils.toMap(sysUserDao.list(), SysUser::getId, SysUser::getNickname);
+
+        if (CollectionUtils.isNotEmpty(list)) {
+            for (FlowHisTask hisTaskVo : list) {
+                if (StrUtil.isNotEmpty(hisTaskVo.getApprover())) {
+                    String name = getName(hisTaskVo.getApprover());
+                    hisTaskVo.setApprover(name);
+                }
+                if (StrUtil.isNotEmpty(hisTaskVo.getCollaborator())) {
+                    hisTaskVo.setCollaborator(userMap.get(Long.valueOf(hisTaskVo.getCollaborator())));
+                }
+            }
+        }
+        return page;
+    }
+
+    /**
+     * 查询已办任务历史记录
+     */
+    @GetMapping("/doneList/{instanceId}")
+    public List<FlowHisTask> doneList(@PathVariable("instanceId") Long instanceId) {
+        List<HisTask> flowHisTasks = hisTaskService.orderById().desc().list(new FlowHisTask().setInstanceId(instanceId));
+        Map<Long, String> userMap = StreamUtils.toMap(sysUserDao.list(), SysUser::getId, SysUser::getNickname);
+
+        List<FlowHisTask> flowHisTaskList = new ArrayList<>();
+        if (CollectionUtils.isNotEmpty(flowHisTasks)) {
+            for (HisTask hisTask : flowHisTasks) {
+                if (StrUtil.isNotEmpty(hisTask.getApprover())) {
+                    String name = getName(hisTask.getApprover());
+                    hisTask.setApprover(name);
+                }
+                if (StrUtil.isNotEmpty(hisTask.getCollaborator())) {
+                    hisTask.setCollaborator(userMap.get(Long.valueOf(hisTask.getCollaborator())));
+                }
+                FlowHisTask flowHisTask = new FlowHisTask();
+                BeanUtils.copyProperties(hisTask, flowHisTask);
+                flowHisTaskList.add(flowHisTask);
+            }
+        }
+        return flowHisTaskList;
+    }
+
+    /**
+     * 根据taskId查询代表任务
+     */
+    @GetMapping("/getTaskById/{taskId}")
+    public Task getTaskById(@PathVariable("taskId") Long taskId) {
+        return taskService.getById(taskId);
+    }
+
+    /**
+     * 查询跳转任意节点列表
+     */
+    @GetMapping("/anyNodeList/{instanceId}")
+    public List<Node> anyNodeList(@PathVariable("instanceId") Long instanceId) {
+        Instance instance = insService.getById(instanceId);
+        return nodeService.list(FlowFactory.newNode().setDefinitionId(instance.getDefinitionId()));
+    }
+
+    /**
+     * 处理非办理的流程交互类型
+     *
+     * @param warmFlowInteractiveTypeVo 要转办用户
+     * @return 是否成功
+     */
+    @PostMapping("/interactiveType")
+    public Boolean interactiveType(WarmFlowInteractiveTypeVo warmFlowInteractiveTypeVo) {
+        return hhDefService.interactiveType(warmFlowInteractiveTypeVo);
+    }
+
+    /**
+     * 交互类型可以选择的用户
+     *
+     * @param vo 交互类型请求类
+     * @return 是否成功
+     */
+    @GetMapping("/interactiveTypeSysUser")
+    public Page<SysUserVo> interactiveTypeSysUser(WarmFlowInteractiveTypeVo vo) {
+        Integer operatorType = vo.getOperatorType();
+        Long taskId = vo.getTaskId();
+
+        List<User> users = flowUserservice.listByAssociatedAndTypes(taskId);
+        Set<Long> userIdSet = users.stream().map(User::getProcessedBy).map(Convert::toLong).collect(Collectors.toSet());
+
+        SysUserSelectDto sysUserSelectDto = new SysUserSelectDto();
+        sysUserSelectDto.setDeptId(vo.getDeptId());
+        if (!Objects.equals(CooperateType.REDUCTION_SIGNATURE.getKey(), operatorType)) {
+            sysUserSelectDto.setNotInUserIdList(userIdSet);
+        } else {
+            sysUserSelectDto.setInUserIdList(userIdSet);
+            sysUserSelectDto.setNotInUserIdList(Collections.singletonList(LoginContext.getUserId()));
+        }
+
+        return sysUserDao.getPage(sysUserSelectDto);
+    }
+
+    /**
+     * 激活流程
+     */
+    @GetMapping("/active/{instanceId}")
+    public Boolean active(@PathVariable("instanceId") Long instanceId) {
+        return insService.active(instanceId);
+    }
+
+    /**
+     * 挂起流程
+     */
+    @GetMapping("/unActive/{instanceId}")
+    public Boolean unActive(@PathVariable("instanceId") Long instanceId) {
+        return insService.unActive(instanceId);
+    }
+
+    /**
+     * 根据ID反显姓名
+     **/
+    @GetMapping(value = "/idReverseDisplayName/{ids}")
+    public List<SysUser> idReverseDisplayName(@PathVariable Long[] ids) {
+        return sysUserDao.listByIds(Arrays.asList(ids));
+    }
+
+
+    private String getName(String id) {
+        Map<Long, String> userMap = StreamUtils.toMap(sysUserDao.list(), SysUser::getId, SysUser::getNickname);
+        Map<Long, String> deptMap = StreamUtils.toMap(sysDeptDao.list(), SysDept::getId, SysDept::getName);
+        Map<Long, String> roleMap = StreamUtils.toMap(sysRoleDao.list(), SysRole::getId, SysRole::getName);
+
+        if (StrUtil.isNotBlank(id)) {
+            if (id.contains("user:")) {
+                String name = userMap.get(Long.valueOf(id.replace("user:", "")));
+                if (StrUtil.isNotEmpty(name)) {
+                    return "用户:" + name;
+                }
+            } else if (id.contains("dept:")) {
+                String name = deptMap.get(Long.valueOf(id.replace("dept:", "")));
+                if (StrUtil.isNotEmpty(name)) {
+                    return "部门:" + name;
+                }
+            } else if (id.contains("role")) {
+                String name = roleMap.get(Long.valueOf(id.replace("role:", "")));
+                if (StrUtil.isNotEmpty(name)) {
+                    return "角色:" + name;
+                }
+            } else {
+                try {
+                    long parseLong = Long.parseLong(id);
+                    String name = userMap.get(parseLong);
+                    if (StrUtil.isNotEmpty(name)) {
+                        return "用户:" + name;
+                    }
+                } catch (NumberFormatException e) {
+                    return id;
+                }
+
+            }
+        }
+        return "";
+    }
+
+}

+ 28 - 0
jy-flow/src/main/java/com/jy/flow/dto/FlowDefinitionDto.java

@@ -0,0 +1,28 @@
+package com.jy.flow.dto;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.warm.flow.orm.entity.FlowDefinition;
+import lombok.Setter;
+
+@Setter
+public class FlowDefinitionDto extends FlowDefinition {
+
+    /**
+     * 页数
+     */
+    private Integer pageNum;
+
+    /**
+     * 每页条数
+     */
+    private Integer pageSize;
+
+    public Integer getPageNum() {
+        return ObjectUtil.defaultIfNull(pageNum, 1);
+    }
+
+    public Integer getPageSize() {
+        return ObjectUtil.defaultIfNull(pageSize, 10);
+    }
+
+}

+ 36 - 0
jy-flow/src/main/java/com/jy/flow/dto/FlowHisTaskDto.java

@@ -0,0 +1,36 @@
+package com.jy.flow.dto;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.warm.flow.orm.entity.FlowHisTask;
+import lombok.Setter;
+
+@Setter
+public class FlowHisTaskDto extends FlowHisTask {
+
+    /**
+     * 页数
+     */
+    private Integer pageNum;
+
+    /**
+     * 每页条数
+     */
+    private Integer pageSize;
+
+    /**
+     * 返回分页实体
+     */
+    public <T> Page<T> getPage() {
+        return new Page<>(getPageNum(), getPageSize());
+    }
+
+    public Integer getPageNum() {
+        return ObjectUtil.defaultIfNull(pageNum, 1);
+    }
+
+    public Integer getPageSize() {
+        return ObjectUtil.defaultIfNull(pageSize, 10);
+    }
+
+}

+ 36 - 0
jy-flow/src/main/java/com/jy/flow/dto/FlowTaskDto.java

@@ -0,0 +1,36 @@
+package com.jy.flow.dto;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.warm.flow.orm.entity.FlowTask;
+import lombok.Setter;
+
+@Setter
+public class FlowTaskDto extends FlowTask {
+
+    /**
+     * 页数
+     */
+    private Integer pageNum;
+
+    /**
+     * 每页条数
+     */
+    private Integer pageSize;
+
+    /**
+     * 返回分页实体
+     */
+    public <T> Page<T> getPage() {
+        return new Page<>(getPageNum(), getPageSize());
+    }
+
+    public Integer getPageNum() {
+        return ObjectUtil.defaultIfNull(pageNum, 1);
+    }
+
+    public Integer getPageSize() {
+        return ObjectUtil.defaultIfNull(pageSize, 10);
+    }
+
+}

+ 28 - 0
jy-flow/src/main/java/com/jy/flow/mapper/WarmFlowMapper.java

@@ -0,0 +1,28 @@
+package com.jy.flow.mapper;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jy.flow.dto.FlowTaskDto;
+import com.jy.flow.vo.FlowTaskVo;
+import com.warm.flow.core.entity.HisTask;
+import com.warm.flow.orm.entity.FlowHisTask;
+import com.warm.flow.orm.entity.FlowTask;
+import org.apache.ibatis.annotations.Param;
+
+public interface WarmFlowMapper {
+
+    /**
+     * 分页查询待办任务
+     */
+    Page<FlowTaskVo> toDoPage(@Param("page") Page<?> page, @Param("task") FlowTaskDto dto);
+
+    /**
+     * 获取最新的已办任务
+     */
+    Page<FlowHisTask> donePage(@Param("page") Page<?> page, @Param("hisTask") HisTask hisTask);
+
+    /**
+     * 分页获取抄送任务
+     */
+    Page<FlowHisTask> copyPage(@Param("page") Page<?> page, @Param("task") FlowTask flowTask);
+
+}

+ 171 - 0
jy-flow/src/main/java/com/jy/flow/mapper/xml/WarmFLowMapper.xml

@@ -0,0 +1,171 @@
+<?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="com.jy.flow.mapper.WarmFlowMapper">
+
+    <resultMap type="com.jy.flow.vo.FlowTaskVo" id="FlowTaskResult">
+        <result property="id" column="id"/>
+        <result property="nodeCode" column="node_code"/>
+        <result property="nodeName" column="node_name"/>
+        <result property="nodeType" column="node_type"/>
+        <result property="definitionId" column="definition_id"/>
+        <result property="instanceId" column="instance_id"/>
+        <result property="flowStatus" column="flow_status"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="tenantId" column="tenant_id"/>
+        <result property="businessId" column="business_id"/>
+        <result property="flowName" column="flow_name"/>
+        <result property="formCustom" column="form_custom"/>
+        <result property="formPath" column="form_path"/>
+        <result property="activityStatus" column="activity_status"/>
+        <result property="delFlag" column="del_flag"/>
+    </resultMap>
+
+    <resultMap type="com.warm.flow.orm.entity.FlowUser" id="FlowUserResult">
+        <result property="id" column="user_id"/>
+        <result property="type" column="type"/>
+        <result property="processedBy" column="processed_by"/>
+        <result property="associated" column="associated"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="tenantId" column="tenant_id"/>
+        <result property="delFlag" column="del_flag"/>
+    </resultMap>
+
+    <resultMap type="com.warm.flow.orm.entity.FlowHisTask" id="FlowHisTaskResult">
+        <result property="id" column="id"/>
+        <result property="nodeCode" column="node_code"/>
+        <result property="nodeName" column="node_name"/>
+        <result property="nodeType" column="node_type"/>
+        <result property="targetNodeCode" column="target_node_code"/>
+        <result property="targetNodeName" column="target_node_name"/>
+        <result property="approver" column="approver"/>
+        <result property="collaborator" column="collaborator"/>
+        <result property="definitionId" column="definition_id"/>
+        <result property="instanceId" column="instance_id"/>
+        <result property="taskId" column="task_id"/>
+        <result property="cooperateType" column="cooperate_type"/>
+        <result property="flowStatus" column="flow_status"/>
+        <result property="message" column="message"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="businessId" column="business_id"/>
+        <result property="tenantId" column="tenant_id"/>
+        <result property="formPath" column="form_path"/>
+        <result property="flowName" column="flow_name"/>
+        <result property="delFlag" column="del_flag"/>
+    </resultMap>
+
+    <select id="toDoPage" resultMap="FlowTaskResult">
+        SELECT
+        distinct
+        t.id,
+        t.node_code,
+        t.node_name,
+        t.node_type,
+        t.definition_id,
+        t.instance_id,
+        t.create_time,
+        t.update_time,
+        t.tenant_id,
+        i.business_id,
+        i.flow_status,
+        i.activity_status,
+        d.flow_name,
+        t.form_custom,
+        t.form_path
+        FROM flow_task AS t
+        LEFT JOIN flow_user uu ON uu.associated = t.id
+        LEFT JOIN flow_definition d on t.definition_id = d.id
+        LEFT JOIN flow_instance i on t.instance_id = i.id
+        <where>
+            t.node_type = 1
+            <if test="task.permissionList != null and task.permissionList.size > 0">
+                AND uu.processed_by in
+                <foreach item="permission" collection="task.permissionList" open="(" separator="," close=")">
+                    #{permission}
+                </foreach>
+            </if>
+            <if test="task.nodeCode != null and task.nodeCode != ''">and t.node_code = #{task.nodeCode}</if>
+            <if test="task.nodeName != null and task.nodeName != ''">and t.node_name like concat('%',
+                #{task.nodeName}, '%')
+            </if>
+            <if test="task.instanceId != null ">and t.instance_id = #{task.instanceId}</if>
+        </where>
+        order by t.create_time desc
+    </select>
+
+    <select id="donePage" resultMap="FlowHisTaskResult">
+        select
+        t.id,
+        t.node_code,
+        t.node_name,
+        t.cooperate_type,
+        t.approver,
+        t.collaborator,
+        t.node_type,
+        t.target_node_code,
+        t.target_node_name,
+        t.definition_id,
+        t.instance_id,
+        i.flow_status,
+        t.message,
+        t.ext,
+        t.create_time,
+        t.update_time,
+        t.tenant_id,
+        i.business_id,
+        t.form_path,
+        d.flow_name
+        from ( SELECT MAX(id) as id
+        FROM flow_his_task
+        <where>
+            <if test="hisTask.permissionList != null and hisTask.permissionList.size > 0">
+                AND approver in
+                <foreach item="permission" collection="hisTask.permissionList" open="(" separator="," close=")">
+                    #{permission}
+                </foreach>
+            </if>
+            <if test="hisTask.nodeCode != null  and hisTask.nodeCode != ''">and node_code =
+                #{hisTask.nodeCode}
+            </if>
+            <if test="hisTask.nodeName != null  and hisTask.nodeName != ''">and node_name like concat('%',
+                #{hisTask.nodeName}, '%')
+            </if>
+            <if test="hisTask.instanceId != null ">and instance_id = #{hisTask.instanceId}</if>
+        </where>
+        GROUP BY instance_id ) tmp
+        LEFT JOIN flow_his_task t ON t.id = tmp.id
+        LEFT JOIN flow_definition d on t.definition_id = d.id
+        LEFT JOIN flow_instance i on t.instance_id = i.id
+        order by t.create_time desc
+    </select>
+    <select id="copyPage" resultMap="FlowTaskResult">
+        SELECT
+        c.nickname AS approver,
+        b.flow_status,
+        b.business_id,
+        a.create_time,
+        b.node_name,
+        b.id ,
+        d.flow_name
+        FROM
+        `flow_user` a
+        LEFT JOIN flow_instance b ON a.associated = b.id
+        LEFT JOIN sys_user c ON b.create_by = c.id
+        LEFT JOIN flow_definition d on b.definition_id=d.id
+        WHERE
+        a.type = 4
+        <if test="task.flowName != null and task.flowName != ''">and c.nick_name like concat('%',
+            #{task.flowName}, '%')
+        </if>
+        <if test="task.nodeName != null and task.nodeName != ''">and b.node_name like concat('%',
+            #{task.nodeName}, '%')
+        </if>
+        <if test="task.nodeType != null">and b.node_type = #{task.nodeType}</if>
+        ORDER BY create_time DESC
+    </select>
+
+</mapper>

+ 26 - 0
jy-flow/src/main/java/com/jy/flow/service/ExecuteService.java

@@ -0,0 +1,26 @@
+package com.jy.flow.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jy.flow.dto.FlowHisTaskDto;
+import com.jy.flow.dto.FlowTaskDto;
+import com.jy.flow.vo.FlowTaskVo;
+import com.warm.flow.orm.entity.FlowHisTask;
+
+public interface ExecuteService {
+
+    /**
+     * 分页查询待办任务
+     */
+    Page<FlowTaskVo> toDoPage(FlowTaskDto dto);
+
+    /**
+     * 获取已办任务
+     */
+    Page<FlowHisTask> donePage(FlowHisTaskDto dto);
+
+    /**
+     * 分页抄送任务列表
+     */
+    Page<FlowHisTask> copyPage(FlowTaskDto dto);
+
+}

+ 9 - 0
jy-flow/src/main/java/com/jy/flow/service/HhDefService.java

@@ -0,0 +1,9 @@
+package com.jy.flow.service;
+
+import com.jy.flow.vo.WarmFlowInteractiveTypeVo;
+
+public interface HhDefService {
+
+    Boolean interactiveType(WarmFlowInteractiveTypeVo warmFlowInteractiveTypeVo);
+
+}

+ 34 - 0
jy-flow/src/main/java/com/jy/flow/service/impl/ExecuteServiceImpl.java

@@ -0,0 +1,34 @@
+package com.jy.flow.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jy.flow.dto.FlowHisTaskDto;
+import com.jy.flow.dto.FlowTaskDto;
+import com.jy.flow.mapper.WarmFlowMapper;
+import com.jy.flow.service.ExecuteService;
+import com.jy.flow.vo.FlowTaskVo;
+import com.warm.flow.orm.entity.FlowHisTask;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ExecuteServiceImpl implements ExecuteService {
+
+    @Resource
+    private WarmFlowMapper flowMapper;
+
+    @Override
+    public Page<FlowTaskVo> toDoPage(FlowTaskDto dto) {
+        return flowMapper.toDoPage(dto.getPage(), dto);
+    }
+
+    @Override
+    public Page<FlowHisTask> donePage(FlowHisTaskDto dto) {
+        return flowMapper.donePage(dto.getPage(), dto);
+    }
+
+    @Override
+    public Page<FlowHisTask> copyPage(FlowTaskDto dto) {
+        return flowMapper.copyPage(dto.getPage(), dto);
+    }
+
+}

+ 42 - 0
jy-flow/src/main/java/com/jy/flow/service/impl/HhDefServiceImpl.java

@@ -0,0 +1,42 @@
+package com.jy.flow.service.impl;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.jy.flow.adapter.WarmFlowAdapter;
+import com.jy.flow.service.HhDefService;
+import com.jy.flow.vo.WarmFlowInteractiveTypeVo;
+import jakarta.annotation.PostConstruct;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class HhDefServiceImpl implements HhDefService {
+
+    private static final List<WarmFlowAdapter> WARM_FLOW_ADAPTERS = new ArrayList<>();
+
+    /**
+     * 初始化方法
+     */
+    @PostConstruct
+    public void initMethod() {
+        String[] beanNamesForType = SpringUtil.getBeanNamesForType(WarmFlowAdapter.class);
+        for (String beanName : beanNamesForType) {
+            WARM_FLOW_ADAPTERS.add(SpringUtil.getBean(beanName));
+        }
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public Boolean interactiveType(WarmFlowInteractiveTypeVo warmFlowInteractiveTypeVo) {
+        Integer operatorType = warmFlowInteractiveTypeVo.getOperatorType();
+        for (WarmFlowAdapter warmFlowAdapter : WARM_FLOW_ADAPTERS) {
+            if (warmFlowAdapter.isAdapter(operatorType)) {
+                return warmFlowAdapter.adapter(warmFlowInteractiveTypeVo);
+            }
+        }
+        return false;
+    }
+
+}

+ 36 - 0
jy-flow/src/main/java/com/jy/flow/vo/FlowTaskVo.java

@@ -0,0 +1,36 @@
+package com.jy.flow.vo;
+
+import com.warm.flow.orm.entity.FlowTask;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class FlowTaskVo extends FlowTask {
+
+    /**
+     * 计划审批人
+     */
+    private String approver;
+
+    /**
+     * 转办人
+     */
+    private String transferredBy;
+
+    /**
+     * 委派人
+     */
+    private String delegate;
+
+    /**
+     * 委派人
+     */
+    private String flowStatus;
+
+    /**
+     * 激活状态
+     */
+    private Integer activityStatus;
+
+}

+ 34 - 0
jy-flow/src/main/java/com/jy/flow/vo/WarmFlowInteractiveTypeVo.java

@@ -0,0 +1,34 @@
+package com.jy.flow.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+public class WarmFlowInteractiveTypeVo {
+
+    /**
+     * 任务id
+     */
+    private Long taskId;
+
+    /**
+     * 增加办理人
+     */
+    private List<String> addHandlers;
+
+    /**
+     * 操作类型[2:转办,6:加签,3:委派,7:减签]
+     */
+    private Integer operatorType;
+
+    /**
+     * 部门ID
+     */
+    private Long deptId;
+
+    private List<String> userIds;
+
+}

+ 5 - 0
jy-starter/pom.xml

@@ -29,6 +29,11 @@
         </dependency>
 
         <dependency>
+            <groupId>com.jy</groupId>
+            <artifactId>jy-flow</artifactId>
+        </dependency>
+
+        <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>

+ 3 - 3
jy-system/src/main/java/com/jy/system/model/dto/SysUserSelectDto.java

@@ -4,7 +4,7 @@ import com.jy.framework.model.base.BaseSelectDto;
 import lombok.Getter;
 import lombok.Setter;
 
-import java.util.List;
+import java.util.Collection;
 
 /**
  * 用户列表查询入参实体
@@ -54,11 +54,11 @@ public class SysUserSelectDto extends BaseSelectDto {
     /**
      * 指定用户列表
      */
-    private List<Long> inUserIdList;
+    private Collection<Long> inUserIdList;
 
     /**
      * 排除用户列表
      */
-    private List<Long> notInUserIdList;
+    private Collection<Long> notInUserIdList;
 
 }

+ 22 - 0
jy-ui/src/api/flow/definition.ts

@@ -0,0 +1,22 @@
+import request from '@/utils/request'
+import { StrAnyObj } from '@/typings'
+
+// 查询流程定义列表
+export function getDefinitionPageApi(params: StrAnyObj): Promise<StrAnyObj> {
+  return request.get('/flow/definition/list', params)
+}
+
+// 查询流程定义详细
+export function getDefinitionApi(id: string): Promise<StrAnyObj> {
+  return request.get(`/flow/definition/${id}`)
+}
+
+// 新增流程定义
+export function addDefinitionApi(params: StrAnyObj): Promise<StrAnyObj> {
+  return request.post('/flow/definition', params)
+}
+
+// 修改流程定义
+export function updateDefinitionApi(id: string, params: StrAnyObj): Promise<StrAnyObj> {
+  return request.put(`/flow/definition`, params)
+}

+ 9 - 0
jy-ui/src/utils/request.ts

@@ -116,6 +116,15 @@ class RequestHttp {
   post<T>(url: string, data?: object | string, _object = {}): Promise<T> {
     return this.service.post(url, data, _object)
   }
+
+  put<T>(url: string, data?: object | string, _object = {}): Promise<T> {
+    return this.service.put(url, data, _object)
+  }
+
+  delete<T>(url: string, params?: object, _object = {}): Promise<T> {
+    return this.service.delete(url, { params, ..._object })
+  }
+
 }
 
 // 序列化参数

+ 280 - 0
jy-ui/src/views/flow/definition/index.vue

@@ -0,0 +1,280 @@
+<script setup lang="ts">
+import AForm from '@/components/AForm/index.vue'
+import { FormConfigType } from '@/components/AForm/type'
+import { ToolbarConfigType } from '@/components/AToolbar/type'
+import { ColumnConfigType } from '@/components/ATable/type'
+import { StrAnyObj, StrAnyObjArr } from '@/typings'
+import { useHandleData } from '@/utils/useHandleData'
+import { deleteApi } from '@/api/system/config'
+import { addDefinitionApi, getDefinitionApi, getDefinitionPageApi, updateDefinitionApi } from "@/api/flow/definition";
+
+const queryRef = ref<InstanceType<typeof AForm>>()
+const formRef = ref<InstanceType<typeof AForm>>()
+
+const showQuery = ref<boolean>(true)
+const selectKeys = ref<string[]>([])
+const pageTotal = ref<number>(0)
+
+const queryData = ref<StrAnyObj>({ pageNum: 1, pageSize: 10 })
+const tableData = ref<StrAnyObjArr>([])
+const formData = ref<StrAnyObj>({})
+
+const dialogTitle = ref<string>('')
+const dialogVisible = ref<boolean>(false)
+
+const queryConfig: FormConfigType[] = [
+  {
+    type: 'input',
+    prop: 'flowCode',
+    label: '流程编码'
+  },
+  {
+    type: 'input',
+    prop: 'flowName',
+    label: '流程名称'
+  },
+  {
+    type: 'version',
+    prop: 'version',
+    label: '流程版本',
+  }
+]
+
+const toolbarConfig: ToolbarConfigType[] = [
+  {
+    common: 'search',
+    click() {
+      queryData.value.pageNum = 1
+      getPage()
+    }
+  },
+  {
+    common: 'reset',
+    click() {
+      queryRef.value?.resetFields()
+      getPage()
+    }
+  },
+  {
+    common: 'add',
+    permissions: 'sysConfig:add',
+    click() {
+      dialogVisible.value = true
+      dialogTitle.value = '新增'
+    }
+  },
+  {
+    common: 'delete',
+    permissions: 'sysConfig:delete',
+    disabled() {
+      return selectKeys.value.length == 0
+    },
+    click() {
+      handleRemove(selectKeys.value)
+    }
+  }
+]
+
+const columnConfig: ColumnConfigType[] = [
+  {
+    prop: 'flowCode',
+    label: '流程编码'
+  },
+  {
+    prop: 'flowName',
+    label: '流程名称'
+  },
+  {
+    prop: 'version',
+    label: '流程版本'
+  },
+  {
+    prop: 'ext',
+    label: '扩展字段',
+  },
+  {
+    prop: 'isPublish',
+    label: '是否发布'
+  },
+  {
+    prop: 'activityStatus',
+    label: '激活状态'
+  },
+  {
+    prop: 'createTime',
+    label: '创建时间'
+  },
+  {
+    width: 200,
+    handleConfig: [
+      {
+        common: 'update',
+        permissions: 'sysConfig:edit',
+        click(row) {
+          dialogVisible.value = true
+          dialogTitle.value = '编辑'
+          getDefinitionApi({ id: row.id }).then((resp: StrAnyObj) => {
+            formData.value = resp
+            if (formData.value.listenerType) {
+              formData.value.listenerType = formData.value.listenerType.split(",")
+            }
+          })
+        }
+      },
+      {
+        common: 'delete',
+        permissions: 'sysConfig:delete',
+        click(row) {
+          handleRemove([row.id])
+        }
+      }
+    ]
+  }
+]
+
+const formConfig: FormConfigType[] = [
+  {
+    type: 'input',
+    prop: 'flowCode',
+    label: '流程编码',
+    rule: [{ required: true, message: '流程编码不能为空', trigger: 'blur' }]
+  },
+  {
+    type: 'input',
+    prop: 'flowName',
+    label: '流程名称',
+    rule: [{ required: true, message: '流程名称不能为空', trigger: 'blur' }]
+  },
+  {
+    type: 'input',
+    prop: 'version',
+    label: '流程版本',
+  },
+  {
+    type: 'input',
+    prop: 'ext',
+    label: '扩展字段',
+  },
+  {
+    type: 'input',
+    prop: 'formPath',
+    label: '审批表单路径',
+  },
+  {
+    type: 'select',
+    prop: 'listenerType',
+    label: '监听器类型',
+    multiple: true,
+    option: [
+      {
+        key: 'create',
+        label: '任务创建'
+      },
+      {
+        key: 'start',
+        label: '任务开始办理'
+      },
+      {
+        key: 'assignment',
+        label: '分派监听器'
+      },
+      {
+        key: 'permission',
+        label: '权限认证'
+      },
+      {
+        key: 'finish',
+        label: '任务完成'
+      }
+    ]
+  },
+  {
+    type: 'input',
+    itemType: 'textarea',
+    prop: 'listenerPath',
+    label: '监听器路径',
+    rows: 8,
+  }
+]
+
+onMounted(() => {
+  getPage()
+})
+
+function getPage() {
+  getDefinitionPageApi(queryData.value).then((resp) => {
+    console.log(resp)
+    tableData.value = resp.list
+    pageTotal.value = resp.total
+  })
+}
+
+function tableSelectionChange(item: StrAnyObjArr) {
+  selectKeys.value = item.map((item) => item.id)
+}
+
+function formSubmit() {
+  formRef.value?.validate(() => {
+    formData.value.listenerType = formData.value.listenerType?.join(",")
+
+    if (formData.value.id) {
+      updateDefinitionApi(formData.value).then(() => {
+        dialogVisible.value = false
+        ElMessage.success('修改成功')
+        getPage()
+      })
+    } else {
+      addDefinitionApi(formData.value).then(() => {
+        dialogVisible.value = false
+        ElMessage.success('新增成功')
+        getPage()
+      })
+    }
+  })
+}
+
+function formClosed() {
+  formRef.value?.resetFields()
+}
+
+function handleRemove(idList: string[]) {
+  useHandleData('是否确认删除?', () => {
+    deleteApi({ idList }).then(() => {
+      ElMessage.success('删除成功')
+      getPage()
+    })
+  })
+}
+</script>
+
+<template>
+  <div>
+    <el-card v-if="showQuery">
+      <a-form ref="queryRef" v-model="queryData" :config="queryConfig" :span="6"> </a-form>
+    </el-card>
+
+    <a-table
+      selection
+      :data="tableData"
+      :page-total="pageTotal"
+      :toolbar-config="toolbarConfig"
+      :column-config="columnConfig"
+      v-model:showQuery="showQuery"
+      v-model:page-num="queryData.pageNum"
+      v-model:page-size="queryData.pageSize"
+      @page-num-change="getPage"
+      @page-size-change="getPage"
+      @selection-change="tableSelectionChange"
+    >
+    </a-table>
+
+    <a-dialog
+      v-model="dialogVisible"
+      :title="dialogTitle"
+      @submit="formSubmit"
+      @closed="formClosed"
+    >
+      <a-form ref="formRef" v-model="formData" :config="formConfig" :span="24"> </a-form>
+    </a-dialog>
+  </div>
+</template>

+ 14 - 7
pom.xml

@@ -27,6 +27,7 @@
         <easy-captcha.version>1.6.2</easy-captcha.version>
         <nashorn-core.version>15.4</nashorn-core.version>
         <beetl.version>3.17.0.RELEASE</beetl.version>
+        <warm-flow.version>1.2.10</warm-flow.version>
     </properties>
 
     <modules>
@@ -36,6 +37,7 @@
         <module>jy-system</module>
         <module>jy-log</module>
         <module>jy-business</module>
+        <module>jy-flow</module>
     </modules>
 
     <!-- 依赖声明 -->
@@ -102,13 +104,6 @@
                 <version>${easy-captcha.version}</version>
             </dependency>
 
-            <!-- java17执行js引擎 -->
-            <dependency>
-                <groupId>org.openjdk.nashorn</groupId>
-                <artifactId>nashorn-core</artifactId>
-                <version>${nashorn-core.version}</version>
-            </dependency>
-
             <!-- mp代码生成 -->
             <dependency>
                 <groupId>com.baomidou</groupId>
@@ -124,6 +119,12 @@
             </dependency>
 
             <dependency>
+                <groupId>io.github.minliuhua</groupId>
+                <version>${warm-flow.version}</version>
+                <artifactId>warm-flow-mybatis-plus-sb-starter</artifactId>
+            </dependency>
+
+            <dependency>
                 <groupId>com.jy</groupId>
                 <artifactId>jy-starter</artifactId>
                 <version>${jy.version}</version>
@@ -153,6 +154,12 @@
                 <version>${jy.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>com.jy</groupId>
+                <artifactId>jy-flow</artifactId>
+                <version>${jy.version}</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>