diff --git a/urbanops-module-api/urbanops-module-workorder-api/src/main/java/com/zteits/urbanops/module/workorder/dto/AppGardenWorkOrderRespVO.java b/urbanops-module-api/urbanops-module-workorder-api/src/main/java/com/zteits/urbanops/module/workorder/dto/AppGardenWorkOrderRespVO.java index 8cda872..0f5a497 100644 --- a/urbanops-module-api/urbanops-module-workorder-api/src/main/java/com/zteits/urbanops/module/workorder/dto/AppGardenWorkOrderRespVO.java +++ b/urbanops-module-api/urbanops-module-workorder-api/src/main/java/com/zteits/urbanops/module/workorder/dto/AppGardenWorkOrderRespVO.java @@ -16,12 +16,6 @@ import java.util.List; @Data public class AppGardenWorkOrderRespVO extends MainInfoRespVO { - @Schema(description = "问题图片", example = "9184") - private List problemImgsList; - - @Schema(description = "处理完成照片", example = "9184") - private List completeImgsList; - @Schema(description = "任务id") private String taskId; @@ -42,4 +36,22 @@ public class AppGardenWorkOrderRespVO extends MainInfoRespVO { @Schema(description = "流程定义key") private String key_; + + @Schema(description = "开始的问题拍照图片") + private List problemsImgs; + + @Schema(description = "实施开始的拍照图片") + private List startImgs; + + @Schema(description = "实施中的拍照图片") + private List processingImgs; + + @Schema(description = "实施结束的拍照图片") + private List endImgs; + + @Schema(description = "实施人员的拍照图片") + private List personImgs; + + @Schema(description = "实施耗材的拍照图片") + private List materialImgs; } diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/api/constant/BpmCommonConstant.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/api/constant/BpmCommonConstant.java index 2845408..d4566ef 100644 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/api/constant/BpmCommonConstant.java +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/api/constant/BpmCommonConstant.java @@ -15,6 +15,11 @@ public class BpmCommonConstant { * 园林巡检工单 流程业务key */ public static final String BPM_GARDEN_INSPECT_WO = "garden_inspect_wo"; + + /** + * 园林巡检工单 通用版本 + */ + public static final String BPM_WORKORDER_COMMON_PROD = "workorder_common_prod"; /** * 物业巡检工单 流程业务key */ @@ -23,22 +28,36 @@ public class BpmCommonConstant { * 市政巡检工单 流程业务key */ public static final String BPM_MUNICIPAL_INSPECT_WO = "municipal_inspect_wo"; - /** + /** 01 问题图片,02 开始图片,03 进行中图片,04 已完成图片,05 人员图片:06 材料图片 + * problemsImgs,startImgs,processingImgs,endImgs,personImgs,materialImgs * 园林问题单处理前图片描述 */ public static final String PROBLEM_IMG_GROUP = "01"; /** - * 园林问题单处理中图片类型 + * 园林工单开始图片类型 + */ + public static final String START_IMG_GROUP = "02"; + /** + * 园林工单进行中图片类型 + */ + public static final String PROCESS_IMG_GROUP = "03"; + + /** + * 园林工单结束图片类型 + */ + public static final String END_IMG_GROUP = "04"; + /** + * 园林工单人员图片类型 */ - public static final String HANDLE_IMG_GROUP = "02"; + public static final String PERSON_IMG_GROUP = "05"; /** - * 园林处理结果图片类型 + * 园林工单耗材图片类型 */ - public static final String RESULT_IMG_GROUP = "03"; + public static final String MATERIAL_IMG_GROUP = "06"; /** * 园林工作流 组长退回的附件照片 */ - public static final String GARDEN_TEAMLEADER_RETURN_IMG = "04"; + public static final String GARDEN_TEAMLEADER_RETURN_IMG = "09"; /** * 园林工单编号前缀 */ diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/AppGardenWorkOrderController.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/AppGardenWorkOrderController.java index 942e535..7f8a332 100644 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/AppGardenWorkOrderController.java +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/AppGardenWorkOrderController.java @@ -3,13 +3,16 @@ package com.zteits.urbanops.module.workorder.controller.app.garden; import com.zteits.urbanops.framework.common.pojo.CommonResult; import com.zteits.urbanops.framework.common.pojo.PageResult; import com.zteits.urbanops.framework.common.util.object.BeanUtils; +import com.zteits.urbanops.framework.common.util.object.ObjectUtils; import com.zteits.urbanops.framework.security.core.util.SecurityFrameworkUtils; import com.zteits.urbanops.module.garden.api.road.RoadApi; import com.zteits.urbanops.module.garden.dto.road.RoadReqDTO; import com.zteits.urbanops.module.garden.dto.road.RoadRespDTO; import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO; import com.zteits.urbanops.module.workorder.controller.app.garden.vo.*; +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.common.AppUniversalApprovalReqVO; import com.zteits.urbanops.module.workorder.controller.app.garden.vo.common.UserInfoPageReqVO; +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskRejectExtReqVO; import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskReturnExtReqVO; import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskTeamLeaderAssignReqVO; import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskWorkerExcuteReqVO; @@ -19,18 +22,22 @@ import com.zteits.urbanops.module.workorder.controller.app.garden.vo.task.*; import com.zteits.urbanops.module.workorder.dal.dataobject.garden.BpmGardenWorkOrderDO; import com.zteits.urbanops.module.workorder.dto.AppGardenWorkOrderReqVO; import com.zteits.urbanops.module.workorder.dto.AppGardenWorkOrderRespVO; +import com.zteits.urbanops.module.workorder.enums.OperateTypeEnum; import com.zteits.urbanops.module.workorder.service.garden.BpmGardenService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.validation.Valid; +import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import java.util.List; +import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.zteits.urbanops.framework.common.pojo.CommonResult.success; import static com.zteits.urbanops.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static com.zteits.urbanops.module.workorder.enums.ErrorCodeConstants.*; /** * @author yanhuiqing @@ -40,6 +47,7 @@ import static com.zteits.urbanops.framework.security.core.util.SecurityFramework */ @Tag(name = "APP - 园林工单bpm") @RestController +@Slf4j @RequestMapping("/bpm/garden/workorder") public class AppGardenWorkOrderController { @Resource @@ -160,6 +168,13 @@ public class AppGardenWorkOrderController { gardenService.returnPreviousNode(reqVO); return success(true); } + @PutMapping("/reject") + @Operation(summary = "app - 不通过任务-驳回") + //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:update')") + public CommonResult rejectTask(@Valid @RequestBody AppGardenTaskRejectExtReqVO reqVO) { + gardenService.rejectTask(reqVO); + return success(true); + } @PutMapping("/withdraw") @Operation(summary = "app - 撤回任务") @@ -230,4 +245,124 @@ public class AppGardenWorkOrderController { PageResult pageResult = gardenService.getUserByLoginIdAndRoleCode(pageVO, SecurityFrameworkUtils.getLoginUserId(),pageVO.getRoleCode(),pageVO.getBusiLine(),pageVO.isNotHas()); return success(pageResult); } + + @Operation(summary = "app-统一审批入口") + @PostMapping("/universalApproval") + //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:update')") + public CommonResult universalApproval(@Valid @RequestBody AppUniversalApprovalReqVO reqVO) { + + log.info("【园林统一审批】接收前端请求,入参:curTaskKey={}, taskId={}, operateType={}, agree={}, reason={}", + reqVO.getTaskKey(), reqVO.getTaskId(), reqVO.getOperateType(), reqVO.getAgree(), reqVO.getReason()); + + OperateTypeEnum operateType = OperateTypeEnum.getByCode(reqVO.getOperateType()); + + switch (operateType) { + case YL_WORKER_RETURN:// 养护员退回 + log.info("当前操作:"+OperateTypeEnum.YL_WORKER_RETURN.getDesc()+"开始,操作类型:"+OperateTypeEnum.YL_WORKER_RETURN.getCode()+"-->"); + AppGardenTaskReturnExtReqVO retReqVO = new AppGardenTaskReturnExtReqVO(); + retReqVO.setId(reqVO.getTaskId()); + retReqVO.setCurTaskKey(reqVO.getTaskKey()); + retReqVO.setReason(reqVO.getReason()); + retReqVO.setWorkerDataId(reqVO.getWorkerDataId()); + retReqVO.setReturnImgs(reqVO.getReturnImgs()); + this.returnPreviousNode(retReqVO); + log.info("当前操作:"+OperateTypeEnum.YL_WORKER_RETURN.getDesc()+"<--结束"); + return success(true); + case YL_WORKER_IMPLEMENT://养护员实施 + log.info("当前操作:"+OperateTypeEnum.YL_WORKER_IMPLEMENT.getDesc()+"开始,操作类型:"+OperateTypeEnum.YL_WORKER_RETURN.getCode()+"-->"); + AppGardenTaskWorkerExcuteReqVO workerExcuteReqVO = new AppGardenTaskWorkerExcuteReqVO(); + workerExcuteReqVO.setWorkerDataId(reqVO.getWorkerDataId()); + workerExcuteReqVO.setId(reqVO.getTaskId()); + workerExcuteReqVO.setCoHandlers(reqVO.getCoHandlers()); + workerExcuteReqVO.setHandleResult(reqVO.getHandleResult()); + workerExcuteReqVO.setProblemsImgs(reqVO.getProblemsImgs()); + workerExcuteReqVO.setStartImgs(reqVO.getStartImgs()); + workerExcuteReqVO.setProcessingImgs(reqVO.getProcessingImgs()); + workerExcuteReqVO.setEndImgs(reqVO.getEndImgs()); + workerExcuteReqVO.setPersonImgs(reqVO.getPersonImgs()); + workerExcuteReqVO.setMaterialImgs(reqVO.getMaterialImgs()); + this.ylWorkerExcuteWOrder(workerExcuteReqVO); + log.info("当前操作:"+OperateTypeEnum.YL_WORKER_IMPLEMENT.getDesc()+"<--结束"); + return success(true); + case YL_TEAM_LEADER_CONFIRM_PASS://养护组长验收通过 + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_CONFIRM_PASS.getDesc()+"开始,操作类型:"+OperateTypeEnum.YL_WORKER_RETURN.getCode()+"-->"); + AppGardenTaskApproveReqVO approveReqVO = new AppGardenTaskApproveReqVO(); + approveReqVO.setReason(reqVO.getReason()); + approveReqVO.setId(reqVO.getTaskId()); + this.approveTask(approveReqVO); + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_CONFIRM_PASS.getDesc()+"<--结束"); + return success(true); + case YL_TEAM_LEADER_CONFIRM_REJECT://养护组长验收不通过 + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_CONFIRM_REJECT.getDesc()+"开始,操作类型:"+OperateTypeEnum.YL_WORKER_RETURN.getCode()+"-->"); + AppGardenTaskReturnExtReqVO rejReqVO = new AppGardenTaskReturnExtReqVO(); + rejReqVO.setId(reqVO.getTaskId()); + rejReqVO.setCurTaskKey(reqVO.getTaskKey()); + rejReqVO.setReason(reqVO.getReason()); + rejReqVO.setWorkerDataId(reqVO.getWorkerDataId()); + rejReqVO.setReturnImgs(reqVO.getReturnImgs()); + this.returnPreviousNode(rejReqVO); + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_CONFIRM_REJECT.getDesc()+"<--结束"); + return success(true); + case YL_TEAM_LEADER_ASSIGN: //养护组长分配 + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_ASSIGN.getDesc()+"开始,操作类型:"+OperateTypeEnum.YL_WORKER_RETURN.getCode()+"-->"); + AppGardenTaskTeamLeaderAssignReqVO assignReqVO = new AppGardenTaskTeamLeaderAssignReqVO(); + assignReqVO.setId(reqVO.getTaskId()); + assignReqVO.setReason(reqVO.getReason()); + Long userId = reqVO.getNextAssignee(); + if(!ObjectUtils.isNotAllEmpty(userId)){ + throw exception(APP_WORKER_NOT_EXISTS); + } + assignReqVO.setNextAssignee(reqVO.getNextAssignee()); + Integer status = reqVO.getAgree(); + if (status == null || (status != 0 && status != 1)) { + throw exception(APP_AGREE_CHOOSE); + } + assignReqVO.setAgree(status); + this.ylTeamLeaderAssignWOrder(assignReqVO); + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_ASSIGN.getDesc()+"<--结束"); + return success(true); + + case YL_TEAM_LEADER_RETURN://养护组长退回 + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_RETURN.getDesc()+"开始,操作类型:"+OperateTypeEnum.YL_WORKER_RETURN.getCode()+"-->"); + AppGardenTaskApproveReqVO returnApproveReqVO = new AppGardenTaskApproveReqVO(); + Integer approveStatus = reqVO.getAgree(); + if (approveStatus == null || (approveStatus != 0 && approveStatus != 1)) { + throw exception(APP_AGREE_CHOOSE); + } + returnApproveReqVO.setAgree(approveStatus); + returnApproveReqVO.setReason(reqVO.getReason()); + returnApproveReqVO.setId(reqVO.getTaskId()); + this.approveTask(returnApproveReqVO); + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_RETURN.getDesc()+"<--结束"); + return success(true); + case YL_INSPECTOR_START_FINISH , YL_INSPECTOR_START_RELAUNCH : //巡查员结束工单,巡查员重新发起 + log.info("当前操作:养护组长结束工单(不同意)或巡查员重新发起(同意)开始,是否同意:"+reqVO.getAgree()+"-->"); + AppGardenTaskApproveReqVO inspectStartReqVO = new AppGardenTaskApproveReqVO(); + Integer revokeStatus = reqVO.getAgree(); + if (revokeStatus == null || (revokeStatus != 0 && revokeStatus != 1)) { + throw exception(APP_AGREE_CHOOSE); + } + inspectStartReqVO.setAgree(revokeStatus); + inspectStartReqVO.setReason(reqVO.getReason()); + inspectStartReqVO.setId(reqVO.getTaskId()); + this.approveTask(inspectStartReqVO); + log.info("当前操作:"+OperateTypeEnum.YL_INSPECTOR_START_FINISH.getDesc()+"<--结束"); + return success(true); + case YL_INSPECTOR_CHECK_PASS , YL_INSPECTOR_CHECK_REJECT ://巡查员验收通过,巡查员验收不通过 + log.info("当前操作:巡查员验收通过 或巡查员验收不通过开始,是否同意:"+reqVO.getAgree()+"-->"); + AppGardenTaskApproveReqVO inspectReqVO = new AppGardenTaskApproveReqVO(); + Integer verifyStatus = reqVO.getAgree(); + if (verifyStatus == null || (verifyStatus != 0 && verifyStatus != 1)) { + throw exception(APP_AGREE_CHOOSE); + } + inspectReqVO.setAgree(verifyStatus); + inspectReqVO.setReason(reqVO.getReason()); + inspectReqVO.setId(reqVO.getTaskId()); + this.approveTask(inspectReqVO); + log.info("当前操作:"+OperateTypeEnum.YL_INSPECTOR_START_FINISH.getDesc()+"<--结束"); + return success(true); + default: + throw exception(APP_OPERATOR_NOT_EXISTS); + } + } } diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/common/AppUniversalApprovalReqVO.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/common/AppUniversalApprovalReqVO.java new file mode 100644 index 0000000..aeb16e7 --- /dev/null +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/common/AppUniversalApprovalReqVO.java @@ -0,0 +1,83 @@ +package com.zteits.urbanops.module.workorder.controller.app.garden.vo.common; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import java.util.List; +import java.util.Set; + +/** + * 类描述:app端统一工作流审批入口 + * 创建人:yanhuiqing + * 创建时间:2025/12/20 10:26 + * 修改人:yanhuiqing + * 修改时间:2025/12/20 10:26 + * 修改备注:优化字段类型,添加业务扩展参数,增加验证分组 + * + * @author yanhuiqing + * @version 1.0 + */ +@Schema(description = "APP - 园林统一审批 通用Request VO") +@Data +public class AppUniversalApprovalReqVO { + // -------------------------- 基础通用参数(所有操作必填) -------------------------- + @Schema(description = "当前任务的taskKey", requiredMode = Schema.RequiredMode.REQUIRED, example = "ylTeamLeader") + @NotEmpty(message = "当前任务的taskKey不能为空") + private String taskKey; + + @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1234567890") + @NotEmpty(message = "任务编号不能为空") + private String taskId; + + @Schema(description = "操作类型(210:养护组长退回,110:养护组长分配,200:巡查员结束工单,100:巡查员重新发起,220:养护员退回,120:养护员实施,130:养护组长验收通过,230:养护组长验收不通过,140:巡查员验收通过,240:巡查员验收不通过)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "操作类型不能为空") + private Integer operateType; // 原String改为Integer,适配数字类型 + + @Schema(description = "同意选择类型:0 同意,1 不同意", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + //@NotNull(message = "同意选择类型不能为空") + private Integer agree; + + @Schema(description = "操作理由(审批/退回理由)", requiredMode = Schema.RequiredMode.REQUIRED, example = "同意该工单处理结果") + //@NotEmpty(message = "操作理由不能为空") + private String reason; + + @Schema(description = "工单的数据id", requiredMode = Schema.RequiredMode.REQUIRED) + //@NotEmpty(message = "工单的数据id不能为空") + private Long workerDataId; + + @Schema(description = "退回时的拍照图片") + private List returnImgs; + // -------------------------- 退回操作专属参数(分组:ReturnGroup) -------------------------- + + // -------------------------- 养护组长分配专属参数(分组:AssignMaintainerGroup) -------------------------- + @Schema(description = "养护员用户ID(养护组长分配操作必填)", example = "user1001") + //@NotEmpty(message = "养护员用户ID不能为空", groups = AssignMaintainerGroup.class) + private Long nextAssignee; + + // -------------------------- 养护员实施专属参数(分组:MaintainerImplementGroup) -------------------------- + @Schema(description = "共同处理人用户ID列表", example = "[111,222]") + private Set coHandlers; + + @Schema(description = "处理意见(养护员实施操作必填)", example = "已完成绿植修剪,效果符合要求") + //@NotEmpty(message = "处理意见不能为空", groups = MaintainerImplementGroup.class) + private String handleResult; + + @Schema(description = "开始的问题拍照图片") + private List problemsImgs; + + @Schema(description = "实施开始的拍照图片") + private List startImgs; + + @Schema(description = "实施中的拍照图片") + private List processingImgs; + + @Schema(description = "实施结束的拍照图片") + private List endImgs; + + @Schema(description = "实施人员的拍照图片") + private List personImgs; + + @Schema(description = "实施耗材的拍照图片") + private List materialImgs; +} \ No newline at end of file diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/operator/AppGardenTaskRejectExtReqVO.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/operator/AppGardenTaskRejectExtReqVO.java new file mode 100644 index 0000000..9f2ac29 --- /dev/null +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/operator/AppGardenTaskRejectExtReqVO.java @@ -0,0 +1,39 @@ +package com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +import java.util.List; + +/** + * 类描述:园林app端拒绝任务的reqVO + * 创建人:yanhuiqing + * 创建时间:2025/12/19 10:55 + * 修改人:yanhuiqing + * 修改时间:2025/12/19 10:55 + * 修改备注: + * + * @author yanhuiqing + * @version 1.0 + */ +@Schema(description = "APP - 驳回的流程任务的 Request VO") +@Data +public class AppGardenTaskRejectExtReqVO { + + @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotEmpty(message = "任务编号不能为空") + private String id; + + @Schema(description = "退回意见", requiredMode = Schema.RequiredMode.REQUIRED, example = "我就是想驳回") + @NotEmpty(message = "退回意见不能为空") + private String reason; + + @Schema(description = "工单的数据id", requiredMode = Schema.RequiredMode.REQUIRED) + //@NotEmpty(message = "工单的数据id不能为空") + private Long workerDataId; + + @Schema(description = "退回时的拍照图片") + private List returnImgs; + +} \ No newline at end of file diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/operator/AppGardenTaskTeamLeaderAssignReqVO.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/operator/AppGardenTaskTeamLeaderAssignReqVO.java index d5b85c7..ff4def3 100644 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/operator/AppGardenTaskTeamLeaderAssignReqVO.java +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/operator/AppGardenTaskTeamLeaderAssignReqVO.java @@ -29,4 +29,8 @@ public class AppGardenTaskTeamLeaderAssignReqVO { @Schema(description = "养护员userId") @NotNull(message = "养护员不能为空") private Long nextAssignee; + + @Schema(description = "同意选择类型:0 同意,1 不同意", example = "0") + //@NotNull(message = "同意选择类型不能为空") + private Integer agree; } \ No newline at end of file diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/operator/AppGardenTaskWorkerExcuteReqVO.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/operator/AppGardenTaskWorkerExcuteReqVO.java index f223453..ce654f2 100644 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/operator/AppGardenTaskWorkerExcuteReqVO.java +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/operator/AppGardenTaskWorkerExcuteReqVO.java @@ -41,9 +41,18 @@ public class AppGardenTaskWorkerExcuteReqVO { @Schema(description = "开始的问题拍照图片") private List problemsImgs; + @Schema(description = "实施开始的拍照图片") + private List startImgs; + @Schema(description = "实施中的拍照图片") - private List handingImgs; + private List processingImgs; @Schema(description = "实施结束的拍照图片") - private List handledImgs; + private List endImgs; + + @Schema(description = "实施人员的拍照图片") + private List personImgs; + + @Schema(description = "实施耗材的拍照图片") + private List materialImgs; } \ No newline at end of file diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/task/AppGardenTaskApproveReqVO.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/task/AppGardenTaskApproveReqVO.java index 263f3ef..91b2099 100644 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/task/AppGardenTaskApproveReqVO.java +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/task/AppGardenTaskApproveReqVO.java @@ -29,4 +29,8 @@ public class AppGardenTaskApproveReqVO { @Schema(description = "审批意见", example = "通过!") private String reason; + @Schema(description = "同意选择类型:0 同意,1 不同意", example = "0") + //@NotNull(message = "同意选择类型不能为空") + private Integer agree; + } \ No newline at end of file diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/convert/garden/AppGardenTaskConvert.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/convert/garden/AppGardenTaskConvert.java index 3a7cb2f..265c4e4 100644 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/convert/garden/AppGardenTaskConvert.java +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/convert/garden/AppGardenTaskConvert.java @@ -142,14 +142,44 @@ public interface AppGardenTaskConvert { source.getOrderNo(), attachmentMapper ); - List completeImgsList = queryAttachment( + List startImgsList = queryAttachment( source.getBusiLine(), - BpmCommonConstant.RESULT_IMG_GROUP, + BpmCommonConstant.START_IMG_GROUP, source.getOrderNo(), attachmentMapper ); - target.setProblemImgsList(problemImgsList); - target.setCompleteImgsList(completeImgsList); + List processImgsList = queryAttachment( + source.getBusiLine(), + BpmCommonConstant.PROCESS_IMG_GROUP, + source.getOrderNo(), + attachmentMapper + ); + + List endImgsList = queryAttachment( + source.getBusiLine(), + BpmCommonConstant.END_IMG_GROUP, + source.getOrderNo(), + attachmentMapper + ); + List personImgsList = queryAttachment( + source.getBusiLine(), + BpmCommonConstant.PERSON_IMG_GROUP, + source.getOrderNo(), + attachmentMapper + ); + + List matirialImgsList = queryAttachment( + source.getBusiLine(), + BpmCommonConstant.MATERIAL_IMG_GROUP, + source.getOrderNo(), + attachmentMapper + ); + target.setProblemsImgs(problemImgsList); + target.setStartImgs(startImgsList); + target.setProcessingImgs(processImgsList); + target.setEndImgs(endImgsList); + target.setPersonImgs(personImgsList); + target.setMaterialImgs(matirialImgsList); return target; } diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/convert/garden/BpmGardenWorkOrderConverter.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/convert/garden/BpmGardenWorkOrderConverter.java index 9321bdf..d5481ab 100644 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/convert/garden/BpmGardenWorkOrderConverter.java +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/convert/garden/BpmGardenWorkOrderConverter.java @@ -53,7 +53,7 @@ public class BpmGardenWorkOrderConverter { ); List completeImgsList = queryAttachment( source.getBusiLine(), - BpmCommonConstant.RESULT_IMG_GROUP, + BpmCommonConstant.PROCESS_IMG_GROUP, source.getOrderNo(), attachmentMapper ); diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/dal/mysql/maininfo/MainInfoExtMapper.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/dal/mysql/maininfo/MainInfoExtMapper.java index 4ab86fc..5c7a0b8 100644 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/dal/mysql/maininfo/MainInfoExtMapper.java +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/dal/mysql/maininfo/MainInfoExtMapper.java @@ -36,8 +36,10 @@ public interface MainInfoExtMapper extends BaseMapperX { "SELECT", " m.*,", " t.ID_ AS task_id,", - " t.NAME_ AS task_name,", - " t.task_def_key_ as task_key,", + /*"t.NAME_ AS task_name,", + "t.task_def_key_ AS task_key,",*/ + " '' AS task_name,", + " '' AS task_key,", " pd.NAME_ AS process_definition_name,", " t.START_TIME_,", " t.END_TIME_,", @@ -249,8 +251,10 @@ public interface MainInfoExtMapper extends BaseMapperX { "SELECT", "m.*,", "t.ID_ AS task_id,", - "t.NAME_ AS task_name,", - "t.task_def_key_ AS task_key,", + /*"t.NAME_ AS task_name,", + "t.task_def_key_ AS task_key,",*/ + "'' AS task_name,", + "'' AS task_key,", "pd.NAME_ AS process_definition_name,", "t.START_TIME_ ,", "t.END_TIME_,", diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/AgreeTypeEnum.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/AgreeTypeEnum.java new file mode 100644 index 0000000..3624842 --- /dev/null +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/AgreeTypeEnum.java @@ -0,0 +1,42 @@ +package com.zteits.urbanops.module.workorder.enums; + +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 类描述:同意类型枚举(0:同意,1:不同意) + * 创建人:yanhuiqing + * 创建时间:2025/12/20 12:00 + * 修改人:yanhuiqing + * 修改时间:2025/12/20 12:00 + * 修改备注: + * + * @author yanhuiqing + * @version 1.0 + */ +@Schema(description = "同意类型枚举") +@Getter +public enum AgreeTypeEnum { + AGREE(0, "同意"), + DISAGREE(1, "不同意"); + + @JsonValue // 序列化时返回code(前端接收数字) + private final Integer code; + private final String desc; + + AgreeTypeEnum(Integer code, String desc) { + this.code = code; + this.desc = desc; + } + + // 根据code获取枚举(业务层转换用) + public static AgreeTypeEnum getByCode(Integer code) { + return Arrays.stream(values()) + .filter(e -> e.getCode().equals(code)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("无效的同意类型:" + code)); + } +} \ No newline at end of file diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/ErrorCodeConstants.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/ErrorCodeConstants.java index 56fa743..96d80cc 100644 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/ErrorCodeConstants.java +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/ErrorCodeConstants.java @@ -18,4 +18,10 @@ public interface ErrorCodeConstants { ErrorCode MATERIAL_DETAIL_NOT_EXISTS = new ErrorCode(1-900-001-002, "工单耗材明细不存在"); ErrorCode TEAM_LEADER_YL_NOT_EXISTS = new ErrorCode(1-900-001-003, "养护班组长人员不存在"); + + ErrorCode APP_AGREE_CHOOSE = new ErrorCode(1-900-001-004, "agree状态只能为0或1"); + + ErrorCode APP_OPERATOR_NOT_EXISTS = new ErrorCode(1-900-001-004, "无此操作类型!"); + + ErrorCode APP_WORKER_NOT_EXISTS = new ErrorCode(1-900-001-004, "养护员必须指派,不能为空!"); } diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/OperateTypeEnum.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/OperateTypeEnum.java new file mode 100644 index 0000000..e346f6e --- /dev/null +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/OperateTypeEnum.java @@ -0,0 +1,48 @@ +package com.zteits.urbanops.module.workorder.enums; + +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import java.util.Arrays; +/** + * 类描述:园林审批操作类型枚举(对应业务1-12的操作类型) + * 创建人:yanhuiqing + * 创建时间:2025/12/20 12:01 + * 修改人:yanhuiqing + * 修改时间:2025/12/20 12:01 + * 修改备注: + * + * @author yanhuiqing + * @version 1.0 + */ +@Schema(description = "园林审批操作类型枚举") +@Getter +public enum OperateTypeEnum { + YL_TEAM_LEADER_ASSIGN(110, "养护组长分配"), + YL_TEAM_LEADER_RETURN(210, "养护组长退回"), + YL_WORKER_IMPLEMENT(120, "养护员实施"), + YL_WORKER_RETURN(220, "养护员退回"), + YL_TEAM_LEADER_CONFIRM_PASS(130, "养护组长验收通过"), + YL_TEAM_LEADER_CONFIRM_REJECT(230, "养护组长验收不通过"), + YL_INSPECTOR_CHECK_PASS(140, "巡查员验收通过"), + YL_INSPECTOR_CHECK_REJECT(240, "巡查员验收不通过"), + YL_INSPECTOR_START_FINISH(200, "巡查员结束工单(不同意)"), + YL_INSPECTOR_START_RELAUNCH(100, "巡查员重新发起(同意)"); + + @JsonValue // 序列化时返回code(前端接收数字) + private final Integer code; + private final String desc; + + OperateTypeEnum(Integer code, String desc) { + this.code = code; + this.desc = desc; + } + + // 根据code获取枚举(业务层转换用) + public static OperateTypeEnum getByCode(Integer code) { + return Arrays.stream(values()) + .filter(e -> e.getCode().equals(code)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("无效的操作类型:" + code)); + } +} \ No newline at end of file diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/BpmGardenService.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/BpmGardenService.java index dc1444f..48c09c7 100644 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/BpmGardenService.java +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/BpmGardenService.java @@ -3,8 +3,10 @@ package com.zteits.urbanops.module.workorder.service.garden; import com.zteits.urbanops.framework.common.pojo.PageParam; import com.zteits.urbanops.framework.common.pojo.PageResult; import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO; +import com.zteits.urbanops.module.workorder.controller.admin.garden.vo.BpmGardenWorkOrderCreateReqVO; import com.zteits.urbanops.module.workorder.controller.admin.garden.vo.BpmGardenWorkOrderPageReqVO; -import com.zteits.urbanops.module.workorder.controller.app.garden.vo.AppGardenWorkOrderPageReqVO; +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.*; +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskRejectExtReqVO; import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskReturnExtReqVO; import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskTeamLeaderAssignReqVO; import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskWorkerExcuteReqVO; @@ -114,6 +116,12 @@ public interface BpmGardenService { void returnPreviousNode(AppGardenTaskReturnExtReqVO reqVO); /** + * 驳回任务 -app端 + * @param reqVO + */ + void rejectTask(AppGardenTaskRejectExtReqVO reqVO); + + /** * 撤回任务 -app端 * @param taskId */ diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/BpmGardenServiceImpl.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/BpmGardenServiceImpl.java index 78532bb..a618b96 100644 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/BpmGardenServiceImpl.java +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/BpmGardenServiceImpl.java @@ -27,7 +27,8 @@ import com.zteits.urbanops.module.workorder.api.constant.BpmCommonConstant; import com.zteits.urbanops.module.workorder.controller.admin.garden.vo.BpmGardenWorkOrderPageReqVO; import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInfoHasTaskPageReqVO; import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInfoPageReqVO; -import com.zteits.urbanops.module.workorder.controller.app.garden.vo.*; +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.AppGardenWorkOrderPageReqVO; +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskRejectExtReqVO; import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskReturnExtReqVO; import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskTeamLeaderAssignReqVO; import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskWorkerExcuteReqVO; @@ -66,7 +67,6 @@ import static com.zteits.urbanops.framework.common.exception.enums.GlobalErrorCo import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception0; import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertSet; -import static com.zteits.urbanops.framework.web.core.util.WebFrameworkUtils.getLoginUserId; import static com.zteits.urbanops.module.workorder.enums.ErrorCodeConstants.MAIN_INFO_NOT_EXISTS; import static com.zteits.urbanops.module.workorder.enums.ErrorCodeConstants.TEAM_LEADER_YL_NOT_EXISTS; @@ -146,9 +146,6 @@ public class BpmGardenServiceImpl implements BpmGardenService{ attachmentApend(imgList,null,longRangeImgList,workOrder); // 发起 BPM 流程 Map processInstanceVariables = new HashMap<>(); - //processInstanceVariables.put("workOrder", workOrder); - //processInstanceVariables.put("imgList", imgList); - //processInstanceVariables.put("longRangeImgList", longRangeImgList); processInstanceVariables.put("initiator", SecurityFrameworkUtils.getLoginUserId()); String processInstanceId = processInstanceApi.createProcessInstance(SecurityFrameworkUtils.getLoginUserId(), @@ -181,6 +178,16 @@ public class BpmGardenServiceImpl implements BpmGardenService{ Map variables = new HashMap<>(); //审批通过 variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,BpmTaskStatusEnum.APPROVE.getStatus()); + Integer status = reqVO.getAgree(); + if(status == null || status == 1){//status == null 此处是为了兼容老接口,防止前段少改造 + variables.put("isNeed",false); + variables.put("isRevoke",false); + variables.put("isVerify",false); + }else { + variables.put("isNeed",true); + variables.put("isRevoke",true); + variables.put("isVerify",true); + } targetVO.setVariables(variables); //TODO 审批候选人需要赋值 Map> nextAssignees = new HashMap<>(); @@ -195,6 +202,12 @@ public class BpmGardenServiceImpl implements BpmGardenService{ //审批通过 variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,BpmTaskStatusEnum.APPROVE.getStatus()); variables.put("ylWorkerId",reqVO.getNextAssignee()); + Integer status = reqVO.getAgree(); + if(status == null || status == 0){//status == null 此处是为了兼容老接口,防止前段少改造 + variables.put("isNeed",true); + }else { + variables.put("isNeed",false); + } targetVO.setVariables(variables); Map> nextAssignees = new HashMap<>(); targetVO.setNextAssignees(nextAssignees); @@ -212,22 +225,35 @@ public class BpmGardenServiceImpl implements BpmGardenService{ targetVO.setVariables(variables); Long id = reqVO.getWorkerDataId(); - List handingImgs = reqVO.getHandingImgs(); - List handledImgs = reqVO.getHandledImgs(); List problemsImgs = reqVO.getProblemsImgs(); + List startImgs = reqVO.getStartImgs(); + List processingImgs = reqVO.getProcessingImgs(); + List endImgs = reqVO.getEndImgs(); + List personImgs = reqVO.getPersonImgs(); + List materialImgs = reqVO.getMaterialImgs(); MainInfoDO workerOrder = workOrderMapper.selectById(id); workerOrder.setHandleResult(reqVO.getHandleResult()); workerOrder.setCoHandlers(reqVO.getCoHandlers()); workOrderMapper.updateById(workerOrder); if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(problemsImgs) && problemsImgs.size()>0){ - attachmentInsertOrUpdate(problemsImgs,BpmCommonConstant.HANDLE_IMG_GROUP,workerOrder); + attachmentInsertOrUpdate(problemsImgs,BpmCommonConstant.PROBLEM_IMG_GROUP,workerOrder); + } + if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(startImgs) && startImgs.size()>0){ + attachmentInsertOrUpdate(startImgs,BpmCommonConstant.START_IMG_GROUP,workerOrder); + } + if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(processingImgs) && processingImgs.size()>0){ + attachmentInsertOrUpdate(processingImgs,BpmCommonConstant.PROCESS_IMG_GROUP,workerOrder); + } + + if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(endImgs) && endImgs.size()>0){ + attachmentInsertOrUpdate(endImgs,BpmCommonConstant.END_IMG_GROUP,workerOrder); } - if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(handingImgs) && handingImgs.size()>0){ - attachmentInsertOrUpdate(handingImgs,BpmCommonConstant.HANDLE_IMG_GROUP,workerOrder); + if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(personImgs) && personImgs.size()>0){ + attachmentInsertOrUpdate(personImgs,BpmCommonConstant.PERSON_IMG_GROUP,workerOrder); } - if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(handledImgs) && handledImgs.size()>0){ - attachmentInsertOrUpdate(handledImgs,BpmCommonConstant.RESULT_IMG_GROUP,workerOrder); + if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(materialImgs) && materialImgs.size()>0){ + attachmentInsertOrUpdate(materialImgs,BpmCommonConstant.MATERIAL_IMG_GROUP,workerOrder); } taskService.approveTask(SecurityFrameworkUtils.getLoginUserId(),targetVO); @@ -245,9 +271,21 @@ public class BpmGardenServiceImpl implements BpmGardenService{ @Transactional(rollbackFor = Exception.class) public void returnPreviousNode(AppGardenTaskReturnExtReqVO reqVO) { BpmTaskReturnReqVO targetVO = BeanUtils.toBean(reqVO,BpmTaskReturnReqVO.class); - targetVO.setTargetTaskDefinitionKey(TaskNodeUtils.getPreviousNodeName(reqVO.getCurTaskKey())); + String currentTaskey = reqVO.getCurTaskKey(); + targetVO.setTargetTaskDefinitionKey(TaskNodeUtils.getPreviousNodeName(currentTaskey)); Long userId = SecurityFrameworkUtils.getLoginUserId(); taskService.returnTask(userId, targetVO); + + /*if(TaskNodeEnum.YL_TEAM_LEADER.getNodeName().equals(currentTaskey)){ + Task task = taskService.getTask(reqVO.getId()); + String processInstanceId = task.getProcessInstanceId(); + + Map variables = new HashMap<>(); + variables.put("isReturnedToFirstApproval", true); + variables.put("isFirstEnterFirstApproval", false); + // 更新流程实例级别变量 + runtimeService.setVariables(processInstanceId, variables); + }*/ Long id = reqVO.getWorkerDataId(); List returnImgs = reqVO.getReturnImgs(); if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(returnImgs) && returnImgs.size()>0){ @@ -258,6 +296,20 @@ public class BpmGardenServiceImpl implements BpmGardenService{ } @Override + @Transactional(rollbackFor = Exception.class) + public void rejectTask(AppGardenTaskRejectExtReqVO reqVO) { + BpmTaskRejectReqVO targetVO = BeanUtils.toBean(reqVO,BpmTaskRejectReqVO.class); + Long userId = SecurityFrameworkUtils.getLoginUserId(); + taskService.rejectTask(userId, targetVO); + Long id = reqVO.getWorkerDataId(); + List returnImgs = reqVO.getReturnImgs(); + if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(returnImgs) && returnImgs.size()>0){ + MainInfoDO workerOrder = workOrderMapper.selectById(id); + attachmentInsertOrUpdate(returnImgs,BpmCommonConstant.GARDEN_TEAMLEADER_RETURN_IMG,workerOrder); + } + } + + @Override public void withdrawTask(String taskId) { Long userId = SecurityFrameworkUtils.getLoginUserId(); taskService.withdrawTask(userId,taskId); @@ -355,7 +407,7 @@ public class BpmGardenServiceImpl implements BpmGardenService{ } taskBuzReqVO.setUserId(SecurityFrameworkUtils.getLoginUserId()); //TODO 先写死 - taskBuzReqVO.setKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO); + //taskBuzReqVO.setKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO); PageResult pageResult = workOrderExtMapper.selectWorkOrderMyPage(pageVO,taskBuzReqVO); return AppGardenTaskConvert.INSTANCE.buildBuziTaskPage(pageResult,attachmentMapper); } @@ -388,7 +440,7 @@ public class BpmGardenServiceImpl implements BpmGardenService{ } taskBuzReqVO.setUserId(SecurityFrameworkUtils.getLoginUserId()); //TODO 先写死 - taskBuzReqVO.setKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO); + //taskBuzReqVO.setKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO); PageResult pageResult = workOrderExtMapper.selectWorkOrderDonePage(pageVO,taskBuzReqVO); return AppGardenTaskConvert.INSTANCE.buildBuziTaskPage(pageResult,attachmentMapper); } @@ -422,7 +474,7 @@ public class BpmGardenServiceImpl implements BpmGardenService{ } taskBuzReqVO.setUserId(SecurityFrameworkUtils.getLoginUserId()); //TODO 先写死 - taskBuzReqVO.setKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO); + //taskBuzReqVO.setKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO); PageResult pageResult = workOrderExtMapper.selectWorkOrderTodoPage(pageVO,taskBuzReqVO); return AppGardenTaskConvert.INSTANCE.buildBuziTaskPage(pageResult,attachmentMapper); @@ -514,10 +566,10 @@ public class BpmGardenServiceImpl implements BpmGardenService{ .map(AdminUserRespDTO::getId) // 收集结果到List .collect(Collectors.toList()); - //startUserSelectAssignees.put("",idList); processInstanceVariables.put("ylTeamLeaderId", idList.get(0)); String processInstanceId = processInstanceApi.createProcessInstance(userId, - new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO) + // new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO) + new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(BpmCommonConstant.BPM_WORKORDER_COMMON_PROD) .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(workOrder.getId())) .setStartUserSelectAssignees(startUserSelectAssignees)); @@ -576,13 +628,13 @@ public class BpmGardenServiceImpl implements BpmGardenService{ if(ObjectUtils.isNotAllEmpty(streetImgList)){ AttachmentDO saveDO = new AttachmentDO(); saveDO.setBusiLine(workOrder.getBusiLine()); - saveDO.setBusiType(BpmCommonConstant.HANDLE_IMG_GROUP); + saveDO.setBusiType(BpmCommonConstant.START_IMG_GROUP); saveDO.setOrderNo(workOrder.getOrderNo()); String filePaths = String.join(",",streetImgList); saveDO.setFileNames(filePaths); LambdaQueryWrapper deleteWrapper = new LambdaQueryWrapper() .eq(AttachmentDO::getBusiLine, workOrder.getBusiLine()) - .eq(AttachmentDO::getBusiType, BpmCommonConstant.HANDLE_IMG_GROUP) + .eq(AttachmentDO::getBusiType, BpmCommonConstant.START_IMG_GROUP) .eq(AttachmentDO::getOrderNo, workOrder.getOrderNo()); attachmentMapper.delete(deleteWrapper); attachmentMapper.insert(saveDO); @@ -591,13 +643,13 @@ public class BpmGardenServiceImpl implements BpmGardenService{ if(ObjectUtils.isNotAllEmpty(longRangeImgList)){ AttachmentDO saveDO = new AttachmentDO(); saveDO.setBusiLine(workOrder.getBusiLine()); - saveDO.setBusiType(BpmCommonConstant.RESULT_IMG_GROUP); + saveDO.setBusiType(BpmCommonConstant.PROCESS_IMG_GROUP); saveDO.setOrderNo(workOrder.getOrderNo()); String filePaths = String.join(",",longRangeImgList); saveDO.setFileNames(filePaths); LambdaQueryWrapper deleteWrapper = new LambdaQueryWrapper() .eq(AttachmentDO::getBusiLine, workOrder.getBusiLine()) - .eq(AttachmentDO::getBusiType, BpmCommonConstant.RESULT_IMG_GROUP) + .eq(AttachmentDO::getBusiType, BpmCommonConstant.PROCESS_IMG_GROUP) .eq(AttachmentDO::getOrderNo, workOrder.getOrderNo()); attachmentMapper.delete(deleteWrapper); attachmentMapper.insert(saveDO); diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/AutoCompleteTaskListener.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/AutoCompleteTaskListener.java deleted file mode 100644 index cdb32c6..0000000 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/AutoCompleteTaskListener.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.zteits.urbanops.module.workorder.service.garden.listener; - -import cn.hutool.core.util.StrUtil; -import jakarta.annotation.Resource; -import org.flowable.engine.HistoryService; -import org.flowable.engine.ProcessEngine; -import org.flowable.engine.RuntimeService; -import org.flowable.engine.TaskService; -import org.flowable.engine.delegate.TaskListener; // 配套的TaskListener也用核心包 -import org.flowable.task.api.Task; -import org.flowable.task.api.history.HistoricTaskInstanceQuery; -import org.flowable.task.service.delegate.DelegateTask; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Component; - -import java.util.HashMap; -import java.util.Map; - -/** - * 自动完成任务的监听器(最终版:适配项目实际包路径 + 移除所有报错依赖) - * Bean名称:autoCompleteTaskListener(与BPMN中的delegateExpression对应) - */ -@Component("autoCompleteTaskListener") -public class AutoCompleteTaskListener implements TaskListener { - - // ========== 仅使用Flowable核心公开API,移除所有内部/拆分接口 ========== - @Resource // 若项目习惯用@Autowired,可直接替换(@Resource按名称,@Autowired按类型,功能一致) - private TaskService taskService; - - @Resource - private RuntimeService runtimeService; - - // 核心:直接注入ProcessEngine(兼容所有Flowable版本,可获取任意服务) - @Resource - private ProcessEngine processEngine; - - @Resource - private ApplicationContext applicationContext; - - // 统一流程状态值(与RuoYi的事件监听器预期值一致) - private static final String FLOW_STATUS = "3"; // 对应“完成”状态 - - @Override - public void notify(DelegateTask delegateTask) { // 此处DelegateTask为核心包的类,与项目一致 - try { - // 1. 获取核心变量 - String taskId = delegateTask.getId(); - String processInstanceId = delegateTask.getProcessInstanceId(); - String assignee = delegateTask.getAssignee(); - - // 兜底:从流程变量获取发起人(initiator是Flowable启动节点的发起人变量) - if (StrUtil.isBlank(assignee)) { - assignee = (String) delegateTask.getVariable("initiator"); - if (StrUtil.isBlank(assignee)) { - assignee = (String) runtimeService.getVariable(processInstanceId, "initiator"); - if (StrUtil.isBlank(assignee)) { - throw new RuntimeException("发起人ID为空,无法完成任务"); - } - } - // 修正:使用Flowable公开API更新办理人(彻底放弃内部类操作,无类型转换) - taskService.setAssignee(taskId, assignee); - } - - // 2. 关键:提前设置所有层级的status变量(解决RuoYi事件status为空) - runtimeService.setVariable(processInstanceId, "status", FLOW_STATUS); // 流程全局变量 - delegateTask.setVariable("status", FLOW_STATUS); // 任务局部变量 - Map variables = new HashMap<>(); - variables.put("status", FLOW_STATUS); - variables.put("completeRemark", "系统自动完成,办理人:" + assignee); - - // 3. 完成任务(Flowable核心API,兼容所有版本) - Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); - if (task != null) { - taskService.complete(taskId, variables); - } - - // 4. 兜底:确保历史任务归档(使用ProcessEngine获取HistoryService,无报错) - ensureHistoricTaskCompleted(taskId, assignee); - - // 5. 手动发布事件补充status(解决RuoYi的事件校验问题) - publishProcessEventWithStatus(processInstanceId); - - } catch (Exception e) { - throw new RuntimeException("自动完成任务失败", e); - } - } - - /** - * 修正:使用ProcessEngine获取HistoryService(兼容所有Flowable版本,无报错) - * 彻底移除HistoryTaskService,改用核心HistoryService - */ - private void ensureHistoricTaskCompleted(String taskId, String assignee) { - // 核心:从ProcessEngine获取HistoryService(Flowable 6.x/7.0通用) - HistoryService historyService = processEngine.getHistoryService(); - // 历史任务查询(Flowable核心API,无报错) - //HistoricTaskInstanceQuery historicTask = historyService.createHistoricTaskInstanceQuery() - // .taskId(taskId) - // .singleResult(); - - /*if (historicTask != null) { - if (historicTask.getEndTime() == null) { - Task runtimeTask = taskService.createTaskQuery().taskId(taskId).singleResult(); - if (runtimeTask != null) { - taskService.complete(taskId); - } else { - // 手动更新历史任务表(通过MyBatis操作,避免Flowable API差异) - // updateHistoricTask(taskId, assignee); // 若需要,自行实现Mapper - } - } - }*/ - } - - /** - * 手动发布包含status的流程事件(适配RuoYi事件类,避免导入依赖) - */ - private void publishProcessEventWithStatus(String processInstanceId) { - try { - // 反射创建RuoYi的ProcessInstanceResultEvent(兼容无参/有参构造) - Class eventClass = Class.forName("com.ruoyi.flowable.event.ProcessInstanceResultEvent"); - Object event = null; - - // 先尝试无参构造 - try { - event = eventClass.getDeclaredConstructor().newInstance(); - } catch (Exception e) { - // 无参失败,尝试单参构造(流程实例ID) - try { - event = eventClass.getConstructor(String.class).newInstance(processInstanceId); - } catch (Exception e2) { - // 单参失败,尝试双参构造(流程实例ID + status) - event = eventClass.getConstructor(String.class, String.class).newInstance(processInstanceId, FLOW_STATUS); - } - } - - // 强制设置status属性(无论构造方式如何) - eventClass.getMethod("setStatus", String.class).invoke(event, FLOW_STATUS); - eventClass.getMethod("setProcessInstanceId", String.class).invoke(event, processInstanceId); - - // 发布事件(覆盖RuoYi的空status事件) - applicationContext.publishEvent(event); - } catch (Exception e) { - // 反射失败时,提示用户修改RuoYi的事件校验逻辑(应急方案) - e.printStackTrace(); - System.out.println("★★★反射发布事件失败,请手动修改RuoYi的ProcessInstanceResultEvent校验逻辑,添加status默认值★★★"); - } - } - - // 若需要手动更新历史任务表,自行实现以下方法(需添加MyBatis Mapper) - // private void updateHistoricTask(String taskId, String assignee) { - // // historicTaskMapper.updateHistoricTask(taskId, assignee, new Date()); - // } -} \ No newline at end of file diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/BpmGardenWorkOrderStatusListener.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/BpmGardenWorkOrderStatusListener.java deleted file mode 100644 index b15e65f..0000000 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/BpmGardenWorkOrderStatusListener.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.zteits.urbanops.module.workorder.service.garden.listener; - -import com.zteits.urbanops.module.bpm.api.event.BpmProcessInstanceStatusEvent; -import com.zteits.urbanops.module.bpm.api.event.BpmProcessInstanceStatusEventListener; -import com.zteits.urbanops.module.workorder.api.constant.BpmCommonConstant; -import com.zteits.urbanops.module.workorder.service.garden.BpmGardenService; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Component; - -/** - * @author yanhuiqing - * @version 1.0 - * @description: 工作流状态监听类 - * @date 2025/12/1 11:45 - */ -@Component -public class BpmGardenWorkOrderStatusListener extends BpmProcessInstanceStatusEventListener { - @Resource - private BpmGardenService gardenService; - @Override - protected String getProcessDefinitionKey() { - - return BpmCommonConstant.BPM_GARDEN_INSPECT_WO; - } - - @Override - protected void onEvent(BpmProcessInstanceStatusEvent event) { - gardenService.updateWorkOrderStatus(Long.parseLong(event.getBusinessKey()), event.getStatus()); - } -} diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/BpmProcessTaskAutoCompleteListener.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/BpmProcessTaskAutoCompleteListener.java index f13659a..677b941 100644 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/BpmProcessTaskAutoCompleteListener.java +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/BpmProcessTaskAutoCompleteListener.java @@ -22,7 +22,8 @@ public class BpmProcessTaskAutoCompleteListener extends BpmProcessInstanceStatus @Override protected String getProcessDefinitionKey() { - return BpmCommonConstant.BPM_GARDEN_INSPECT_WO; + //return BpmCommonConstant.BPM_GARDEN_INSPECT_WO; + return BpmCommonConstant.BPM_WORKORDER_COMMON_PROD; } @Override diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/FirstApprovalAutoCompleteListener.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/FirstApprovalAutoCompleteListener.java deleted file mode 100644 index 1817060..0000000 --- a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/FirstApprovalAutoCompleteListener.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.zteits.urbanops.module.workorder.service.garden.listener; - -/** - * 类描述:第一次跳过审批,第二次手动审批 - * 创建人:yanhuiqing - * 创建时间:2025/12/18 20:28 - * 修改人:yanhuiqing - * 修改时间:2025/12/18 20:28 - * 修改备注: - * - * @author yanhuiqing - * @version 1.0 - */ -import org.flowable.engine.TaskService; -import org.flowable.engine.delegate.TaskListener; -import org.flowable.task.service.delegate.DelegateTask; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * 初审节点自动通过监听器 - */ -@Component("firstApprovalAutoCompleteListener") // 组件名,供流程设计器调用 -public class FirstApprovalAutoCompleteListener implements TaskListener { - - // 注入Flowable的TaskService,用于完成任务 - @Autowired - private TaskService taskService; - - @Override - public void notify(DelegateTask delegateTask) { - // 1. 获取流程变量 - String starterId = (String) delegateTask.getVariable("starterId"); // 发起人ID - Boolean isFirstEnter = (Boolean) delegateTask.getVariable("isFirstEnterFirstApproval"); // 是否首次进入 - Boolean isReturned = (Boolean) delegateTask.getVariable("isReturnedToFirstApproval"); // 是否退回 - - // 2. 获取当前审批节点的审批人ID - String assigneeId = delegateTask.getAssignee(); - - // 3. 核心逻辑:首次进入 + 发起人=审批人 → 自动完成任务 - if (isFirstEnter != null && isFirstEnter - && !Boolean.TRUE.equals(isReturned) - && starterId != null && starterId.equals(assigneeId)) { - - // 标记:首次进入已处理,后续不再触发自动通过 - delegateTask.setVariable("isFirstEnterFirstApproval", false); - - // 自动完成任务(流程继续向下) - taskService.complete(delegateTask.getId()); - } - // 若为退回进入(isReturned=true),则不执行自动完成,等待手动处理 - } -} \ No newline at end of file diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/start/FirstTaskParamValueListener.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/start/FirstTaskParamValueListener.java new file mode 100644 index 0000000..585122d --- /dev/null +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/start/FirstTaskParamValueListener.java @@ -0,0 +1,86 @@ +package com.zteits.urbanops.module.workorder.service.garden.listener.start; + +import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.ExecutionListener; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl; +import org.flowable.task.service.delegate.DelegateTask; +import org.springframework.stereotype.Component; + +/** + * 类描述:任务启动初始化属性值的监听类 + * 创建人:yanhuiqing + * 创建时间:2025/12/19 11:42 + * 修改人:yanhuiqing + * 修改时间:2025/12/19 11:42 + * 修改备注: + * + * @author yanhuiqing + * @version 1.0 + */ +@Slf4j +@Component("firstTaskParamValueListener") // 组件名,供流程设计器调用 +public class FirstTaskParamValueListener implements ExecutionListener { + + + @Override + public void notify(DelegateExecution execution) { + + // ========== 幂等性标记(核心:按流程实例+节点ID命名,避免冲突) ========== + String flagKey = "listener_executed_" + execution.getProcessInstanceId() + "_ylInspectorStart"; + if (Boolean.TRUE.equals(getBooleanVariable(execution, flagKey))) { + log.info("监听器已执行,跳过:{}", execution.getId()); + return; + } + + log.info("===== 监听器触发 ====="); + log.info("执行实例ID:{}", execution.getId()); + log.info("父执行实例ID:{}", execution.getParentId()); + log.info("当前活动ID:{}", execution.getCurrentActivityId()); + log.info("流程实例ID:{}", execution.getProcessInstanceId()); + log.info("流程实例ID:{}", execution.getProcessInstanceId()); + log.info("流程事件名称:{}", execution.getEventName()); + ; + log.info("触发时的流程变量:isFirstEnter={}",execution.getVariable("isFirstEnterFirstApproval")); + String targetActivityId = "ylInspectorStart"; + if (!targetActivityId.equals(execution.getCurrentActivityId())) { + log.info("非目标节点,跳过监听器逻辑"); + return; + } + ExecutionEntityImpl parent = (ExecutionEntityImpl) execution.getParent(); + String starterId = parent.getStartUserId(); + + Boolean isFirstEnter = getBooleanVariable(execution, "isFirstEnterFirstApproval"); + + //第一个节点的指派人 + Long assigneeId = (Long) execution.getVariable("applyUserId"); + if (Boolean.TRUE.equals(isFirstEnter) + && starterId != null && starterId.equals(Long.toString(assigneeId))) { + // 标记:首次进入跳过 + execution.setVariable("skipFirstApproval", true); + //首次进入改为false + execution.setVariable("isFirstEnterFirstApproval", "false"); + + }else{ + execution.setVariable("skipFirstApproval", false); + + } + // ========== 标记为已执行 ========== + execution.setVariable(flagKey, true); + + } + + private Boolean getBooleanVariable(DelegateExecution delegateTask, String variableName) { + Object variable = delegateTask.getVariable(variableName); + if (variable == null) { + return false; + } + if (variable instanceof Boolean) { + return (Boolean) variable; + } + if (variable instanceof String) { + return Boolean.parseBoolean((String) variable); + } + return false; + } +} \ No newline at end of file diff --git a/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/start/StartInitParamValueListener.java b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/start/StartInitParamValueListener.java new file mode 100644 index 0000000..830045d --- /dev/null +++ b/urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/start/StartInitParamValueListener.java @@ -0,0 +1,37 @@ +package com.zteits.urbanops.module.workorder.service.garden.listener.start; + +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.ExecutionListener; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl; +import org.springframework.stereotype.Component; + +/** + * 类描述:任务启动初始化属性值的监听类 + * 创建人:yanhuiqing + * 创建时间:2025/12/19 11:42 + * 修改人:yanhuiqing + * 修改时间:2025/12/19 11:42 + * 修改备注: + * + * @author yanhuiqing + * @version 1.0 + */ +@Component("startInitParamValueListener") // 组件名,供流程设计器调用 +public class StartInitParamValueListener implements ExecutionListener { + + + @Override + public void notify(DelegateExecution execution) { + + ExecutionEntityImpl parent = (ExecutionEntityImpl) execution.getParent(); + String starterId = parent.getStartUserId(); + execution.setVariable("starterId",starterId); + + + + Boolean isFirstEnter = (Boolean) execution.getVariable("isFirstEnterFirstApproval"); // 是否首次进入 + if(null == isFirstEnter){ + execution.setVariable("isFirstEnterFirstApproval","true"); + } + } +} \ No newline at end of file