feat: initial iShare project code
This commit is contained in:
18
pigx-flow/pigx-flow-task/pigx-flow-task-biz/Dockerfile
Normal file
18
pigx-flow/pigx-flow-task/pigx-flow-task-biz/Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
FROM pig4cloud/java:8-jre
|
||||
|
||||
MAINTAINER wangiegie@gmail.com
|
||||
|
||||
ENV TZ=Asia/Shanghai
|
||||
ENV JAVA_OPTS="-Xms512m -Xmx1024m -Djava.security.egd=file:/dev/./urandom"
|
||||
|
||||
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
RUN mkdir -p /pigx-flow-task
|
||||
|
||||
WORKDIR /pigx-flow-task
|
||||
|
||||
EXPOSE 9030
|
||||
|
||||
ADD ./target/pigx-flow-task-biz.jar ./
|
||||
|
||||
CMD sleep 60;java $JAVA_OPTS -jar pigx-flow-task-biz.jar
|
||||
118
pigx-flow/pigx-flow-task/pigx-flow-task-biz/pom.xml
Normal file
118
pigx-flow/pigx-flow-task/pigx-flow-task-biz/pom.xml
Normal file
@@ -0,0 +1,118 @@
|
||||
<?xml version="1.0"?>
|
||||
<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.pig4cloud</groupId>
|
||||
<artifactId>pigx-flow-task</artifactId>
|
||||
<version>5.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-flow-task-biz</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!--必备: undertow容器-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
</dependency>
|
||||
<!--必备: spring boot web-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!--必备: 注册中心客户端-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
<!--必备: 配置中心客户端-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
<!--必备: 操作数据源相关-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-data</artifactId>
|
||||
</dependency>
|
||||
<!--选配: 发号器-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-sequence</artifactId>
|
||||
</dependency>
|
||||
<!--必备:pigx安全模块-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-security</artifactId>
|
||||
</dependency>
|
||||
<!--必备:xss 过滤模块-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-xss</artifactId>
|
||||
</dependency>
|
||||
<!--必备: sentinel 依赖-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-sentinel</artifactId>
|
||||
</dependency>
|
||||
<!--必备: feign 依赖-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-feign</artifactId>
|
||||
</dependency>
|
||||
<!--必备: 依赖api模块-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-flow-task-api</artifactId>
|
||||
</dependency>
|
||||
<!--必备: log 依赖-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-log</artifactId>
|
||||
</dependency>
|
||||
<!--选配: mybatis 依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!--选配: druid 连接池 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!--选配: mysql 数据库驱动 -->
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
</dependency>
|
||||
<!--选配: swagger文档-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-swagger</artifactId>
|
||||
</dependency>
|
||||
<!--测试: spring boot test-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dameng</groupId>
|
||||
<artifactId>DmJdbcDriver18</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.pig4cloud.pigx.flow.task;
|
||||
|
||||
import com.pig4cloud.pigx.common.feign.annotation.EnablePigxFeignClients;
|
||||
import com.pig4cloud.pigx.common.security.annotation.EnablePigxResourceServer;
|
||||
import com.pig4cloud.pigx.common.swagger.annotation.EnableOpenApi;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
|
||||
/**
|
||||
* @author pigx archetype
|
||||
* <p>
|
||||
* 项目启动类
|
||||
*/
|
||||
@EnableOpenApi("task")
|
||||
@EnablePigxFeignClients
|
||||
@EnableDiscoveryClient
|
||||
@EnablePigxResourceServer
|
||||
@SpringBootApplication
|
||||
public class PigxFlowTaskApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(PigxFlowTaskApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.pig4cloud.pigx.flow.task.config;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
|
||||
import com.pig4cloud.pigx.common.sequence.builder.DbSeqBuilder;
|
||||
import com.pig4cloud.pigx.common.sequence.properties.SequenceDbProperties;
|
||||
import com.pig4cloud.pigx.common.sequence.sequence.Sequence;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2023-07-19
|
||||
* <p>
|
||||
* 设置发号器生成规则
|
||||
*/
|
||||
@Configuration
|
||||
public class SequenceConfiguration {
|
||||
|
||||
/**
|
||||
* 工作流发号器
|
||||
* @param dataSource
|
||||
* @param properties
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Sequence flowSequence(DataSource dataSource, SequenceDbProperties properties) {
|
||||
return DbSeqBuilder.create()
|
||||
.bizName(() -> String.format("flow_%s_%s", TenantContextHolder.getTenantId(), DateUtil.today()))
|
||||
.dataSource(dataSource).step(properties.getStep()).retryTimes(properties.getRetryTimes())
|
||||
.tableName(properties.getTableName()).build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.pig4cloud.pigx.flow.task.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.service.ICombinationGroupService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 组聚合接口控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/combination/group")
|
||||
public class CombinationGroupController {
|
||||
|
||||
private final ICombinationGroupService combinationGroupService;
|
||||
|
||||
/**
|
||||
* 查询表单组包含流程
|
||||
* @return 表单组数据
|
||||
*/
|
||||
@GetMapping("listGroupWithProcess")
|
||||
public R listGroupWithProcess(Page page, Long groupId) {
|
||||
return combinationGroupService.listGroupWithProcess(page, groupId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有我可以发起的表单组
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("listCurrentUserStartGroup")
|
||||
public R listCurrentUserStartGroup() {
|
||||
return combinationGroupService.listCurrentUserStartGroup();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.pig4cloud.pigx.flow.task.controller;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.service.IOrgService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author : willian fu
|
||||
* @date : 2022/6/27
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/org")
|
||||
public class OrgController {
|
||||
|
||||
private final IOrgService orgService;
|
||||
|
||||
/**
|
||||
* 查询组织架构树
|
||||
* @param deptId 部门id
|
||||
* @param showLeave 是否显示离职员工
|
||||
* @return 组织架构树数据
|
||||
*/
|
||||
@GetMapping("tree")
|
||||
public R getOrgTreeData(@RequestParam(defaultValue = "0") Long deptId, String type,
|
||||
@RequestParam(defaultValue = "false") Boolean showLeave) {
|
||||
return orgService.getOrgTreeData(deptId, type, showLeave);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模糊搜索用户
|
||||
* @param userName 用户名/拼音/首字母
|
||||
* @return 匹配到的用户
|
||||
*/
|
||||
@GetMapping("tree/user/search")
|
||||
public R getOrgTreeUser(@RequestParam String userName) {
|
||||
return orgService.getOrgTreeUser(userName.trim());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.pig4cloud.pigx.flow.task.controller;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.entity.Process;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessService;
|
||||
import com.pig4cloud.pigx.flow.task.vo.ProcessVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/process")
|
||||
public class ProcessController {
|
||||
|
||||
private final IProcessService processService;
|
||||
|
||||
/**
|
||||
* 获取详细数据
|
||||
* @param flowId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("getDetail")
|
||||
public R<ProcessVO> getDetail(String flowId) {
|
||||
return processService.getDetail(flowId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建流程
|
||||
* @param process
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("create")
|
||||
public R create(@RequestBody Process process) {
|
||||
return processService.create(process);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑表单
|
||||
* @param flowId 摸板ID
|
||||
* @param type 类型 stop using delete
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("update/{flowId}")
|
||||
public R update(@PathVariable String flowId, @RequestParam String type,
|
||||
@RequestParam(required = false) Long groupId) {
|
||||
return processService.update(flowId, type, groupId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.pig4cloud.pigx.flow.task.controller;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessCopyService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程抄送数据 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-20
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/processCopy")
|
||||
public class ProcessCopyController {
|
||||
|
||||
private final IProcessCopyService processCopyService;
|
||||
|
||||
/**
|
||||
* 查询单个抄送详细信息
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("querySingleDetail")
|
||||
public R querySingleDetail(long id) {
|
||||
return processCopyService.querySingleDetail(id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.pig4cloud.pigx.flow.task.controller;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessGroup;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessGroupService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("processGroup")
|
||||
public class ProcessGroupController {
|
||||
|
||||
private final IProcessGroupService processGroupService;
|
||||
|
||||
/**
|
||||
* 组列表
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("list")
|
||||
public R<List<ProcessGroup>> queryList() {
|
||||
return processGroupService.queryList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增流程分组
|
||||
* @param processGroup 分组名
|
||||
* @return 添加结果
|
||||
*/
|
||||
@PostMapping("create")
|
||||
public R create(@RequestBody ProcessGroup processGroup) {
|
||||
return processGroupService.create(processGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除分组
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping("delete/{id}")
|
||||
public R delete(@PathVariable long id) {
|
||||
return processGroupService.delete(id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.pig4cloud.pigx.flow.task.controller;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.dto.ProcessInstanceParamDto;
|
||||
import com.pig4cloud.pigx.flow.task.dto.TaskQueryParamDto;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessInstanceService;
|
||||
import com.pig4cloud.pigx.flow.task.vo.NodeFormatParamVo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 流程实例
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/process-instance")
|
||||
public class ProcessInstanceController {
|
||||
|
||||
private final IProcessInstanceService processInstanceService;
|
||||
|
||||
/**
|
||||
* 启动流程
|
||||
* @param processInstanceParamDto
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("startProcessInstance")
|
||||
public R startProcessInstance(@RequestBody ProcessInstanceParamDto processInstanceParamDto) {
|
||||
return processInstanceService.startProcessInstance(processInstanceParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前登录用户的待办任务
|
||||
* @param pageDto
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("queryMineTask")
|
||||
public R queryMineTask(@RequestBody TaskQueryParamDto queryParamDto) {
|
||||
return processInstanceService.queryMineTask(queryParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前登录用户已办任务
|
||||
* @param taskQueryParamDto
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("queryMineEndTask")
|
||||
public R queryMineEndTask(@RequestBody TaskQueryParamDto taskQueryParamDto) {
|
||||
return processInstanceService.queryMineEndTask(taskQueryParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我发起的
|
||||
* @param pageDto
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("queryMineStarted")
|
||||
public R queryMineStarted(@RequestBody TaskQueryParamDto taskQueryParamDto) {
|
||||
return processInstanceService.queryMineStarted(taskQueryParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询抄送我的
|
||||
* @param pageDto
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("queryMineCC")
|
||||
public R queryMineCC(@RequestBody TaskQueryParamDto taskQueryParamDto) {
|
||||
return processInstanceService.queryMineCC(taskQueryParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化流程显示
|
||||
* @param nodeFormatParamVo
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("formatStartNodeShow")
|
||||
public R formatStartNodeShow(@RequestBody NodeFormatParamVo nodeFormatParamVo) {
|
||||
return processInstanceService.formatStartNodeShow(nodeFormatParamVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程详情
|
||||
* @param processInstanceId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("detail")
|
||||
public R detail(String processInstanceId) {
|
||||
return processInstanceService.detail(processInstanceId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.pig4cloud.pigx.flow.task.controller;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.dto.Node;
|
||||
import com.pig4cloud.pigx.flow.task.dto.ProcessNodeDataDto;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessNodeDataService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程节点数据 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-07
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/processNodeData")
|
||||
public class ProcessNodeDataController {
|
||||
|
||||
private final IProcessNodeDataService processNodeDataService;
|
||||
|
||||
/**
|
||||
* 保存节点数据
|
||||
* @param processNodeDataDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("saveNodeData")
|
||||
public R saveNodeData(@RequestBody ProcessNodeDataDto processNodeDataDto) {
|
||||
return processNodeDataService.saveNodeData(processNodeDataDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取节点数据
|
||||
* @param flowId
|
||||
* @param nodeId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("getNodeData")
|
||||
public R<Node> getNodeData(String flowId, String nodeId) {
|
||||
return processNodeDataService.getNodeData(flowId, nodeId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package com.pig4cloud.pigx.flow.task.controller;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.dto.*;
|
||||
import com.pig4cloud.pigx.flow.task.service.IRemoteService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 远程请求控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/remote")
|
||||
public class RemoteController {
|
||||
|
||||
private final IRemoteService remoteService;
|
||||
|
||||
/**
|
||||
* 根据角色id集合查询用户id集合
|
||||
* @param roleIdList
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("queryUserIdListByRoleIdList")
|
||||
public R<List<Long>> queryUserIdListByRoleIdList(@RequestBody List<Long> roleIdList) {
|
||||
return remoteService.queryUserIdListByRoleIdList(roleIdList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存抄送
|
||||
* @param copyDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("savecc")
|
||||
public R saveCC(@RequestBody ProcessCopyDto copyDto) {
|
||||
return remoteService.saveCC(copyDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是所有的父级
|
||||
* @param checkParentDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("checkIsAllParent")
|
||||
public R<Boolean> checkIsAllParent(@RequestBody CheckParentDto checkParentDto) {
|
||||
return remoteService.checkIsAllParent(checkParentDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门id集合查询用户id集合
|
||||
* @param depIdList
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("queryUserIdListByDepIdList")
|
||||
public R<List<Long>> queryUserIdListByDepIdList(@RequestBody List<Long> depIdList) {
|
||||
return remoteService.queryUserIdListByDepIdList(depIdList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是所有的子级
|
||||
* @param checkChildDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("checkIsAllChild")
|
||||
public R<Boolean> checkIsAllChild(@RequestBody CheckChildDto checkChildDto) {
|
||||
return remoteService.checkIsAllChild(checkChildDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的信息-包括扩展字段
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("queryUserAllInfo")
|
||||
public R<Map<String, Object>> queryUserAllInfo(long userId) {
|
||||
return remoteService.queryUserAllInfo(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始节点事件
|
||||
* @param recordParamDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("startNodeEvent")
|
||||
public R startNodeEvent(@RequestBody ProcessNodeRecordParamDto recordParamDto) {
|
||||
return remoteService.startNodeEvent(recordParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程创建了
|
||||
* @param processInstanceRecordParamDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("createProcessEvent")
|
||||
public R createProcessEvent(@RequestBody ProcessInstanceRecordParamDto processInstanceRecordParamDto) {
|
||||
return remoteService.createProcessEvent(processInstanceRecordParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束节点事件
|
||||
* @param recordParamDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("endNodeEvent")
|
||||
public R endNodeEvent(@RequestBody ProcessNodeRecordParamDto recordParamDto) {
|
||||
return remoteService.endNodeEvent(recordParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始设置执行人
|
||||
* @param processNodeRecordAssignUserParamDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("startAssignUser")
|
||||
public R startAssignUser(@RequestBody ProcessNodeRecordAssignUserParamDto processNodeRecordAssignUserParamDto) {
|
||||
return remoteService.startAssignUser(processNodeRecordAssignUserParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务结束事件
|
||||
* @param processNodeRecordAssignUserParamDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("taskEndEvent")
|
||||
public R taskEndEvent(@RequestBody ProcessNodeRecordAssignUserParamDto processNodeRecordAssignUserParamDto) {
|
||||
return remoteService.taskEndEvent(processNodeRecordAssignUserParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例结束
|
||||
* @param processInstanceParamDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("endProcess")
|
||||
public R endProcess(@RequestBody ProcessInstanceParamDto processInstanceParamDto) {
|
||||
return remoteService.endProcess(processInstanceParamDto.getProcessInstanceId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询流程管理员
|
||||
* @param flowId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("queryProcessAdmin")
|
||||
public R<Long> queryProcessAdmin(String flowId) {
|
||||
return remoteService.queryProcessAdmin(flowId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.pig4cloud.pigx.flow.task.controller;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.dto.TaskParamDto;
|
||||
import com.pig4cloud.pigx.flow.task.service.ITaskService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 任务实例
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/task")
|
||||
public class TaskController {
|
||||
|
||||
private final ITaskService taskService;
|
||||
|
||||
/**
|
||||
* 查询首页数据看板
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@GetMapping("queryTaskData")
|
||||
public R queryTaskData() {
|
||||
return taskService.queryTaskData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询任务
|
||||
* @param taskId
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@GetMapping("queryTask")
|
||||
public R queryTask(String taskId, boolean view) {
|
||||
|
||||
return taskService.queryTask(taskId, view);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成任务
|
||||
* @param completeParamDto
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("completeTask")
|
||||
public R completeTask(@RequestBody TaskParamDto completeParamDto) {
|
||||
|
||||
return taskService.completeTask(completeParamDto);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 前加签
|
||||
* @param completeParamDto
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("delegateTask")
|
||||
public R delegateTask(@RequestBody TaskParamDto completeParamDto) {
|
||||
|
||||
return taskService.delegateTask(completeParamDto);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 加签完成任务
|
||||
* @param completeParamDto
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("resolveTask")
|
||||
public R resolveTask(@RequestBody TaskParamDto completeParamDto) {
|
||||
|
||||
return taskService.resolveTask(completeParamDto);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置执行人
|
||||
* @param completeParamDto
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("setAssignee")
|
||||
public R setAssignee(@RequestBody TaskParamDto completeParamDto) {
|
||||
|
||||
return taskService.setAssignee(completeParamDto);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束流程
|
||||
* @param completeParamDto
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@PostMapping("stopProcessInstance")
|
||||
public R stopProcessInstance(@RequestBody TaskParamDto completeParamDto) {
|
||||
|
||||
return taskService.stopProcessInstance(completeParamDto);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 退回
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("back")
|
||||
public R back(@RequestBody TaskParamDto taskParamDto) {
|
||||
return taskService.back(taskParamDto);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.pig4cloud.pigx.flow.task.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessCopy;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程抄送数据 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-20
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProcessCopyMapper extends BaseMapper<ProcessCopy> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.pig4cloud.pigx.flow.task.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessGroup;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-25
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProcessGroupMapper extends BaseMapper<ProcessGroup> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.pig4cloud.pigx.flow.task.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessInstanceRecord;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程记录 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-07
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProcessInstanceRecordMapper extends BaseMapper<ProcessInstanceRecord> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.pig4cloud.pigx.flow.task.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.pig4cloud.pigx.flow.task.entity.Process;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author cxygzl
|
||||
* @since 2023-05-25
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProcessMapper extends BaseMapper<Process> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.pig4cloud.pigx.flow.task.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessNodeData;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程节点数据 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-07
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProcessNodeDataMapper extends BaseMapper<ProcessNodeData> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.pig4cloud.pigx.flow.task.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessNodeRecordAssignUser;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程节点记录-执行人 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author cxygzl
|
||||
* @since 2023-05-10
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProcessNodeRecordAssignUserMapper extends BaseMapper<ProcessNodeRecordAssignUser> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.pig4cloud.pigx.flow.task.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessNodeRecord;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程节点记录 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author cxygzl
|
||||
* @since 2023-05-10
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProcessNodeRecordMapper extends BaseMapper<ProcessNodeRecord> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.pig4cloud.pigx.flow.task.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessStarter;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程发起人 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-30
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProcessStarterMapper extends BaseMapper<ProcessStarter> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
|
||||
/**
|
||||
* 聚合接口
|
||||
*/
|
||||
public interface ICombinationGroupService {
|
||||
|
||||
/**
|
||||
* 查询表单组包含流程
|
||||
* @param groupId 表单ID
|
||||
* @return 表单组数据
|
||||
*/
|
||||
R listGroupWithProcess(Page page, Long groupId);
|
||||
|
||||
/**
|
||||
* 查询所有我可以发起的表单组
|
||||
* @return
|
||||
*/
|
||||
R listCurrentUserStartGroup();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
|
||||
/**
|
||||
* @author : willian fu
|
||||
* @version : 1.0
|
||||
*/
|
||||
public interface IOrgService {
|
||||
|
||||
/**
|
||||
* 查询组织架构树
|
||||
* @param deptId 部门id
|
||||
* @param type 只查询部门架构
|
||||
* @param showLeave 是否显示离职员工
|
||||
* @return 组织架构树数据
|
||||
*/
|
||||
R getOrgTreeData(Long deptId, String type, Boolean showLeave);
|
||||
|
||||
/**
|
||||
* 模糊搜索用户
|
||||
* @param userName 用户名/拼音/首字母
|
||||
* @return 匹配到的用户
|
||||
*/
|
||||
R getOrgTreeUser(String userName);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessCopy;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程抄送数据 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-20
|
||||
*/
|
||||
public interface IProcessCopyService extends IService<ProcessCopy> {
|
||||
|
||||
/**
|
||||
* 查询单个抄送详细信息
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
R querySingleDetail(long id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-25
|
||||
*/
|
||||
public interface IProcessGroupService extends IService<ProcessGroup> {
|
||||
|
||||
/**
|
||||
* 组列表
|
||||
* @return
|
||||
*/
|
||||
R<List<ProcessGroup>> queryList();
|
||||
|
||||
/**
|
||||
* 新增流程分组
|
||||
* @param processGroup 分组名
|
||||
* @return 添加结果
|
||||
*/
|
||||
R create(ProcessGroup processGroup);
|
||||
|
||||
/**
|
||||
* 删除分组
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
R delete(long id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessInstanceRecord;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程记录 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-07
|
||||
*/
|
||||
public interface IProcessInstanceRecordService extends IService<ProcessInstanceRecord> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.dto.ProcessInstanceParamDto;
|
||||
import com.pig4cloud.pigx.flow.task.dto.TaskQueryParamDto;
|
||||
import com.pig4cloud.pigx.flow.task.vo.NodeFormatParamVo;
|
||||
|
||||
/**
|
||||
* 流程实例进程
|
||||
*/
|
||||
public interface IProcessInstanceService {
|
||||
|
||||
/**
|
||||
* 启动流程
|
||||
* @param processInstanceParamDto
|
||||
* @return
|
||||
*/
|
||||
R startProcessInstance(ProcessInstanceParamDto processInstanceParamDto);
|
||||
|
||||
/**
|
||||
* 查询当前登录用户的待办任务
|
||||
* @param taskQueryParamDto taskQueryParamDto
|
||||
* @return
|
||||
*/
|
||||
R queryMineTask(TaskQueryParamDto taskQueryParamDto);
|
||||
|
||||
/**
|
||||
* 查询已办任务
|
||||
* @param taskQueryParamDto
|
||||
* @return
|
||||
*/
|
||||
R queryMineEndTask(TaskQueryParamDto taskQueryParamDto);
|
||||
|
||||
/**
|
||||
* 流程结束
|
||||
* @param processsInstanceId
|
||||
* @return
|
||||
*/
|
||||
R end(String processsInstanceId);
|
||||
|
||||
/**
|
||||
* 查询我发起的
|
||||
* @param taskQueryParamDto
|
||||
* @return
|
||||
*/
|
||||
R queryMineStarted(TaskQueryParamDto taskQueryParamDto);
|
||||
|
||||
/**
|
||||
* 查询抄送给我的
|
||||
* @param taskQueryParamDto
|
||||
* @return
|
||||
*/
|
||||
R queryMineCC(TaskQueryParamDto taskQueryParamDto);
|
||||
|
||||
/**
|
||||
* 格式化流程显示
|
||||
* @param nodeFormatParamVo
|
||||
* @return
|
||||
*/
|
||||
R formatStartNodeShow(NodeFormatParamVo nodeFormatParamVo);
|
||||
|
||||
/**
|
||||
* 流程详情
|
||||
* @param processInstanceId
|
||||
* @return
|
||||
*/
|
||||
R detail(String processInstanceId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.dto.Node;
|
||||
import com.pig4cloud.pigx.flow.task.dto.ProcessNodeDataDto;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessNodeData;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程节点数据 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-07
|
||||
*/
|
||||
public interface IProcessNodeDataService extends IService<ProcessNodeData> {
|
||||
|
||||
/**
|
||||
* 保存流程节点数据
|
||||
* @param processNodeDataDto
|
||||
* @return
|
||||
*/
|
||||
R saveNodeData(ProcessNodeDataDto processNodeDataDto);
|
||||
|
||||
/***
|
||||
* 获取节点数据
|
||||
* @param flowId
|
||||
* @param nodeId
|
||||
* @return
|
||||
*/
|
||||
R<Node> getNodeData(String flowId, String nodeId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.dto.ProcessNodeRecordAssignUserParamDto;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessNodeRecordAssignUser;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程节点记录-执行人 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author cxygzl
|
||||
* @since 2023-05-10
|
||||
*/
|
||||
public interface IProcessNodeRecordAssignUserService extends IService<ProcessNodeRecordAssignUser> {
|
||||
|
||||
/**
|
||||
* 设置执行人
|
||||
* @param processNodeRecordAssignUserParamDto
|
||||
* @return
|
||||
*/
|
||||
R addAssignUser(ProcessNodeRecordAssignUserParamDto processNodeRecordAssignUserParamDto);
|
||||
|
||||
/**
|
||||
* 任务完成通知
|
||||
* @param processNodeRecordAssignUserParamDto
|
||||
* @return
|
||||
*/
|
||||
R completeTaskEvent(ProcessNodeRecordAssignUserParamDto processNodeRecordAssignUserParamDto);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.dto.ProcessNodeRecordParamDto;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessNodeRecord;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程节点记录 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author cxygzl
|
||||
* @since 2023-05-10
|
||||
*/
|
||||
public interface IProcessNodeRecordService extends IService<ProcessNodeRecord> {
|
||||
|
||||
/**
|
||||
* 节点开始
|
||||
* @param processNodeRecordParamDto
|
||||
* @return
|
||||
*/
|
||||
R start(ProcessNodeRecordParamDto processNodeRecordParamDto);
|
||||
|
||||
/**
|
||||
* 节点结束
|
||||
* @param processNodeRecordParamDto
|
||||
* @return
|
||||
*/
|
||||
R complete(ProcessNodeRecordParamDto processNodeRecordParamDto);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.entity.Process;
|
||||
import com.pig4cloud.pigx.flow.task.vo.ProcessVO;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author cxygzl
|
||||
* @since 2023-05-25
|
||||
*/
|
||||
public interface IProcessService extends IService<Process> {
|
||||
|
||||
/**
|
||||
* 获取详细数据
|
||||
* @param flowId
|
||||
* @return
|
||||
*/
|
||||
R<ProcessVO> getDetail(String flowId);
|
||||
|
||||
Process getByFlowId(String flowId);
|
||||
|
||||
void updateByFlowId(Process process);
|
||||
|
||||
void hide(String flowId);
|
||||
|
||||
/**
|
||||
* 创建流程
|
||||
* @param process
|
||||
* @return
|
||||
*/
|
||||
R create(Process process);
|
||||
|
||||
/**
|
||||
* 编辑表单
|
||||
* @param flowId 摸板ID
|
||||
* @param type 类型 stop using delete
|
||||
* @return 操作结果
|
||||
*/
|
||||
R update(String flowId, String type, Long groupId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessStarter;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程发起人 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-30
|
||||
*/
|
||||
public interface IProcessStarterService extends IService<ProcessStarter> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.dto.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 远程调用的接口
|
||||
*/
|
||||
public interface IRemoteService {
|
||||
|
||||
/**
|
||||
* 根据角色id集合查询用户id集合
|
||||
* @param roleIdList
|
||||
* @return
|
||||
*/
|
||||
R<List<Long>> queryUserIdListByRoleIdList(List<Long> roleIdList);
|
||||
|
||||
/**
|
||||
* 保存抄送
|
||||
* @param copyDto
|
||||
* @return
|
||||
*/
|
||||
R saveCC(ProcessCopyDto copyDto);
|
||||
|
||||
/**
|
||||
* 检查是否是所有的父级
|
||||
* @param checkParentDto
|
||||
* @return
|
||||
*/
|
||||
R<Boolean> checkIsAllParent(CheckParentDto checkParentDto);
|
||||
|
||||
/**
|
||||
* 根据部门id集合查询用户id集合
|
||||
* @param depIdList
|
||||
* @return
|
||||
*/
|
||||
R<List<Long>> queryUserIdListByDepIdList(List<Long> depIdList);
|
||||
|
||||
/**
|
||||
* 检查是否是所有的子级
|
||||
* @param checkChildDto
|
||||
* @return
|
||||
*/
|
||||
R<Boolean> checkIsAllChild(CheckChildDto checkChildDto);
|
||||
|
||||
/**
|
||||
* 获取用户的信息-包括扩展字段
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
R<Map<String, Object>> queryUserAllInfo(long userId);
|
||||
|
||||
/**
|
||||
* 开始节点事件
|
||||
* @param recordParamDto
|
||||
* @return
|
||||
*/
|
||||
R startNodeEvent(ProcessNodeRecordParamDto recordParamDto);
|
||||
|
||||
/**
|
||||
* 流程创建了
|
||||
* @param processInstanceRecordParamDto
|
||||
* @return
|
||||
*/
|
||||
R createProcessEvent(ProcessInstanceRecordParamDto processInstanceRecordParamDto);
|
||||
|
||||
/**
|
||||
* 完成节点事件
|
||||
* @param recordParamDto
|
||||
* @return
|
||||
*/
|
||||
R endNodeEvent(ProcessNodeRecordParamDto recordParamDto);
|
||||
|
||||
/**
|
||||
* 开始设置执行人
|
||||
* @param processNodeRecordAssignUserParamDto
|
||||
* @return
|
||||
*/
|
||||
R startAssignUser(ProcessNodeRecordAssignUserParamDto processNodeRecordAssignUserParamDto);
|
||||
|
||||
/**
|
||||
* 任务结束事件
|
||||
* @param processNodeRecordAssignUserParamDto
|
||||
* @return
|
||||
*/
|
||||
R taskEndEvent(ProcessNodeRecordAssignUserParamDto processNodeRecordAssignUserParamDto);
|
||||
|
||||
/**
|
||||
* 实例结束
|
||||
* @param processInstanceId
|
||||
* @return
|
||||
*/
|
||||
R endProcess(String processInstanceId);
|
||||
|
||||
/**
|
||||
* 查询流程管理员
|
||||
* @param flowId
|
||||
* @return
|
||||
*/
|
||||
R<Long> queryProcessAdmin(String flowId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.pig4cloud.pigx.flow.task.service;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.dto.TaskParamDto;
|
||||
|
||||
/**
|
||||
* 任务处理
|
||||
*/
|
||||
public interface ITaskService {
|
||||
|
||||
/**
|
||||
* 查询任务
|
||||
* @param taskId
|
||||
* @param view
|
||||
* @return
|
||||
*/
|
||||
R queryTask(String taskId, boolean view);
|
||||
|
||||
/**
|
||||
* 完成任务
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
R completeTask(TaskParamDto taskParamDto);
|
||||
|
||||
/**
|
||||
* 前加签
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
R delegateTask(TaskParamDto taskParamDto);
|
||||
|
||||
/**
|
||||
* 加签完成任务
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
R resolveTask(TaskParamDto taskParamDto);
|
||||
|
||||
/**
|
||||
* 设置执行人
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
R setAssignee(TaskParamDto taskParamDto);
|
||||
|
||||
/**
|
||||
* 结束流程
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
R stopProcessInstance(TaskParamDto taskParamDto);
|
||||
|
||||
/**
|
||||
* 退回
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
R back(TaskParamDto taskParamDto);
|
||||
|
||||
/**
|
||||
* 查询首页数据看板
|
||||
* @return
|
||||
*/
|
||||
R queryTaskData();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.security.service.PigxUser;
|
||||
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
|
||||
import com.pig4cloud.pigx.flow.task.constant.NodeUserTypeEnum;
|
||||
import com.pig4cloud.pigx.flow.task.entity.Process;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessGroup;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessStarter;
|
||||
import com.pig4cloud.pigx.flow.task.service.ICombinationGroupService;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessGroupService;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessService;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessStarterService;
|
||||
import com.pig4cloud.pigx.flow.task.vo.FormGroupVo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class CombinationGroupServiceImpl implements ICombinationGroupService {
|
||||
|
||||
private final IProcessGroupService processGroupService;
|
||||
|
||||
private final IProcessService processService;
|
||||
|
||||
private final IProcessStarterService processStarterService;
|
||||
|
||||
/**
|
||||
* 查询表单组包含流程
|
||||
* @param hidden
|
||||
* @return 表单组数据
|
||||
*/
|
||||
@Override
|
||||
public R listGroupWithProcess(Page page, Long groupId) {
|
||||
return R.ok(processService.lambdaQuery().eq(Process::getGroupId, groupId).eq(Process::getHidden, false)
|
||||
.orderByAsc(Process::getSort).orderByDesc(Process::getCreateTime).page(page));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有我可以发起的表单组
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R listCurrentUserStartGroup() {
|
||||
PigxUser user = SecurityUtils.getUser();
|
||||
|
||||
List<FormGroupVo> formGroupVos = new LinkedList<>();
|
||||
|
||||
List<ProcessGroup> processGroupList = processGroupService.lambdaQuery().orderByAsc(ProcessGroup::getSort)
|
||||
.list();
|
||||
|
||||
processGroupList.forEach(group -> {
|
||||
FormGroupVo formGroupVo = FormGroupVo.builder().id(group.getId()).name(group.getGroupName())
|
||||
.items(new LinkedList<>()).build();
|
||||
formGroupVos.add(formGroupVo);
|
||||
|
||||
List<Process> processList = processService.lambdaQuery().eq(Process::getGroupId, group.getId())
|
||||
.eq(Process::getHidden, false).eq(Process::getStop, false).orderByAsc(Process::getSort).list();
|
||||
|
||||
Map<Long, Boolean> existMap = new HashMap<>();
|
||||
|
||||
if (!processList.isEmpty()) {
|
||||
List<Long> idList = processList.stream().map(Process::getId).collect(Collectors.toList());
|
||||
// 查询发起人集合
|
||||
List<ProcessStarter> processStarterList = processStarterService.lambdaQuery()
|
||||
.in(ProcessStarter::getProcessId, idList).list();
|
||||
Map<Long, List<ProcessStarter>> groupmap = processStarterList.stream()
|
||||
.collect(Collectors.groupingBy(ProcessStarter::getProcessId));
|
||||
|
||||
for (Process process : processList) {
|
||||
List<ProcessStarter> processStarters = groupmap.get(process.getId());
|
||||
if (processStarters == null) {
|
||||
existMap.put(process.getId(), true);
|
||||
continue;
|
||||
}
|
||||
boolean match = processStarters.stream().anyMatch(w -> w.getTypeId().longValue() == user.getId()
|
||||
&& w.getType().equals(NodeUserTypeEnum.USER.getKey()));
|
||||
if (match) {
|
||||
existMap.put(process.getId(), true);
|
||||
continue;
|
||||
}
|
||||
Set<Long> deptIdSet = processStarters.stream()
|
||||
.filter(w -> w.getType().equals(NodeUserTypeEnum.DEPT.getKey())).map(w -> w.getTypeId())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
existMap.put(process.getId(), deptIdSet.contains(user.getDeptId()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
processList.forEach(process -> {
|
||||
|
||||
if (!existMap.get(process.getId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
formGroupVo.getItems()
|
||||
.add(FormGroupVo.FlowVo.builder().flowId(process.getFlowId()).name(process.getName())
|
||||
.logo(process.getLogo()).remark(process.getRemark()).stop(process.getStop())
|
||||
.updated(process.getUpdateTime()).build());
|
||||
});
|
||||
});
|
||||
return R.ok(formGroupVos);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysDept;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysRole;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysUser;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteDeptService;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteRoleService;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteUserService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.core.util.RetOps;
|
||||
import com.pig4cloud.pigx.flow.task.constant.NodeUserTypeEnum;
|
||||
import com.pig4cloud.pigx.flow.task.service.IOrgService;
|
||||
import com.pig4cloud.pigx.flow.task.utils.DataUtil;
|
||||
import com.pig4cloud.pigx.flow.task.vo.OrgTreeVo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class OrgServiceImpl implements IOrgService {
|
||||
|
||||
private final RemoteUserService remoteUserService;
|
||||
|
||||
private final RemoteRoleService remoteRoleService;
|
||||
|
||||
private final RemoteDeptService remoteDeptService;
|
||||
|
||||
/**
|
||||
* 查询组织架构树
|
||||
* @param deptId 部门id
|
||||
* @param type 只查询部门架构
|
||||
* @param showLeave 是否显示离职员工
|
||||
* @return 组织架构树数据
|
||||
*/
|
||||
@Override
|
||||
public R getOrgTreeData(Long deptId, String type, Boolean showLeave) {
|
||||
List<OrgTreeVo> orgs = new LinkedList<>();
|
||||
|
||||
if (StrUtil.equals(type, NodeUserTypeEnum.ROLE.getKey())) {
|
||||
// 角色
|
||||
|
||||
List<SysRole> roleList = remoteRoleService.getAllRole().getData();
|
||||
|
||||
for (SysRole role : roleList) {
|
||||
OrgTreeVo orgTreeVo = new OrgTreeVo();
|
||||
orgTreeVo.setId(role.getRoleId());
|
||||
orgTreeVo.setName(role.getRoleName());
|
||||
orgTreeVo.setType(NodeUserTypeEnum.ROLE.getKey());
|
||||
orgTreeVo.setSelected(false);
|
||||
orgs.add(orgTreeVo);
|
||||
}
|
||||
|
||||
Dict dict = Dict.create().set("roleList", orgs).set("childDepartments", orgs).set("employees",
|
||||
new ArrayList<>());
|
||||
return R.ok(dict);
|
||||
|
||||
}
|
||||
|
||||
Dict dict = Dict.create().set("titleDepartments", new ArrayList<>()).set("roleList", new ArrayList<>())
|
||||
.set("employees", new ArrayList<>());
|
||||
|
||||
List<SysDept> deptList = remoteDeptService.getAllDept().getData();
|
||||
|
||||
// 查询所有部门及员工
|
||||
{
|
||||
List deptVoList = new ArrayList();
|
||||
for (SysDept dept : deptList) {
|
||||
OrgTreeVo orgTreeVo = new OrgTreeVo();
|
||||
orgTreeVo.setId(dept.getDeptId());
|
||||
orgTreeVo.setName(dept.getName());
|
||||
orgTreeVo.setType(NodeUserTypeEnum.DEPT.getKey());
|
||||
orgTreeVo.setSelected(false);
|
||||
deptVoList.add(orgTreeVo);
|
||||
}
|
||||
dict.set("childDepartments", deptVoList);
|
||||
}
|
||||
if (!StrUtil.equals(type, NodeUserTypeEnum.DEPT.getKey())) {
|
||||
|
||||
List userVoList = new ArrayList();
|
||||
|
||||
List<SysUser> userList = remoteUserService.getUserIdListByDeptIdList(CollUtil.toList(deptId)).getData();
|
||||
|
||||
for (SysUser user : userList) {
|
||||
OrgTreeVo orgTreeVo = new OrgTreeVo();
|
||||
orgTreeVo.setId(user.getUserId());
|
||||
orgTreeVo.setName(user.getUsername());
|
||||
orgTreeVo.setType(NodeUserTypeEnum.USER.getKey());
|
||||
orgTreeVo.setSelected(false);
|
||||
orgTreeVo.setAvatar(user.getAvatar());
|
||||
userVoList.add(orgTreeVo);
|
||||
}
|
||||
dict.set("employees", userVoList);
|
||||
}
|
||||
|
||||
if (deptId > 0) {
|
||||
List<SysDept> allDept = remoteDeptService.getAllDept().getData();
|
||||
List<SysDept> depts = DataUtil.selectParentByDept(deptId, allDept);
|
||||
dict.set("titleDepartments", CollUtil.reverse(depts));
|
||||
}
|
||||
|
||||
return R.ok(dict);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模糊搜索用户
|
||||
* @param userName 用户名/拼音/首字母
|
||||
* @return 匹配到的用户
|
||||
*/
|
||||
@Override
|
||||
public R getOrgTreeUser(String userName) {
|
||||
return R.ok(RetOps.of(remoteUserService.getUserListByUserName(userName)).getData().orElseGet(ArrayList::new)
|
||||
.stream().map(user -> {
|
||||
OrgTreeVo orgTreeVo = new OrgTreeVo();
|
||||
orgTreeVo.setId(user.getUserId());
|
||||
orgTreeVo.setName(user.getUsername());
|
||||
orgTreeVo.setType(NodeUserTypeEnum.USER.getKey());
|
||||
orgTreeVo.setSelected(false);
|
||||
orgTreeVo.setAvatar(user.getAvatar());
|
||||
return orgTreeVo;
|
||||
}).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.constant.FormTypeEnum;
|
||||
import com.pig4cloud.pigx.flow.task.constant.ProcessInstanceConstant;
|
||||
import com.pig4cloud.pigx.flow.task.dto.Node;
|
||||
import com.pig4cloud.pigx.flow.task.entity.Process;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessCopy;
|
||||
import com.pig4cloud.pigx.flow.task.mapper.ProcessCopyMapper;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessCopyService;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessNodeDataService;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessService;
|
||||
import com.pig4cloud.pigx.flow.task.vo.FormItemVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程抄送数据 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-20
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ProcessCopyServiceImpl extends ServiceImpl<ProcessCopyMapper, ProcessCopy> implements IProcessCopyService {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
private final IProcessService processService;
|
||||
|
||||
private final IProcessNodeDataService nodeDataService;
|
||||
|
||||
/**
|
||||
* 查询单个抄送详细信息
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public R querySingleDetail(long id) {
|
||||
ProcessCopy processCopy = this.getById(id);
|
||||
String flowId = processCopy.getFlowId();
|
||||
Process oaForms = processService.getByFlowId(flowId);
|
||||
if (oaForms == null) {
|
||||
return R.failed("流程不存在");
|
||||
}
|
||||
String formData = processCopy.getFormData();
|
||||
|
||||
Map<String, Object> variableMap = objectMapper.readValue(formData, new TypeReference<Map<String, Object>>() {
|
||||
});
|
||||
|
||||
String nodeId = processCopy.getNodeId();
|
||||
|
||||
Node node = nodeDataService.getNodeData(flowId, nodeId).getData();
|
||||
Map<String, String> formPerms = node.getFormPerms();
|
||||
|
||||
List<FormItemVO> jsonObjectList = objectMapper.readValue(oaForms.getFormItems(),
|
||||
new TypeReference<List<FormItemVO>>() {
|
||||
});
|
||||
for (FormItemVO formItemVO : jsonObjectList) {
|
||||
String fid = formItemVO.getId();
|
||||
String perm = formPerms.get(fid);
|
||||
formItemVO.setPerm(StrUtil.isBlankIfStr(perm) ? ProcessInstanceConstant.FormPermClass.HIDE : perm);
|
||||
|
||||
if (formItemVO.getType().equals(FormTypeEnum.LAYOUT.getType())) {
|
||||
// 明细
|
||||
|
||||
List<Map<String, Object>> subParamList = MapUtil.get(variableMap, fid,
|
||||
new cn.hutool.core.lang.TypeReference<List<Map<String, Object>>>() {
|
||||
});
|
||||
|
||||
Object value = formItemVO.getProps().getValue();
|
||||
|
||||
List<List<FormItemVO>> l = new ArrayList<>();
|
||||
for (Map<String, Object> map : subParamList) {
|
||||
List<FormItemVO> subItemList = Convert.toList(FormItemVO.class, value);
|
||||
for (FormItemVO itemVO : subItemList) {
|
||||
itemVO.getProps().setValue(map.get(itemVO.getId()));
|
||||
|
||||
String permSub = formPerms.get(itemVO.getId());
|
||||
if (StrUtil.isNotBlank(permSub)) {
|
||||
itemVO.setPerm(ProcessInstanceConstant.FormPermClass.EDIT.equals(permSub)
|
||||
? ProcessInstanceConstant.FormPermClass.READ : permSub
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
else {
|
||||
itemVO.setPerm(ProcessInstanceConstant.FormPermClass.HIDE);
|
||||
}
|
||||
|
||||
}
|
||||
l.add(subItemList);
|
||||
}
|
||||
formItemVO.getProps().setValue(l);
|
||||
|
||||
}
|
||||
else {
|
||||
formItemVO.getProps().setValue(variableMap.get(fid));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Dict set = Dict.create().set("formItems", jsonObjectList);
|
||||
|
||||
return R.ok(set);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessGroup;
|
||||
import com.pig4cloud.pigx.flow.task.mapper.ProcessGroupMapper;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessGroupService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-25
|
||||
*/
|
||||
@Service
|
||||
public class ProcessGroupServiceImpl extends ServiceImpl<ProcessGroupMapper, ProcessGroup>
|
||||
implements IProcessGroupService {
|
||||
|
||||
/**
|
||||
* 组列表
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R<List<ProcessGroup>> queryList() {
|
||||
List<ProcessGroup> processGroupList = this.lambdaQuery().orderByAsc(ProcessGroup::getSort).list();
|
||||
|
||||
return R.ok(processGroupList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增表单分组
|
||||
* @param processGroup 分组名
|
||||
* @return 添加结果
|
||||
*/
|
||||
@Override
|
||||
public R create(ProcessGroup processGroup) {
|
||||
ProcessGroup pg = new ProcessGroup();
|
||||
pg.setSort(0);
|
||||
pg.setGroupName(processGroup.getGroupName());
|
||||
|
||||
this.save(pg);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除分组
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R delete(long id) {
|
||||
this.removeById(id);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessInstanceRecord;
|
||||
import com.pig4cloud.pigx.flow.task.mapper.ProcessInstanceRecordMapper;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessInstanceRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程记录 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-07
|
||||
*/
|
||||
@Service
|
||||
public class ProcessInstanceRecordServiceImpl extends ServiceImpl<ProcessInstanceRecordMapper, ProcessInstanceRecord>
|
||||
implements IProcessInstanceRecordService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,417 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysUser;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteUserService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.security.service.PigxUser;
|
||||
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
|
||||
import com.pig4cloud.pigx.flow.task.api.feign.RemoteFlowEngineService;
|
||||
import com.pig4cloud.pigx.flow.task.constant.FormTypeEnum;
|
||||
import com.pig4cloud.pigx.flow.task.constant.NodeStatusEnum;
|
||||
import com.pig4cloud.pigx.flow.task.constant.NodeUserTypeEnum;
|
||||
import com.pig4cloud.pigx.flow.task.constant.ProcessInstanceConstant;
|
||||
import com.pig4cloud.pigx.flow.task.dto.*;
|
||||
import com.pig4cloud.pigx.flow.task.entity.Process;
|
||||
import com.pig4cloud.pigx.flow.task.entity.*;
|
||||
import com.pig4cloud.pigx.flow.task.service.*;
|
||||
import com.pig4cloud.pigx.flow.task.utils.NodeFormatUtil;
|
||||
import com.pig4cloud.pigx.flow.task.vo.FormItemVO;
|
||||
import com.pig4cloud.pigx.flow.task.vo.NodeFormatParamVo;
|
||||
import com.pig4cloud.pigx.flow.task.vo.NodeVo;
|
||||
import com.pig4cloud.pigx.flow.task.vo.ProcessCopyVo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 实例进程服务
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class ProcessInstanceServiceImpl implements IProcessInstanceService {
|
||||
|
||||
private final RemoteFlowEngineService flowEngineService;
|
||||
|
||||
private final RemoteUserService userService;
|
||||
|
||||
private final IProcessInstanceRecordService processInstanceRecordService;
|
||||
|
||||
private final IProcessCopyService processCopyService;
|
||||
|
||||
private final IProcessService processService;
|
||||
|
||||
private final IProcessNodeRecordService processNodeRecordService;
|
||||
|
||||
private final IProcessNodeRecordAssignUserService processNodeRecordAssignUserService;
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
/**
|
||||
* 启动流程
|
||||
* @param processInstanceParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R startProcessInstance(ProcessInstanceParamDto processInstanceParamDto) {
|
||||
|
||||
PigxUser user = SecurityUtils.getUser();
|
||||
|
||||
processInstanceParamDto.setStartUserId(String.valueOf(user.getId()));
|
||||
Map<String, Object> paramMap = processInstanceParamDto.getParamMap();
|
||||
Dict rootUser = Dict.create().set("id", user.getId()).set("name", user.getUsername()).set("type",
|
||||
NodeUserTypeEnum.USER.getKey());
|
||||
paramMap.put("root", CollUtil.newArrayList(rootUser));
|
||||
return flowEngineService.startProcess(processInstanceParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前登录用户的待办任务
|
||||
* @param pageVO
|
||||
* @param taskDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R queryMineTask(TaskQueryParamDto taskQueryParamDto) {
|
||||
taskQueryParamDto.setAssign(SecurityUtils.getUser().getId().toString());
|
||||
R<Page<TaskDto>> r = flowEngineService.queryAssignTask(taskQueryParamDto);
|
||||
|
||||
if (CollUtil.isEmpty(r.getData().getRecords())) {
|
||||
return r;
|
||||
}
|
||||
|
||||
Set<String> processInstanceIdSet = r.getData().getRecords().stream().map(TaskDto::getProcessInstanceId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 流程实例记录
|
||||
List<ProcessInstanceRecord> processInstanceRecordList = processInstanceRecordService.lambdaQuery()
|
||||
.in(ProcessInstanceRecord::getProcessInstanceId, processInstanceIdSet).list();
|
||||
|
||||
// 发起人
|
||||
List<SysUser> startUserList = processInstanceRecordList.stream().map(ProcessInstanceRecord::getUserId)
|
||||
.map(userId -> userService.getUserById(userId).getData()).collect(Collectors.toList());
|
||||
|
||||
Page<TaskDto> pageResultDto = r.getData();
|
||||
List<TaskDto> taskDtoList = new ArrayList<>();
|
||||
for (TaskDto record : r.getData().getRecords()) {
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordList.stream()
|
||||
.filter(w -> StrUtil.equals(w.getProcessInstanceId(), record.getProcessInstanceId())).findAny()
|
||||
.orElse(null);
|
||||
|
||||
if (processInstanceRecord != null) {
|
||||
record.setProcessName(processInstanceRecord.getName());
|
||||
SysUser startUser = startUserList.stream()
|
||||
.filter(w -> w.getUserId().longValue() == processInstanceRecord.getUserId()).findAny()
|
||||
.orElse(null);
|
||||
|
||||
record.setRootUserId(processInstanceRecord.getUserId());
|
||||
record.setGroupName(processInstanceRecord.getGroupName());
|
||||
record.setRootUserName(startUser.getUsername());
|
||||
record.setRootUserAvatarUrl(startUser.getAvatar());
|
||||
record.setStartTime(processInstanceRecord.getCreateTime());
|
||||
|
||||
taskDtoList.add(record);
|
||||
}
|
||||
}
|
||||
|
||||
pageResultDto.setRecords(taskDtoList);
|
||||
|
||||
return R.ok(pageResultDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询已办任务
|
||||
* @param taskQueryParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R queryMineEndTask(TaskQueryParamDto taskQueryParamDto) {
|
||||
taskQueryParamDto.setAssign(SecurityUtils.getUser().getId().toString());
|
||||
R<Page<TaskDto>> r = flowEngineService.queryCompletedTask(taskQueryParamDto);
|
||||
|
||||
Page<TaskDto> pageResultDto = r.getData();
|
||||
List<TaskDto> records = pageResultDto.getRecords();
|
||||
if (CollUtil.isEmpty(records)) {
|
||||
return R.ok(pageResultDto);
|
||||
|
||||
}
|
||||
|
||||
Set<String> processInstanceIdSet = records.stream().map(TaskDto::getProcessInstanceId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 流程实例记录
|
||||
List<ProcessInstanceRecord> processInstanceRecordList = processInstanceRecordService.lambdaQuery()
|
||||
.in(ProcessInstanceRecord::getProcessInstanceId, processInstanceIdSet).list();
|
||||
|
||||
// 发起人
|
||||
List<SysUser> startUserList = processInstanceRecordList.stream().map(ProcessInstanceRecord::getUserId)
|
||||
.map(userId -> userService.getUserById(userId).getData()).collect(Collectors.toList());
|
||||
|
||||
List<TaskDto> taskDtoList = new ArrayList<>();
|
||||
for (TaskDto record : records) {
|
||||
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordList.stream()
|
||||
.filter(w -> StrUtil.equals(w.getProcessInstanceId(), record.getProcessInstanceId())).findAny()
|
||||
.orElse(null);
|
||||
|
||||
if (processInstanceRecord != null) {
|
||||
|
||||
record.setProcessName(processInstanceRecord.getName());
|
||||
|
||||
SysUser startUser = startUserList.stream()
|
||||
.filter(w -> w.getUserId().longValue() == processInstanceRecord.getUserId()).findAny()
|
||||
.orElse(null);
|
||||
|
||||
record.setRootUserId(processInstanceRecord.getUserId());
|
||||
record.setGroupName(processInstanceRecord.getGroupName());
|
||||
record.setRootUserName(startUser.getName());
|
||||
record.setRootUserAvatarUrl(startUser.getAvatar());
|
||||
record.setTaskId(record.getTaskId());
|
||||
record.setStartTime(processInstanceRecord.getCreateTime());
|
||||
taskDtoList.add(record);
|
||||
}
|
||||
}
|
||||
|
||||
pageResultDto.setRecords(taskDtoList);
|
||||
|
||||
return R.ok(pageResultDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程结束
|
||||
* @param processsInstanceId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R end(String processsInstanceId) {
|
||||
processInstanceRecordService.lambdaUpdate().set(ProcessInstanceRecord::getEndTime, new Date())
|
||||
.set(ProcessInstanceRecord::getStatus, NodeStatusEnum.YJS.getCode())
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processsInstanceId)
|
||||
.update(new ProcessInstanceRecord());
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我发起的
|
||||
* @param pageDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R queryMineStarted(TaskQueryParamDto taskQueryParamDto) {
|
||||
|
||||
long userId = SecurityUtils.getUser().getId();
|
||||
|
||||
Page<ProcessInstanceRecord> instanceRecordPage = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getUserId, userId)
|
||||
.eq(ProcessInstanceRecord::getStatus, taskQueryParamDto.getStatus())
|
||||
.between(ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()), ProcessInstanceRecord::getCreateTime,
|
||||
ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[0]
|
||||
: null,
|
||||
ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[1]
|
||||
: null)
|
||||
.orderByDesc(ProcessInstanceRecord::getCreateTime)
|
||||
.page(new Page<>(taskQueryParamDto.getPageNum(), taskQueryParamDto.getPageSize()));
|
||||
|
||||
return R.ok(instanceRecordPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询抄送给我的
|
||||
* @param pageDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R queryMineCC(TaskQueryParamDto taskQueryParamDto) {
|
||||
|
||||
long userId = SecurityUtils.getUser().getId();
|
||||
|
||||
Page<ProcessCopy> page = processCopyService.lambdaQuery().eq(ProcessCopy::getUserId, userId).between(
|
||||
ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()), ProcessCopy::getCreateTime,
|
||||
ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[0] : null,
|
||||
ArrayUtil.isNotEmpty(taskQueryParamDto.getTaskTime()) ? taskQueryParamDto.getTaskTime()[1] : null)
|
||||
.orderByDesc(ProcessCopy::getNodeTime)
|
||||
.page(new Page<>(taskQueryParamDto.getPageNum(), taskQueryParamDto.getPageSize()));
|
||||
|
||||
List<ProcessCopy> records = page.getRecords();
|
||||
|
||||
List<ProcessCopyVo> processCopyVoList = BeanUtil.copyToList(records, ProcessCopyVo.class);
|
||||
|
||||
if (CollUtil.isNotEmpty(records)) {
|
||||
// 发起人
|
||||
List<SysUser> startUserList = records.stream().map(ProcessCopy::getStartUserId)
|
||||
.map(id -> userService.getUserById(id).getData()).collect(Collectors.toList());
|
||||
|
||||
for (ProcessCopyVo record : processCopyVoList) {
|
||||
SysUser startUser = startUserList.stream()
|
||||
.filter(w -> w.getUserId().longValue() == record.getStartUserId()).findAny().orElse(null);
|
||||
record.setStartUserName(startUser.getUsername());
|
||||
}
|
||||
}
|
||||
|
||||
Page p = BeanUtil.copyProperties(page, Page.class);
|
||||
|
||||
p.setRecords(processCopyVoList);
|
||||
|
||||
return R.ok(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化流程显示
|
||||
* @param nodeFormatParamVo
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public R formatStartNodeShow(NodeFormatParamVo nodeFormatParamVo) {
|
||||
String flowId = nodeFormatParamVo.getFlowId();
|
||||
String processInstanceId = nodeFormatParamVo.getProcessInstanceId();
|
||||
if (StrUtil.isAllBlank(flowId, processInstanceId)) {
|
||||
return R.ok(new ArrayList<>());
|
||||
}
|
||||
|
||||
if (StrUtil.isBlankIfStr(flowId) && StrUtil.isNotBlank(processInstanceId)) {
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId).one();
|
||||
flowId = processInstanceRecord.getFlowId();
|
||||
|
||||
}
|
||||
Map<String, Object> paramMap = nodeFormatParamVo.getParamMap();
|
||||
if (StrUtil.isNotBlank(nodeFormatParamVo.getTaskId())) {
|
||||
VariableQueryParamDto variableQueryParamDto = new VariableQueryParamDto();
|
||||
variableQueryParamDto.setTaskId(nodeFormatParamVo.getTaskId());
|
||||
R<Map<String, Object>> r = flowEngineService.queryTaskVariables(variableQueryParamDto);
|
||||
if (!r.isOk()) {
|
||||
ProcessNodeRecordAssignUser processNodeRecordAssignUser = processNodeRecordAssignUserService
|
||||
.lambdaQuery().eq(ProcessNodeRecordAssignUser::getTaskId, nodeFormatParamVo.getTaskId())
|
||||
.eq(ProcessNodeRecordAssignUser::getStatus, NodeStatusEnum.YJS.getCode()).last("limit 1")
|
||||
.orderByDesc(ProcessNodeRecordAssignUser::getEndTime).one();
|
||||
|
||||
String data = processNodeRecordAssignUser.getData();
|
||||
|
||||
Map<String, Object> variableMap = objectMapper.readValue(data,
|
||||
new TypeReference<Map<String, Object>>() {
|
||||
});
|
||||
variableMap.putAll(paramMap);
|
||||
paramMap.putAll(variableMap);
|
||||
}
|
||||
else {
|
||||
Map<String, Object> variableMap = r.getData();
|
||||
variableMap.putAll(paramMap);
|
||||
paramMap.putAll(variableMap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Set<String> completeNodeSet = new HashSet<>();
|
||||
|
||||
if (StrUtil.isNotBlank(processInstanceId)) {
|
||||
List<ProcessNodeRecord> processNodeRecordList = processNodeRecordService.lambdaQuery()
|
||||
.eq(ProcessNodeRecord::getProcessInstanceId, processInstanceId)
|
||||
.eq(ProcessNodeRecord::getStatus, NodeStatusEnum.YJS.getCode()).list();
|
||||
Set<String> collect = processNodeRecordList.stream().map(ProcessNodeRecord::getNodeId)
|
||||
.collect(Collectors.toSet());
|
||||
completeNodeSet.addAll(collect);
|
||||
}
|
||||
|
||||
Process oaForms = processService.getByFlowId(flowId);
|
||||
String process = oaForms.getProcess();
|
||||
Node nodeDto = objectMapper.readValue(process, new TypeReference<Node>() {
|
||||
});
|
||||
|
||||
List<NodeVo> processNodeShowDtos = NodeFormatUtil.formatProcessNodeShow(nodeDto, completeNodeSet,
|
||||
new HashSet<>(), processInstanceId, paramMap);
|
||||
|
||||
return R.ok(processNodeShowDtos);
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程详情
|
||||
* @param processInstanceId
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public R detail(String processInstanceId) {
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId).one();
|
||||
|
||||
Process oaForms = processService.getByFlowId(processInstanceRecord.getFlowId());
|
||||
if (oaForms == null) {
|
||||
return R.failed("流程不存在");
|
||||
}
|
||||
|
||||
// 发起人变量数据
|
||||
String formData = processInstanceRecord.getFormData();
|
||||
Map<String, Object> variableMap = objectMapper.readValue(formData, new TypeReference<Map<String, Object>>() {
|
||||
});
|
||||
// 发起人表单权限
|
||||
String process = oaForms.getProcess();
|
||||
|
||||
Node nodeDto = objectMapper.readValue(process, Node.class);
|
||||
Map<String, String> formPerms1 = nodeDto.getFormPerms();
|
||||
|
||||
List<FormItemVO> jsonObjectList = objectMapper.readValue(oaForms.getFormItems(),
|
||||
new TypeReference<List<FormItemVO>>() {
|
||||
});
|
||||
for (FormItemVO formItemVO : jsonObjectList) {
|
||||
String id = formItemVO.getId();
|
||||
String perm = formPerms1.get(id);
|
||||
|
||||
formItemVO.setPerm(StrUtil.isBlankIfStr(perm) ? ProcessInstanceConstant.FormPermClass.READ
|
||||
: (StrUtil.equals(perm, ProcessInstanceConstant.FormPermClass.HIDE) ? perm
|
||||
: ProcessInstanceConstant.FormPermClass.READ));
|
||||
|
||||
if (formItemVO.getType().equals(FormTypeEnum.LAYOUT.getType())) {
|
||||
// 明细
|
||||
List<Map<String, Object>> subParamList = MapUtil.get(variableMap, id,
|
||||
new cn.hutool.core.lang.TypeReference<List<Map<String, Object>>>() {
|
||||
});
|
||||
|
||||
Object value = formItemVO.getProps().getValue();
|
||||
|
||||
List<List<FormItemVO>> l = new ArrayList<>();
|
||||
for (Map<String, Object> map : subParamList) {
|
||||
List<FormItemVO> subItemList = Convert.toList(FormItemVO.class, value);
|
||||
for (FormItemVO itemVO : subItemList) {
|
||||
itemVO.getProps().setValue(map.get(itemVO.getId()));
|
||||
|
||||
String permSub = formPerms1.get(itemVO.getId());
|
||||
|
||||
itemVO.setPerm(StrUtil.isBlankIfStr(permSub) ? ProcessInstanceConstant.FormPermClass.READ
|
||||
: (StrUtil.equals(permSub, ProcessInstanceConstant.FormPermClass.HIDE) ? permSub
|
||||
: ProcessInstanceConstant.FormPermClass.READ));
|
||||
|
||||
}
|
||||
l.add(subItemList);
|
||||
}
|
||||
formItemVO.getProps().setValue(l);
|
||||
|
||||
}
|
||||
else {
|
||||
formItemVO.getProps().setValue(variableMap.get(id));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Dict set = Dict.create().set("processInstanceId", processInstanceId).set("process", oaForms.getProcess())
|
||||
|
||||
.set("formItems", jsonObjectList);
|
||||
|
||||
return R.ok(set);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.dto.Node;
|
||||
import com.pig4cloud.pigx.flow.task.dto.ProcessNodeDataDto;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessNodeData;
|
||||
import com.pig4cloud.pigx.flow.task.mapper.ProcessNodeDataMapper;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessNodeDataService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程节点数据 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-07
|
||||
*/
|
||||
@Service
|
||||
public class ProcessNodeDataServiceImpl extends ServiceImpl<ProcessNodeDataMapper, ProcessNodeData>
|
||||
implements IProcessNodeDataService {
|
||||
|
||||
/**
|
||||
* 保存流程节点数据。
|
||||
* @param processNodeDataDto 流程节点数据DTO
|
||||
* @return 保存结果
|
||||
*/
|
||||
@Override
|
||||
public R saveNodeData(ProcessNodeDataDto processNodeDataDto) {
|
||||
ProcessNodeData processNodeData = BeanUtil.copyProperties(processNodeDataDto, ProcessNodeData.class);
|
||||
this.save(processNodeData);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取节点数据。
|
||||
* @param flowId 流程ID
|
||||
* @param nodeId 节点ID
|
||||
* @return 节点数据
|
||||
*/
|
||||
@Override
|
||||
public R<Node> getNodeData(String flowId, String nodeId) {
|
||||
Optional<ProcessNodeData> processNodeDataOptional = this.lambdaQuery().eq(ProcessNodeData::getFlowId, flowId)
|
||||
.eq(ProcessNodeData::getNodeId, nodeId).oneOpt();
|
||||
|
||||
Node node = processNodeDataOptional
|
||||
.map(processNodeData -> JSONUtil.toBean(processNodeData.getData(), Node.class)).orElse(null);
|
||||
|
||||
return R.ok(node);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.constant.NodeStatusEnum;
|
||||
import com.pig4cloud.pigx.flow.task.dto.ProcessNodeRecordAssignUserParamDto;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessNodeRecordAssignUser;
|
||||
import com.pig4cloud.pigx.flow.task.mapper.ProcessNodeRecordAssignUserMapper;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessNodeRecordAssignUserService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程节点记录-执行人 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author cxygzl
|
||||
* @since 2023-05-10
|
||||
*/
|
||||
@Service
|
||||
public class ProcessNodeRecordAssignUserServiceImpl
|
||||
extends ServiceImpl<ProcessNodeRecordAssignUserMapper, ProcessNodeRecordAssignUser>
|
||||
implements IProcessNodeRecordAssignUserService {
|
||||
|
||||
/**
|
||||
* 设置执行人
|
||||
* @param processNodeRecordAssignUserParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R addAssignUser(ProcessNodeRecordAssignUserParamDto processNodeRecordAssignUserParamDto) {
|
||||
if (StrUtil.isNotBlank(processNodeRecordAssignUserParamDto.getApproveDesc())) {
|
||||
ProcessNodeRecordAssignUser processNodeRecordAssignUser = this.lambdaQuery()
|
||||
.eq(ProcessNodeRecordAssignUser::getTaskId, processNodeRecordAssignUserParamDto.getTaskId())
|
||||
.orderByDesc(ProcessNodeRecordAssignUser::getId).last("limit 1").one();
|
||||
if (processNodeRecordAssignUser != null) {
|
||||
processNodeRecordAssignUser.setApproveDesc(processNodeRecordAssignUserParamDto.getApproveDesc());
|
||||
processNodeRecordAssignUser.setTaskType(processNodeRecordAssignUserParamDto.getTaskType());
|
||||
processNodeRecordAssignUser.setStatus(NodeStatusEnum.YJS.getCode());
|
||||
processNodeRecordAssignUser.setEndTime(LocalDateTime.now());
|
||||
this.updateById(processNodeRecordAssignUser);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ProcessNodeRecordAssignUser processNodeRecordAssignUser = BeanUtil
|
||||
.copyProperties(processNodeRecordAssignUserParamDto, ProcessNodeRecordAssignUser.class);
|
||||
processNodeRecordAssignUser.setStartTime(LocalDateTime.now());
|
||||
processNodeRecordAssignUser.setStatus(NodeStatusEnum.JXZ.getCode());
|
||||
processNodeRecordAssignUser.setApproveDesc("");
|
||||
processNodeRecordAssignUser.setTaskType("");
|
||||
this.save(processNodeRecordAssignUser);
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务完成通知
|
||||
* @param processNodeRecordAssignUserParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R completeTaskEvent(ProcessNodeRecordAssignUserParamDto processNodeRecordAssignUserParamDto) {
|
||||
ProcessNodeRecordAssignUser processNodeRecordAssignUser = this.lambdaQuery()
|
||||
.eq(ProcessNodeRecordAssignUser::getTaskId, processNodeRecordAssignUserParamDto.getTaskId())
|
||||
.eq(ProcessNodeRecordAssignUser::getUserId, processNodeRecordAssignUserParamDto.getUserId())
|
||||
.eq(ProcessNodeRecordAssignUser::getProcessInstanceId,
|
||||
processNodeRecordAssignUserParamDto.getProcessInstanceId())
|
||||
.eq(ProcessNodeRecordAssignUser::getStatus, NodeStatusEnum.JXZ.getCode())
|
||||
.orderByDesc(ProcessNodeRecordAssignUser::getId).last("limit 1").one();
|
||||
processNodeRecordAssignUser.setStatus(NodeStatusEnum.YJS.getCode());
|
||||
processNodeRecordAssignUser.setApproveDesc(processNodeRecordAssignUserParamDto.getApproveDesc());
|
||||
processNodeRecordAssignUser.setEndTime(LocalDateTime.now());
|
||||
processNodeRecordAssignUser.setData(processNodeRecordAssignUserParamDto.getData());
|
||||
processNodeRecordAssignUser.setLocalData(processNodeRecordAssignUserParamDto.getLocalData());
|
||||
processNodeRecordAssignUser.setTaskType("COMPLETE");
|
||||
this.updateById(processNodeRecordAssignUser);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.constant.NodeStatusEnum;
|
||||
import com.pig4cloud.pigx.flow.task.dto.ProcessNodeRecordParamDto;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessNodeRecord;
|
||||
import com.pig4cloud.pigx.flow.task.mapper.ProcessNodeRecordMapper;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessNodeRecordService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程节点记录 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author cxygzl
|
||||
* @since 2023-05-10
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ProcessNodeRecordServiceImpl extends ServiceImpl<ProcessNodeRecordMapper, ProcessNodeRecord>
|
||||
implements IProcessNodeRecordService {
|
||||
|
||||
/**
|
||||
* 节点开始
|
||||
* @param processNodeRecordParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R start(ProcessNodeRecordParamDto processNodeRecordParamDto) {
|
||||
|
||||
ProcessNodeRecord processNodeRecord = BeanUtil.copyProperties(processNodeRecordParamDto,
|
||||
ProcessNodeRecord.class);
|
||||
processNodeRecord.setStartTime(new Date());
|
||||
processNodeRecord.setStatus(NodeStatusEnum.JXZ.getCode());
|
||||
|
||||
this.save(processNodeRecord);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 节点结束
|
||||
* @param processNodeRecordParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R complete(ProcessNodeRecordParamDto processNodeRecordParamDto) {
|
||||
|
||||
log.info("节点结束---{}", processNodeRecordParamDto);
|
||||
|
||||
// TODO 完成节点和完成任务要区分下
|
||||
this.lambdaUpdate().set(ProcessNodeRecord::getStatus, NodeStatusEnum.YJS.getCode())
|
||||
.set(ProcessNodeRecord::getEndTime, new Date())
|
||||
.eq(ProcessNodeRecord::getProcessInstanceId, processNodeRecordParamDto.getProcessInstanceId())
|
||||
.eq(ProcessNodeRecord::getNodeId, processNodeRecordParamDto.getNodeId())
|
||||
.update(new ProcessNodeRecord());
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
|
||||
import com.pig4cloud.pigx.common.sequence.sequence.Sequence;
|
||||
import com.pig4cloud.pigx.flow.task.api.feign.RemoteFlowEngineService;
|
||||
import com.pig4cloud.pigx.flow.task.constant.FormTypeEnum;
|
||||
import com.pig4cloud.pigx.flow.task.constant.ProcessInstanceConstant;
|
||||
import com.pig4cloud.pigx.flow.task.dto.Node;
|
||||
import com.pig4cloud.pigx.flow.task.dto.NodeUser;
|
||||
import com.pig4cloud.pigx.flow.task.entity.Process;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessStarter;
|
||||
import com.pig4cloud.pigx.flow.task.mapper.ProcessMapper;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessService;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessStarterService;
|
||||
import com.pig4cloud.pigx.flow.task.utils.NodeUtil;
|
||||
import com.pig4cloud.pigx.flow.task.vo.FormItemVO;
|
||||
import com.pig4cloud.pigx.flow.task.vo.ProcessVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author cxygzl
|
||||
* @since 2023-05-25
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> implements IProcessService {
|
||||
|
||||
private final IProcessStarterService processStarterService;
|
||||
|
||||
private final RemoteFlowEngineService flowEngineService;
|
||||
|
||||
private final Sequence flowSequence;
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
/**
|
||||
* 获取详细数据
|
||||
* @param flowId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R<ProcessVO> getDetail(String flowId) {
|
||||
// 获取流程详情
|
||||
ProcessVO processVO = this.getProcessVO(flowId);
|
||||
return R.ok(processVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据流程ID获取流程详情
|
||||
* @param flowId 流程ID
|
||||
* @return 流程详情
|
||||
*/
|
||||
@SneakyThrows
|
||||
private ProcessVO getProcessVO(String flowId) {
|
||||
|
||||
Process oaForms = getByFlowId(flowId);
|
||||
String process = oaForms.getProcess();
|
||||
String formItems = oaForms.getFormItems();
|
||||
Node startNode = objectMapper.readValue(process, new TypeReference<Node>() {
|
||||
});
|
||||
|
||||
Map<String, String> formPerms = startNode.getFormPerms();
|
||||
|
||||
List<FormItemVO> formItemVOList = objectMapper.readValue(formItems, new TypeReference<List<FormItemVO>>() {
|
||||
});
|
||||
for (FormItemVO formItemVO : formItemVOList) {
|
||||
String perm = MapUtil.getStr(formPerms, formItemVO.getId(), ProcessInstanceConstant.FormPermClass.EDIT);
|
||||
formItemVO.setPerm(perm);
|
||||
|
||||
// 发号器赋值
|
||||
if (StrUtil.equals(formItemVO.getType(), FormTypeEnum.SEQUENCE.getType())) {
|
||||
FormItemVO.Props props = formItemVO.getProps();
|
||||
String prefix = props.getPrefix();
|
||||
String nextNo = flowSequence.nextNo();
|
||||
formItemVO.setPlaceholder(StrUtil.isNotBlank(prefix) ? prefix + nextNo : nextNo);
|
||||
props.setValue(StrUtil.isNotBlank(prefix) ? prefix + nextNo : nextNo);
|
||||
formItemVO.setProps(props);
|
||||
}
|
||||
|
||||
if (StrUtil.equals(formItemVO.getType(), FormTypeEnum.LAYOUT.getType())) {
|
||||
// 明细
|
||||
Object value = formItemVO.getProps().getValue();
|
||||
List<FormItemVO> subList = Convert.toList(FormItemVO.class, value);
|
||||
for (FormItemVO itemVO : subList) {
|
||||
String perm1 = MapUtil.getStr(formPerms, itemVO.getId(),
|
||||
ProcessInstanceConstant.FormPermClass.EDIT);
|
||||
itemVO.setPerm(perm1);
|
||||
}
|
||||
|
||||
formItemVO.getProps().setValue(subList);
|
||||
formItemVO.getProps();
|
||||
}
|
||||
|
||||
}
|
||||
oaForms.setFormItems(objectMapper.writeValueAsString(formItemVOList));
|
||||
|
||||
List<String> selectUserNodeId = NodeUtil.selectUserNodeId(startNode);
|
||||
|
||||
ProcessVO processVO = BeanUtil.copyProperties(oaForms, ProcessVO.class);
|
||||
processVO.setSelectUserNodeId(selectUserNodeId);
|
||||
|
||||
return processVO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据流程ID获取流程
|
||||
* @param flowId 流程ID
|
||||
* @return 流程
|
||||
*/
|
||||
@Override
|
||||
public Process getByFlowId(String flowId) {
|
||||
return this.lambdaQuery().eq(Process::getFlowId, flowId).one();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新流程
|
||||
* @param process 流程
|
||||
*/
|
||||
@Override
|
||||
public void updateByFlowId(Process process) {
|
||||
this.lambdaUpdate().eq(Process::getFlowId, process.getFlowId()).update(process);
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏流程
|
||||
* @param flowId 流程ID
|
||||
*/
|
||||
@Override
|
||||
public void hide(String flowId) {
|
||||
this.lambdaUpdate().set(Process::getHidden, true).eq(Process::getFlowId, flowId).update(new Process());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建流程
|
||||
* @param process 流程
|
||||
* @return 操作结果
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public R create(Process process) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("process", process);
|
||||
map.put("userId", SecurityUtils.getUser().getId());
|
||||
R<String> r = flowEngineService.createFlow(map);
|
||||
if (!r.isOk()) {
|
||||
return R.failed(r.getMsg());
|
||||
}
|
||||
String flowId = r.getData();
|
||||
NodeUser nodeUser = objectMapper.readValue(process.getAdminList(), new TypeReference<List<NodeUser>>() {
|
||||
}).get(0);
|
||||
|
||||
// 更新流程
|
||||
if (StrUtil.isNotBlank(process.getFlowId())) {
|
||||
|
||||
Process oldProcess = this.getByFlowId(process.getFlowId());
|
||||
this.hide(process.getFlowId());
|
||||
// 修改所有的管理员
|
||||
this.lambdaUpdate().set(Process::getAdminId, nodeUser.getId())
|
||||
.eq(Process::getUniqueId, oldProcess.getUniqueId()).update(new Process());
|
||||
|
||||
}
|
||||
|
||||
Node startNode = objectMapper.readValue(process.getProcess(), Node.class);
|
||||
|
||||
List<NodeUser> nodeUserList = startNode.getNodeUserList();
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (CollUtil.isNotEmpty(nodeUserList)) {
|
||||
int index = 0;
|
||||
|
||||
for (NodeUser user : nodeUserList) {
|
||||
if (index > 0) {
|
||||
stringBuilder.append(",");
|
||||
}
|
||||
stringBuilder.append(user.getName());
|
||||
index++;
|
||||
if (index > 5) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Process p = new Process();
|
||||
p.setFlowId(flowId);
|
||||
p.setName(process.getName());
|
||||
p.setLogo(process.getLogo());
|
||||
p.setSettings(process.getSettings());
|
||||
p.setGroupId(process.getGroupId());
|
||||
p.setFormItems(process.getFormItems());
|
||||
p.setProcess(process.getProcess());
|
||||
p.setRemark(process.getRemark());
|
||||
p.setSort(0);
|
||||
p.setHidden(false);
|
||||
p.setStop(false);
|
||||
p.setAdminId(nodeUser.getId());
|
||||
p.setUniqueId(IdUtil.fastSimpleUUID());
|
||||
p.setAdminList(process.getAdminList());
|
||||
p.setRangeShow(stringBuilder.toString());
|
||||
|
||||
this.save(p);
|
||||
|
||||
// 保存范围
|
||||
for (NodeUser nodeUserDto : nodeUserList) {
|
||||
ProcessStarter processStarter = new ProcessStarter();
|
||||
|
||||
processStarter.setProcessId(p.getId());
|
||||
processStarter.setTypeId(nodeUserDto.getId());
|
||||
processStarter.setType(nodeUserDto.getType());
|
||||
processStarterService.save(processStarter);
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑表单
|
||||
* @param flowId 流程ID
|
||||
* @param type 类型 stop using delete
|
||||
* @param groupId 分组ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
public R update(String flowId, String type, Long groupId) {
|
||||
Process process = new Process();
|
||||
process.setFlowId(flowId);
|
||||
process.setStop("stop".equals(type));
|
||||
process.setHidden("delete".equals(type));
|
||||
process.setGroupId(groupId);
|
||||
this.updateByFlowId(process);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessStarter;
|
||||
import com.pig4cloud.pigx.flow.task.mapper.ProcessStarterMapper;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessStarterService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 流程发起人 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author Vincent
|
||||
* @since 2023-05-30
|
||||
*/
|
||||
@Service
|
||||
public class ProcessStarterServiceImpl extends ServiceImpl<ProcessStarterMapper, ProcessStarter>
|
||||
implements IProcessStarterService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysDept;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysUser;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteDeptService;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteUserService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.flow.task.constant.NodeStatusEnum;
|
||||
import com.pig4cloud.pigx.flow.task.dto.*;
|
||||
import com.pig4cloud.pigx.flow.task.entity.Process;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessCopy;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessGroup;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessInstanceRecord;
|
||||
import com.pig4cloud.pigx.flow.task.service.*;
|
||||
import com.pig4cloud.pigx.flow.task.utils.DataUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class RemoteServiceImpl implements IRemoteService {
|
||||
|
||||
private final IProcessInstanceRecordService processInstanceRecordService;
|
||||
|
||||
private final IProcessNodeRecordService processNodeRecordService;
|
||||
|
||||
private final IProcessNodeRecordAssignUserService processNodeRecordAssignUserService;
|
||||
|
||||
private final IProcessInstanceService processInstanceService;
|
||||
|
||||
private final IProcessCopyService processCopyService;
|
||||
|
||||
private final IProcessService processService;
|
||||
|
||||
private final IProcessGroupService processGroupService;
|
||||
|
||||
private final RemoteUserService userService;
|
||||
|
||||
private final RemoteDeptService deptService;
|
||||
|
||||
/**
|
||||
* 根据角色id集合查询用户id集合
|
||||
* @param roleIdList
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R<List<Long>> queryUserIdListByRoleIdList(List<Long> roleIdList) {
|
||||
return userService.getUserIdListByRoleIdList(roleIdList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存抄送
|
||||
* @param copyDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R saveCC(ProcessCopyDto copyDto) {
|
||||
|
||||
String processInstanceId = copyDto.getProcessInstanceId();
|
||||
|
||||
// 如果抄送是第一个节点 会出现查询不到的情况
|
||||
ThreadUtil.execute(() -> {
|
||||
try {
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId).one();
|
||||
|
||||
int index = 10;
|
||||
while (index > 0 && processInstanceRecord == null) {
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
processInstanceRecord = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId).one();
|
||||
index--;
|
||||
}
|
||||
|
||||
ProcessCopy processCopy = BeanUtil.copyProperties(copyDto, ProcessCopy.class);
|
||||
processCopy.setGroupId(processInstanceRecord.getGroupId());
|
||||
processCopy.setGroupName(processInstanceRecord.getGroupName());
|
||||
processCopy.setProcessName(processInstanceRecord.getName());
|
||||
processCopy.setStartTime(processInstanceRecord.getCreateTime());
|
||||
|
||||
processCopyService.save(processCopy);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Error:", e);
|
||||
}
|
||||
});
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是所有的父级
|
||||
* @param checkParentDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R<Boolean> checkIsAllParent(CheckParentDto checkParentDto) {
|
||||
|
||||
Long parentId = checkParentDto.getParentId();
|
||||
List<Long> deptIdList = checkParentDto.getDeptIdList();
|
||||
// 查询子级包括自己
|
||||
List<SysDept> allDept = deptService.getAllDept().getData();
|
||||
List<SysDept> childrenDeptList = DataUtil.selectChildrenByDept(parentId, allDept);
|
||||
|
||||
List<Long> childrenDeptIdList = childrenDeptList.stream().map(SysDept::getDeptId).collect(Collectors.toList());
|
||||
childrenDeptIdList.remove(parentId);
|
||||
|
||||
List<Long> remainIdList = CollUtil.removeAny(deptIdList, ArrayUtil.toArray(childrenDeptIdList, Long.class));
|
||||
|
||||
return R.ok(remainIdList.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门id集合查询用户id集合
|
||||
* @param depIdList
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R<List<Long>> queryUserIdListByDepIdList(List<Long> depIdList) {
|
||||
List<Long> list = userService.getUserIdListByDeptIdList(depIdList).getData().stream().map(SysUser::getUserId)
|
||||
.collect(Collectors.toList());
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是所有的子级
|
||||
* @param checkChildDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R<Boolean> checkIsAllChild(CheckChildDto checkChildDto) {
|
||||
Long childId = checkChildDto.getChildId();
|
||||
List<Long> deptIdList = checkChildDto.getDeptIdList();
|
||||
// 查询父级包括自己
|
||||
List<SysDept> allDept = deptService.getAllDept().getData();
|
||||
List<SysDept> parentDeptList = DataUtil.selectParentByDept(childId, allDept);
|
||||
|
||||
List<Long> parentDeptIdList = parentDeptList.stream().map(SysDept::getDeptId).collect(Collectors.toList());
|
||||
parentDeptIdList.remove(childId);
|
||||
|
||||
List<Long> remainIdList = CollUtil.removeAny(deptIdList, ArrayUtil.toArray(parentDeptIdList, Long.class));
|
||||
|
||||
return R.ok(remainIdList.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的信息-包括扩展字段
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R<Map<String, Object>> queryUserAllInfo(long userId) {
|
||||
SysUser sysUser = userService.getUserById(userId).getData();
|
||||
return R.ok(BeanUtil.beanToMap(sysUser));
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始节点事件
|
||||
* @param recordParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R startNodeEvent(ProcessNodeRecordParamDto recordParamDto) {
|
||||
return processNodeRecordService.start(recordParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程创建了
|
||||
* @param processInstanceRecordParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R createProcessEvent(ProcessInstanceRecordParamDto processInstanceRecordParamDto) {
|
||||
ProcessInstanceRecord entity = BeanUtil.copyProperties(processInstanceRecordParamDto,
|
||||
ProcessInstanceRecord.class);
|
||||
|
||||
Process oaForms = processService.getByFlowId(processInstanceRecordParamDto.getFlowId());
|
||||
|
||||
ProcessGroup oaFormGroups = processGroupService.getById(oaForms.getGroupId());
|
||||
|
||||
entity.setName(oaForms.getName());
|
||||
entity.setLogo(oaForms.getLogo());
|
||||
entity.setUserId(processInstanceRecordParamDto.getUserId());
|
||||
entity.setFlowId(processInstanceRecordParamDto.getFlowId());
|
||||
entity.setProcessInstanceId(processInstanceRecordParamDto.getProcessInstanceId());
|
||||
entity.setGroupId(oaFormGroups.getId());
|
||||
entity.setGroupName(oaFormGroups.getGroupName());
|
||||
entity.setStatus(NodeStatusEnum.JXZ.getCode());
|
||||
|
||||
processInstanceRecordService.save(entity);
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成节点事件
|
||||
* @param recordParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R endNodeEvent(ProcessNodeRecordParamDto recordParamDto) {
|
||||
return processNodeRecordService.complete(recordParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始设置执行人
|
||||
* @param processNodeRecordAssignUserParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R startAssignUser(ProcessNodeRecordAssignUserParamDto processNodeRecordAssignUserParamDto) {
|
||||
return processNodeRecordAssignUserService.addAssignUser(processNodeRecordAssignUserParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务结束事件
|
||||
* @param processNodeRecordAssignUserParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R taskEndEvent(ProcessNodeRecordAssignUserParamDto processNodeRecordAssignUserParamDto) {
|
||||
return processNodeRecordAssignUserService.completeTaskEvent(processNodeRecordAssignUserParamDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例结束
|
||||
* @param processInstanceId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R endProcess(String processInstanceId) {
|
||||
return processInstanceService.end(processInstanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询流程管理员
|
||||
* @param flowId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R<Long> queryProcessAdmin(String flowId) {
|
||||
Process process = processService.getByFlowId(flowId);
|
||||
return R.ok(process.getAdminId());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
package com.pig4cloud.pigx.flow.task.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
|
||||
import com.pig4cloud.pigx.flow.task.api.feign.RemoteFlowEngineService;
|
||||
import com.pig4cloud.pigx.flow.task.constant.FormTypeEnum;
|
||||
import com.pig4cloud.pigx.flow.task.constant.NodeStatusEnum;
|
||||
import com.pig4cloud.pigx.flow.task.constant.ProcessInstanceConstant;
|
||||
import com.pig4cloud.pigx.flow.task.dto.IndexPageStatistics;
|
||||
import com.pig4cloud.pigx.flow.task.dto.Node;
|
||||
import com.pig4cloud.pigx.flow.task.dto.TaskParamDto;
|
||||
import com.pig4cloud.pigx.flow.task.dto.TaskResultDto;
|
||||
import com.pig4cloud.pigx.flow.task.entity.Process;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessCopy;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessInstanceRecord;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessNodeRecordAssignUser;
|
||||
import com.pig4cloud.pigx.flow.task.service.*;
|
||||
import com.pig4cloud.pigx.flow.task.vo.FormItemVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class TaskServiceImpl implements ITaskService {
|
||||
|
||||
private final RemoteFlowEngineService flowEngineService;
|
||||
|
||||
private final IProcessService processService;
|
||||
|
||||
private final IProcessCopyService processCopyService;
|
||||
|
||||
private final IProcessNodeDataService nodeDataService;
|
||||
|
||||
private final IProcessNodeRecordAssignUserService processNodeRecordAssignUserService;
|
||||
|
||||
private final IProcessInstanceRecordService processInstanceRecordService;
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
/**
|
||||
* 查询首页数据看板
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R queryTaskData() {
|
||||
R<IndexPageStatistics> indexPageStatisticsR = flowEngineService
|
||||
.querySimpleData(SecurityUtils.getUser().getId());
|
||||
|
||||
// 获取抄送任务
|
||||
Long copyCount = processCopyService.lambdaQuery().eq(ProcessCopy::getUserId, SecurityUtils.getUser().getId())
|
||||
.count();
|
||||
indexPageStatisticsR.getData().setCopyNum(copyCount);
|
||||
return indexPageStatisticsR;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询任务
|
||||
* @param taskId
|
||||
* @param view
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public R queryTask(String taskId, boolean view) {
|
||||
|
||||
long userId = SecurityUtils.getUser().getId();
|
||||
|
||||
R<TaskResultDto> r = flowEngineService.queryTask(taskId, userId);
|
||||
|
||||
if (!r.isOk()) {
|
||||
return R.failed(r.getMsg());
|
||||
}
|
||||
|
||||
TaskResultDto taskResultDto = r.getData();
|
||||
|
||||
// 变量
|
||||
Map<String, Object> paramMap = taskResultDto.getVariableAll();
|
||||
// 是否是当前活动任务
|
||||
Boolean currentTask = taskResultDto.getCurrentTask();
|
||||
if (!currentTask) {
|
||||
ProcessNodeRecordAssignUser processNodeRecordAssignUser = processNodeRecordAssignUserService.lambdaQuery()
|
||||
.eq(ProcessNodeRecordAssignUser::getTaskId, taskId)
|
||||
.eq(ProcessNodeRecordAssignUser::getUserId, userId)
|
||||
.eq(ProcessNodeRecordAssignUser::getStatus, NodeStatusEnum.YJS.getCode()).last("limit 1")
|
||||
.orderByDesc(ProcessNodeRecordAssignUser::getEndTime).one();
|
||||
|
||||
if (processNodeRecordAssignUser != null) {
|
||||
String data = processNodeRecordAssignUser.getData();
|
||||
if (StrUtil.isNotBlank(data)) {
|
||||
Map<String, Object> collect = objectMapper.readValue(data,
|
||||
new TypeReference<Map<String, Object>>() {
|
||||
});
|
||||
paramMap.putAll(collect);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 当前节点数据
|
||||
Node node = nodeDataService.getNodeData(taskResultDto.getFlowId(), taskResultDto.getNodeId()).getData();
|
||||
Map<String, String> formPerms = node.getFormPerms();
|
||||
|
||||
Process oaForms = processService.getByFlowId(taskResultDto.getFlowId());
|
||||
if (oaForms == null) {
|
||||
return R.failed("流程不存在");
|
||||
}
|
||||
|
||||
List<FormItemVO> formItemVOList = JSONUtil.toList(oaForms.getFormItems(), FormItemVO.class);
|
||||
for (FormItemVO formItemVO : formItemVOList) {
|
||||
|
||||
String id = formItemVO.getId();
|
||||
|
||||
String perm = formPerms.get(id);
|
||||
|
||||
if (StrUtil.isNotBlank(perm)) {
|
||||
|
||||
formItemVO.setPerm(view ? (ProcessInstanceConstant.FormPermClass.EDIT.equals(perm)
|
||||
? ProcessInstanceConstant.FormPermClass.READ : perm) : perm);
|
||||
|
||||
}
|
||||
else {
|
||||
formItemVO.setPerm(ProcessInstanceConstant.FormPermClass.HIDE);
|
||||
}
|
||||
|
||||
if (formItemVO.getType().equals(FormTypeEnum.LAYOUT.getType())) {
|
||||
// 明细
|
||||
|
||||
List<Map<String, Object>> subParamList = MapUtil.get(paramMap, id,
|
||||
new cn.hutool.core.lang.TypeReference<List<Map<String, Object>>>() {
|
||||
});
|
||||
|
||||
Object value = formItemVO.getProps().getValue();
|
||||
|
||||
List<List<FormItemVO>> l = new ArrayList<>();
|
||||
for (Map<String, Object> map : subParamList) {
|
||||
List<FormItemVO> subItemList = Convert.toList(FormItemVO.class, value);
|
||||
for (FormItemVO itemVO : subItemList) {
|
||||
itemVO.getProps().setValue(map.get(itemVO.getId()));
|
||||
|
||||
String permSub = formPerms.get(itemVO.getId());
|
||||
if (StrUtil.isNotBlank(permSub)) {
|
||||
itemVO.setPerm(view ? (ProcessInstanceConstant.FormPermClass.EDIT.equals(permSub)
|
||||
? ProcessInstanceConstant.FormPermClass.READ : permSub) : permSub);
|
||||
|
||||
}
|
||||
else {
|
||||
itemVO.setPerm(ProcessInstanceConstant.FormPermClass.HIDE);
|
||||
}
|
||||
|
||||
}
|
||||
l.add(subItemList);
|
||||
}
|
||||
formItemVO.getProps().setValue(l);
|
||||
{
|
||||
List<FormItemVO> subItemList = Convert.toList(FormItemVO.class, value);
|
||||
for (FormItemVO itemVO : subItemList) {
|
||||
|
||||
String permSub = formPerms.get(itemVO.getId());
|
||||
if (StrUtil.isNotBlank(permSub)) {
|
||||
|
||||
itemVO.setPerm(permSub);
|
||||
|
||||
}
|
||||
else {
|
||||
itemVO.setPerm(ProcessInstanceConstant.FormPermClass.HIDE);
|
||||
}
|
||||
|
||||
}
|
||||
formItemVO.getProps().setOriForm(subItemList);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
formItemVO.getProps().setValue(paramMap.get(id));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Dict set = Dict.create().set("processInstanceId", taskResultDto.getProcessInstanceId())
|
||||
.set("node", taskResultDto.getTaskNode()).set("process", oaForms.getProcess())
|
||||
.set("delegateAgain", taskResultDto.getDelegate())
|
||||
.set("delegationTask", StrUtil.equals(taskResultDto.getDelegationState(), "PENDING"))
|
||||
|
||||
.set("formItems", formItemVOList);
|
||||
|
||||
return R.ok(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成任务
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R completeTask(TaskParamDto taskParamDto) {
|
||||
long userId = SecurityUtils.getUser().getId();
|
||||
taskParamDto.setUserId(String.valueOf(userId));
|
||||
|
||||
R r = flowEngineService.completeTask(taskParamDto);
|
||||
|
||||
if (!r.isOk()) {
|
||||
return R.failed(r.getMsg());
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 前加签
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
@Transactional
|
||||
@Override
|
||||
public R delegateTask(TaskParamDto taskParamDto) {
|
||||
|
||||
taskParamDto.setUserId(SecurityUtils.getUser().getId().toString());
|
||||
|
||||
R r = flowEngineService.delegateTask(taskParamDto);
|
||||
if (!r.isOk()) {
|
||||
return R.failed(r.getMsg());
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 加签完成任务
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R resolveTask(TaskParamDto taskParamDto) {
|
||||
R r = flowEngineService.resolveTask(taskParamDto);
|
||||
if (!r.isOk()) {
|
||||
return R.failed(r.getMsg());
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置执行人
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R setAssignee(TaskParamDto taskParamDto) {
|
||||
taskParamDto.setUserId(SecurityUtils.getUser().getId().toString());
|
||||
R r = flowEngineService.setAssignee(taskParamDto);
|
||||
if (!r.isOk()) {
|
||||
return R.failed(r.getMsg());
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束流程
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R stopProcessInstance(TaskParamDto taskParamDto) {
|
||||
|
||||
String processInstanceId = taskParamDto.getProcessInstanceId();
|
||||
|
||||
List<String> allStopProcessInstanceIdList = getAllStopProcessInstanceIdList(processInstanceId);
|
||||
CollUtil.reverse(allStopProcessInstanceIdList);
|
||||
allStopProcessInstanceIdList.add(processInstanceId);
|
||||
|
||||
taskParamDto.setProcessInstanceIdList(allStopProcessInstanceIdList);
|
||||
taskParamDto.setUserId(SecurityUtils.getUser().getId().toString());
|
||||
R r = flowEngineService.stopProcessInstance(taskParamDto);
|
||||
|
||||
if (!r.isOk()) {
|
||||
return R.failed(r.getMsg());
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 退回
|
||||
* @param taskParamDto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R back(TaskParamDto taskParamDto) {
|
||||
taskParamDto.setUserId(SecurityUtils.getUser().getId().toString());
|
||||
R r = flowEngineService.back(taskParamDto);
|
||||
if (!r.isOk()) {
|
||||
return R.failed(r.getMsg());
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
private List<String> getAllStopProcessInstanceIdList(String processInstanceId) {
|
||||
List<ProcessInstanceRecord> list = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getParentProcessInstanceId, processInstanceId).list();
|
||||
|
||||
List<String> collect = list.stream().map(w -> w.getProcessInstanceId()).collect(Collectors.toList());
|
||||
|
||||
for (ProcessInstanceRecord processInstanceRecord : list) {
|
||||
List<String> allStopProcessInstanceIdList = getAllStopProcessInstanceIdList(
|
||||
processInstanceRecord.getProcessInstanceId());
|
||||
|
||||
collect.addAll(allStopProcessInstanceIdList);
|
||||
|
||||
}
|
||||
return collect;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.pig4cloud.pigx.flow.task.utils;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysDept;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysMenu;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DataUtil {
|
||||
|
||||
/**
|
||||
* 根据当前部门id,向上查找所有的部门
|
||||
* @param deptId
|
||||
* @param allDeptList
|
||||
* @return 返回包括自己部门在内的所有父级部门
|
||||
*/
|
||||
public static List<SysDept> selectParentByDept(long deptId, List<SysDept> allDeptList) {
|
||||
List<SysDept> list = new ArrayList<>();
|
||||
SysDept dept = allDeptList.stream().filter(w -> w.getDeptId() == deptId).findAny().orElse(null);
|
||||
if (dept == null || dept.getParentId() == null) {
|
||||
return list;
|
||||
}
|
||||
Long parentId = dept.getParentId();
|
||||
List<SysDept> depts = selectParentByDept(parentId, allDeptList);
|
||||
list.add(dept);
|
||||
list.addAll(depts);
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前部门id,向下查找所有的部门
|
||||
* @param deptId
|
||||
* @param allDeptList
|
||||
* @return 返回包括自己部门在内的所有子级部门
|
||||
*/
|
||||
public static List<SysDept> selectChildrenByDept(long deptId, List<SysDept> allDeptList) {
|
||||
List<SysDept> list = new ArrayList<>();
|
||||
list.add(allDeptList.stream().filter(w -> w.getDeptId() == deptId).findFirst().get());
|
||||
|
||||
List<SysDept> collect = allDeptList.stream().filter(w -> w.getParentId() == deptId)
|
||||
.collect(Collectors.toList());
|
||||
if (CollUtil.isEmpty(collect)) {
|
||||
return list;
|
||||
}
|
||||
for (SysDept dept : collect) {
|
||||
List<SysDept> depts = selectChildrenByDept(dept.getDeptId(), allDeptList);
|
||||
list.addAll(depts);
|
||||
}
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前菜单id,向下查找所有的菜单
|
||||
* @param menuId
|
||||
* @param allMenuList
|
||||
* @return 返回包括自己在内的所有子级菜单
|
||||
*/
|
||||
public static List<SysMenu> selectChildrenByMenu(long menuId, List<SysMenu> allMenuList) {
|
||||
List<SysMenu> list = new ArrayList<>();
|
||||
list.add(allMenuList.stream().filter(w -> w.getMenuId() == menuId).findFirst().get());
|
||||
|
||||
List<SysMenu> collect = allMenuList.stream().filter(w -> w.getParentId() == menuId)
|
||||
.collect(Collectors.toList());
|
||||
if (CollUtil.isEmpty(collect)) {
|
||||
return list;
|
||||
}
|
||||
for (SysMenu dept : collect) {
|
||||
List<SysMenu> depts = selectChildrenByMenu(dept.getMenuId(), allMenuList);
|
||||
list.addAll(depts);
|
||||
}
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
package com.pig4cloud.pigx.flow.task.utils;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysUser;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteUserService;
|
||||
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
|
||||
import com.pig4cloud.pigx.flow.task.constant.NodeStatusEnum;
|
||||
import com.pig4cloud.pigx.flow.task.constant.NodeTypeEnum;
|
||||
import com.pig4cloud.pigx.flow.task.constant.NodeUserTypeEnum;
|
||||
import com.pig4cloud.pigx.flow.task.constant.ProcessInstanceConstant;
|
||||
import com.pig4cloud.pigx.flow.task.dto.Node;
|
||||
import com.pig4cloud.pigx.flow.task.dto.NodeUser;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessInstanceRecord;
|
||||
import com.pig4cloud.pigx.flow.task.entity.ProcessNodeRecordAssignUser;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessInstanceRecordService;
|
||||
import com.pig4cloud.pigx.flow.task.service.IProcessNodeRecordAssignUserService;
|
||||
import com.pig4cloud.pigx.flow.task.service.IRemoteService;
|
||||
import com.pig4cloud.pigx.flow.task.vo.NodeVo;
|
||||
import com.pig4cloud.pigx.flow.task.vo.UserVo;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 节点格式化显示工具
|
||||
*/
|
||||
public class NodeFormatUtil {
|
||||
|
||||
/**
|
||||
* 格式化流程节点显示
|
||||
* @param node
|
||||
* @param completeNodeSet
|
||||
* @param continueNodeSet
|
||||
* @param processInstanceId
|
||||
* @param paramMap
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static List<NodeVo> formatProcessNodeShow(Node node, Set<String> completeNodeSet,
|
||||
Set<String> continueNodeSet, String processInstanceId, Map<String, Object> paramMap) {
|
||||
List<NodeVo> list = new ArrayList<>();
|
||||
|
||||
if (!NodeUtil.isNode(node)) {
|
||||
return list;
|
||||
}
|
||||
|
||||
String name = node.getName();
|
||||
Integer type = node.getType();
|
||||
|
||||
// SELF_SELECT
|
||||
|
||||
NodeVo nodeVo = new NodeVo();
|
||||
nodeVo.setId(node.getId());
|
||||
nodeVo.setName(name);
|
||||
nodeVo.setType(type);
|
||||
nodeVo.setStatus(NodeStatusEnum.WKS.getCode());
|
||||
if (completeNodeSet.contains(node.getId())) {
|
||||
nodeVo.setStatus(NodeStatusEnum.YJS.getCode());
|
||||
|
||||
}
|
||||
if (continueNodeSet.contains(node.getId())) {
|
||||
nodeVo.setStatus(NodeStatusEnum.JXZ.getCode());
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
nodeVo.setPlaceholder(node.getPlaceHolder());
|
||||
|
||||
}
|
||||
|
||||
List<UserVo> userVoList = new ArrayList<>();
|
||||
if (type == NodeTypeEnum.APPROVAL.getValue().intValue()) {
|
||||
|
||||
Integer assignedType = node.getAssignedType();
|
||||
|
||||
boolean selfSelect = assignedType == ProcessInstanceConstant.AssignedTypeClass.SELF_SELECT;
|
||||
nodeVo.setSelectUser(selfSelect);
|
||||
if (selfSelect) {
|
||||
nodeVo.setMultiple(node.getMultiple());
|
||||
}
|
||||
|
||||
// 用户列表
|
||||
if (StrUtil.isNotBlank(processInstanceId)) {
|
||||
IProcessNodeRecordAssignUserService processNodeRecordAssignUserService = SpringUtil
|
||||
.getBean(IProcessNodeRecordAssignUserService.class);
|
||||
List<ProcessNodeRecordAssignUser> processNodeRecordAssignUserList = processNodeRecordAssignUserService
|
||||
.lambdaQuery().eq(ProcessNodeRecordAssignUser::getNodeId, node.getId())
|
||||
.eq(ProcessNodeRecordAssignUser::getProcessInstanceId, processInstanceId)
|
||||
.orderByAsc(ProcessNodeRecordAssignUser::getCreateTime).list();
|
||||
Map<String, List<ProcessNodeRecordAssignUser>> map = processNodeRecordAssignUserList.stream()
|
||||
.collect(Collectors.groupingBy(ProcessNodeRecordAssignUser::getTaskId));
|
||||
|
||||
for (Map.Entry<String, List<ProcessNodeRecordAssignUser>> entry : map.entrySet()) {
|
||||
List<ProcessNodeRecordAssignUser> value = entry.getValue();
|
||||
List<UserVo> collect = value.stream().map(w -> {
|
||||
UserVo userVo = buildUser(Long.parseLong(w.getUserId()));
|
||||
userVo.setShowTime(w.getEndTime());
|
||||
userVo.setApproveDesc(w.getApproveDesc());
|
||||
userVo.setStatus(w.getStatus());
|
||||
userVo.setOperType(w.getTaskType());
|
||||
return userVo;
|
||||
}).collect(Collectors.toList());
|
||||
userVoList.addAll(collect);
|
||||
}
|
||||
|
||||
if (processNodeRecordAssignUserList.isEmpty()) {
|
||||
if (assignedType == ProcessInstanceConstant.AssignedTypeClass.SELF) {
|
||||
// 发起人自己
|
||||
userVoList.addAll(CollUtil.newArrayList(buildRootUser(processInstanceId)));
|
||||
}
|
||||
if (assignedType == ProcessInstanceConstant.AssignedTypeClass.SELF_SELECT) {
|
||||
// 发起人自选
|
||||
Object variable = paramMap.get(StrUtil.format("{}_assignee_select", node.getId()));
|
||||
|
||||
ObjectMapper objectMapper = SpringUtil.getBean(ObjectMapper.class);
|
||||
List<NodeUser> nodeUserDtos = objectMapper.readValue(objectMapper.writeValueAsString(variable),
|
||||
new TypeReference<List<NodeUser>>() {
|
||||
});
|
||||
|
||||
List<Long> collect = nodeUserDtos.stream().map(w -> Long.valueOf(w.getId()))
|
||||
.collect(Collectors.toList());
|
||||
for (Long aLong : collect) {
|
||||
UserVo userVo = buildUser(aLong);
|
||||
userVoList.addAll(CollUtil.newArrayList(userVo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (assignedType == ProcessInstanceConstant.AssignedTypeClass.USER) {
|
||||
// 指定用户
|
||||
|
||||
List<NodeUser> nodeUserList = node.getNodeUserList();
|
||||
List<UserVo> tempList = buildUser(nodeUserList);
|
||||
userVoList.addAll(tempList);
|
||||
|
||||
}
|
||||
else if (assignedType == ProcessInstanceConstant.AssignedTypeClass.FORM_USER) {
|
||||
// 表单人员
|
||||
String formUser = node.getFormUserId();
|
||||
|
||||
Object o = paramMap.get(formUser);
|
||||
if (o != null) {
|
||||
ObjectMapper objectMapper = SpringUtil.getBean(ObjectMapper.class);
|
||||
String jsonString = objectMapper.writeValueAsString(o);
|
||||
if (StrUtil.isNotBlank(jsonString)) {
|
||||
List<NodeUser> nodeUserDtoList = objectMapper.readValue(jsonString,
|
||||
new TypeReference<List<NodeUser>>() {
|
||||
});
|
||||
List<Long> userIdList = nodeUserDtoList.stream().map(NodeUser::getId)
|
||||
.collect(Collectors.toList());
|
||||
for (Long aLong : userIdList) {
|
||||
userVoList.addAll(CollUtil.newArrayList(buildUser(aLong)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (assignedType == ProcessInstanceConstant.AssignedTypeClass.SELF) {
|
||||
// 发起人自己
|
||||
userVoList.addAll(CollUtil.newArrayList(buildUser(SecurityUtils.getUser().getId())));
|
||||
}
|
||||
|
||||
}
|
||||
else if (Objects.equals(node.getType(), NodeTypeEnum.ROOT.getValue())) {
|
||||
// 发起节点
|
||||
if (StrUtil.isBlank(processInstanceId)) {
|
||||
UserVo userVo = buildUser(SecurityUtils.getUser().getId());
|
||||
userVoList.addAll(CollUtil.newArrayList(userVo));
|
||||
}
|
||||
else {
|
||||
|
||||
IProcessInstanceRecordService processInstanceRecordService = SpringUtil
|
||||
.getBean(IProcessInstanceRecordService.class);
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId).one();
|
||||
|
||||
UserVo userVo = buildRootUser(processInstanceId);
|
||||
userVo.setShowTime(processInstanceRecord.getCreateTime());
|
||||
userVo.setStatus(NodeStatusEnum.YJS.getCode());
|
||||
userVoList.addAll(CollUtil.newArrayList(userVo));
|
||||
|
||||
}
|
||||
}
|
||||
else if (node.getType() == NodeTypeEnum.CC.getValue()) {
|
||||
// 抄送节点
|
||||
|
||||
List<NodeUser> nodeUserList = node.getNodeUserList();
|
||||
|
||||
List<UserVo> tempList = buildUser(nodeUserList);
|
||||
userVoList.addAll(tempList);
|
||||
|
||||
}
|
||||
nodeVo.setUserVoList(userVoList);
|
||||
|
||||
List<NodeVo> branchList = new ArrayList<>();
|
||||
|
||||
if (type == NodeTypeEnum.EXCLUSIVE_GATEWAY.getValue().intValue()
|
||||
|| type == NodeTypeEnum.PARALLEL_GATEWAY.getValue().intValue()) {
|
||||
// 条件分支
|
||||
List<Node> branchs = node.getConditionNodes();
|
||||
|
||||
for (Node branch : branchs) {
|
||||
Node children = branch.getChildren();
|
||||
List<NodeVo> processNodeShowDtos = formatProcessNodeShow(children, completeNodeSet, continueNodeSet,
|
||||
processInstanceId, paramMap);
|
||||
|
||||
NodeVo p = new NodeVo();
|
||||
p.setChildren(processNodeShowDtos);
|
||||
|
||||
p.setPlaceholder(branch.getPlaceHolder());
|
||||
branchList.add(p);
|
||||
}
|
||||
}
|
||||
nodeVo.setBranch(branchList);
|
||||
|
||||
list.add(nodeVo);
|
||||
|
||||
List<NodeVo> next = formatProcessNodeShow(node.getChildren(), completeNodeSet, continueNodeSet,
|
||||
processInstanceId, paramMap);
|
||||
list.addAll(next);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据实例id
|
||||
* @param processInstanceId
|
||||
* @return
|
||||
*/
|
||||
private static UserVo buildRootUser(String processInstanceId) {
|
||||
|
||||
IProcessInstanceRecordService processInstanceRecordService = SpringUtil
|
||||
.getBean(IProcessInstanceRecordService.class);
|
||||
ProcessInstanceRecord processInstanceRecord = processInstanceRecordService.lambdaQuery()
|
||||
.eq(ProcessInstanceRecord::getProcessInstanceId, processInstanceId).one();
|
||||
Long userId = processInstanceRecord.getUserId();
|
||||
UserVo userVo = buildUser(userId);
|
||||
return userVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
private static UserVo buildUser(long userId) {
|
||||
RemoteUserService userService = SpringUtil.getBean(RemoteUserService.class);
|
||||
SysUser user = userService.getUserById(userId).getData();
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return UserVo.builder().id(userId).name(user.getName()).avatar(user.getAvatar()).build();
|
||||
}
|
||||
|
||||
private static List<UserVo> buildUser(List<NodeUser> nodeUserList) {
|
||||
List<UserVo> userVoList = new ArrayList<>();
|
||||
// 用户id
|
||||
List<Long> userIdList = nodeUserList.stream()
|
||||
.filter(w -> StrUtil.equals(w.getType(), NodeUserTypeEnum.USER.getKey()))
|
||||
.map(w -> Convert.toLong(w.getId())).collect(Collectors.toList());
|
||||
// 部门id
|
||||
List<Long> deptIdList = nodeUserList.stream()
|
||||
.filter(w -> StrUtil.equals(w.getType(), NodeUserTypeEnum.DEPT.getKey()))
|
||||
.map(w -> Convert.toLong(w.getId())).collect(Collectors.toList());
|
||||
|
||||
if (CollUtil.isNotEmpty(deptIdList)) {
|
||||
|
||||
IRemoteService iRemoteService = SpringUtil.getBean(IRemoteService.class);
|
||||
|
||||
List<Long> data = iRemoteService.queryUserIdListByDepIdList(deptIdList).getData();
|
||||
|
||||
if (CollUtil.isNotEmpty(data)) {
|
||||
for (long datum : data) {
|
||||
if (!userIdList.contains(datum)) {
|
||||
userIdList.add(datum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
for (Long aLong : userIdList) {
|
||||
userVoList.addAll(CollUtil.newArrayList(buildUser(aLong)));
|
||||
}
|
||||
}
|
||||
return userVoList;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
server:
|
||||
port: 9030
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: @artifactId@
|
||||
cloud:
|
||||
nacos:
|
||||
username: @nacos.username@
|
||||
password: @nacos.password@
|
||||
discovery:
|
||||
server-addr: ${NACOS_HOST:pigx-register}:${NACOS_PORT:8848}
|
||||
config:
|
||||
server-addr: ${spring.cloud.nacos.discovery.server-addr}
|
||||
config:
|
||||
import:
|
||||
- optional:nacos:application-@profiles.active@.yml
|
||||
- optional:nacos:${spring.application.name}-@profiles.active@.yml
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
小技巧: 在根pom里面设置统一存放路径,统一管理方便维护
|
||||
<properties>
|
||||
<log-path>/Users/lengleng</log-path>
|
||||
</properties>
|
||||
1. 其他模块加日志输出,直接copy本文件放在resources 目录即可
|
||||
2. 注意修改 <property name="${log-path}/log.path" value=""/> 的value模块
|
||||
-->
|
||||
<configuration debug="false" scan="false">
|
||||
<property name="log.path" value="logs/${project.artifactId}"/>
|
||||
<!-- 彩色日志格式 -->
|
||||
<property name="CONSOLE_LOG_PATTERN"
|
||||
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
|
||||
<!-- 彩色日志依赖的渲染类 -->
|
||||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
|
||||
<conversionRule conversionWord="wex"
|
||||
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
|
||||
<conversionRule conversionWord="wEx"
|
||||
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
|
||||
<!-- Console log output -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Log file debug output -->
|
||||
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/debug.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Log file error output -->
|
||||
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/error.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>ERROR</level>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<logger name="org.activiti.engine.impl.db" level="DEBUG">
|
||||
<appender-ref ref="debug"/>
|
||||
</logger>
|
||||
|
||||
<!--nacos 心跳 INFO 屏蔽-->
|
||||
<logger name="com.alibaba.nacos" level="OFF">
|
||||
<appender-ref ref="error"/>
|
||||
</logger>
|
||||
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
|
||||
<root level="INFO">
|
||||
<appender-ref ref="console"/>
|
||||
<appender-ref ref="debug"/>
|
||||
</root>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user