.gitignore
@@ -58,3 +58,6 @@ .claude/settings.local.json .claude/worktrees/ .claude/scheduled_tasks.json graphify-out/ .agents/ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java
@@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackQuickCreateRespVO; import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackRespVO; import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackSaveReqVO; import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackSubmitReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; @@ -176,10 +177,9 @@ @PutMapping("/submit") @Operation(summary = "æäº¤æ¥å·¥") @Parameter(name = "id", description = "ç¼å·", required = true) @PreAuthorize("@ss.hasPermission('mes:pro-feedback:update')") public CommonResult<Boolean> submitFeedback(@RequestParam("id") Long id) { feedbackService.submitFeedback(id); public CommonResult<Boolean> submitFeedback(@Valid @RequestBody MesProFeedbackSubmitReqVO reqVO) { feedbackService.submitFeedback(reqVO); return success(true); } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackRespVO.java
@@ -169,4 +169,12 @@ @ExcelProperty("å建æ¶é´") private LocalDateTime createTime; @Schema(description = "BPM æµç¨å®ä¾ç¼å·") @ExcelProperty("BPM æµç¨å®ä¾ç¼å·") private String processInstanceId; @Schema(description = "BPM æµç¨å®ä¹ Key") @ExcelProperty("BPM æµç¨å®ä¹ Key") private String processDefinitionKey; } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackSaveReqVO.java
@@ -87,4 +87,10 @@ @Schema(description = "夿³¨", example = "夿³¨") private String remark; @Schema(description = "BPM æµç¨å®ä¾ç¼å·") private String processInstanceId; @Schema(description = "BPM æµç¨å®ä¹ Key") private String processDefinitionKey; } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackSubmitReqVO.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,50 @@ package cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import lombok.Data; import java.time.LocalDateTime; @Schema(description = "管çåå° - MES ç产æ¥å·¥æäº¤ Request VO") @Data public class MesProFeedbackSubmitReqVO { @Schema(description = "æ¥å·¥åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") @NotNull(message = "æ¥å·¥åIDä¸è½ä¸ºç©º") private Long id; @Schema(description = "çäº§æ¥æ") private LocalDateTime produceDate; @Schema(description = "è¿ææ¥æ") private LocalDateTime expireDate; @Schema(description = "å ¥åºæ¥æ") private LocalDateTime receiptDate; @Schema(description = "ä¾åºåID") private Long vendorId; @Schema(description = "客æ·ID") private Long clientId; @Schema(description = "éè´è®¢åç¼å·") private String purchaseOrderCode; @Schema(description = "éå®è®¢åç¼å·") private String salesOrderCode; @Schema(description = "å·¥å ·ID") private Long toolId; @Schema(description = "æ¨¡å ·ID") private Long moldId; @Schema(description = "ç产æ¹å·") private String lotNumber; @Schema(description = "è´¨éç¶æ") private Integer qualityStatus; } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/task/vo/MesProTaskRespVO.java
@@ -140,4 +140,6 @@ @Schema(description = "æå®æ¥å·¥äººåå§åéå") private List<String> assigneeUserNames; @Schema(description = "æ¯å¦æ¥å·¥å®¡æ¹") private Boolean feedbackApprove; } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/MesProWorkOrderController.java
@@ -113,6 +113,13 @@ return success(new PageResult<>(buildWorkOrderRespVOList(pageResult.getList()), pageResult.getTotal())); } @GetMapping("/approve-process-list") @Operation(summary = "è·åå®¡æ¹æ¥å·¥çæµç¨å®ä¹å表") @PreAuthorize("@ss.hasPermission('mes:pro-work-order:query')") public CommonResult<List<Map<String, Object>>> getWorkOrderApproveProcessDefinitionList() { return success(workOrderService.getWorkOrderApproveProcessDefinitionList()); } @GetMapping("/schedule-page") @Operation(summary = "è·å¾ç产工åè°åº¦ç¶æå页") @PreAuthorize("@ss.hasPermission('mes:pro-work-order:query')") yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/MesProWorkOrderRespVO.java
@@ -145,4 +145,16 @@ @ExcelProperty("çäº§ç¶æ") private Integer productionStatus; @Schema(description = "æ¯å¦æ¥å·¥å®¡æ¹") @ExcelProperty("æ¯å¦æ¥å·¥å®¡æ¹") private Boolean feedbackApprove; @Schema(description = "BPM æµç¨å®ä¹ Key") @ExcelProperty("BPM æµç¨å®ä¹ Key") private String processDefinitionKey; @Schema(description = "æ¥å·¥è§è² (å¤ä¸ªè§è²éå·åé)") @ExcelProperty("æ¥å·¥è§è²") private String feedbackRole; } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/MesProWorkOrderSaveReqVO.java
@@ -70,4 +70,13 @@ @Schema(description = "夿³¨", example = "夿³¨") private String remark; @Schema(description = "æ¯å¦æ¥å·¥å®¡æ¹") private Boolean feedbackApprove; @Schema(description = "BPM æµç¨å®ä¹ Key") private String processDefinitionKey; @Schema(description = "æ¥å·¥è§è² (å¤ä¸ªè§è²éå·åé)") private String feedbackRole; } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/feedback/MesProFeedbackDO.java
@@ -160,4 +160,14 @@ */ private String remark; /** * BPM æµç¨å®ä¾ç¼å· */ private String processInstanceId; /** * BPM æµç¨å®ä¹ Key */ private String processDefinitionKey; } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/workorder/MesProWorkOrderDO.java
@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.math.BigDecimal; @@ -148,4 +149,21 @@ */ private String remark; /** * æ¯å¦æ¥å·¥å®¡æ¹ */ @com.baomidou.mybatisplus.annotation.TableField("is_feedback_approve") private Boolean feedbackApprove; /** * BPM æµç¨å®ä¹ Key */ private String processDefinitionKey; /** * æ¥å·¥è§è² (å¤ä¸ªè§è²éå·åé) */ private String feedbackRole; } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -39,6 +39,7 @@ ErrorCode MD_ITEM_BATCH_CONFIG_NOT_EXISTS = new ErrorCode(1_040_102_100, "ç©ææ¹æ¬¡å±æ§é ç½®ä¸åå¨"); ErrorCode MD_ITEM_BATCH_CONFIG_AT_LEAST_ONE_FLAG = new ErrorCode(1_040_102_101, "æ¹æ¬¡ç®¡çå·²å¯ç¨ï¼è³å°éè¦é ç½®ä¸ä¸ªæ¹æ¬¡å±æ§"); ErrorCode MD_ITEM_PRODUCT_BOM_REQUIRED = new ErrorCode(1_040_102_102, "产åç±»ç©æå¯ç¨åï¼å¿ é¡»é ç½®è³å°ä¸ä¸ª BOM ç»æ"); ErrorCode MD_ITEM_BATCH_CONFIG_AT_LEAST_ONE_APPROVE_FLAG = new ErrorCode(1_040_102_103, "éè¦é ç½®ä¸ä¸ªæ¹æ¬¡å±æ§,请å¨å®¡æ¹æè§ä¸å¡«å"); // ========== MES ä»åºç®¡ç-æ¹æ¬¡ç®¡çï¼1-040-717-000ï¼ ========== ErrorCode WM_BATCH_PRODUCE_DATE_REQUIRED = new ErrorCode(1_040_717_000, "æ¹æ¬¡é ç½®è¦æ±çäº§æ¥æä¸è½ä¸ºç©º"); yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/common/bpm/MesBpmProcessService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,19 @@ package cn.iocoder.yudao.module.mes.service.common.bpm; import java.util.List; import java.util.Map; /** * MES 模åçéç¨ BPM æµç¨å¤ç Service æ¥å£ */ public interface MesBpmProcessService { /** * è·åæå®åç±»ä¸çæ¿æ´»ç¶æãææ°çæ¬çæµç¨å®ä¹å表 * * @param categoryCode æµç¨åç±»ç¼ç * @return æµç¨å®ä¹å表ï¼å å« id, key, name */ List<Map<String, Object>> getApproveProcessDefinitionList(String categoryCode); } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/common/bpm/MesBpmProcessServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,71 @@ package cn.iocoder.yudao.module.mes.service.common.bpm; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.repository.ProcessDefinition; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import java.util.*; /** * MES 模åçéç¨ BPM æµç¨å¤ç Service å®ç°ç±» */ @Service @Validated @Slf4j public class MesBpmProcessServiceImpl implements MesBpmProcessService { @Resource private BpmCategoryService bpmCategoryService; @Resource private BpmProcessDefinitionService bpmProcessDefinitionService; @Override public List<Map<String, Object>> getApproveProcessDefinitionList(String categoryCode) { // 1. æ ¡éªåç±»æ¯å¦åå¨ List<BpmCategoryDO> categories = bpmCategoryService.getCategoryListByCode( Collections.singletonList(categoryCode)); if (CollUtil.isEmpty(categories)) { log.warn("[getApproveProcessDefinitionList] BPM æµç¨åç±» {} ä¸åå¨", categoryCode); return Collections.emptyList(); } // 2. è·ååç±»ä¸çæµç¨å®ä¹ä¿¡æ¯ List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService .getProcessDefinitionInfoListByCategory(categoryCode); if (CollUtil.isEmpty(definitionInfoList)) { return Collections.emptyList(); } // 3. è¿æ»¤æ¿æ´»ç¶æï¼ä¿çææ°çæ¬ Map<String, ProcessDefinition> latestVersionMap = new HashMap<>(); for (BpmProcessDefinitionInfoDO info : definitionInfoList) { ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId()); if (pd == null || pd.isSuspended()) { continue; } ProcessDefinition existing = latestVersionMap.get(pd.getKey()); if (existing == null || pd.getVersion() > existing.getVersion()) { latestVersionMap.put(pd.getKey(), pd); } } // 4. è¿åæµç¨å®ä¹å表 List<Map<String, Object>> result = new ArrayList<>(); for (ProcessDefinition pd : latestVersionMap.values()) { Map<String, Object> item = new HashMap<>(); item.put("id", pd.getId()); item.put("key", pd.getKey()); item.put("name", pd.getName()); result.add(item); } return result; } } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectServiceImpl.java
@@ -7,8 +7,7 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum; import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.mes.service.common.bpm.MesBpmProcessService; import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.pd.document.MesPdDocumentDO; @@ -80,10 +79,7 @@ private BpmProcessInstanceApi processInstanceApi; @Resource private BpmCategoryService bpmCategoryService; @Resource private BpmProcessDefinitionService bpmProcessDefinitionService; private MesBpmProcessService mesBpmProcessService; @Override @Transactional(rollbackFor = Exception.class) @@ -238,40 +234,7 @@ @Override public List<Map<String, Object>> getProjectApproveProcessDefinitionList() { // 1. æ ¡éªåç±»æ¯å¦åå¨ List<BpmCategoryDO> categories = bpmCategoryService.getCategoryListByCode( Collections.singletonList(BPM_PROCESS_DEFINITION_CATEGORY_CODE)); if (CollUtil.isEmpty(categories)) { throw exception(PD_PROJECT_BPM_CATEGORY_NOT_EXISTS); } // 2. è·ååç±»ä¸çæµç¨å®ä¹ä¿¡æ¯ List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService .getProcessDefinitionInfoListByCategory(BPM_PROCESS_DEFINITION_CATEGORY_CODE); if (CollUtil.isEmpty(definitionInfoList)) { return Collections.emptyList(); } // 3. è¿æ»¤æ¿æ´»ç¶æï¼ä¿çææ°çæ¬ Map<String, ProcessDefinition> latestVersionMap = new HashMap<>(); for (BpmProcessDefinitionInfoDO info : definitionInfoList) { ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId()); if (pd == null || pd.isSuspended()) { continue; } ProcessDefinition existing = latestVersionMap.get(pd.getKey()); if (existing == null || pd.getVersion() > existing.getVersion()) { latestVersionMap.put(pd.getKey(), pd); } } // 4. è¿åæµç¨å®ä¹å表 List<Map<String, Object>> result = new ArrayList<>(); for (ProcessDefinition pd : latestVersionMap.values()) { Map<String, Object> item = new HashMap<>(); item.put("id", pd.getId()); item.put("key", pd.getKey()); item.put("name", pd.getName()); result.add(item); } return result; return mesBpmProcessService.getApproveProcessDefinitionList(BPM_PROCESS_DEFINITION_CATEGORY_CODE); } @Override yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackService.java
@@ -81,9 +81,9 @@ /** * æäº¤æ¥å·¥ï¼è稿 â 审æ¹ä¸ï¼ * * @param id ç¼å· * @param reqVO æäº¤è¯·æ± */ void submitFeedback(Long id); void submitFeedback(@Valid MesProFeedbackSubmitReqVO reqVO); /** * 驳忥工ï¼å®¡æ¹ä¸ â èç¨¿ï¼ @@ -122,6 +122,14 @@ MesProFeedbackBatchCheckRespVO checkBatchRequirements(Long feedbackId); /** * å¤ç BPM 审æ¹ç»æ * * @param id æ¥å·¥åID * @param bpmResult 审æ¹ç»æç¶æ */ void handleBpmProcessResult(Long id, Integer bpmResult,String reason); /** * IPQC 宿ååè°ï¼å®ææ¥å·¥åå¹¶æ´æ°ä»»å¡/å·¥åè¿åº¦ * * <p>ç± IPQC æ£éªå®ææ¶è°ç¨ï¼å°æ¥å·¥åç¶æä»å¾ æ£éªæ¹ä¸ºå·²å®æï¼ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.*; @@ -62,6 +63,7 @@ */ @Service @Validated @lombok.extern.slf4j.Slf4j public class MesProFeedbackServiceImpl implements MesProFeedbackService { @Resource @@ -94,6 +96,8 @@ private MesMdmItemService mdmItemService; @Resource private MdmItemBatchConfigApi itemBatchConfigApi; @Resource private cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi processInstanceApi; @Override public Long createFeedback(MesProFeedbackSaveReqVO createReqVO) { @@ -154,13 +158,76 @@ } @Override public void submitFeedback(Long id) { @Transactional(rollbackFor = Exception.class) public void submitFeedback(MesProFeedbackSubmitReqVO reqVO) { Long id = reqVO.getId(); // 1. æ ¡éªåå¨ + èç¨¿ç¶æ validateFeedbackStatusPrepare(id); MesProFeedbackDO feedback = validateFeedbackStatusPrepare(id); // 2. æ´æ°ç¶æä¸ºå®¡æ¹ä¸ï¼æ¥å·¥äººåæ¥å·¥æ¶é´ç±è¡¨åä¿åæ¶ç¡®å®ï¼æäº¤ä¸è¦çï¼ MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(feedback.getWorkOrderId()); if (workOrder != null && Boolean.TRUE.equals(workOrder.getFeedbackApprove()) && cn.hutool.core.util.StrUtil.isNotBlank(workOrder.getProcessDefinitionKey())) { // 2. æ´æ°ç¶æä¸ºå®¡æ¹ä¸ï¼å¹¶å¯å¨æµç¨ String processInstanceId = processInstanceApi.createProcessInstance(cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId(), new cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO() .setProcessDefinitionKey(workOrder.getProcessDefinitionKey()) .setBusinessKey(String.valueOf(id))); feedbackMapper.updateById(new MesProFeedbackDO().setId(id) .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus()) .setProcessDefinitionKey(workOrder.getProcessDefinitionKey()) .setProcessInstanceId(processInstanceId)); } else { // 2. 夿è¿ä¸ªæ¥å·¥éä¸éè¦æ¹æ¬¡å· MesProFeedbackBatchCheckRespVO mesProFeedbackBatchCheckRespVO = checkBatchRequirements(id); if (mesProFeedbackBatchCheckRespVO.getNeedBatchInput()) { if (StrUtil.isBlank(reqVO.getLotNumber())) { throw exception(MD_ITEM_BATCH_CONFIG_AT_LEAST_ONE_APPROVE_FLAG); } } // 3. æ´æ°ç¶æä¸ºå®¡æ¹ä¸ï¼ç¶åç´æ¥éè¿å®¡æ¹ feedbackMapper.updateById(new MesProFeedbackDO().setId(id) .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus())); MesProFeedbackApproveReqVO approveReqVO = cn.iocoder.yudao.framework.common.util.object.BeanUtils.toBean(reqVO, MesProFeedbackApproveReqVO.class); approveFeedback(approveReqVO); } } @Override @Transactional(rollbackFor = Exception.class) public void handleBpmProcessResult(Long id, Integer bpmResult,String reason) { // 1. ææ§æ ¡éªï¼è·åæ¥å·¥åå¹¶å¤æç¶æ MesProFeedbackDO feedback = feedbackMapper.selectById(id); if (feedback == null) { log.warn("[handleBpmProcessResult] ç产æ¥å·¥({}) ä¸åå¨", id); return; } if (!MesProFeedbackStatusEnum.APPROVING.getStatus().equals(feedback.getStatus())) { log.warn("[handleBpmProcessResult] ç产æ¥å·¥({}) ä¸å¤äºå®¡æ¹ä¸ç¶æï¼å½åç¶æï¼{}", id, feedback.getStatus()); return; } // 2. æ ¹æ®å®¡æ¹ç»æè¿è¡å¤ç if (cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.APPROVE.getStatus().equals(bpmResult)) { MesProFeedbackApproveReqVO reqVO = new MesProFeedbackApproveReqVO(); reqVO.setId(id); // 夿è¿ä¸ªæ¥å·¥éä¸éè¦æ¹æ¬¡å· MesProFeedbackBatchCheckRespVO mesProFeedbackBatchCheckRespVO = checkBatchRequirements(id); if (mesProFeedbackBatchCheckRespVO.getNeedBatchInput()){ if (StrUtil.isBlank(reason)){ // æ¥é 请å¨å®¡æ¹æè§éå¡«åæ¹æ¬¡å· throw exception(MD_ITEM_BATCH_CONFIG_AT_LEAST_ONE_APPROVE_FLAG); }else { BeanUtils.copyProperties(mesProFeedbackBatchCheckRespVO,reqVO); reqVO.setLotNumber(reason); } } approveFeedback(reqVO); } else if (cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.REJECT.getStatus().equals(bpmResult) || cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.CANCEL.getStatus().equals(bpmResult)) { rejectFeedback(id); } } @Override yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/listener/MesProFeedbackStatusListener.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,74 @@ package cn.iocoder.yudao.module.mes.service.pro.feedback.listener; import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent; import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener; import cn.iocoder.yudao.module.mes.service.pro.feedback.MesProFeedbackService; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants; import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; import org.flowable.task.api.history.HistoricTaskInstance; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.Comparator; import java.util.List; /** * ç产æ¥å·¥å®¡æ¹ç¶æçå¬å¨ * * çå¬ BPM æµç¨å®ä¾ç¶æåæ´äºä»¶ï¼æ´æ°ç产æ¥å·¥ç审æ¹ç¶æ * * @author è¶ çº§ç®¡çå */ @Component @Slf4j public class MesProFeedbackStatusListener extends BpmProcessInstanceStatusEventListener { /** * BPM ç产æ¥å·¥å®¡æ¹æµç¨å®ä¹ key */ private static final String BPM_PROCESS_DEFINITION_KEY = "mes-pro-feedback-audit"; @Resource private MesProFeedbackService feedbackService; @Resource private BpmTaskService bpmTaskService; @Override protected String getProcessDefinitionKey() { return BPM_PROCESS_DEFINITION_KEY; } @Override protected void onEvent(BpmProcessInstanceStatusEvent event) { Long feedbackId; try { feedbackId = Long.parseLong(event.getBusinessKey()); } catch (NumberFormatException e) { log.warn("[onEvent] businessKey({}) 䏿¯ææçç产æ¥å·¥ç¼å·", event.getBusinessKey()); return; } String reason = event.getReason(); if (StrUtil.isEmpty(reason) && event.getId() != null) { // å½ event.getReason() 为空æ¶ï¼å°è¯ä»æåä¸ä¸ªå®æçä»»å¡ä¸è·åå®¡æ¹æè§ List<HistoricTaskInstance> tasks = bpmTaskService.getTaskListByProcessInstanceId(event.getId(), false); if (CollUtil.isNotEmpty(tasks)) { HistoricTaskInstance lastTask = tasks.stream() .filter(task -> task.getEndTime() != null) .max(Comparator.comparing(HistoricTaskInstance::getEndTime)) .orElse(null); if (lastTask != null && lastTask.getTaskLocalVariables() != null) { reason = (String) lastTask.getTaskLocalVariables().get(BpmnVariableConstants.TASK_VARIABLE_REASON); } } } log.info("[onEvent] æ¶å°BPM审æ¹äºä»¶ï¼feedbackId={}, status={},Reason={}", feedbackId, event.getStatus(), reason); feedbackService.handleBpmProcessResult(feedbackId, event.getStatus(), reason); } } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderService.java
@@ -67,6 +67,13 @@ MesProWorkOrderDO getWorkOrder(String code); /** * è·åå®¡æ¹æ¥å·¥çæµç¨å®ä¹å表 * * @return æµç¨å®ä¹å表ï¼å å« id, key, name */ List<Map<String, Object>> getWorkOrderApproveProcessDefinitionList(); /** * è·å¾ç产工åå页 * * @param pageReqVO å页æ¥è¯¢ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderServiceImpl.java
@@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum; import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemBatchConfigService; import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; import cn.iocoder.yudao.module.mes.service.common.bpm.MesBpmProcessService; import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.MesProWorkOrderProgressRespVO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO; @@ -46,6 +47,11 @@ @Service @Validated public class MesProWorkOrderServiceImpl implements MesProWorkOrderService { @Resource private MesBpmProcessService mesBpmProcessService; private static final String BPM_PROCESS_DEFINITION_CATEGORY_CODE = "mes_pro_feedback_audit"; @Resource private MesProWorkOrderMapper workOrderMapper; @@ -150,6 +156,13 @@ } @Override public List<Map<String, Object>> getWorkOrderApproveProcessDefinitionList() { return mesBpmProcessService.getApproveProcessDefinitionList(BPM_PROCESS_DEFINITION_CATEGORY_CODE); } @Override public MesProWorkOrderDO getWorkOrder(Long id) { return workOrderMapper.selectById(id); } yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java
@@ -157,15 +157,19 @@ } @GetMapping("/list-by-role-code") @Operation(summary = "éè¿è§è²æ è¯è·åç¨æ·ç²¾ç®ä¿¡æ¯å表", description = "åªå 嫿¥æè¯¥è§è²çç¨æ·ï¼ä¸»è¦ç¨äºå端ç䏿é项") @Parameter(name = "code", description = "è§è²æ è¯", required = true, example = "admin") @Operation(summary = "éè¿è§è²æ è¯è·åç¨æ·ç²¾ç®ä¿¡æ¯å表", description = "åªå 嫿¥æè¿äºè§è²çç¨æ·ï¼ä¸»è¦ç¨äºå端ç䏿éé¡¹ãæ¯æéå·åéçå¤ä¸ªè§è²æ è¯") @Parameter(name = "code", description = "è§è²æ è¯ï¼æ¯æå¤ä¸ªï¼éå·åé", required = true, example = "admin,user") public CommonResult<List<UserSimpleRespVO>> getSimpleUserListByRoleCode( @RequestParam("code") String code) { RoleDO role = roleService.getRoleByCode(code); if (role == null) { if (StrUtil.isBlank(code)) { return success(Collections.emptyList()); } Set<Long> userIds = permissionService.getUserRoleIdListByRoleId(Collections.singleton(role.getId())); List<String> codes = StrUtil.split(code, ","); List<RoleDO> roles = roleService.getRoleListByCodes(codes); if (CollUtil.isEmpty(roles)) { return success(Collections.emptyList()); } Set<Long> userIds = permissionService.getUserRoleIdListByRoleId(convertList(roles, RoleDO::getId)); if (CollUtil.isEmpty(userIds)) { return success(Collections.emptyList()); } yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMapper.java
@@ -32,6 +32,10 @@ return selectOne(RoleDO::getCode, code); } default List<RoleDO> selectListByCodes(Collection<String> codes) { return selectList(RoleDO::getCode, codes); } default List<RoleDO> selectListByStatus(@Nullable Collection<Integer> statuses) { return selectList(RoleDO::getStatus, statuses); } yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java
@@ -73,6 +73,14 @@ RoleDO getRoleByCode(String code); /** * è·å¾è§è²å表 * * @param codes è§è²ç¼ç æ°ç» * @return è§è²å表 */ List<RoleDO> getRoleListByCodes(Collection<String> codes); /** * è·å¾è§è²ï¼ä»ç¼åä¸ * * @param id è§è²ç¼å· yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java
@@ -195,6 +195,14 @@ } @Override public List<RoleDO> getRoleListByCodes(Collection<String> codes) { if (CollUtil.isEmpty(codes)) { return Collections.emptyList(); } return roleMapper.selectListByCodes(codes); } @Override @Cacheable(value = RedisKeyConstants.ROLE, key = "#id", unless = "#result == null") public RoleDO getRoleFromCache(Long id) {