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.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 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 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 resolveTemplateIds(QualityMonitorDetails detail) { String rawIds = detail.getTemplateIds(); if (!StringUtils.hasText(rawIds) && detail.getTemplateId() != null) { rawIds = String.valueOf(detail.getTemplateId()); } Set 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.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.lambdaQuery() .eq(InsOrderState::getInsOrderId, task.getId()).ne(InsOrderState::getInsState, 0)); if (startedStates > 0) throw new ErrorException("任务已开始,不能取消"); Long filledSnapshots = snapshotMapper.selectCount(Wrappers.lambdaQuery() .eq(InsOrderStandardTemplate::getInsOrderId, task.getId()) .isNotNull(InsOrderStandardTemplate::getRecordValues)); if (filledSnapshots > 0) throw new ErrorException("原始记录已填写,不能取消任务"); task.setState(5); orderMapper.updateById(task); } }