| | |
| | | package com.dy.pmsStation.assemblyStep; |
| | | |
| | | import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; |
| | | import com.baomidou.mybatisplus.core.toolkit.StringUtils; |
| | | import com.dy.pmsGlobal.daoOth.OthFileMapper; |
| | | import com.dy.pmsGlobal.daoPlt.*; |
| | | import com.dy.pmsGlobal.daoPr.PrAssemblyPlanMapper; |
| | | import com.dy.pmsGlobal.daoPr.PrProductionNodeMapper; |
| | | import com.dy.pmsGlobal.daoSta.*; |
| | | import com.dy.pmsGlobal.dyFile.FileOperate; |
| | | import com.dy.pmsGlobal.dyFile.FileRestVo; |
| | | import com.dy.pmsGlobal.pojoOth.OthFile; |
| | | import com.dy.pmsGlobal.pojoPlt.*; |
| | | import com.dy.pmsGlobal.pojoPr.PrAssemblyPlan; |
| | | import com.dy.pmsGlobal.pojoPr.PrProductionNode; |
| | | import com.dy.pmsGlobal.pojoPr.PrWorkingInstruction; |
| | | import com.dy.pmsGlobal.pojoSta.*; |
| | | import com.dy.pmsGlobal.util.DeviceStatus; |
| | | import com.dy.pmsGlobal.util.QrCodeConstant; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.*; |
| | | |
| | | @Slf4j |
| | | @Service |
| | | public class AssemblyStepSv { |
| | | private static final int STATUS_OK = 1; |
| | | private static final int STATUS_COMPLETE = 2; |
| | | private static final int STATUS_REPAIR = 3; |
| | | private static final int STATUS_WASTE = 4; |
| | | private static final String WORK_TYPE_ASSEMBLY = "1"; |
| | | private static final String WORK_TYPE_TEST = "2"; |
| | | private static final String WORK_TYPE_INSPECTION = "3"; |
| | | private static final String WORK_TYPE_REPAIR = "4"; |
| | | |
| | | private StaDeviceLastMapper deviceLastDao; |
| | | private StaDeviceLifeMapper deviceLifeDao; |
| | |
| | | private StaDeviceProductionLogMapper deviceProductionLogDao; |
| | | private StaAssemblyWorkLastMapper assemblyWorkLastDao; |
| | | private PrAssemblyPlanMapper assemblyPlanDao; |
| | | // private PrProductionProcessMapper processDao; |
| | | // private PrProductionProcessMapper processDao; |
| | | private PrProductionNodeMapper nodeDao; |
| | | private StaRepairInfoMapper repairInfoDao; |
| | | private PltProductQualityInspectionItemsMapper qualityItemsDao; |
| | | private PltProductTestInspectionItemsMapper testItemsDao; |
| | | private PltProductMapper productDao; |
| | | private PltProParamsMapper paramsDao; |
| | | private PltProductFileMapper productFileDao; |
| | | private FileOperate fileOperate; |
| | | private OthFileMapper othFileMapper; |
| | | @Value("${dy.webFile.fmUrl}") |
| | | private String fmUrl; |
| | | |
| | | @Autowired |
| | | public void setDeviceLastDao(StaDeviceLastMapper deviceLastDao) { |
| | | this.deviceLastDao = deviceLastDao; |
| | |
| | | public void setRepairInfoDao(StaRepairInfoMapper repairInfoDao) { |
| | | this.repairInfoDao = repairInfoDao; |
| | | } |
| | | @Autowired |
| | | public void setQualityItemsDao(PltProductQualityInspectionItemsMapper qualityItemsDao) { |
| | | this.qualityItemsDao = qualityItemsDao; |
| | | } |
| | | @Autowired |
| | | public void setTestItemsDao(PltProductTestInspectionItemsMapper testItemsDao) { |
| | | this.testItemsDao = testItemsDao; |
| | | } |
| | | @Autowired |
| | | public void setProductDao(PltProductMapper productDao) { |
| | | this.productDao = productDao; |
| | | } |
| | | |
| | | @Autowired |
| | | public void setParamsDao(PltProParamsMapper paramsDao) { |
| | | this.paramsDao = paramsDao; |
| | | } |
| | | |
| | | @Autowired |
| | | public void setProductFileDao(PltProductFileMapper productFileDao) { |
| | | this.productFileDao = productFileDao; |
| | | } |
| | | |
| | | @Autowired |
| | | public void setFileOperate(FileOperate fileOperate) { |
| | | this.fileOperate = fileOperate; |
| | | } |
| | | |
| | | @Autowired |
| | | public void setOthFileMapper(OthFileMapper othFileMapper) { |
| | | this.othFileMapper = othFileMapper; |
| | | } |
| | | |
| | | @Transactional |
| | | public int save(QueryVo params) { |
| | | long workId = Long.parseLong(params.workId); |
| | | StaAssemblyWorkLast workLast = assemblyWorkLastDao.selectByPrimaryKey(workId); |
| | | if (workLast == null) { |
| | | throw new RuntimeException("系统中没有该条登录信息");//工单不存在 |
| | | } |
| | | //fancy 2024/6/27 是不是可以不用检查任务与设备码... |
| | | PrAssemblyPlan plan = assemblyPlanDao.selectByPrimaryKey(workLast.getPlanId()); |
| | | // 验证并处理设备号和物料号 |
| | | Set<String> deviceSet = new HashSet<>(Arrays.asList(params.deviceNo.split(","))); |
| | | // 分类设备号和物料号 |
| | | List<String> deviceList = new ArrayList<>(); |
| | | List<String> materialList = new ArrayList<>(); |
| | | |
| | | List<PltProduct> productList = productDao.selectAll(null); |
| | | deviceSet.forEach(device -> { |
| | | if (device.contains(plan.batchNo)) { |
| | | deviceList.add(device); |
| | | } else { |
| | | } else if(isOurProduct(device,productList)){ |
| | | materialList.add(device); |
| | | } |
| | | }); |
| | | |
| | | if (deviceList.isEmpty()) { |
| | | throw new RuntimeException("设备号("+ params.deviceNo +")均不属于当前任务计划"); |
| | | throw new RuntimeException("设备号(" + params.deviceNo + ")均不属于当前任务计划"); |
| | | } |
| | | if (deviceList.size() > 1) { |
| | | throw new RuntimeException("设备号有且只能有一个属于当前任务计划"); |
| | |
| | | deviceLifeDao.insertSelective(life); |
| | | } |
| | | |
| | | private StaDeviceLast buildDeviceLast(QueryVo params, StaAssemblyWorkLast workLast, String deviceNo){ |
| | | private StaDeviceLast buildDeviceLast(QueryVo params, StaAssemblyWorkLast workLast,String deviceNo) { |
| | | //组装数据 |
| | | StaDeviceLast record = new StaDeviceLast(); |
| | | |
| | | StaDeviceLast preRecord = deviceLastDao.selectByDeviceNo(deviceNo); |
| | | if(preRecord != null){ |
| | | if (preRecord != null) { |
| | | record.id = preRecord.id; |
| | | record.inTime = preRecord.outTime; |
| | | } |
| | |
| | | record.planId = workLast.planId; |
| | | record.workId = Long.parseLong(params.workId); |
| | | record.stationId = workLast.stationId; |
| | | record.equipNo = deviceNo; |
| | | record.deviceNo = deviceNo; |
| | | record.currNode = workLast.nodeId; |
| | | // record.setNextNode(getNextNode(params.status,workLast.nodeId)); |
| | | |
| | | record.updatedBy = workLast.userId; |
| | | record.assistants = params.assistants; |
| | | record.errorMsg = params.errorMsg; |
| | | |
| | | PrProductionNode node = nodeDao.selectByPrimaryKey(workLast.nodeId); |
| | | record.nodeContent = node.content; |
| | | if(node.isRecord){ |
| | | record.equipCycleContent = node.equipCycleContent; |
| | | if (node.isRecord) { |
| | | record.deviceCycleContent = node.equipCycleContent; |
| | | } |
| | | record.status = getStatus(params.status,node.isEnd); |
| | | record.status = getStatus(params.status, node.isEnd,params.workType); |
| | | return record; |
| | | } |
| | | private int saveSnEx(StaAssemblyWorkLast workLast, List<String> deviceList,List<String> materialList, PrAssemblyPlan plan){ |
| | | StaWipSnEx snEx = new StaWipSnEx(); |
| | | snEx.deviceNo = deviceList.get(0); |
| | | snEx.productNo = plan.batchNo; |
| | | snEx.deviceNo = materialList.get(0); |
| | | snEx.createTime = workLast.startTime; |
| | | snEx.createBy = workLast.userId; |
| | | snEx.productName = plan.proName; |
| | | return wipSnExDao.insertSelective(snEx); |
| | | |
| | | private void saveSnEx(StaAssemblyWorkLast workLast, List<String> deviceList, List<String> materialList, PrAssemblyPlan plan) { |
| | | for (String material : materialList) { |
| | | StaWipSnEx snEx = new StaWipSnEx(); |
| | | snEx.deviceNo = deviceList.get(0); |
| | | snEx.productId = plan.process.proId; |
| | | snEx.productNo = material; |
| | | snEx.createTime = workLast.startTime; |
| | | snEx.createBy = workLast.userId; |
| | | snEx.productName = plan.proName; |
| | | wipSnExDao.insertSelective(snEx); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 状态: 1:组装中,2:完成,3:维修,4:报废 |
| | | * @param status 状态 |
| | | * |
| | | * @param status 状态 |
| | | * @param isEndNode 是否结束节点 |
| | | * @return 状态 |
| | | */ |
| | | private int getStatus(String status,boolean isEndNode){ |
| | | return switch (status) { |
| | | case QrCodeConstant.MarkOk -> isEndNode? STATUS_COMPLETE:STATUS_OK; |
| | | case QrCodeConstant.MarkUnqualified -> STATUS_REPAIR; |
| | | case QrCodeConstant.MarkWaste -> STATUS_WASTE; |
| | | default -> throw new RuntimeException("状态错误"); |
| | | }; |
| | | private int getStatus(String status, boolean isEndNode,String workType) { |
| | | //组装,维修 |
| | | if (WORK_TYPE_ASSEMBLY.equals(workType)||WORK_TYPE_REPAIR.equals(workType)) { |
| | | return switch (status) { |
| | | case QrCodeConstant.MarkOk -> isEndNode? DeviceStatus.COMPLETED.getCode(): DeviceStatus.ASSEMBLING.getCode(); |
| | | case QrCodeConstant.MarkUnqualified, QrCodeConstant.MarkPreUnqualified -> DeviceStatus.REPAIR.getCode(); |
| | | case QrCodeConstant.MarkWaste -> DeviceStatus.WASTE.getCode(); |
| | | default -> throw new RuntimeException("状态错误"); |
| | | }; |
| | | //品检,测试 |
| | | }else if(WORK_TYPE_INSPECTION.equals(workType)||WORK_TYPE_TEST.equals(workType)){ |
| | | return switch (status) { |
| | | case QrCodeConstant.MarkOk -> DeviceStatus.COMPLETED.getCode(); |
| | | case QrCodeConstant.MarkUnqualified -> DeviceStatus.TEST_FAILED.getCode(); |
| | | case QrCodeConstant.MarkWaste -> DeviceStatus.WASTE.getCode(); |
| | | default -> throw new RuntimeException("状态错误"); |
| | | }; |
| | | } |
| | | throw new RuntimeException("状态错误,无效的节点类型: " + workType); |
| | | } |
| | | |
| | | public int repair(QueryVo vo) { |
| | | long workId = Long.parseLong(vo.workId); |
| | | StaAssemblyWorkLast workLast = assemblyWorkLastDao.selectByPrimaryKey(workId); |
| | | if (workLast == null) { |
| | | throw new RuntimeException("工单不存在"); |
| | | throw new RuntimeException("系统中没有该条登录信息"); |
| | | } |
| | | StaDeviceLast preDeviceRecord = deviceLastDao.selectByDeviceNo(vo.deviceNo); |
| | | StaRepairInfo repairInfo = new StaRepairInfo(); |
| | | repairInfo.workId = workId; |
| | | repairInfo.equipNo = vo.deviceNo; |
| | | repairInfo.deviceNo = vo.deviceNo; |
| | | repairInfo.repairTime = new Date(); |
| | | repairInfo.repairBy = workLast.userId; |
| | | repairInfo.repairReason = vo.errorMsg; |
| | | repairInfo.fromNode = preDeviceRecord.currNode; |
| | | repairInfoDao.insertSelective(repairInfo); |
| | | |
| | | StaDeviceLast deviceLast = new StaDeviceLast(); |
| | | BeanUtils.copyProperties(preDeviceRecord, deviceLast); |
| | | deviceLast.repairId = repairInfo.id; |
| | | deviceLast.errorCode = vo.errorMsg; |
| | | deviceLast.assistants = vo.assistants; |
| | | //如果原节点是结束节点或之后的节点,是则更新为完成,否则更新为组装中(默认维修节点的状态只能为 确定或 报废) |
| | | boolean isEndNode = nodeDao.isEndNode(preDeviceRecord.currNode); |
| | | if(QrCodeConstant.MarkWaste.equals(vo.status)){ |
| | | deviceLast.status = STATUS_WASTE; |
| | | }else{ |
| | | deviceLast.status = isEndNode? STATUS_COMPLETE:STATUS_OK; |
| | | } |
| | | StaDeviceLast deviceLast = buildDeviceLast(vo, workLast, vo.deviceNo); |
| | | |
| | | int count = deviceLast.id == null ? deviceLastDao.insertSelective(deviceLast) : |
| | | deviceLastDao.updateByPrimaryKeySelective(deviceLast); |
| | | saveDeviceProductionLog(deviceLast); |
| | | |
| | | boolean isEndNode = nodeDao.isEndNode(preDeviceRecord.currNode); |
| | | if (isEndNode) { |
| | | saveDeviceLife(deviceLast); |
| | | } |
| | | return count; |
| | | } |
| | | |
| | | public int testing(QueryVo vo) { |
| | | long workId = Long.parseLong(vo.workId); |
| | | StaAssemblyWorkLast workLast = assemblyWorkLastDao.selectByPrimaryKey(workId); |
| | | if (workLast == null) { |
| | | throw new RuntimeException("系统中没有该条登录信息"); |
| | | } |
| | | |
| | | StaDeviceLast deviceLast = buildDeviceLast(vo, workLast, vo.deviceNo); |
| | | int count = deviceLast.id == null ? deviceLastDao.insertSelective(deviceLast) : |
| | | deviceLastDao.updateByPrimaryKeySelective(deviceLast); |
| | | saveDeviceProductionLog(deviceLast); |
| | | return count; |
| | | } |
| | | //根据节点查出节点作业指导书 |
| | | public PrProductionNode getSopByNodeId(String nodeId) { |
| | | if(com.alibaba.excel.util.StringUtils.isBlank(nodeId)){ |
| | | throw new RuntimeException("节点ID不能为空"); |
| | | } |
| | | PrProductionNode node = nodeDao.selectByPrimaryKey(Long.parseLong(nodeId)); |
| | | if(node == null){ |
| | | throw new RuntimeException("节点ID不存在,请检查"); |
| | | } |
| | | if(node.instruction != null){ |
| | | addUrl(node.instruction); |
| | | } |
| | | return node; |
| | | } |
| | | //主要技术参数 俩个方法同 platform-->product-->productSv |
| | | public List<PltProductParams> getParamsByProId(String proId) { |
| | | if(StringUtils.isBlank(proId)){ |
| | | throw new RuntimeException("产品ID不能为空"); |
| | | } |
| | | List<PltProductParams> proParams = paramsDao.selectParams(Long.parseLong(proId)); |
| | | return proParams; |
| | | } |
| | | // 根据产品查出产品文件 |
| | | public List<PltProductFile> getFileByProId(String proId) { |
| | | if(StringUtils.isBlank(proId)){ |
| | | throw new RuntimeException("产品ID不能为空"); |
| | | } |
| | | List<PltProductFile> proFiles = productFileDao.selectDocuments(Long.parseLong(proId)); |
| | | proFiles.stream().forEach(doc -> { |
| | | OthFile file = othFileMapper.selectByPrimaryKey(doc.fileId); |
| | | if (file == null) { |
| | | return; |
| | | } |
| | | FileRestVo fileRestVo = fileOperate.parseHashcode(fmUrl, file.hash); |
| | | doc.webUrl = fileRestVo.fileSysRestUrl + fileRestVo.fileWebDownloadPath + doc.fileId; |
| | | doc.orgName = file.orgName; |
| | | doc.extName = file.extName; |
| | | }); |
| | | return proFiles; |
| | | } |
| | | |
| | | public List<PltProductQualityInspectionItems> getQualityItems(String proId) { |
| | | Map<String, Object> params = new HashMap<>(); |
| | | params.put("proId", proId);//item start count |
| | | //查询符合条件的记录 |
| | | return qualityItemsDao.selectSome(params); |
| | | } |
| | | |
| | | public List<PltProductTestInspectionItems> getTestItems(String proId) { |
| | | Map<String, Object> params = new HashMap<>(); |
| | | params.put("proId", proId); |
| | | return testItemsDao.selectSome(params); |
| | | } |
| | | |
| | | private boolean isOurProduct(String deviceNo, List<PltProduct> products){ |
| | | if(StringUtils.isNotEmpty(deviceNo) && deviceNo.length() ==22 ){ |
| | | for(PltProduct product:products){ |
| | | if(deviceNo.startsWith(QrCodeConstant.TypeProduct + product.getCode())){ |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | private void addUrl(PrWorkingInstruction ins) { |
| | | if (ins == null || ins.fileId == null) { |
| | | return; |
| | | } |
| | | OthFile file = othFileMapper.selectByPrimaryKey(ins.fileId); |
| | | if (file == null) { |
| | | return; |
| | | } |
| | | FileRestVo fileRestVo = fileOperate.parseHashcode(fmUrl, file.hash); |
| | | ins.webUrl = fileRestVo.fileSysRestUrl + fileRestVo.fileWebDownloadPath + ins.fileId; |
| | | ins.orgName = file.orgName; |
| | | ins.extName = file.extName; |
| | | } |
| | | private PltProduct addWebUrl(PltProduct pro) { |
| | | if (pro != null) { |
| | | if (pro.image != null) { |
| | | String filePathWithWebUrl = getFilePathWithWebUrl(pro.image); |
| | | pro.imageWebPath = filePathWithWebUrl; |
| | | pro.imageWebPathZip = fileOperate.getImgFileZipPath(filePathWithWebUrl); |
| | | } |
| | | |
| | | pro.proFiles.stream().forEach(doc -> { |
| | | OthFile file = othFileMapper.selectByPrimaryKey(doc.fileId); |
| | | if (file == null) { |
| | | return; |
| | | } |
| | | FileRestVo fileRestVo = fileOperate.parseHashcode(fmUrl, file.hash); |
| | | doc.webUrl = fileRestVo.fileSysRestUrl + fileRestVo.fileWebDownloadPath + doc.fileId; |
| | | doc.orgName = file.orgName; |
| | | doc.extName = file.extName; |
| | | }); |
| | | } |
| | | return pro; |
| | | } |
| | | private String getFilePathWithWebUrl(Long fileId) { |
| | | OthFile file = othFileMapper.selectByPrimaryKey(fileId); |
| | | FileRestVo fileRestVo = fileOperate.parseHashcode(fmUrl, file.hash); |
| | | return fileRestVo.fileWebUrl + file.filePath; |
| | | } |
| | | |
| | | public Map<String,String> queryByDeviceNo(String deviceNo) { |
| | | Map<String,String> map = new HashMap<>(); |
| | | map.put("deviceNo", deviceNo); |
| | | map.put("proName", "-"); |
| | | map.put("proType", "-"); |
| | | |
| | | PltProduct product = productDao.selectByCode(deviceNo.substring(3,6)); |
| | | if(product != null){ |
| | | map.put("proName", product.getName()); |
| | | map.put("proType", product.getType()); |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | public List<StaDeviceLife> queryLifeByDeviceNo(String deviceNo) { |
| | | return deviceLifeDao.selectByDeviceNo(deviceNo); |
| | | } |
| | | |
| | | public List<StaDeviceProductionLog> queryLogByDeviceNo(String devoiceNo) { |
| | | return deviceProductionLogDao.selectByDeviceNo(devoiceNo); |
| | | } |
| | | } |