Commit d9a34189135c919e3e1379f92ad98abd80b38b1f

Authored by wangqian
2 parents 11aace07 5c844e25

Merge remote-tracking branch 'origin/dev' into dev

Showing 22 changed files with 666 additions and 282 deletions
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;
16 16 @Data
17 17 public class AppGardenWorkOrderRespVO extends MainInfoRespVO {
18 18  
19   - @Schema(description = "问题图片", example = "9184")
20   - private List<String> problemImgsList;
21   -
22   - @Schema(description = "处理完成照片", example = "9184")
23   - private List<String> completeImgsList;
24   -
25 19 @Schema(description = "任务id")
26 20 private String taskId;
27 21  
... ... @@ -42,4 +36,22 @@ public class AppGardenWorkOrderRespVO extends MainInfoRespVO {
42 36  
43 37 @Schema(description = "流程定义key")
44 38 private String key_;
  39 +
  40 + @Schema(description = "开始的问题拍照图片")
  41 + private List<String> problemsImgs;
  42 +
  43 + @Schema(description = "实施开始的拍照图片")
  44 + private List<String> startImgs;
  45 +
  46 + @Schema(description = "实施中的拍照图片")
  47 + private List<String> processingImgs;
  48 +
  49 + @Schema(description = "实施结束的拍照图片")
  50 + private List<String> endImgs;
  51 +
  52 + @Schema(description = "实施人员的拍照图片")
  53 + private List<String> personImgs;
  54 +
  55 + @Schema(description = "实施耗材的拍照图片")
  56 + private List<String> materialImgs;
45 57 }
... ...
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/api/constant/BpmCommonConstant.java
... ... @@ -15,6 +15,11 @@ public class BpmCommonConstant {
15 15 * 园林巡检工单 流程业务key
16 16 */
17 17 public static final String BPM_GARDEN_INSPECT_WO = "garden_inspect_wo";
  18 +
  19 + /**
  20 + * 园林巡检工单 通用版本
  21 + */
  22 + public static final String BPM_WORKORDER_COMMON_PROD = "workorder_common_prod";
18 23 /**
19 24 * 物业巡检工单 流程业务key
20 25 */
... ... @@ -23,22 +28,36 @@ public class BpmCommonConstant {
23 28 * 市政巡检工单 流程业务key
24 29 */
25 30 public static final String BPM_MUNICIPAL_INSPECT_WO = "municipal_inspect_wo";
26   - /**
  31 + /** 01 问题图片,02 开始图片,03 进行中图片,04 已完成图片,05 人员图片:06 材料图片
  32 + * problemsImgs,startImgs,processingImgs,endImgs,personImgs,materialImgs
27 33 * 园林问题单处理前图片描述
28 34 */
29 35 public static final String PROBLEM_IMG_GROUP = "01";
30 36 /**
31   - * 园林问题单处理中图片类型
  37 + * 园林工单开始图片类型
  38 + */
  39 + public static final String START_IMG_GROUP = "02";
  40 + /**
  41 + * 园林工单进行中图片类型
  42 + */
  43 + public static final String PROCESS_IMG_GROUP = "03";
  44 +
  45 + /**
  46 + * 园林工单结束图片类型
  47 + */
  48 + public static final String END_IMG_GROUP = "04";
  49 + /**
  50 + * 园林工单人员图片类型
32 51 */
33   - public static final String HANDLE_IMG_GROUP = "02";
  52 + public static final String PERSON_IMG_GROUP = "05";
34 53 /**
35   - * 园林处理结果图片类型
  54 + * 园林工单耗材图片类型
36 55 */
37   - public static final String RESULT_IMG_GROUP = "03";
  56 + public static final String MATERIAL_IMG_GROUP = "06";
38 57 /**
39 58 * 园林工作流 组长退回的附件照片
40 59 */
41   - public static final String GARDEN_TEAMLEADER_RETURN_IMG = "04";
  60 + public static final String GARDEN_TEAMLEADER_RETURN_IMG = "09";
42 61 /**
43 62 * 园林工单编号前缀
44 63 */
... ...
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;
3 3 import com.zteits.urbanops.framework.common.pojo.CommonResult;
4 4 import com.zteits.urbanops.framework.common.pojo.PageResult;
5 5 import com.zteits.urbanops.framework.common.util.object.BeanUtils;
  6 +import com.zteits.urbanops.framework.common.util.object.ObjectUtils;
6 7 import com.zteits.urbanops.framework.security.core.util.SecurityFrameworkUtils;
7 8 import com.zteits.urbanops.module.garden.api.road.RoadApi;
8 9 import com.zteits.urbanops.module.garden.dto.road.RoadReqDTO;
9 10 import com.zteits.urbanops.module.garden.dto.road.RoadRespDTO;
10 11 import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO;
11 12 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.*;
  13 +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.common.AppUniversalApprovalReqVO;
12 14 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.common.UserInfoPageReqVO;
  15 +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskRejectExtReqVO;
13 16 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskReturnExtReqVO;
14 17 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskTeamLeaderAssignReqVO;
15 18 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.*;
19 22 import com.zteits.urbanops.module.workorder.dal.dataobject.garden.BpmGardenWorkOrderDO;
20 23 import com.zteits.urbanops.module.workorder.dto.AppGardenWorkOrderReqVO;
21 24 import com.zteits.urbanops.module.workorder.dto.AppGardenWorkOrderRespVO;
  25 +import com.zteits.urbanops.module.workorder.enums.OperateTypeEnum;
22 26 import com.zteits.urbanops.module.workorder.service.garden.BpmGardenService;
23 27 import io.swagger.v3.oas.annotations.Operation;
24 28 import io.swagger.v3.oas.annotations.Parameter;
25 29 import io.swagger.v3.oas.annotations.tags.Tag;
26 30 import jakarta.annotation.Resource;
27 31 import jakarta.validation.Valid;
  32 +import lombok.extern.slf4j.Slf4j;
28 33 import org.springframework.web.bind.annotation.*;
29 34  
30 35 import java.util.List;
31 36  
  37 +import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception;
32 38 import static com.zteits.urbanops.framework.common.pojo.CommonResult.success;
33 39 import static com.zteits.urbanops.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  40 +import static com.zteits.urbanops.module.workorder.enums.ErrorCodeConstants.*;
34 41  
35 42 /**
36 43 * @author yanhuiqing
... ... @@ -40,6 +47,7 @@ import static com.zteits.urbanops.framework.security.core.util.SecurityFramework
40 47 */
41 48 @Tag(name = "APP - 园林工单bpm")
42 49 @RestController
  50 +@Slf4j
43 51 @RequestMapping("/bpm/garden/workorder")
44 52 public class AppGardenWorkOrderController {
45 53 @Resource
... ... @@ -160,6 +168,13 @@ public class AppGardenWorkOrderController {
160 168 gardenService.returnPreviousNode(reqVO);
161 169 return success(true);
162 170 }
  171 + @PutMapping("/reject")
  172 + @Operation(summary = "app - 不通过任务-驳回")
  173 + //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:update')")
  174 + public CommonResult<Boolean> rejectTask(@Valid @RequestBody AppGardenTaskRejectExtReqVO reqVO) {
  175 + gardenService.rejectTask(reqVO);
  176 + return success(true);
  177 + }
163 178  
164 179 @PutMapping("/withdraw")
165 180 @Operation(summary = "app - 撤回任务")
... ... @@ -230,4 +245,124 @@ public class AppGardenWorkOrderController {
230 245 PageResult<AdminUserRespDTO> pageResult = gardenService.getUserByLoginIdAndRoleCode(pageVO, SecurityFrameworkUtils.getLoginUserId(),pageVO.getRoleCode(),pageVO.getBusiLine(),pageVO.isNotHas());
231 246 return success(pageResult);
232 247 }
  248 +
  249 + @Operation(summary = "app-统一审批入口")
  250 + @PostMapping("/universalApproval")
  251 + //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:update')")
  252 + public CommonResult<Boolean> universalApproval(@Valid @RequestBody AppUniversalApprovalReqVO reqVO) {
  253 +
  254 + log.info("【园林统一审批】接收前端请求,入参:curTaskKey={}, taskId={}, operateType={}, agree={}, reason={}",
  255 + reqVO.getTaskKey(), reqVO.getTaskId(), reqVO.getOperateType(), reqVO.getAgree(), reqVO.getReason());
  256 +
  257 + OperateTypeEnum operateType = OperateTypeEnum.getByCode(reqVO.getOperateType());
  258 +
  259 + switch (operateType) {
  260 + case YL_WORKER_RETURN:// 养护员退回
  261 + log.info("当前操作:"+OperateTypeEnum.YL_WORKER_RETURN.getDesc()+"开始,操作类型:"+OperateTypeEnum.YL_WORKER_RETURN.getCode()+"-->");
  262 + AppGardenTaskReturnExtReqVO retReqVO = new AppGardenTaskReturnExtReqVO();
  263 + retReqVO.setId(reqVO.getTaskId());
  264 + retReqVO.setCurTaskKey(reqVO.getTaskKey());
  265 + retReqVO.setReason(reqVO.getReason());
  266 + retReqVO.setWorkerDataId(reqVO.getWorkerDataId());
  267 + retReqVO.setReturnImgs(reqVO.getReturnImgs());
  268 + this.returnPreviousNode(retReqVO);
  269 + log.info("当前操作:"+OperateTypeEnum.YL_WORKER_RETURN.getDesc()+"<--结束");
  270 + return success(true);
  271 + case YL_WORKER_IMPLEMENT://养护员实施
  272 + log.info("当前操作:"+OperateTypeEnum.YL_WORKER_IMPLEMENT.getDesc()+"开始,操作类型:"+OperateTypeEnum.YL_WORKER_RETURN.getCode()+"-->");
  273 + AppGardenTaskWorkerExcuteReqVO workerExcuteReqVO = new AppGardenTaskWorkerExcuteReqVO();
  274 + workerExcuteReqVO.setWorkerDataId(reqVO.getWorkerDataId());
  275 + workerExcuteReqVO.setId(reqVO.getTaskId());
  276 + workerExcuteReqVO.setCoHandlers(reqVO.getCoHandlers());
  277 + workerExcuteReqVO.setHandleResult(reqVO.getHandleResult());
  278 + workerExcuteReqVO.setProblemsImgs(reqVO.getProblemsImgs());
  279 + workerExcuteReqVO.setStartImgs(reqVO.getStartImgs());
  280 + workerExcuteReqVO.setProcessingImgs(reqVO.getProcessingImgs());
  281 + workerExcuteReqVO.setEndImgs(reqVO.getEndImgs());
  282 + workerExcuteReqVO.setPersonImgs(reqVO.getPersonImgs());
  283 + workerExcuteReqVO.setMaterialImgs(reqVO.getMaterialImgs());
  284 + this.ylWorkerExcuteWOrder(workerExcuteReqVO);
  285 + log.info("当前操作:"+OperateTypeEnum.YL_WORKER_IMPLEMENT.getDesc()+"<--结束");
  286 + return success(true);
  287 + case YL_TEAM_LEADER_CONFIRM_PASS://养护组长验收通过
  288 + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_CONFIRM_PASS.getDesc()+"开始,操作类型:"+OperateTypeEnum.YL_WORKER_RETURN.getCode()+"-->");
  289 + AppGardenTaskApproveReqVO approveReqVO = new AppGardenTaskApproveReqVO();
  290 + approveReqVO.setReason(reqVO.getReason());
  291 + approveReqVO.setId(reqVO.getTaskId());
  292 + this.approveTask(approveReqVO);
  293 + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_CONFIRM_PASS.getDesc()+"<--结束");
  294 + return success(true);
  295 + case YL_TEAM_LEADER_CONFIRM_REJECT://养护组长验收不通过
  296 + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_CONFIRM_REJECT.getDesc()+"开始,操作类型:"+OperateTypeEnum.YL_WORKER_RETURN.getCode()+"-->");
  297 + AppGardenTaskReturnExtReqVO rejReqVO = new AppGardenTaskReturnExtReqVO();
  298 + rejReqVO.setId(reqVO.getTaskId());
  299 + rejReqVO.setCurTaskKey(reqVO.getTaskKey());
  300 + rejReqVO.setReason(reqVO.getReason());
  301 + rejReqVO.setWorkerDataId(reqVO.getWorkerDataId());
  302 + rejReqVO.setReturnImgs(reqVO.getReturnImgs());
  303 + this.returnPreviousNode(rejReqVO);
  304 + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_CONFIRM_REJECT.getDesc()+"<--结束");
  305 + return success(true);
  306 + case YL_TEAM_LEADER_ASSIGN: //养护组长分配
  307 + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_ASSIGN.getDesc()+"开始,操作类型:"+OperateTypeEnum.YL_WORKER_RETURN.getCode()+"-->");
  308 + AppGardenTaskTeamLeaderAssignReqVO assignReqVO = new AppGardenTaskTeamLeaderAssignReqVO();
  309 + assignReqVO.setId(reqVO.getTaskId());
  310 + assignReqVO.setReason(reqVO.getReason());
  311 + Long userId = reqVO.getNextAssignee();
  312 + if(!ObjectUtils.isNotAllEmpty(userId)){
  313 + throw exception(APP_WORKER_NOT_EXISTS);
  314 + }
  315 + assignReqVO.setNextAssignee(reqVO.getNextAssignee());
  316 + Integer status = reqVO.getAgree();
  317 + if (status == null || (status != 0 && status != 1)) {
  318 + throw exception(APP_AGREE_CHOOSE);
  319 + }
  320 + assignReqVO.setAgree(status);
  321 + this.ylTeamLeaderAssignWOrder(assignReqVO);
  322 + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_ASSIGN.getDesc()+"<--结束");
  323 + return success(true);
  324 +
  325 + case YL_TEAM_LEADER_RETURN://养护组长退回
  326 + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_RETURN.getDesc()+"开始,操作类型:"+OperateTypeEnum.YL_WORKER_RETURN.getCode()+"-->");
  327 + AppGardenTaskApproveReqVO returnApproveReqVO = new AppGardenTaskApproveReqVO();
  328 + Integer approveStatus = reqVO.getAgree();
  329 + if (approveStatus == null || (approveStatus != 0 && approveStatus != 1)) {
  330 + throw exception(APP_AGREE_CHOOSE);
  331 + }
  332 + returnApproveReqVO.setAgree(approveStatus);
  333 + returnApproveReqVO.setReason(reqVO.getReason());
  334 + returnApproveReqVO.setId(reqVO.getTaskId());
  335 + this.approveTask(returnApproveReqVO);
  336 + log.info("当前操作:"+OperateTypeEnum.YL_TEAM_LEADER_RETURN.getDesc()+"<--结束");
  337 + return success(true);
  338 + case YL_INSPECTOR_START_FINISH , YL_INSPECTOR_START_RELAUNCH : //巡查员结束工单,巡查员重新发起
  339 + log.info("当前操作:养护组长结束工单(不同意)或巡查员重新发起(同意)开始,是否同意:"+reqVO.getAgree()+"-->");
  340 + AppGardenTaskApproveReqVO inspectStartReqVO = new AppGardenTaskApproveReqVO();
  341 + Integer revokeStatus = reqVO.getAgree();
  342 + if (revokeStatus == null || (revokeStatus != 0 && revokeStatus != 1)) {
  343 + throw exception(APP_AGREE_CHOOSE);
  344 + }
  345 + inspectStartReqVO.setAgree(revokeStatus);
  346 + inspectStartReqVO.setReason(reqVO.getReason());
  347 + inspectStartReqVO.setId(reqVO.getTaskId());
  348 + this.approveTask(inspectStartReqVO);
  349 + log.info("当前操作:"+OperateTypeEnum.YL_INSPECTOR_START_FINISH.getDesc()+"<--结束");
  350 + return success(true);
  351 + case YL_INSPECTOR_CHECK_PASS , YL_INSPECTOR_CHECK_REJECT ://巡查员验收通过,巡查员验收不通过
  352 + log.info("当前操作:巡查员验收通过 或巡查员验收不通过开始,是否同意:"+reqVO.getAgree()+"-->");
  353 + AppGardenTaskApproveReqVO inspectReqVO = new AppGardenTaskApproveReqVO();
  354 + Integer verifyStatus = reqVO.getAgree();
  355 + if (verifyStatus == null || (verifyStatus != 0 && verifyStatus != 1)) {
  356 + throw exception(APP_AGREE_CHOOSE);
  357 + }
  358 + inspectReqVO.setAgree(verifyStatus);
  359 + inspectReqVO.setReason(reqVO.getReason());
  360 + inspectReqVO.setId(reqVO.getTaskId());
  361 + this.approveTask(inspectReqVO);
  362 + log.info("当前操作:"+OperateTypeEnum.YL_INSPECTOR_START_FINISH.getDesc()+"<--结束");
  363 + return success(true);
  364 + default:
  365 + throw exception(APP_OPERATOR_NOT_EXISTS);
  366 + }
  367 + }
