package com.chinaztt.mes.quality.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import com.chinaztt.ifs.api.feign.IfsFeignClient; import com.chinaztt.inspect.api.feign.InspectFeignClient; import com.chinaztt.mes.common.numgen.NumberGenerator; import com.chinaztt.mes.quality.dto.ReportSampleDTO; import com.chinaztt.mes.quality.dto.ReportSampleItemDTO; import com.chinaztt.mes.quality.dto.ValidateIsCheckItemDTO; import com.chinaztt.mes.quality.entity.*; import com.chinaztt.mes.quality.mapper.*; import com.chinaztt.mes.quality.service.ReportSampleItemService; import com.chinaztt.mes.quality.service.ReportSampleService; import com.chinaztt.mes.quality.state.result.constant.ResultStateStringValues; import com.chinaztt.mes.quality.utils.AutoJudgmentUtils; import com.chinaztt.mes.quality.utils.ReportUtils; import com.chinaztt.mes.quality.utils.SelfJudgmentUtils; import com.chinaztt.mes.warehouse.dto.ValidateWeighPackagingDTO; import com.chinaztt.ztt.common.core.util.R; import com.chinaztt.ztt.common.oss.OssProperties; import com.chinaztt.ztt.common.oss.service.OssTemplate; import com.chinaztt.ztt.common.security.util.SecurityUtils; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.math.NumberUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.math.BigDecimal; import java.text.DecimalFormat; import java.util.*; import java.util.stream.Collectors; /** * 检测汇报样品表 * * @author cxf * @date 2021-04-06 14:29:44 */ @Slf4j @Service @AllArgsConstructor @Transactional(rollbackFor = Exception.class) public class ReportSampleServiceImpl extends ServiceImpl implements ReportSampleService { private final OssProperties ossProperties; private final OssTemplate minioTemplate; private NumberGenerator reportSampleNumberGenerator; private ReportSampleItemMapper reportSampleItemMapper; private ReportMapper reportMapper; private ReportUtils reportUtils; private SelfJudgmentUtils selfJudgmentUtils; private ApplyPartMapper applyPartMapper; private ReportSampleAttachmentMapper reportSampleAttachmentMapper; private TestStandardMapper testStandardMapper; private ReportSampleItemService reportSampleItemService; private InspectFeignClient inspectFeignClient; @Override public boolean saveBatchList(List reportSampleList) { for (ReportSample reportSample : reportSampleList) { reportSample.setSampleNo(reportSampleNumberGenerator.generateNumberWithPrefix(ReportSample.DIGIT, ReportSample.PREFIX, ReportSample::getSampleNo)); //这里增加一个检测标准id字段值的自动校正补充功能 if(true || reportSample.getTestStandardId() == null){//改成直接矫正,applyPart表中的检测标准不准 //根据产出系统编号、检测汇报id获取检测制造订单检测标准id Long moTestStandardId = baseMapper.getMoTestStandardId(reportSample.getReportId(),reportSample.getSystemNo()); String moTestStandardNo = baseMapper.getMoTestStandardNoById(moTestStandardId); reportSample.setTestStandardId(moTestStandardId); reportSample.setTestStandardNo(moTestStandardNo); } baseMapper.insert(reportSample); if (StringUtils.isNotBlank(reportSample.getTestStandardNo())) { // 这边查的是制造订单的检测标准 reportSampleItemMapper.insertMoSampleItemsById(reportSample); // 获取配置继承检测参数的检测汇报项 List extendsItemList = reportSampleItemMapper.selectList(Wrappers.lambdaQuery().eq(ReportSampleItem::getReportSampleId, reportSample.getId()) .isNotNull(ReportSampleItem::getExtendsTestStandardParamId)); if (CollectionUtil.isEmpty(extendsItemList)) { return true; } List technologyDocumentStandardParamIdList = extendsItemList.stream().map(ReportSampleItem::getExtendsTestStandardParamId).collect(Collectors.toList()); Set systemNoSet = new HashSet<>(); // 将自己系统编号加进来,有可能继承检测项是同一道工序下,因此根据投入找不到检测项 systemNoSet.add(reportSample.getSystemNo()); getInputSystemNoByOutReportSampleSystemNo(systemNoSet, Collections.singletonList(reportSample.getSystemNo())); // 获取继承检验参数项检测结果 List parentItemList = reportSampleItemMapper.getParentItemList(technologyDocumentStandardParamIdList, systemNoSet); Map> extendsItemMap = extendsItemList.stream().collect(Collectors.groupingBy(ReportSampleItem::getExtendsTestStandardParamId)); Map parentItemMap = parentItemList.stream().collect(Collectors.toMap(ReportSampleItem::getTechnologyDocumentStandardParamId, item -> item, (k1, k2) -> k1)); // 将继承的参数项结果值,复制到当前检测结果中 for (Map.Entry> entry : extendsItemMap.entrySet()) { if (!parentItemMap.containsKey(entry.getKey())) { entry.getValue().forEach(v->v.setExtendsResultFlag(Boolean.FALSE)); }else{ entry.getValue().forEach(v->{ v.setItemValue(parentItemMap.get(entry.getKey()).getItemValue()); v.setExtendsResultFlag(Boolean.TRUE); }); } } reportSampleItemService.updateBatchById(extendsItemList); } } return true; } /** * 递归获取当前产出的投入 * @param systemNo * @return */ private void getInputSystemNoByOutReportSampleSystemNo(SetsystemNoSet, List systemNos) { // 获取当前系统号产出的投入系统号 List inputSystemNos = reportSampleItemMapper.getInputSystemNoByOutReportSampleSystemNo(systemNos); if (CollectionUtil.isNotEmpty(inputSystemNos)) { getInputSystemNoByOutReportSampleSystemNo(systemNoSet, inputSystemNos); systemNoSet.addAll(inputSystemNos); } } @Override public List getReportSampleList(QueryWrapper gen) { return baseMapper.getReportSampleList(gen); } @Override public ReportSample updateSampleById(ReportSample reportSample) { // 如果检测标准编号被修改了,需要替换样品检测项目 ReportSample oldReportSample = baseMapper.selectById(reportSample.getId()); String oldTestStandardNo = oldReportSample.getTestStandardNo(); String testStandardNo = reportSample.getTestStandardNo(); if (StringUtils.isNotBlank(oldTestStandardNo) && StringUtils.isNotBlank(testStandardNo) && oldTestStandardNo.trim().equals(testStandardNo.trim())) { } else { // 先去查询检测标准编号对应的检测标准 TestStandard newTestStandard = testStandardMapper.selectOne(Wrappers.lambdaQuery().eq(TestStandard::getActive, true) .eq(TestStandard::getStandardNo, testStandardNo)); if (newTestStandard == null) { throw new RuntimeException("质量-检测标准中不存在输入的检测标准编号,请确认"); } // 样品的检测标准编号被修改,就认为是质量-检测标准 reportSample.setIsMoTestStandard(false); reportSample.setTestStandardId(newTestStandard.getId()); reportSampleItemMapper.delete(Wrappers.query().lambda().eq(ReportSampleItem::getReportSampleId, reportSample.getId())); // 这边查的是检测标准 reportSampleItemMapper.insertSampleItemsById(reportSample); } baseMapper.updateById(reportSample); return reportSample; } @Override public ReportSample updateSampleByIdV2(ReportSample reportSample) { // 如果检测标准编号被修改了,需要替换样品检测项目 ReportSample oldReportSample = baseMapper.selectById(reportSample.getId()); String oldTestStandardNo = oldReportSample.getTestStandardNo(); String testStandardNo = reportSample.getTestStandardNo(); if (StringUtils.isNotBlank(oldTestStandardNo) && StringUtils.isNotBlank(testStandardNo) && oldTestStandardNo.trim().equals(testStandardNo.trim())) { } else { // 判断是否是车间订单的检测标准 if (reportSample.getIsMoTestStandard()) { reportSampleItemMapper.delete(Wrappers.query().lambda().eq(ReportSampleItem::getReportSampleId, reportSample.getId())); reportSampleItemMapper.insertMoSampleItemsById(reportSample); } else { // 先去查询检测标准编号对应的检测标准 TestStandard newTestStandard = testStandardMapper.selectOne(Wrappers.lambdaQuery().eq(TestStandard::getActive, true) .eq(TestStandard::getStandardNo, testStandardNo)); if (newTestStandard == null) { throw new RuntimeException("质量-检测标准中不存在输入的检测标准编号,请确认"); } // 样品的检测标准编号被修改,就认为是质量-检测标准 reportSample.setTestStandardId(newTestStandard.getId()); reportSampleItemMapper.delete(Wrappers.query().lambda().eq(ReportSampleItem::getReportSampleId, reportSample.getId())); // 这边查的是检测标准 reportSampleItemMapper.insertSampleItemsById(reportSample); } } baseMapper.updateById(reportSample); return reportSample; } @Override public boolean deleteById(Long id) { // 删除检测标准数据 reportSampleItemMapper.delete(Wrappers.query().lambda().eq(ReportSampleItem::getReportSampleId, id)); reportSampleAttachmentMapper.delete(Wrappers.lambdaQuery().eq(ReportSampleAttachment::getSampleId, id)); return SqlHelper.retBool(baseMapper.deleteById(id)); } @Override public List getSampleItemsById(ReportSampleDTO reportSampleDTO) { return reportSampleItemMapper.getSampleItemsById(reportSampleDTO); } @Override public List getSampleSysItemsById(ReportSampleDTO reportSampleDTO) { return reportSampleItemMapper.getSampleSysItemsById(reportSampleDTO); } @Override public R uploadFile(MultipartFile file, Long sampleId) { String fileName = IdUtil.simpleUUID() + StrUtil.DOT + FileUtil.extName(file.getOriginalFilename()); String url = String.format("/mes/reportSample/%s/%s", ossProperties.getBucketName(), fileName); try { minioTemplate.putObject(ossProperties.getBucketName(), fileName, file.getInputStream()); ReportSampleAttachment attachment = new ReportSampleAttachment(); attachment.setOriginal(file.getOriginalFilename()); attachment.setPath(url); attachment.setFileName(fileName); attachment.setSampleId(sampleId); reportSampleAttachmentMapper.insert(attachment); } catch (Exception e) { log.error("上传失败", e); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return R.failed(e.getLocalizedMessage()); } return R.ok(); } @Override @SneakyThrows public R deleteFile(String fileName) { ReportSampleAttachment attachment = reportSampleAttachmentMapper.selectOne(Wrappers.lambdaQuery().eq(ReportSampleAttachment::getFileName, fileName)); minioTemplate.removeObject(ossProperties.getBucketName(), attachment.getFileName()); reportSampleAttachmentMapper.deleteById(attachment.getId()); return R.ok(); } @Override public List getReportSampleAttachment(Long id) { return reportSampleAttachmentMapper.selectList(Wrappers.lambdaQuery().eq(ReportSampleAttachment::getSampleId, id)); } @Override public void getFile(String bucket, String fileName, HttpServletResponse response) { try (InputStream inputStream = minioTemplate.getObject(bucket, fileName)) { response.setContentType("application/octet-stream; charset=UTF-8"); IoUtil.copy(inputStream, response.getOutputStream()); } catch (Exception e) { log.error("文件读取异常: {}", e.getLocalizedMessage()); } } @Override public ReportSampleDTO saveSelfSampleItem(ReportSampleDTO reportSampleDTO) { // 1.同步创建检测汇报 Report report = new Report(); report.setRemark(reportSampleDTO.getOutBatchNo()); report.setReportType("04self"); report.setReportPerson(SecurityUtils.getUser().getUsername()); reportUtils.checkReportNo(report); reportMapper.insert(report); // 2.同步创建检测汇报零件 ApplyPart applyPart = new ApplyPart(); applyPart.setReportId(report.getId()); applyPart.setLotBatchNo(reportSampleDTO.getOutBatchNo()); applyPart.setSystemNo(reportSampleDTO.getSystemNo()); applyPart.setPartId(reportSampleDTO.getPartId()); applyPart.setPartNo(reportSampleDTO.getPartNo()); applyPart.setPartDesc(reportSampleDTO.getPartName()); applyPart.setIsErp(false); applyPart.setQtyArrived(reportSampleDTO.getQtyArrived().stripTrailingZeros().toPlainString()); applyPart.setUnqualifiedArrived("0"); applyPart.setMoTestStandardId(reportSampleDTO.getTestStandardId()); applyPart.setTestStandardNo(reportSampleDTO.getTestStandardNo()); applyPartMapper.insert(applyPart); // 修改检测结果状态为检测中 reportSampleDTO.setCheckStatus(ResultStateStringValues.TESTING); reportSampleDTO.setIsUsed(false); // 3.同步创建样品 reportSampleDTO.setReportId(report.getId()); reportSampleDTO.setSampleNo(reportSampleNumberGenerator.generateNumberWithPrefix(ReportSample.DIGIT, ReportSample.PREFIX, ReportSample::getSampleNo)); baseMapper.insert(reportSampleDTO); // 4.同步创建样品检测项 List reportSampleItemList = reportSampleDTO.getReportSampleItemList(); if (CollectionUtil.isNotEmpty(reportSampleItemList)) { reportSampleItemList.stream().forEach(item -> { item.setReportSampleId(reportSampleDTO.getId()); reportSampleItemMapper.insert(item); }); } return reportSampleDTO; } @Override public ReportSampleDTO getReportSampleForSelf(ReportSampleDTO reportSampleDTO) { reportSampleDTO = baseMapper.getReportSampleForSelf(reportSampleDTO); if (reportSampleDTO != null) { reportSampleDTO.setReportSampleItemList(reportSampleItemMapper.getSampleItemsById(reportSampleDTO)); } return reportSampleDTO; } @Override public ReportSampleDTO autoMoveStock(ReportSampleDTO reportSampleDTO) { reportSampleDTO.setReportSampleItemList(reportSampleItemMapper.getSampleItemsById(reportSampleDTO)); reportSampleDTO.setIsSelfQualified(reportSampleDTO.getIsQualified()); reportSampleDTO.setCheckStatus(ResultStateStringValues.TESTED); reportSampleDTO.setIsUsed(reportSampleDTO.getIsQualified()); selfJudgmentUtils.autoMoveStock(reportSampleDTO); return reportSampleDTO; } @Override public R judgmentSampleCheck(ReportSampleDTO reportSampleDTO) { // 1.判断各个检测项是否合格 List reportSampleItemList = reportSampleItemMapper.getSampleItemsById(reportSampleDTO); List isCheckSampleItemList = reportSampleItemList.stream().filter(ReportSampleItem::getIsCheck).filter(a->StringUtils.isBlank(a.getItemValue())).collect(Collectors.toList()); if(CollectionUtils.isNotEmpty(isCheckSampleItemList)){ List isCheckItemNameList = isCheckSampleItemList.stream().map(ReportSampleItem::getItemName).collect(Collectors.toList()); return R.ok(ValidateIsCheckItemDTO.builder().success(Boolean.FALSE).message("以下抽检项未填,是否继续"+isCheckItemNameList.toString()).build()); }else{ return R.ok(ValidateIsCheckItemDTO.builder().success(Boolean.TRUE).build()); } } @Override public ReportSampleDTO autoJudgmentSample(ReportSampleDTO reportSampleDTO) { // 1.判断各个检测项是否合格 List reportSampleItemList = reportSampleItemMapper.getSampleItemsById(reportSampleDTO); List isCheckSampleItemList = reportSampleItemList.stream().filter(ReportSampleItem::getIsCheck).filter(a->StringUtils.isBlank(a.getItemValue())).collect(Collectors.toList()); if(CollectionUtils.isNotEmpty(isCheckSampleItemList)){ reportSampleItemList.removeAll(isCheckSampleItemList); } if (CollectionUtil.isNotEmpty(reportSampleItemList)) { // 1.1判断值公式 reportSampleItemList.stream().forEach(reportSampleItem -> { // 检测项值和值公式都为空,才去帮忙计算 if (StringUtils.isNotBlank(reportSampleItem.getValueFormula())) { String expression = AutoJudgmentUtils.replace(reportSampleItem.getValueFormula(), reportSampleItemList); try { reportSampleItem.setItemValue(AutoJudgmentUtils.computeResult(expression)); } catch (Exception e) { throw new RuntimeException("明细行检测项编号 = 【" + reportSampleItem.getItemCode() + "】 -> 表达式 = 【" + expression + "】异常"); //throw new RuntimeException("检测项编号为" + reportSampleItem.getItemCode() + "公式不正确,请检查后重试"); } if (StringUtils.isNotBlank(reportSampleItem.getParameterFormat())) { if (NumberUtils.isCreatable(reportSampleItem.getItemValue())) { DecimalFormat decimalFormat = new DecimalFormat(reportSampleItem.getParameterFormat().replace("#", "#0")); reportSampleItem.setItemValue(decimalFormat.format(new BigDecimal(reportSampleItem.getItemValue()))); } } } }); // 1.2判断合格公式 reportSampleItemList.stream().forEach(reportSampleItem -> { if (StringUtils.isNotBlank(reportSampleItem.getJudgeFormula())) { // 根据编号替换值 String expression = AutoJudgmentUtils.replace(reportSampleItem.getJudgeFormula(), reportSampleItemList); // 再判断 reportSampleItem.setIsQualified(AutoJudgmentUtils.computeExpression(expression,"->检测项编号=" + reportSampleItem.getItemCode())); } reportSampleItemMapper.updateById(reportSampleItem); }); } // 2.判断整体是否合格 String sampleExpression = baseMapper.selectSampleExpressionById(reportSampleDTO.getId()); if (StringUtils.isNotBlank(sampleExpression)) { sampleExpression = AutoJudgmentUtils.replace(sampleExpression, reportSampleItemList); reportSampleDTO.setIsQualified(AutoJudgmentUtils.computeExpression(sampleExpression,"->业务类别=" + "判断整体是否合格")); baseMapper.updateById(reportSampleDTO); } return reportSampleDTO; } @Override public ReportSampleItemDTO autoJudgmentSampleSingle(ReportSampleItemDTO reportSampleItemDTO){ if(StringUtils.isNotBlank(reportSampleItemDTO.getItemValue()) && StringUtils.isNotBlank(reportSampleItemDTO.getJudgeFormula()) && StringUtils.isBlank(reportSampleItemDTO.getValueFormula())){ //如果检测值及判断公式存在,且值计算公式不存在,则继续执行(如果检测值本身就是自动计算出来的,则不在本次功能范围内) List reportSampleItemList = new ArrayList<>(); reportSampleItemList.add(reportSampleItemDTO); // 根据编号替换值 String expression = AutoJudgmentUtils.replace(reportSampleItemDTO.getJudgeFormula(), reportSampleItemList); // 再判断 try{ reportSampleItemDTO.setIsQualified(AutoJudgmentUtils.computeExpression(expression,"->检测项编号=" + reportSampleItemDTO.getItemCode())); //reportSampleItemMapper.updateById(reportSampleItemDTO);//不用保存结果 }catch(Exception e){ //单条实时自动判定中屏蔽异常 } } if(StringUtils.isNotBlank(reportSampleItemDTO.getItemValue()) && StringUtils.isBlank(reportSampleItemDTO.getJudgeFormula())){ reportSampleItemDTO.setIsQualified(true);//如果实测值不为空,且计算公式为空,则默认结果为合格 } return reportSampleItemDTO; } @Override public List dataAcquisition(Long id,String sn) { List reportSampleItemList = reportSampleItemMapper.selectList(Wrappers.lambdaQuery() .eq(ReportSampleItem::getReportSampleId,id) .eq(ReportSampleItem::getParamType,"采集项")); Map map = new HashMap<>(); //map.put("pdf_name","18012606007"); map.put("pdf_name",sn); /* map.put("1","20℃导体电阻—红色主线芯1#"); map.put("2","20℃导体电阻—白色主线芯1#"); map.put("pdf_name",sn);*/ for(ReportSampleItem reportSampleItem:reportSampleItemList){ map.put(reportSampleItem.getSort()+"",reportSampleItem.getItemName().replace("-","—")); } R res = inspectFeignClient.getInfo(map); if(res==null || res.getCode()==1){ throw new RuntimeException("请求inspect失败"); } HashMap hashMap = JSONObject.parseObject(JSONObject.toJSONString(res.getData()), HashMap.class); Set keySet = hashMap.keySet(); List reportSampleItemInputList = null; if(CollectionUtil.isNotEmpty(keySet)) { List keyList = keySet.stream().map(Long::valueOf).collect(Collectors.toList()); reportSampleItemInputList = reportSampleItemMapper.getSampleSysItemsBySortAndId(id, keyList); } List returnList = new ArrayList<>(); Iterator > iterator = hashMap.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry< String, String > entry = iterator.next(); Long key = Long.valueOf(entry.getKey()); for (ReportSampleItemDTO reportSampleItemDTO:reportSampleItemInputList) { if(key.equals(reportSampleItemDTO.getSort())){ reportSampleItemDTO.setItemValue(entry.getValue()); //判断是否合格 if(StringUtils.isNotBlank(reportSampleItemDTO.getItemValue()) && StringUtils.isNotBlank(reportSampleItemDTO.getJudgeFormula()) && StringUtils.isBlank(reportSampleItemDTO.getValueFormula())){ //如果检测值及判断公式存在,且值计算公式不存在,则继续执行(如果检测值本身就是自动计算出来的,则不在本次功能范围内) List reportSampleItemDTOList = new ArrayList<>(); reportSampleItemDTOList.add(reportSampleItemDTO); // 根据编号替换值 String expression = AutoJudgmentUtils.replace(reportSampleItemDTO.getJudgeFormula(), reportSampleItemDTOList); // 再判断 try{ reportSampleItemDTO.setIsQualified(AutoJudgmentUtils.computeExpression(expression,"->检测项编号=" + reportSampleItemDTO.getItemCode())); //reportSampleItemMapper.updateById(reportSampleItemDTO);//不用保存结果 }catch(Exception e){ //单条实时自动判定中屏蔽异常 } } if(StringUtils.isNotBlank(reportSampleItemDTO.getItemValue()) && StringUtils.isBlank(reportSampleItemDTO.getJudgeFormula())){ reportSampleItemDTO.setIsQualified(true);//如果实测值不为空,且计算公式为空,则默认结果为合格 } returnList.add(reportSampleItemDTO); } } } return returnList; } @Override public boolean insert(ReportSample reportSample) { reportSample.setSampleNo(reportSampleNumberGenerator.generateNumberWithPrefix(ReportSample.DIGIT, ReportSample.PREFIX, ReportSample::getSampleNo)); return this.save(reportSample); } @Override public List getTestStandardNoBySnOrPartId(String partBatchNo, Long partId, String testType) { return this.baseMapper.getTestStandardNoBySnOrPartId(partBatchNo, partId, testType); } }