cnas-process/src/main/java/com/ruoyi/process/controller/ProcessMethodVerifyController.java
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.core.domain.Result; import com.ruoyi.process.dto.ProcessMethodVerifyDto; import com.ruoyi.process.dto.ProcessMethodVerifyCalibrationsFileDto; import com.ruoyi.process.pojo.ProcessMethodVerify; import com.ruoyi.process.pojo.ProcessMethodVerifyMethodFile; import com.ruoyi.process.pojo.ProcessMethodVerifyWorkFile; @@ -81,6 +82,12 @@ return Result.success(processMethodVerifyService.getCurrentWorkFiles(userIds)); } @Operation(summary = "宿¶æ¥çæéè®¾å¤æ ¡åè¯ä¹¦") @GetMapping("/getCurrentCalibrationFiles") public Result<List<ProcessMethodVerifyCalibrationsFileDto>> getCurrentCalibrationFiles(String deviceIds) { return Result.success(processMethodVerifyService.getCurrentCalibrationFiles(deviceIds)); } /** * ä¿®æ¹æ åæ¹æ³éªè¯ cnas-process/src/main/java/com/ruoyi/process/controller/QualityMonitorController.java
@@ -8,9 +8,14 @@ import com.ruoyi.process.dto.QualityMonitorDetailsDto; import com.ruoyi.process.dto.QualityMonitorDto; import com.ruoyi.process.mapper.QualityMonitorDetailsEvaluateFileMapper; import com.ruoyi.process.mapper.QualityMonitorDetailsEvaluateMapper; import com.ruoyi.process.pojo.*; import com.ruoyi.process.service.QualityMonitorDetailsService; import com.ruoyi.process.service.QualityMonitorService; import com.ruoyi.process.service.QualityMonitorTaskService; import com.ruoyi.process.service.QualityMonitorInspectionEvaluationService; import com.ruoyi.inspect.pojo.InsOrder; import com.ruoyi.system.mapper.UserMapper; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import lombok.AllArgsConstructor; @@ -19,8 +24,11 @@ import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; /** @@ -35,6 +43,24 @@ @RequestMapping("/qualityMonitor") public class QualityMonitorController { @Operation(summary = "æ°å»ºå¹´åº¦è´¨éæ§å¶è®¡å") @PostMapping("/createAnnualPlan") public Result<QualityMonitorDto> createAnnualPlan(@RequestBody QualityMonitor qualityMonitor) { return Result.success(qualityMonitorService.createAnnualPlan(qualityMonitor)); } @Operation(summary = "æå¹´åº¦æ¥è¯¢å½åè´¨éæ§å¶è®¡å") @GetMapping("/getAnnualPlan") public Result<QualityMonitorDto> getAnnualPlan(String monitorYear, Integer qualityMonitorId) { return Result.success(qualityMonitorService.getAnnualPlan(monitorYear, qualityMonitorId)); } @Operation(summary = "æäº¤å¹´åº¦è´¨éæ§å¶è®¡åå®¡æ ¸") @PostMapping("/submitAnnualPlan") public Result submitAnnualPlan(@RequestBody Map<String, Integer> request) { return Result.success(qualityMonitorService.submitAnnualPlan(request.get("qualityMonitorId"))); } @Resource private QualityMonitorService qualityMonitorService; @@ -43,6 +69,58 @@ @Resource private QualityMonitorDetailsEvaluateFileMapper qualityMonitorDetailsEvaluateFileMapper; @Resource private QualityMonitorDetailsEvaluateMapper qualityMonitorDetailsEvaluateMapper; @Resource private QualityMonitorTaskService qualityMonitorTaskService; @Resource private QualityMonitorInspectionEvaluationService inspectionEvaluationService; @Resource private UserMapper userMapper; @Operation(summary = "è·åè´¨éçæ§æ£éªè¯ä»·") @GetMapping("/getInspectionEvaluation") public Result<QualityMonitorDetailsEvaluate> getInspectionEvaluation(Integer qualityMonitorDetailsId) { return Result.success(inspectionEvaluationService.get(qualityMonitorDetailsId)); } @Operation(summary = "æäº¤è´¨éçæ§æ£éªè¯ä»·") @PostMapping("/submitInspectionEvaluation") public Result<QualityMonitorDetailsEvaluate> submitInspectionEvaluation(@RequestBody QualityMonitorDetailsEvaluate evaluation) { return Result.success(inspectionEvaluationService.submit(evaluation)); } @Operation(summary = "æ¹åæéåè´¨éçæ§æ£éªè¯ä»·") @PostMapping("/approveInspectionEvaluation") public Result approveInspectionEvaluation(@RequestBody Map<String, Object> request) { Integer detailId = (Integer) request.get("qualityMonitorDetailsId"); boolean approved = Boolean.TRUE.equals(request.get("approved")); inspectionEvaluationService.approve(detailId, approved, (String) request.get("opinion")); return Result.success(); } @Operation(summary = "ä¸åè´¨éçæ§æ£éªä»»å¡") @PostMapping("/dispatchInspectionTask") public Result<InsOrder> dispatchInspectionTask(@RequestBody Map<String, Integer> request) { return Result.success(qualityMonitorTaskService.dispatch(request.get("qualityMonitorDetailsId"))); } @Operation(summary = "æ¥è¯¢è´¨éçæ§æç»å ³èçæ£éªä»»å¡") @GetMapping("/getInspectionTask") public Result<InsOrder> getInspectionTask(Integer qualityMonitorDetailsId) { return Result.success(qualityMonitorTaskService.getTask(qualityMonitorDetailsId)); } @Operation(summary = "åæ¶æªå¼å§çè´¨éçæ§æ£éªä»»å¡") @PostMapping("/cancelInspectionTask") public Result cancelInspectionTask(@RequestBody Map<String, Integer> request) { qualityMonitorTaskService.cancel(request.get("qualityMonitorDetailsId")); return Result.success(); } /** * å¯¼å ¥çæ§è®¡å @@ -116,6 +194,14 @@ if (qualityMonitorDetails.getQualityMonitorId() == null) { throw new ErrorException("缺å°çæ§è®¡å主表id"); } qualityMonitorService.validateDetailEditable(qualityMonitorDetails.getQualityMonitorId()); normalizeTemplateIds(qualityMonitorDetails); validateAnnualDetail(qualityMonitorDetails); if (qualityMonitorDetails.getSortNo() == null) { qualityMonitorDetails.setSortNo((int) qualityMonitorDetailsService.count( com.baomidou.mybatisplus.core.toolkit.Wrappers.<QualityMonitorDetails>lambdaQuery() .eq(QualityMonitorDetails::getQualityMonitorId, qualityMonitorDetails.getQualityMonitorId())) + 1); } return Result.success(qualityMonitorDetailsService.save(qualityMonitorDetails)); } @@ -126,6 +212,15 @@ @Operation(summary = "ä¿®æ¹çæ§è®¡å详æ ") @PostMapping("/updateQualityMonitorDetail") public Result updateQualityMonitorDetail(@RequestBody QualityMonitorDetails qualityMonitorDetails) { QualityMonitorDetails stored = qualityMonitorDetailsService.getById(qualityMonitorDetails.getQualityMonitorDetailsId()); if (stored == null) throw new ErrorException("è´¨æ§é¡¹ç®ä¸åå¨"); qualityMonitorDetails.setQualityMonitorId(stored.getQualityMonitorId()); qualityMonitorService.validateDetailEditable(stored.getQualityMonitorId()); normalizeTemplateIds(qualityMonitorDetails); validateAnnualDetail(qualityMonitorDetails); if (qualityMonitorTaskService.getTask(qualityMonitorDetails.getQualityMonitorDetailsId()) != null) { throw new ErrorException("å·²ä¸åæ£éªä»»å¡ç计åæç»ä¸å¯ç´æ¥ä¿®æ¹"); } return Result.success(qualityMonitorDetailsService.updateById(qualityMonitorDetails)); } @@ -136,7 +231,64 @@ @Operation(summary = "å é¤çæ§è®¡å详æ ") @DeleteMapping("/delQualityMonitorDetail") public Result delQualityMonitorDetail(Integer qualityMonitorDetailsId) { QualityMonitorDetails stored = qualityMonitorDetailsService.getById(qualityMonitorDetailsId); if (stored == null) throw new ErrorException("è´¨æ§é¡¹ç®ä¸åå¨"); qualityMonitorService.validateDetailEditable(stored.getQualityMonitorId()); if (qualityMonitorTaskService.getTask(qualityMonitorDetailsId) != null) { throw new ErrorException("å·²ä¸åæ£éªä»»å¡ç计åæç»ä¸å¯å é¤"); } return Result.success(qualityMonitorDetailsService.removeById(qualityMonitorDetailsId)); } private void validateAnnualDetail(QualityMonitorDetails detail) { if (!org.springframework.util.StringUtils.hasText(detail.getMonitorProject()) || !org.springframework.util.StringUtils.hasText(detail.getTechnicalStandardText()) || !org.springframework.util.StringUtils.hasText(detail.getMonitorWay()) || !org.springframework.util.StringUtils.hasText(detail.getCompletionMonth()) || !detail.getCompletionMonth().matches("\\d{4}-\\d{2}") || detail.getResponsibleUserId() == null) { throw new ErrorException("请补é½è´¨æ§é¡¹ç®ãææ¯æ åãè´¨æ§æ¹å¼ã宿æ¶éåè´è´£äºº"); } QualityMonitor plan = qualityMonitorService.getById(detail.getQualityMonitorId()); if (plan == null || !detail.getCompletionMonth().startsWith(plan.getMonitorYear() + "-")) { throw new ErrorException("宿æ¶éå¿ é¡»å±äºå½å计å年度"); } int month = Integer.parseInt(detail.getCompletionMonth().substring(5)); if (month < 1 || month > 12) throw new ErrorException("宿æ¶éæä»½ä¸æ£ç¡®"); if (userMapper.selectById(detail.getResponsibleUserId()) == null) { throw new ErrorException("è´è´£äººä¸åå¨"); } } private void normalizeTemplateIds(QualityMonitorDetails detail) { String rawIds = detail.getTemplateIds(); if (!org.springframework.util.StringUtils.hasText(rawIds) && detail.getTemplateId() != null) { rawIds = String.valueOf(detail.getTemplateId()); } if (!org.springframework.util.StringUtils.hasText(rawIds)) { detail.setTemplateIds(null); detail.setTemplateId(null); return; } Set<Integer> templateIds = new LinkedHashSet<>(); try { for (String rawId : rawIds.split(",")) { if (!org.springframework.util.StringUtils.hasText(rawId)) continue; int templateId = Integer.parseInt(rawId.trim()); if (templateId <= 0) throw new NumberFormatException(); templateIds.add(templateId); } } catch (NumberFormatException exception) { throw new ErrorException("åå§è®°å½æ¨¡æ¿åæ°ä¸æ£ç¡®"); } if (templateIds.size() > 50) throw new ErrorException("åå§è®°å½æ¨¡æ¿æå¤éæ©50个"); if (templateIds.isEmpty()) { detail.setTemplateIds(null); detail.setTemplateId(null); return; } detail.setTemplateIds(templateIds.stream().map(String::valueOf).collect(Collectors.joining(","))); detail.setTemplateId(templateIds.iterator().next()); } /** @@ -211,6 +363,9 @@ @Operation(summary = "æ°å¢çæ§è¯ä»·") @PostMapping("/addQualityMonitorEvaluate") public Result addQualityMonitorEvaluate(@RequestBody QualityMonitorDetailsEvaluate qualityMonitorDetailsEvaluate) { if (qualityMonitorTaskService.getTask(qualityMonitorDetailsEvaluate.getQualityMonitorDetailsId()) != null) { throw new ErrorException("è´¨éçæ§æ£éªè¯ä»·è¯·ä½¿ç¨æ£éªè¯ä»·å ¥å£"); } return Result.success(qualityMonitorService.addQualityMonitorEvaluate(qualityMonitorDetailsEvaluate)); } @@ -231,6 +386,10 @@ @Operation(summary = "çæ§è¯ä»·æ¹åæè§") @PostMapping("/addMonitorEvaluateOpinion") public Result addMonitorEvaluateOpinion(@RequestBody QualityMonitorDetailsEvaluate qualityMonitorDetailsEvaluate) { QualityMonitorDetailsEvaluate stored = qualityMonitorDetailsEvaluateMapper.selectById(qualityMonitorDetailsEvaluate.getDetailsEvaluateId()); if (stored != null && qualityMonitorTaskService.getTask(stored.getQualityMonitorDetailsId()) != null) { throw new ErrorException("è´¨éçæ§æ£éªè¯ä»·è¯·ä½¿ç¨æ£éªè¯ä»·å®¡æ¹å ¥å£"); } return Result.success(qualityMonitorService.addMonitorEvaluateOpinion(qualityMonitorDetailsEvaluate)); } @@ -279,6 +438,9 @@ @Operation(summary = "ä¸ä¼ çæ§å®ææ¥å") @PostMapping("/uploadFinishReport") public Result uploadFinishReport(MultipartFile file, Integer qualityMonitorDetailsId) { if (qualityMonitorTaskService.getTask(qualityMonitorDetailsId) != null) { throw new ErrorException("è´¨éçæ§æ£éªä»»å¡æ éä¸ä¼ 宿æ¥å"); } return Result.success(qualityMonitorService.uploadFinishReport(file, qualityMonitorDetailsId)); } @@ -290,6 +452,9 @@ @Operation(summary = "æ¹å宿æ¥å") @PostMapping("/ratifyFinishReport") public Result ratifyFinishReport(@RequestBody QualityMonitorDetails qualityMonitorDetails) { if (qualityMonitorTaskService.getTask(qualityMonitorDetails.getQualityMonitorDetailsId()) != null) { throw new ErrorException("è´¨éçæ§æ£éªä»»å¡æ éæ¹å宿æ¥å"); } return Result.success(qualityMonitorService.ratifyFinishReport(qualityMonitorDetails)); } } cnas-process/src/main/java/com/ruoyi/process/dto/QualityMonitorDetailsDto.java
@@ -9,8 +9,30 @@ * @Date 2025/3/24 */ @Data @Schema(description = "è´¨éçæ§è®¡åæç»åä»»å¡è¯ä»·ç¶æ") public class QualityMonitorDetailsDto extends QualityMonitorDetails { @Schema(description = "è´è´£äººå§å") private String responsibleName; @Schema(description = "è¯ä»·äººå§å") private String evaluatorName; @Schema(description = "å ³èæ£éªä»»å¡ID") private Integer inspectionTaskId; @Schema(description = "è´¨éçæ§ä»»å¡ç¼å·") private String inspectionTaskCode; @Schema(description = "æ£éªä»»å¡ç¶æ") private Integer inspectionTaskState; private Integer inspectionTaskOrderState; private Integer planRatifyStatus; private Integer planRatifyUserId; @Schema(description = "宿½ç¶æ, 0: æªå¼å§, 1:å¾ æ¹å, 2:䏿¹å, 3:å·²æ¹å") private Integer detailsRatifyStatus; cnas-process/src/main/java/com/ruoyi/process/dto/QualityMonitorDetailsEvaluateDto.java
@@ -10,6 +10,7 @@ * Description: */ @Data @Schema(description = "è´¨éæ§å¶è¯ä»·è®°å½å¯¼åºæ°æ®") public class QualityMonitorDetailsEvaluateDto extends QualityMonitorDetailsEvaluate { @Schema(description = "æ¹åæ¶é´") private String ratifyTimeStr; cnas-process/src/main/java/com/ruoyi/process/dto/QualityMonitorDto.java
@@ -9,6 +9,7 @@ * @Date 2024/11/6 */ @Data @Schema(description = "年度质éçæ§è®¡ååç¼å¶å®¡æ ¸äººåä¿¡æ¯") public class QualityMonitorDto extends QualityMonitor { @Schema(description = "ç¼å¶äºº") cnas-process/src/main/java/com/ruoyi/process/excel/QualityMonitorDetailsUpload.java
@@ -1,6 +1,7 @@ package com.ruoyi.process.excel; import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; /** @@ -8,26 +9,51 @@ * @Date 2024/11/8 */ @Data @Schema(description = "年度质éçæ§è®¡åæç»å¯¼å ¥è¡") public class QualityMonitorDetailsUpload { @ExcelProperty("çæ§ç®ç") @Schema(description = "计åå æåºå·") @ExcelProperty("åºå·") private Integer sortNo; @Schema(description = "è´¨æ§é¡¹ç®") @ExcelProperty("è´¨æ§é¡¹ç®") private String monitorProject; @Schema(description = "ææ¯æ å") @ExcelProperty("ææ¯æ å") private String technicalStandardText; @Schema(description = "è´¨æ§æ¹å¼") @ExcelProperty("è´¨æ§æ¹å¼") private String monitorWay; @Schema(description = "计å宿æä»½") @ExcelProperty("宿æ¶é") private String completionMonth; @Schema(description = "è´è´£äººå§å") @ExcelProperty("è´è´£äºº") private String responsibleName; @Schema(description = "çæ§ç®çï¼å ¼å®¹åå²å¯¼å ¥å") @ExcelProperty(value = "çæ§ç®ç", index = -1) private String monitorPurpose; @Schema(description = "计åå¼å±æ¶é´ï¼å ¼å®¹åå²å¯¼å ¥å") @ExcelProperty("计åå¼å±æ¶é´") private String plannedTime; @ExcelProperty("çæ§é¡¹ç®") private String monitorProject; @Schema(description = "åå åä½æäººå") @ExcelProperty("åå åä½ï¼äººåï¼") private String participant; @Schema(description = "é¢ç®éé¢") @ExcelProperty("é¢ç®ï¼å ï¼") private String budget; @Schema(description = "ç»ç»äººå") @ExcelProperty("ç»ç»äººå") private String organization; @ExcelProperty("çæ§æ¹å¼") private String monitorWay; } cnas-process/src/main/java/com/ruoyi/process/mapper/QualityMonitorEvaluateResultMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,9 @@ package com.ruoyi.process.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.process.pojo.QualityMonitorEvaluateResult; import org.apache.ibatis.annotations.Mapper; @Mapper public interface QualityMonitorEvaluateResultMapper extends BaseMapper<QualityMonitorEvaluateResult> { } cnas-process/src/main/java/com/ruoyi/process/mapper/QualityMonitorMapper.java
@@ -24,5 +24,7 @@ */ IPage<QualityMonitorDto> pageQualityMonitor(Page page, @Param("ew") QueryWrapper<QualityMonitor> qualityMonitorQueryWrapper); QualityMonitorDto selectPlanDtoById(@Param("id") Integer id); } cnas-process/src/main/java/com/ruoyi/process/mapper/QualityMonitorTaskCodeMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,15 @@ package com.ruoyi.process.mapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @Mapper public interface QualityMonitorTaskCodeMapper { void ensureYear(@Param("year") int year); int lockCurrent(@Param("year") int year); void updateCurrent(@Param("year") int year, @Param("value") int value); int countStandardTemplateBinding(@Param("standardId") int standardId, @Param("templateId") int templateId); } cnas-process/src/main/java/com/ruoyi/process/pojo/QualityMonitor.java
@@ -18,6 +18,7 @@ @Schema(description = "è´¨éçæ§è®¡å主表") public class QualityMonitor { @Schema(description = "年度质éçæ§è®¡åID") @TableId(type = IdType.AUTO) private Integer qualityMonitorId; @@ -27,6 +28,12 @@ @Schema(description = "计å年份") private String monitorYear; @Schema(description = "æµç¨ç¶æï¼DRAFT/PENDING_REVIEW/REVIEW_REJECTED/PENDING_APPROVAL/APPROVAL_REJECTED/APPROVED") private String workflowStatus; @Schema(description = "å ¼å®¹æ§æ°æ®ççæ¬æ è®°ï¼æ°æµç¨ä¸å使ç¨") private Integer isCurrent; @Schema(description = "å¤é®ï¼ç¨æ·idï¼ç¼å¶äººï¼") private Integer writeUserId; cnas-process/src/main/java/com/ruoyi/process/pojo/QualityMonitorDetails.java
@@ -6,6 +6,7 @@ import lombok.Data; import java.time.LocalDateTime; import java.time.LocalDate; /** * è´¨éçæ§è®¡å详æ 表 @@ -18,11 +19,24 @@ @Schema(description = "è´¨éçæ§è®¡å详æ 表") public class QualityMonitorDetails { @Schema(description = "è´¨éçæ§è®¡åæç»ID") @TableId(type = IdType.AUTO) private Integer qualityMonitorDetailsId; @Schema(description = "çæ§è®¡åid") private Integer qualityMonitorId; @Schema(description = "计åå æåºå·") private Integer sortNo; @Schema(description = "年度计å表ä¸çææ¯æ åææ¬") private String technicalStandardText; @Schema(description = "宿æä»½ï¼æ ¼å¼yyyy-MM") private String completionMonth; @Schema(description = "è´è´£äººç¨æ·ID") private Integer responsibleUserId; @Schema(description = "çæ§ç®ç") private String monitorPurpose; @@ -44,6 +58,32 @@ @Schema(description = "çæ§æ¹å¼") private String monitorWay; @Schema(description = "äºé¡¹ç±»å«ï¼INSPECTIONæ£æµç±»ï¼OTHER鿣æµç±»") private String itemKind; @Schema(description = "æ£æµæ åID") private Integer standardMethodId; @Schema(description = "å ¼å®¹æ§æ°æ®çé¦ä¸ªåå§è®°å½æ¨¡æ¿ID") private Integer templateId; @Schema(description = "åå§è®°å½æ¨¡æ¿IDéåï¼å¤ä¸ªID使ç¨è±æéå·åé") private String templateIds; @Schema(description = "æ£æµåç¨æ·ID") private Integer inspectorUserId; @Schema(description = "åå²è®¡å夿 ¸äººç¨æ·IDï¼æ°æµç¨ä¸ä½¿ç¨") private Integer reviewerUserId; @Schema(description = "è¯ä»·äººç¨æ·ID") private Integer evaluatorUserId; @Schema(description = "æ£æµæ ·ååç§°") private String sampleName; @Schema(description = "æ£æµæ ·åè§æ ¼") private String sampleSpec; @Schema(description = "è´¨æ§æ£éªä»»å¡æªæ¢æ¥æ") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate dueDate; @Schema(description = "宿æ¥åå°å") private String finishReportUrl; @@ -85,6 +125,7 @@ private LocalDateTime updateTime; // 导åºä½¿ç¨ @Schema(description = "导åºè¡åºå·ï¼éæ°æ®åºå段") @TableField(select = false, exist = false) private Integer index; cnas-process/src/main/java/com/ruoyi/process/pojo/QualityMonitorDetailsEvaluate.java
@@ -6,6 +6,8 @@ import lombok.Data; import java.time.LocalDateTime; import java.time.LocalDate; import java.util.List; /** * è´¨éçæ§è®¡å详æ è¯ä»·è¡¨ @@ -18,12 +20,85 @@ @Schema(description = "è´¨éçæ§è®¡å详æ è¯ä»·è¡¨") public class QualityMonitorDetailsEvaluate { @Schema(description = "è´¨éæ§å¶è¯ä»·è®°å½ID") @TableId(type = IdType.AUTO) private Integer detailsEvaluateId; @Schema(description = "çæ§è®¡å详æ id") private Integer qualityMonitorDetailsId; @Schema(description = "å ³èçè´¨æ§æ£éªä»»å¡ID") private Integer insOrderId; @Schema(description = "çç£åç¨æ·IDï¼ä¸è¯ä»·äººåå¼") private Integer supervisorUserId; @Schema(description = "被çç£æ£æµåç¨æ·ID") private Integer inspectorUserId; @Schema(description = "æ£æµæ ·ååç§°") private String sampleName; @Schema(description = "æ£æµæ ·åè§æ ¼") private String sampleSpec; @Schema(description = "åå²å䏿£æµæ¶é´ï¼æ°è¯ä»·é¡µé¢ä»åå§è®°å½è¯»åæ¥æ") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime inspectionTime; @Schema(description = "åå²è®¾å¤åç§°ï¼æ°è¯ä»·é¡µé¢ä»åå§è®°å½è¯»åæç¨è®¾å¤") private String equipmentDescription; @Schema(description = "åå²è®¾å¤è§æ ¼ï¼æ°è¯ä»·é¡µé¢ä»åå§è®°å½è¯»åæç¨è®¾å¤") private String equipmentSpec; @Schema(description = "åå²è®¾å¤ç¼å·ï¼æ°è¯ä»·é¡µé¢ä»åå§è®°å½è¯»åæç¨è®¾å¤") private String equipmentCode; @Schema(description = "æ£æµæ åµåè¯ä»·") private String evaluationConclusion; @Schema(description = "çº æ£æªæ½åé¢é²æªæ½") private String correctiveAction; @Schema(description = "éªè¯æ åµ") private String verificationResult; @Schema(description = "çº æ£æªæ½è´£ä»»äººç¨æ·ID") private Integer correctiveResponsibleUserId; @Schema(description = "çº æ£æªæ½å®ææ¥æ") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate correctiveDueDate; @Schema(description = "éªè¯è´£ä»»äººç¨æ·ID") private Integer verificationResponsibleUserId; @Schema(description = "éªè¯æ¥æ") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate verificationDate; @Schema(description = "æ£æµæ°æ®ä¸ç²æ ·å¼å¯¹ç §è¡ï¼éæ°æ®åºå段") @TableField(exist = false) private List<QualityMonitorEvaluateResult> resultRows; @Schema(description = "è¯ä»·äººå·²æ ¸å¯¹åå§è®°å½æ£æµæ°æ®ï¼æäº¤æ ¡éªä½¿ç¨") @TableField(exist = false) private Boolean measurementConfirmed; @Schema(description = "å½åç»å½ç¨æ·è½å¦ç¼åè¯ä»·ï¼éæ°æ®åºå段") @TableField(exist = false) private Boolean evaluationEditable; @Schema(description = "å½åä¸è½ç¼åè¯ä»·çåå ï¼éæ°æ®åºå段") @TableField(exist = false) private String evaluationEditReason; @Schema(description = "è´¨æ§æ£éªä»»å¡ç¶æï¼éæ°æ®åºå段") @TableField(exist = false) private Integer inspectionTaskState; @Schema(description = "已夿 ¸åå§è®°å½ä¸çæ£æµæ¥æéåï¼éæ°æ®åºå段") @TableField(exist = false) private List<String> rawInspectionDates; @Schema(description = "已夿 ¸åå§è®°å½ä¸ç设å¤åç§°ï¼éæ°æ®åºå段") @TableField(exist = false) private String rawEquipmentDescription; @Schema(description = "已夿 ¸åå§è®°å½ä¸ç设å¤è§æ ¼ï¼éæ°æ®åºå段") @TableField(exist = false) private String rawEquipmentSpec; @Schema(description = "已夿 ¸åå§è®°å½ä¸ç设å¤ç¼å·ï¼éæ°æ®åºå段") @TableField(exist = false) private String rawEquipmentCode; @Schema(description = "è¯å®¡ç®ç") private String reviewPurpose; cnas-process/src/main/java/com/ruoyi/process/pojo/QualityMonitorDetailsEvaluateFile.java
@@ -18,6 +18,7 @@ @Schema(description = "è´¨éçæ§è®¡å详æ è¯ä»·é件表") public class QualityMonitorDetailsEvaluateFile { @Schema(description = "è¯ä»·éä»¶ID") @TableId(type = IdType.AUTO) private Integer evaluateFileId; cnas-process/src/main/java/com/ruoyi/process/pojo/QualityMonitorDetailsRatify.java
@@ -18,6 +18,7 @@ @Schema(description = "è´¨éçæ§è®¡åè¯¦æ æ¹å表") public class QualityMonitorDetailsRatify { @Schema(description = "è´¨éçæ§è®¡åæç»æ¹åè®°å½ID") @TableId(type = IdType.AUTO) private Integer detailsRatifyId; cnas-process/src/main/java/com/ruoyi/process/pojo/QualityMonitorEvaluateResult.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,49 @@ package com.ruoyi.process.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data @TableName("cnas_quality_monitor_evaluate_result") @Schema(description = "è´¨éæ§å¶è¯ä»·è®°å½çæ£æµæ°æ®ä¸ç²æ ·å¼å¯¹ç §") public class QualityMonitorEvaluateResult { @Schema(description = "è¯ä»·æ°æ®è¡ID") @TableId(type = IdType.AUTO) private Integer id; @Schema(description = "è´¨éæ§å¶è¯ä»·è®°å½ID") private Integer detailsEvaluateId; @Schema(description = "被çç£æ£æµåç¨æ·ID") private Integer inspectorUserId; @Schema(description = "ä»å·²å¤æ ¸åå§è®°å½å¸¦å ¥ç彿¥æ£æµæ°æ®") private String measuredValue; @Schema(description = "è¯ä»·äººå½å ¥çç²æ ·å¼") private String referenceValue; @Schema(description = "æ£æµæ°æ®åä½") private String unit; @Schema(description = "å¤å®è§åï¼å ¼å®¹åå²è¯ä»·è®°å½") private String acceptanceRule; @Schema(description = "æ£æµå¼ä¸åèå¼åå·®ï¼å ¼å®¹åå²è¯ä»·è®°å½") private String deviation; @Schema(description = "åè¡å¤å®ç»æï¼å ¼å®¹åå²è¯ä»·è®°å½") private String result; @Schema(description = "æ°æ®è¡æåºå·") private Integer sortNo; @Schema(description = "åå§è®°å½ä¸çæ£æµé¡¹ç®åç§°ï¼ä» ç¨äºå±ç¤º") @TableField(exist = false) private String itemName; } cnas-process/src/main/java/com/ruoyi/process/service/ProcessMethodVerifyService.java
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.process.dto.ProcessMethodVerifyDto; import com.ruoyi.process.dto.ProcessMethodVerifyCalibrationsFileDto; import com.ruoyi.process.pojo.ProcessMethodVerify; import com.ruoyi.process.pojo.ProcessMethodVerifyMethodFile; import com.ruoyi.process.pojo.ProcessMethodVerifyWorkFile; @@ -45,6 +46,9 @@ /** 宿¶è¯»åæéæ£æµäººåçä»»èææè¯ä¹¦ã */ List<ProcessMethodVerifyWorkFile> getCurrentWorkFiles(String userIds); /** 宿¶è¯»åæé设å¤çæ ¡åè¯ä¹¦ã */ List<ProcessMethodVerifyCalibrationsFileDto> getCurrentCalibrationFiles(String deviceIds); /** * ä¿®æ¹æ åæ¹æ³éªè¯ * @param methodVerifyDto cnas-process/src/main/java/com/ruoyi/process/service/QualityMonitorInspectionEvaluationService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,243 @@ package com.ruoyi.process.service; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.framework.exception.ErrorException; import com.ruoyi.inspect.mapper.InsOrderStateMapper; import com.ruoyi.inspect.pojo.InsOrder; import com.ruoyi.inspect.pojo.InsOrderState; import com.ruoyi.inspect.service.InsOrderPlanService; import com.ruoyi.inspect.vo.QualityMonitorRawContext; import com.ruoyi.process.mapper.QualityMonitorDetailsEvaluateMapper; import com.ruoyi.process.mapper.QualityMonitorDetailsMapper; import com.ruoyi.process.mapper.QualityMonitorEvaluateResultMapper; import com.ruoyi.process.mapper.QualityMonitorMapper; import com.ruoyi.process.pojo.QualityMonitor; import com.ruoyi.process.pojo.QualityMonitorDetails; import com.ruoyi.process.pojo.QualityMonitorDetailsEvaluate; import com.ruoyi.process.pojo.QualityMonitorEvaluateResult; import com.ruoyi.system.mapper.UserMapper; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; @Service public class QualityMonitorInspectionEvaluationService { @Resource private QualityMonitorTaskService taskService; @Resource private QualityMonitorDetailsMapper detailsMapper; @Resource private QualityMonitorMapper monitorMapper; @Resource private QualityMonitorDetailsEvaluateMapper evaluateMapper; @Resource private QualityMonitorEvaluateResultMapper resultMapper; @Resource private InsOrderStateMapper stateMapper; @Resource private UserMapper userMapper; @Resource private InsOrderPlanService insOrderPlanService; public QualityMonitorDetailsEvaluate get(Integer detailId) { QualityMonitorDetails detail = requireDetail(detailId); QualityMonitorDetailsEvaluate evaluation = evaluateMapper.selectOne(Wrappers.<QualityMonitorDetailsEvaluate>lambdaQuery() .eq(QualityMonitorDetailsEvaluate::getQualityMonitorDetailsId, detailId).last("limit 1")); InsOrder task = taskService.getTask(detailId); if (evaluation == null) { evaluation = new QualityMonitorDetailsEvaluate(); evaluation.setQualityMonitorDetailsId(detailId); evaluation.setInspectorUserId(detail.getInspectorUserId()); evaluation.setSampleName(detail.getSampleName()); evaluation.setSampleSpec(detail.getSampleSpec()); } List<QualityMonitorEvaluateResult> rows = evaluation.getDetailsEvaluateId() == null ? List.of() : resultMapper.selectList(Wrappers.<QualityMonitorEvaluateResult>lambdaQuery() .eq(QualityMonitorEvaluateResult::getDetailsEvaluateId, evaluation.getDetailsEvaluateId()) .orderByAsc(QualityMonitorEvaluateResult::getSortNo, QualityMonitorEvaluateResult::getId)); if (task != null && Integer.valueOf(5).equals(task.getInsState())) { List<Map<String, String>> rawRows = insOrderPlanService.getQualityMonitorRawResults(task.getId()); fillRawContext(evaluation, insOrderPlanService.getQualityMonitorRawContext(task.getId())); if (!rows.isEmpty() && rows.size() != rawRows.size()) throw new ErrorException("åå§è®°å½æ£æµæ°æ®å·²ååï¼è¯·éæ°æ ¸å¯¹è¯ä»·è®°å½"); if (rows.isEmpty()) { rows = new java.util.ArrayList<>(); for (int i = 0; i < rawRows.size(); i++) { QualityMonitorEvaluateResult row = new QualityMonitorEvaluateResult(); row.setInspectorUserId(detail.getInspectorUserId()); row.setMeasuredValue(rawRows.get(i).get("result")); row.setUnit(rawRows.get(i).get("unit")); row.setSortNo(i); rows.add(row); } } for (int i = 0; i < rows.size(); i++) rows.get(i).setItemName(rawRows.get(i).get("itemName")); } evaluation.setResultRows(rows); evaluation.setInspectionTaskState(task == null ? null : task.getInsState()); if (Integer.valueOf(1).equals(evaluation.getIsFinish())) { evaluation.setEvaluationEditReason("è¯ä»·å·²æ¹å彿¡£ï¼åªè½æ¥ç"); } else if (task == null) { evaluation.setEvaluationEditReason("è´¨æ§æ£éªä»»å¡å°æªä¸åï¼æä¸è½å¡«åè¯ä»·"); } else if (!Integer.valueOf(5).equals(task.getInsState())) { evaluation.setEvaluationEditReason("åå§è®°å½å¤æ ¸éè¿åï¼æå®è¯ä»·äººæå¯ä»¥å¡«å"); } else if (detail.getEvaluatorUserId() == null) { evaluation.setEvaluationEditReason("计å项ç®å°æªæå®è¯ä»·äºº"); } else if (!Integer.valueOf(SecurityUtils.getUserId().intValue()).equals(detail.getEvaluatorUserId())) { var evaluator = userMapper.selectById(detail.getEvaluatorUserId()); evaluation.setEvaluationEditReason("å½åè´¦å·ä¸æ¯æå®è¯ä»·äººï¼" + (evaluator == null ? "ç¨æ·ID " + detail.getEvaluatorUserId() : evaluator.getName()) + "ï¼ï¼åªè½æ¥ç"); } else { evaluation.setEvaluationEditable(true); } return evaluation; } @Transactional(rollbackFor = Exception.class) public QualityMonitorDetailsEvaluate submit(QualityMonitorDetailsEvaluate input) { if (input == null) throw new ErrorException("è¯ä»·å 容ä¸è½ä¸ºç©º"); QualityMonitorDetails detail = requireDetail(input.getQualityMonitorDetailsId()); InsOrder task = taskService.getTask(detail.getQualityMonitorDetailsId()); if (task == null || !QualityMonitorTaskService.SOURCE.equals(task.getTaskSource())) throw new ErrorException("è´¨éçæ§æ£éªä»»å¡ä¸åå¨"); if (!Integer.valueOf(5).equals(task.getInsState())) throw new ErrorException("åå§è®°å½å¤æ ¸éè¿åæè½è¯ä»·"); if (!Integer.valueOf(SecurityUtils.getUserId().intValue()).equals(detail.getEvaluatorUserId())) throw new ErrorException("åªææå®è¯ä»·äººå¯ä»¥å¡«åè¯ä»·"); if (input.getSupervisorUserId() == null || input.getSupervisorUserId().equals(detail.getInspectorUserId()) || input.getSupervisorUserId().equals(detail.getEvaluatorUserId()) || userMapper.selectById(input.getSupervisorUserId()) == null) throw new ErrorException("è¯·éæ©ä¸æ£æµåãè¯ä»·äººä¸åççç£å"); Long pendingCount = stateMapper.selectCount(Wrappers.<InsOrderState>lambdaQuery() .eq(InsOrderState::getInsOrderId, task.getId()).ne(InsOrderState::getInsState, 5)); if (pendingCount > 0) throw new ErrorException("åå§è®°å½å¤æ ¸éè¿åæè½è¯ä»·"); List<Map<String, String>> rawRows = insOrderPlanService.getQualityMonitorRawResults(task.getId()); QualityMonitorRawContext rawContext = insOrderPlanService.getQualityMonitorRawContext(task.getId()); if (rawContext.getDetectionDates().isEmpty() || rawContext.getDevices().isEmpty()) throw new ErrorException("åå§è®°å½ç¼ºå°æ£æµæ¶é´ææç¨è®¾å¤ï¼è¯·å è¡¥é½å¹¶å¤æ ¸"); if (!StringUtils.hasText(input.getEvaluationConclusion()) || input.getResultRows() == null || input.getResultRows().size() != rawRows.size()) throw new ErrorException("请填åè¯ä»·å å®¹å¹¶æ ¸å¯¹å ¨é¨åå§è®°å½æ£æµæ°æ®"); if (!Boolean.TRUE.equals(input.getMeasurementConfirmed())) throw new ErrorException("è¯·å æ ¸å¯¹å·²å¤æ ¸åå§è®°å½çæ£æµæ°æ®"); QualityMonitorDetailsEvaluate existing = evaluateMapper.selectOne(Wrappers.<QualityMonitorDetailsEvaluate>lambdaQuery() .eq(QualityMonitorDetailsEvaluate::getQualityMonitorDetailsId, detail.getQualityMonitorDetailsId()) .last("FOR UPDATE")); if (existing != null && Integer.valueOf(1).equals(existing.getIsFinish())) throw new ErrorException("å·²æ¹åçè¯ä»·ä¸å¯ä¿®æ¹"); QualityMonitor plan = monitorMapper.selectById(detail.getQualityMonitorId()); QualityMonitorDetailsEvaluate saved = existing == null ? new QualityMonitorDetailsEvaluate() : existing; saved.setQualityMonitorDetailsId(detail.getQualityMonitorDetailsId()); saved.setInsOrderId(task.getId()); saved.setInspectorUserId(detail.getInspectorUserId()); saved.setImplementUserId(detail.getEvaluatorUserId()); saved.setRatifyUserId(plan.getRatifyUserId()); saved.setSupervisorUserId(input.getSupervisorUserId()); saved.setSampleName(detail.getSampleName()); saved.setSampleSpec(detail.getSampleSpec()); // æ¶é´å设å¤å§ç»ç±å·²å¤æ ¸åå§è®°å½è¯»åï¼è¯ä»·è¯·æ±ä¸çåååæ®µä¸åä¸ä¿åã saved.setImplementCondition(input.getEvaluationConclusion()); saved.setImplementResult(input.getImplementResult()); saved.setEvaluationConclusion(input.getEvaluationConclusion()); saved.setCorrectiveAction(input.getCorrectiveAction()); saved.setVerificationResult(input.getVerificationResult()); saved.setCorrectiveResponsibleUserId(input.getCorrectiveResponsibleUserId()); saved.setCorrectiveDueDate(input.getCorrectiveDueDate()); saved.setVerificationResponsibleUserId(input.getVerificationResponsibleUserId()); saved.setVerificationDate(input.getVerificationDate()); saved.setReviewPurpose(detail.getMonitorPurpose()); saved.setReviewUser(userMapper.selectById(detail.getEvaluatorUserId()).getName()); saved.setReviewTime(LocalDateTime.now().toLocalDate().toString()); if (!StringUtils.hasText(saved.getImplementResult())) { saved.setImplementResult(input.getEvaluationConclusion()); } saved.setIsFinish(0); if (existing == null) evaluateMapper.insert(saved); else evaluateMapper.updateById(saved); resultMapper.delete(Wrappers.<QualityMonitorEvaluateResult>lambdaQuery() .eq(QualityMonitorEvaluateResult::getDetailsEvaluateId, saved.getDetailsEvaluateId())); int index = 0; for (QualityMonitorEvaluateResult row : input.getResultRows()) { Map<String, String> rawRow = rawRows.get(index); if (!Objects.equals(row.getMeasuredValue(), rawRow.get("result"))) throw new ErrorException("æ£æµæ°æ®ä¸å·²å¤æ ¸åå§è®°å½ä¸ä¸è´ï¼è¯·å·æ°åéæ°æ ¸å¯¹"); if (!StringUtils.hasText(row.getReferenceValue())) throw new ErrorException("请填åç²æ ·å¼"); row.setId(null); row.setDetailsEvaluateId(saved.getDetailsEvaluateId()); row.setInspectorUserId(detail.getInspectorUserId()); row.setMeasuredValue(rawRow.get("result")); row.setUnit(rawRow.get("unit")); row.setSortNo(index++); resultMapper.insert(row); } return get(detail.getQualityMonitorDetailsId()); } @Transactional(rollbackFor = Exception.class) public void approve(Integer detailId, boolean approved, String opinion) { QualityMonitorDetails detail = requireDetail(detailId); QualityMonitor plan = monitorMapper.selectById(detail.getQualityMonitorId()); int current = SecurityUtils.getUserId().intValue(); if (plan == null || !Integer.valueOf(current).equals(plan.getRatifyUserId()) || Integer.valueOf(current).equals(detail.getInspectorUserId())) throw new ErrorException("åªææå®æ¹å人å¯ä»¥å®¡æ¹è¯ä»·"); QualityMonitorDetailsEvaluate evaluation = evaluateMapper.selectOne(Wrappers.<QualityMonitorDetailsEvaluate>lambdaQuery() .eq(QualityMonitorDetailsEvaluate::getQualityMonitorDetailsId, detailId).last("FOR UPDATE")); if (evaluation == null || Integer.valueOf(1).equals(evaluation.getIsFinish())) throw new ErrorException("è¯ä»·ä¸å卿已æ¹å"); if (approved && StringUtils.hasText(evaluation.getCorrectiveAction()) && (!StringUtils.hasText(evaluation.getVerificationResult()) || evaluation.getCorrectiveResponsibleUserId() == null || evaluation.getCorrectiveDueDate() == null || evaluation.getVerificationResponsibleUserId() == null || evaluation.getVerificationDate() == null)) throw new ErrorException("请补é½çº æ£æªæ½è´£ä»»äººãå®ææ¥æåéªè¯ä¿¡æ¯ååæ¹å"); evaluation.setRatifyOpinion(opinion); evaluation.setRatifyTime(LocalDateTime.now()); evaluation.setIsFinish(approved ? 1 : 0); evaluateMapper.updateById(evaluation); } private QualityMonitorDetails requireDetail(Integer detailId) { QualityMonitorDetails detail = detailId == null ? null : detailsMapper.selectById(detailId); if (detail == null || !"INSPECTION".equals(detail.getItemKind())) throw new ErrorException("è´¨éçæ§æ£æµæç»ä¸åå¨"); return detail; } private void fillRawContext(QualityMonitorDetailsEvaluate evaluation, QualityMonitorRawContext context) { evaluation.setRawInspectionDates(context.getDetectionDates().stream() .map(date -> date.format(DateTimeFormatter.ISO_LOCAL_DATE)).collect(Collectors.toList())); List<String> names = new ArrayList<>(); List<String> specs = new ArrayList<>(); List<String> codes = new ArrayList<>(); for (Map<String, String> device : context.getDevices()) { names.add(deviceText(device, "device_name", "deviceName")); specs.add(deviceText(device, "specification_model", "specificationModel")); String managementNumber = deviceText(device, "management_number", "managementNumber"); codes.add("-".equals(managementNumber) ? deviceText(device, "factory_no", "factoryNo") : managementNumber); } evaluation.setRawEquipmentDescription(String.join("\n", names)); evaluation.setRawEquipmentSpec(String.join("\n", specs)); evaluation.setRawEquipmentCode(String.join("\n", codes)); } private String deviceText(Map<String, String> device, String snakeCase, String camelCase) { String value = device.get(snakeCase); if (!StringUtils.hasText(value)) value = device.get(camelCase); return StringUtils.hasText(value) ? value : "-"; } } cnas-process/src/main/java/com/ruoyi/process/service/QualityMonitorService.java
@@ -19,6 +19,14 @@ */ public interface QualityMonitorService extends IService<QualityMonitor> { QualityMonitorDto createAnnualPlan(QualityMonitor qualityMonitor); QualityMonitorDto getAnnualPlan(String monitorYear, Integer qualityMonitorId); boolean submitAnnualPlan(Integer qualityMonitorId); void validateDetailEditable(Integer qualityMonitorId); /** * å¯¼å ¥çæ§è®¡å * @param file cnas-process/src/main/java/com/ruoyi/process/service/QualityMonitorTaskService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,222 @@ package com.ruoyi.process.service; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.basic.pojo.StandardMethod; import com.ruoyi.basic.pojo.StandardTemplate; import com.ruoyi.basic.service.StandardMethodService; import com.ruoyi.basic.service.StandardTemplateService; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.core.domain.entity.InformationNotification; import com.ruoyi.system.service.InformationNotificationService; import com.ruoyi.framework.exception.ErrorException; import com.ruoyi.inspect.mapper.InsOrderMapper; import com.ruoyi.inspect.mapper.InsOrderStandardTemplateMapper; import com.ruoyi.inspect.mapper.InsSampleMapper; import com.ruoyi.inspect.mapper.InsOrderStateMapper; import com.ruoyi.inspect.pojo.InsOrder; import com.ruoyi.inspect.pojo.InsOrderStandardTemplate; import com.ruoyi.inspect.pojo.InsSample; import com.ruoyi.inspect.pojo.InsOrderState; import com.ruoyi.inspect.service.InsOrderService; import com.ruoyi.process.mapper.QualityMonitorDetailsMapper; import com.ruoyi.process.mapper.QualityMonitorMapper; import com.ruoyi.process.mapper.QualityMonitorTaskCodeMapper; import com.ruoyi.process.pojo.QualityMonitor; import com.ruoyi.process.pojo.QualityMonitorDetails; import com.ruoyi.system.mapper.UserMapper; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.YearMonth; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @Service public class QualityMonitorTaskService { public static final String SOURCE = "QUALITY_MONITOR"; private static final String LABORATORY = "æ°è"; @Resource private QualityMonitorDetailsMapper detailsMapper; @Resource private QualityMonitorMapper monitorMapper; @Resource private QualityMonitorTaskCodeMapper codeMapper; @Resource private InsOrderMapper orderMapper; @Resource private InsSampleMapper sampleMapper; @Resource private InsOrderStateMapper stateMapper; @Resource private InsOrderStandardTemplateMapper snapshotMapper; @Resource private InsOrderService orderService; @Resource private StandardMethodService standardMethodService; @Resource private StandardTemplateService standardTemplateService; @Resource private UserMapper userMapper; @Resource private InformationNotificationService notificationService; @Transactional(rollbackFor = Exception.class) public InsOrder dispatch(Integer detailsId) { if (detailsId == null) throw new ErrorException("缺å°è´¨éçæ§è®¡åæç»ID"); QualityMonitorDetails detail = detailsMapper.selectOne(Wrappers.<QualityMonitorDetails>lambdaQuery() .eq(QualityMonitorDetails::getQualityMonitorDetailsId, detailsId).last("FOR UPDATE")); if (detail == null) throw new ErrorException("è´¨éçæ§è®¡åæç»ä¸åå¨"); InsOrder existing = getTask(detailsId); if (existing != null) return existing; QualityMonitor plan = monitorMapper.selectById(detail.getQualityMonitorId()); if (plan == null || !Integer.valueOf(1).equals(plan.getExamineStatus()) || !Integer.valueOf(1).equals(plan.getRatifyStatus())) { throw new ErrorException("è´¨éçæ§è®¡åå®¡æ ¸ãæ¹åéè¿åæè½ä¸å"); } if (!"INSPECTION".equals(detail.getItemKind())) throw new ErrorException("ä» æ£æµç±»æç»å¯ä¸åæ£éªä»»å¡"); if (!StringUtils.hasText(detail.getTechnicalStandardText()) || !StringUtils.hasText(detail.getMonitorWay()) || !StringUtils.hasText(detail.getCompletionMonth()) || detail.getResponsibleUserId() == null) { throw new ErrorException("请补é½è´¨æ§é¡¹ç®ãææ¯æ åãè´¨æ§æ¹å¼ã宿æ¶éåè´è´£äºº"); } List<Integer> templateIds = resolveTemplateIds(detail); if (detail.getStandardMethodId() == null || templateIds.isEmpty() || detail.getInspectorUserId() == null || detail.getEvaluatorUserId() == null || detail.getDueDate() == null || !StringUtils.hasText(detail.getSampleName())) { throw new ErrorException("è¯·è¡¥é½æ åãåå§è®°å½æ¨¡æ¿ãæ£æµåãè¯ä»·äººãæ ·åå宿æé"); } if (detail.getInspectorUserId().equals(detail.getEvaluatorUserId())) { throw new ErrorException("æ£æµåä¸è½åæ¶æ ä»»è¯ä»·äºº"); } if (userMapper.selectById(detail.getInspectorUserId()) == null || userMapper.selectById(detail.getEvaluatorUserId()) == null) { throw new ErrorException("æ£æµåæè¯ä»·äººä¸åå¨"); } StandardMethod standard = standardMethodService.getById(detail.getStandardMethodId()); if (standard == null) throw new ErrorException("æ£æµæ åä¸åå¨"); List<StandardTemplate> templates = new ArrayList<>(); for (Integer templateId : templateIds) { StandardTemplate template = standardTemplateService.getById(templateId); if (template == null || !StringUtils.hasText(template.getThing())) { throw new ErrorException("åå§è®°å½æ¨¡æ¿ä¸å卿å 容为空ï¼" + templateId); } if (codeMapper.countStandardTemplateBinding(standard.getId(), template.getId()) == 0) { throw new ErrorException("åå§è®°å½æ¨¡æ¿æªç»å®å½åæ£æµæ åï¼" + template.getName()); } templates.add(template); } LocalDate today = LocalDate.now(ZoneId.of("Asia/Shanghai")); YearMonth completionMonth; try { completionMonth = YearMonth.parse(detail.getCompletionMonth()); } catch (Exception exception) { throw new ErrorException("计å宿æ¶éæ ¼å¼ä¸æ£ç¡®"); } if (YearMonth.from(detail.getDueDate()).isAfter(completionMonth)) { throw new ErrorException("æ£éªä»»å¡æªæ¢æ¥ä¸è½æäºè®¡å宿æä»½"); } int year = today.getYear(); codeMapper.ensureYear(year); int sequence = codeMapper.lockCurrent(year) + 1; codeMapper.updateCurrent(year, sequence); String code = String.format("QC-%d-%04d", year, sequence); InsOrder order = new InsOrder(); order.setEntrustCode(code); order.setTaskSource(SOURCE); order.setQualityMonitorDetailsId(detailsId); order.setOrderType(SOURCE); order.setTypeSource(-1); order.setState(1); order.setInsState(0); order.setLaboratory(LABORATORY); order.setSample(detail.getSampleName()); order.setPartDetail(detail.getSampleSpec()); order.setAppointed(detail.getDueDate()); order.setExamineTime(LocalDateTime.now()); orderMapper.insert(order); InsSample sample = new InsSample(); sample.setInsOrderId(order.getId()); sample.setSampleCode(code); sample.setLaboratory(LABORATORY); sample.setSample(detail.getSampleName()); sample.setQuantity(1); sampleMapper.insert(sample); for (int index = 0; index < templates.size(); index++) { StandardTemplate template = templates.get(index); InsOrderStandardTemplate snapshot = new InsOrderStandardTemplate(); snapshot.setInsOrderId(order.getId()); snapshot.setTemplateId(template.getId()); snapshot.setName(template.getName()); snapshot.setNumber(template.getNumber()); snapshot.setRemark(template.getRemark()); snapshot.setThing(template.getThing()); snapshot.setSort(index); snapshotMapper.insert(snapshot); } orderService.upInsOrder(order.getId(), sample.getId(), detail.getDueDate().toString(), detail.getInspectorUserId(), LABORATORY); InformationNotification notice = new InformationNotification(); notice.setCreateUser(userMapper.selectById(SecurityUtils.getUserId().intValue()).getName()); notice.setSenderId(SecurityUtils.getUserId().intValue()); notice.setConsigneeId(detail.getInspectorUserId()); notice.setMessageType("2"); notice.setTheme("è´¨éçæ§æ£éªä»»å¡"); notice.setContent("è´¨éçæ§ä»»å¡ " + code + " å¾ æ£æµï¼è¯·æ¥çè¯ä»·è¦æ±ååå§è®°å½æ¨¡æ¿"); notice.setJumpPath("InspectionTask"); notificationService.addInformationNotification(notice); return orderMapper.selectById(order.getId()); } private List<Integer> resolveTemplateIds(QualityMonitorDetails detail) { String rawIds = detail.getTemplateIds(); if (!StringUtils.hasText(rawIds) && detail.getTemplateId() != null) { rawIds = String.valueOf(detail.getTemplateId()); } Set<Integer> result = new LinkedHashSet<>(); if (!StringUtils.hasText(rawIds)) return new ArrayList<>(); try { for (String rawId : rawIds.split(",")) { if (!StringUtils.hasText(rawId)) continue; int templateId = Integer.parseInt(rawId.trim()); if (templateId <= 0) throw new NumberFormatException(); result.add(templateId); } } catch (NumberFormatException exception) { throw new ErrorException("åå§è®°å½æ¨¡æ¿åæ°ä¸æ£ç¡®"); } if (result.size() > 50) throw new ErrorException("åå§è®°å½æ¨¡æ¿æå¤éæ©50个"); return new ArrayList<>(result); } public InsOrder getTask(Integer detailsId) { if (detailsId == null) return null; return orderMapper.selectOne(Wrappers.<InsOrder>lambdaQuery() .eq(InsOrder::getQualityMonitorDetailsId, detailsId).last("limit 1")); } @Transactional(rollbackFor = Exception.class) public void cancel(Integer detailsId) { InsOrder task = getTask(detailsId); if (task == null || !SOURCE.equals(task.getTaskSource()) || !Integer.valueOf(1).equals(task.getState())) { throw new ErrorException("è´¨éçæ§ä»»å¡ä¸å卿已忶"); } QualityMonitorDetails detail = detailsMapper.selectById(detailsId); QualityMonitor plan = detail == null ? null : monitorMapper.selectById(detail.getQualityMonitorId()); int current = SecurityUtils.getUserId().intValue(); if (plan == null || !(Integer.valueOf(current).equals(plan.getRatifyUserId()) || Integer.valueOf(current).equals(task.getCreateUser()))) { throw new ErrorException("åªæä¸å人æè®¡åæ¹å人å¯ä»¥åæ¶ä»»å¡"); } Long startedStates = stateMapper.selectCount(Wrappers.<InsOrderState>lambdaQuery() .eq(InsOrderState::getInsOrderId, task.getId()).ne(InsOrderState::getInsState, 0)); if (startedStates > 0) throw new ErrorException("ä»»å¡å·²å¼å§ï¼ä¸è½åæ¶"); Long filledSnapshots = snapshotMapper.selectCount(Wrappers.<InsOrderStandardTemplate>lambdaQuery() .eq(InsOrderStandardTemplate::getInsOrderId, task.getId()) .isNotNull(InsOrderStandardTemplate::getRecordValues)); if (filledSnapshots > 0) throw new ErrorException("åå§è®°å½å·²å¡«åï¼ä¸è½åæ¶ä»»å¡"); task.setState(5); orderMapper.updateById(task); } } cnas-process/src/main/java/com/ruoyi/process/service/impl/ProcessMethodVerifyServiceImpl.java
@@ -17,10 +17,12 @@ import com.ruoyi.common.core.domain.entity.User; import com.ruoyi.common.utils.QueryWrappers; import com.ruoyi.device.mapper.DeviceMapper; import com.ruoyi.device.pojo.Device; import com.ruoyi.framework.exception.ErrorException; import com.ruoyi.inspect.util.HackLoopTableRenderPolicy; import com.ruoyi.inspect.util.UserUtils; import com.ruoyi.process.dto.ProcessMethodVerifyDto; import com.ruoyi.process.dto.ProcessMethodVerifyCalibrationsFileDto; import com.ruoyi.process.dto.ProcessMethodVerifyExportWordDto; import com.ruoyi.process.mapper.ProcessMethodVerifyCalibrationsFileMapper; import com.ruoyi.process.mapper.ProcessMethodVerifyMapper; @@ -191,6 +193,39 @@ return files; } @Override public List<ProcessMethodVerifyCalibrationsFileDto> getCurrentCalibrationFiles(String deviceIds) { List<ProcessMethodVerifyCalibrationsFileDto> files = new ArrayList<>(); if (StringUtils.isBlank(deviceIds)) return files; Set<Integer> ids = new LinkedHashSet<>(); for (String value : StrUtil.split(deviceIds, ",")) { try { ids.add(Integer.valueOf(value.trim())); } catch (NumberFormatException e) { throw new ErrorException("设å¤IDæ æ"); } } if (ids.size() > 50) throw new ErrorException("æå¤æ¥ç50å°è®¾å¤çæ ¡åè¯ä¹¦"); for (Integer deviceId : ids) { String fileName = processMethodVerifyCalibrationsFileMapper.selectCalibrationsFile(deviceId); if (StringUtils.isBlank(fileName)) continue; Device device = deviceMapper.selectById(deviceId); if (device == null) continue; ProcessMethodVerifyCalibrationsFileDto file = new ProcessMethodVerifyCalibrationsFileDto(); file.setDeviceId(deviceId); file.setDeviceName(device.getDeviceName()); file.setManagementNumber(device.getManagementNumber()); file.setFileName(fileName); file.setFileUrl(fileName); file.setType(fileName.matches("(?i).*\\.(png|jpe?g|gif|bmp|webp)$") ? 1 : 2); files.add(file); } return files; } /** * ä¿®æ¹æ åæ¹æ³éªè¯ * cnas-process/src/main/java/com/ruoyi/process/service/impl/QualityMonitorServiceImpl.java
@@ -70,6 +70,9 @@ @Transactional(rollbackFor = Exception.class) public class QualityMonitorServiceImpl extends ServiceImpl<QualityMonitorMapper, QualityMonitor> implements QualityMonitorService { private static final Set<String> EDITABLE_PLAN_STATES = new HashSet<>(Arrays.asList( "DRAFT", "REVIEW_REJECTED", "APPROVAL_REJECTED")); @Resource private QualityMonitorDetailsService qualityMonitorDetailsService; @Resource @@ -96,6 +99,111 @@ @Value("${wordUrl}") private String wordUrl; @Override public QualityMonitorDto createAnnualPlan(QualityMonitor input) { if (input == null || StringUtils.isBlank(input.getMonitorYear()) || !input.getMonitorYear().matches("\\d{4}")) { throw new ErrorException("è¯·éæ©æ£ç¡®ç计å年度"); } if (input.getExamineUserId() == null || userMapper.selectById(input.getExamineUserId()) == null) { throw new ErrorException("è¯·éæ©ææçå®¡æ ¸äºº"); } if (StringUtils.isBlank(input.getMonitorName())) { throw new ErrorException("请填å计ååç§°"); } int userId = SecurityUtils.getUserId().intValue(); QualityMonitor plan = new QualityMonitor(); plan.setMonitorYear(input.getMonitorYear()); plan.setMonitorName(input.getMonitorName().trim()); plan.setWriteUserId(userId); plan.setWriteTime(LocalDateTime.now()); plan.setExamineUserId(input.getExamineUserId()); plan.setWorkflowStatus("DRAFT"); baseMapper.insert(plan); return baseMapper.selectPlanDtoById(plan.getQualityMonitorId()); } @Override public QualityMonitorDto getAnnualPlan(String monitorYear, Integer qualityMonitorId) { QualityMonitor plan; if (qualityMonitorId != null) { plan = baseMapper.selectById(qualityMonitorId); if (plan == null || (StringUtils.isNotBlank(monitorYear) && !monitorYear.equals(plan.getMonitorYear()))) return null; } else { if (StringUtils.isBlank(monitorYear)) throw new ErrorException("è¯·éæ©è®¡å年度"); plan = baseMapper.selectOne(Wrappers.<QualityMonitor>lambdaQuery() .eq(QualityMonitor::getMonitorYear, monitorYear) .orderByDesc(QualityMonitor::getCreateTime, QualityMonitor::getQualityMonitorId) .last("limit 1")); } return plan == null ? null : baseMapper.selectPlanDtoById(plan.getQualityMonitorId()); } @Override public boolean submitAnnualPlan(Integer qualityMonitorId) { QualityMonitor plan = requirePlan(qualityMonitorId); int current = SecurityUtils.getUserId().intValue(); if (!Integer.valueOf(current).equals(plan.getWriteUserId())) { throw new ErrorException("åªæè®¡åç¼å¶äººå¯ä»¥æäº¤å®¡æ ¸"); } String state = effectiveStatus(plan); if (!EDITABLE_PLAN_STATES.contains(state)) throw new ErrorException("å½å计åç¶æä¸è½æäº¤å®¡æ ¸"); if (qualityMonitorDetailsMapper.selectCount(Wrappers.<QualityMonitorDetails>lambdaQuery() .eq(QualityMonitorDetails::getQualityMonitorId, qualityMonitorId)) == 0) { throw new ErrorException("请è³å°æ°å¢ä¸æ¡è´¨æ§é¡¹ç®ååæäº¤å®¡æ ¸"); } baseMapper.update(null, Wrappers.<QualityMonitor>lambdaUpdate() .eq(QualityMonitor::getQualityMonitorId, qualityMonitorId) .set(QualityMonitor::getWorkflowStatus, "PENDING_REVIEW") .set(QualityMonitor::getExamineStatus, null) .set(QualityMonitor::getExamineRemark, null) .set(QualityMonitor::getRatifyStatus, null)); sendPlanNotice(plan, plan.getExamineUserId(), "CNASè´¨éçæ§è®¡åå®¡æ ¸éç¥", "è´¨éçæ§è®¡åå¾ å®¡æ ¸"); return true; } @Override public void validateDetailEditable(Integer qualityMonitorId) { QualityMonitor plan = requirePlan(qualityMonitorId); if (!Integer.valueOf(SecurityUtils.getUserId().intValue()).equals(plan.getWriteUserId())) { throw new ErrorException("åªæè®¡åç¼å¶äººå¯ä»¥ç»´æ¤è´¨æ§é¡¹ç®"); } if (!EDITABLE_PLAN_STATES.contains(effectiveStatus(plan))) { throw new ErrorException("å½å计åå·²æäº¤ï¼ä¸è½ä¿®æ¹è´¨æ§é¡¹ç®"); } } private QualityMonitor requirePlan(Integer id) { QualityMonitor plan = id == null ? null : baseMapper.selectById(id); if (plan == null) throw new ErrorException("å¹´åº¦è´¨éæ§å¶è®¡åä¸åå¨"); return plan; } private String effectiveStatus(QualityMonitor plan) { if (StringUtils.isNotBlank(plan.getWorkflowStatus())) return plan.getWorkflowStatus(); if (Integer.valueOf(1).equals(plan.getRatifyStatus())) return "APPROVED"; if (Integer.valueOf(0).equals(plan.getRatifyStatus())) return "APPROVAL_REJECTED"; if (Integer.valueOf(1).equals(plan.getExamineStatus())) return "PENDING_APPROVAL"; if (Integer.valueOf(0).equals(plan.getExamineStatus())) return "REVIEW_REJECTED"; return "DRAFT"; } private void sendPlanNotice(QualityMonitor plan, Integer receiverId, String theme, String suffix) { if (receiverId == null) return; int sender = SecurityUtils.getUserId().intValue(); User senderUser = userMapper.selectById(sender); InformationNotification info = new InformationNotification(); info.setCreateUser(senderUser == null ? "" : senderUser.getName()); info.setMessageType("6"); info.setTheme(theme); info.setContent(plan.getMonitorName() + suffix); info.setSenderId(sender); info.setConsigneeId(receiverId); info.setJumpPath(MenuJumpPathConstants.QUALITY_MONITOR); informationNotificationService.addInformationNotification(info); } /** * å¯¼å ¥çæ§è®¡å @@ -108,17 +216,18 @@ Integer userId = SecurityUtils.getUserId().intValue(); // æä»¶åç§° String fileName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf(".")); if (monitor.getMonitorYear() == null || !monitor.getMonitorYear().matches("\\d{4}")) { throw new ErrorException("è¯·éæ©æ£ç¡®ç计å年度"); } if (monitor.getExamineUserId() == null) throw new ErrorException("缺å°å®¡æ ¸äºº"); QualityMonitor qualityMonitor = new QualityMonitor(); qualityMonitor.setMonitorName(fileName); qualityMonitor.setMonitorYear(monitor.getMonitorYear()); qualityMonitor.setWriteUserId(userId); qualityMonitor.setExamineUserId(monitor.getExamineUserId()); qualityMonitor.setWriteTime(LocalDateTime.now()); qualityMonitor.setWorkflowStatus("PENDING_REVIEW"); baseMapper.insert(qualityMonitor); if (monitor.getExamineUserId() == null) { throw new ErrorException("缺å°å®¡æ ¸äºº"); } User user = userMapper.selectById(userId); // æ¶æ¯åé @@ -159,14 +268,27 @@ EasyExcel.read(file.getInputStream(), QualityMonitorDetailsUpload.class, new AnalysisEventListener<QualityMonitorDetailsUpload>() { @Override public void invoke(QualityMonitorDetailsUpload detailsUpload, AnalysisContext analysisContext) { // 夿æ¯å¦ä¸ºç©º if (StringUtils.isBlank(detailsUpload.getPlannedTime())) { throw new ErrorException("计åå¼å±æ¶é´ä¸è½ä¸ºç©º"); if (StringUtils.isBlank(detailsUpload.getMonitorProject()) || StringUtils.isBlank(detailsUpload.getTechnicalStandardText()) || StringUtils.isBlank(detailsUpload.getMonitorWay()) || StringUtils.isBlank(detailsUpload.getCompletionMonth())) { throw new ErrorException("è´¨æ§é¡¹ç®ãææ¯æ åãè´¨æ§æ¹å¼å宿æ¶éä¸è½ä¸ºç©º"); } // 对象å¤å¶ QualityMonitorDetails monitorDetails = new QualityMonitorDetails(); BeanUtils.copyProperties(detailsUpload, monitorDetails); monitorDetails.setQualityMonitorId(qualityMonitor.getQualityMonitorId()); if (!detailsUpload.getCompletionMonth().matches("\\d{4}-\\d{2}")) { throw new ErrorException("宿æ¶éæ ¼å¼åºä¸ºyyyy-MM"); } if (StringUtils.isBlank(detailsUpload.getResponsibleName())) { throw new ErrorException("è´è´£äººä¸è½ä¸ºç©º"); } List<User> users = userMapper.selectList(Wrappers.<User>lambdaQuery() .eq(User::getName, detailsUpload.getResponsibleName())); if (users.size() != 1) throw new ErrorException("è´è´£äººå§åä¸å卿ä¸å¯ä¸ï¼" + detailsUpload.getResponsibleName()); monitorDetails.setResponsibleUserId(users.get(0).getId()); monitorDetails.setItemKind("OTHER"); detailsUploadList.add(monitorDetails); } @@ -191,8 +313,16 @@ */ @Override public boolean examineQualityMonitor(QualityMonitor qualityMonitor) { if (qualityMonitor.getRatifyUserId() == null) { throw new ErrorException("ç¼ºå°æ¹å人"); QualityMonitor stored = requirePlan(qualityMonitor.getQualityMonitorId()); int current = SecurityUtils.getUserId().intValue(); if (!Integer.valueOf(current).equals(stored.getExamineUserId())) { throw new ErrorException("åªææå®å®¡æ ¸äººå¯ä»¥å®¡æ ¸è®¡å"); } if (!"PENDING_REVIEW".equals(effectiveStatus(stored))) { throw new ErrorException("å½å计åä¸å¨å¾ å®¡æ ¸ç¶æ"); } if (Integer.valueOf(1).equals(qualityMonitor.getExamineStatus()) && qualityMonitor.getRatifyUserId() == null) { throw new ErrorException("å®¡æ ¸éè¿æ¶å¿ é¡»æå®æ¹å人"); } // å½åç»å½ç¨æ· @@ -202,7 +332,11 @@ .set(QualityMonitor::getExamineRemark, qualityMonitor.getExamineRemark()) .set(QualityMonitor::getExamineStatus, qualityMonitor.getExamineStatus()) .set(QualityMonitor::getExamineTime, LocalDateTime.now()) .set(QualityMonitor::getWorkflowStatus, Integer.valueOf(1).equals(qualityMonitor.getExamineStatus()) ? "PENDING_APPROVAL" : "REVIEW_REJECTED") ); if (!Integer.valueOf(1).equals(qualityMonitor.getExamineStatus())) return true; QualityMonitor monitor = baseMapper.selectById(qualityMonitor.getQualityMonitorId()); @@ -247,12 +381,22 @@ */ @Override public boolean ratifyQualityMonitor(QualityMonitor qualityMonitor) { QualityMonitor stored = requirePlan(qualityMonitor.getQualityMonitorId()); int current = SecurityUtils.getUserId().intValue(); if (!Integer.valueOf(current).equals(stored.getRatifyUserId())) { throw new ErrorException("åªææå®æ¹å人å¯ä»¥æ¹å计å"); } if (!"PENDING_APPROVAL".equals(effectiveStatus(stored))) { throw new ErrorException("å½å计åä¸å¨å¾ æ¹åç¶æ"); } // å½åç»å½ç¨æ· baseMapper.update(null, Wrappers.<QualityMonitor>lambdaUpdate() .eq(QualityMonitor::getQualityMonitorId, qualityMonitor.getQualityMonitorId()) .set(QualityMonitor::getRatifyRemark, qualityMonitor.getRatifyRemark()) .set(QualityMonitor::getRatifyStatus, qualityMonitor.getRatifyStatus()) .set(QualityMonitor::getRatifyTime, LocalDateTime.now()) .set(QualityMonitor::getWorkflowStatus, Integer.valueOf(1).equals(qualityMonitor.getRatifyStatus()) ? "APPROVED" : "APPROVAL_REJECTED") ); return true; } cnas-process/src/main/resources/mapper/QualityMonitorDetailsMapper.xml
@@ -4,12 +4,21 @@ <select id="pageQualityMonitorDetail" resultType="com.ruoyi.process.dto.QualityMonitorDetailsDto"> select * from ( SELECT cqmd.*, ru.name responsible_name, eu.name evaluator_name, qot.id inspection_task_id, qot.entrust_code inspection_task_code, qot.ins_state inspection_task_state, qot.state inspection_task_order_state, qmp.ratify_status plan_ratify_status, qmp.ratify_user_id plan_ratify_user_id, CASE WHEN cqmder.is_finish = 1 THEN 3 WHEN cqmder.is_finish = 0 THEN 2 WHEN cqmder.quality_monitor_details_id IS NOT NULL THEN 1 ELSE 0 END details_ratify_status, CASE WHEN cqmd.item_kind = 'INSPECTION' THEN -1 WHEN cqmd.ratify_status = 1 THEN 3 WHEN cqmd.ratify_status = 0 THEN 2 WHEN cqmd.finish_report_url IS NOT NULL THEN 1 @@ -18,8 +27,13 @@ WHEN cqmde.is_finish = 1 THEN 3 WHEN cqmde.ratify_user_id IS NOT NULL THEN 2 WHEN cqmde.implement_user_id IS NOT NULL and cqmde.details_evaluate_id is not null THEN 1 WHEN qot.ins_state = 5 THEN 1 ELSE 0 END evaluate_status FROM cnas_quality_monitor_details cqmd LEFT JOIN user ru ON ru.id = cqmd.responsible_user_id LEFT JOIN user eu ON eu.id = cqmd.evaluator_user_id LEFT JOIN cnas_quality_monitor qmp ON qmp.quality_monitor_id = cqmd.quality_monitor_id LEFT JOIN ins_order qot ON qot.quality_monitor_details_id = cqmd.quality_monitor_details_id LEFT JOIN cnas_quality_monitor_details_evaluate cqmde ON cqmd.quality_monitor_details_id = cqmde.quality_monitor_details_id LEFT JOIN cnas_quality_monitor_details_ratify cqmder @@ -29,12 +43,6 @@ <if test="ew.customSqlSegment != null and ew.customSqlSegment != ''"> ${ew.customSqlSegment} </if> order by quality_monitor_id, monitor_purpose, -- æå年份 CAST(SUBSTRING(planned_time, 1, 4) AS SIGNED) ASC, -- æåæä»½ CASE WHEN planned_time LIKE '% - %' THEN 1 ELSE CAST(SUBSTRING_INDEX(SUBSTRING(planned_time, 6), 'æ', 1) AS SIGNED) END ASC order by quality_monitor_id, COALESCE(sort_no, 2147483647), quality_monitor_details_id </select> </mapper> cnas-process/src/main/resources/mapper/QualityMonitorMapper.xml
@@ -17,4 +17,13 @@ ${ew.customSqlSegment} </if> </select> <select id="selectPlanDtoById" resultType="com.ruoyi.process.dto.QualityMonitorDto"> SELECT cqm.*, u1.name write_name, u2.name examine_name, u3.name ratify_name FROM cnas_quality_monitor cqm LEFT JOIN user u1 ON u1.id = cqm.write_user_id LEFT JOIN user u2 ON u2.id = cqm.examine_user_id LEFT JOIN user u3 ON u3.id = cqm.ratify_user_id WHERE cqm.quality_monitor_id = #{id} </select> </mapper> cnas-process/src/main/resources/mapper/QualityMonitorTaskCodeMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,30 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.ruoyi.process.mapper.QualityMonitorTaskCodeMapper"> <insert id="ensureYear"> INSERT INTO cnas_quality_monitor_task_code_seq(task_year, current_value) VALUES(#{year}, 0) ON DUPLICATE KEY UPDATE task_year = task_year </insert> <select id="lockCurrent" resultType="java.lang.Integer"> SELECT current_value FROM cnas_quality_monitor_task_code_seq WHERE task_year = #{year} FOR UPDATE </select> <update id="updateCurrent"> UPDATE cnas_quality_monitor_task_code_seq SET current_value = #{value} WHERE task_year = #{year} </update> <select id="countStandardTemplateBinding" resultType="java.lang.Integer"> SELECT COUNT(*) FROM standard_tree st JOIN standard_tree_template_binding b ON b.standard_tree_id = st.id WHERE st.standard_method_id = #{standardId} AND b.template_id = #{templateId} </select> </mapper> inspect-server/src/main/java/com/ruoyi/inspect/dto/InsOrderPlanDTO.java
@@ -27,6 +27,9 @@ @Schema(description = "å§æç¼å·") private String entrustCode; @Schema(description = "任塿¥æºï¼ENTRUSTEDæQUALITY_MONITOR") private String taskSource; @Schema(description = "æ£éªç±»å") private Integer typeSource; inspect-server/src/main/java/com/ruoyi/inspect/mapper/InsOrderMapper.java
@@ -29,6 +29,11 @@ @Mapper public interface InsOrderMapper extends BaseMapper<InsOrder> { Integer selectQualityMonitorEvaluatorId(@Param("orderId") Integer orderId); Integer selectQualityMonitorInspectorId(@Param("orderId") Integer orderId); //è·åæ£éªä¸åæ°æ® IPage<SampleOrderDto> selectInsOrderPage(@Param("page") IPage<InsOrder> page, @Param("ew") QueryWrapper<SampleOrderDto> ew, @Param("laboratory") String laboratory, @Param("isOrderAll") String isOrderAll, @Param("receiptSubmitted") String receiptSubmitted); inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrder.java
@@ -36,6 +36,12 @@ @Schema(description = "æ£éªç±»å«") private String orderType; @Schema(description = "任塿¥æºï¼ENTRUSTEDå§æï¼QUALITY_MONITORè´¨éçæ§") private String taskSource; @Schema(description = "è´¨éçæ§è®¡åæç»ID") private Integer qualityMonitorDetailsId; @Schema(description = "ä¸å客æ·") private String custom; inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrderDeviceRecord.java
@@ -16,8 +16,10 @@ */ @Data @TableName("device_record") @Schema(description = "æ£éªä»»å¡è®¾å¤ä½¿ç¨è®°å½") public class InsOrderDeviceRecord { @Schema(description = "设å¤ä½¿ç¨è®°å½ID") @TableId(value = "id", type = IdType.AUTO) private Integer id; inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrderStandardTemplate.java
@@ -17,8 +17,10 @@ */ @Data @TableName(value = "ins_order_standard_template") @Schema(description = "æ£éªä»»å¡åå§è®°å½æ¨¡æ¿å¿«ç §") public class InsOrderStandardTemplate { @Schema(description = "模æ¿å¿«ç §ID") @TableId(type = IdType.AUTO) private Integer id; inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrderTemplateDevice.java
@@ -9,8 +9,10 @@ /** è®¢åæ¨¡æ¿ä¸æ£éªè®¾å¤å ³ç³»ã */ @Data @TableName("ins_order_template_device") @Schema(description = "åå§è®°å½æ¨¡æ¿éç¨è®¾å¤å ³ç³»") public class InsOrderTemplateDevice { @Schema(description = "模æ¿è®¾å¤å ³ç³»ID") @TableId(type = IdType.AUTO) private Integer id; inspect-server/src/main/java/com/ruoyi/inspect/service/InsOrderPlanService.java
@@ -13,6 +13,7 @@ import com.ruoyi.inspect.pojo.InsProduct; import com.ruoyi.inspect.vo.InsOrderPlanTaskSwitchVo; import com.ruoyi.inspect.vo.InsOrderPlanVO; import com.ruoyi.inspect.vo.QualityMonitorRawContext; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.multipart.MultipartFile; @@ -37,6 +38,12 @@ void saveOrderDevices(SaveOrderDevicesDto saveOrderDevicesDto); /** ä»å·²å¤æ ¸çè´¨æ§ä»»å¡åå§è®°å½è¯»åå¯¼åºæ£æµæ°æ®ã */ List<Map<String, String>> getQualityMonitorRawResults(Integer orderId); /** ä»å·²å¤æ ¸çåå§è®°å½è·åæ¯ä¸ªæ¨¡æ¿çæ£æµæ¥æåæé设å¤ã */ QualityMonitorRawContext getQualityMonitorRawContext(Integer orderId); Map<String, Object> doInsOrder(Integer id, String laboratory); int upPlanUser(Integer userId, Integer orderId,String sonLaboratory); inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java
@@ -49,6 +49,7 @@ import com.ruoyi.inspect.util.ReportSignaturePictureUtils; import com.ruoyi.inspect.vo.InsOrderPlanTaskSwitchVo; import com.ruoyi.inspect.vo.InsOrderPlanVO; import com.ruoyi.inspect.vo.QualityMonitorRawContext; import com.ruoyi.inspect.vo.InsSampleUserVO; import com.ruoyi.performance.mapper.AuxiliaryOutputWorkingHoursMapper; import com.ruoyi.performance.pojo.AuxiliaryOutputWorkingHours; @@ -223,6 +224,10 @@ public boolean claimInsOrderPlan(InsOrderPlanDTO entity) { if (Objects.isNull(entity)) { return false; } InsOrder claimOrder = insOrderMapper.selectById(entity.getInsSampleId()); if (claimOrder != null && "QUALITY_MONITOR".equals(claimOrder.getTaskSource())) { throw new ErrorException("è´¨éçæ§ä»»å¡ç±è®¡åæå®æ£æµåï¼ä¸è½è®¤é¢"); } Integer userId = SecurityUtils.getUserId().intValue(); InsSampleUser insSampleUser = new InsSampleUser(entity.getInsSampleId().intValue(), userId, 0, entity.getSonLaboratory()); @@ -612,6 +617,16 @@ public void saveTemplateContext(SaveTemplateContextDto dto) { if (dto.getOrderId() == null || dto.getSampleId() == null || dto.getTemplateId() == null) { throw new ErrorException("订åãæ ·å忍¡æ¿ä¸è½ä¸ºç©º"); } InsOrder sourceOrder = insOrderMapper.selectById(dto.getOrderId()); if (sourceOrder != null && "QUALITY_MONITOR".equals(sourceOrder.getTaskSource()) && !Objects.equals(sourceOrder.getState(), 1)) { throw new ErrorException("已忶çè´¨éçæ§ä»»å¡ä¸è½å¡«ååå§è®°å½"); } if (sourceOrder != null && "QUALITY_MONITOR".equals(sourceOrder.getTaskSource()) && !Objects.equals(SecurityUtils.getUserId().intValue(), insOrderMapper.selectQualityMonitorInspectorId(dto.getOrderId()))) { throw new ErrorException("åªæè®¡åæå®çæ£æµåå¯ä»¥å¡«åè´¨éçæ§åå§è®°å½"); } InsSample sample = insSampleMapper.selectById(dto.getSampleId()); if (sample == null || !Objects.equals(sample.getInsOrderId(), dto.getOrderId())) { @@ -1027,6 +1042,10 @@ //äº¤æ¥ @Override public int upPlanUser(Integer userId, Integer orderId, String sonLaboratory) { InsOrder handoffOrder = insOrderMapper.selectById(orderId); if (handoffOrder != null && "QUALITY_MONITOR".equals(handoffOrder.getTaskSource())) { throw new ErrorException("è´¨éçæ§ä»»å¡æ£æµåç±è®¡åæå®ï¼ä¸è½ç´æ¥äº¤æ¥"); } InsSampleUser insSampleUser = new InsSampleUser(); insSampleUser.setUserId(userId); insSampleUser.setInsSampleId(orderId); @@ -1211,6 +1230,23 @@ InsOrder order = insOrderMapper.selectOne(Wrappers.<InsOrder>lambdaQuery() .eq(InsOrder::getId, orderId) .last("FOR UPDATE")); if (order == null) throw new ErrorException("æ£éªä»»å¡ä¸åå¨"); if ("QUALITY_MONITOR".equals(order.getTaskSource()) && !Objects.equals(order.getState(), 1)) { throw new ErrorException("已忶çè´¨éçæ§ä»»å¡ä¸è½æäº¤"); } if ("QUALITY_MONITOR".equals(order.getTaskSource()) && (verifyUser == null || userMapper.selectById(verifyUser) == null)) { throw new ErrorException("è¯·éæ©è´¨éçæ§ä»»å¡å¤æ ¸äºº"); } if ("QUALITY_MONITOR".equals(order.getTaskSource()) && Objects.equals(verifyUser, insOrderMapper.selectQualityMonitorInspectorId(orderId))) { throw new ErrorException("æ£æµåä¸è½å¤æ ¸èªå·±çè´¨éçæ§åå§è®°å½"); } if ("QUALITY_MONITOR".equals(order.getTaskSource()) && !Objects.equals(SecurityUtils.getUserId().intValue(), insOrderMapper.selectQualityMonitorInspectorId(orderId))) { throw new ErrorException("åªæè®¡åæå®çæ£æµåå¯ä»¥æäº¤è´¨éçæ§ä»»å¡"); } boolean isInspectionReport = Objects.equals(INSPECTION_REPORT, reportType); registerInsResults = isInspectionReport && Boolean.TRUE.equals(registerInsResults); // 1. å§æç¼å·å ¨å±å¯ä¸ï¼æäº¤å¤æ ¸æ¶åæ¬¡æ ¡éªï¼é²æ¢å¹¶åæå岿°æ®ç»è¿çææ ¡éªã @@ -1675,11 +1711,25 @@ if (orderId == null || laboratory == null || type == null) { throw new ErrorException("夿 ¸åæ°ä¸å®æ´"); } InsOrder verifyOrder = insOrderMapper.selectById(orderId); if (verifyOrder == null) throw new ErrorException("æ£éªä»»å¡ä¸åå¨"); if ("QUALITY_MONITOR".equals(verifyOrder.getTaskSource()) && !Objects.equals(verifyOrder.getState(), 1)) { throw new ErrorException("已忶çè´¨éçæ§ä»»å¡ä¸è½å¤æ ¸"); } ensureDirectTemplateOrderState(orderId); InsOrderState currentState = insOrderStateMapper.selectOne(Wrappers.<InsOrderState>lambdaQuery() .eq(InsOrderState::getInsOrderId, orderId) .eq(InsOrderState::getLaboratory, laboratory) .last("limit 1")); if ("QUALITY_MONITOR".equals(verifyOrder.getTaskSource()) && (currentState == null || currentState.getVerifyUser() == null || !Objects.equals(SecurityUtils.getUserId().intValue(), currentState.getVerifyUser()))) { throw new ErrorException("åªææäº¤æ¶æå®ç夿 ¸äººå¯ä»¥å¤æ ¸è´¨éçæ§ä»»å¡"); } if ("QUALITY_MONITOR".equals(verifyOrder.getTaskSource()) && Objects.equals(type, 1) && currentState != null && Objects.equals(currentState.getInsState(), 5)) { return 1; } InsReport existingReport = insReportMapper.selectOne(Wrappers.<InsReport>lambdaQuery() .eq(InsReport::getInsOrderId, orderId) .last("limit 1")); @@ -1738,6 +1788,24 @@ insOrderMapper.update(null, Wrappers.<InsOrder>lambdaUpdate() .eq(InsOrder::getId, orderId) .set(InsOrder::getInsState, 5)); // è´¨éçæ§ä»»å¡åªä¿çåå§è®°å½ï¼åç»ç±è´¨éçæ§è¯ä»·å®æå½æ¡£ã if ("QUALITY_MONITOR".equals(order.getTaskSource())) { Integer evaluatorId = insOrderMapper.selectQualityMonitorEvaluatorId(orderId); if (evaluatorId != null) { InformationNotification notice = new InformationNotification(); notice.setCreateUser(insProductMapper.selectUserById(SecurityUtils.getUserId().intValue()).get("name")); notice.setSenderId(SecurityUtils.getUserId().intValue()); notice.setConsigneeId(evaluatorId); notice.setMessageType("2"); notice.setTheme("è´¨éçæ§è¯ä»·éç¥"); notice.setContent("è´¨éçæ§ä»»å¡ " + order.getEntrustCode() + " çåå§è®°å½å·²å¤æ ¸ï¼è¯·å¡«åè¯ä»·è®°å½"); notice.setViewStatus(false); notice.setJumpPath(MenuJumpPathConstants.QUALITY_MONITOR); informationNotificationService.addInformationNotification(notice); } return 1; } // æ£éªäººåæäº¤å¤æ ¸æ¶ä¸çææ¥åï¼å ¨é¨è¯éªå®¤å¤æ ¸éè¿åçææ¥åã if (report == null || StringUtils.isBlank(report.getUrl())) { @@ -2009,6 +2077,10 @@ * @param orderId */ private void generateReport(Integer orderId, Integer reportType, Integer writeUserId) { InsOrder sourceOrder = insOrderMapper.selectById(orderId); if (sourceOrder != null && "QUALITY_MONITOR".equals(sourceOrder.getTaskSource())) { throw new ErrorException("è´¨éçæ§æ£éªä»»å¡ä¸çææ¥å"); } /*æ ·åä¸ç项ç®åªè¦æä¸ä¸ªé¡¹ç®ä¸åæ ¼åæ£éªç»æä¸º0,å¦å为1*/ //è¿éçinsSamplesæ¯è®¢åä¸çæææ ·åå æ¬("/") List<InsSample> insSamples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery().eq(InsSample::getInsOrderId, orderId)); @@ -3774,6 +3846,40 @@ /** * æ°èç´ç»æ¨¡æ¿è®¢åï¼æ¨¡æ¿ä¸æ¯ä¸ä¸ªâ导åºå¼âæ¹æ³¨é½å¯¹åºæ¥åä¸ç䏿¡æ£æµé¡¹ç®ã */ @Override public List<Map<String, String>> getQualityMonitorRawResults(Integer orderId) { requireReviewedQualityMonitorOrder(orderId); return buildTemplateDetectionResultRows(orderId); } @Override public QualityMonitorRawContext getQualityMonitorRawContext(Integer orderId) { requireReviewedQualityMonitorOrder(orderId); QualityMonitorRawContext context = new QualityMonitorRawContext(); List<InsOrderStandardTemplate> snapshots = insOrderStandardTemplateService.list( Wrappers.<InsOrderStandardTemplate>lambdaQuery() .eq(InsOrderStandardTemplate::getInsOrderId, orderId) .orderByAsc(InsOrderStandardTemplate::getSort, InsOrderStandardTemplate::getId)); context.setDetectionDates(snapshots.stream().map(InsOrderStandardTemplate::getDetectionTime) .filter(Objects::nonNull).distinct().sorted().collect(Collectors.toList())); List<Integer> deviceIds = insOrderTemplateDeviceMapper.selectDeviceIdsByOrderId(orderId); if (CollectionUtils.isNotEmpty(deviceIds)) { context.setDevices(insOrderMapper.selectDeviceListByIds(new LinkedHashSet<>(deviceIds))); } return context; } private void requireReviewedQualityMonitorOrder(Integer orderId) { InsOrder order = insOrderMapper.selectById(orderId); if (order == null || !"QUALITY_MONITOR".equals(order.getTaskSource()) || !Objects.equals(order.getInsState(), 5)) { throw new ErrorException("è´¨æ§ä»»å¡åå§è®°å½å¤æ ¸éè¿åæè½è¯»åæ£æµæ°æ®"); } Long pendingCount = insOrderStateMapper.selectCount(Wrappers.<InsOrderState>lambdaQuery() .eq(InsOrderState::getInsOrderId, orderId).ne(InsOrderState::getInsState, 5)); if (pendingCount > 0) throw new ErrorException("è´¨æ§ä»»å¡ä»ææªå¤æ ¸çåå§è®°å½"); } private List<Map<String, String>> buildTemplateDetectionResultRows(Integer orderId) { List<InsOrderStandardTemplate> snapshots = insOrderStandardTemplateService.list( Wrappers.<InsOrderStandardTemplate>lambdaQuery() inspect-server/src/main/java/com/ruoyi/inspect/vo/IfsOrderVO.java
@@ -77,4 +77,5 @@ @Schema(description = "ååå§è®°å½æ¨¡æ¿çç¯å¢æ¡ä»¶") private List<TemplateConditionVo> templateConditions; } inspect-server/src/main/java/com/ruoyi/inspect/vo/InsOrderPlanTaskSwitchVo.java
@@ -9,6 +9,8 @@ private String entrustCode; private String taskSource; private String sampleType; @Schema(description = "ç´§æ¥ç¨åº¦") inspect-server/src/main/java/com/ruoyi/inspect/vo/InsOrderPlanVO.java
@@ -12,6 +12,19 @@ @Schema(description = "å§æç¼å·") private String entrustCode; private String taskSource; private Integer qualityMonitorDetailsId; private String monitorProject; private String dueDate; private String monitorPurpose; private String monitorWay; private String sampleSpec; private String standardCode; private Integer evaluatorUserId; private Integer planRatifyUserId; private Integer evaluateStatus; private String technicalStandardText; @Schema(description = "æ ·ååç§°") private String sample; inspect-server/src/main/java/com/ruoyi/inspect/vo/QualityMonitorRawContext.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,23 @@ package com.ruoyi.inspect.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * 已夿 ¸çè´¨æ§åå§è®°å½ä¸ç¨äºè¯ä»·è¡¨çæ¥æå设å¤ã */ @Data @Schema(description = "已夿 ¸è´¨æ§åå§è®°å½ä¸çæ£æµæ¥æä¸æç¨è®¾å¤") public class QualityMonitorRawContext { @Schema(description = "ååå§è®°å½æ¨¡æ¿çæ£æµæ¥æï¼å»éå¹¶ææ¥æååºæå") private List<LocalDate> detectionDates = new ArrayList<>(); @Schema(description = "ä»»å¡å®é éç¨ç设å¤ä¿¡æ¯ï¼æè®¾å¤éæ©é¡ºåºæå") private List<Map<String, String>> devices = new ArrayList<>(); } inspect-server/src/main/resources/mapper/InsOrderMapper.xml
@@ -4,6 +4,22 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.inspect.mapper.InsOrderMapper"> <select id="selectQualityMonitorEvaluatorId" resultType="java.lang.Integer"> SELECT cqmd.evaluator_user_id FROM ins_order io JOIN cnas_quality_monitor_details cqmd ON cqmd.quality_monitor_details_id = io.quality_monitor_details_id WHERE io.id = #{orderId} </select> <select id="selectQualityMonitorInspectorId" resultType="java.lang.Integer"> SELECT cqmd.inspector_user_id FROM ins_order io JOIN cnas_quality_monitor_details cqmd ON cqmd.quality_monitor_details_id = io.quality_monitor_details_id WHERE io.id = #{orderId} </select> <resultMap id="selectSampleDefectsMap" type="com.ruoyi.inspect.vo.SampleDefectsFatherVo"> <id column="id" property="id"/> <result column="sample" property="sample"/> inspect-server/src/main/resources/mapper/InsSampleMapper.xml
@@ -205,6 +205,24 @@ io.appointed, io.send_time, io.order_type, io.task_source, io.quality_monitor_details_id, cqmd.monitor_project, cqmd.due_date, cqmd.monitor_purpose, cqmd.monitor_way, cqmd.sample_spec, cqmd.evaluator_user_id, cqmd.technical_standard_text, qmp.ratify_user_id plan_ratify_user_id, CASE WHEN cqmde.is_finish = 1 THEN 3 WHEN cqmde.ratify_user_id IS NOT NULL THEN 2 WHEN cqmde.details_evaluate_id IS NOT NULL THEN 1 WHEN io.ins_state = 5 THEN 1 ELSE 0 END evaluate_status, qsm.code standard_code, case when io.type_source = 0 then io.sample_view @@ -230,6 +248,10 @@ iiq.material_prop AS material_prop FROM ins_order io LEFT JOIN cnas_quality_monitor_details cqmd ON cqmd.quality_monitor_details_id = io.quality_monitor_details_id LEFT JOIN cnas_quality_monitor qmp ON qmp.quality_monitor_id = cqmd.quality_monitor_id LEFT JOIN cnas_quality_monitor_details_evaluate cqmde ON cqmde.quality_monitor_details_id = cqmd.quality_monitor_details_id LEFT JOIN standard_method qsm ON qsm.id = cqmd.standard_method_id LEFT JOIN ins_sample isa ON isa.ins_order_id = io.id LEFT JOIN ins_report ira ON ira.ins_order_id = io.id LEFT JOIN ifs_inventory_quantity iiq ON iiq.id = io.ifs_inventory_id @@ -310,6 +332,7 @@ SELECT io.id, io.entrust_code, io.task_source, io.type, io.appointed, io.send_time,