233 368 }
... ...
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/common/AppUniversalApprovalReqVO.java 0 → 100644
  1 +package com.zteits.urbanops.module.workorder.controller.app.garden.vo.common;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotEmpty;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +import java.util.List;
  8 +import java.util.Set;
  9 +
  10 +/**
  11 + * 类描述:app端统一工作流审批入口
  12 + * 创建人:yanhuiqing
  13 + * 创建时间:2025/12/20 10:26
  14 + * 修改人:yanhuiqing
  15 + * 修改时间:2025/12/20 10:26
  16 + * 修改备注:优化字段类型,添加业务扩展参数,增加验证分组
  17 + *
  18 + * @author yanhuiqing
  19 + * @version 1.0
  20 + */
  21 +@Schema(description = "APP - 园林统一审批 通用Request VO")
  22 +@Data
  23 +public class AppUniversalApprovalReqVO {
  24 + // -------------------------- 基础通用参数(所有操作必填) --------------------------
  25 + @Schema(description = "当前任务的taskKey", requiredMode = Schema.RequiredMode.REQUIRED, example = "ylTeamLeader")
  26 + @NotEmpty(message = "当前任务的taskKey不能为空")
  27 + private String taskKey;
  28 +
  29 + @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1234567890")
  30 + @NotEmpty(message = "任务编号不能为空")
  31 + private String taskId;
  32 +
  33 + @Schema(description = "操作类型(210:养护组长退回,110:养护组长分配,200:巡查员结束工单,100:巡查员重新发起,220:养护员退回,120:养护员实施,130:养护组长验收通过,230:养护组长验收不通过,140:巡查员验收通过,240:巡查员验收不通过)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  34 + @NotNull(message = "操作类型不能为空")
  35 + private Integer operateType; // 原String改为Integer,适配数字类型
  36 +
  37 + @Schema(description = "同意选择类型:0 同意,1 不同意", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  38 + //@NotNull(message = "同意选择类型不能为空")
  39 + private Integer agree;
  40 +
  41 + @Schema(description = "操作理由(审批/退回理由)", requiredMode = Schema.RequiredMode.REQUIRED, example = "同意该工单处理结果")
  42 + //@NotEmpty(message = "操作理由不能为空")
  43 + private String reason;
  44 +
  45 + @Schema(description = "工单的数据id", requiredMode = Schema.RequiredMode.REQUIRED)
  46 + //@NotEmpty(message = "工单的数据id不能为空")
  47 + private Long workerDataId;
  48 +
  49 + @Schema(description = "退回时的拍照图片")
  50 + private List<String> returnImgs;
  51 + // -------------------------- 退回操作专属参数(分组:ReturnGroup) --------------------------
  52 +
  53 + // -------------------------- 养护组长分配专属参数(分组:AssignMaintainerGroup) --------------------------
  54 + @Schema(description = "养护员用户ID(养护组长分配操作必填)", example = "user1001")
  55 + //@NotEmpty(message = "养护员用户ID不能为空", groups = AssignMaintainerGroup.class)
  56 + private Long nextAssignee;
  57 +
  58 + // -------------------------- 养护员实施专属参数(分组:MaintainerImplementGroup) --------------------------
  59 + @Schema(description = "共同处理人用户ID列表", example = "[111,222]")
  60 + private Set<Long> coHandlers;
  61 +
  62 + @Schema(description = "处理意见(养护员实施操作必填)", example = "已完成绿植修剪,效果符合要求")
  63 + //@NotEmpty(message = "处理意见不能为空", groups = MaintainerImplementGroup.class)
  64 + private String handleResult;
  65 +
  66 + @Schema(description = "开始的问题拍照图片")
  67 + private List<String> problemsImgs;
  68 +
  69 + @Schema(description = "实施开始的拍照图片")
  70 + private List<String> startImgs;
  71 +
  72 + @Schema(description = "实施中的拍照图片")
  73 + private List<String> processingImgs;
  74 +
  75 + @Schema(description = "实施结束的拍照图片")
  76 + private List<String> endImgs;
  77 +
  78 + @Schema(description = "实施人员的拍照图片")
  79 + private List<String> personImgs;
  80 +
  81 + @Schema(description = "实施耗材的拍照图片")
  82 + private List<String> materialImgs;
  83 +}
0 84 \ No newline at end of file
... ...
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/operator/AppGardenTaskRejectExtReqVO.java 0 → 100644
  1 +package com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotEmpty;
  5 +import lombok.Data;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * 类描述:园林app端拒绝任务的reqVO
  11 + * 创建人:yanhuiqing
  12 + * 创建时间:2025/12/19 10:55
  13 + * 修改人:yanhuiqing
  14 + * 修改时间:2025/12/19 10:55
  15 + * 修改备注:
  16 + *
  17 + * @author yanhuiqing
  18 + * @version 1.0
  19 + */
  20 +@Schema(description = "APP - 驳回的流程任务的 Request VO")
  21 +@Data
  22 +public class AppGardenTaskRejectExtReqVO {
  23 +
  24 + @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  25 + @NotEmpty(message = "任务编号不能为空")
  26 + private String id;
  27 +
  28 + @Schema(description = "退回意见", requiredMode = Schema.RequiredMode.REQUIRED, example = "我就是想驳回")
  29 + @NotEmpty(message = "退回意见不能为空")
  30 + private String reason;
  31 +
  32 + @Schema(description = "工单的数据id", requiredMode = Schema.RequiredMode.REQUIRED)
  33 + //@NotEmpty(message = "工单的数据id不能为空")
  34 + private Long workerDataId;
  35 +
  36 + @Schema(description = "退回时的拍照图片")
  37 + private List<String> returnImgs;
  38 +
  39 +}
0 40 \ No newline at end of file
... ...
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 {
29 29 @Schema(description = "养护员userId")
30 30 @NotNull(message = "养护员不能为空")
31 31 private Long nextAssignee;
  32 +
  33 + @Schema(description = "同意选择类型:0 同意,1 不同意", example = "0")
  34 + //@NotNull(message = "同意选择类型不能为空")
  35 + private Integer agree;
32 36 }
33 37 \ No newline at end of file
... ...
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 {
41 41 @Schema(description = "开始的问题拍照图片")
42 42 private List<String> problemsImgs;
43 43  
  44 + @Schema(description = "实施开始的拍照图片")
  45 + private List<String> startImgs;
  46 +
44 47 @Schema(description = "实施中的拍照图片")
45   - private List<String> handingImgs;
  48 + private List<String> processingImgs;
46 49  
47 50 @Schema(description = "实施结束的拍照图片")
48   - private List<String> handledImgs;
  51 + private List<String> endImgs;
  52 +
  53 + @Schema(description = "实施人员的拍照图片")
  54 + private List<String> personImgs;
  55 +
  56 + @Schema(description = "实施耗材的拍照图片")
  57 + private List<String> materialImgs;
49 58 }
50 59 \ No newline at end of file
... ...
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 {
29 29 @Schema(description = "审批意见", example = "通过!")
30 30 private String reason;
31 31  
  32 + @Schema(description = "同意选择类型:0 同意,1 不同意", example = "0")
  33 + //@NotNull(message = "同意选择类型不能为空")
  34 + private Integer agree;
  35 +
32 36 }
33 37 \ No newline at end of file
... ...
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/convert/garden/AppGardenTaskConvert.java
... ... @@ -142,14 +142,44 @@ public interface AppGardenTaskConvert {
142 142 source.getOrderNo(),
143 143 attachmentMapper
144 144 );
145   - List<String> completeImgsList = queryAttachment(
  145 + List<String> startImgsList = queryAttachment(
146 146 source.getBusiLine(),
147   - BpmCommonConstant.RESULT_IMG_GROUP,
  147 + BpmCommonConstant.START_IMG_GROUP,
148 148 source.getOrderNo(),
149 149 attachmentMapper
150 150 );
151   - target.setProblemImgsList(problemImgsList);
152   - target.setCompleteImgsList(completeImgsList);
  151 + List<String> processImgsList = queryAttachment(
  152 + source.getBusiLine(),
  153 + BpmCommonConstant.PROCESS_IMG_GROUP,
  154 + source.getOrderNo(),
  155 + attachmentMapper
  156 + );
  157 +
  158 + List<String> endImgsList = queryAttachment(
  159 + source.getBusiLine(),
  160 + BpmCommonConstant.END_IMG_GROUP,
  161 + source.getOrderNo(),
  162 + attachmentMapper
  163 + );
  164 + List<String> personImgsList = queryAttachment(
  165 + source.getBusiLine(),
  166 + BpmCommonConstant.PERSON_IMG_GROUP,
  167 + source.getOrderNo(),
  168 + attachmentMapper
  169 + );
  170 +
  171 + List<String> matirialImgsList = queryAttachment(
  172 + source.getBusiLine(),
  173 + BpmCommonConstant.MATERIAL_IMG_GROUP,
  174 + source.getOrderNo(),
  175 + attachmentMapper
  176 + );
  177 + target.setProblemsImgs(problemImgsList);
  178 + target.setStartImgs(startImgsList);
  179 + target.setProcessingImgs(processImgsList);
  180 + target.setEndImgs(endImgsList);
  181 + target.setPersonImgs(personImgsList);
  182 + target.setMaterialImgs(matirialImgsList);
153 183  
154 184 return target;
155 185 }
... ...
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/convert/garden/BpmGardenWorkOrderConverter.java
... ... @@ -53,7 +53,7 @@ public class BpmGardenWorkOrderConverter {
53 53 );
54 54 List<String> completeImgsList = queryAttachment(
55 55 source.getBusiLine(),
56   - BpmCommonConstant.RESULT_IMG_GROUP,
  56 + BpmCommonConstant.PROCESS_IMG_GROUP,
57 57 source.getOrderNo(),
58 58 attachmentMapper
59 59 );
... ...
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&lt;MainInfoDO&gt; {
36 36 "SELECT",
37 37 " m.*,",
38 38 " t.ID_ AS task_id,",
39   - " t.NAME_ AS task_name,",
40   - " t.task_def_key_ as task_key,",
  39 + /*"t.NAME_ AS task_name,",
  40 + "t.task_def_key_ AS task_key,",*/
  41 + " '' AS task_name,",
  42 + " '' AS task_key,",
41 43 " pd.NAME_ AS process_definition_name,",
42 44 " t.START_TIME_,",
43 45 " t.END_TIME_,",
... ... @@ -249,8 +251,10 @@ public interface MainInfoExtMapper extends BaseMapperX&lt;MainInfoDO&gt; {
249 251 "SELECT",
250 252 "m.*,",
251 253 "t.ID_ AS task_id,",
252   - "t.NAME_ AS task_name,",
253   - "t.task_def_key_ AS task_key,",
  254 + /*"t.NAME_ AS task_name,",
  255 + "t.task_def_key_ AS task_key,",*/
  256 + "'' AS task_name,",
  257 + "'' AS task_key,",
254 258 "pd.NAME_ AS process_definition_name,",
255 259 "t.START_TIME_ ,",
256 260 "t.END_TIME_,",
... ...
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/AgreeTypeEnum.java 0 → 100644
  1 +package com.zteits.urbanops.module.workorder.enums;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonValue;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 类描述:同意类型枚举(0:同意,1:不同意)
  11 + * 创建人:yanhuiqing
  12 + * 创建时间:2025/12/20 12:00
  13 + * 修改人:yanhuiqing
  14 + * 修改时间:2025/12/20 12:00
  15 + * 修改备注:
  16 + *
  17 + * @author yanhuiqing
  18 + * @version 1.0
  19 + */
  20 +@Schema(description = "同意类型枚举")
  21 +@Getter
  22 +public enum AgreeTypeEnum {
  23 + AGREE(0, "同意"),
  24 + DISAGREE(1, "不同意");
  25 +
  26 + @JsonValue // 序列化时返回code(前端接收数字)
  27 + private final Integer code;
  28 + private final String desc;
  29 +
  30 + AgreeTypeEnum(Integer code, String desc) {
  31 + this.code = code;
  32 + this.desc = desc;
  33 + }
  34 +
  35 + // 根据code获取枚举(业务层转换用)
  36 + public static AgreeTypeEnum getByCode(Integer code) {
  37 + return Arrays.stream(values())
  38 + .filter(e -> e.getCode().equals(code))
  39 + .findFirst()
  40 + .orElseThrow(() -> new IllegalArgumentException("无效的同意类型:" + code));
  41 + }
  42 +}
0 43 \ No newline at end of file
... ...
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/ErrorCodeConstants.java
... ... @@ -18,4 +18,10 @@ public interface ErrorCodeConstants {
18 18 ErrorCode MATERIAL_DETAIL_NOT_EXISTS = new ErrorCode(1-900-001-002, "工单耗材明细不存在");
19 19  
20 20 ErrorCode TEAM_LEADER_YL_NOT_EXISTS = new ErrorCode(1-900-001-003, "养护班组长人员不存在");
  21 +
  22 + ErrorCode APP_AGREE_CHOOSE = new ErrorCode(1-900-001-004, "agree状态只能为0或1");
  23 +
  24 + ErrorCode APP_OPERATOR_NOT_EXISTS = new ErrorCode(1-900-001-004, "无此操作类型!");
  25 +
  26 + ErrorCode APP_WORKER_NOT_EXISTS = new ErrorCode(1-900-001-004, "养护员必须指派,不能为空!");
21 27 }
... ...
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/enums/OperateTypeEnum.java 0 → 100644
  1 +package com.zteits.urbanops.module.workorder.enums;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonValue;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Getter;
  6 +import java.util.Arrays;
  7 +/**
  8 + * 类描述:园林审批操作类型枚举(对应业务1-12的操作类型)
  9 + * 创建人:yanhuiqing
  10 + * 创建时间:2025/12/20 12:01
  11 + * 修改人:yanhuiqing
  12 + * 修改时间:2025/12/20 12:01
  13 + * 修改备注:
  14 + *
  15 + * @author yanhuiqing
  16 + * @version 1.0
  17 + */
  18 +@Schema(description = "园林审批操作类型枚举")
  19 +@Getter
  20 +public enum OperateTypeEnum {
  21 + YL_TEAM_LEADER_ASSIGN(110, "养护组长分配"),
  22 + YL_TEAM_LEADER_RETURN(210, "养护组长退回"),
  23 + YL_WORKER_IMPLEMENT(120, "养护员实施"),
  24 + YL_WORKER_RETURN(220, "养护员退回"),
  25 + YL_TEAM_LEADER_CONFIRM_PASS(130, "养护组长验收通过"),
  26 + YL_TEAM_LEADER_CONFIRM_REJECT(230, "养护组长验收不通过"),
  27 + YL_INSPECTOR_CHECK_PASS(140, "巡查员验收通过"),
  28 + YL_INSPECTOR_CHECK_REJECT(240, "巡查员验收不通过"),
  29 + YL_INSPECTOR_START_FINISH(200, "巡查员结束工单(不同意)"),
  30 + YL_INSPECTOR_START_RELAUNCH(100, "巡查员重新发起(同意)");
  31 +
  32 + @JsonValue // 序列化时返回code(前端接收数字)
  33 + private final Integer code;
  34 + private final String desc;
  35 +
  36 + OperateTypeEnum(Integer code, String desc) {
  37 + this.code = code;
  38 + this.desc = desc;
  39 + }
  40 +
  41 + // 根据code获取枚举(业务层转换用)
  42 + public static OperateTypeEnum getByCode(Integer code) {
  43 + return Arrays.stream(values())
  44 + .filter(e -> e.getCode().equals(code))
  45 + .findFirst()
  46 + .orElseThrow(() -> new IllegalArgumentException("无效的操作类型:" + code));
  47 + }
  48 +}
0 49 \ No newline at end of file
... ...
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;
3 3 import com.zteits.urbanops.framework.common.pojo.PageParam;
4 4 import com.zteits.urbanops.framework.common.pojo.PageResult;
5 5 import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO;
  6 +import com.zteits.urbanops.module.workorder.controller.admin.garden.vo.BpmGardenWorkOrderCreateReqVO;
6 7 import com.zteits.urbanops.module.workorder.controller.admin.garden.vo.BpmGardenWorkOrderPageReqVO;
7   -import com.zteits.urbanops.module.workorder.controller.app.garden.vo.AppGardenWorkOrderPageReqVO;
  8 +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.*;
  9 +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskRejectExtReqVO;
8 10 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskReturnExtReqVO;
9 11 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskTeamLeaderAssignReqVO;
10 12 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskWorkerExcuteReqVO;
... ... @@ -114,6 +116,12 @@ public interface BpmGardenService {
114 116 void returnPreviousNode(AppGardenTaskReturnExtReqVO reqVO);
115 117  
116 118 /**
  119 + * 驳回任务 -app端
  120 + * @param reqVO
  121 + */
  122 + void rejectTask(AppGardenTaskRejectExtReqVO reqVO);
  123 +
  124 + /**
117 125 * 撤回任务 -app端
118 126 * @param taskId
119 127 */
... ...
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;
27 27 import com.zteits.urbanops.module.workorder.controller.admin.garden.vo.BpmGardenWorkOrderPageReqVO;
28 28 import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInfoHasTaskPageReqVO;
29 29 import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInfoPageReqVO;
30   -import com.zteits.urbanops.module.workorder.controller.app.garden.vo.*;
  30 +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.AppGardenWorkOrderPageReqVO;
  31 +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskRejectExtReqVO;
31 32 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskReturnExtReqVO;
32 33 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.operator.AppGardenTaskTeamLeaderAssignReqVO;
33 34 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
66 67 import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception;
67 68 import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception0;
68 69 import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertSet;
69   -import static com.zteits.urbanops.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
70 70 import static com.zteits.urbanops.module.workorder.enums.ErrorCodeConstants.MAIN_INFO_NOT_EXISTS;
71 71 import static com.zteits.urbanops.module.workorder.enums.ErrorCodeConstants.TEAM_LEADER_YL_NOT_EXISTS;
72 72  
... ... @@ -146,9 +146,6 @@ public class BpmGardenServiceImpl implements BpmGardenService{
146 146 attachmentApend(imgList,null,longRangeImgList,workOrder);
147 147 // 发起 BPM 流程
148 148 Map<String, Object> processInstanceVariables = new HashMap<>();
149   - //processInstanceVariables.put("workOrder", workOrder);
150   - //processInstanceVariables.put("imgList", imgList);
151   - //processInstanceVariables.put("longRangeImgList", longRangeImgList);
152 149 processInstanceVariables.put("initiator", SecurityFrameworkUtils.getLoginUserId());
153 150  
154 151 String processInstanceId = processInstanceApi.createProcessInstance(SecurityFrameworkUtils.getLoginUserId(),
... ... @@ -181,6 +178,16 @@ public class BpmGardenServiceImpl implements BpmGardenService{
181 178 Map<String, Object> variables = new HashMap<>();
182 179 //审批通过
183 180 variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,BpmTaskStatusEnum.APPROVE.getStatus());
  181 + Integer status = reqVO.getAgree();
  182 + if(status == null || status == 1){//status == null 此处是为了兼容老接口,防止前段少改造
  183 + variables.put("isNeed",false);
  184 + variables.put("isRevoke",false);
  185 + variables.put("isVerify",false);
  186 + }else {
  187 + variables.put("isNeed",true);
  188 + variables.put("isRevoke",true);
  189 + variables.put("isVerify",true);
  190 + }
184 191 targetVO.setVariables(variables);
185 192 //TODO 审批候选人需要赋值
186 193 Map<String, List<Long>> nextAssignees = new HashMap<>();
... ... @@ -195,6 +202,12 @@ public class BpmGardenServiceImpl implements BpmGardenService{
195 202 //审批通过
196 203 variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,BpmTaskStatusEnum.APPROVE.getStatus());
197 204 variables.put("ylWorkerId",reqVO.getNextAssignee());
  205 + Integer status = reqVO.getAgree();
  206 + if(status == null || status == 0){//status == null 此处是为了兼容老接口,防止前段少改造
  207 + variables.put("isNeed",true);
  208 + }else {
  209 + variables.put("isNeed",false);
  210 + }
198 211 targetVO.setVariables(variables);
199 212 Map<String, List<Long>> nextAssignees = new HashMap<>();
200 213 targetVO.setNextAssignees(nextAssignees);
... ... @@ -212,22 +225,35 @@ public class BpmGardenServiceImpl implements BpmGardenService{
212 225 targetVO.setVariables(variables);
213 226  
214 227 Long id = reqVO.getWorkerDataId();
215   - List<String> handingImgs = reqVO.getHandingImgs();
216   - List<String> handledImgs = reqVO.getHandledImgs();
217 228 List<String> problemsImgs = reqVO.getProblemsImgs();
  229 + List<String> startImgs = reqVO.getStartImgs();
  230 + List<String> processingImgs = reqVO.getProcessingImgs();
  231 + List<String> endImgs = reqVO.getEndImgs();
  232 + List<String> personImgs = reqVO.getPersonImgs();
  233 + List<String> materialImgs = reqVO.getMaterialImgs();
218 234 MainInfoDO workerOrder = workOrderMapper.selectById(id);
219 235 workerOrder.setHandleResult(reqVO.getHandleResult());
220 236 workerOrder.setCoHandlers(reqVO.getCoHandlers());
221 237 workOrderMapper.updateById(workerOrder);
222 238  
223 239 if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(problemsImgs) && problemsImgs.size()>0){
224   - attachmentInsertOrUpdate(problemsImgs,BpmCommonConstant.HANDLE_IMG_GROUP,workerOrder);
  240 + attachmentInsertOrUpdate(problemsImgs,BpmCommonConstant.PROBLEM_IMG_GROUP,workerOrder);
  241 + }
  242 + if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(startImgs) && startImgs.size()>0){
  243 + attachmentInsertOrUpdate(startImgs,BpmCommonConstant.START_IMG_GROUP,workerOrder);
  244 + }
  245 + if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(processingImgs) && processingImgs.size()>0){
  246 + attachmentInsertOrUpdate(processingImgs,BpmCommonConstant.PROCESS_IMG_GROUP,workerOrder);
  247 + }
  248 +
  249 + if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(endImgs) && endImgs.size()>0){
  250 + attachmentInsertOrUpdate(endImgs,BpmCommonConstant.END_IMG_GROUP,workerOrder);
225 251 }
226   - if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(handingImgs) && handingImgs.size()>0){
227   - attachmentInsertOrUpdate(handingImgs,BpmCommonConstant.HANDLE_IMG_GROUP,workerOrder);
  252 + if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(personImgs) && personImgs.size()>0){
  253 + attachmentInsertOrUpdate(personImgs,BpmCommonConstant.PERSON_IMG_GROUP,workerOrder);
228 254 }
229   - if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(handledImgs) && handledImgs.size()>0){
230   - attachmentInsertOrUpdate(handledImgs,BpmCommonConstant.RESULT_IMG_GROUP,workerOrder);
  255 + if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(materialImgs) && materialImgs.size()>0){
  256 + attachmentInsertOrUpdate(materialImgs,BpmCommonConstant.MATERIAL_IMG_GROUP,workerOrder);
231 257 }
232 258 taskService.approveTask(SecurityFrameworkUtils.getLoginUserId(),targetVO);
233 259  
... ... @@ -245,9 +271,21 @@ public class BpmGardenServiceImpl implements BpmGardenService{
245 271 @Transactional(rollbackFor = Exception.class)
246 272 public void returnPreviousNode(AppGardenTaskReturnExtReqVO reqVO) {
247 273 BpmTaskReturnReqVO targetVO = BeanUtils.toBean(reqVO,BpmTaskReturnReqVO.class);
248   - targetVO.setTargetTaskDefinitionKey(TaskNodeUtils.getPreviousNodeName(reqVO.getCurTaskKey()));
  274 + String currentTaskey = reqVO.getCurTaskKey();
  275 + targetVO.setTargetTaskDefinitionKey(TaskNodeUtils.getPreviousNodeName(currentTaskey));
249 276 Long userId = SecurityFrameworkUtils.getLoginUserId();
250 277 taskService.returnTask(userId, targetVO);
  278 +
  279 + /*if(TaskNodeEnum.YL_TEAM_LEADER.getNodeName().equals(currentTaskey)){
  280 + Task task = taskService.getTask(reqVO.getId());
  281 + String processInstanceId = task.getProcessInstanceId();
  282 +
  283 + Map<String, Object> variables = new HashMap<>();
  284 + variables.put("isReturnedToFirstApproval", true);
  285 + variables.put("isFirstEnterFirstApproval", false);
  286 + // 更新流程实例级别变量
  287 + runtimeService.setVariables(processInstanceId, variables);
  288 + }*/
251 289 Long id = reqVO.getWorkerDataId();
252 290 List<String> returnImgs = reqVO.getReturnImgs();
253 291 if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(returnImgs) && returnImgs.size()>0){
... ... @@ -258,6 +296,20 @@ public class BpmGardenServiceImpl implements BpmGardenService{
258 296 }
259 297  
260 298 @Override
  299 + @Transactional(rollbackFor = Exception.class)
  300 + public void rejectTask(AppGardenTaskRejectExtReqVO reqVO) {
  301 + BpmTaskRejectReqVO targetVO = BeanUtils.toBean(reqVO,BpmTaskRejectReqVO.class);
  302 + Long userId = SecurityFrameworkUtils.getLoginUserId();
  303 + taskService.rejectTask(userId, targetVO);
  304 + Long id = reqVO.getWorkerDataId();
  305 + List<String> returnImgs = reqVO.getReturnImgs();
  306 + if(ObjectUtils.isNotAllEmpty(id) && ObjectUtils.isNotAllEmpty(returnImgs) && returnImgs.size()>0){
  307 + MainInfoDO workerOrder = workOrderMapper.selectById(id);
  308 + attachmentInsertOrUpdate(returnImgs,BpmCommonConstant.GARDEN_TEAMLEADER_RETURN_IMG,workerOrder);
  309 + }
  310 + }
  311 +
  312 + @Override
261 313 public void withdrawTask(String taskId) {
262 314 Long userId = SecurityFrameworkUtils.getLoginUserId();
263 315 taskService.withdrawTask(userId,taskId);
... ... @@ -355,7 +407,7 @@ public class BpmGardenServiceImpl implements BpmGardenService{
355 407 }
356 408 taskBuzReqVO.setUserId(SecurityFrameworkUtils.getLoginUserId());
357 409 //TODO 先写死
358   - taskBuzReqVO.setKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO);
  410 + //taskBuzReqVO.setKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO);
359 411 PageResult<MainInfoExtDO> pageResult = workOrderExtMapper.selectWorkOrderMyPage(pageVO,taskBuzReqVO);
360 412 return AppGardenTaskConvert.INSTANCE.buildBuziTaskPage(pageResult,attachmentMapper);
361 413 }
... ... @@ -388,7 +440,7 @@ public class BpmGardenServiceImpl implements BpmGardenService{
388 440 }
389 441 taskBuzReqVO.setUserId(SecurityFrameworkUtils.getLoginUserId());
390 442 //TODO 先写死
391   - taskBuzReqVO.setKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO);
  443 + //taskBuzReqVO.setKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO);
392 444 PageResult<MainInfoExtDO> pageResult = workOrderExtMapper.selectWorkOrderDonePage(pageVO,taskBuzReqVO);
393 445 return AppGardenTaskConvert.INSTANCE.buildBuziTaskPage(pageResult,attachmentMapper);
394 446 }
... ... @@ -422,7 +474,7 @@ public class BpmGardenServiceImpl implements BpmGardenService{
422 474 }
423 475 taskBuzReqVO.setUserId(SecurityFrameworkUtils.getLoginUserId());
424 476 //TODO 先写死
425   - taskBuzReqVO.setKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO);
  477 + //taskBuzReqVO.setKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO);
