流转记录扩展修改
Some checks failed
Java CI with Maven / build (11) (push) Has been cancelled
Java CI with Maven / build (17) (push) Has been cancelled
Java CI with Maven / build (8) (push) Has been cancelled
yudao-ui-admin CI / build (14.x) (push) Has been cancelled
yudao-ui-admin CI / build (16.x) (push) Has been cancelled
Some checks failed
Java CI with Maven / build (11) (push) Has been cancelled
Java CI with Maven / build (17) (push) Has been cancelled
Java CI with Maven / build (8) (push) Has been cancelled
yudao-ui-admin CI / build (14.x) (push) Has been cancelled
yudao-ui-admin CI / build (16.x) (push) Has been cancelled
This commit is contained in:
parent
b606c2c873
commit
088d8a5e90
@ -102,7 +102,8 @@ public interface ErrorCodeConstants {
|
|||||||
ErrorCode PROCESS_KEY_NOT_PROVIDED = new ErrorCode(1_009_022_001, "工作流表单key没有提供");
|
ErrorCode PROCESS_KEY_NOT_PROVIDED = new ErrorCode(1_009_022_001, "工作流表单key没有提供");
|
||||||
// ========== BPM 流程实例信息 1_009_023_000 ==========
|
// ========== BPM 流程实例信息 1_009_023_000 ==========
|
||||||
ErrorCode PROCESS_INSTANCE_TODO_NOT_EXISTS = new ErrorCode(1_009_023_000, "BPM 流程实例信息不存在");
|
ErrorCode PROCESS_INSTANCE_TODO_NOT_EXISTS = new ErrorCode(1_009_023_000, "BPM 流程实例信息不存在");
|
||||||
|
// ========== BPM 流转记录扩展 1_009_024_000 ==========
|
||||||
|
ErrorCode TASK_EXTEND_RECORD_NOT_EXISTS = new ErrorCode(1_009_024_000, "BPM 流转记录扩展不存在");
|
||||||
|
|
||||||
// ========== only 1_011_013_000 ==========
|
// ========== only 1_011_013_000 ==========
|
||||||
ErrorCode DOC_FILE_NOT_EXISTS = new ErrorCode(1_011_013_000, "目标文档不存在");
|
ErrorCode DOC_FILE_NOT_EXISTS = new ErrorCode(1_011_013_000, "目标文档不存在");
|
||||||
|
@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
|
|||||||
import cn.iocoder.yudao.module.bpm.service.processinstancetodo.ProcessInstanceTodoService;
|
import cn.iocoder.yudao.module.bpm.service.processinstancetodo.ProcessInstanceTodoService;
|
||||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||||
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
|
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.taskextendrecord.TaskTransitionLog;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
@ -144,7 +145,30 @@ public class BpmTaskController {
|
|||||||
return success(BpmTaskConvert.INSTANCE.buildTaskListByProcessInstanceId(taskList,
|
return success(BpmTaskConvert.INSTANCE.buildTaskListByProcessInstanceId(taskList,
|
||||||
formMap, userMap, deptMap));
|
formMap, userMap, deptMap));
|
||||||
}
|
}
|
||||||
|
@GetMapping("/list-by-process-instance-id2")
|
||||||
|
@Operation(summary = "获得指定流程实例的任务列表", description = "包括完成的、未完成的")
|
||||||
|
@Parameter(name = "processInstanceId", description = "流程实例的编号", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermission('bpm:task:query')")
|
||||||
|
public CommonResult<List<BpmTaskRespVO>> getTaskListByProcessInstanceId2(
|
||||||
|
@RequestParam("processInstanceId") String processInstanceId) {
|
||||||
|
//List<HistoricTaskInstance> taskList = taskService.getTaskListByProcessInstanceId(processInstanceId, true);
|
||||||
|
List<TaskTransitionLog> taskList = taskService.getTaskListByProcessInstanceId2(processInstanceId, true);
|
||||||
|
if (CollUtil.isEmpty(taskList)) {
|
||||||
|
return success(Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拼接数据
|
||||||
|
Set<Long> userIds = convertSetByFlatMap(taskList, task ->
|
||||||
|
Stream.of(NumberUtils.parseLong(task.getUserId()), NumberUtils.parseLong(task.getUserId())));
|
||||||
|
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
|
||||||
|
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
|
||||||
|
convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
|
||||||
|
// 获得 Form Map
|
||||||
|
Map<Long, BpmFormDO> formMap = formService.getFormMap(
|
||||||
|
convertSet(taskList, task -> NumberUtils.parseLong(task.getFormKey())));
|
||||||
|
return success(BpmTaskConvert.INSTANCE.buildTaskListByProcessInstanceId2(taskList,
|
||||||
|
formMap, userMap, deptMap));
|
||||||
|
}
|
||||||
@PutMapping("/approve")
|
@PutMapping("/approve")
|
||||||
@Operation(summary = "通过任务")
|
@Operation(summary = "通过任务")
|
||||||
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
||||||
|
@ -0,0 +1,95 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.controller.admin.taskextendrecord;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import javax.validation.*;
|
||||||
|
import javax.servlet.http.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||||
|
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.bpm.controller.admin.taskextendrecord.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.taskextendrecord.TaskExtendRecordDO;
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.taskextendrecord.TaskExtendRecordService;
|
||||||
|
|
||||||
|
@Tag(name = "管理后台 - BPM 流转记录扩展")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/bpm/task-extend-record")
|
||||||
|
@Validated
|
||||||
|
public class TaskExtendRecordController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TaskExtendRecordService taskExtendRecordService;
|
||||||
|
|
||||||
|
@PostMapping("/create")
|
||||||
|
@Operation(summary = "创建BPM 流转记录扩展")
|
||||||
|
@PreAuthorize("@ss.hasPermission('bpm:task-extend-record:create')")
|
||||||
|
public CommonResult<Long> createTaskExtendRecord(@Valid @RequestBody TaskExtendRecordSaveReqVO createReqVO) {
|
||||||
|
return success(taskExtendRecordService.createTaskExtendRecord(createReqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update")
|
||||||
|
@Operation(summary = "更新BPM 流转记录扩展")
|
||||||
|
@PreAuthorize("@ss.hasPermission('bpm:task-extend-record:update')")
|
||||||
|
public CommonResult<Boolean> updateTaskExtendRecord(@Valid @RequestBody TaskExtendRecordSaveReqVO updateReqVO) {
|
||||||
|
taskExtendRecordService.updateTaskExtendRecord(updateReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete")
|
||||||
|
@Operation(summary = "删除BPM 流转记录扩展")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermission('bpm:task-extend-record:delete')")
|
||||||
|
public CommonResult<Boolean> deleteTaskExtendRecord(@RequestParam("id") Long id) {
|
||||||
|
taskExtendRecordService.deleteTaskExtendRecord(id);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get")
|
||||||
|
@Operation(summary = "获得BPM 流转记录扩展")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||||
|
@PreAuthorize("@ss.hasPermission('bpm:task-extend-record:query')")
|
||||||
|
public CommonResult<TaskExtendRecordRespVO> getTaskExtendRecord(@RequestParam("id") Long id) {
|
||||||
|
TaskExtendRecordDO taskExtendRecord = taskExtendRecordService.getTaskExtendRecord(id);
|
||||||
|
return success(BeanUtils.toBean(taskExtendRecord, TaskExtendRecordRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/page")
|
||||||
|
@Operation(summary = "获得BPM 流转记录扩展分页")
|
||||||
|
@PreAuthorize("@ss.hasPermission('bpm:task-extend-record:query')")
|
||||||
|
public CommonResult<PageResult<TaskExtendRecordRespVO>> getTaskExtendRecordPage(@Valid TaskExtendRecordPageReqVO pageReqVO) {
|
||||||
|
PageResult<TaskExtendRecordDO> pageResult = taskExtendRecordService.getTaskExtendRecordPage(pageReqVO);
|
||||||
|
return success(BeanUtils.toBean(pageResult, TaskExtendRecordRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/export-excel")
|
||||||
|
@Operation(summary = "导出BPM 流转记录扩展 Excel")
|
||||||
|
@PreAuthorize("@ss.hasPermission('bpm:task-extend-record:export')")
|
||||||
|
@ApiAccessLog(operateType = EXPORT)
|
||||||
|
public void exportTaskExtendRecordExcel(@Valid TaskExtendRecordPageReqVO pageReqVO,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||||
|
List<TaskExtendRecordDO> list = taskExtendRecordService.getTaskExtendRecordPage(pageReqVO).getList();
|
||||||
|
// 导出 Excel
|
||||||
|
ExcelUtils.write(response, "BPM 流转记录扩展.xls", "数据", TaskExtendRecordRespVO.class,
|
||||||
|
BeanUtils.toBean(list, TaskExtendRecordRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.controller.admin.taskextendrecord.vo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - BPM 流转记录扩展分页 Request VO")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class TaskExtendRecordPageReqVO extends PageParam {
|
||||||
|
|
||||||
|
@Schema(description = "任务id", example = "12523")
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
@Schema(description = "任务名称", example = "李四")
|
||||||
|
private String taskName;
|
||||||
|
|
||||||
|
@Schema(description = "开始时间")
|
||||||
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
|
private LocalDateTime[] startTime;
|
||||||
|
|
||||||
|
@Schema(description = "结束时间")
|
||||||
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
|
private LocalDateTime[] endTime;
|
||||||
|
|
||||||
|
@Schema(description = "用户id", example = "13977")
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
@Schema(description = "用户名称", example = "张三")
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
@Schema(description = "意见", example = "不对")
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
@Schema(description = "持续时间")
|
||||||
|
private Long duration;
|
||||||
|
|
||||||
|
@Schema(description = "工作时间")
|
||||||
|
private Long workTime;
|
||||||
|
|
||||||
|
@Schema(description = "流程实例id", example = "1932")
|
||||||
|
private String processInstanceId;
|
||||||
|
|
||||||
|
@Schema(description = "备用字段1")
|
||||||
|
private String field1;
|
||||||
|
|
||||||
|
@Schema(description = "备用字段2")
|
||||||
|
private String field2;
|
||||||
|
|
||||||
|
@Schema(description = "备用字段3")
|
||||||
|
private String field3;
|
||||||
|
|
||||||
|
@Schema(description = "审批状态", example = "1")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
|
private LocalDateTime[] createTime;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.controller.admin.taskextendrecord.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.alibaba.excel.annotation.*;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - BPM 流转记录扩展 Response VO")
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
public class TaskExtendRecordRespVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "6915")
|
||||||
|
@ExcelProperty("编号")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "任务id", example = "12523")
|
||||||
|
@ExcelProperty("任务id")
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
@Schema(description = "任务名称", example = "李四")
|
||||||
|
@ExcelProperty("任务名称")
|
||||||
|
private String taskName;
|
||||||
|
|
||||||
|
@Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ExcelProperty("开始时间")
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
|
@Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ExcelProperty("结束时间")
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
|
||||||
|
@Schema(description = "用户id", example = "13977")
|
||||||
|
@ExcelProperty("用户id")
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
@Schema(description = "用户名称", example = "张三")
|
||||||
|
@ExcelProperty("用户名称")
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
@Schema(description = "意见", requiredMode = Schema.RequiredMode.REQUIRED, example = "不对")
|
||||||
|
@ExcelProperty("意见")
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
@Schema(description = "持续时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ExcelProperty("持续时间")
|
||||||
|
private Long duration;
|
||||||
|
|
||||||
|
@Schema(description = "工作时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ExcelProperty("工作时间")
|
||||||
|
private Long workTime;
|
||||||
|
|
||||||
|
@Schema(description = "流程实例id", example = "1932")
|
||||||
|
@ExcelProperty("流程实例id")
|
||||||
|
private String processInstanceId;
|
||||||
|
|
||||||
|
@Schema(description = "备用字段1")
|
||||||
|
@ExcelProperty("备用字段1")
|
||||||
|
private String field1;
|
||||||
|
|
||||||
|
@Schema(description = "备用字段2")
|
||||||
|
@ExcelProperty("备用字段2")
|
||||||
|
private String field2;
|
||||||
|
|
||||||
|
@Schema(description = "备用字段3")
|
||||||
|
@ExcelProperty("备用字段3")
|
||||||
|
private String field3;
|
||||||
|
|
||||||
|
@Schema(description = "审批状态", example = "1")
|
||||||
|
@ExcelProperty("审批状态")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ExcelProperty("创建时间")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.controller.admin.taskextendrecord.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - BPM 流转记录扩展新增/修改 Request VO")
|
||||||
|
@Data
|
||||||
|
public class TaskExtendRecordSaveReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "6915")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "任务id", example = "12523")
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
@Schema(description = "任务名称", example = "李四")
|
||||||
|
private String taskName;
|
||||||
|
|
||||||
|
@Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "开始时间不能为空")
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
|
@Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "结束时间不能为空")
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
|
||||||
|
@Schema(description = "用户id", example = "13977")
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
@Schema(description = "用户名称", example = "张三")
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
@Schema(description = "意见", requiredMode = Schema.RequiredMode.REQUIRED, example = "不对")
|
||||||
|
@NotEmpty(message = "意见不能为空")
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
@Schema(description = "持续时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "持续时间不能为空")
|
||||||
|
private Long duration;
|
||||||
|
|
||||||
|
@Schema(description = "工作时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "工作时间不能为空")
|
||||||
|
private Long workTime;
|
||||||
|
|
||||||
|
@Schema(description = "流程实例id", example = "1932")
|
||||||
|
private String processInstanceId;
|
||||||
|
|
||||||
|
@Schema(description = "备用字段1")
|
||||||
|
private String field1;
|
||||||
|
|
||||||
|
@Schema(description = "备用字段2")
|
||||||
|
private String field2;
|
||||||
|
|
||||||
|
@Schema(description = "备用字段3")
|
||||||
|
private String field3;
|
||||||
|
|
||||||
|
@Schema(description = "审批状态", example = "1")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
}
|
@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.processinstancetodo.ProcessIns
|
|||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
|
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.taskextendrecord.TaskTransitionLog;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||||
import org.flowable.engine.history.HistoricProcessInstance;
|
import org.flowable.engine.history.HistoricProcessInstance;
|
||||||
@ -119,6 +120,34 @@ public interface BpmTaskConvert {
|
|||||||
return taskVO;
|
return taskVO;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
default List<BpmTaskRespVO> buildTaskListByProcessInstanceId2(List<TaskTransitionLog> taskList,
|
||||||
|
Map<Long, BpmFormDO> formMap,
|
||||||
|
Map<Long, AdminUserRespDTO> userMap,
|
||||||
|
Map<Long, DeptRespDTO> deptMap) {
|
||||||
|
return CollectionUtils.convertList(taskList, task -> {
|
||||||
|
// 特殊:已取消的任务,不返回
|
||||||
|
BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
|
||||||
|
Integer taskStatus = task.getStatus();
|
||||||
|
if (BpmTaskStatusEnum.isCancelStatus(taskStatus)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskVO.setStatus(taskStatus).setReason(task.getReason() );
|
||||||
|
// 表单信息
|
||||||
|
BpmFormDO form = MapUtil.get(formMap, NumberUtils.parseLong(task.getFormKey()), BpmFormDO.class);
|
||||||
|
if (form != null) {
|
||||||
|
// taskVO.setFormId(form.getId()).setFormName(form.getName()).setFormConf(form.getConf())
|
||||||
|
// .setFormFields(form.getFields()).setFormVariables(FlowableUtils.getTaskFormVariable(task));
|
||||||
|
}
|
||||||
|
// 用户信息
|
||||||
|
// buildTaskAssignee(taskVO, task.getAssignee(), userMap, deptMap);
|
||||||
|
// buildTaskOwner(taskVO, task.getOwner(), userMap, deptMap);
|
||||||
|
buildTaskAssignee(taskVO, task.getUserId(), userMap, deptMap);
|
||||||
|
buildTaskOwner(taskVO, task.getUserId(), userMap, deptMap);
|
||||||
|
|
||||||
|
return taskVO;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
default PageResult<BpmTaskRespVO> buildTaskPageNew(PageResult<HistoricTaskInstance> pageResult,
|
default PageResult<BpmTaskRespVO> buildTaskPageNew(PageResult<HistoricTaskInstance> pageResult,
|
||||||
Map<String, HistoricProcessInstance> processInstanceMap,
|
Map<String, HistoricProcessInstance> processInstanceMap,
|
||||||
|
@ -0,0 +1,89 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.dal.dataobject.taskextendrecord;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BPM 流转记录扩展 DO
|
||||||
|
*
|
||||||
|
* @author 君风
|
||||||
|
*/
|
||||||
|
@TableName("bpm_task_extend_record")
|
||||||
|
@KeySequence("bpm_task_extend_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class TaskExtendRecordDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 任务id
|
||||||
|
*/
|
||||||
|
private String taskId;
|
||||||
|
/**
|
||||||
|
* 任务名称
|
||||||
|
*/
|
||||||
|
private String taskName;
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
/**
|
||||||
|
* 结束时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
/**
|
||||||
|
* 用户id
|
||||||
|
*/
|
||||||
|
private String userId;
|
||||||
|
/**
|
||||||
|
* 用户名称
|
||||||
|
*/
|
||||||
|
private String userName;
|
||||||
|
/**
|
||||||
|
* 意见
|
||||||
|
*/
|
||||||
|
private String reason;
|
||||||
|
/**
|
||||||
|
* 持续时间
|
||||||
|
*/
|
||||||
|
private Long duration;
|
||||||
|
/**
|
||||||
|
* 工作时间
|
||||||
|
*/
|
||||||
|
private Long workTime;
|
||||||
|
/**
|
||||||
|
* 流程实例id
|
||||||
|
*/
|
||||||
|
private String processInstanceId;
|
||||||
|
/**
|
||||||
|
* 备用字段1
|
||||||
|
*/
|
||||||
|
private String field1;
|
||||||
|
/**
|
||||||
|
* 备用字段2
|
||||||
|
*/
|
||||||
|
private String field2;
|
||||||
|
/**
|
||||||
|
* 备用字段3
|
||||||
|
*/
|
||||||
|
private String field3;
|
||||||
|
/**
|
||||||
|
* 审批状态
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.dal.mysql.taskextendrecord;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.taskextendrecord.TaskExtendRecordDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import cn.iocoder.yudao.module.bpm.controller.admin.taskextendrecord.vo.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BPM 流转记录扩展 Mapper
|
||||||
|
*
|
||||||
|
* @author 君风
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface TaskExtendRecordMapper extends BaseMapperX<TaskExtendRecordDO> {
|
||||||
|
|
||||||
|
default PageResult<TaskExtendRecordDO> selectPage(TaskExtendRecordPageReqVO reqVO) {
|
||||||
|
return selectPage(reqVO, new LambdaQueryWrapperX<TaskExtendRecordDO>()
|
||||||
|
.eqIfPresent(TaskExtendRecordDO::getTaskId, reqVO.getTaskId())
|
||||||
|
.likeIfPresent(TaskExtendRecordDO::getTaskName, reqVO.getTaskName())
|
||||||
|
.betweenIfPresent(TaskExtendRecordDO::getStartTime, reqVO.getStartTime())
|
||||||
|
.betweenIfPresent(TaskExtendRecordDO::getEndTime, reqVO.getEndTime())
|
||||||
|
.eqIfPresent(TaskExtendRecordDO::getUserId, reqVO.getUserId())
|
||||||
|
.likeIfPresent(TaskExtendRecordDO::getUserName, reqVO.getUserName())
|
||||||
|
.eqIfPresent(TaskExtendRecordDO::getReason, reqVO.getReason())
|
||||||
|
.eqIfPresent(TaskExtendRecordDO::getDuration, reqVO.getDuration())
|
||||||
|
.eqIfPresent(TaskExtendRecordDO::getWorkTime, reqVO.getWorkTime())
|
||||||
|
.eqIfPresent(TaskExtendRecordDO::getProcessInstanceId, reqVO.getProcessInstanceId())
|
||||||
|
.eqIfPresent(TaskExtendRecordDO::getField1, reqVO.getField1())
|
||||||
|
.eqIfPresent(TaskExtendRecordDO::getField2, reqVO.getField2())
|
||||||
|
.eqIfPresent(TaskExtendRecordDO::getField3, reqVO.getField3())
|
||||||
|
.eqIfPresent(TaskExtendRecordDO::getStatus, reqVO.getStatus())
|
||||||
|
.betweenIfPresent(TaskExtendRecordDO::getCreateTime, reqVO.getCreateTime())
|
||||||
|
.orderByDesc(TaskExtendRecordDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据任务 ID 查询扩展记录
|
||||||
|
default List<TaskExtendRecordDO> getRecordsByProcessInstanceId(String processInstanceId) {
|
||||||
|
return selectList(new LambdaQueryWrapperX<TaskExtendRecordDO>()
|
||||||
|
.eq(TaskExtendRecordDO::getProcessInstanceId, processInstanceId)
|
||||||
|
.eq(TaskExtendRecordDO::getDeleted, 0) // 确保只查询未删除的记录
|
||||||
|
.orderByDesc(TaskExtendRecordDO::getCreateTime)); // 按照创建时间降序排列
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
|
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutHandlerTypeEnum;
|
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutHandlerTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.taskextendrecord.TaskTransitionLog;
|
||||||
import org.flowable.bpmn.model.UserTask;
|
import org.flowable.bpmn.model.UserTask;
|
||||||
import org.flowable.engine.history.HistoricActivityInstance;
|
import org.flowable.engine.history.HistoricActivityInstance;
|
||||||
import org.flowable.task.api.Task;
|
import org.flowable.task.api.Task;
|
||||||
@ -87,8 +88,8 @@ public interface BpmTaskService {
|
|||||||
* @param asc 是否升序
|
* @param asc 是否升序
|
||||||
* @return 流程任务列表
|
* @return 流程任务列表
|
||||||
*/
|
*/
|
||||||
|
List<TaskTransitionLog> getTaskListByProcessInstanceId2(String processInstanceId, Boolean asc);
|
||||||
List<HistoricTaskInstance> getTaskListByProcessInstanceId(String processInstanceId, Boolean asc);
|
List<HistoricTaskInstance> getTaskListByProcessInstanceId(String processInstanceId, Boolean asc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取任务
|
* 获取任务
|
||||||
*
|
*
|
||||||
|
@ -9,10 +9,12 @@ import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
|||||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.PageUtils;
|
import cn.iocoder.yudao.framework.common.util.object.PageUtils;
|
||||||
|
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
||||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
|
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
|
||||||
import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
|
import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
|
||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
|
||||||
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.taskextendrecord.TaskExtendRecordDO;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.definition.*;
|
import cn.iocoder.yudao.module.bpm.enums.definition.*;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
|
||||||
@ -26,15 +28,14 @@ import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
|
|||||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
|
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
|
||||||
import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
|
import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
|
||||||
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskTimeoutReqDTO;
|
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskTimeoutReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.taskextendrecord.TaskExtendRecordService;
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.taskextendrecord.TaskTransitionLog;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.flowable.bpmn.model.BpmnModel;
|
import org.flowable.bpmn.model.*;
|
||||||
import org.flowable.bpmn.model.EndEvent;
|
|
||||||
import org.flowable.bpmn.model.FlowElement;
|
|
||||||
import org.flowable.bpmn.model.UserTask;
|
|
||||||
import org.flowable.engine.*;
|
import org.flowable.engine.*;
|
||||||
import org.flowable.engine.history.HistoricActivityInstance;
|
import org.flowable.engine.history.HistoricActivityInstance;
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
@ -53,8 +54,13 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
@ -102,6 +108,9 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
@Resource
|
@Resource
|
||||||
private RepositoryService repositoryService;
|
private RepositoryService repositoryService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TaskExtendRecordService taskExtendRecordService;
|
||||||
|
|
||||||
// ========== Query 查询相关方法 ==========
|
// ========== Query 查询相关方法 ==========
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -225,9 +234,9 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
}
|
}
|
||||||
return taskService.createTaskQuery().processInstanceIdIn(processInstanceIds).list();
|
return taskService.createTaskQuery().processInstanceIdIn(processInstanceIds).list();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<HistoricTaskInstance> getTaskListByProcessInstanceId(String processInstanceId, Boolean asc) {
|
public List<HistoricTaskInstance> getTaskListByProcessInstanceId(String processInstanceId, Boolean asc) {
|
||||||
|
// 1. 获取 Flowable 历史任务记录
|
||||||
HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery()
|
HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery()
|
||||||
.includeTaskLocalVariables()
|
.includeTaskLocalVariables()
|
||||||
.processInstanceId(processInstanceId);
|
.processInstanceId(processInstanceId);
|
||||||
@ -236,7 +245,84 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
} else {
|
} else {
|
||||||
query.orderByHistoricTaskInstanceStartTime().desc();
|
query.orderByHistoricTaskInstanceStartTime().desc();
|
||||||
}
|
}
|
||||||
return query.list();
|
List<HistoricTaskInstance> historicTasks = query.list();
|
||||||
|
|
||||||
|
return historicTasks;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public List<TaskTransitionLog> getTaskListByProcessInstanceId2(String processInstanceId, Boolean asc) {
|
||||||
|
// 1. 获取 Flowable 历史任务记录
|
||||||
|
HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery()
|
||||||
|
.includeTaskLocalVariables()
|
||||||
|
.processInstanceId(processInstanceId);
|
||||||
|
if (Boolean.TRUE.equals(asc)) {
|
||||||
|
query.orderByHistoricTaskInstanceStartTime().asc();
|
||||||
|
} else {
|
||||||
|
query.orderByHistoricTaskInstanceStartTime().desc();
|
||||||
|
}
|
||||||
|
List<HistoricTaskInstance> historicTasks = query.list();
|
||||||
|
|
||||||
|
// 2.获取所有相关的扩展记录
|
||||||
|
List<TaskExtendRecordDO> relatedRecords = taskExtendRecordService.getTaskExtendRecordsByProcessInstanceId(processInstanceId);
|
||||||
|
|
||||||
|
// 3. 转换 TaskExtendRecordDO 为 TaskTransitionLog
|
||||||
|
List<TaskTransitionLog> transitionLogs = relatedRecords.stream()
|
||||||
|
.map(record -> {
|
||||||
|
TaskTransitionLog log = new TaskTransitionLog();
|
||||||
|
log.setId(record.getTaskId());
|
||||||
|
log.setName(record.getTaskName());
|
||||||
|
log.setUserId(record.getUserId());
|
||||||
|
log.setUserName(record.getUserName());
|
||||||
|
log.setCreateTime(record.getStartTime()); // 使用 startTime 作为时间戳
|
||||||
|
log.setEndTime(record.getEndTime());
|
||||||
|
log.setReason(record.getReason());
|
||||||
|
if ( record.getStatus() != null ) {
|
||||||
|
log.setStatus(record.getStatus());
|
||||||
|
}
|
||||||
|
if ( record.getDuration() != null ) {
|
||||||
|
log.setDurationInMillis( record.getDuration() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return log;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 4. 将 historicTasks 转换为 TaskTransitionLog
|
||||||
|
List<TaskTransitionLog> taskLogs = historicTasks.stream()
|
||||||
|
.map(task -> {
|
||||||
|
TaskTransitionLog log = new TaskTransitionLog();
|
||||||
|
log.setId( task.getId() );
|
||||||
|
log.setName( task.getName() );
|
||||||
|
log.setUserId( task.getAssignee());
|
||||||
|
log.setReason( FlowableUtils.getTaskReason(task) ); // 可以从评论或其他字段获取具体原因
|
||||||
|
//startTime--------------------将 Date 转换为 LocalDateTime
|
||||||
|
Date startDate = task.getStartTime();
|
||||||
|
if ( startDate != null ) {
|
||||||
|
LocalDateTime startTime = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||||
|
log.setCreateTime(startTime);
|
||||||
|
}
|
||||||
|
//endTime----------------------将 Date 转换为 LocalDateTime
|
||||||
|
Date endDate = task.getEndTime();
|
||||||
|
if ( endDate != null) {
|
||||||
|
LocalDateTime endTime = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||||
|
log.setEndTime( endTime );
|
||||||
|
}
|
||||||
|
log.setFormKey( task.getFormKey() );
|
||||||
|
log.setStatus( FlowableUtils.getTaskStatus(task) );
|
||||||
|
if ( task.getDurationInMillis() != null ) {
|
||||||
|
log.setDurationInMillis( task.getDurationInMillis() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return log;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 5. 合并流转记录和任务记录
|
||||||
|
List<TaskTransitionLog> allLogs = new ArrayList<>();
|
||||||
|
allLogs.addAll(transitionLogs); // 加入扩展记录
|
||||||
|
allLogs.addAll(taskLogs); // 加入历史任务记录
|
||||||
|
|
||||||
|
// 6. 按时间排序所有记录(升序)
|
||||||
|
allLogs.sort(Comparator.comparing(TaskTransitionLog::getCreateTime).thenComparing(TaskTransitionLog::getEndTime));
|
||||||
|
return allLogs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -309,13 +395,51 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
// 2.1 查询该任务的前置任务节点的 key 集合
|
// 2.1 查询该任务的前置任务节点的 key 集合
|
||||||
List<UserTask> previousUserList = BpmnModelUtils.getPreviousUserTaskList(source, null, null);
|
List<UserTask> previousUserList = BpmnModelUtils.getPreviousUserTaskList(source, null, null);
|
||||||
if (CollUtil.isEmpty(previousUserList)) {
|
if (CollUtil.isEmpty(previousUserList)) {
|
||||||
return Collections.emptyList();
|
//return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.2 过滤:只有串行可到达的节点,才可以退回。类似非串行、子流程无法退回
|
// 2.2 过滤:只有串行可到达的节点,才可以退回。类似非串行、子流程无法退回
|
||||||
previousUserList.removeIf(userTask -> !BpmnModelUtils.isSequentialReachable(source, userTask, null));
|
previousUserList.removeIf(userTask -> !BpmnModelUtils.isSequentialReachable(source, userTask, null));
|
||||||
|
|
||||||
|
// 3. 获取流程模型中的起始节点(开始事件)
|
||||||
|
// FlowElement startElement = getStartEvent(bpmnModel);
|
||||||
|
// if (startElement != null) {
|
||||||
|
// // 将起始节点信息转换为 UserTask 对象
|
||||||
|
// UserTask startUserTask = new UserTask();
|
||||||
|
// startUserTask.setId(startElement.getId()); // 设置起始节点 ID
|
||||||
|
// if (startElement.getName().equals("")) {
|
||||||
|
// startUserTask.setName("开始");
|
||||||
|
// }else{
|
||||||
|
// startUserTask.setName(startElement.getName()); // 设置起始节点名称
|
||||||
|
// }
|
||||||
|
// startUserTask.setAssignee(""); // 可以为空,通常起始节点不直接关联任务的处理人
|
||||||
|
// startUserTask.setCategory("StartEvent"); // 设置类别为 StartEvent,表示这是一个起始节点
|
||||||
|
//
|
||||||
|
// // 添加起始节点到 previousUserList
|
||||||
|
// previousUserList.add(startUserTask);
|
||||||
|
// // 打印或者记录起始节点信息
|
||||||
|
// //System.out.println("起始节点: " + startElement.getId() + " - " + startElement.getName());
|
||||||
|
// }
|
||||||
|
|
||||||
return previousUserList;
|
return previousUserList;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 获取流程模型中的起始节点(开始事件)
|
||||||
|
*
|
||||||
|
* @param bpmnModel 流程模型
|
||||||
|
* @return 起始节点
|
||||||
|
*/
|
||||||
|
private FlowElement getStartEvent(BpmnModel bpmnModel) {
|
||||||
|
System.out.println("getStartEvent");
|
||||||
|
// 获取流程的开始事件(通常是第一个节点)
|
||||||
|
for (FlowElement flowElement : bpmnModel.getMainProcess().getFlowElements()) {
|
||||||
|
if (flowElement instanceof StartEvent) {
|
||||||
|
System.out.println(flowElement);
|
||||||
|
return flowElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null; // 如果没有找到起始事件,返回 null
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public <T extends TaskInfo> List<T> getAllChildrenTaskListByParentTaskId(String parentTaskId, List<T> tasks) {
|
public <T extends TaskInfo> List<T> getAllChildrenTaskListByParentTaskId(String parentTaskId, List<T> tasks) {
|
||||||
if (CollUtil.isEmpty(tasks)) {
|
if (CollUtil.isEmpty(tasks)) {
|
||||||
@ -764,13 +888,13 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
.moveExecutionsToSingleActivityId(runExecutionIds, reqVO.getTargetTaskDefinitionKey())
|
.moveExecutionsToSingleActivityId(runExecutionIds, reqVO.getTargetTaskDefinitionKey())
|
||||||
.changeState();
|
.changeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void delegateTask(Long userId, BpmTaskDelegateReqVO reqVO) {
|
public void delegateTask(Long userId, BpmTaskDelegateReqVO reqVO) {
|
||||||
String taskId = reqVO.getId();
|
String taskId = reqVO.getId();
|
||||||
// 1.1 校验任务
|
// 1.1 校验任务
|
||||||
Task task = validateTask(userId, reqVO.getId());
|
Task task = validateTask(userId, reqVO.getId());
|
||||||
|
Date startDate = task.getCreateTime();
|
||||||
if (task.getAssignee().equals(reqVO.getDelegateUserId().toString())) { // 校验当前审批人和被委派人不是同一人
|
if (task.getAssignee().equals(reqVO.getDelegateUserId().toString())) { // 校验当前审批人和被委派人不是同一人
|
||||||
throw exception(TASK_DELEGATE_FAIL_USER_REPEAT);
|
throw exception(TASK_DELEGATE_FAIL_USER_REPEAT);
|
||||||
}
|
}
|
||||||
@ -790,13 +914,34 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
// 3.2 执行委派,将任务委派给 delegateUser
|
// 3.2 执行委派,将任务委派给 delegateUser
|
||||||
taskService.delegateTask(taskId, reqVO.getDelegateUserId().toString());
|
taskService.delegateTask(taskId, reqVO.getDelegateUserId().toString());
|
||||||
// 补充说明:委托不单独设置状态。如果需要,可通过 Task 的 DelegationState 字段,判断是否为 DelegationState.PENDING 委托中
|
// 补充说明:委托不单独设置状态。如果需要,可通过 Task 的 DelegationState 字段,判断是否为 DelegationState.PENDING 委托中
|
||||||
|
|
||||||
|
LocalDateTime startTime = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().minusSeconds(1);
|
||||||
|
LocalDateTime endTime = LocalDateTime.now();
|
||||||
|
Duration duration = Duration.between(startTime, endTime);
|
||||||
|
long seconds = duration.getSeconds();
|
||||||
|
|
||||||
|
//同步更新到流转记录库
|
||||||
|
taskExtendRecordService.toCreateTaskExtendRecord(
|
||||||
|
task.getId(),
|
||||||
|
task.getName()+"("+currentUser.getNickname()+"委托)",
|
||||||
|
startTime,
|
||||||
|
endTime,
|
||||||
|
String.valueOf(userId),
|
||||||
|
reqVO.getReason(),
|
||||||
|
duration.getSeconds()*1000,
|
||||||
|
task.getProcessInstanceId(),
|
||||||
|
2
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@DataPermission(enable = false)
|
||||||
public void transferTask(Long userId, BpmTaskTransferReqVO reqVO) {
|
public void transferTask(Long userId, BpmTaskTransferReqVO reqVO) {
|
||||||
String taskId = reqVO.getId();
|
String taskId = reqVO.getId();
|
||||||
// 1.1 校验任务
|
// 1.1 校验任务
|
||||||
Task task = validateTask(userId, reqVO.getId());
|
Task task = validateTask(userId, reqVO.getId());
|
||||||
|
Date startDate = task.getCreateTime();
|
||||||
|
|
||||||
if (task.getAssignee().equals(reqVO.getAssigneeUserId().toString())) { // 校验当前审批人和被转派人不是同一人
|
if (task.getAssignee().equals(reqVO.getAssigneeUserId().toString())) { // 校验当前审批人和被转派人不是同一人
|
||||||
throw exception(TASK_TRANSFER_FAIL_USER_REPEAT);
|
throw exception(TASK_TRANSFER_FAIL_USER_REPEAT);
|
||||||
}
|
}
|
||||||
@ -816,6 +961,24 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
// 3.2 执行转派(审批人),将任务转派给 assigneeUser
|
// 3.2 执行转派(审批人),将任务转派给 assigneeUser
|
||||||
// 委托( delegate)和转派(transfer)的差别,就在这块的调用!!!!
|
// 委托( delegate)和转派(transfer)的差别,就在这块的调用!!!!
|
||||||
taskService.setAssignee(taskId, reqVO.getAssigneeUserId().toString());
|
taskService.setAssignee(taskId, reqVO.getAssigneeUserId().toString());
|
||||||
|
|
||||||
|
LocalDateTime startTime = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().minusSeconds(1);
|
||||||
|
LocalDateTime endTime = LocalDateTime.now();
|
||||||
|
Duration duration = Duration.between(startTime, endTime);
|
||||||
|
long seconds = duration.getSeconds();
|
||||||
|
|
||||||
|
//同步更新到流转记录库
|
||||||
|
taskExtendRecordService.toCreateTaskExtendRecord(
|
||||||
|
task.getId(),
|
||||||
|
task.getName()+"("+currentUser.getNickname()+"转办)",
|
||||||
|
startTime,
|
||||||
|
endTime,
|
||||||
|
String.valueOf(userId),
|
||||||
|
reqVO.getReason(),
|
||||||
|
duration.getSeconds()*1000,
|
||||||
|
task.getProcessInstanceId(),
|
||||||
|
2
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1300,6 +1463,16 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 扩展属性
|
||||||
|
userTask.getExtensionElements().forEach((key, value) -> {
|
||||||
|
//System.out.println("Extension Key: " + key);
|
||||||
|
if ( key.equals( itemStr ) ) {
|
||||||
|
value.forEach(extensionElement -> {
|
||||||
|
//System.out.println("Extension Value: " + extensionElement.getElementText());
|
||||||
|
valueStrRef.set( extensionElement.getElementText() );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.service.taskextendrecord;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.validation.*;
|
||||||
|
import cn.iocoder.yudao.module.bpm.controller.admin.taskextendrecord.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.taskextendrecord.TaskExtendRecordDO;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BPM 流转记录扩展 Service 接口
|
||||||
|
*
|
||||||
|
* @author 君风
|
||||||
|
*/
|
||||||
|
public interface TaskExtendRecordService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建BPM 流转记录扩展
|
||||||
|
*
|
||||||
|
* @param createReqVO 创建信息
|
||||||
|
* @return 编号
|
||||||
|
*/
|
||||||
|
Long createTaskExtendRecord(@Valid TaskExtendRecordSaveReqVO createReqVO);
|
||||||
|
void toCreateTaskExtendRecord(String taskId, String taskName, LocalDateTime startTime, LocalDateTime endTime, String userId, String reason, Long duration, String processInstanceId, Integer status) ;
|
||||||
|
/**
|
||||||
|
* 更新BPM 流转记录扩展
|
||||||
|
*
|
||||||
|
* @param updateReqVO 更新信息
|
||||||
|
*/
|
||||||
|
void updateTaskExtendRecord(@Valid TaskExtendRecordSaveReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除BPM 流转记录扩展
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
*/
|
||||||
|
void deleteTaskExtendRecord(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得BPM 流转记录扩展
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
* @return BPM 流转记录扩展
|
||||||
|
*/
|
||||||
|
TaskExtendRecordDO getTaskExtendRecord(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得BPM 流转记录扩展分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @return BPM 流转记录扩展分页
|
||||||
|
*/
|
||||||
|
PageResult<TaskExtendRecordDO> getTaskExtendRecordPage(TaskExtendRecordPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
public List<TaskExtendRecordDO> getTaskExtendRecordsByProcessInstanceId(String taskId);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.service.taskextendrecord;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.*;
|
||||||
|
import cn.iocoder.yudao.module.bpm.controller.admin.taskextendrecord.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.taskextendrecord.TaskExtendRecordDO;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.bpm.dal.mysql.taskextendrecord.TaskExtendRecordMapper;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BPM 流转记录扩展 Service 实现类
|
||||||
|
*
|
||||||
|
* @author 君风
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class TaskExtendRecordServiceImpl implements TaskExtendRecordService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TaskExtendRecordMapper taskExtendRecordMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long createTaskExtendRecord(TaskExtendRecordSaveReqVO createReqVO) {
|
||||||
|
// 插入
|
||||||
|
TaskExtendRecordDO taskExtendRecord = BeanUtils.toBean(createReqVO, TaskExtendRecordDO.class);
|
||||||
|
taskExtendRecordMapper.insert(taskExtendRecord);
|
||||||
|
// 返回
|
||||||
|
return taskExtendRecord.getId();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void toCreateTaskExtendRecord(String taskId, String taskName, LocalDateTime startTime,LocalDateTime endTime,String userId,String reason,Long duration,String processInstanceId,Integer status) {
|
||||||
|
// 插入
|
||||||
|
TaskExtendRecordDO taskExtendRecord = new TaskExtendRecordDO();
|
||||||
|
taskExtendRecord.setTaskId(taskId);
|
||||||
|
taskExtendRecord.setTaskName(taskName);
|
||||||
|
taskExtendRecord.setStartTime( startTime );
|
||||||
|
taskExtendRecord.setEndTime( endTime );
|
||||||
|
taskExtendRecord.setUserId( userId );
|
||||||
|
taskExtendRecord.setReason( reason );
|
||||||
|
taskExtendRecord.setDuration( duration );
|
||||||
|
taskExtendRecord.setProcessInstanceId( processInstanceId );
|
||||||
|
taskExtendRecord.setStatus( status );
|
||||||
|
|
||||||
|
taskExtendRecordMapper.insert(taskExtendRecord);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void updateTaskExtendRecord(TaskExtendRecordSaveReqVO updateReqVO) {
|
||||||
|
// 校验存在
|
||||||
|
validateTaskExtendRecordExists(updateReqVO.getId());
|
||||||
|
// 更新
|
||||||
|
TaskExtendRecordDO updateObj = BeanUtils.toBean(updateReqVO, TaskExtendRecordDO.class);
|
||||||
|
taskExtendRecordMapper.updateById(updateObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteTaskExtendRecord(Long id) {
|
||||||
|
// 校验存在
|
||||||
|
validateTaskExtendRecordExists(id);
|
||||||
|
// 删除
|
||||||
|
taskExtendRecordMapper.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateTaskExtendRecordExists(Long id) {
|
||||||
|
if (taskExtendRecordMapper.selectById(id) == null) {
|
||||||
|
throw exception(TASK_EXTEND_RECORD_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaskExtendRecordDO getTaskExtendRecord(Long id) {
|
||||||
|
return taskExtendRecordMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<TaskExtendRecordDO> getTaskExtendRecordPage(TaskExtendRecordPageReqVO pageReqVO) {
|
||||||
|
return taskExtendRecordMapper.selectPage(pageReqVO);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public List<TaskExtendRecordDO> getTaskExtendRecordsByProcessInstanceId(String taskId) {
|
||||||
|
return taskExtendRecordMapper.getRecordsByProcessInstanceId(taskId);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.service.taskextendrecord;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TaskTransitionLog {
|
||||||
|
private String id; //任务id
|
||||||
|
private String name; //任务名称
|
||||||
|
private String actionType; // 起草、转办、委托
|
||||||
|
private String userId; // 执行该操作的用户
|
||||||
|
private String userName; //用户姓名
|
||||||
|
private LocalDateTime createTime; //开始时间
|
||||||
|
private LocalDateTime endTime; //结束时间
|
||||||
|
private String reason; // 操作意见
|
||||||
|
private String FormKey;
|
||||||
|
private long durationInMillis; // 操作意见
|
||||||
|
private int status;
|
||||||
|
}
|
@ -1,10 +1,12 @@
|
|||||||
package cn.iocoder.yudao.module.home.service.fwgl;
|
package cn.iocoder.yudao.module.home.service.fwgl;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.taskextendrecord.TaskExtendRecordService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import cn.iocoder.yudao.module.home.controller.admin.fwgl.vo.*;
|
import cn.iocoder.yudao.module.home.controller.admin.fwgl.vo.*;
|
||||||
import cn.iocoder.yudao.module.home.dal.dataobject.fwgl.FwglDO;
|
import cn.iocoder.yudao.module.home.dal.dataobject.fwgl.FwglDO;
|
||||||
@ -42,6 +44,9 @@ public class FwglServiceImpl implements FwglService {
|
|||||||
@Resource
|
@Resource
|
||||||
private FwglMapper fwglMapper;
|
private FwglMapper fwglMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TaskExtendRecordService taskExtendRecordService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long saveDraft(Long userId,FwglSaveReqVO createReqVO) {
|
public Long saveDraft(Long userId,FwglSaveReqVO createReqVO) {
|
||||||
// 插入
|
// 插入
|
||||||
@ -71,6 +76,7 @@ public class FwglServiceImpl implements FwglService {
|
|||||||
.setVariables(processInstanceVariables).setBusinessKey(String.valueOf(fwgl.getId()))
|
.setVariables(processInstanceVariables).setBusinessKey(String.valueOf(fwgl.getId()))
|
||||||
.setStartUserSelectAssignees(createReqVO.getStartUserSelectAssignees()));
|
.setStartUserSelectAssignees(createReqVO.getStartUserSelectAssignees()));
|
||||||
|
|
||||||
|
|
||||||
// 将工作流的编号,更新到 OA 请假单中
|
// 将工作流的编号,更新到 OA 请假单中
|
||||||
fwglMapper.updateById(new FwglDO().setId(fwgl.getId()).setProcessInstanceId(processInstanceId));
|
fwglMapper.updateById(new FwglDO().setId(fwgl.getId()).setProcessInstanceId(processInstanceId));
|
||||||
//同步更新流程待办库
|
//同步更新流程待办库
|
||||||
@ -80,6 +86,19 @@ public class FwglServiceImpl implements FwglService {
|
|||||||
processInstanceId,
|
processInstanceId,
|
||||||
createReqVO.getCurfullpath()
|
createReqVO.getCurfullpath()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//同步更新到流转记录库
|
||||||
|
// taskExtendRecordService.toCreateTaskExtendRecord(
|
||||||
|
// processInstanceId,
|
||||||
|
// "起草",
|
||||||
|
// LocalDateTime.now().minusSeconds(20),
|
||||||
|
// LocalDateTime.now().minusSeconds(20),
|
||||||
|
// String.valueOf(userId),
|
||||||
|
// "",
|
||||||
|
// 0L,
|
||||||
|
// processInstanceId,
|
||||||
|
// 2
|
||||||
|
// );
|
||||||
// 返回
|
// 返回
|
||||||
return fwgl.getId();
|
return fwgl.getId();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user