| | |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import cn.hutool.core.date.DateTime; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.alibaba.fastjson.JSON; |
| | |
| | | import com.ruoyi.basic.service.StandardTemplateService; |
| | | import com.ruoyi.common.constant.DictDataConstants; |
| | | import com.ruoyi.common.constant.InsOrderTypeConstants; |
| | | import com.ruoyi.common.constant.MenuJumpPathConstants; |
| | | import com.ruoyi.common.core.domain.entity.Custom; |
| | | import com.ruoyi.common.core.domain.entity.InformationNotification; |
| | | import com.ruoyi.common.core.domain.entity.User; |
| | | import com.ruoyi.common.enums.OrderType; |
| | | import com.ruoyi.common.utils.*; |
| | | import com.ruoyi.framework.exception.ErrorException; |
| | | import com.ruoyi.inspect.dto.*; |
| | |
| | | import com.ruoyi.inspect.pojo.*; |
| | | import com.ruoyi.inspect.service.*; |
| | | import com.ruoyi.inspect.util.HackLoopTableRenderPolicy; |
| | | import com.ruoyi.inspect.util.PreserveReportPicturePlaceholderHandler; |
| | | import com.ruoyi.inspect.vo.InsOrderPlanTaskSwitchVo; |
| | | import com.ruoyi.inspect.vo.InsOrderPlanVO; |
| | | import com.ruoyi.performance.mapper.PerformanceShiftMapper; |
| | | import com.ruoyi.performance.mapper.ShiftTimeMapper; |
| | | import com.ruoyi.inspect.vo.InsSampleUserVO; |
| | | import com.ruoyi.performance.mapper.AuxiliaryOutputWorkingHoursMapper; |
| | | import com.ruoyi.performance.pojo.AuxiliaryOutputWorkingHours; |
| | | import com.ruoyi.performance.pojo.AuxiliaryOutputWorkingHoursTemporary; |
| | | import com.ruoyi.performance.service.AuxiliaryOutputWorkingHoursService; |
| | | import com.ruoyi.performance.service.AuxiliaryOutputWorkingHoursTemporaryService; |
| | | import com.ruoyi.system.mapper.CustomMapper; |
| | | import com.ruoyi.system.mapper.UserMapper; |
| | | import com.ruoyi.system.service.ISysDictTypeService; |
| | |
| | | import java.math.RoundingMode; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.Paths; |
| | | import java.time.LocalDate; |
| | | import java.text.DecimalFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | |
| | | import java.util.concurrent.atomic.AtomicReference; |
| | | import java.util.regex.Pattern; |
| | | import java.util.stream.Collectors; |
| | | import java.util.stream.Stream; |
| | | |
| | | /** |
| | | * 检验任务-业务实现层 |
| | | */ |
| | | @Service |
| | | public class InsOrderPlanServiceImpl extends ServiceImpl<InsOrderMapper, InsOrder> implements InsOrderPlanService { |
| | | |
| | | private static final int DETECTION_REPORT = 0; |
| | | private static final int INSPECTION_REPORT = 1; |
| | | private static final String DIRECT_TEMPLATE_LABORATORY = "新聚"; |
| | | |
| | | @Resource |
| | | private InsSampleMapper insSampleMapper; |
| | |
| | | private InsOrderStateMapper insOrderStateMapper; |
| | | @Resource |
| | | private InsProductMapper insProductMapper; |
| | | @Resource |
| | | private ShiftTimeMapper shiftTimeMapper; |
| | | @Resource |
| | | private PerformanceShiftMapper performanceShiftMapper; |
| | | |
| | | @Value("${wordUrl}") |
| | | private String wordUrl; |
| | | @Value("${twoCode}") |
| | | private String twoCode; |
| | | @Resource |
| | | private InsReportMapper insReportMapper; |
| | | @Resource |
| | |
| | | @Resource |
| | | private AuxiliaryOutputWorkingHoursService auxiliaryOutputWorkingHoursService; |
| | | @Resource |
| | | private AuxiliaryOutputWorkingHoursTemporaryService auxiliaryOutputWorkingHoursTemporaryService; |
| | | private AuxiliaryOutputWorkingHoursMapper auxiliaryOutputWorkingHoursMapper; |
| | | @Resource |
| | | private InformationNotificationService informationNotificationService; |
| | | @Resource |
| | |
| | | private InsOrderFileMapper insOrderFileMapper; |
| | | @Resource |
| | | private IfsInventoryQuantityMapper ifsInventoryQuantityMapper; |
| | | @Resource |
| | | private IfsPartPropsRecordMapper ifsPartPropsRecordMapper; |
| | | @Resource |
| | | private InsReportService insReportService; |
| | | @Resource |
| | |
| | | private InsOrderFactoryVerifyMapper insOrderFactoryVerifyMapper; |
| | | @Resource |
| | | private InsOrderFactoryVerifyItemService insOrderFactoryVerifyItemService; |
| | | |
| | | |
| | | @Resource |
| | | private SpotCheckQuarterItemMapper spotCheckQuarterItemMapper; |
| | | @Resource |
| | |
| | | @Resource |
| | | private InsOrderDeviceRecordMapper insOrderDeviceRecordMapper; |
| | | @Resource |
| | | private InsOrderTemplateDeviceMapper insOrderTemplateDeviceMapper; |
| | | @Resource |
| | | private InsOrderDeviceRecordService insOrderDeviceRecordService; |
| | | @Resource |
| | | private ISysDictTypeService iSysDictTypeService; |
| | | @Resource |
| | | private InsOrderRatesService insOrderRatesService; |
| | | @Resource |
| | | private InsProductDeviationWarningService insProductDeviationWarningService; |
| | | @Resource |
| | | private InsProductDeviationWarningDetailService insProductDeviationWarningDetailService; |
| | | |
| | | |
| | | @Override |
| | | public IPage<InsOrderPlanVO> selectInsOrderPlanList(Page page, InsOrderPlanDTO insOrderPlanDTO) { |
| | | // todo: 仅看自己或者实验室 |
| | | //获取当前人所属实验室id |
| | | |
| | | String laboratory = null; |
| | | |
| | | String userName = null; |
| | | Integer userId = null; |
| | | if (ObjectUtil.isNotEmpty(insOrderPlanDTO.getUserId())) { |
| | |
| | | |
| | | @Override |
| | | public Map<String, Object> doInsOrder(Integer id, String laboratory) { |
| | | InsOrder insOrder = new InsOrder(); |
| | | insOrder.setId(id); |
| | | ensureDirectTemplateOrderState(id); |
| | | InsOrder order = insOrderMapper.selectById(id); |
| | | if (BeanUtil.isEmpty(order.getInsTime())) { |
| | | insOrder.setInsTime(LocalDateTime.now()); |
| | | insOrderMapper.updateById(insOrder); |
| | | insOrderStateMapper.update(null, Wrappers.<InsOrderState>lambdaUpdate().eq(InsOrderState::getInsOrderId, id).eq(InsOrderState::getLaboratory, laboratory).set(InsOrderState::getInsTime, LocalDateTime.now()).set(InsOrderState::getInsState, 1)); |
| | | } |
| | | Map<String, Object> map = insOrderService.getInsOrderAndSample(id, laboratory); |
| | | List<SampleProductDto> list = JSON.parseArray(JSON.toJSONString(map.get("sampleProduct")), SampleProductDto.class); |
| | | map.put("sampleProduct", list); |
| | | |
| | | // 查询厂家密度 |
| | | String supplierDensity = ""; |
| | | SampleProductDto sampleProductDto = list.get(0); |
| | | if (CollectionUtils.isNotEmpty(list)) { |
| | | SampleProductDto sampleProductDto = list.get(0); |
| | | |
| | | // 判断有没有绑定型号 |
| | | String modelValue = insSampleMapper.selectSupplierDensityModel(sampleProductDto.getSample(), |
| | | order.getProduction(), |
| | | sampleProductDto.getModel()); |
| | | if (StringUtils.isNotBlank(modelValue)) { |
| | | supplierDensity = modelValue; |
| | | } else { |
| | | supplierDensity = insSampleMapper.selectSupplierDensity(sampleProductDto.getSample(), |
| | | order.getProduction()); |
| | | // 判断有没有绑定型号 |
| | | String modelValue = insSampleMapper.selectSupplierDensityModel(sampleProductDto.getSample(), |
| | | order.getProduction(), |
| | | sampleProductDto.getModel()); |
| | | if (StringUtils.isNotBlank(modelValue)) { |
| | | supplierDensity = modelValue; |
| | | } else { |
| | | supplierDensity = insSampleMapper.selectSupplierDensity(sampleProductDto.getSample(), |
| | | order.getProduction()); |
| | | } |
| | | } |
| | | map.put("supplierDensity", supplierDensity); |
| | | return map; |
| | |
| | | List<InsProduct> insProducts = new ArrayList<>(); |
| | | switch (dto.getType()) { |
| | | case 0: |
| | | insProducts = insSampleMapper.getInsProduct1(dto.getId(), dto.getLaboratory(), dto.getCableTag(), dto.getRepetitionTag(), null); |
| | | //样品 |
| | | break; |
| | | case 4: |
| | | //电缆配置 |
| | | insProducts = insSampleMapper.getInsProduct1(dto.getId(), dto.getLaboratory(), dto.getCableTag(), dto.getRepetitionTag(), null); |
| | | //委托 |
| | | insProducts = insSampleMapper.getInsProduct1(dto.getId(), dto.getLaboratory(), dto.getCableTag(), dto.getRepetitionTag()); |
| | | break; |
| | | case 5: |
| | | //原材料下单 |
| | | insProducts = insSampleMapper.getInsProduct6(dto.getId(), dto.getLaboratory(), dto.getRawMaterialTag(), null); |
| | | insProducts = insSampleMapper.getInsProduct6(dto.getId(), dto.getLaboratory(), dto.getRawMaterialTag()); |
| | | break; |
| | | } |
| | | if (BeanUtil.isEmpty(insProducts)) { |
| | | return null; |
| | | } |
| | | // 查询订单Id |
| | | InsOrder order = insOrderMapper.selectFirstSubmit(dto.getId()); |
| | | getTemplateThing(order, insProducts); |
| | | if (order == null) { |
| | | return BeanUtil.isEmpty(insProducts) ? null : insProducts; |
| | | } |
| | | insProducts = mergeDirectTemplateSnapshots(order, dto.getId(), dto.getLaboratory(), insProducts); |
| | | if (BeanUtil.isEmpty(insProducts)) { |
| | | return null; |
| | | } |
| | | getTemplateThing(order, insProducts, dto.getLaboratory()); |
| | | return insProducts; |
| | | } |
| | | |
| | | @Override |
| | | public List<String> checkSubmitPlan(Integer orderId, String laboratory) { |
| | | List<String> collect = new ArrayList<>(); |
| | | List<InsSample> insSamples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery().eq(InsSample::getInsOrderId, orderId).select(InsSample::getId)); |
| | | List<Integer> ids = insSamples.stream().map(a -> a.getId()).collect(Collectors.toList()); |
| | | List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery() |
| | | .in(InsProduct::getInsSampleId, ids) |
| | | .eq(InsProduct::getSonLaboratory, laboratory) |
| | | .eq(InsProduct::getState, 1) |
| | | .eq(InsProduct::getInsResult, 0)); |
| | | |
| | | // 过滤判断是有复测的值是合格的 |
| | | List<InsProduct> productList = insProducts.stream().filter(insProduct -> { |
| | | // 查询不合格复测 |
| | | Long count = insUnqualifiedRetestProductMapper.selectCount(Wrappers.<InsUnqualifiedRetestProduct>lambdaQuery() |
| | | .eq(InsUnqualifiedRetestProduct::getInsProductId, insProduct.getId()) |
| | | .ne(InsUnqualifiedRetestProduct::getInsResult, 0)); |
| | | if (count != 2) { |
| | | return true; |
| | | } |
| | | return false; |
| | | }).collect(Collectors.toList()); |
| | | if (productList.size() > 0) { |
| | | collect = productList.stream().map(insProduct -> { |
| | | return insProduct.getInspectionItem() + "-" + insProduct.getInspectionItemSubclass(); |
| | | }).collect(Collectors.toList()); |
| | | /** |
| | | * 直绑模板订单的页签来源是订单模板快照,而不是已生成的检验项。 |
| | | * <p> |
| | | * 仍保留每个模板下已有的检验项记录;如果某个模板没有“检验项”标记,补一条仅用于 |
| | | * 承载模板内容的返回对象,使前端也能展示、填写该模板。 |
| | | */ |
| | | private List<InsProduct> mergeDirectTemplateSnapshots(InsOrder order, Integer sampleId, |
| | | String laboratory, List<InsProduct> products) { |
| | | List<InsProduct> source = products == null ? new ArrayList<>() : products; |
| | | List<InsOrderStandardTemplate> snapshots = insOrderStandardTemplateService.list( |
| | | Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, order.getId()) |
| | | .orderByAsc(InsOrderStandardTemplate::getSort, InsOrderStandardTemplate::getId)); |
| | | if (snapshots.isEmpty()) { |
| | | return source; |
| | | } |
| | | return collect; |
| | | InsSample sample = insSampleMapper.selectById(sampleId); |
| | | boolean directTemplateOrder = source.stream() |
| | | .anyMatch(product -> product.getTemplateRowIndex() != null) |
| | | || isDirectTemplateSample(order, sample); |
| | | if (!directTemplateOrder) { |
| | | return source; |
| | | } |
| | | |
| | | Map<Integer, List<InsProduct>> productsByTemplate = source.stream() |
| | | .filter(product -> product.getTemplateId() != null) |
| | | .collect(Collectors.groupingBy(InsProduct::getTemplateId, LinkedHashMap::new, Collectors.toList())); |
| | | List<InsProduct> result = new ArrayList<>(); |
| | | for (InsOrderStandardTemplate snapshot : snapshots) { |
| | | List<InsProduct> templateProducts = productsByTemplate.remove(snapshot.getTemplateId()); |
| | | if (CollectionUtils.isNotEmpty(templateProducts)) { |
| | | templateProducts.forEach(product -> product.setTemplateSort(snapshot.getSort())); |
| | | result.addAll(templateProducts); |
| | | continue; |
| | | } |
| | | InsProduct templateCarrier = new InsProduct(); |
| | | templateCarrier.setInsSampleId(sampleId); |
| | | templateCarrier.setTemplateId(snapshot.getTemplateId()); |
| | | templateCarrier.setSonLaboratory(laboratory); |
| | | templateCarrier.setState(1); |
| | | templateCarrier.setSort(snapshot.getSort()); |
| | | templateCarrier.setTemplateSort(snapshot.getSort()); |
| | | result.add(templateCarrier); |
| | | } |
| | | // 兼容历史异常数据:订单快照以外的检验项仍然返回,但放在快照页签之后。 |
| | | for (List<InsProduct> remaining : productsByTemplate.values()) { |
| | | result.addAll(remaining); |
| | | } |
| | | source.stream().filter(product -> product.getTemplateId() == null).forEach(result::add); |
| | | return result; |
| | | } |
| | | |
| | | private boolean isDirectTemplateSample(InsOrder order, InsSample sample) { |
| | | return sample != null |
| | | && Objects.equals(sample.getInsOrderId(), order.getId()) |
| | | && sample.getStandardMethodListId() == null |
| | | && StringUtils.isBlank(sample.getFactory()) |
| | | && StringUtils.isBlank(sample.getSampleType()) |
| | | && StringUtils.isBlank(sample.getModel()) |
| | | && StringUtils.isBlank(order.getFactory()) |
| | | && StringUtils.isBlank(order.getSampleType()); |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> checkSubmitPlan(Integer orderId, String laboratory) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | | List<String> collect = new ArrayList<>(); |
| | | if (isDirectTemplateOrder(orderId)) { |
| | | List<InsOrderStandardTemplate> snapshots = insOrderStandardTemplateService.list( |
| | | Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, orderId) |
| | | .orderByAsc(InsOrderStandardTemplate::getSort, |
| | | InsOrderStandardTemplate::getId)); |
| | | for (InsOrderStandardTemplate snapshot : snapshots) { |
| | | String templateName = StringUtils.defaultIfBlank(snapshot.getName(), |
| | | "模板ID " + snapshot.getTemplateId()); |
| | | if (snapshot.getDetectionTime() == null) { |
| | | collect.add("请选择“" + templateName + "”的检测时间"); |
| | | } |
| | | if (StringUtils.isBlank(snapshot.getDetectionPlace())) { |
| | | collect.add("请填写“" + templateName + "”的检测地点"); |
| | | } |
| | | } |
| | | map.put("errorMsg", collect); |
| | | map.put("missingExportItems", getMissingTemplateExportValues(orderId)); |
| | | map.put("unInsOrderCount", 0L); |
| | | return map; |
| | | } |
| | | map.put("errorMsg", collect); |
| | | map.put("unInsOrderCount", 0L); |
| | | return map; |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void saveInsContext(Map<String, Object> insContext, Integer currentTable, Integer currentSampleId, Integer orderId, String sonLaboratory) { |
| | | public void saveInsContext(SaveInsContextDto saveInsContextDto) { |
| | | Map<String, Object> insContext = JSON.parseObject(saveInsContextDto.getParam(), Map.class); |
| | | Integer userId = SecurityUtils.getUserId().intValue(); |
| | | InsSample insSample = insSampleMapper.selectById(currentSampleId); |
| | | InsSample insSample = insSampleMapper.selectById(saveInsContextDto.getSampleId()); |
| | | insContext.forEach((k, v) -> { |
| | | JSONObject jo = JSON.parseObject(JSON.toJSONString(v)); |
| | | InsProduct insProduct = new InsProduct(); |
| | | insProduct.setId(Integer.parseInt(k)); |
| | | InsProduct product = insProductMapper.selectById(insProduct.getId()); |
| | | if (currentTable.equals(product.getTemplateId()) && currentSampleId.equals(product.getInsSampleId())) { |
| | | if (saveInsContextDto.getCurrentTable().equals(product.getTemplateId()) && saveInsContextDto.getSampleId().equals(product.getInsSampleId())) { |
| | | List<InsProductResult> oldResults = insProductResultMapper.selectList(Wrappers.<InsProductResult>lambdaQuery() |
| | | .eq(InsProductResult::getInsProductId, insProduct.getId())); |
| | | InsProductResult newResult = new InsProductResult(); |
| | |
| | | } |
| | | } |
| | | |
| | | // 添加工时 |
| | | // 判断是否只是参与计算值, 参与计算值实际没有填写 |
| | | InsProduct finalInsProduct = insProductMapper.selectById(product.getId()); |
| | | InsOrder insOrder = insOrderMapper.selectById(insSample.getInsOrderId()); |
| | | if (StringUtils.isNotBlank(newResult.getInsValue()) && !newResult.getInsValue().equals("[]")) { |
| | | threadPoolTaskExecutor.execute(() -> { |
| | | this.addAuxiliary(userId, finalInsProduct, insOrder); |
| | | }); |
| | | } else { |
| | | // 判断是否是没有检验值的内容 |
| | | if (saveInsContextDto.getIsNoTestValue() != null && saveInsContextDto.getIsNoTestValue() == 1) { |
| | | threadPoolTaskExecutor.execute(() -> { |
| | | this.addAuxiliary(userId, finalInsProduct, insOrder); |
| | | }); |
| | | } |
| | | } |
| | | |
| | | } |
| | | }); |
| | | String sampleIdStr = insContext.keySet().stream().findFirst().orElse(null); |
| | | if (sampleIdStr != null) { |
| | | int count = insProductMapper.selectInsProductCountByOrderId(orderId); |
| | | int count = insProductMapper.selectInsProductCountByOrderId(saveInsContextDto.getOrderId()); |
| | | if (count == 0) { |
| | | insOrderStateMapper.update(new InsOrderState(), Wrappers.<InsOrderState>lambdaUpdate() |
| | | .eq(InsOrderState::getInsOrderId, orderId) |
| | | .eq(InsOrderState::getLaboratory, sonLaboratory) |
| | | .eq(InsOrderState::getInsOrderId, saveInsContextDto.getOrderId()) |
| | | .eq(InsOrderState::getLaboratory, saveInsContextDto.getSonLaboratory()) |
| | | .set(InsOrderState::getInsState, 2)); |
| | | } |
| | | } |
| | |
| | | |
| | | // 添加设备记录 |
| | | threadPoolTaskExecutor.execute(() -> { |
| | | InsOrder order = insOrderMapper.selectById(insSample.getInsOrderId()); |
| | | User user = userMapper.selectById(userId); |
| | | // 查询设备使用记录查询该订单的使用记录 |
| | | List<InsOrderDeviceRecordDto> deviceRecordDtoList = insOrderDeviceRecordMapper.selectDeviceNumber(insSample.getInsOrderId()); |
| | | Set<String> recordCodeset = deviceRecordDtoList.stream().map(InsOrderDeviceRecordDto::getManagementNumber).collect(Collectors.toSet()); |
| | | // 添加设备使用记录 |
| | | addDeviceRecord(insSample, userId); |
| | | }); |
| | | } |
| | | |
| | | // 获取订单设备编号 |
| | | List<InsProductResult> resultList = insProductResultMapper.selectResultByOrderId(insSample.getInsOrderId()); |
| | | Set<String> deviceCodeSet = new HashSet<>(); |
| | | for (InsProductResult result : resultList) { |
| | | // 添加设备编号 |
| | | List<JSONObject> jsonObjects = JSON.parseArray(result.getEquipValue(), JSONObject.class); |
| | | for (JSONObject jsonObject : jsonObjects) { |
| | | if (!"".equals(jsonObject.get("v") + "")) { |
| | | List<String> v = StrUtil.split(jsonObject.get("v") + "", ","); |
| | | deviceCodeSet.addAll(v); |
| | | } |
| | | /** |
| | | * 新聚订单的外层 key 是 templateId,不是 ins_product.id;因此单独按模板快照保存。 |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void saveTemplateContext(SaveTemplateContextDto dto) { |
| | | if (dto.getOrderId() == null || dto.getSampleId() == null || dto.getTemplateId() == null) { |
| | | throw new ErrorException("订单、样品和模板不能为空"); |
| | | } |
| | | InsSample sample = insSampleMapper.selectById(dto.getSampleId()); |
| | | if (sample == null || !Objects.equals(sample.getInsOrderId(), dto.getOrderId())) { |
| | | throw new ErrorException("样品不属于当前检验单"); |
| | | } |
| | | InsOrderStandardTemplate snapshot = insOrderStandardTemplateService.getOne( |
| | | Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, dto.getOrderId()) |
| | | .eq(InsOrderStandardTemplate::getTemplateId, dto.getTemplateId()) |
| | | .last("limit 1")); |
| | | if (snapshot == null) { |
| | | throw new ErrorException("未找到当前订单的原始记录模板快照"); |
| | | } |
| | | ensureDirectTemplateOrderState(dto.getOrderId()); |
| | | List<InsProduct> products = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery() |
| | | .eq(InsProduct::getInsSampleId, dto.getSampleId()) |
| | | .eq(InsProduct::getTemplateId, dto.getTemplateId()) |
| | | .isNotNull(InsProduct::getTemplateRowIndex) |
| | | .eq(InsProduct::getState, 1)); |
| | | |
| | | JSONObject values = JSON.parseObject(JSON.toJSONString(dto.getValues() == null |
| | | ? Collections.emptyMap() : dto.getValues())); |
| | | // 检验期间页面展示的是标准维护中的最新模板,保存校验必须使用同一份模板, |
| | | // 避免模板新增“导出值”批注后仍按下单时的旧快照误报未配置。 |
| | | String currentTemplateThing = getCurrentTemplateThing(snapshot); |
| | | List<String> exportValueCoordinates = getExportValueCoordinates(currentTemplateThing).values().stream() |
| | | .flatMap(Collection::stream) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | if (exportValueCoordinates.isEmpty()) { |
| | | throw new ErrorException("模板必须至少配置一个导出值批注"); |
| | | } |
| | | |
| | | // 导出值按模板配置,不再要求每个检验项区块分别配置。一个模板取第一个导出值作为结果。 |
| | | String exportValueCoordinate = exportValueCoordinates.get(0); |
| | | JSONObject exportValueCell = values.getJSONObject(exportValueCoordinate); |
| | | String exportValue = exportValueCell == null || exportValueCell.get("v") == null |
| | | ? "" : String.valueOf(exportValueCell.get("v")); |
| | | Integer userId = SecurityUtils.getUserId().intValue(); |
| | | for (InsProduct product : products) { |
| | | InsProduct update = new InsProduct(); |
| | | update.setId(product.getId()); |
| | | update.setLastValue(exportValue); |
| | | update.setUpdateUser(userId); |
| | | insProductMapper.updateById(update); |
| | | insProductUserMapper.insert(new InsProductUser(null, userId, LocalDateTime.now(), product.getId())); |
| | | } |
| | | snapshot.setRecordValues(values.toJSONString()); |
| | | insOrderStandardTemplateService.updateById(snapshot); |
| | | |
| | | if (hasSavedTemplateValue(values)) { |
| | | markInspectionStarted(dto.getOrderId(), products); |
| | | } |
| | | |
| | | Long unfinished = insProductMapper.selectCount(Wrappers.<InsProduct>lambdaQuery() |
| | | .eq(InsProduct::getInsSampleId, dto.getSampleId()) |
| | | .isNotNull(InsProduct::getTemplateRowIndex) |
| | | .eq(InsProduct::getState, 1) |
| | | .and(w -> w.isNull(InsProduct::getLastValue).or().eq(InsProduct::getLastValue, ""))); |
| | | sample.setInsState(unfinished == 0 ? 2 : 1); |
| | | insSampleMapper.updateById(sample); |
| | | } |
| | | |
| | | /** |
| | | * 第一次成功保存任意非空模板值时,记录真实检验开始时间并将任务从待检改为在检。 |
| | | */ |
| | | private void markInspectionStarted(Integer orderId, List<InsProduct> products) { |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | insOrderMapper.update(null, Wrappers.<InsOrder>lambdaUpdate() |
| | | .eq(InsOrder::getId, orderId) |
| | | .isNull(InsOrder::getFirstInspectDate) |
| | | .set(InsOrder::getFirstInspectDate, now) |
| | | // 保留原字段供检验任务列表中的“检验开始时间”继续展示。 |
| | | .set(InsOrder::getInsTime, now)); |
| | | |
| | | Set<String> laboratories = products.stream() |
| | | .map(InsProduct::getSonLaboratory) |
| | | .filter(StringUtils::isNotBlank) |
| | | .collect(Collectors.toSet()); |
| | | if (laboratories.isEmpty() && isDirectTemplateOrder(orderId)) { |
| | | laboratories.add(DIRECT_TEMPLATE_LABORATORY); |
| | | } |
| | | if (!laboratories.isEmpty()) { |
| | | insOrderStateMapper.update(null, Wrappers.<InsOrderState>lambdaUpdate() |
| | | .eq(InsOrderState::getInsOrderId, orderId) |
| | | .in(InsOrderState::getLaboratory, laboratories) |
| | | .eq(InsOrderState::getInsState, 0) |
| | | .set(InsOrderState::getInsTime, now) |
| | | .set(InsOrderState::getInsState, 1)); |
| | | } |
| | | } |
| | | |
| | | private boolean hasSavedTemplateValue(JSONObject values) { |
| | | if (values == null || values.isEmpty()) { |
| | | return false; |
| | | } |
| | | for (Object rawCell : values.values()) { |
| | | JSONObject cell = rawCell instanceof JSONObject |
| | | ? (JSONObject) rawCell |
| | | : JSON.parseObject(JSON.toJSONString(rawCell)); |
| | | if (cell != null && hasMeaningfulValue(cell.get("v"))) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | private boolean hasMeaningfulValue(Object value) { |
| | | if (value == null) { |
| | | return false; |
| | | } |
| | | if (value instanceof CharSequence) { |
| | | return StringUtils.isNotBlank(value.toString()); |
| | | } |
| | | if (value instanceof Collection) { |
| | | return ((Collection<?>) value).stream().anyMatch(this::hasMeaningfulValue); |
| | | } |
| | | if (value instanceof Map) { |
| | | return ((Map<?, ?>) value).values().stream().anyMatch(this::hasMeaningfulValue); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | private NavigableMap<Integer, List<String>> getExportValueCoordinates(String compressedThing) { |
| | | if (StrUtil.isBlank(compressedThing)) { |
| | | throw new ErrorException("原始记录模板为空"); |
| | | } |
| | | String thing; |
| | | try { |
| | | thing = GZipUtil.uncompress(compressedThing); |
| | | } catch (Exception ignored) { |
| | | thing = compressedThing; |
| | | } |
| | | JSONArray cellData = JSON.parseObject(thing).getJSONArray("data").getJSONObject(0).getJSONArray("celldata"); |
| | | NavigableMap<Integer, List<String>> result = new TreeMap<>(); |
| | | Integer inspectionResultColumn = null; |
| | | for (Object item : cellData) { |
| | | JSONObject cell = JSON.parseObject(JSON.toJSONString(item)); |
| | | Integer column = cell.getInteger("c"); |
| | | JSONObject value = cell.getJSONObject("v"); |
| | | String displayValue = value == null ? null : value.getString("v"); |
| | | if (inspectionResultColumn == null && "检验结果".equals(StringUtils.trim(displayValue))) { |
| | | inspectionResultColumn = column; |
| | | } |
| | | } |
| | | for (Object item : cellData) { |
| | | JSONObject cell = JSON.parseObject(JSON.toJSONString(item)); |
| | | JSONObject value = cell.getJSONObject("v"); |
| | | JSONObject ps = value == null ? null : value.getJSONObject("ps"); |
| | | if (ps == null || !"导出值".equals(ps.getString("value"))) { |
| | | continue; |
| | | } |
| | | Integer row = cell.getInteger("r"); |
| | | Integer column = cell.getInteger("c"); |
| | | if (row != null && column != null) { |
| | | // “导出值”标在检测项目标题单元格时,真正导出的值是同一行“检验结果”列的单元格。 |
| | | String coordinate = row + "-" + column; |
| | | String resultCoordinate = row + "-" + inspectionResultColumn; |
| | | if (inspectionResultColumn != null && !Objects.equals(column, inspectionResultColumn)) { |
| | | coordinate = resultCoordinate; |
| | | } |
| | | result.computeIfAbsent(row, ignored -> new ArrayList<>()).add(coordinate); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 检验保存、提交校验读取标准维护中的实时模板;模板已被删除或内容为空时才回退订单快照。 |
| | | * 检验完成后的展示和报告仍由订单快照负责,不会随标准模板后续修改而变化。 |
| | | */ |
| | | private String getCurrentTemplateThing(InsOrderStandardTemplate snapshot) { |
| | | if (snapshot != null && snapshot.getTemplateId() != null) { |
| | | StandardTemplate currentTemplate = standardTemplateService.getById(snapshot.getTemplateId()); |
| | | if (currentTemplate != null && StrUtil.isNotBlank(currentTemplate.getThing())) { |
| | | return currentTemplate.getThing(); |
| | | } |
| | | } |
| | | return snapshot == null ? null : snapshot.getThing(); |
| | | } |
| | | |
| | | /** |
| | | * 直绑模板订单只校验模板中标记为“导出值”的单元格,不使用检验项状态或 last_value 判定。 |
| | | */ |
| | | private List<String> getMissingTemplateExportValues(Integer orderId) { |
| | | List<InsOrderStandardTemplate> snapshots = insOrderStandardTemplateService.list( |
| | | Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, orderId) |
| | | .orderByAsc(InsOrderStandardTemplate::getSort, InsOrderStandardTemplate::getId)); |
| | | List<String> missing = new ArrayList<>(); |
| | | if (snapshots.isEmpty()) { |
| | | missing.add("当前订单未找到原始记录模板快照"); |
| | | return missing; |
| | | } |
| | | for (InsOrderStandardTemplate snapshot : snapshots) { |
| | | Integer templateId = snapshot.getTemplateId(); |
| | | List<String> coordinates = getExportValueCoordinates(getCurrentTemplateThing(snapshot)).values().stream() |
| | | .flatMap(Collection::stream) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | String templateName = StringUtils.defaultIfBlank(snapshot.getName(), "模板ID " + templateId); |
| | | if (coordinates.isEmpty()) { |
| | | missing.add(templateName + "(未配置导出值)"); |
| | | continue; |
| | | } |
| | | |
| | | JSONObject recordValues = StrUtil.isBlank(snapshot.getRecordValues()) |
| | | ? new JSONObject() : JSON.parseObject(snapshot.getRecordValues()); |
| | | for (String coordinate : coordinates) { |
| | | JSONObject cell = recordValues.getJSONObject(coordinate); |
| | | Object value = cell == null ? null : cell.get("v"); |
| | | if (value == null || StringUtils.isBlank(String.valueOf(value))) { |
| | | missing.add(templateName + "(" + coordinate + ")"); |
| | | } |
| | | } |
| | | // 1.判断是否有没有添加的使用记录 |
| | | Set<String> orderDeviceNumbers = getDeviceDifference(deviceCodeSet, recordCodeset); |
| | | // 添加使用记录, 根据编号查询设备id |
| | | if (CollectionUtils.isNotEmpty(orderDeviceNumbers)) { |
| | | List<Integer> orderDeviceIds = insOrderDeviceRecordMapper.selectDeviceIdsByNumbers(orderDeviceNumbers); |
| | | List<InsOrderDeviceRecord> collect = orderDeviceIds.stream().map(deviceId -> { |
| | | InsOrderDeviceRecord insOrderDeviceRecord = new InsOrderDeviceRecord(); |
| | | insOrderDeviceRecord.setInsOrderId(insSample.getInsOrderId()); |
| | | insOrderDeviceRecord.setDeviceId(deviceId); |
| | | insOrderDeviceRecord.setSampleCode(order.getEntrustCode()); |
| | | insOrderDeviceRecord.setUseBefore(1); |
| | | insOrderDeviceRecord.setUseAfter(1); |
| | | insOrderDeviceRecord.setUsePerson(user.getName()); |
| | | insOrderDeviceRecord.setUsePersonId(user.getId()); |
| | | return insOrderDeviceRecord; |
| | | }).collect(Collectors.toList()); |
| | | } |
| | | return missing; |
| | | } |
| | | |
| | | insOrderDeviceRecordService.saveBatch(collect); |
| | | @Override |
| | | public List<Integer> getOrderDeviceIds(Integer orderId) { |
| | | return insOrderDeviceRecordMapper.selectList(Wrappers.<InsOrderDeviceRecord>lambdaQuery() |
| | | .eq(InsOrderDeviceRecord::getInsOrderId, orderId)) |
| | | .stream().map(InsOrderDeviceRecord::getDeviceId).filter(Objects::nonNull).distinct() |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void saveOrderDevices(SaveOrderDevicesDto dto) { |
| | | if (dto.getOrderId() == null || insOrderMapper.selectById(dto.getOrderId()) == null) { |
| | | throw new ErrorException("检验单不存在"); |
| | | } |
| | | Set<Integer> deviceIds = dto.getDeviceIds() == null ? Collections.emptySet() : dto.getDeviceIds().stream() |
| | | .filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | List<InsOrderDeviceRecord> oldRecords = insOrderDeviceRecordMapper.selectList( |
| | | Wrappers.<InsOrderDeviceRecord>lambdaQuery().eq(InsOrderDeviceRecord::getInsOrderId, dto.getOrderId())); |
| | | Set<Integer> oldIds = oldRecords.stream().map(InsOrderDeviceRecord::getDeviceId).collect(Collectors.toSet()); |
| | | if (!oldIds.isEmpty()) { |
| | | insOrderDeviceRecordMapper.delete(Wrappers.<InsOrderDeviceRecord>lambdaQuery() |
| | | .eq(InsOrderDeviceRecord::getInsOrderId, dto.getOrderId()) |
| | | .notIn(!deviceIds.isEmpty(), InsOrderDeviceRecord::getDeviceId, deviceIds)); |
| | | } |
| | | InsOrder order = insOrderMapper.selectById(dto.getOrderId()); |
| | | User user = userMapper.selectById(SecurityUtils.getUserId().intValue()); |
| | | List<InsOrderDeviceRecord> additions = deviceIds.stream().filter(id -> !oldIds.contains(id)).map(id -> { |
| | | InsOrderDeviceRecord record = new InsOrderDeviceRecord(); |
| | | record.setInsOrderId(dto.getOrderId()); |
| | | record.setDeviceId(id); |
| | | record.setSampleCode(order.getEntrustCode()); |
| | | record.setUseBefore(1); |
| | | record.setUseAfter(1); |
| | | record.setUsePersonId(user.getId()); |
| | | record.setUsePerson(user.getName()); |
| | | return record; |
| | | }).collect(Collectors.toList()); |
| | | if (!additions.isEmpty()) { |
| | | insOrderDeviceRecordService.saveBatch(additions); |
| | | } |
| | | } |
| | | |
| | | private synchronized void addDeviceRecord(InsSample insSample, Integer userId) { |
| | | InsOrder order = insOrderMapper.selectById(insSample.getInsOrderId()); |
| | | User user = userMapper.selectById(userId); |
| | | // 查询设备使用记录查询该订单的使用记录 |
| | | List<InsOrderDeviceRecordDto> deviceRecordDtoList = insOrderDeviceRecordMapper.selectDeviceNumber(insSample.getInsOrderId()); |
| | | Set<String> recordCodeset = deviceRecordDtoList.stream().map(InsOrderDeviceRecordDto::getManagementNumber).collect(Collectors.toSet()); |
| | | |
| | | // 获取订单设备编号 |
| | | List<InsProductResult> resultList = insProductResultMapper.selectResultByOrderId(insSample.getInsOrderId()); |
| | | Set<String> deviceCodeSet = new HashSet<>(); |
| | | for (InsProductResult result : resultList) { |
| | | // 添加设备编号 |
| | | List<JSONObject> jsonObjects = JSON.parseArray(result.getEquipValue(), JSONObject.class); |
| | | for (JSONObject jsonObject : jsonObjects) { |
| | | if (!"".equals(jsonObject.get("v") + "")) { |
| | | List<String> v = StrUtil.split(jsonObject.get("v") + "", ","); |
| | | deviceCodeSet.addAll(v); |
| | | } |
| | | } |
| | | } |
| | | // 1.判断是否有没有添加的使用记录 |
| | | Set<String> orderDeviceNumbers = getDeviceDifference(deviceCodeSet, recordCodeset); |
| | | // 添加使用记录, 根据编号查询设备id |
| | | if (CollectionUtils.isNotEmpty(orderDeviceNumbers)) { |
| | | List<Integer> orderDeviceIds = insOrderDeviceRecordMapper.selectDeviceIdsByNumbers(orderDeviceNumbers); |
| | | List<InsOrderDeviceRecord> collect = orderDeviceIds.stream().map(deviceId -> { |
| | | InsOrderDeviceRecord insOrderDeviceRecord = new InsOrderDeviceRecord(); |
| | | insOrderDeviceRecord.setInsOrderId(insSample.getInsOrderId()); |
| | | insOrderDeviceRecord.setDeviceId(deviceId); |
| | | insOrderDeviceRecord.setSampleCode(order.getEntrustCode()); |
| | | insOrderDeviceRecord.setUseBefore(1); |
| | | insOrderDeviceRecord.setUseAfter(1); |
| | | insOrderDeviceRecord.setUsePerson(user.getName()); |
| | | insOrderDeviceRecord.setUsePersonId(user.getId()); |
| | | return insOrderDeviceRecord; |
| | | }).collect(Collectors.toList()); |
| | | |
| | | // 2.判断是否取消了设备使用 |
| | | Set<String> repoprNumbers = getDeviceDifference(recordCodeset, deviceCodeSet); |
| | | if (CollectionUtils.isNotEmpty(repoprNumbers)) { |
| | | List<Integer> reportDeviceIds = insOrderDeviceRecordMapper.selectDeviceIdsByNumbers(repoprNumbers); |
| | | insOrderDeviceRecordMapper.delete(Wrappers.<InsOrderDeviceRecord>lambdaQuery() |
| | | .in(InsOrderDeviceRecord::getDeviceId, reportDeviceIds) |
| | | .eq(InsOrderDeviceRecord::getInsOrderId, insSample.getInsOrderId())); |
| | | } |
| | | }); |
| | | insOrderDeviceRecordService.saveBatch(collect); |
| | | |
| | | } |
| | | |
| | | // 2.判断是否取消了设备使用 |
| | | Set<String> repoprNumbers = getDeviceDifference(recordCodeset, deviceCodeSet); |
| | | if (CollectionUtils.isNotEmpty(repoprNumbers)) { |
| | | List<Integer> reportDeviceIds = insOrderDeviceRecordMapper.selectDeviceIdsByNumbers(repoprNumbers); |
| | | insOrderDeviceRecordMapper.delete(Wrappers.<InsOrderDeviceRecord>lambdaQuery() |
| | | .in(InsOrderDeviceRecord::getDeviceId, reportDeviceIds) |
| | | .eq(InsOrderDeviceRecord::getInsOrderId, insSample.getInsOrderId())); |
| | | } |
| | | } |
| | | |
| | | private static Set<String> getDeviceDifference(Set<String> number1, Set<String> number2) { |
| | |
| | | |
| | | /** |
| | | * 查询模板内容 |
| | | * |
| | | * @param order |
| | | * @param insProducts |
| | | */ |
| | | private void getTemplateThing(InsOrder order, List<InsProduct> insProducts) { |
| | | private void getTemplateThing(InsOrder order, List<InsProduct> insProducts, String laboratory) { |
| | | Set<Integer> set = new HashSet<>(); |
| | | // 检验项分类+检验项+检验子项的拼接 |
| | | // List<String> itemNameList = insProducts.stream().map(insProduct -> { |
| | | // String itemName = ""; |
| | | // if (StringUtils.isNotBlank(insProduct.getInspectionItemClass())) { |
| | | // itemName += insProduct.getInspectionItemClass().trim(); |
| | | // } |
| | | // if (StringUtils.isNotBlank(insProduct.getInspectionItem())) { |
| | | // itemName += insProduct.getInspectionItem().trim(); |
| | | // } |
| | | // if (StringUtils.isNotBlank(insProduct.getInspectionItemSubclass())) { |
| | | // itemName += insProduct.getInspectionItemSubclass().trim(); |
| | | // } |
| | | // return itemName; |
| | | // }).collect(Collectors.toList()); |
| | | // 查询订单状态判断是否是查历史模板 |
| | | if (order.getIsFirstSubmit() != null && order.getIsFirstSubmit().equals(1)) { |
| | | InsOrderState insOrderState = insOrderStateMapper.selectOne(Wrappers.<InsOrderState>lambdaQuery() |
| | | .eq(InsOrderState::getInsOrderId, order.getId()) |
| | | .last("limit 1")); |
| | | if (insOrderState != null && (!insOrderState.getInsState().equals(3) || !insOrderState.getInsState().equals(5))) { |
| | | for (InsProduct product : insProducts) { |
| | | if (product.getTemplateId() == null) { |
| | | product.setTemplate(new ArrayList<>()); |
| | | Map<Integer, String> recordValuesByTemplate = new HashMap<>(); |
| | | for (InsOrderStandardTemplate snapshot : insOrderStandardTemplateService.list( |
| | | Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, order.getId()))) { |
| | | // record_values 在首次填写前允许为空;Collectors.toMap 不接受 null value。 |
| | | if (snapshot.getTemplateId() != null && snapshot.getRecordValues() != null) { |
| | | recordValuesByTemplate.putIfAbsent(snapshot.getTemplateId(), snapshot.getRecordValues()); |
| | | } |
| | | } |
| | | boolean directTemplateOrder = insProducts.stream() |
| | | .anyMatch(product -> product.getTemplateRowIndex() != null); |
| | | Long snapshotCount = insOrderStandardTemplateService.count(Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, order.getId())); |
| | | InsOrderState insOrderState = insOrderStateMapper.selectOne(Wrappers.<InsOrderState>lambdaQuery() |
| | | .eq(InsOrderState::getInsOrderId, order.getId()) |
| | | .eq(StringUtils.isNotBlank(laboratory), InsOrderState::getLaboratory, laboratory) |
| | | .last("limit 1")); |
| | | Integer insState = insOrderState == null ? null : insOrderState.getInsState(); |
| | | boolean hasSnapshot = snapshotCount > 0 && (directTemplateOrder |
| | | || Objects.equals(order.getIsFirstSubmit(), 1)); |
| | | // 待检验、检验中使用基础配置的最新模板;已检验及后续状态使用订单快照。 |
| | | boolean useSnapshot = hasSnapshot && insState != null && insState >= 2; |
| | | if (useSnapshot) { |
| | | for (InsProduct product : insProducts) { |
| | | if (product.getTemplateId() == null) { |
| | | product.setTemplate(new ArrayList<>()); |
| | | continue; |
| | | } |
| | | if (set.add(product.getTemplateId())) { |
| | | InsOrderStandardTemplate one = insOrderStandardTemplateService.getOne(Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getTemplateId, product.getTemplateId()) |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, order.getId())); |
| | | if (one == null || StrUtil.isEmpty(one.getThing())) { |
| | | // 快照不完整时允许后面的最新模板查询兜底。 |
| | | set.remove(product.getTemplateId()); |
| | | continue; |
| | | } |
| | | String thing = null; |
| | | if (product.getTemplateId() != null && set.add(product.getTemplateId())) { |
| | | // 查询历史模板 |
| | | InsOrderStandardTemplate one = insOrderStandardTemplateService.getOne(Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getTemplateId, product.getTemplateId()) |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, order.getId())); |
| | | thing = one.getThing(); |
| | | if (StrUtil.isNotEmpty(thing)) { |
| | | thing = GZipUtil.uncompress(thing); |
| | | JSONObject sheet = JSON.parseObject(thing).getJSONArray("data").getJSONObject(0); |
| | | JSONObject config = sheet.getJSONObject("config"); |
| | | List<JSONObject> cellData = JSON.parseArray(JSON.toJSONString(sheet.get("celldata")), JSONObject.class); |
| | | Map<String, Object> style = new HashMap<>(); |
| | | style.put("rowlen", config.get("rowlen")); |
| | | style.put("columnlen", config.get("columnlen")); |
| | | product.setTemplate(cellData); |
| | | product.setStyle(style); |
| | | product.setTemplateName(one.getName()); |
| | | } |
| | | } |
| | | String thing = GZipUtil.uncompress(one.getThing()); |
| | | JSONObject sheet = JSON.parseObject(thing).getJSONArray("data").getJSONObject(0); |
| | | JSONObject config = sheet.getJSONObject("config"); |
| | | List<JSONObject> cellData = JSON.parseArray(JSON.toJSONString(sheet.get("celldata")), JSONObject.class); |
| | | Map<String, Object> style = new HashMap<>(); |
| | | style.put("rowlen", config.get("rowlen")); |
| | | style.put("columnlen", config.get("columnlen")); |
| | | product.setTemplate(cellData); |
| | | product.setStyle(style); |
| | | product.setTemplateName(one.getName()); |
| | | } |
| | | } |
| | | } |
| | |
| | | product.setStyle(style); |
| | | product.setTemplateName(standardTemplateService.getStandTempNameById(product.getTemplateId())); |
| | | } |
| | | product.setRecordValues(recordValuesByTemplate.get(product.getTemplateId())); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * todo: 清除没有使用的检验项 |
| | | * todo: 原始记录模板清除没有使用的检验项(暂时有bug无法使用) |
| | | * |
| | | * @param sheet |
| | | * @param itemNameList |
| | | */ |
| | |
| | | |
| | | /** |
| | | * 坐标拼接 |
| | | * |
| | | * @param r 横坐标 |
| | | * @param c 纵坐标 |
| | | * @return |
| | |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int submitPlan(Integer orderId, String laboratory, Integer verifyUser, String entrustCode) { |
| | | InsOrder order = insOrderMapper.selectById(orderId); |
| | | public int submitPlan(Integer orderId, String laboratory, Integer verifyUser, String entrustCode, Boolean registerInsResults) { |
| | | ensureDirectTemplateOrderState(orderId); |
| | | int reportType = DETECTION_REPORT; |
| | | InsOrder order = insOrderMapper.selectOne(Wrappers.<InsOrder>lambdaQuery() |
| | | .eq(InsOrder::getId, orderId) |
| | | .last("FOR UPDATE")); |
| | | boolean isInspectionReport = Objects.equals(INSPECTION_REPORT, reportType); |
| | | registerInsResults = isInspectionReport && Boolean.TRUE.equals(registerInsResults); |
| | | // 1. 判断是否有重复编号, 有重复编号做提醒 |
| | | Long codeCount = insOrderMapper.selectCount(Wrappers.<InsOrder>lambdaQuery() |
| | | .ne(InsOrder::getState, -1) |
| | |
| | | } |
| | | |
| | | // 2. 判断该订单是否是第一次生产(后续报告生成只取第一次提交时间) |
| | | if (!(order.getIsFirstSubmit() != null && order.getIsFirstSubmit().equals(1))) { |
| | | boolean firstSubmit = !Objects.equals(order.getIsFirstSubmit(), 1); |
| | | if (firstSubmit) { |
| | | insOrderMapper.update(null, Wrappers.<InsOrder>lambdaUpdate() |
| | | .eq(InsOrder::getId, orderId) |
| | | .set(InsOrder::getIsFirstSubmit, 1) |
| | | .set(InsOrder::getFirstSubmitDate, LocalDateTime.now())); |
| | | } |
| | | |
| | | // 3. 判断是否有未检项 |
| | | // 3. 直绑模板仅校验“导出值”;普通订单沿用原检验项校验。 |
| | | List<InsSample> insSamples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery() |
| | | .eq(InsSample::getInsOrderId, orderId).select(InsSample::getId)); |
| | | List<Integer> InsSampleIds = insSamples.stream().map(InsSample::getId).collect(Collectors.toList()); |
| | | List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery() |
| | | .in(InsProduct::getInsSampleId, InsSampleIds) |
| | | .eq(InsProduct::getSonLaboratory, laboratory) |
| | | .eq(InsProduct::getState, 1) |
| | | .and(wrapper -> wrapper |
| | | .isNull(InsProduct::getInsResult) |
| | | .or() |
| | | .eq(InsProduct::getInsResult, 2) |
| | | ) |
| | | .ne(InsProduct::getIsBinding, 1)); |
| | | insProducts.addAll(insProductMapper.selectFiberInsProduct(InsSampleIds, laboratory)); |
| | | boolean directTemplateOrder = isDirectTemplateOrder(orderId); |
| | | List<InsProduct> insProducts; |
| | | if (directTemplateOrder) { |
| | | List<String> missingExportValues = getMissingTemplateExportValues(orderId); |
| | | if (!missingExportValues.isEmpty()) { |
| | | throw new ErrorException("模板中的导出值不能为空:\n" + String.join("\n", missingExportValues)); |
| | | } |
| | | insProducts = Collections.emptyList(); |
| | | } else { |
| | | insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery() |
| | | .in(InsProduct::getInsSampleId, InsSampleIds) |
| | | .eq(InsProduct::getSonLaboratory, laboratory) |
| | | .eq(InsProduct::getState, 1) |
| | | .and(wrapper -> { |
| | | if (Objects.equals(reportType, DETECTION_REPORT)) { |
| | | wrapper.isNull(InsProduct::getLastValue).or().eq(InsProduct::getLastValue, ""); |
| | | } else { |
| | | wrapper.isNull(InsProduct::getInsResult).or().eq(InsProduct::getInsResult, 2); |
| | | } |
| | | }) |
| | | .ne(InsProduct::getIsBinding, 1)); |
| | | } |
| | | if (!directTemplateOrder && Objects.equals(reportType, INSPECTION_REPORT)) { |
| | | List<InsProduct> insProducts1 = insProductMapper.selectFiberInsProduct(InsSampleIds, laboratory); |
| | | insProducts.addAll(insProducts1); |
| | | } |
| | | if (insProducts.size() > 0) { |
| | | String str = ""; |
| | | int count = 0; |
| | | for (InsProduct product : insProducts) { |
| | | count++; |
| | | str += "<br/>" + count + ":" + product.getInspectionItem() + " " + product.getInspectionItemSubclass() + "<br/>"; |
| | | |
| | | str += (count != 0 ? "\n" : "") + count + ":" + |
| | | product.getInspectionItemClass() + " " + |
| | | product.getInspectionItem() + " " + |
| | | product.getInspectionItemSubclass(); |
| | | } |
| | | if (ObjectUtils.isNotEmpty(str)) { |
| | | throw new ErrorException("<strong>存在待检验的项目:</strong><br/>" + str); |
| | | throw new ErrorException("存在待检验的项目:" + str); |
| | | } |
| | | } |
| | | |
| | |
| | | info.setSenderId(userId); |
| | | info.setConsigneeId(verifyUser); |
| | | info.setViewStatus(false); |
| | | info.setJumpPath("b1-inspect-orderPlan-review"); |
| | | info.setJumpPath(MenuJumpPathConstants.INSPECTION_REVIEW); |
| | | informationNotificationService.addInformationNotification(info); |
| | | |
| | | // 6.复核人--新增检验单相关负责人 |
| | |
| | | } |
| | | }); |
| | | |
| | | // 8.提交生成报告 |
| | | this.generateReport(orderId); |
| | | // 8.首次提交时将本次检验使用的最新模板冻结为订单快照。 |
| | | Long snapshotCount = insOrderStandardTemplateService.count(Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, orderId)); |
| | | if (firstSubmit || snapshotCount == 0) { |
| | | this.templateCopy(orderId, InsSampleIds); |
| | | } |
| | | |
| | | // 9.添加临时pdf生成地址 |
| | | InsReport report = insReportMapper.selectOne(Wrappers.<InsReport>lambdaQuery() |
| | | .eq(InsReport::getInsOrderId, orderId)); |
| | | String tempUrlPdf = this.wordToPdfTemp(report.getUrl().replace("/word", wordUrl)); |
| | | report.setTempUrlPdf("/word/" + tempUrlPdf); |
| | | insReportMapper.updateById(report); |
| | | // 9. 检测报告仅在全部复核通过时生成,提交复核阶段不生成报告。 |
| | | |
| | | // 10.原始记录模板复制(添加备份, 避免修改原始模板影响到已经完成的单子) |
| | | this.templateCopy(orderId, InsSampleIds); |
| | | |
| | | // 11.成品抽样添加合格状态 |
| | | // 10.成品抽样添加合格状态 |
| | | // 判断是否有抽样信息 |
| | | if (order.getQuarterItemId() != null) { |
| | | if (isInspectionReport && order.getQuarterItemId() != null) { |
| | | // 判断是否有不合格 |
| | | this.addProductSpotCheck(insSamples, order); |
| | | } |
| | | |
| | | // 12.添加工时 |
| | | // 删除原本订单工时 |
| | | auxiliaryOutputWorkingHoursService.remove(Wrappers.<AuxiliaryOutputWorkingHours>lambdaQuery() |
| | | .eq(AuxiliaryOutputWorkingHours::getOrderId, orderId)); |
| | | // 查询工时暂存 |
| | | List<AuxiliaryOutputWorkingHoursTemporary> hoursTemporaries = auxiliaryOutputWorkingHoursTemporaryService.list(Wrappers.<AuxiliaryOutputWorkingHoursTemporary>lambdaQuery() |
| | | .eq(AuxiliaryOutputWorkingHoursTemporary::getOrderId, orderId)); |
| | | List<AuxiliaryOutputWorkingHours> outputWorkingHours = hoursTemporaries.stream().map(hoursTemporary -> { |
| | | AuxiliaryOutputWorkingHours workingHours = new AuxiliaryOutputWorkingHours(); |
| | | BeanUtil.copyProperties(hoursTemporary, workingHours); |
| | | workingHours.setId(null); |
| | | return workingHours; |
| | | }).collect(Collectors.toList()); |
| | | auxiliaryOutputWorkingHoursService.saveBatch(outputWorkingHours); |
| | | |
| | | // 13.添加订单费用统计信息 |
| | | // 11.添加订单费用统计信息 |
| | | List<InsProduct> productList = insProductMapper.selectProductByOrderId(orderId); |
| | | // 删除原本费用信息 |
| | | insOrderRatesService.remove(Wrappers.<InsOrderRates>lambdaQuery() |
| | |
| | | insOrderRatesService.saveBatch(orderRatesList); |
| | | |
| | | |
| | | // 14.发送企业微信通知 |
| | | // 12.发送企业微信通知 |
| | | // 查询原材料 |
| | | IfsInventoryQuantity ifsInventoryQuantity = ifsInventoryQuantityMapper.selectById(order.getIfsInventoryId()); |
| | | // 查询样品信息 |
| | |
| | | } |
| | | //发送企业微信消息通知 提交复核 |
| | | try { |
| | | WxCpUtils.inform(sendUserAccount, message, null); |
| | | // WxCpUtils.inform(sendUserAccount, message, null); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | }); |
| | | |
| | | // 15.ifs移库(原材料需要进行移库操作) --> 最后执行,因为失败无法回滚 |
| | | if (ifsInventoryQuantity != null) { |
| | | // 13.ifs移库(原材料需要进行移库操作) --> 最后执行,因为失败无法回滚 |
| | | if (ifsInventoryQuantity != null && isInspectionReport) { |
| | | // 登记检验结果 |
| | | // 判断是否有不合格, 有不合格不能移库 |
| | | // todo: ifs移库 |
| | | insReportService.isRawMaterial(order); |
| | | } else { |
| | | insReportService.isRawMaterial(order, registerInsResults, false); |
| | | |
| | | // 14 判断当前样品是否为原材料, 原材料需要进行数据分析, 判断之前10条数据同一个供应商, 同一个检验项的偏差是否超过10% |
| | | // 查询ifs信息获取获取前10个供应商一样的, 检验项一样信息 |
| | | threadPoolTaskExecutor.execute(() -> { |
| | | // 添加分析数据 |
| | | addAnalysis(productList, ifsInventoryQuantity, order, sendUserAccount); |
| | | }); |
| | | |
| | | |
| | | } else if (isInspectionReport && !directTemplateOrder) { |
| | | // 修改成品状态 |
| | | // 判断是否有不合格 |
| | | Long unqualifiedCount = insReportService.getUnqualifiedCount(order); |
| | |
| | | return 1; |
| | | } |
| | | |
| | | /** |
| | | * *****添加分析数据****** |
| | | * |
| | | * @param productList |
| | | * @param ifsInventoryQuantity |
| | | * @param order |
| | | */ |
| | | private void addAnalysis(List<InsProduct> productList, IfsInventoryQuantity ifsInventoryQuantity, InsOrder order, String sendUserAccount) { |
| | | for (InsProduct insProduct : productList) { |
| | | // 判断是否是数值类型 |
| | | if ("1".equals(insProduct.getInspectionValueType()) && Objects.equals(insProduct.getInsResult(), 1)) { |
| | | List<InsProductDeviationWarningDetail> insProductAnalysisDtoList = insProductMapper.selectAnalysis(insProduct, ifsInventoryQuantity.getSupplierName()); |
| | | |
| | | if (CollectionUtils.isEmpty(insProductAnalysisDtoList)) { |
| | | continue; |
| | | } |
| | | |
| | | // 判断当前检测项是否偏差超过10% |
| | | List<String> laseValueList = insProductAnalysisDtoList.stream().map(InsProductDeviationWarningDetail::getTestValue) |
| | | .collect(Collectors.toList()); |
| | | |
| | | double deviation = isDeviationOverTenPercent(laseValueList, insProduct.getLastValue()); |
| | | // 判断要求值是否偏差超过10% |
| | | double asked = isDeviationOverTenPercentByAsked(insProduct.getAsk(), insProduct.getLastValue()); |
| | | // 判断偏差是否大于10 |
| | | if (deviation > 10 || asked > 10) { |
| | | // 判断之前是否添加过, 添加过不需要添加 |
| | | long count = insProductDeviationWarningService.count(Wrappers.<InsProductDeviationWarning>lambdaQuery() |
| | | .eq(InsProductDeviationWarning::getInsProductId, insProduct.getId())); |
| | | if (count == 0L) { |
| | | // 发送通知, 并且添加数据 |
| | | // 添加主表信息 |
| | | InsProductDeviationWarning deviationWarning = new InsProductDeviationWarning(); |
| | | deviationWarning.setInsOrderId(order.getId()); |
| | | deviationWarning.setInsSampleId(insProduct.getInsSampleId()); |
| | | deviationWarning.setInsProductId(insProduct.getId()); |
| | | deviationWarning.setEntrustCode(order.getEntrustCode()); |
| | | deviationWarning.setSampleCode(insProduct.getSampleCode()); |
| | | deviationWarning.setSupplierName(ifsInventoryQuantity.getSupplierName()); |
| | | deviationWarning.setDeviationValue(Double.toString(deviation)); |
| | | deviationWarning.setDetectionTime(insProduct.getUpdateTime()); |
| | | insProductDeviationWarningService.save(deviationWarning); |
| | | |
| | | // 添加详情数据 |
| | | InsProductDeviationWarningDetail deviationWarningDetail = new InsProductDeviationWarningDetail(); |
| | | deviationWarningDetail.setInsOrderId(order.getId()); |
| | | deviationWarningDetail.setInsSampleId(insProduct.getInsSampleId()); |
| | | deviationWarningDetail.setInsProductId(insProduct.getId()); |
| | | deviationWarningDetail.setEntrustCode(order.getEntrustCode()); |
| | | deviationWarningDetail.setSampleCode(insProduct.getSampleCode()); |
| | | deviationWarningDetail.setSupplierName(ifsInventoryQuantity.getSupplierName()); |
| | | deviationWarningDetail.setTestValue(insProduct.getLastValue()); |
| | | deviationWarningDetail.setDetectionTime(insProduct.getCreateTime()); |
| | | deviationWarningDetail.setIsIssue(deviation > 10 ? 1 : 0); |
| | | deviationWarningDetail.setIsIssueAsked(asked > 10 ? 1 : 0); |
| | | |
| | | insProductAnalysisDtoList.add(deviationWarningDetail); |
| | | |
| | | // 添加id |
| | | for (InsProductDeviationWarningDetail warningDetail : insProductAnalysisDtoList) { |
| | | warningDetail.setDeviationWarningId(deviationWarning.getDeviationWarningId()); |
| | | } |
| | | |
| | | insProductDeviationWarningDetailService.saveBatch(insProductAnalysisDtoList); |
| | | |
| | | //发送企业微信消息通知 检验项预警预警通知 |
| | | try { |
| | | String message = ""; |
| | | message += "检验项预警预警通知"; |
| | | message += "\n委托编号: " + order.getEntrustCode(); |
| | | message += "\n样品名称: " + order.getSample(); |
| | | message += "\n规格型号: " + order.getPartDetail(); |
| | | message += "\n批次号: " + ifsInventoryQuantity.getUpdateBatchNo(); |
| | | message += "\n供应商名称: " + ifsInventoryQuantity.getSupplierName(); |
| | | message += "\n检验项: " + insProduct.getInspectionItem() + insProduct.getInspectionItemSubclass(); |
| | | message += "\n偏差超过了 10%"; |
| | | // 发送给提交人 |
| | | // WxCpUtils.inform(sendUserAccount, message, null); |
| | | // |
| | | // // todo: 发送给检测中心主任(固定死) |
| | | // WxCpUtils.inform("ZT-004704", message, null); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | log.error("偏差预警企业微信通知报错"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * *****计算偏差**** |
| | | * |
| | | * @param data |
| | | * @param targetStr |
| | | * @return |
| | | */ |
| | | public static double isDeviationOverTenPercent(List<String> data, String targetStr) { |
| | | if (data.isEmpty()) { |
| | | return 0; |
| | | } |
| | | List<Double> doubleData = data.stream() |
| | | .map(Double::parseDouble) |
| | | .collect(Collectors.toList()); |
| | | double sum = doubleData.stream().mapToDouble(Double::doubleValue).sum(); |
| | | double average = sum / doubleData.size(); |
| | | |
| | | double target = Double.parseDouble(targetStr); |
| | | double deviationPercent = Math.abs(target - average) / average * 100; |
| | | |
| | | // 保留两位小数 |
| | | DecimalFormat df = new DecimalFormat("#.00"); |
| | | String formatted = df.format(deviationPercent); |
| | | return Double.parseDouble(formatted); |
| | | } |
| | | |
| | | /** |
| | | * *****计算偏差(要求值)**** |
| | | * |
| | | * @param asked |
| | | * @param targetStr |
| | | * @return |
| | | */ |
| | | public static double isDeviationOverTenPercentByAsked(String asked, String targetStr) { |
| | | if (!isNumeric(asked)) return 0; |
| | | double average = Double.parseDouble(asked); |
| | | double target = Double.parseDouble(targetStr); |
| | | double deviationPercent = Math.abs(target - average) / average * 100; |
| | | |
| | | // 保留两位小数 |
| | | DecimalFormat df = new DecimalFormat("#.00"); |
| | | String formatted = df.format(deviationPercent); |
| | | return Double.parseDouble(formatted); |
| | | } |
| | | |
| | | /** |
| | | * ******原始记录模板复制***** |
| | | * |
| | | * @param orderId |
| | | * @param ids |
| | | */ |
| | | private void templateCopy(Integer orderId, List<Integer> ids) { |
| | | // 删除原本模板 |
| | | insOrderStandardTemplateService.remove(Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, orderId)); |
| | | // 复制模板 |
| | | Set<Integer> set = new HashSet<>(); |
| | | // 保留模板页签顺序,并在首次提交复核时用检验期间采用的最新模板刷新快照。 |
| | | // 直绑模板订单必须以原订单快照为模板清单,不能只按 ins_product 重建: |
| | | // 没有“检验项”标记的模板不会生成 ins_product,否则提交后会被错误删除。 |
| | | List<InsOrderStandardTemplate> oldSnapshots = insOrderStandardTemplateService.list( |
| | | Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, orderId) |
| | | .orderByAsc(InsOrderStandardTemplate::getSort, InsOrderStandardTemplate::getId)); |
| | | Map<Integer, Integer> templateSortMap = new HashMap<>(); |
| | | Map<Integer, String> templateRecordValuesMap = new HashMap<>(); |
| | | Map<Integer, String> templateTemperatureMap = new HashMap<>(); |
| | | Map<Integer, String> templateHumidityMap = new HashMap<>(); |
| | | Map<Integer, InsOrderStandardTemplate> oldSnapshotMap = new LinkedHashMap<>(); |
| | | int nextTemplateSort = 0; |
| | | for (InsOrderStandardTemplate snapshot : oldSnapshots) { |
| | | if (snapshot.getTemplateId() != null) { |
| | | oldSnapshotMap.putIfAbsent(snapshot.getTemplateId(), snapshot); |
| | | if (snapshot.getSort() != null) { |
| | | templateSortMap.putIfAbsent(snapshot.getTemplateId(), snapshot.getSort()); |
| | | nextTemplateSort = Math.max(nextTemplateSort, snapshot.getSort() + 1); |
| | | } |
| | | if (snapshot.getRecordValues() != null) { |
| | | templateRecordValuesMap.putIfAbsent(snapshot.getTemplateId(), snapshot.getRecordValues()); |
| | | } |
| | | if (snapshot.getTemperature() != null) { |
| | | templateTemperatureMap.putIfAbsent(snapshot.getTemplateId(), snapshot.getTemperature()); |
| | | } |
| | | if (snapshot.getHumidity() != null) { |
| | | templateHumidityMap.putIfAbsent(snapshot.getTemplateId(), snapshot.getHumidity()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | LinkedHashSet<Integer> templateIds = new LinkedHashSet<>(); |
| | | if (isDirectTemplateOrder(orderId)) { |
| | | // 先加入订单原来绑定的全部模板,包括不生成检验项记录的模板。 |
| | | templateIds.addAll(oldSnapshotMap.keySet()); |
| | | } |
| | | List<InsProduct> insProductList = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery() |
| | | .in(InsProduct::getInsSampleId, ids) |
| | | .select(InsProduct::getTemplateId)); |
| | | insProductList.stream() |
| | | .map(InsProduct::getTemplateId) |
| | | .filter(Objects::nonNull) |
| | | .forEach(templateIds::add); |
| | | |
| | | for (InsProduct product : insProductList) { |
| | | // 查询模板id |
| | | if (product.getTemplateId() != null && set.add(product.getTemplateId())) { |
| | | StandardTemplate standardTemplate = standardTemplateService.getById(product.getTemplateId()); |
| | | if (standardTemplate != null) { |
| | | InsOrderStandardTemplate insOrderStandardTemplate = new InsOrderStandardTemplate(); |
| | | insOrderStandardTemplate.setInsOrderId(orderId); |
| | | insOrderStandardTemplate.setTemplateId(standardTemplate.getId()); |
| | | insOrderStandardTemplate.setNumber(standardTemplate.getNumber()); |
| | | insOrderStandardTemplate.setName(standardTemplate.getName()); |
| | | insOrderStandardTemplate.setThing(standardTemplate.getThing()); |
| | | insOrderStandardTemplateService.save(insOrderStandardTemplate); |
| | | } |
| | | List<InsOrderStandardTemplate> refreshedSnapshots = new ArrayList<>(); |
| | | for (Integer templateId : templateIds) { |
| | | StandardTemplate standardTemplate = standardTemplateService.getById(templateId); |
| | | InsOrderStandardTemplate oldSnapshot = oldSnapshotMap.get(templateId); |
| | | if (standardTemplate == null && oldSnapshot == null) { |
| | | continue; |
| | | } |
| | | InsOrderStandardTemplate refreshed = new InsOrderStandardTemplate(); |
| | | refreshed.setInsOrderId(orderId); |
| | | refreshed.setTemplateId(templateId); |
| | | refreshed.setNumber(standardTemplate == null ? oldSnapshot.getNumber() : standardTemplate.getNumber()); |
| | | refreshed.setName(standardTemplate == null ? oldSnapshot.getName() : standardTemplate.getName()); |
| | | refreshed.setRemark(standardTemplate == null ? oldSnapshot.getRemark() : standardTemplate.getRemark()); |
| | | refreshed.setThing(standardTemplate == null ? oldSnapshot.getThing() : standardTemplate.getThing()); |
| | | refreshed.setRecordValues(templateRecordValuesMap.get(templateId)); |
| | | refreshed.setTemperature(templateTemperatureMap.get(templateId)); |
| | | refreshed.setHumidity(templateHumidityMap.get(templateId)); |
| | | Integer templateSort = templateSortMap.get(templateId); |
| | | refreshed.setSort(templateSort == null ? nextTemplateSort++ : templateSort); |
| | | refreshedSnapshots.add(refreshed); |
| | | } |
| | | |
| | | // 新快照已完整组装后再替换;事务失败时会整体回滚。 |
| | | insOrderStandardTemplateService.remove(Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, orderId)); |
| | | if (!refreshedSnapshots.isEmpty()) { |
| | | insOrderStandardTemplateService.saveBatch(refreshedSnapshots); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 检验任务复核 |
| | | * |
| | | * @param orderId |
| | | * @param laboratory |
| | | * @param type |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int rawMaterialVerifyPlan(Integer orderId, String laboratory, Integer type, String tell, Integer userId) { |
| | | VerifyPlanDto dto = new VerifyPlanDto(); |
| | | dto.setOrderId(orderId); |
| | | dto.setLaboratory(laboratory); |
| | | dto.setType(type); |
| | | dto.setTell(tell); |
| | | dto.setUserId(userId); |
| | | return rawMaterialVerifyPlan(dto); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int rawMaterialVerifyPlan(VerifyPlanDto dto) { |
| | | Integer orderId = dto.getOrderId(); |
| | | String laboratory = dto.getLaboratory(); |
| | | Integer type = dto.getType(); |
| | | String tell = dto.getTell(); |
| | | Integer userId = dto.getUserId(); |
| | | if (orderId == null || laboratory == null || type == null) { |
| | | throw new ErrorException("复核参数不完整"); |
| | | } |
| | | ensureDirectTemplateOrderState(orderId); |
| | | InsOrderState currentState = insOrderStateMapper.selectOne(Wrappers.<InsOrderState>lambdaQuery() |
| | | .eq(InsOrderState::getInsOrderId, orderId) |
| | | .eq(InsOrderState::getLaboratory, laboratory) |
| | | .last("limit 1")); |
| | | InsReport existingReport = insReportMapper.selectOne(Wrappers.<InsReport>lambdaQuery() |
| | | .eq(InsReport::getInsOrderId, orderId) |
| | | .last("limit 1")); |
| | | if (currentState != null && Objects.equals(currentState.getInsState(), 5) |
| | | && existingReport != null && StringUtils.isNotBlank(existingReport.getUrl())) { |
| | | // 防止复核页面重复点击或网络重试重复生成报告、重复发起报告审批。 |
| | | return 1; |
| | | } |
| | | boolean directTemplateOrder = isDirectTemplateOrder(orderId); |
| | | if (directTemplateOrder && Objects.equals(type, 1) |
| | | && !Objects.equals(dto.getInsResult(), 0) && !Objects.equals(dto.getInsResult(), 1)) { |
| | | throw new ErrorException("请选择检验单结论"); |
| | | } |
| | | Integer num = (type == 1 ? 5 : 4); |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | insOrderStateMapper.update(null, Wrappers.<InsOrderState>lambdaUpdate() |
| | |
| | | .eq(InsOrderState::getInsOrderId, orderId) |
| | | .ne(InsOrderState::getInsState, 5)); |
| | | InsReport report = insReportMapper.selectOne(Wrappers.<InsReport>lambdaQuery() |
| | | .eq(InsReport::getInsOrderId, orderId)); |
| | | .eq(InsReport::getInsOrderId, orderId) |
| | | .last("limit 1")); |
| | | Integer writeUserId = report != null && report.getWriteUserId() != null |
| | | ? report.getWriteUserId() : resolveInspectionUserId(orderId, laboratory); |
| | | // 查询订单 |
| | | InsOrder order = insOrderMapper.selectById(orderId); |
| | | if (directTemplateOrder && Objects.equals(type, 1)) { |
| | | List<Integer> templateResults = insOrderStandardTemplateService.list( |
| | | Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, orderId) |
| | | .select(InsOrderStandardTemplate::getInsResult)) |
| | | .stream().map(InsOrderStandardTemplate::getInsResult) |
| | | .collect(Collectors.toList()); |
| | | if (templateResults.isEmpty() |
| | | || templateResults.stream().anyMatch(result -> !Objects.equals(result, 0) |
| | | && !Objects.equals(result, 1))) { |
| | | throw new ErrorException("请先填写全部模板的检验结论"); |
| | | } |
| | | Integer aggregateResult = templateResults.stream().allMatch(result -> Objects.equals(result, 1)) |
| | | ? 1 : 0; |
| | | insOrderMapper.update(null, Wrappers.<InsOrder>lambdaUpdate() |
| | | .eq(InsOrder::getId, orderId) |
| | | .set(InsOrder::getInsResult, aggregateResult)); |
| | | order.setInsResult(aggregateResult); |
| | | } |
| | | if (count == 0 && num == 5) { |
| | | // 修改报告状态 |
| | | insReportMapper.update(null, Wrappers.<InsReport>lambdaUpdate() |
| | | .eq(InsReport::getInsOrderId, orderId) |
| | | .set(InsReport::getIsPass, 1)); |
| | | |
| | | // 修改订单状态 |
| | | insOrderMapper.update(null, Wrappers.<InsOrder>lambdaUpdate() |
| | | .eq(InsOrder::getId, orderId) |
| | | .set(InsOrder::getInsState, 5)); |
| | | |
| | | // 检验人员提交复核时不再生成报告;仅在全部试验室复核通过后生成检测报告。 |
| | | if (report == null || StringUtils.isBlank(report.getUrl())) { |
| | | this.generateReport(orderId, DETECTION_REPORT, writeUserId); |
| | | report = insReportMapper.selectOne(Wrappers.<InsReport>lambdaQuery() |
| | | .eq(InsReport::getInsOrderId, orderId) |
| | | .last("limit 1")); |
| | | } |
| | | if (report == null || StringUtils.isBlank(report.getUrl())) { |
| | | throw new ErrorException("检测报告生成失败"); |
| | | } |
| | | if (report.getTempUrlPdf() == null) { |
| | | String tempUrlPdf = this.wordToPdfTemp(report.getUrl().replace("/word", wordUrl)); |
| | | report.setTempUrlPdf("/word/" + tempUrlPdf); |
| | | } |
| | | report.setIsPass(1); |
| | | insReportMapper.updateById(report); |
| | | |
| | | //生成原材料进货验证原始记录到附件里 |
| | | if (order.getTypeSource() != null && order.getTypeSource().equals(1)) { |
| | | this.reportFactoryVerify(orderId, userId, report.getWriteUserId()); |
| | | this.reportFactoryVerify(orderId, userId, writeUserId); |
| | | } |
| | | |
| | | // 查询检验任务的检验任务 |
| | | // 报告盖上批准人 |
| | | insReportService.writeReport(report.getId(), userId, report.getWriteUserId()); |
| | | insReportService.writeReport(report.getId(), userId, writeUserId); |
| | | |
| | | // 检验人 |
| | | String userName = insProductMapper.selectUserById(report.getWriteUserId()).get("name"); |
| | | String userName = insProductMapper.selectUserById(writeUserId).get("name"); |
| | | |
| | | // 复核人 |
| | | Integer checkUserId = SecurityUtils.getUserId().intValue(); |
| | |
| | | |
| | | // 发送消息的人 |
| | | // 查询发送人信息 |
| | | String sendUserAccount = insProductMapper.selectUserById(report.getWriteUserId()).get("account"); |
| | | String sendUserAccount = insProductMapper.selectUserById(writeUserId).get("account"); |
| | | |
| | | // 发送企业微信通知(检验任务退回) |
| | | threadPoolTaskExecutor.execute(() -> { |
| | |
| | | return 1; |
| | | } |
| | | |
| | | private boolean isDirectTemplateOrder(Integer orderId) { |
| | | List<InsSample> samples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery() |
| | | .eq(InsSample::getInsOrderId, orderId)); |
| | | if (samples.isEmpty()) { |
| | | return false; |
| | | } |
| | | Long snapshotCount = insOrderStandardTemplateService.count( |
| | | Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, orderId)); |
| | | InsOrder order = snapshotCount == 0 ? null : insOrderMapper.selectById(orderId); |
| | | if (order != null && samples.stream().anyMatch(sample -> isDirectTemplateSample(order, sample))) { |
| | | return true; |
| | | } |
| | | // 兼容已经生成了模板行号、但订单基础字段不完整的历史直绑订单。 |
| | | return insProductMapper.selectCount(Wrappers.<InsProduct>lambdaQuery() |
| | | .in(InsProduct::getInsSampleId, samples.stream().map(InsSample::getId).collect(Collectors.toList())) |
| | | .isNotNull(InsProduct::getTemplateRowIndex)) > 0; |
| | | } |
| | | |
| | | /** |
| | | * 兼容修复上线前已经下发、但因没有 ins_product 而缺少任务状态的直绑模板订单。 |
| | | */ |
| | | private void ensureDirectTemplateOrderState(Integer orderId) { |
| | | if (!isDirectTemplateOrder(orderId)) { |
| | | return; |
| | | } |
| | | Long stateCount = insOrderStateMapper.selectCount(Wrappers.<InsOrderState>lambdaQuery() |
| | | .eq(InsOrderState::getInsOrderId, orderId) |
| | | .eq(InsOrderState::getLaboratory, DIRECT_TEMPLATE_LABORATORY)); |
| | | if (stateCount > 0) { |
| | | return; |
| | | } |
| | | InsOrderState state = new InsOrderState(); |
| | | state.setInsOrderId(orderId); |
| | | state.setLaboratory(DIRECT_TEMPLATE_LABORATORY); |
| | | state.setInsState(0); |
| | | insOrderStateMapper.insert(state); |
| | | } |
| | | |
| | | private Integer resolveInspectionUserId(Integer orderId, String laboratory) { |
| | | InsSampleUser inspector = insSampleUserMapper.selectOne(Wrappers.<InsSampleUser>lambdaQuery() |
| | | .eq(InsSampleUser::getInsSampleId, orderId) |
| | | .eq(InsSampleUser::getState, 0) |
| | | .eq(StringUtils.isNotBlank(laboratory), InsSampleUser::getSonLaboratory, laboratory) |
| | | .orderByDesc(InsSampleUser::getId) |
| | | .last("limit 1")); |
| | | if (inspector == null || inspector.getUserId() == null) { |
| | | throw new ErrorException("找不到当前检验任务的检验人,无法生成检测报告"); |
| | | } |
| | | return inspector.getUserId(); |
| | | } |
| | | |
| | | /** |
| | | * 生成报告 |
| | | * |
| | | * @param orderId |
| | | */ |
| | | private void generateReport(Integer orderId) { |
| | | private void generateReport(Integer orderId, Integer reportType, Integer writeUserId) { |
| | | /*样品下的项目只要有一个项目不合格则检验结果为0,否则为1*/ |
| | | //这里的insSamples是订单下的所有样品包括("/") |
| | | List<InsSample> insSamples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery().eq(InsSample::getInsOrderId, orderId)); |
| | | for (InsSample insSample : insSamples) { |
| | | List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery() |
| | | .eq(InsProduct::getInsSampleId, insSample.getId()) |
| | | .eq(InsProduct::getState, 1) |
| | | .ne(InsProduct::getIsBinding, 1)); |
| | | List<Integer> results = insProducts.stream().map(InsProduct::getInsResult).filter(str -> str != null).collect(Collectors.toList()); |
| | | if (results.contains(0)) { |
| | | insSample.setInsResult(0); |
| | | } else { |
| | | insSample.setInsResult(1); |
| | | if (Objects.equals(reportType, INSPECTION_REPORT)) { |
| | | for (InsSample insSample : insSamples) { |
| | | List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery() |
| | | .eq(InsProduct::getInsSampleId, insSample.getId()) |
| | | .eq(InsProduct::getState, 1) |
| | | .ne(InsProduct::getIsBinding, 1)); |
| | | List<Integer> results = insProducts.stream().map(InsProduct::getInsResult).filter(Objects::nonNull).collect(Collectors.toList()); |
| | | if (results.contains(0)) { |
| | | insSample.setInsResult(0); |
| | | } else { |
| | | insSample.setInsResult(1); |
| | | } |
| | | insSampleMapper.updateById(insSample); |
| | | } |
| | | insSampleMapper.updateById(insSample); |
| | | } |
| | | InsOrder insOrder = insOrderMapper.selectById(orderId); |
| | | // 抽检变成委托检验 |
| | |
| | | // 判断是大报告还是小报告 进厂小报告, 其他都是大报告 |
| | | if (insOrder.getOrderType().equals(InsOrderTypeConstants.ENTER_THE_FACTORY)) { |
| | | // 生成小报告 |
| | | addSmallReport(orderId, insOrder, insSamples); |
| | | addSmallReport(orderId, insOrder, insSamples, reportType, writeUserId); |
| | | } else { |
| | | //生成大报告 |
| | | addBitReport(orderId, insOrder); |
| | | addBitReport(orderId, insOrder, reportType, writeUserId); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | /** |
| | | * 电缆配置, 查看配置标识 |
| | | * |
| | | * @param id |
| | | * @param laboratory |
| | | * @return |
| | |
| | | |
| | | /** |
| | | * 原材料查看标识 |
| | | * |
| | | * @param id |
| | | * @param laboratory |
| | | * @return |
| | |
| | | |
| | | /** |
| | | * 查看重复标识 |
| | | * |
| | | * @param id |
| | | * @param laboratory |
| | | * @return |
| | |
| | | } |
| | | |
| | | /** |
| | | * 获取不合格数据 |
| | | * @return |
| | | */ |
| | | @Override |
| | | public List<InsProduct> getInsProductUnqualified(InsOrderPlanProductDto dto) { |
| | | List<InsProduct> insProducts = new ArrayList<>(); |
| | | switch (dto.getType()) { |
| | | case 0: |
| | | //样品 |
| | | insProducts = insSampleMapper.getInsProduct1(dto.getId(), dto.getLaboratory(), dto.getCableTag(), dto.getRepetitionTag(), "1"); |
| | | break; |
| | | case 4: |
| | | //电缆配置 |
| | | insProducts = insSampleMapper.getInsProduct1(dto.getId(), dto.getLaboratory(), dto.getCableTag(), dto.getRepetitionTag(), "1"); |
| | | break; |
| | | case 5: |
| | | //原材料下单 |
| | | insProducts = insSampleMapper.getInsProduct6(dto.getId(), dto.getLaboratory(), dto.getRawMaterialTag(), "1"); |
| | | break; |
| | | } |
| | | return insProducts; |
| | | } |
| | | |
| | | /** |
| | | * 新增不合格复测内容 |
| | | * @param ids |
| | | * |
| | | * @return |
| | | */ |
| | | @Override |
| | | public boolean addDisqualificationRetest(List<Integer> ids) { |
| | | public boolean addDisqualificationRetest(List<InsProduct> insProductsList) { |
| | | List<Integer> ids = insProductsList.stream().map(InsProduct::getId).collect(Collectors.toList()); |
| | | |
| | | // 判断之前是否添加过 |
| | | Long count = insUnqualifiedRetestProductMapper.selectCount(Wrappers.<InsUnqualifiedRetestProduct>lambdaQuery() |
| | | .in(InsUnqualifiedRetestProduct::getInsProductId, ids)); |
| | |
| | | |
| | | // 查询不合格内容 |
| | | List<InsUnqualifiedRetestProduct> list = insUnqualifiedRetestProductMapper.selectRetestProduct(ids); |
| | | // 循环判断是否是绑定值, 绑定值修改检验要求 |
| | | for (InsUnqualifiedRetestProduct insUnqualifiedRetestProduct : list) { |
| | | for (InsProduct insProduct : insProductsList) { |
| | | if (insProduct.getIsBinding().equals(1)) { |
| | | insUnqualifiedRetestProduct.setIsBinding(1); |
| | | insUnqualifiedRetestProduct.setAsk(null); |
| | | insUnqualifiedRetestProduct.setTell(null); |
| | | insUnqualifiedRetestProduct.setPrice(null); |
| | | insUnqualifiedRetestProduct.setManHour(null); |
| | | insUnqualifiedRetestProduct.setSection(null); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 新增不合格内容 |
| | | insUnqualifiedRetestProductService.saveBatch(list); |
| | | list.forEach(insUnqualifiedRetestProduct -> { |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<InsProduct> getInsProductUnqualifiedRetest(Integer id, Integer type, String laboratory, String cableTag, String rawMaterialTag, String retestTag) { |
| | | public List<InsProduct> getInsProductUnqualifiedRetest(InsOrderPlanProductDto dto) { |
| | | |
| | | List<InsProduct> insProducts = new ArrayList<>(); |
| | | switch (type) { |
| | | switch (dto.getType()) { |
| | | case 0: |
| | | //样品 |
| | | insProducts = insUnqualifiedRetestProductMapper.getInsProductUnqualifiedRetest1(id, laboratory, retestTag); |
| | | break; |
| | | case 4: |
| | | //电缆配置 |
| | | insProducts = insUnqualifiedRetestProductMapper.getInsProductUnqualifiedRetest5(id, laboratory, cableTag, retestTag); |
| | | //委托 |
| | | insProducts = insUnqualifiedRetestProductMapper.getInsProductUnqualifiedRetest1(dto.getId(), dto.getLaboratory(), dto.getCableTag(), dto.getRepetitionTag(), dto.getRetestTag()); |
| | | break; |
| | | case 5: |
| | | //原材料下单 |
| | | insProducts = insUnqualifiedRetestProductMapper.getInsProductUnqualifiedRetest6(id, laboratory, rawMaterialTag, retestTag); |
| | | insProducts = insUnqualifiedRetestProductMapper.getInsProductUnqualifiedRetest6(dto.getId(), dto.getLaboratory(), dto.getRawMaterialTag(), dto.getRetestTag()); |
| | | break; |
| | | } |
| | | if (BeanUtil.isEmpty(insProducts)) { |
| | | return null; |
| | | } |
| | | InsOrder order = insOrderMapper.selectFirstSubmit(id); |
| | | getTemplateThing(order, Collections.unmodifiableList(insProducts)); |
| | | InsOrder order = insOrderMapper.selectFirstSubmit(dto.getId()); |
| | | getTemplateThing(order, Collections.unmodifiableList(insProducts), dto.getLaboratory()); |
| | | return insProducts; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 保存不合格复测检验内容 |
| | | * @param currentTable |
| | | * @param orderId |
| | | * @param sonLaboratory |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void saveUnqualifiedContext(Map<String, Object> insContext, Integer currentTable, Integer currentSampleId, Integer orderId, String sonLaboratory) { |
| | |
| | | BeanUtil.copyProperties(oldResults.get(0), newResult); |
| | | } |
| | | newResult.setRetestProductId(Integer.parseInt(k)); |
| | | |
| | | /*校验一下result表*/ |
| | | if (oldResults.size() > 1) { |
| | | for (int i = 1; i < oldResults.size(); i++) { |
| | | insUnqualifiedRetestResultMapper.deleteById(oldResults.get(i)); |
| | | } |
| | | } |
| | | |
| | | //检验值 |
| | | if (jo.get("insValue") != null) { |
| | | JSONArray jsonArray = JSON.parseArray(JSON.toJSONString(jo.get("insValue"))); |
| | |
| | | for (Object o : jsonArray2) { |
| | | JSONObject comValue = JSON.parseObject(JSON.toJSONString(o)); |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("r", JSON.toJSONString(comValue.get("r"))); |
| | | map.put("c", JSON.toJSONString(comValue.get("c"))); |
| | | map.put("v", JSON.parseObject(JSON.toJSONString(comValue.get("v"))).get("v")); |
| | | cv.add(map); |
| | | } |
| | |
| | | insProductUserMapper.insert(new InsProductUser(null, userId, LocalDateTime.now(), insProduct.getId())); |
| | | |
| | | |
| | | InsSample insSample = insSampleMapper.selectById(insProductMapper.selectById(insProduct.getId()).getInsSampleId()); |
| | | insSample.setInsState(1); |
| | | Long l = insProductMapper.selectCount(Wrappers.<InsProduct>lambdaQuery() |
| | | .eq(InsProduct::getInsSampleId, insSample.getId())); |
| | | Long l1 = insProductMapper.selectCount(Wrappers.<InsProduct>lambdaQuery() |
| | | .eq(InsProduct::getInsSampleId, insSample.getId()) |
| | | .and(wrapper -> wrapper |
| | | .isNotNull(InsProduct::getInsResult) |
| | | .or() |
| | | .ne(InsProduct::getInsResult, 2) |
| | | )); |
| | | if (Objects.equals(l, l1)) { |
| | | insSample.setInsState(2); |
| | | } |
| | | insSampleMapper.updateById(insSample); |
| | | /*校验一下result表*/ |
| | | List<InsUnqualifiedRetestResult> insProductResults = insUnqualifiedRetestResultMapper.selectList(Wrappers.<InsUnqualifiedRetestResult>lambdaQuery() |
| | | .eq(InsUnqualifiedRetestResult::getRetestProductId, insProduct.getId())); |
| | | .eq(InsUnqualifiedRetestResult::getRetestProductId, product.getId())); |
| | | if (insProductResults.size() > 1) { |
| | | for (int i = 1; i < insProductResults.size(); i++) { |
| | | insUnqualifiedRetestResultMapper.deleteById(insProductResults.get(i)); |
| | | } |
| | | } |
| | | |
| | | } |
| | | }); |
| | | String sampleIdStr = insContext.keySet().stream().findFirst().orElse(null); |
| | | if (sampleIdStr != null) { |
| | | int count = insProductMapper.selectInsProductCountByOrderId(orderId); |
| | | if (count == 0) { |
| | | insOrderStateMapper.update(new InsOrderState(), Wrappers.<InsOrderState>lambdaUpdate() |
| | | .eq(InsOrderState::getInsOrderId, orderId) |
| | | .eq(InsOrderState::getLaboratory, sonLaboratory) |
| | | .set(InsOrderState::getInsState, 2)); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 查询进货原始记录 |
| | | * |
| | | * @param insOrderId |
| | | * @return |
| | | */ |
| | |
| | | |
| | | /** |
| | | * 保存原材料进货验证 |
| | | * |
| | | * @param factoryVerify |
| | | * @return |
| | | */ |
| | |
| | | /***************************************************** 小报告 ***************************************************************************/ |
| | | |
| | | /** |
| | | * 设置表格样式 |
| | | * |
| | | * @param max 标识最大个数 |
| | | * @return |
| | | */ |
| | | private TableStyle setTableStyle(int max, boolean showResult) { |
| | | //设置样式 |
| | | TableStyle tableStyle = new TableStyle(); |
| | | if (!showResult) { |
| | | switch (max) { |
| | | case 1: |
| | | tableStyle.setColWidths(new int[]{650, 3000, 850, 2400, 3100}); |
| | | break; |
| | | case 2: |
| | | tableStyle.setColWidths(new int[]{650, 2800, 850, 2200, 1750, 1750}); |
| | | break; |
| | | case 3: |
| | | tableStyle.setColWidths(new int[]{650, 2600, 850, 1800, 1400, 1400, 1400}); |
| | | break; |
| | | case 4: |
| | | tableStyle.setColWidths(new int[]{650, 2400, 850, 1600, 1125, 1125, 1125, 1125}); |
| | | break; |
| | | case 5: |
| | | tableStyle.setColWidths(new int[]{650, 2200, 850, 1500, 960, 960, 960, 960, 960}); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } else if (max <= 5) { |
| | | for (int i = 1; i <= max; i++) { |
| | | // 根据检验结果个数修改长度 |
| | | switch (i) { |
| | | case 1: |
| | | tableStyle.setColWidths(new int[]{650, 2900, 850, 2300, 2100, 1200}); |
| | | break; |
| | | case 2: |
| | | tableStyle.setColWidths(new int[]{650, 2700, 850, 2200, 1200, 1200, 1200}); |
| | | break; |
| | | case 3: |
| | | tableStyle.setColWidths(new int[]{650, 2700, 850, 1600, 1000, 1000, 1000, 1200}); |
| | | break; |
| | | case 4: |
| | | tableStyle.setColWidths(new int[]{650, 2400, 850, 1500, 850, 850, 850, 850, 1200}); |
| | | break; |
| | | case 5: |
| | | tableStyle.setColWidths(new int[]{650, 2200, 850, 1350, 770, 770, 770, 770, 770, 1100}); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | tableStyle.setWidth("10000"); |
| | | tableStyle.setAlign(TableRowAlign.CENTER); |
| | | BorderStyle borderStyle = new BorderStyle(); |
| | | borderStyle.setColor("000000"); |
| | | borderStyle.setType(XWPFTable.XWPFBorderType.SINGLE); |
| | | borderStyle.setSize(4); |
| | | tableStyle.setLeftBorder(borderStyle); |
| | | tableStyle.setRightBorder(borderStyle); |
| | | tableStyle.setInsideHBorder(borderStyle); // 设置水平内边框 |
| | | tableStyle.setInsideVBorder(borderStyle); |
| | | return tableStyle; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 处理有电缆颜色标识的检测项 |
| | | * |
| | | * @param cableTags 电缆颜色标识 |
| | | * @param collect 检测项列表 |
| | | * @param startIndex 起始下标 |
| | | * @param endIndex 结束下标 |
| | | * @return |
| | | */ |
| | | private List<SampleProductExportDto> transformSampleProduct(List<String> cableTags, Map<String, List<SampleProductExportDto>> collect, int startIndex, int endIndex) { |
| | | List<SampleProductExportDto> sampleProductExportDtos = new ArrayList<>(); |
| | | for (String s : collect.keySet()) { |
| | | List<String> lastValueList = new ArrayList<>(); |
| | | SampleProductExportDto dto = new SampleProductExportDto(); |
| | | BeanUtil.copyProperties(collect.get(s).get(0), dto); |
| | | Set<String> tellSet = new HashSet<>(); |
| | | for (int i = startIndex; i < endIndex; i++) { |
| | | String cableTag = cableTags.get(i); |
| | | for (SampleProductExportDto sDto : collect.get(s)) { |
| | | tellSet.add(sDto.getTell()); |
| | | if (sDto.getCableTag().equals(cableTag)) { |
| | | lastValueList.add(sDto.getLastValue()); |
| | | } |
| | | } |
| | | } |
| | | //切割电缆配置项 |
| | | dto.setTell(String.join("\n", tellSet)); |
| | | dto.setLastValueList(lastValueList); |
| | | sampleProductExportDtos.add(dto); |
| | | } |
| | | return sampleProductExportDtos; |
| | | } |
| | | |
| | | /** |
| | | * 检测项排序 |
| | | * |
| | | * @param sourceMap |
| | | * @param targetMap |
| | | */ |
| | | private void sortSampleProduct(Map<String, List<SampleProductExportDto>> sourceMap, Map<String, List<SampleProductExportDto>> targetMap) { |
| | | List<Map.Entry<String, List<SampleProductExportDto>>> entries = new ArrayList<>(sourceMap.entrySet()); |
| | | entries.sort(Comparator.comparingInt(o -> (o.getValue().get(0).getSort() == null ? 0 : o.getValue().get(0).getSort()))); |
| | | for (Map.Entry<String, List<SampleProductExportDto>> entry : entries) { |
| | | targetMap.put(entry.getKey(), entry.getValue()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 小报告生成 |
| | | * |
| | | * @param orderId |
| | | * @param insOrder |
| | | * @param insSamples |
| | | */ |
| | | private void addSmallReport(Integer orderId, InsOrder insOrder, List<InsSample> insSamples) { |
| | | private void addSmallReport(Integer orderId, InsOrder insOrder, List<InsSample> insSamples, Integer reportType, Integer writeUserId) { |
| | | InsReport insReport = new InsReport(); |
| | | AtomicReference<String> resultCh = new AtomicReference<>(""); |
| | | boolean showResult = Objects.equals(reportType, INSPECTION_REPORT); |
| | | insReport.setCode(insOrder.getEntrustCode()); |
| | | insReport.setInsOrderId(orderId); |
| | | insReport.setReportType(reportType); |
| | | InsSample insSample = insSamples.get(0); |
| | | // 填充基础数据 |
| | | EnterFactoryReport enterFactoryReport = new EnterFactoryReport(); |
| | |
| | | enterFactoryReport.setSample(insOrder.getSample()); |
| | | // 获取ifs数据 |
| | | IfsInventoryQuantity ifsInventoryQuantity = ifsInventoryQuantityMapper.selectById(insOrder.getIfsInventoryId()); |
| | | //查询零件属性 |
| | | IfsPartPropsRecord ifsPartPropsRecord = ifsPartPropsRecordMapper.selectOne(Wrappers.<IfsPartPropsRecord>lambdaQuery() |
| | | .eq(IfsPartPropsRecord::getIfsInventoryId, ifsInventoryQuantity.getId())); |
| | | if (Objects.nonNull(ifsPartPropsRecord)) { |
| | | enterFactoryReport.setOuterColor(ifsPartPropsRecord.getOuterColor()); |
| | | } |
| | | enterFactoryReport.setQtyArrived(ifsInventoryQuantity.getQtyArrived() == null ? "" : |
| | | ifsInventoryQuantity.getQtyArrived().stripTrailingZeros().toPlainString() + ifsInventoryQuantity.getBuyUnitMeas()); |
| | | enterFactoryReport.setQuantity(insOrder.getTestQuantity()); |
| | | enterFactoryReport.setPartDesc(insOrder.getPartDetail()); |
| | | enterFactoryReport.setSupplierName("**********"); |
| | | enterFactoryReport.setSupplierName(ifsInventoryQuantity.getSupplierName()); |
| | | enterFactoryReport.setLotBatchNo(ifsInventoryQuantity.getUpdateBatchNo()); |
| | | |
| | | // 检测依据 |
| | |
| | | List<RowRenderData> rows = new ArrayList<>(); |
| | | List<TextRenderData> text = new ArrayList<>(); |
| | | RowRenderData rowRenderData = null; |
| | | List<Map<String, Object>> cableTagEnclosureTables = new ArrayList<>(); |
| | | |
| | | // 查询检验内容 |
| | | List<SampleProductExportDto> sampleProductDto2s = insOrderMapper.selectSampleBySampleId(insSamples.stream() |
| | |
| | | |
| | | List<SampleProductExportDto> sampleList = new ArrayList<>(); |
| | | Integer max = insSamples.stream().mapToInt(InsSample::getQuantity).sum(); |
| | | TableRenderData tableRenderData = new TableRenderData(); |
| | | String templateName; |
| | | if (StringUtils.equals(OrderType.WG.getValue(), ifsInventoryQuantity.getOrderType())) { |
| | | //过滤不判定的检测项 |
| | | List<SampleProductExportDto> filterItems = sampleProductDto2s.stream() |
| | | .filter(f -> !showResult || f.getInsResult() != 3) |
| | | .collect(Collectors.toList()); |
| | | int maxCableTag = 5;//单个表格,电缆颜色标识最大个数 |
| | | templateName = showResult ? "/static/small-wg-report-template.docx" : "/static/small-wg-detection-template.docx"; |
| | | //查询检验单消息 |
| | | InsSampleUserVO insSampleUser = insSampleUserMapper.selectUserNameByOrderId(orderId); |
| | | if (Objects.nonNull(insSampleUser)) { |
| | | enterFactoryReport.setPartDesc(insSampleUser.getModel()); |
| | | enterFactoryReport.setInspector(insSampleUser.getInspector()); |
| | | enterFactoryReport.setInspectDate(insSampleUser.getInspectDate()); |
| | | } |
| | | |
| | | // 转成Mpa进行排序 |
| | | Map<String, List<SampleProductExportDto>> sortedMap = sampleProductDto2s.stream() |
| | | .filter(sampleProductDto2 -> StringUtils.isNotBlank(sampleProductDto2.getInspectionItem())) |
| | | .collect(Collectors.groupingBy(SampleProductExportDto::getInspectionItem)); |
| | | List<Map.Entry<String, List<SampleProductExportDto>>> entries = new ArrayList<>(sortedMap.entrySet()); |
| | | entries.sort((o1, o2) -> (o1.getValue().get(0).getSort() == null ? 0 : o1.getValue().get(0).getSort()) |
| | | - (o2.getValue().get(0).getSort() == null ? 0 : o2.getValue().get(0).getSort())); |
| | | // 创建一个 LinkedHashMap 来保持插入顺序 |
| | | Map<String, List<SampleProductExportDto>> item = new LinkedHashMap<>(); |
| | | for (Map.Entry<String, List<SampleProductExportDto>> entry : entries) { |
| | | item.put(entry.getKey(), entry.getValue()); |
| | | Map<String, List<SampleProductExportDto>> totalItem = new LinkedHashMap<>();//检测项列表 |
| | | Map<String, List<SampleProductExportDto>> cableTagItem = new LinkedHashMap<>();//电缆配置检测项 |
| | | Map<String, List<SampleProductExportDto>> cableTagEnclosureItem = new LinkedHashMap<>();//电缆配置检测项附件 |
| | | |
| | | AtomicInteger finalIndex = new AtomicInteger(1); |
| | | List<String> cableTags = insOrderMapper.selectSampleCableTag(insSample.getId()); |
| | | max = Math.max(cableTags.size(), 1); |
| | | //处理电缆配置检测项 |
| | | Map<String, List<SampleProductExportDto>> tempMap = new HashMap<>(); |
| | | Map<String, List<SampleProductExportDto>> tempMap2 = new HashMap<>(); |
| | | Map<String, List<SampleProductExportDto>> listMap2 = filterItems.stream() |
| | | .filter(f -> StringUtils.isNotBlank(f.getCableTag()) && StringUtils.isNotBlank(f.getInspectionItem())) |
| | | .collect(Collectors.groupingBy(SampleProductExportDto::getInspectionItem)); |
| | | for (String key : listMap2.keySet()) { |
| | | List<SampleProductExportDto> sampleProductExportDtos; |
| | | List<SampleProductExportDto> sampleProductExportDtos2; |
| | | //处理电缆配置项 |
| | | Map<String, List<SampleProductExportDto>> collect = listMap2.get(key).stream().collect(Collectors.groupingBy(SampleProductExportDto::getInspectionItemSubclass)); |
| | | if (cableTags.size() > maxCableTag) { |
| | | sampleProductExportDtos = transformSampleProduct(cableTags, collect, 0, maxCableTag); |
| | | sampleProductExportDtos2 = transformSampleProduct(cableTags, collect, maxCableTag, cableTags.size()); |
| | | tempMap2.put(key, sampleProductExportDtos2); |
| | | } else { |
| | | sampleProductExportDtos = transformSampleProduct(cableTags, collect, 0, cableTags.size()); |
| | | } |
| | | cableTagItem.put(key, sampleProductExportDtos); |
| | | } |
| | | //处理非电缆配置检测项 |
| | | Map<String, List<SampleProductExportDto>> listMap = filterItems.stream() |
| | | .filter(f -> StringUtils.isBlank(f.getCableTag()) && StringUtils.isNotBlank(f.getInspectionItem())) |
| | | .collect(Collectors.groupingBy(s -> s.getInspectionItem() + "&")); |
| | | //合并检测项列表 |
| | | tempMap.putAll(cableTagItem); |
| | | tempMap.putAll(listMap); |
| | | sortSampleProduct(tempMap, totalItem); |
| | | int tagNum = Math.min(max, maxCableTag); |
| | | List<String> tagList = cableTags.isEmpty() ? new ArrayList<>() : cableTags.subList(0, tagNum); |
| | | handlerSampleItems(OrderType.WG.getValue(), totalItem, finalIndex, sampleList, tagNum, text, rows, rowRenderData, resultCh, tagList, true, showResult); |
| | | |
| | | if (CollectionUtil.isNotEmpty(tempMap2)) { |
| | | sortSampleProduct(tempMap2, cableTagEnclosureItem); |
| | | //生成附件电缆表格 |
| | | TableRenderData tableRenderData2 = new TableRenderData(); |
| | | List<String> newCableTags = cableTags.subList(maxCableTag, cableTags.size()); |
| | | AtomicInteger finalIndex2 = new AtomicInteger(1); |
| | | List<TextRenderData> newText = new ArrayList<TextRenderData>(); |
| | | List<RowRenderData> newRows = new ArrayList<>(); |
| | | RowRenderData newRowRenderData = null; |
| | | handlerSampleItems(OrderType.WG.getValue(), cableTagEnclosureItem, finalIndex2, new ArrayList<>(), newCableTags.size(), newText, newRows, newRowRenderData, resultCh, newCableTags, true, showResult); |
| | | tableRenderData2.setRows(newRows); |
| | | tableRenderData2.setTableStyle(setTableStyle(newCableTags.size(), showResult)); |
| | | HashMap<String, Object> tableMap = new HashMap<>(); |
| | | tableMap.put("enclosureTable", tableRenderData2); |
| | | tableMap.put("resultCh", resultCh); |
| | | tableMap.put("writeUrl", null); |
| | | tableMap.put("examineUrl", null); |
| | | tableMap.put("ratifyUrl", null); |
| | | tableMap.put("writeDateUrl", null); |
| | | tableMap.put("examineDateUrl", null); |
| | | tableMap.put("ratifyDateUrl", null); |
| | | tableMap.put("seal1", null); |
| | | cableTagEnclosureTables.add(tableMap); |
| | | } |
| | | |
| | | tableRenderData.setRows(rows); |
| | | tableRenderData.setTableStyle(setTableStyle(tagNum, showResult)); |
| | | if (showResult && !resultCh.get().isEmpty()) { |
| | | resultCh.set("经检验," + resultCh.get() + "所检项目不合格,其余所检项目均合格。(盖章有效)"); |
| | | } else if (showResult) { |
| | | resultCh.set("本产品符合相关标准要求,经检验合格准予出厂(盖章有效)"); |
| | | } |
| | | |
| | | } else { |
| | | templateName = showResult ? "/static/small-report-template.docx" : "/static/small-detection-template.docx"; |
| | | // 转成Mpa进行排序 |
| | | Map<String, List<SampleProductExportDto>> sortedMap = sampleProductDto2s.stream() |
| | | .filter(sampleProductDto2 -> StringUtils.isNotBlank(sampleProductDto2.getInspectionItem())) |
| | | .collect(Collectors.groupingBy(SampleProductExportDto::getInspectionItem)); |
| | | // // 创建一个 LinkedHashMap 来保持插入顺序 |
| | | Map<String, List<SampleProductExportDto>> item = new LinkedHashMap<>(); |
| | | sortSampleProduct(sortedMap, item); |
| | | |
| | | |
| | | AtomicInteger finalIndex = new AtomicInteger(1); |
| | | handlerSampleItems(OrderType.RAW.getValue(), item, finalIndex, sampleList, max, text, rows, rowRenderData, resultCh, null, true, showResult); |
| | | tableRenderData.setRows(rows); |
| | | tableRenderData.setTableStyle(setTableStyle(max, showResult)); |
| | | |
| | | if (showResult && !resultCh.get().equals("")) { |
| | | resultCh.set("经检验," + resultCh.get() + "所检项目不合格,其余所检项目均合格。"); |
| | | } else if (showResult) { |
| | | resultCh.set("经检验此批" + enterFactoryReport.getSample() + "各项目均符合检验规范要求。"); |
| | | } |
| | | } |
| | | |
| | | AtomicInteger finalIndex = new AtomicInteger(1); |
| | | ConfigureBuilder builder = Configure.builder(); |
| | | builder.useSpringEL(true); |
| | | |
| | | InputStream inputStream = this.getClass().getResourceAsStream(templateName); |
| | | XWPFTemplate template = XWPFTemplate.compile(inputStream, builder.build()).render( |
| | | new HashMap<String, Object>() {{ |
| | | put("report", enterFactoryReport); |
| | | put("standardMethod", standardMethod2.toString().equals("null") ? "" : standardMethod2); |
| | | put("orderType", orderType); |
| | | put("table", tableRenderData); |
| | | put("enclosureTables", cableTagEnclosureTables.isEmpty() ? null : cableTagEnclosureTables); |
| | | put("resultCh", resultCh); |
| | | put("writeUrl", null); |
| | | put("examineUrl", null); |
| | | put("ratifyUrl", null); |
| | | put("writeDateUrl", null); |
| | | put("examineDateUrl", null); |
| | | put("ratifyDateUrl", null); |
| | | put("seal1", null); |
| | | }}); |
| | | try { |
| | | // 修改换行和合并问题 |
| | | updaeMerge(template.getXWPFDocument(), true); |
| | | String name = insReport.getCode().replace("/", "") + (showResult ? "-J.docx" : "-C.docx"); |
| | | Files.createDirectories(Paths.get(wordUrl)); |
| | | template.writeAndClose(Files.newOutputStream(Paths.get(wordUrl, name))); |
| | | insReport.setUrl("/word/" + name); |
| | | insReport.setIsPass(0); |
| | | insReport.setWriteUserId(writeUserId);//编制人(检验人) |
| | | insReport.setWriteTime(LocalDateTime.now());//提交时间 |
| | | saveGeneratedReport(insReport); |
| | | inputStream.close(); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 处理常规检测项 |
| | | * |
| | | * @param item |
| | | * @param finalIndex |
| | | * @param sampleList |
| | | * @param max |
| | | * @param text |
| | | * @param rows |
| | | * @param rowRenderData |
| | | * @param resultCh |
| | | */ |
| | | private static void handlerSampleItems(String orderType, Map<String, List<SampleProductExportDto>> item, AtomicInteger finalIndex, List<SampleProductExportDto> sampleList, Integer max, List<TextRenderData> text, List<RowRenderData> rows, RowRenderData rowRenderData, AtomicReference<String> resultCh, List<String> cableTagList, Boolean hasAddHead, boolean showResult) { |
| | | item.forEach((s, sampleProductDtoInside) -> { |
| | | // 添加检验项 |
| | | SampleProductExportDto dto2 = new SampleProductExportDto(); |
| | |
| | | // 处理集合 |
| | | Map<String, SampleProductExportDto> map = new LinkedHashMap<>(); |
| | | for (SampleProductExportDto productDto2 : sampleProductDtoInside) { |
| | | String productName = productDto2.getInspectionItemClass() + productDto2.getInspectionItem(); |
| | | String productName = productDto2.getInspectionItemClass() + productDto2.getInspectionItem() + productDto2.getCableTag(); |
| | | if (map.containsKey(productName)) { |
| | | // 如果名称已经存在,添加 lastValue 值到 lastValueList 列表 |
| | | map.get(productName) |
| | | .getLastValueList() |
| | | .add(productDto2.getLastValue()); |
| | | if (CollectionUtil.isEmpty(map.get(productName).getLastValueList()) || StringUtils.equals(OrderType.RAW.getValue(), orderType)) { |
| | | map.get(productName) |
| | | .getLastValueList() |
| | | .add(productDto2.getLastValue()); |
| | | } |
| | | map.get(productName) |
| | | .getInsResultList() |
| | | .add(productDto2.getInsResult()); |
| | | } else { |
| | | // 如果名称不存在,直接放入 map |
| | | productDto2.setLastValueList(new ArrayList<>()); // 检验内容 |
| | | productDto2.getLastValueList().add(productDto2.getLastValue()); |
| | | if (CollectionUtil.isEmpty(productDto2.getLastValueList()) || StringUtils.equals(OrderType.RAW.getValue(), orderType)) { |
| | | productDto2.setLastValueList(new ArrayList<>()); // 检验内容 |
| | | productDto2.getLastValueList().add(productDto2.getLastValue()); |
| | | } |
| | | productDto2.setInsResultList(new ArrayList<>()); // 结果 |
| | | productDto2.getInsResultList().add(productDto2.getInsResult()); |
| | | |
| | |
| | | // 处理集合 |
| | | Map<String, SampleProductExportDto> map = new LinkedHashMap<>(); |
| | | for (SampleProductExportDto productDto2 : sampleProductDtoInside) { |
| | | String productName = productDto2.getInspectionItemClass() + productDto2.getInspectionItem() + productDto2.getInspectionItemSubclass(); |
| | | String productName = productDto2.getInspectionItemClass() + productDto2.getInspectionItem() + productDto2.getInspectionItemSubclass() + productDto2.getCableTag(); |
| | | if (map.containsKey(productName)) { |
| | | // 如果名称已经存在,添加 lastValue 值到 lastValueList 列表 |
| | | map.get(productName) |
| | | .getLastValueList() |
| | | .add(productDto2.getLastValue()); |
| | | if (CollectionUtil.isEmpty(map.get(productName).getLastValueList()) || StringUtils.equals(OrderType.RAW.getValue(), orderType)) { |
| | | map.get(productName) |
| | | .getLastValueList() |
| | | .add(productDto2.getLastValue()); |
| | | } |
| | | map.get(productName) |
| | | .getInsResultList() |
| | | .add(productDto2.getInsResult()); |
| | | } else { |
| | | // 如果名称不存在,直接放入 map |
| | | productDto2.setLastValueList(new ArrayList<>()); // 检验内容 |
| | | productDto2.getLastValueList().add(productDto2.getLastValue()); |
| | | if (CollectionUtil.isEmpty(productDto2.getLastValueList()) || StringUtils.equals(OrderType.RAW.getValue(), orderType)) { |
| | | productDto2.setLastValueList(new ArrayList<>()); // 检验内容 |
| | | productDto2.getLastValueList().add(productDto2.getLastValue()); |
| | | } |
| | | productDto2.setInsResultList(new ArrayList<>()); // 结果 |
| | | productDto2.getInsResultList().add(productDto2.getInsResult()); |
| | | |
| | |
| | | }); |
| | | |
| | | // 添加小报告表头 |
| | | text = addSmallHead(text, max, rows); |
| | | |
| | | if (hasAddHead) { |
| | | text = addSmallHead(text, max, rows, cableTagList, showResult); |
| | | } |
| | | |
| | | // 中间检测值添加 |
| | | for (int i = 0; i < sampleList.size(); i++) { |
| | |
| | | |
| | | // 检验项目 |
| | | TextRenderData middleRenderData2 = new TextRenderData(); |
| | | middleRenderData2.setText(sample.getInspectionName()); |
| | | String[] split = sample.getInspectionName().split("&"); |
| | | String itemName = split.length > 0 ? split[0] : sample.getInspectionName(); |
| | | middleRenderData2.setText(itemName + "∑" + itemName + i + "_" + finalIndex); |
| | | Style middleStyle2 = new Style(); |
| | | middleStyle2.setFontFamily("宋体"); |
| | | middleStyle2.setColor("000000"); |
| | |
| | | if (CollectionUtils.isNotEmpty(sample.getLastValueList()) |
| | | && sample.getLastValueList().size() == max) { |
| | | // 判断是否是外观, 外观全部合格的话需要合并 |
| | | if (sample.getInspectionItem().contains("外观")) { |
| | | if (showResult && sample.getInspectionItem().contains("外观")) { |
| | | // 判定结果 |
| | | boolean falg = false; |
| | | if (CollectionUtils.isNotEmpty(sample.getLastValueList())) { |
| | | // 判断是否有一个错误 |
| | | if (sample.getInsResultList().stream().anyMatch(s -> s.equals(2))) { |
| | | if (sample.getInsResultList().stream().anyMatch(s -> Objects.equals(s, 2))) { |
| | | falg = true; |
| | | } else { |
| | | boolean error = sample.getInsResultList().stream().anyMatch(s -> s.equals(0)); |
| | | boolean error = sample.getInsResultList().stream().anyMatch(s -> Objects.equals(s, 0)); |
| | | if (!error) { |
| | | falg = true; |
| | | } |
| | | } |
| | | } else { |
| | | if (!sample.getInsResult().equals(2)) { |
| | | if (!Objects.equals(sample.getInsResult(), 2)) { |
| | | falg = true; |
| | | } |
| | | } |
| | |
| | | TextRenderData middleRenderData6 = new TextRenderData(); |
| | | middleRenderData6.setText((StringUtils.isNotEmpty(sample.getLastValue()) ? |
| | | sample.getLastValue() : "") |
| | | + "∑" + (7 + i)); |
| | | + "∑" + (finalIndex.get() + "_" + i)); |
| | | Style middleStyle6 = new Style(); |
| | | middleStyle6.setFontFamily("宋体"); |
| | | middleStyle6.setColor("000000"); |
| | |
| | | |
| | | // 判定结果 |
| | | String result = ""; |
| | | if (sample.getInsResult() != null) { |
| | | if (showResult && sample.getInsResult() != null) { |
| | | switch (sample.getInsResult()) { |
| | | case 1: |
| | | result = "√"; |
| | |
| | | break; |
| | | } |
| | | } |
| | | if (CollectionUtils.isNotEmpty(sample.getLastValueList())) { |
| | | if (showResult && CollectionUtils.isNotEmpty(sample.getLastValueList())) { |
| | | // 判断是否有一个错误 |
| | | if (sample.getInsResultList().stream().anyMatch(s -> s.equals(3))) { |
| | | if (sample.getInsResultList().stream().anyMatch(s -> Objects.equals(s, 3))) { |
| | | result = "-"; |
| | | } else { |
| | | boolean error = sample.getInsResultList().stream().anyMatch(s -> s.equals(0)); |
| | | boolean error = sample.getInsResultList().stream().anyMatch(s -> Objects.equals(s, 0)); |
| | | if (error) { |
| | | List<String> collect = new ArrayList<>(); |
| | | int index = 1; |
| | | for (Integer count : sample.getInsResultList()) { |
| | | String type; |
| | | if (count.equals(0)) { |
| | | if (Objects.equals(count, 0)) { |
| | | // 添加不合格描述 |
| | | String item1 = (max == 1 ? "" : "第" + Integer.toString(index) + "次") |
| | | String item1 = (max == 1 ? "" : "第" + index + "次") |
| | | + sample.getInspectionItem() |
| | | + (StringUtils.isBlank(sample.getInspectionItemSubclass()) ? "" : "" + sample.getInspectionItemSubclass()); |
| | | if (resultCh.get().equals("")) { |
| | |
| | | } |
| | | } |
| | | |
| | | TextRenderData middleRenderData7 = new TextRenderData(); |
| | | middleRenderData7.setText(result); |
| | | Style middleStyle7 = new Style(); |
| | | middleStyle7.setFontFamily("宋体"); |
| | | middleStyle7.setColor("000000"); |
| | | middleRenderData7.setStyle(middleStyle7); |
| | | text.add(middleRenderData7); |
| | | if (showResult) { |
| | | TextRenderData middleRenderData7 = new TextRenderData(); |
| | | middleRenderData7.setText(result); |
| | | Style middleStyle7 = new Style(); |
| | | middleStyle7.setFontFamily("宋体"); |
| | | middleStyle7.setColor("000000"); |
| | | middleRenderData7.setStyle(middleStyle7); |
| | | text.add(middleRenderData7); |
| | | } |
| | | |
| | | TextRenderData[] text2 = text.toArray(new TextRenderData[0]); |
| | | rowRenderData = Rows.of(text2).center().rowAtleastHeight(1).create(); |
| | |
| | | text = new ArrayList<>(); |
| | | } |
| | | |
| | | TableRenderData tableRenderData = new TableRenderData(); |
| | | tableRenderData.setRows(rows); |
| | | |
| | | //设置样式 |
| | | TableStyle tableStyle = new TableStyle(); |
| | | for (int i = 1; i <= max; i++) { |
| | | // 根据减压那结果个数修改长度 |
| | | switch (i) { |
| | | case 1: |
| | | tableStyle.setColWidths(new int[]{650, 2900, 850, 2300, 2100, 1200}); |
| | | break; |
| | | case 2: |
| | | tableStyle.setColWidths(new int[]{650, 2700, 850, 2200, 1200, 1200, 1200}); |
| | | break; |
| | | case 3: |
| | | tableStyle.setColWidths(new int[]{650, 2700, 850, 1600, 1000, 1000, 1000, 1200}); |
| | | break; |
| | | case 4: |
| | | tableStyle.setColWidths(new int[]{650, 2400, 850, 1500, 850, 850, 850, 850, 1200}); |
| | | break; |
| | | case 5: |
| | | tableStyle.setColWidths(new int[]{650, 2200, 850, 1350, 750, 750, 750, 750, 750, 1200}); |
| | | break; |
| | | } |
| | | } |
| | | tableStyle.setWidth("10000"); |
| | | tableStyle.setAlign(TableRowAlign.CENTER); |
| | | BorderStyle borderStyle = new BorderStyle(); |
| | | borderStyle.setColor("000000"); |
| | | borderStyle.setType(XWPFTable.XWPFBorderType.SINGLE); |
| | | borderStyle.setSize(4); |
| | | tableStyle.setLeftBorder(borderStyle); |
| | | tableStyle.setRightBorder(borderStyle); |
| | | tableStyle.setInsideHBorder(borderStyle); // 设置水平内边框 |
| | | tableStyle.setInsideVBorder(borderStyle); |
| | | tableRenderData.setTableStyle(tableStyle); |
| | | |
| | | if (!resultCh.get().equals("")) { |
| | | resultCh.set("经检验," + resultCh.get() + "所检项目不合格,其余所检项目均合格。"); |
| | | } else { |
| | | resultCh.set("经检验此批" + enterFactoryReport.getSample() + "各项目均符合检验规范要求。"); |
| | | } |
| | | |
| | | ConfigureBuilder builder = Configure.builder(); |
| | | builder.useSpringEL(true); |
| | | // 获取当前时间 |
| | | LocalDate currentDate = LocalDate.now(); |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | String formattedDate = currentDate.format(formatter); |
| | | |
| | | InputStream inputStream = this.getClass().getResourceAsStream("/static/small-report-template.docx"); |
| | | XWPFTemplate template = XWPFTemplate.compile(inputStream, builder.build()).render( |
| | | new HashMap<String, Object>() {{ |
| | | put("report", enterFactoryReport); |
| | | put("standardMethod", standardMethod2.toString().equals("null") ? "" : standardMethod2); |
| | | put("orderType", orderType); |
| | | put("table", tableRenderData); |
| | | put("resultCh", resultCh); |
| | | put("writeUrl", null); |
| | | put("examineUrl", null); |
| | | put("ratifyUrl", null); |
| | | put("writeDateUrl", null); |
| | | put("examineDateUrl", null); |
| | | put("ratifyDateUrl", null); |
| | | put("seal1", null); |
| | | }}); |
| | | try { |
| | | // 修改换行和合并问题 |
| | | updaeMerge(template.getXWPFDocument(), true); |
| | | String name = insReport.getCode().replace("/", "") + "-J.docx"; |
| | | template.writeAndClose(Files.newOutputStream(Paths.get(wordUrl + "/" + name))); |
| | | insReport.setUrl("/word/" + name); |
| | | insReport.setIsPass(0); |
| | | insReport.setWriteUserId(SecurityUtils.getUserId().intValue());//提交人 |
| | | insReport.setWriteTime(LocalDateTime.now());//提交时间 |
| | | // 查询报告, 判断之前是否添加过, 添加过删除 |
| | | insReportMapper.delete(Wrappers.<InsReport>lambdaQuery() |
| | | .eq(InsReport::getInsOrderId, insOrder.getId())); |
| | | insReportMapper.insert(insReport); |
| | | |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 添加小宝表头 |
| | | * 添加小报告表头 |
| | | * |
| | | * @param text |
| | | * @param max |
| | | * @param rows |
| | | * @return |
| | | */ |
| | | private static List<TextRenderData> addSmallHead(List<TextRenderData> text, Integer max, List<RowRenderData> rows) { |
| | | private static List<TextRenderData> addSmallHead(List<TextRenderData> text, Integer max, List<RowRenderData> rows, List<String> cableTagList, boolean showResult) { |
| | | RowRenderData rowRenderData; |
| | | // // 头 |
| | | TextRenderData headRenderData1 = new TextRenderData(); |
| | |
| | | |
| | | for (int i = 0; i < max; i++) { |
| | | TextRenderData headRenderData6 = new TextRenderData(); |
| | | headRenderData6.setText("检验结果∑6"); |
| | | headRenderData6.setText(showResult ? "检验结果∑6" : "检测数据∑6"); |
| | | Style headStyle6 = new Style(); |
| | | headStyle6.setFontFamily("宋体"); |
| | | headStyle6.setColor("000000"); |
| | | headRenderData6.setStyle(headStyle6); |
| | | text.add(headRenderData6); |
| | | } |
| | | TextRenderData headRenderData7 = new TextRenderData(); |
| | | headRenderData7.setText("单项判断"); |
| | | Style headStyle7 = new Style(); |
| | | headStyle7.setFontFamily("宋体"); |
| | | headStyle7.setColor("000000"); |
| | | headRenderData7.setStyle(headStyle7); |
| | | text.add(headRenderData7); |
| | | if (showResult) { |
| | | TextRenderData headRenderData7 = new TextRenderData(); |
| | | headRenderData7.setText("单项判断"); |
| | | Style headStyle7 = new Style(); |
| | | headStyle7.setFontFamily("宋体"); |
| | | headStyle7.setColor("000000"); |
| | | headRenderData7.setStyle(headStyle7); |
| | | text.add(headRenderData7); |
| | | } |
| | | |
| | | TextRenderData[] text3 = text.toArray(new TextRenderData[0]); |
| | | rowRenderData = Rows.of(text3).center().rowAtleastHeight(1).create(); |
| | |
| | | text = new ArrayList<>(); |
| | | |
| | | // 第二行(可能没有) |
| | | if (max > 1) { |
| | | if (max > 1 && CollectionUtil.isEmpty(cableTagList)) { |
| | | TextRenderData tagRenderData1 = new TextRenderData(); |
| | | tagRenderData1.setText(""); |
| | | Style tagStyle1 = new Style(); |
| | |
| | | tagRenderData6.setStyle(tagStyle6); |
| | | text.add(tagRenderData6); |
| | | } |
| | | TextRenderData tagRenderData7 = new TextRenderData(); |
| | | tagRenderData7.setText(""); |
| | | Style tagStyle7 = new Style(); |
| | | tagStyle7.setFontFamily("宋体"); |
| | | tagStyle7.setColor("000000"); |
| | | tagRenderData7.setStyle(tagStyle7); |
| | | text.add(tagRenderData7); |
| | | if (showResult) { |
| | | TextRenderData tagRenderData7 = new TextRenderData(); |
| | | tagRenderData7.setText(""); |
| | | Style tagStyle7 = new Style(); |
| | | tagStyle7.setFontFamily("宋体"); |
| | | tagStyle7.setColor("000000"); |
| | | tagRenderData7.setStyle(tagStyle7); |
| | | text.add(tagRenderData7); |
| | | } |
| | | |
| | | TextRenderData[] text4 = text.toArray(new TextRenderData[0]); |
| | | rowRenderData = Rows.of(text4).center().rowAtleastHeight(1).create(); |
| | |
| | | |
| | | |
| | | } |
| | | //如果有电缆颜色,生成颜色标识行 |
| | | if (CollectionUtil.isNotEmpty(cableTagList)) { |
| | | TextRenderData tagRenderData1 = new TextRenderData(); |
| | | tagRenderData1.setText(""); |
| | | Style tagStyle1 = new Style(); |
| | | tagStyle1.setFontFamily("宋体"); |
| | | tagStyle1.setColor("000000"); |
| | | tagRenderData1.setStyle(tagStyle1); |
| | | text.add(tagRenderData1); |
| | | |
| | | TextRenderData tagRenderData2 = new TextRenderData(); |
| | | tagRenderData2.setText("绝缘线芯颜色和标志"); |
| | | Style tagStyle2 = new Style(); |
| | | tagStyle2.setFontFamily("宋体"); |
| | | tagStyle2.setColor("000000"); |
| | | tagRenderData2.setStyle(tagStyle2); |
| | | text.add(tagRenderData2); |
| | | |
| | | TextRenderData tagRenderData4 = new TextRenderData(); |
| | | tagRenderData4.setText("/"); |
| | | Style tagStyle4 = new Style(); |
| | | tagStyle4.setFontFamily("宋体"); |
| | | tagStyle4.setColor("000000"); |
| | | tagRenderData4.setStyle(tagStyle4); |
| | | text.add(tagRenderData4); |
| | | |
| | | TextRenderData tagRenderData5 = new TextRenderData(); |
| | | tagRenderData5.setText("/"); |
| | | Style tagStyle5 = new Style(); |
| | | tagStyle5.setFontFamily("宋体"); |
| | | tagStyle5.setColor("000000"); |
| | | tagRenderData5.setStyle(tagStyle5); |
| | | text.add(tagRenderData5); |
| | | |
| | | for (String cableTag : cableTagList) { |
| | | TextRenderData tagRenderData6 = new TextRenderData(); |
| | | tagRenderData6.setText(cableTag); |
| | | Style tagStyle6 = new Style(); |
| | | tagStyle6.setFontFamily("宋体"); |
| | | tagStyle6.setColor("000000"); |
| | | tagRenderData6.setStyle(tagStyle6); |
| | | text.add(tagRenderData6); |
| | | } |
| | | if (showResult) { |
| | | TextRenderData tagRenderData7 = new TextRenderData(); |
| | | tagRenderData7.setText("/"); |
| | | Style tagStyle7 = new Style(); |
| | | tagStyle7.setFontFamily("宋体"); |
| | | tagStyle7.setColor("000000"); |
| | | tagRenderData7.setStyle(tagStyle7); |
| | | text.add(tagRenderData7); |
| | | } |
| | | |
| | | TextRenderData[] text4 = text.toArray(new TextRenderData[0]); |
| | | rowRenderData = Rows.of(text4).center().rowAtleastHeight(1).create(); |
| | | rows.add(rowRenderData); |
| | | text = new ArrayList<>(); |
| | | } |
| | | return text; |
| | | } |
| | | |
| | |
| | | |
| | | /** |
| | | * 创建大报告 |
| | | * |
| | | * @param orderId |
| | | * @param insOrder |
| | | * @param |
| | | */ |
| | | private void addBitReport(Integer orderId, InsOrder insOrder) { |
| | | Map<String, String> user = insProductMapper.selectUserById(insOrder.getUserId()); |
| | | private void addBitReport(Integer orderId, InsOrder insOrder, Integer reportType, Integer writeUserId) { |
| | | //samples是不包括带有"/"的样品 |
| | | List<SampleProductDto> samples = insSampleMapper.selectSampleProductListByOrderId(orderId); |
| | | boolean directTemplateOrder = isDirectTemplateOrder(orderId); |
| | | if (!directTemplateOrder && CollectionUtils.isEmpty(samples)) { |
| | | throw new ErrorException("当前订单未找到可生成报告的有效检验项目"); |
| | | } |
| | | InsReport insReport = new InsReport(); |
| | | insReport.setCode(insOrder.getEntrustCode()); |
| | | insReport.setInsOrderId(orderId); |
| | | insReport.setReportType(reportType); |
| | | boolean showResult = Objects.equals(reportType, INSPECTION_REPORT); |
| | | List<Map<String, Object>> tables = new ArrayList<>(); |
| | | Set<String> standardMethod = new HashSet<>(); |
| | | Set<String> deviceSet = new HashSet<>(); |
| | |
| | | List<String> resultChList = new ArrayList<>(); |
| | | List<String> resultEnList = new ArrayList<>(); |
| | | // 判断是否是只有一个样品 |
| | | boolean isOneSample = samples.size() == 1 ? true : false; |
| | | boolean isOneSample = samples.size() == 1; |
| | | /*基础报告(根据绘制的原始记录模版形成)*/ |
| | | samples.forEach(a -> { |
| | | Map<Integer, String> map2 = new HashMap<>(); |
| | | models.add(a.getModel()); |
| | | String standardMethodCode = baseMapper.getStandardMethodCode(a.getStandardMethodListId()); |
| | | if (StrUtil.isNotBlank(a.getSpecialStandardMethod())) { |
| | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 新版检测报告直接使用固定四列结果行,不再构造旧版可变列 TableRenderData。 |
| | | // 检验报告仍沿用下方原有的大表格逻辑。 |
| | | if (!showResult) { |
| | | return; |
| | | } |
| | | // 收样日期 |
| | | List<RowRenderData> rows = new ArrayList<>(); |
| | |
| | | } |
| | | } |
| | | } |
| | | insOrder.setSampleView(insOrder.getSample()); |
| | | String sampleViewEn = insSampleMapper.getSampleEn(insOrder.getSample()); |
| | | if (StringUtils.isBlank(sampleViewEn)) { |
| | | sampleViewEn = insSampleMapper.getSampleEnByObject(insOrder.getSample()); |
| | | if (StringUtils.isBlank(insOrder.getSampleView())) { |
| | | insOrder.setSampleView(insOrder.getSample()); |
| | | } |
| | | insOrder.setSampleViewEn(sampleViewEn); |
| | | if (StringUtils.isBlank(insOrder.getSampleViewEn())) { |
| | | String sampleViewEn = insSampleMapper.getSampleEn(insOrder.getSample()); |
| | | if (StringUtils.isBlank(sampleViewEn)) { |
| | | sampleViewEn = insSampleMapper.getSampleEnByObject(insOrder.getSample()); |
| | | } |
| | | insOrder.setSampleViewEn(sampleViewEn); |
| | | } |
| | | } else { |
| | | // 获得批量检验的总数 |
| | | max = insOrderMapper.selectSampleMax(a.getId()); |
| | |
| | | } |
| | | |
| | | // 表头添加 |
| | | addHead(a, text, rowRenderData, rows, max, cableTags); |
| | | addHead(a, text, rowRenderData, rows, max, cableTags, showResult); |
| | | text = new ArrayList<>(); |
| | | |
| | | // 添加检测值 |
| | | productSize.set(addTestValue(a, text, rowRenderData, rows, max, resultChList, resultEnList, insSamples, cableTags, isOneSample)); |
| | | productSize.set(addTestValue(a, text, rowRenderData, rows, max, resultChList, resultEnList, insSamples, cableTags, isOneSample, showResult)); |
| | | text = new ArrayList<>(); |
| | | |
| | | // 结尾添加 |
| | | addEnding(text, rowRenderData, rows, max); |
| | | addEnding(text, rowRenderData, rows, max, showResult); |
| | | text = new ArrayList<>(); |
| | | |
| | | List<TableRenderData> tables1 = new ArrayList<>(); |
| | |
| | | newTableRenderData.setRows(new ArrayList<>(firstTwoRows)); |
| | | //设置样式 |
| | | TableStyle tableStyle = new TableStyle(); |
| | | for (int i = 1; i <= max; i++) { |
| | | // 根据减压那结果个数修改长度 |
| | | switch (i) { |
| | | case 1: |
| | | tableStyle.setColWidths(new int[]{650, 2000, 2000, 850, 2200, 2100, 1200}); |
| | | break; |
| | | case 2: |
| | | tableStyle.setColWidths(new int[]{650, 1400, 1400, 850, 2100, 1200, 1200, 1200}); |
| | | break; |
| | | case 3: |
| | | tableStyle.setColWidths(new int[]{650, 1400, 1400, 850, 1500, 1000, 1000, 1000, 1200}); |
| | | break; |
| | | case 4: |
| | | tableStyle.setColWidths(new int[]{650, 1200, 1200, 850, 1400, 850, 850, 850, 850, 1200}); |
| | | break; |
| | | case 5: |
| | | tableStyle.setColWidths(new int[]{650, 1100, 1100, 850, 1350, 750, 750, 750, 750, 750, 1200}); |
| | | break; |
| | | } |
| | | } |
| | | // for (int i = 1; i <= max; i++) { |
| | | // } |
| | | // 根据检验结果个数修改长度 |
| | | tableStyle.setColWidths(calcTableColWidths(max, showResult)); |
| | | // switch (max) { |
| | | // case 1: |
| | | // tableStyle.setColWidths(new int[]{650, 2000, 2000, 850, 2200, 2100, 1200}); |
| | | // break; |
| | | // case 2: |
| | | // tableStyle.setColWidths(new int[]{650, 1400, 1400, 850, 2100, 1200, 1200, 1200}); |
| | | // break; |
| | | // case 3: |
| | | // tableStyle.setColWidths(new int[]{650, 1400, 1400, 850, 1500, 1000, 1000, 1000, 1200}); |
| | | // break; |
| | | // case 4: |
| | | // tableStyle.setColWidths(new int[]{650, 1200, 1200, 850, 1400, 850, 850, 850, 850, 1200}); |
| | | // break; |
| | | // case 5: |
| | | // tableStyle.setColWidths(new int[]{650, 1100, 1100, 850, 1350, 750, 750, 750, 750, 750, 1200}); |
| | | // break; |
| | | // } |
| | | tableStyle.setWidth("10000"); |
| | | tableStyle.setAlign(TableRowAlign.CENTER); |
| | | BorderStyle borderStyle = new BorderStyle(); |
| | |
| | | } |
| | | tableRenderData.getRows().add(row); |
| | | } |
| | | if (!tableRenderData.getRows().isEmpty() && tableRenderData.getRows().size() != 3) { |
| | | TableStyle tableStyle = new TableStyle(); |
| | | if (tableRenderData.getRows().size() != 3) { |
| | | //设置样式 |
| | | TableStyle tableStyle = new TableStyle(); |
| | | for (int i = 1; i <= max; i++) { |
| | | // 根据减压那结果个数修改长度 |
| | | switch (i) { |
| | | case 1: |
| | | tableStyle.setColWidths(new int[]{650, 2000, 2000, 850, 2200, 2100, 1200}); |
| | | break; |
| | | case 2: |
| | | tableStyle.setColWidths(new int[]{650, 1400, 1400, 850, 2100, 1200, 1200, 1200}); |
| | | break; |
| | | case 3: |
| | | tableStyle.setColWidths(new int[]{650, 1400, 1400, 850, 1500, 1000, 1000, 1000, 1200}); |
| | | break; |
| | | case 4: |
| | | tableStyle.setColWidths(new int[]{650, 1200, 1200, 850, 1400, 850, 850, 850, 850, 1200}); |
| | | break; |
| | | case 5: |
| | | tableStyle.setColWidths(new int[]{650, 1100, 1100, 850, 1350, 750, 750, 750, 750, 750, 1200}); |
| | | break; |
| | | } |
| | | } |
| | | tableStyle.setWidth("10000"); |
| | | tableStyle.setAlign(TableRowAlign.CENTER); |
| | | BorderStyle borderStyle = new BorderStyle(); |
| | | borderStyle.setColor("000000"); |
| | | borderStyle.setType(XWPFTable.XWPFBorderType.THICK); |
| | | borderStyle.setSize(14); |
| | | tableStyle.setLeftBorder(borderStyle); |
| | | tableStyle.setTopBorder(borderStyle); |
| | | tableStyle.setRightBorder(borderStyle); |
| | | tableStyle.setBottomBorder(borderStyle); |
| | | tableRenderData.setTableStyle(tableStyle); |
| | | tables1.add(tableRenderData); |
| | | // for (int i = 1; i <= max; i++) { |
| | | // } |
| | | // 根据检验结果个数修改长度 |
| | | tableStyle.setColWidths(calcTableColWidths(max, showResult)); |
| | | // switch (max) { |
| | | // case 1: |
| | | // tableStyle.setColWidths(new int[]{650, 2000, 2000, 850, 2200, 2100, 1200}); |
| | | // break; |
| | | // case 2: |
| | | // tableStyle.setColWidths(new int[]{650, 1400, 1400, 850, 2100, 1200, 1200, 1200}); |
| | | // break; |
| | | // case 3: |
| | | // tableStyle.setColWidths(new int[]{650, 1400, 1400, 850, 1500, 1000, 1000, 1000, 1200}); |
| | | // break; |
| | | // case 4: |
| | | // tableStyle.setColWidths(new int[]{650, 1200, 1200, 850, 1400, 850, 850, 850, 850, 1200}); |
| | | // break; |
| | | // case 5: |
| | | // tableStyle.setColWidths(new int[]{650, 1100, 1100, 850, 1350, 750, 750, 750, 750, 750, 1200}); |
| | | // break; |
| | | // } |
| | | } |
| | | tableStyle.setWidth("10000"); |
| | | tableStyle.setAlign(TableRowAlign.CENTER); |
| | | BorderStyle borderStyle = new BorderStyle(); |
| | | borderStyle.setColor("000000"); |
| | | borderStyle.setType(XWPFTable.XWPFBorderType.THICK); |
| | | borderStyle.setSize(14); |
| | | tableStyle.setLeftBorder(borderStyle); |
| | | tableStyle.setTopBorder(borderStyle); |
| | | tableStyle.setRightBorder(borderStyle); |
| | | tableStyle.setBottomBorder(borderStyle); |
| | | tableRenderData.setTableStyle(tableStyle); |
| | | tables1.add(tableRenderData); |
| | | tables1.forEach(table -> { |
| | | Map<String, Object> tableMap = new HashMap<>(); |
| | | tableMap.put("table", table); |
| | |
| | | for (String s : standardMethod) { |
| | | standardMethod2.append("、").append(s); |
| | | } |
| | | standardMethod2.replace(0, 1, ""); |
| | | if (standardMethod2.length() > 0) { |
| | | standardMethod2.deleteCharAt(0); |
| | | } |
| | | tables.forEach(table -> { |
| | | table.put("tableSize", tables.size() + 1); |
| | | }); |
| | | // 设备信息 |
| | | List<Map<String, String>> deviceList = null; |
| | | if (CollectionUtils.isNotEmpty(deviceSet)) { |
| | | deviceList = insOrderMapper.selectDeviceList(deviceSet); |
| | | // 新订单按模板选择设备;旧订单没有模板设备关系时回退到订单级设备记录。 |
| | | Set<String> reportDeviceNumbers = insOrderTemplateDeviceMapper |
| | | .selectManagementNumbersByOrderId(orderId).stream() |
| | | .filter(StringUtils::isNotBlank) |
| | | .collect(Collectors.toCollection(LinkedHashSet::new)); |
| | | if (reportDeviceNumbers.isEmpty()) { |
| | | reportDeviceNumbers.addAll(insOrderDeviceRecordMapper.selectDeviceNumber(orderId).stream() |
| | | .map(InsOrderDeviceRecordDto::getManagementNumber) |
| | | .filter(StringUtils::isNotBlank) |
| | | .collect(Collectors.toList())); |
| | | } |
| | | reportDeviceNumbers.addAll(deviceSet); |
| | | List<Map<String, String>> deviceList = reportDeviceNumbers.isEmpty() |
| | | ? new ArrayList<>() : insOrderMapper.selectDeviceList(reportDeviceNumbers); |
| | | if (CollectionUtils.isNotEmpty(deviceList)) { |
| | | int count = 1; |
| | | for (Map<String, String> stringMap : deviceList) { |
| | |
| | | count++; |
| | | } |
| | | } |
| | | |
| | | Map<String, String> codeStr = new HashMap<>(); |
| | | codeStr.put("报告编号", insReport.getCode()); |
| | | codeStr.put("样品名称", insOrder.getSample()); |
| | | codeStr.put("规格型号", samples.get(0).getModel()); |
| | | codeStr.put("发放日期", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); |
| | | |
| | | String modelStr = CollUtil.join(models, "\n"); |
| | | |
| | |
| | | // 来样方式 |
| | | String formType = iSysDictTypeService.selectLabelByDict(DictDataConstants.FORM_TYPE, insOrder.getFormType()); |
| | | |
| | | // 样品状态 |
| | | String sampleStatus = iSysDictTypeService.selectLabelByDict(DictDataConstants.SAMPLE_STATUS_LIST, insOrder.getSampleStatus()); |
| | | ; |
| | | // 样品外观优先展示字典名称;历史数据或直接保存文本时,回退展示订单原值。 |
| | | String sampleStatus = defaultReportText( |
| | | iSysDictTypeService.selectLabelByDict( |
| | | DictDataConstants.SAMPLE_STATUS_LIST, insOrder.getSampleStatus()), |
| | | insOrder.getSampleStatus()); |
| | | |
| | | // 公司信息 |
| | | Custom custom = customMapper.selectById(insOrder.getCompanyId()); |
| | | |
| | | // 查询判断是否有不判定项目,和全都是判定项 |
| | | int judgeType = insProductMapper.selectNoJudge(insOrder.getId()); |
| | | int judgeType = showResult ? insProductMapper.selectNoJudge(insOrder.getId()) : 0; |
| | | String resultCh = ""; |
| | | String resultEn = ""; |
| | | for (String reference : resultChList) { |
| | |
| | | // 抽样日期 |
| | | // 成品是抽样时间 |
| | | LocalDateTime sendTime = insOrder.getSendTime(); |
| | | if (insOrder.getTypeSource() != null && insOrder.getTypeSource().equals(1)) { |
| | | IfsInventoryQuantity reportInventory = null; |
| | | if (insOrder.getIfsInventoryId() != null) { |
| | | reportInventory = ifsInventoryQuantityMapper.selectById(insOrder.getIfsInventoryId()); |
| | | } |
| | | if (insOrder.getTypeSource() != null && insOrder.getTypeSource().equals(1) && reportInventory != null) { |
| | | // 原材料收样日期是报检日期 |
| | | IfsInventoryQuantity ifsInventoryQuantity = ifsInventoryQuantityMapper.selectById(insOrder.getIfsInventoryId()); |
| | | sendTime = ifsInventoryQuantity.getDeclareDate(); |
| | | sendTime = reportInventory.getDeclareDate(); |
| | | } |
| | | |
| | | // 检验时间 抽样时间-提交时间 |
| | | // 检测日期:首次保存模板值时间-首次提交时间 |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | // 提交时间 |
| | | LocalDateTime submitTime = LocalDateTime.now(); |
| | |
| | | submitTime = insOrder.getFirstSubmitDate(); |
| | | } |
| | | |
| | | String insTime = insOrder.getSendTime().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")) + "-" |
| | | LocalDateTime firstInspectDate = insOrder.getFirstInspectDate(); |
| | | // 字段上线前的历史订单沿用原来的下发时间,避免改变既有报告口径。 |
| | | if (firstInspectDate == null) { |
| | | firstInspectDate = insOrder.getSendTime(); |
| | | } |
| | | |
| | | String insTime = firstInspectDate.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")) + "-" |
| | | + submitTime.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")); |
| | | |
| | | String insTimeEn = monthNames[insOrder.getSendTime().getMonthValue() - 1] + " " + insOrder.getSendTime().format(DateTimeFormatter.ofPattern("dd, yyyy")) + "-" |
| | | String insTimeEn = monthNames[firstInspectDate.getMonthValue() - 1] + " " + firstInspectDate.format(DateTimeFormatter.ofPattern("dd, yyyy")) + "-" |
| | | + monthNames[submitTime.getMonthValue() - 1] + " " + submitTime.format(DateTimeFormatter.ofPattern("dd, yyyy")); |
| | | |
| | | //检验项目的环境 |
| | | String environment = ""; |
| | | environment = (ObjectUtils.isNotEmpty(insOrder.getTemperature()) ? insOrder.getTemperature() + "℃ " : "") + (ObjectUtils.isNotEmpty(insOrder.getHumidity()) ? insOrder.getHumidity() + "%" : ""); |
| | | // 检验环境:优先汇总各模板填写的温湿度,报告展示全部模板的最小值到最大值。 |
| | | String environment = buildReportEnvironment(orderId, insOrder); |
| | | String finalEnvironment = environment; |
| | | LocalDateTime finalSendTime = sendTime; |
| | | String finalResultCh = resultCh; |
| | |
| | | List<Map<String, String>> finalDeviceList = deviceList; |
| | | String finalModelStr = modelStr; |
| | | |
| | | InputStream inputStream = this.getClass().getResourceAsStream("/static/report-template.docx"); |
| | | // 直绑模板订单没有 ins_product,检测项目、单位和结果均从订单模板快照中获取。 |
| | | List<Map<String, String>> detectionResultRows = directTemplateOrder |
| | | ? buildTemplateDetectionResultRows(orderId) |
| | | : buildDetectionResultRows(samples); |
| | | String productName = defaultReportText(insOrder.getSampleView(), insOrder.getSample()); |
| | | String customerName = defaultReportText(custom == null ? null : custom.getCompany(), insOrder.getCompany()); |
| | | String detectionCategory = defaultReportText(finalOrderType, "委托检测"); |
| | | String sampleCode = samples.stream() |
| | | .map(SampleProductDto::getSampleCode) |
| | | .filter(StringUtils::isNotBlank) |
| | | .distinct() |
| | | .collect(Collectors.joining("、")); |
| | | String productAndModel = productName; |
| | | if (StringUtils.isNotBlank(finalModelStr) && !Objects.equals(productName, finalModelStr)) { |
| | | productAndModel = productName + " " + finalModelStr; |
| | | } |
| | | String standardMethodText = "null".equals(standardMethod2.toString()) ? "" : standardMethod2.toString(); |
| | | String productionDate = "/"; |
| | | String batchNo = "/"; |
| | | if (reportInventory != null) { |
| | | if (reportInventory.getProductDate() != null) { |
| | | productionDate = reportInventory.getProductDate().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")); |
| | | } |
| | | batchNo = defaultReportText(reportInventory.getUpdateBatchNo(), reportInventory.getLotBatchNo()); |
| | | } |
| | | // 新聚直绑模板订单:报告信息取委托信息和订单模板快照,不再取能力范围标准方法。 |
| | | List<InsOrderStandardTemplate> templateSnapshots = insOrderStandardTemplateService.list( |
| | | Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, orderId) |
| | | .orderByAsc(InsOrderStandardTemplate::getSort, InsOrderStandardTemplate::getId)); |
| | | boolean newJuTemplateOrder = !templateSnapshots.isEmpty() && directTemplateOrder; |
| | | if (newJuTemplateOrder) { |
| | | productName = defaultReportText(insOrder.getSampleView(), insOrder.getSample()); |
| | | finalModelStr = "/"; |
| | | productAndModel = productName; |
| | | if (insOrder.getSampleDate() != null) { |
| | | finalSendTime = insOrder.getSampleDate().atStartOfDay(); |
| | | } |
| | | if (insOrder.getProductionDate() != null) { |
| | | productionDate = insOrder.getProductionDate().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")); |
| | | } |
| | | batchNo = defaultReportText(insOrder.getProductionBatch(), "/"); |
| | | standardMethodText = templateSnapshots.stream() |
| | | .map(InsOrderStandardTemplate::getRemark) |
| | | .filter(StringUtils::isNotBlank) |
| | | .distinct() |
| | | .collect(Collectors.joining(";")); |
| | | } |
| | | boolean containsOrganicChlorine = detectionResultRows.stream() |
| | | .map(row -> row.get("itemName")) |
| | | .filter(Objects::nonNull) |
| | | .anyMatch(name -> name.contains("有机氯")); |
| | | String resultRemark = containsOrganicChlorine |
| | | ? "微库仑法,有机氯含量小于0.005%时,以未检出报出。" |
| | | : defaultReportText(insOrder.getRemark(), "/"); |
| | | |
| | | // 检测报告和检验报告统一使用新版报告模板 |
| | | String templateName = "/static/detection-report-template-v2.docx"; |
| | | InputStream inputStream = this.getClass().getResourceAsStream(templateName); |
| | | if (inputStream == null) { |
| | | throw new RuntimeException("找不到报告模板: " + templateName); |
| | | } |
| | | Configure configure = Configure.builder() |
| | | .bind("deviceList", new HackLoopTableRenderPolicy()) |
| | | .bind("r", new HackLoopTableRenderPolicy(true)) |
| | | .setValidErrorHandler(new PreserveReportPicturePlaceholderHandler()) |
| | | .useSpringEL(true) |
| | | .build(); |
| | | |
| | | String finalProductAndModel = productAndModel; |
| | | String finalProductName = productName; |
| | | String finalCustomerName = customerName; |
| | | String finalDetectionCategory = detectionCategory; |
| | | String finalSampleCode = defaultReportText(sampleCode, "/"); |
| | | String finalStandardMethodText = defaultReportText(standardMethodText, "/"); |
| | | String finalProductionDate = productionDate; |
| | | String finalBatchNo = batchNo; |
| | | String finalResultRemark = resultRemark; |
| | | String equipmentText = buildEquipmentText(finalDeviceList); |
| | | String issueDate = now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")); |
| | | String finalReportModelStr = finalModelStr; |
| | | LocalDateTime finalReportSendTime = finalSendTime; |
| | | XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render( |
| | | new HashMap<String, Object>() {{ |
| | | put("order", insOrder); |
| | |
| | | put("sampleSize", insOrder.getTestQuantity()); |
| | | put("tables", tables); |
| | | put("tableSize", tables.size() + 1); |
| | | put("standardMethod", (standardMethod2.toString().equals("null") ? "" : standardMethod2)); |
| | | put("standardMethod", finalStandardMethodText); |
| | | put("deviceList", finalDeviceList); |
| | | put("twoCode", null); |
| | | put("models", finalModelStr); |
| | | put("models", finalReportModelStr); |
| | | put("productSize", productSize.get()); |
| | | put("createTime", now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"))); |
| | | put("createTimeEn", monthNames[now.getMonthValue() - 1] + " " + now.format(DateTimeFormatter.ofPattern("dd, yyyy"))); |
| | |
| | | put("examineUrl", null); |
| | | put("ratifyUrl", null); |
| | | put("orderType", finalOrderType); |
| | | put("getTime", finalSendTime.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"))); |
| | | put("getTimeEn", monthNames[finalSendTime.getMonthValue() - 1] + " " + finalSendTime.format(DateTimeFormatter.ofPattern("dd, yyyy"))); |
| | | put("getTime", finalReportSendTime.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"))); |
| | | put("getTimeEn", monthNames[finalReportSendTime.getMonthValue() - 1] + " " + finalReportSendTime.format(DateTimeFormatter.ofPattern("dd, yyyy"))); |
| | | put("seal1", null); |
| | | put("seal2", null); |
| | | put("formTypeCh", formType); |
| | |
| | | put("resultCh", finalResultCh); |
| | | put("resultEn", finalResultEn); |
| | | put("sampleStatus", sampleStatus); |
| | | // 新版检测报告模板(参照《有机氯检测报告》)使用的扁平字段。 |
| | | put("no", insReport.getCode()); |
| | | put("cover", finalProductAndModel); |
| | | put("product", finalProductName); |
| | | put("model", defaultReportText(finalReportModelStr, "/")); |
| | | put("customer", finalCustomerName); |
| | | put("category", finalDetectionCategory); |
| | | put("date", issueDate); |
| | | put("maker", defaultReportText(insOrder.getProduction(), "/")); |
| | | put("env", finalEnvironment); |
| | | put("qty", defaultReportText(insOrder.getTestQuantity(), "/")); |
| | | put("receive", finalReportSendTime.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"))); |
| | | put("sampleNo", finalSampleCode); |
| | | put("appearance", defaultReportText(sampleStatus, "/")); |
| | | put("sender", defaultReportText(insOrder.getPrepareUser(), "/")); |
| | | put("produced", finalProductionDate); |
| | | put("batch", finalBatchNo); |
| | | put("phone", defaultReportText(insOrder.getPhone(), "/")); |
| | | put("testDate", insTime); |
| | | put("entrustNo", defaultReportText(insOrder.getEntrustCode(), "/")); |
| | | put("sampling", "/"); |
| | | put("standard", finalStandardMethodText); |
| | | put("equipment", equipmentText); |
| | | put("conclusion", "样品按委托方要求进行检测,数据见检测结果。"); |
| | | put("remark", "本报告检测结果仅对当日所接收样品负责。"); |
| | | put("r", detectionResultRows); |
| | | put("resultNote", finalResultRemark); |
| | | }}); |
| | | try { |
| | | // 修改换行和合并问题 |
| | | updaeMerge(template.getXWPFDocument(), false); |
| | | String name = insReport.getCode().replace("/", "") + ".docx"; |
| | | template.writeAndClose(Files.newOutputStream(Paths.get(wordUrl + "/" + name))); |
| | | String name = insReport.getCode().replace("/", "") + (showResult ? ".docx" : "-C.docx"); |
| | | Files.createDirectories(Paths.get(wordUrl)); |
| | | template.writeAndClose(Files.newOutputStream(Paths.get(wordUrl, name))); |
| | | insReport.setUrl("/word/" + name); |
| | | insReport.setWriteUserId(SecurityUtils.getUserId().intValue());//提交人 |
| | | insReport.setWriteUserId(writeUserId);//编制人(检验人) |
| | | insReport.setWriteTime(LocalDateTime.now());//提交时间 |
| | | // 查询报告, 判断之前是否添加过, 添加过删除 |
| | | insReportMapper.delete(Wrappers.<InsReport>lambdaQuery() |
| | | .eq(InsReport::getInsOrderId, insOrder.getId())); |
| | | insReportMapper.insert(insReport); |
| | | saveGeneratedReport(insReport); |
| | | inputStream.close(); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | private void saveGeneratedReport(InsReport report) { |
| | | InsReport existing = insReportMapper.selectOne(Wrappers.<InsReport>lambdaQuery() |
| | | .eq(InsReport::getInsOrderId, report.getInsOrderId()) |
| | | .last("limit 1")); |
| | | if (existing == null) { |
| | | insReportMapper.insert(report); |
| | | return; |
| | | } |
| | | report.setId(existing.getId()); |
| | | insReportMapper.updateById(report); |
| | | } |
| | | |
| | | /** |
| | | * 新版检测报告的结果表固定为四列:序号、检测项目、单位、检测结果。 |
| | | */ |
| | | private List<Map<String, String>> buildDetectionResultRows(List<SampleProductDto> samples) { |
| | | List<Map<String, String>> rows = new ArrayList<>(); |
| | | if (CollectionUtils.isEmpty(samples)) { |
| | | return rows; |
| | | } |
| | | |
| | | boolean multipleSamples = samples.size() > 1; |
| | | int sequence = 1; |
| | | for (SampleProductDto sample : samples) { |
| | | if (CollectionUtils.isEmpty(sample.getInsProduct())) { |
| | | continue; |
| | | } |
| | | for (InsProduct product : sample.getInsProduct()) { |
| | | // 绑定项目仅参与计算,不应出现在报告中。 |
| | | if (product == null || Objects.equals(product.getIsBinding(), 1)) { |
| | | continue; |
| | | } |
| | | |
| | | String itemName = defaultReportText( |
| | | product.getInspectionItemSubclass(), |
| | | defaultReportText(product.getInspectionItem(), product.getInspectionItemClass())); |
| | | if (multipleSamples && StringUtils.isNotBlank(sample.getSampleCode())) { |
| | | itemName = sample.getSampleCode() + " - " + itemName; |
| | | } |
| | | |
| | | Map<String, String> row = new LinkedHashMap<>(); |
| | | row.put("seq", String.valueOf(sequence++)); |
| | | row.put("itemName", itemName); |
| | | row.put("unit", defaultReportText(product.getUnit(), "/")); |
| | | row.put("result", defaultReportText(product.getLastValue(), "/")); |
| | | rows.add(row); |
| | | } |
| | | } |
| | | return rows; |
| | | } |
| | | |
| | | /** |
| | | * 新聚直绑模板订单:模板中每一个“导出值”批注都对应报告中的一条检测项目。 |
| | | */ |
| | | private List<Map<String, String>> buildTemplateDetectionResultRows(Integer orderId) { |
| | | List<InsOrderStandardTemplate> snapshots = insOrderStandardTemplateService.list( |
| | | Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, orderId) |
| | | .orderByAsc(InsOrderStandardTemplate::getSort, InsOrderStandardTemplate::getId)); |
| | | List<Map<String, String>> rows = new ArrayList<>(); |
| | | int sequence = 1; |
| | | for (InsOrderStandardTemplate snapshot : snapshots) { |
| | | List<TemplateExportCell> exportCells = getTemplateExportCells(snapshot.getThing()); |
| | | JSONObject recordValues = StrUtil.isBlank(snapshot.getRecordValues()) |
| | | ? new JSONObject() : JSON.parseObject(snapshot.getRecordValues()); |
| | | for (TemplateExportCell exportCell : exportCells) { |
| | | String result = readTemplateCellText(recordValues, exportCell.resultCoordinate, exportCell.templateValues); |
| | | if (StringUtils.isBlank(result)) { |
| | | throw new ErrorException("模板“" + defaultReportText(snapshot.getName(), "模板ID " + snapshot.getTemplateId()) |
| | | + "”的导出值不能为空(" + exportCell.resultCoordinate + ")"); |
| | | } |
| | | String unit = exportCell.unitCoordinate == null ? null |
| | | : readTemplateCellText(recordValues, exportCell.unitCoordinate, exportCell.templateValues); |
| | | String itemName = exportCell.itemCoordinate == null ? null |
| | | : readTemplateCellText(recordValues, exportCell.itemCoordinate, exportCell.templateValues); |
| | | |
| | | Map<String, String> row = new LinkedHashMap<>(); |
| | | row.put("seq", String.valueOf(sequence++)); |
| | | String reportItemName = defaultReportText(itemName, |
| | | defaultReportText(snapshot.getName(), "模板ID " + snapshot.getTemplateId())); |
| | | row.put("itemName", formatExportItemName(reportItemName)); |
| | | row.put("unit", defaultReportText(unit, "/")); |
| | | row.put("result", result); |
| | | rows.add(row); |
| | | } |
| | | } |
| | | if (rows.isEmpty()) { |
| | | throw new ErrorException("当前订单未找到可生成报告的原始记录模板"); |
| | | } |
| | | return rows; |
| | | } |
| | | |
| | | private List<TemplateExportCell> getTemplateExportCells(String compressedThing) { |
| | | if (StrUtil.isBlank(compressedThing)) { |
| | | throw new ErrorException("原始记录模板为空"); |
| | | } |
| | | String thing; |
| | | try { |
| | | thing = GZipUtil.uncompress(compressedThing); |
| | | } catch (Exception ignored) { |
| | | thing = compressedThing; |
| | | } |
| | | JSONArray cellData = JSON.parseObject(thing).getJSONArray("data").getJSONObject(0).getJSONArray("celldata"); |
| | | Integer resultColumn = null; |
| | | Integer itemColumn = null; |
| | | Integer unitColumn = null; |
| | | List<int[]> exportCells = new ArrayList<>(); |
| | | Map<String, String> templateValues = new HashMap<>(); |
| | | for (Object item : cellData) { |
| | | JSONObject cell = JSON.parseObject(JSON.toJSONString(item)); |
| | | Integer row = cell.getInteger("r"); |
| | | Integer column = cell.getInteger("c"); |
| | | JSONObject value = cell.getJSONObject("v"); |
| | | if (row == null || column == null || value == null) { |
| | | continue; |
| | | } |
| | | String displayValue = value.get("v") == null ? null : String.valueOf(value.get("v")); |
| | | templateValues.put(row + "-" + column, displayValue); |
| | | if (resultColumn == null && "检验结果".equals(StringUtils.trim(displayValue))) { |
| | | resultColumn = column; |
| | | } |
| | | if (itemColumn == null && ("检测项目".equals(StringUtils.trim(displayValue)) |
| | | || "检验项目".equals(StringUtils.trim(displayValue)))) { |
| | | itemColumn = column; |
| | | } |
| | | if (unitColumn == null && "单位".equals(StringUtils.trim(displayValue))) { |
| | | unitColumn = column; |
| | | } |
| | | JSONObject ps = value.getJSONObject("ps"); |
| | | if (ps != null && "导出值".equals(ps.getString("value"))) { |
| | | exportCells.add(new int[]{row, column}); |
| | | } |
| | | } |
| | | if (exportCells.isEmpty()) { |
| | | throw new ErrorException("模板必须至少配置一个导出值批注"); |
| | | } |
| | | exportCells.sort(Comparator.comparingInt((int[] cell) -> cell[0]).thenComparingInt(cell -> cell[1])); |
| | | List<TemplateExportCell> results = new ArrayList<>(); |
| | | for (int[] exportCell : exportCells) { |
| | | int resultColumnForRow = resultColumn == null ? exportCell[1] : resultColumn; |
| | | // 通常“导出值”批注配置在项目名称单元格;若配置在结果单元格,则回到“检测项目”列取名称。 |
| | | Integer itemColumnForRow = !Objects.equals(exportCell[1], resultColumnForRow) |
| | | ? exportCell[1] : itemColumn; |
| | | TemplateExportCell result = new TemplateExportCell(); |
| | | result.resultCoordinate = exportCell[0] + "-" + resultColumnForRow; |
| | | result.itemCoordinate = itemColumnForRow == null ? null : exportCell[0] + "-" + itemColumnForRow; |
| | | result.unitCoordinate = unitColumn == null ? null : exportCell[0] + "-" + unitColumn; |
| | | result.templateValues = templateValues; |
| | | results.add(result); |
| | | } |
| | | return results; |
| | | } |
| | | |
| | | private String readTemplateCellText(JSONObject recordValues, String coordinate, Map<String, String> templateValues) { |
| | | JSONObject recordCell = recordValues == null ? null : recordValues.getJSONObject(coordinate); |
| | | if (recordCell != null && recordCell.get("v") != null) { |
| | | String value = String.valueOf(recordCell.get("v")); |
| | | if (StringUtils.isNotBlank(value)) { |
| | | return value; |
| | | } |
| | | } |
| | | return templateValues.get(coordinate); |
| | | } |
| | | |
| | | private static class TemplateExportCell { |
| | | private String itemCoordinate; |
| | | private String resultCoordinate; |
| | | private String unitCoordinate; |
| | | private Map<String, String> templateValues; |
| | | } |
| | | |
| | | private static String buildEquipmentText(List<Map<String, String>> deviceList) { |
| | | if (CollectionUtils.isEmpty(deviceList)) { |
| | | return "/"; |
| | | } |
| | | Set<String> lines = new LinkedHashSet<>(); |
| | | int sequence = 1; |
| | | for (Map<String, String> device : deviceList) { |
| | | String name = getMapText(device, "deviceName", "device_name"); |
| | | String managementNumber = getMapText(device, "managementNumber", "management_number"); |
| | | String line = sequence++ + ". " + defaultReportText(name, "/"); |
| | | if (StringUtils.isNotBlank(managementNumber)) { |
| | | line += ":" + managementNumber; |
| | | } |
| | | lines.add(line); |
| | | } |
| | | return String.join("\n", lines); |
| | | } |
| | | |
| | | private String buildReportEnvironment(Integer orderId, InsOrder order) { |
| | | List<InsOrderStandardTemplate> snapshots = insOrderStandardTemplateService.list( |
| | | Wrappers.<InsOrderStandardTemplate>lambdaQuery() |
| | | .eq(InsOrderStandardTemplate::getInsOrderId, orderId) |
| | | .select(InsOrderStandardTemplate::getTemperature, |
| | | InsOrderStandardTemplate::getHumidity)); |
| | | List<String> temperatures = snapshots.stream() |
| | | .map(InsOrderStandardTemplate::getTemperature) |
| | | .filter(StringUtils::isNotBlank) |
| | | .collect(Collectors.toList()); |
| | | List<String> humidities = snapshots.stream() |
| | | .map(InsOrderStandardTemplate::getHumidity) |
| | | .filter(StringUtils::isNotBlank) |
| | | .collect(Collectors.toList()); |
| | | |
| | | String temperature = formatConditionRange(temperatures, order.getTemperature(), "℃"); |
| | | String humidity = formatConditionRange(humidities, order.getHumidity(), "%"); |
| | | return Stream.of(temperature, humidity) |
| | | .filter(StringUtils::isNotBlank) |
| | | .collect(Collectors.joining(" ")); |
| | | } |
| | | |
| | | private static String formatConditionRange(List<String> values, String fallback, String unit) { |
| | | List<BigDecimal> numbers = new ArrayList<>(); |
| | | List<String> candidates = CollectionUtils.isEmpty(values) |
| | | ? Collections.singletonList(fallback) : values; |
| | | Pattern numberPattern = Pattern.compile("-?\\d+(?:\\.\\d+)?"); |
| | | for (String value : candidates) { |
| | | if (StringUtils.isBlank(value)) { |
| | | continue; |
| | | } |
| | | java.util.regex.Matcher matcher = numberPattern.matcher(value); |
| | | while (matcher.find()) { |
| | | numbers.add(new BigDecimal(matcher.group())); |
| | | } |
| | | } |
| | | if (numbers.isEmpty()) { |
| | | // “/”表示模板明确填写了不适用,不能再按空值处理或追加单位。 |
| | | return candidates.stream() |
| | | .filter(StringUtils::isNotBlank) |
| | | .map(String::trim) |
| | | .distinct() |
| | | .collect(Collectors.joining("~")); |
| | | } |
| | | BigDecimal minimum = Collections.min(numbers); |
| | | BigDecimal maximum = Collections.max(numbers); |
| | | String minimumText = minimum.stripTrailingZeros().toPlainString(); |
| | | if (minimum.compareTo(maximum) == 0) { |
| | | return minimumText + unit; |
| | | } |
| | | return minimumText + "~" + maximum.stripTrailingZeros().toPlainString() + unit; |
| | | } |
| | | |
| | | /** |
| | | * 报告项目名称不展示模板计算过程中的“平均值”字样及其后的分隔逗号。 |
| | | */ |
| | | private static String formatExportItemName(String itemName) { |
| | | if (StringUtils.isBlank(itemName)) { |
| | | return itemName; |
| | | } |
| | | return itemName.replaceAll("平均值\\s*[,,]?\\s*", ""); |
| | | } |
| | | |
| | | private static String getMapText(Map<String, String> map, String... keys) { |
| | | if (map == null) { |
| | | return null; |
| | | } |
| | | for (String key : keys) { |
| | | String value = map.get(key); |
| | | if (StringUtils.isNotBlank(value)) { |
| | | return value; |
| | | } |
| | | for (Map.Entry<String, String> entry : map.entrySet()) { |
| | | if (entry.getKey() != null && entry.getKey().equalsIgnoreCase(key) |
| | | && StringUtils.isNotBlank(entry.getValue())) { |
| | | return entry.getValue(); |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private static String defaultReportText(String value, String fallback) { |
| | | if (StringUtils.isNotBlank(value)) { |
| | | return value; |
| | | } |
| | | return StringUtils.isNotBlank(fallback) ? fallback : "/"; |
| | | } |
| | | |
| | | /** |
| | | * 计算表格列宽度 |
| | | * |
| | | * @param max 最大检验个数 |
| | | * @return |
| | | */ |
| | | private static int[] calcTableColWidths(int max, boolean showResult) { |
| | | if (!showResult) { |
| | | switch (max) { |
| | | case 1: |
| | | return new int[]{650, 2200, 2200, 850, 2300, 1800}; |
| | | case 2: |
| | | return new int[]{650, 1600, 1600, 850, 1900, 1700, 1700}; |
| | | case 3: |
| | | return new int[]{650, 1400, 1400, 850, 1600, 1375, 1375, 1375}; |
| | | case 4: |
| | | return new int[]{650, 1250, 1250, 850, 1450, 1140, 1140, 1140, 1140}; |
| | | case 5: |
| | | return new int[]{650, 1150, 1150, 850, 1300, 980, 980, 980, 980, 980}; |
| | | default: |
| | | return new int[0]; |
| | | } |
| | | } |
| | | int[] colWidths = null; |
| | | switch (max) { |
| | | case 1: |
| | | colWidths = new int[]{650, 2000, 2000, 850, 2200, 2100, 1200}; |
| | | break; |
| | | case 2: |
| | | colWidths = new int[]{650, 1400, 1400, 850, 2100, 1200, 1200, 1200}; |
| | | break; |
| | | case 3: |
| | | colWidths = new int[]{650, 1400, 1400, 850, 1500, 1000, 1000, 1000, 1200}; |
| | | break; |
| | | case 4: |
| | | colWidths = new int[]{650, 1200, 1200, 850, 1400, 850, 850, 850, 850, 1200}; |
| | | break; |
| | | case 5: |
| | | colWidths = new int[]{650, 1100, 1100, 850, 1350, 750, 750, 750, 750, 750, 1200}; |
| | | break; |
| | | } |
| | | if (ObjectUtils.isNull(colWidths)) { |
| | | List<Integer> defaultColWidths = new ArrayList<>(Arrays.asList(650, 1100, 1100, 850, 1350)); |
| | | int totalWidth = 3000;//总宽度 |
| | | int byOneWidth = totalWidth / max;//每一个的宽度 |
| | | int realWidth = 0;//实际宽度 |
| | | for (int i = 0; i < max; i++) { |
| | | realWidth += byOneWidth; |
| | | defaultColWidths.add(byOneWidth); |
| | | } |
| | | defaultColWidths.add(1200 + (totalWidth - realWidth)); |
| | | return defaultColWidths.stream().mapToInt(Integer::intValue).toArray(); |
| | | } |
| | | return colWidths; |
| | | } |
| | | |
| | | /** |
| | | * 调整高度 |
| | | * |
| | | * @param row |
| | | * @param rowHeight |
| | | * @return |
| | |
| | | // 获取检测内容判断是否超出 |
| | | if (StringUtils.isNotBlank(dataText) && dataText.contains("@")) { |
| | | double number = 1; |
| | | double chinaLength = 0; |
| | | double englishLength = 0; |
| | | double valueLength = 0; |
| | | double chinaLength = 14; |
| | | double englishLength = 28; |
| | | double valueLength = 6; |
| | | // 根据线芯个数判断距离 |
| | | switch (max) { |
| | | case 1: |
| | |
| | | |
| | | /** |
| | | * 添加报告表头 |
| | | * |
| | | * @param sample |
| | | * @param text |
| | | * @param rowRenderData |
| | | * @param rows |
| | | * @param max |
| | | * @param cableTags 线芯颜色 |
| | | * @param cableTags 线芯颜色 |
| | | */ |
| | | private static void addHead(SampleProductDto sample, List<TextRenderData> text, RowRenderData rowRenderData, List<RowRenderData> rows, int max, List<String> cableTags) { |
| | | private static void addHead(SampleProductDto sample, List<TextRenderData> text, RowRenderData rowRenderData, List<RowRenderData> rows, int max, List<String> cableTags, boolean showResult) { |
| | | // 第一行 |
| | | TextRenderData firstRenderData1 = new TextRenderData(); |
| | | firstRenderData1.setText("样品编号@Sample No.∑1"); |
| | |
| | | } |
| | | |
| | | } |
| | | // 检测报告不展示“结论”列,首行也要同步减少一个单元格, |
| | | // 否则首行为 max + 6 列、其余行为 max + 5 列,poi-tl 无法渲染表格。 |
| | | if (!showResult && !text.isEmpty()) { |
| | | text.remove(text.size() - 1); |
| | | } |
| | | TextRenderData[] text2 = text.toArray(new TextRenderData[0]); |
| | | rowRenderData = Rows.of(text2).center().rowAtleastHeight(1).create(); |
| | | rows.add(rowRenderData); |
| | |
| | | |
| | | for (int i = 0; i < max; i++) { |
| | | TextRenderData headRenderData6 = new TextRenderData(); |
| | | headRenderData6.setText("检验结果@Test result∑6"); |
| | | headRenderData6.setText(showResult ? "检验结果@Test result∑6" : "检测数据@Test data∑6"); |
| | | Style headStyle6 = new Style(); |
| | | headStyle6.setFontFamily("宋体"); |
| | | headStyle6.setColor("000000"); |
| | | headRenderData6.setStyle(headStyle6); |
| | | text.add(headRenderData6); |
| | | } |
| | | TextRenderData headRenderData7 = new TextRenderData(); |
| | | headRenderData7.setText("结论@Conclusion"); |
| | | Style headStyle7 = new Style(); |
| | | headStyle7.setFontFamily("宋体"); |
| | | headStyle7.setColor("000000"); |
| | | headRenderData7.setStyle(headStyle7); |
| | | text.add(headRenderData7); |
| | | if (showResult) { |
| | | TextRenderData headRenderData7 = new TextRenderData(); |
| | | headRenderData7.setText("结论@Conclusion"); |
| | | Style headStyle7 = new Style(); |
| | | headStyle7.setFontFamily("宋体"); |
| | | headStyle7.setColor("000000"); |
| | | headRenderData7.setStyle(headStyle7); |
| | | text.add(headRenderData7); |
| | | } |
| | | |
| | | TextRenderData[] text3 = text.toArray(new TextRenderData[0]); |
| | | rowRenderData = Rows.of(text3).center().rowAtleastHeight(1).create(); |
| | |
| | | cableRenderData6.setStyle(cableStyle6); |
| | | text.add(cableRenderData6); |
| | | } |
| | | TextRenderData cableRenderData7 = new TextRenderData(); |
| | | cableRenderData7.setText("-"); |
| | | Style cableStyle7 = new Style(); |
| | | cableStyle7.setFontFamily("宋体"); |
| | | cableStyle7.setColor("000000"); |
| | | cableRenderData7.setStyle(cableStyle7); |
| | | text.add(cableRenderData7); |
| | | if (showResult) { |
| | | TextRenderData cableRenderData7 = new TextRenderData(); |
| | | cableRenderData7.setText("-"); |
| | | Style cableStyle7 = new Style(); |
| | | cableStyle7.setFontFamily("宋体"); |
| | | cableStyle7.setColor("000000"); |
| | | cableRenderData7.setStyle(cableStyle7); |
| | | text.add(cableRenderData7); |
| | | } |
| | | |
| | | TextRenderData[] text4 = text.toArray(new TextRenderData[0]); |
| | | rowRenderData = Rows.of(text4).center().rowAtleastHeight(1).create(); |
| | |
| | | |
| | | /** |
| | | * 添加检测值 |
| | | * @param a 当前样品 |
| | | * |
| | | * @param a 当前样品 |
| | | * @param text |
| | | * @param rowRenderData |
| | | * @param rows |
| | | * @param max 检验数量 |
| | | * @param max 检验数量 |
| | | * @param resultChList 不符合信息中文 |
| | | * @param resultEhList 不符合信息英文 |
| | | * @param insSamples |
| | | * @param cableTags 线芯颜色 |
| | | * @param isOneSample 判断是否是只有一个样品 |
| | | * @param cableTags 线芯颜色 |
| | | * @param isOneSample 判断是否是只有一个样品 |
| | | */ |
| | | private int addTestValue(SampleProductDto a, |
| | | List<TextRenderData> text, |
| | |
| | | List<String> resultChList, |
| | | List<String> resultEhList, |
| | | InsSample insSamples, List<String> cableTags, |
| | | boolean isOneSample) { |
| | | boolean isOneSample, boolean showResult) { |
| | | // 检验项总数 |
| | | AtomicInteger productSize = new AtomicInteger(1); |
| | | // 不合格信息 |
| | |
| | | // 检验项分类 检验项 检验子项 |
| | | Map<String, LinkedHashMap<String, List<String>>> errorClassItemMapCn = new LinkedHashMap<>(); |
| | | Map<String, LinkedHashMap<String, List<String>>> errorClassItemMapEn = new LinkedHashMap<>(); |
| | | |
| | | // 中间检测值添加 |
| | | for (int i = 0; i < sampleList.size(); i++) { |
| | | SampleProductExportDto sample = sampleList.get(i); |
| | |
| | | |
| | | // 判断是否有电缆标识map |
| | | if (CollectionUtils.isNotEmpty(sample.getCableTagValueMap())) { |
| | | sample.setLastValueList(new ArrayList<>(sample.getCableTagValueMap().values())); |
| | | TreeMap<String, String> cableTagValues = new TreeMap<>(Comparator.comparingInt(cableTags::indexOf)); |
| | | cableTagValues.putAll(sample.getCableTagValueMap()); |
| | | sample.setLastValueList(new ArrayList<>(cableTagValues.values())); |
| | | } |
| | | if (CollectionUtils.isNotEmpty(sample.getCableTagResultMap())) { |
| | | sample.setInsResultList(new ArrayList<>(sample.getCableTagResultMap().values())); |
| | |
| | | } |
| | | } |
| | | // 判定结果 |
| | | String result = ""; |
| | | if (sample.getInsResult() != null) { |
| | | switch (sample.getInsResult()) { |
| | | case 1: |
| | | result = "√"; |
| | | break; |
| | | case 2: |
| | | result = "×"; |
| | | break; |
| | | case 3: |
| | | result = "-"; |
| | | break; |
| | | } |
| | | } |
| | | if (CollectionUtils.isNotEmpty(sample.getLastValueList())) { |
| | | // 判断是否有一个错误 |
| | | if (sample.getInsResultList().stream().anyMatch(s -> s.equals(3))) { |
| | | result = "-"; |
| | | } else { |
| | | boolean error = sample.getInsResultList().stream().anyMatch(s -> s.equals(0)); |
| | | if (error) { |
| | | List<String> collect = new ArrayList<>(); |
| | | int index = 0; |
| | | for (Integer count : sample.getInsResultList()) { |
| | | String type; |
| | | if (count.equals(0)) { |
| | | String itemCh = ""; |
| | | String itemEn = ""; |
| | | // 添加不合格描述 |
| | | // 判断长度是否为1 |
| | | if (sample.getLastValueList().size() == 1) { |
| | | this.fillReportErrorResult(errorClassItemMapCn, errorClassItemMapEn, sample, itemCh, itemEn); |
| | | } else if (CollectionUtils.isNotEmpty(cableTags)) { |
| | | // 判断是否有电缆配置, 不是的话可能为原材料 |
| | | // 添加不合格描述 |
| | | itemCh = (max == 1 ? "" : cableTags.get(index)); |
| | | itemEn = (max == 1 ? "" : "The " + Integer.toString(index + 1) + " time "); |
| | | this.fillReportErrorResult(errorClassItemMapCn, errorClassItemMapEn, sample, itemCh, itemEn); |
| | | } else { |
| | | // 添加不合格描述 |
| | | itemCh = (max == 1 ? "" : "第" + Integer.toString(index + 1) + "次"); |
| | | itemEn = (max == 1 ? "" : "The " + Integer.toString(index + 1) + " time "); |
| | | this.fillReportErrorResult(errorClassItemMapCn, errorClassItemMapEn, sample, itemCh, itemEn); |
| | | } |
| | | type = "×"; |
| | | } else { |
| | | type = "√"; |
| | | } |
| | | collect.add(type); |
| | | index++; |
| | | } |
| | | result = CollUtil.join(collect, " "); |
| | | ; |
| | | } else { |
| | | result = "√"; |
| | | if (showResult) { |
| | | String result = ""; |
| | | if (sample.getInsResult() != null) { |
| | | switch (sample.getInsResult()) { |
| | | case 1: |
| | | result = "√"; |
| | | break; |
| | | case 2: |
| | | result = "×"; |
| | | break; |
| | | case 3: |
| | | result = "-"; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | if (CollectionUtils.isNotEmpty(sample.getLastValueList())) { |
| | | // 判断是否有一个错误 |
| | | if (sample.getInsResultList().stream().anyMatch(s -> Objects.equals(s, 3))) { |
| | | result = "-"; |
| | | } else { |
| | | boolean error = sample.getInsResultList().stream().anyMatch(s -> Objects.equals(s, 0)); |
| | | if (error) { |
| | | List<String> collect = new ArrayList<>(); |
| | | int index = 0; |
| | | for (Integer count : sample.getInsResultList()) { |
| | | String type; |
| | | if (Objects.equals(count, 0)) { |
| | | String itemCh = ""; |
| | | String itemEn = ""; |
| | | // 添加不合格描述 |
| | | // 判断长度是否为1 |
| | | if (sample.getLastValueList().size() == 1) { |
| | | this.fillReportErrorResult(errorClassItemMapCn, errorClassItemMapEn, sample, itemCh, itemEn); |
| | | } else if (CollectionUtils.isNotEmpty(cableTags)) { |
| | | // 判断是否有电缆配置, 不是的话可能为原材料 |
| | | // 添加不合格描述 |
| | | itemCh = (max == 1 ? "" : cableTags.get(index)); |
| | | itemEn = (max == 1 ? "" : "The " + Integer.toString(index + 1) + " time "); |
| | | this.fillReportErrorResult(errorClassItemMapCn, errorClassItemMapEn, sample, itemCh, itemEn); |
| | | } else { |
| | | // 添加不合格描述 |
| | | itemCh = (max == 1 ? "" : "第" + Integer.toString(index + 1) + "次"); |
| | | itemEn = (max == 1 ? "" : "The " + Integer.toString(index + 1) + " time "); |
| | | this.fillReportErrorResult(errorClassItemMapCn, errorClassItemMapEn, sample, itemCh, itemEn); |
| | | } |
| | | type = "×"; |
| | | } else { |
| | | type = "√"; |
| | | } |
| | | collect.add(type); |
| | | index++; |
| | | } |
| | | result = CollUtil.join(collect, " "); |
| | | ; |
| | | } else { |
| | | result = "√"; |
| | | } |
| | | } |
| | | } |
| | | |
| | | TextRenderData headRenderData7 = new TextRenderData(); |
| | | headRenderData7.setText(result); |
| | | Style headStyle7 = new Style(); |
| | | headStyle7.setFontFamily("宋体"); |
| | | headStyle7.setColor("000000"); |
| | | headRenderData7.setStyle(headStyle7); |
| | | text.add(headRenderData7); |
| | | if (showResult) { |
| | | TextRenderData headRenderData7 = new TextRenderData(); |
| | | headRenderData7.setText(result); |
| | | Style headStyle7 = new Style(); |
| | | headStyle7.setFontFamily("宋体"); |
| | | headStyle7.setColor("000000"); |
| | | headRenderData7.setStyle(headStyle7); |
| | | text.add(headRenderData7); |
| | | } |
| | | } |
| | | |
| | | TextRenderData[] text2 = text.toArray(new TextRenderData[0]); |
| | | rowRenderData = Rows.of(text2).center().rowAtleastHeight(1).create(); |
| | |
| | | } |
| | | |
| | | /** |
| | | * NBSP(非间断空格) 转成 普通空格 |
| | | * |
| | | * @param oldStr |
| | | * @return |
| | | */ |
| | | private String normalizedSpaces(String oldStr) { |
| | | if (StringUtils.isBlank(oldStr)) { |
| | | return oldStr; |
| | | } |
| | | return oldStr.replaceAll("\u00A0", " ").trim(); |
| | | } |
| | | |
| | | /** |
| | | * 添加报告结论中英文 |
| | | * |
| | | * @param sample |
| | | * @param itemCh |
| | | * @param itemEn |
| | |
| | | String itemCh, |
| | | String itemEn) { |
| | | // 判断是否有检验项分类map |
| | | String classTiemName = itemCh + (StringUtils.isBlank(sample.getInspectionItemClass()) ? "" : sample.getInspectionItemClass()); |
| | | String classTiemNameEn = itemEn + (StringUtils.isBlank(sample.getInspectionItemClassEN()) ? "" : sample.getInspectionItemClassEN()); |
| | | String classTiemNameItemEN = StringUtils.isBlank(sample.getInspectionItemEn()) ? "" : sample.getInspectionItemEn(); |
| | | String classTiemName = itemCh + (StringUtils.isBlank(sample.getInspectionItemClass()) ? "" : normalizedSpaces(sample.getInspectionItemClass())); |
| | | String classTiemNameEn = itemEn + (StringUtils.isBlank(sample.getInspectionItemClassEN()) ? "" : normalizedSpaces(sample.getInspectionItemClassEN())); |
| | | String classTiemNameItemEN = StringUtils.isBlank(sample.getInspectionItemEn()) ? "" : normalizedSpaces(sample.getInspectionItemEn()); |
| | | |
| | | if (errorClassItemMapCn.containsKey(classTiemName)) { |
| | | // 判断是否有检验项map |
| | |
| | | |
| | | /** |
| | | * 格式化修改检验项 |
| | | * |
| | | * @param sampleProductDto2s |
| | | */ |
| | | private void formatProducts(List<SampleProductExportDto> sampleProductDto2s) { |
| | |
| | | sampleProductDto2.setLastValue(sampleProductDto2.getLastValue().trim()); |
| | | } |
| | | |
| | | if (sampleProductDto2.getInsResult().equals(0)) { |
| | | if (Objects.equals(sampleProductDto2.getInsResult(), 0)) { |
| | | // 查询不合格复测 |
| | | Long count = insUnqualifiedRetestProductMapper.selectCount(Wrappers.<InsUnqualifiedRetestProduct>lambdaQuery() |
| | | .eq(InsUnqualifiedRetestProduct::getInsProductId, sampleProductDto2.getInsProductId()) |
| | |
| | | |
| | | /** |
| | | * 添加结尾 |
| | | * |
| | | * @param text |
| | | * @param rowRenderData |
| | | * @param rows |
| | | */ |
| | | private static void addEnding(List<TextRenderData> text, RowRenderData rowRenderData, List<RowRenderData> rows, int max) { |
| | | private static void addEnding(List<TextRenderData> text, RowRenderData rowRenderData, List<RowRenderData> rows, int max, boolean showResult) { |
| | | for (int i = 0; i < 2; i++) { |
| | | TextRenderData endingRenderData = new TextRenderData(); |
| | | endingRenderData.setText("备注∑1999"); |
| | |
| | | text.add(endingRenderData); |
| | | } |
| | | |
| | | for (int i = 0; i < 5 + max - 1; i++) { |
| | | for (int i = 0; i < (showResult ? 5 : 4) + max - 1; i++) { |
| | | TextRenderData endingRenderData = new TextRenderData(); |
| | | endingRenderData.setText("“√”表示项目合格,“×”表示项目不合格,“-”表示不要判定,“/”表示没有标准要求。@“√” indicates test ltem is qualified,“×” indicates test ltem is unqualified,“-” indicates test ltem judgment is not required,“/” indicates test ltem is no test requirement.∑2000"); |
| | | endingRenderData.setText(showResult ? "“√”表示项目合格,“×”表示项目不合格,“-”表示不要判定,“/”表示没有标准要求。@“√” indicates test ltem is qualified,“×” indicates test ltem is unqualified,“-” indicates test ltem judgment is not required,“/” indicates test ltem is no test requirement.∑2000" : ""); |
| | | Style endingStyle = new Style(); |
| | | endingStyle.setFontFamily("宋体"); |
| | | endingStyle.setColor("000000"); |
| | |
| | | |
| | | /** |
| | | * 判断当前内容是否是科学计数法 |
| | | * |
| | | * @param str |
| | | * @return |
| | | */ |
| | |
| | | |
| | | /** |
| | | * 修改要求描述的科学计数法 |
| | | * |
| | | * @param input |
| | | */ |
| | | public static String convertToScientificNotation(String input) { |
| | |
| | | |
| | | /** |
| | | * 展示成科学计数法 |
| | | * |
| | | * @param number |
| | | * @return |
| | | */ |
| | |
| | | |
| | | /** |
| | | * 根据要求描述保留结果小数点位数 |
| | | * |
| | | * @param reference |
| | | * @param value |
| | | * @return |
| | |
| | | |
| | | /** |
| | | * 保留位数, 如果等于0 返回找到的一个非0位数 |
| | | * |
| | | * @param number 当前数字 |
| | | * @param scale 原本保留的位数 |
| | | * @return |
| | |
| | | |
| | | /** |
| | | * *****保存元此阿里进货验证原始记录***** |
| | | * @param insOrderId 订单Id |
| | | * @param examineUserId 复核人Id |
| | | * @param writeUserId 检验员Id |
| | | * |
| | | * @param insOrderId 订单Id |
| | | * @param examineUserId 复核人Id |
| | | * @param writeUserId 检验员Id |
| | | */ |
| | | private void reportFactoryVerify(Integer insOrderId, Integer examineUserId, Integer writeUserId) { |
| | | // 查询进货验证原始记录 |
| | |
| | | |
| | | // 保存到附件里面 |
| | | uploadFile(insOrderId, multipartFile); |
| | | try { |
| | | inputStream.close(); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | |
| | | } |
| | | |
| | |
| | | |
| | | /** |
| | | * ***格式化进厂验证内容**** |
| | | * |
| | | * @param basicType |
| | | * @return |
| | | */ |
| | |
| | | |
| | | /** |
| | | * ***word转换pdf*** |
| | | * |
| | | * @param path |
| | | * @return |
| | | */ |
| | |
| | | |
| | | /** |
| | | * *****修改成品抽样状态****** |
| | | * |
| | | * @param insSamples |
| | | * @param order |
| | | */ |
| | |
| | | .set(SpotCheckQuarterItem::getResult, unqualifiedCount.equals(0L) ? "合格" : "不合格")); |
| | | } |
| | | |
| | | /** |
| | | * 添加工时 |
| | | * |
| | | * @param userId |
| | | * @param insProduct |
| | | * @param insOrder |
| | | */ |
| | | private synchronized void addAuxiliary(Integer userId, InsProduct insProduct, InsOrder insOrder) { |
| | | if (insProduct.getIsBinding().equals(1)) { |
| | | return; |
| | | } |
| | | |
| | | //校验如果这个人这个检测项目已经添加过了 |
| | | List<AuxiliaryOutputWorkingHours> count2s = auxiliaryOutputWorkingHoursMapper.selectList(Wrappers.<AuxiliaryOutputWorkingHours>lambdaQuery() |
| | | .eq(AuxiliaryOutputWorkingHours::getCheck, userId) |
| | | .eq(AuxiliaryOutputWorkingHours::getInsProductId, insProduct.getId())); |
| | | if (CollectionUtils.isNotEmpty(count2s)) { |
| | | for (AuxiliaryOutputWorkingHours auxiliaryOutputWorkingHours : count2s) { |
| | | auxiliaryOutputWorkingHours.setCheck(userId);//检测人 |
| | | } |
| | | auxiliaryOutputWorkingHoursService.updateBatchById(count2s); |
| | | } else { |
| | | if (ObjectUtils.isNotEmpty(insProduct.getManHour()) && StringUtils.isNotBlank(insProduct.getLastValue())) { |
| | | AuxiliaryOutputWorkingHours auxiliaryOutputWorkingHours = new AuxiliaryOutputWorkingHours(); |
| | | auxiliaryOutputWorkingHours.setInspectionItemClass(insProduct.getInspectionItemClass());//检测项分类 |
| | | auxiliaryOutputWorkingHours.setInspectionItem(insProduct.getInspectionItem());//检测父项 |
| | | auxiliaryOutputWorkingHours.setInspectionItemSubclass(insProduct.getInspectionItemSubclass());//检测子项 |
| | | auxiliaryOutputWorkingHours.setSample(insSampleMapper.selectById(insProduct.getInsSampleId()).getSampleCode());//样品编号 |
| | | auxiliaryOutputWorkingHours.setOrderId(insOrder.getId());//订单id |
| | | auxiliaryOutputWorkingHours.setOrderNo(insOrder.getEntrustCode());//非加班委托单号 |
| | | auxiliaryOutputWorkingHours.setWorkTime(insProduct.getManHour());//非加班工时 |
| | | auxiliaryOutputWorkingHours.setAmount(1);//非加班数量 |
| | | auxiliaryOutputWorkingHours.setOutputWorkTime((ObjectUtils.isNotEmpty(auxiliaryOutputWorkingHours.getOvertimeWorkTime()) ? auxiliaryOutputWorkingHours.getOvertimeWorkTime() : BigDecimal.ZERO).add(ObjectUtils.isNotEmpty(auxiliaryOutputWorkingHours.getWorkTime()) ? auxiliaryOutputWorkingHours.getWorkTime() : BigDecimal.ZERO));//产量工时 |
| | | auxiliaryOutputWorkingHours.setManHourGroup(insProduct.getManHourGroup());//工时分组 |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | DateTimeFormatter formatters = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
| | | auxiliaryOutputWorkingHours.setDateTime(LocalDateTime.now().toLocalDate().atStartOfDay().format(formatters));//日期 |
| | | LocalDateTime localDateTime = LocalDateTime.now(); |
| | | DateTime parse = DateUtil.parse(localDateTime.format(formatter)); |
| | | auxiliaryOutputWorkingHours.setWeekDay(getWeek(localDateTime.format(formatters)));//星期 |
| | | auxiliaryOutputWorkingHours.setWeek(String.valueOf(DateUtil.weekOfYear(DateUtil.offsetDay(parse, 1))));//周次 |
| | | auxiliaryOutputWorkingHours.setCheck(userId);//检测人 |
| | | auxiliaryOutputWorkingHours.setPrice(insProduct.getPrice());//单价 |
| | | auxiliaryOutputWorkingHours.setSampleId(insProduct.getInsSampleId());//样品id |
| | | auxiliaryOutputWorkingHours.setInsProductId(insProduct.getId());//检验项id |
| | | |
| | | auxiliaryOutputWorkingHoursMapper.insert(auxiliaryOutputWorkingHours); |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | public static String getWeek(String dayStr) { |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | try { |
| | | Date date = sdf.parse(dayStr); |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(date); |
| | | int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); |
| | | int day = calendar.get(Calendar.DAY_OF_MONTH); |
| | | return getWeekDay(dayOfWeek); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static String getWeekDay(int dayOfWeek) { |
| | | switch (dayOfWeek) { |
| | | case Calendar.MONDAY: |
| | | return "周一"; |
| | | case Calendar.TUESDAY: |
| | | return "周二"; |
| | | case Calendar.WEDNESDAY: |
| | | return "周三"; |
| | | case Calendar.THURSDAY: |
| | | return "周四"; |
| | | case Calendar.FRIDAY: |
| | | return "周五"; |
| | | case Calendar.SATURDAY: |
| | | return "周六"; |
| | | case Calendar.SUNDAY: |
| | | return "周日"; |
| | | default: |
| | | return "未知"; |
| | | } |
| | | } |
| | | } |