426 478 PageResult<MainInfoExtDO> pageResult = workOrderExtMapper.selectWorkOrderTodoPage(pageVO,taskBuzReqVO);
427 479  
428 480 return AppGardenTaskConvert.INSTANCE.buildBuziTaskPage(pageResult,attachmentMapper);
... ... @@ -514,10 +566,10 @@ public class BpmGardenServiceImpl implements BpmGardenService{
514 566 .map(AdminUserRespDTO::getId)
515 567 // 收集结果到List
516 568 .collect(Collectors.toList());
517   - //startUserSelectAssignees.put("",idList);
518 569 processInstanceVariables.put("ylTeamLeaderId", idList.get(0));
519 570 String processInstanceId = processInstanceApi.createProcessInstance(userId,
520   - new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO)
  571 + // new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(BpmCommonConstant.BPM_GARDEN_INSPECT_WO)
  572 + new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(BpmCommonConstant.BPM_WORKORDER_COMMON_PROD)
521 573 .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(workOrder.getId()))
522 574 .setStartUserSelectAssignees(startUserSelectAssignees));
523 575  
... ... @@ -576,13 +628,13 @@ public class BpmGardenServiceImpl implements BpmGardenService{
576 628 if(ObjectUtils.isNotAllEmpty(streetImgList)){
577 629 AttachmentDO saveDO = new AttachmentDO();
578 630 saveDO.setBusiLine(workOrder.getBusiLine());
579   - saveDO.setBusiType(BpmCommonConstant.HANDLE_IMG_GROUP);
  631 + saveDO.setBusiType(BpmCommonConstant.START_IMG_GROUP);
580 632 saveDO.setOrderNo(workOrder.getOrderNo());
581 633 String filePaths = String.join(",",streetImgList);
582 634 saveDO.setFileNames(filePaths);
583 635 LambdaQueryWrapper<AttachmentDO> deleteWrapper = new LambdaQueryWrapper<AttachmentDO>()
584 636 .eq(AttachmentDO::getBusiLine, workOrder.getBusiLine())
585   - .eq(AttachmentDO::getBusiType, BpmCommonConstant.HANDLE_IMG_GROUP)
  637 + .eq(AttachmentDO::getBusiType, BpmCommonConstant.START_IMG_GROUP)
586 638 .eq(AttachmentDO::getOrderNo, workOrder.getOrderNo());
587 639 attachmentMapper.delete(deleteWrapper);
588 640 attachmentMapper.insert(saveDO);
... ... @@ -591,13 +643,13 @@ public class BpmGardenServiceImpl implements BpmGardenService{
591 643 if(ObjectUtils.isNotAllEmpty(longRangeImgList)){
592 644 AttachmentDO saveDO = new AttachmentDO();
593 645 saveDO.setBusiLine(workOrder.getBusiLine());
594   - saveDO.setBusiType(BpmCommonConstant.RESULT_IMG_GROUP);
  646 + saveDO.setBusiType(BpmCommonConstant.PROCESS_IMG_GROUP);
595 647 saveDO.setOrderNo(workOrder.getOrderNo());
596 648 String filePaths = String.join(",",longRangeImgList);
597 649 saveDO.setFileNames(filePaths);
598 650 LambdaQueryWrapper<AttachmentDO> deleteWrapper = new LambdaQueryWrapper<AttachmentDO>()
599 651 .eq(AttachmentDO::getBusiLine, workOrder.getBusiLine())
600   - .eq(AttachmentDO::getBusiType, BpmCommonConstant.RESULT_IMG_GROUP)
  652 + .eq(AttachmentDO::getBusiType, BpmCommonConstant.PROCESS_IMG_GROUP)
601 653 .eq(AttachmentDO::getOrderNo, workOrder.getOrderNo());
602 654 attachmentMapper.delete(deleteWrapper);
603 655 attachmentMapper.insert(saveDO);
... ...
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/AutoCompleteTaskListener.java deleted
1   -package com.zteits.urbanops.module.workorder.service.garden.listener;
2   -
3   -import cn.hutool.core.util.StrUtil;
4   -import jakarta.annotation.Resource;
5   -import org.flowable.engine.HistoryService;
6   -import org.flowable.engine.ProcessEngine;
7   -import org.flowable.engine.RuntimeService;
8   -import org.flowable.engine.TaskService;
9   -import org.flowable.engine.delegate.TaskListener; // 配套的TaskListener也用核心包
10   -import org.flowable.task.api.Task;
11   -import org.flowable.task.api.history.HistoricTaskInstanceQuery;
12   -import org.flowable.task.service.delegate.DelegateTask;
13   -import org.springframework.context.ApplicationContext;
14   -import org.springframework.stereotype.Component;
15   -
16   -import java.util.HashMap;
17   -import java.util.Map;
18   -
19   -/**
20   - * 自动完成任务的监听器(最终版:适配项目实际包路径 + 移除所有报错依赖)
21   - * Bean名称:autoCompleteTaskListener(与BPMN中的delegateExpression对应)
22   - */
23   -@Component("autoCompleteTaskListener")
24   -public class AutoCompleteTaskListener implements TaskListener {
25   -
26   - // ========== 仅使用Flowable核心公开API,移除所有内部/拆分接口 ==========
27   - @Resource // 若项目习惯用@Autowired,可直接替换(@Resource按名称,@Autowired按类型,功能一致)
28   - private TaskService taskService;
29   -
30   - @Resource
31   - private RuntimeService runtimeService;
32   -
33   - // 核心:直接注入ProcessEngine(兼容所有Flowable版本,可获取任意服务)
34   - @Resource
35   - private ProcessEngine processEngine;
36   -
37   - @Resource
38   - private ApplicationContext applicationContext;
39   -
40   - // 统一流程状态值(与RuoYi的事件监听器预期值一致)
41   - private static final String FLOW_STATUS = "3"; // 对应“完成”状态
42   -
43   - @Override
44   - public void notify(DelegateTask delegateTask) { // 此处DelegateTask为核心包的类,与项目一致
45   - try {
46   - // 1. 获取核心变量
47   - String taskId = delegateTask.getId();
48   - String processInstanceId = delegateTask.getProcessInstanceId();
49   - String assignee = delegateTask.getAssignee();
50   -
51   - // 兜底:从流程变量获取发起人(initiator是Flowable启动节点的发起人变量)
52   - if (StrUtil.isBlank(assignee)) {
53   - assignee = (String) delegateTask.getVariable("initiator");
54   - if (StrUtil.isBlank(assignee)) {
55   - assignee = (String) runtimeService.getVariable(processInstanceId, "initiator");
56   - if (StrUtil.isBlank(assignee)) {
57   - throw new RuntimeException("发起人ID为空,无法完成任务");
58   - }
59   - }
60   - // 修正:使用Flowable公开API更新办理人(彻底放弃内部类操作,无类型转换)
61   - taskService.setAssignee(taskId, assignee);
62   - }
63   -
64   - // 2. 关键:提前设置所有层级的status变量(解决RuoYi事件status为空)
65   - runtimeService.setVariable(processInstanceId, "status", FLOW_STATUS); // 流程全局变量
66   - delegateTask.setVariable("status", FLOW_STATUS); // 任务局部变量
67   - Map<String, Object> variables = new HashMap<>();
68   - variables.put("status", FLOW_STATUS);
69   - variables.put("completeRemark", "系统自动完成,办理人:" + assignee);
70   -
71   - // 3. 完成任务(Flowable核心API,兼容所有版本)
72   - Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
73   - if (task != null) {
74   - taskService.complete(taskId, variables);
75   - }
76   -
77   - // 4. 兜底:确保历史任务归档(使用ProcessEngine获取HistoryService,无报错)
78   - ensureHistoricTaskCompleted(taskId, assignee);
79   -
80   - // 5. 手动发布事件补充status(解决RuoYi的事件校验问题)
81   - publishProcessEventWithStatus(processInstanceId);
82   -
83   - } catch (Exception e) {
84   - throw new RuntimeException("自动完成任务失败", e);
85   - }
86   - }
87   -
88   - /**
89   - * 修正:使用ProcessEngine获取HistoryService(兼容所有Flowable版本,无报错)
90   - * 彻底移除HistoryTaskService,改用核心HistoryService
91   - */
92   - private void ensureHistoricTaskCompleted(String taskId, String assignee) {
93   - // 核心:从ProcessEngine获取HistoryService(Flowable 6.x/7.0通用)
94   - HistoryService historyService = processEngine.getHistoryService();
95   - // 历史任务查询(Flowable核心API,无报错)
96   - //HistoricTaskInstanceQuery historicTask = historyService.createHistoricTaskInstanceQuery()
97   - // .taskId(taskId)
98   - // .singleResult();
99   -
100   - /*if (historicTask != null) {
101   - if (historicTask.getEndTime() == null) {
102   - Task runtimeTask = taskService.createTaskQuery().taskId(taskId).singleResult();
103   - if (runtimeTask != null) {
104   - taskService.complete(taskId);
105   - } else {
106   - // 手动更新历史任务表(通过MyBatis操作,避免Flowable API差异)
107   - // updateHistoricTask(taskId, assignee); // 若需要,自行实现Mapper
108   - }
109   - }
110   - }*/
111   - }
112   -
113   - /**
114   - * 手动发布包含status的流程事件(适配RuoYi事件类,避免导入依赖)
115   - */
116   - private void publishProcessEventWithStatus(String processInstanceId) {
117   - try {
118   - // 反射创建RuoYi的ProcessInstanceResultEvent(兼容无参/有参构造)
119   - Class<?> eventClass = Class.forName("com.ruoyi.flowable.event.ProcessInstanceResultEvent");
120   - Object event = null;
121   -
122   - // 先尝试无参构造
123   - try {
124   - event = eventClass.getDeclaredConstructor().newInstance();
125   - } catch (Exception e) {
126   - // 无参失败,尝试单参构造(流程实例ID)
127   - try {
128   - event = eventClass.getConstructor(String.class).newInstance(processInstanceId);
129   - } catch (Exception e2) {
130   - // 单参失败,尝试双参构造(流程实例ID + status)
131   - event = eventClass.getConstructor(String.class, String.class).newInstance(processInstanceId, FLOW_STATUS);
132   - }
133   - }
134   -
135   - // 强制设置status属性(无论构造方式如何)
136   - eventClass.getMethod("setStatus", String.class).invoke(event, FLOW_STATUS);
137   - eventClass.getMethod("setProcessInstanceId", String.class).invoke(event, processInstanceId);
138   -
139   - // 发布事件(覆盖RuoYi的空status事件)
140   - applicationContext.publishEvent(event);
141   - } catch (Exception e) {
142   - // 反射失败时,提示用户修改RuoYi的事件校验逻辑(应急方案)
143   - e.printStackTrace();
144   - System.out.println("★★★反射发布事件失败,请手动修改RuoYi的ProcessInstanceResultEvent校验逻辑,添加status默认值★★★");
145   - }
146   - }
147   -
148   - // 若需要手动更新历史任务表,自行实现以下方法(需添加MyBatis Mapper)
149   - // private void updateHistoricTask(String taskId, String assignee) {
150   - // // historicTaskMapper.updateHistoricTask(taskId, assignee, new Date());
151   - // }
152   -}
153 0 \ No newline at end of file
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/BpmGardenWorkOrderStatusListener.java deleted
1   -package com.zteits.urbanops.module.workorder.service.garden.listener;
2   -
3   -import com.zteits.urbanops.module.bpm.api.event.BpmProcessInstanceStatusEvent;
4   -import com.zteits.urbanops.module.bpm.api.event.BpmProcessInstanceStatusEventListener;
5   -import com.zteits.urbanops.module.workorder.api.constant.BpmCommonConstant;
6   -import com.zteits.urbanops.module.workorder.service.garden.BpmGardenService;
7   -import jakarta.annotation.Resource;
8   -import org.springframework.stereotype.Component;
9   -
10   -/**
11   - * @author yanhuiqing
12   - * @version 1.0
13   - * @description: 工作流状态监听类
14   - * @date 2025/12/1 11:45
15   - */
16   -@Component
17   -public class BpmGardenWorkOrderStatusListener extends BpmProcessInstanceStatusEventListener {
18   - @Resource
19   - private BpmGardenService gardenService;
20   - @Override
21   - protected String getProcessDefinitionKey() {
22   -
23   - return BpmCommonConstant.BPM_GARDEN_INSPECT_WO;
24   - }
25   -
26   - @Override
27   - protected void onEvent(BpmProcessInstanceStatusEvent event) {
28   - gardenService.updateWorkOrderStatus(Long.parseLong(event.getBusinessKey()), event.getStatus());
29   - }
30   -}
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
22 22 @Override
23 23 protected String getProcessDefinitionKey() {
24 24  
25   - return BpmCommonConstant.BPM_GARDEN_INSPECT_WO;
  25 + //return BpmCommonConstant.BPM_GARDEN_INSPECT_WO;
  26 + return BpmCommonConstant.BPM_WORKORDER_COMMON_PROD;
26 27 }
27 28  
28 29 @Override
... ...
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/FirstApprovalAutoCompleteListener.java deleted
1   -package com.zteits.urbanops.module.workorder.service.garden.listener;
2   -
3   -/**
4   - * 类描述:第一次跳过审批,第二次手动审批
5   - * 创建人:yanhuiqing
6   - * 创建时间:2025/12/18 20:28
7   - * 修改人:yanhuiqing
8   - * 修改时间:2025/12/18 20:28
9   - * 修改备注:
10   - *
11   - * @author yanhuiqing
12   - * @version 1.0
13   - */
14   -import org.flowable.engine.TaskService;
15   -import org.flowable.engine.delegate.TaskListener;
16   -import org.flowable.task.service.delegate.DelegateTask;
17   -import org.springframework.beans.factory.annotation.Autowired;
18   -import org.springframework.stereotype.Component;
19   -
20   -/**
21   - * 初审节点自动通过监听器
22   - */
23   -@Component("firstApprovalAutoCompleteListener") // 组件名,供流程设计器调用
24   -public class FirstApprovalAutoCompleteListener implements TaskListener {
25   -
26   - // 注入Flowable的TaskService,用于完成任务
27   - @Autowired
28   - private TaskService taskService;
29   -
30   - @Override
31   - public void notify(DelegateTask delegateTask) {
32   - // 1. 获取流程变量
33   - String starterId = (String) delegateTask.getVariable("starterId"); // 发起人ID
34   - Boolean isFirstEnter = (Boolean) delegateTask.getVariable("isFirstEnterFirstApproval"); // 是否首次进入
35   - Boolean isReturned = (Boolean) delegateTask.getVariable("isReturnedToFirstApproval"); // 是否退回
36   -
37   - // 2. 获取当前审批节点的审批人ID
38   - String assigneeId = delegateTask.getAssignee();
39   -
40   - // 3. 核心逻辑:首次进入 + 发起人=审批人 → 自动完成任务
41   - if (isFirstEnter != null && isFirstEnter
42   - && !Boolean.TRUE.equals(isReturned)
43   - && starterId != null && starterId.equals(assigneeId)) {
44   -
45   - // 标记:首次进入已处理,后续不再触发自动通过
46   - delegateTask.setVariable("isFirstEnterFirstApproval", false);
47   -
48   - // 自动完成任务(流程继续向下)
49   - taskService.complete(delegateTask.getId());
50   - }
51   - // 若为退回进入(isReturned=true),则不执行自动完成,等待手动处理
52   - }
53   -}
54 0 \ No newline at end of file
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/start/FirstTaskParamValueListener.java 0 → 100644
  1 +package com.zteits.urbanops.module.workorder.service.garden.listener.start;
  2 +
  3 +import lombok.extern.slf4j.Slf4j;
  4 +import org.flowable.engine.delegate.DelegateExecution;
  5 +import org.flowable.engine.delegate.ExecutionListener;
  6 +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
  7 +import org.flowable.task.service.delegate.DelegateTask;
  8 +import org.springframework.stereotype.Component;
  9 +
  10 +/**
  11 + * 类描述:任务启动初始化属性值的监听类
  12 + * 创建人:yanhuiqing
  13 + * 创建时间:2025/12/19 11:42
  14 + * 修改人:yanhuiqing
  15 + * 修改时间:2025/12/19 11:42
  16 + * 修改备注:
  17 + *
  18 + * @author yanhuiqing
  19 + * @version 1.0
  20 + */
  21 +@Slf4j
  22 +@Component("firstTaskParamValueListener") // 组件名,供流程设计器调用
  23 +public class FirstTaskParamValueListener implements ExecutionListener {
  24 +
  25 +
  26 + @Override
  27 + public void notify(DelegateExecution execution) {
  28 +
  29 + // ========== 幂等性标记(核心:按流程实例+节点ID命名,避免冲突) ==========
  30 + String flagKey = "listener_executed_" + execution.getProcessInstanceId() + "_ylInspectorStart";
  31 + if (Boolean.TRUE.equals(getBooleanVariable(execution, flagKey))) {
  32 + log.info("监听器已执行,跳过:{}", execution.getId());
  33 + return;
  34 + }
  35 +
  36 + log.info("===== 监听器触发 =====");
  37 + log.info("执行实例ID:{}", execution.getId());
  38 + log.info("父执行实例ID:{}", execution.getParentId());
  39 + log.info("当前活动ID:{}", execution.getCurrentActivityId());
  40 + log.info("流程实例ID:{}", execution.getProcessInstanceId());
  41 + log.info("流程实例ID:{}", execution.getProcessInstanceId());
  42 + log.info("流程事件名称:{}", execution.getEventName());
  43 + ;
  44 + log.info("触发时的流程变量:isFirstEnter={}",execution.getVariable("isFirstEnterFirstApproval"));
  45 + String targetActivityId = "ylInspectorStart";
  46 + if (!targetActivityId.equals(execution.getCurrentActivityId())) {
  47 + log.info("非目标节点,跳过监听器逻辑");
  48 + return;
  49 + }
  50 + ExecutionEntityImpl parent = (ExecutionEntityImpl) execution.getParent();
  51 + String starterId = parent.getStartUserId();
  52 +
  53 + Boolean isFirstEnter = getBooleanVariable(execution, "isFirstEnterFirstApproval");
  54 +
  55 + //第一个节点的指派人
  56 + Long assigneeId = (Long) execution.getVariable("applyUserId");
  57 + if (Boolean.TRUE.equals(isFirstEnter)
  58 + && starterId != null && starterId.equals(Long.toString(assigneeId))) {
  59 + // 标记:首次进入跳过
  60 + execution.setVariable("skipFirstApproval", true);
  61 + //首次进入改为false
  62 + execution.setVariable("isFirstEnterFirstApproval", "false");
  63 +
  64 + }else{
  65 + execution.setVariable("skipFirstApproval", false);
  66 +
  67 + }
  68 + // ========== 标记为已执行 ==========
  69 + execution.setVariable(flagKey, true);
  70 +
  71 + }
  72 +
  73 + private Boolean getBooleanVariable(DelegateExecution delegateTask, String variableName) {
  74 + Object variable = delegateTask.getVariable(variableName);
  75 + if (variable == null) {
  76 + return false;
  77 + }
  78 + if (variable instanceof Boolean) {
  79 + return (Boolean) variable;
  80 + }
  81 + if (variable instanceof String) {
  82 + return Boolean.parseBoolean((String) variable);
  83 + }
  84 + return false;
  85 + }
  86 +}
0 87 \ No newline at end of file
... ...
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/start/StartInitParamValueListener.java 0 → 100644
  1 +package com.zteits.urbanops.module.workorder.service.garden.listener.start;
  2 +
  3 +import org.flowable.engine.delegate.DelegateExecution;
  4 +import org.flowable.engine.delegate.ExecutionListener;
  5 +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +/**
  9 + * 类描述:任务启动初始化属性值的监听类
  10 + * 创建人:yanhuiqing
  11 + * 创建时间:2025/12/19 11:42
  12 + * 修改人:yanhuiqing
  13 + * 修改时间:2025/12/19 11:42
  14 + * 修改备注:
  15 + *
  16 + * @author yanhuiqing
  17 + * @version 1.0
  18 + */
  19 +@Component("startInitParamValueListener") // 组件名,供流程设计器调用
  20 +public class StartInitParamValueListener implements ExecutionListener {
  21 +
  22 +
  23 + @Override
  24 + public void notify(DelegateExecution execution) {
  25 +
  26 + ExecutionEntityImpl parent = (ExecutionEntityImpl) execution.getParent();
  27 + String starterId = parent.getStartUserId();
  28 + execution.setVariable("starterId",starterId);
  29 +
  30 +
  31 +
  32 + Boolean isFirstEnter = (Boolean) execution.getVariable("isFirstEnterFirstApproval"); // 是否首次进入
  33 + if(null == isFirstEnter){
  34 + execution.setVariable("isFirstEnterFirstApproval","true");
  35 + }
  36 + }
  37 +}
0 38 \ No newline at end of file
... ...