src/main/java/com/ruoyi/basic/excel/ExcelUtils.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,9 @@ package com.ruoyi.basic.excel; /** * @author buhuazhen * @date 2026/4/25 * @email 3038525872@qq.com */ public class ExcelUtils { } src/main/java/com/ruoyi/basic/excel/ProductionPrintOrderExcel.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,104 @@ package com.ruoyi.basic.excel; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.IdUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.enums.WriteDirectionEnum; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.fill.FillConfig; import com.alibaba.excel.write.metadata.fill.FillWrapper; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.production.dto.ExportProductionPrintOrderDto; import com.ruoyi.production.pojo.ProductionPrintOrder; import lombok.SneakyThrows; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFDrawing; import org.apache.poi.xssf.usermodel.XSSFPicture; import org.apache.poi.xssf.usermodel.XSSFShape; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.springframework.stereotype.Component; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.List; /** * @author buhuazhen * @date 2026/4/25 * @email 3038525872@qq.com */ @Component public class ProductionPrintOrderExcel { @SneakyThrows public void createPrintOrderTemplate(ExportProductionPrintOrderDto printOrderDto, InputStream templateInputStream) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); try (ExcelWriter excelWriter = EasyExcel.write(byteArrayOutputStream) .withTemplate(templateInputStream) .build()) { FillConfig fillConfig = FillConfig.builder() .forceNewRow(true) .autoStyle(true) .direction(WriteDirectionEnum.VERTICAL) .build(); WriteSheet writeSheet = EasyExcel.writerSheet().build(); excelWriter.fill(printOrderDto, writeSheet); excelWriter.fill(new FillWrapper("materialInfo", printOrderDto.getMaterialInfo()), fillConfig, writeSheet); excelWriter.fill(new FillWrapper("processContent", printOrderDto.getProcessContent()), fillConfig, writeSheet); excelWriter.fill(new FillWrapper("plateMaking", printOrderDto.getPlateMaking()), fillConfig, writeSheet); excelWriter.finish(); } catch (Exception e) { throw new ServiceException("excel çæå¤±è´¥! " + e.getMessage()); } try { Workbook workbook = WorkbookFactory.create( new ByteArrayInputStream(byteArrayOutputStream.toByteArray()) ); Sheet sheet = workbook.getSheetAt(0); // ===== æå ¥å¾ç ===== byte[] imageBytes = printOrderDto.getCuttingImage(); int pictureIdx = workbook.addPicture(imageBytes, Workbook.PICTURE_TYPE_JPEG); CreationHelper helper = workbook.getCreationHelper(); Drawing<?> drawing = sheet.createDrawingPatriarch(); ClientAnchor anchor = helper.createClientAnchor(); anchor.setCol1(6); // 第7åï¼Gåï¼ anchor.setRow1(7); anchor.setDx1(1082700); // åå³ç§»å¨ï¼çº¦åæ ¼ï¼ Picture picture = drawing.createPicture(anchor, pictureIdx); picture.resize(); ByteArrayOutputStream out = new ByteArrayOutputStream(); workbook.write(out); workbook.close(); FileUtil.writeBytes( out.toByteArray(), "/Users/ONEX/Downloads/uploads/" + IdUtil.simpleUUID() + ".xlsx" ); } catch (Exception e) { throw new ServiceException("å¾çå¤ç失败! " + e.getMessage()); } } } src/main/java/com/ruoyi/common/utils/StringUtils.java
@@ -1,5 +1,6 @@ package com.ruoyi.common.utils; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; @@ -761,4 +762,49 @@ return sb.toString(); } } public static void fillStringNull(Object obj) { if (obj == null) return; Class<?> clazz = obj.getClass(); // åºæ¬ç±»å / å è£ ç±» / String ä¸å¤ç if (clazz.isPrimitive() || clazz == String.class || Number.class.isAssignableFrom(clazz) || clazz == Boolean.class || clazz == Character.class) { return; } for (Field field : clazz.getDeclaredFields()) { field.setAccessible(true); try { Object value = field.get(obj); // 1ï¸â£ String ç±»åï¼null â "" if (field.getType() == String.class) { if (value == null) { field.set(obj, ""); } } // 2ï¸â£ List éå½å¤ç else if (value instanceof List) { for (Object item : (List<?>) value) { fillStringNull(item); } } // 3ï¸â£ å ¶ä»å¯¹è±¡éå½ else if (value != null && !isJdkClass(value.getClass())) { fillStringNull(value); } } catch (IllegalAccessException ignored) {} } } private static boolean isJdkClass(Class<?> clazz) { return clazz.getPackage() != null && clazz.getPackage().getName().startsWith("java."); } } src/main/java/com/ruoyi/production/controller/ProductionPrintOrderController.java
@@ -33,4 +33,9 @@ return productionPrintOrderService.getByProductWordId(id); } @PostMapping("/export/{id}") public R export(@PathVariable Long id){ productionPrintOrderService.exportPrintExcelByWordId(id); return R.ok(); } } src/main/java/com/ruoyi/production/dto/ExportProductionPrintOrderDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,68 @@ package com.ruoyi.production.dto; import com.alibaba.excel.metadata.data.ImageData; import com.alibaba.excel.metadata.data.WriteCellData; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.Collections; /** * @author buhuazhen * @date 2026/4/25 * @email 3038525872@qq.com */ @EqualsAndHashCode(callSuper = true) @Data @AllArgsConstructor @NoArgsConstructor public class ExportProductionPrintOrderDto extends ProductionPrintOrderDto implements Serializable { private String numSuffix; private String unitSuffix; private String priceSuffix; // å¶åæ¥æ private String printOrderTimeStr; // å®ææ¥æ private String finishTimeStr; // ä»ç»ä¿¡ private String introductionLetter1 = "£"; // åæ æ³¨å private String introductionLetter2 = "£"; // å§å°å private String introductionLetter3 = "£"; // ä¹¦å· private String introductionLetter4 = "£"; // å¹³å¼ private String cuttingDiagramCheckout1 = "£"; // å·ç private String cuttingDiagramCheckout2 = "£"; private byte[] cuttingImage; // // public void setCuttingImage(byte[] bytes) { // // WriteCellData<Void> cell = new WriteCellData<>(); // // ImageData imageData = new ImageData(); // // imageData.setImage(bytes); // // imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG); // // cell.setImageDataList(Collections.singletonList(imageData)); // // this.cuttingImage = cell; // // } } src/main/java/com/ruoyi/production/dto/ProductOrderDto.java
@@ -94,4 +94,6 @@ @Excel(name = "è²æ°",sort = 9) private String printColorCount; private Long printId; } src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
@@ -19,5 +19,5 @@ List<ProductWorkOrderDto> selectWorkOrderStartStats(@Param("startDate") String startDate, @Param("endDate") String endDate); ProductWorkOrder selectMax(@Param("datePrefix") String datePrefix); Integer selectMax(@Param("datePrefix") String datePrefix); } src/main/java/com/ruoyi/production/pojo/ProductionPrintOrder.java
@@ -262,6 +262,12 @@ @TableField(value = "client_name") private String clientName; /** * åæå¾ç¤ºéæ© åé */ @TableField(value = "cutting_diagram_checkout") private String cuttingDiagramCheckout; public ProductOrderDto convertProductOrderDto(@NotNull ProductOrderDto dto) { dto.setCutSize(this.getCutSize()); src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java
@@ -26,5 +26,5 @@ * @param npsNo ç产订åå· * @return String */ String generateProductWorkOrder(String datePrefix, String processName,String npsNo); String generateProductWorkOrder(String processName, String npsNo); } src/main/java/com/ruoyi/production/service/ProductionPrintOrderService.java
@@ -30,4 +30,11 @@ List<ProductionPrintOrder> getListByOrders(@Nullable List<Long> orderIds); /** * çæå¯¼åºexcel å°å·å模ç * @param orderId 订åid */ void exportPrintExcelByWordId(@Nullable Long orderId); } src/main/java/com/ruoyi/production/service/impl/ProcessRouteServiceImpl.java
@@ -234,7 +234,7 @@ productWorkOrder.setDeviceId(dto.getDeviceId()); productWorkOrder.setUserIds(dto.getUserIds()); productWorkOrder.setUserNames(dto.getUserNames()); productWorkOrder.setWorkOrderNo(productWorkOrderService.generateProductWorkOrder(null, productProcess.getName(), byId.getNpsNo())); productWorkOrder.setWorkOrderNo(productWorkOrderService.generateProductWorkOrder( productProcess.getName(), byId.getNpsNo())); productWorkOrder.setStatus(1); productWorkOrderService.save(productWorkOrder); } src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -83,8 +83,6 @@ productionPrintOrder.convertProductOrderDto(record); } }); } return productOrderDtoIPage; @@ -126,7 +124,7 @@ productWorkOrder.setProductOrderId(productOrder.getId()); ProductOrder order = productOrderMapper.selectById(productOrder.getId()); productWorkOrder.setPlanQuantity(order.getQuantity()); productWorkOrder.setWorkOrderNo(productWorkOrderService.generateProductWorkOrder(null, productProcessMap.getOrDefault(productProcessRouteItem.getProcessId(), new ProductProcess()).getName(), productOrder.getNpsNo())); productWorkOrder.setWorkOrderNo(productWorkOrderService.generateProductWorkOrder( productProcessMap.getOrDefault(productProcessRouteItem.getProcessId(), new ProductProcess()).getName(), productOrder.getNpsNo())); productWorkOrder.setStatus(1); productWorkOrderMapper.insert(productWorkOrder); } src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java
@@ -145,7 +145,7 @@ productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId()); productWorkOrder.setProductOrderId(productProcessRouteItem.getProductOrderId()); productWorkOrder.setPlanQuantity(productOrder.getQuantity()); productWorkOrder.setWorkOrderNo(productWorkOrderService.generateProductWorkOrder(null,productProcess.getName(),productOrder.getNpsNo())); productWorkOrder.setWorkOrderNo(productWorkOrderService.generateProductWorkOrder(productProcess.getName(),productOrder.getNpsNo())); productWorkOrder.setStatus(1); productWorkOrderMapper.insert(productWorkOrder); } src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
@@ -3,7 +3,6 @@ import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.pinyin.PinyinUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -29,8 +28,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -73,7 +70,7 @@ if (CollectionUtils.isNotEmpty(productWorkOrderFiles)) { productWorkOrderFiles.forEach(productWorkOrderFile -> { Map<String, Object> image = new HashMap<>(); PictureRenderData pictureRenderData = Pictures.ofLocal( productWorkOrderFile.getUrl()).sizeInCm(17, 20).create(); PictureRenderData pictureRenderData = Pictures.ofLocal(productWorkOrderFile.getUrl()).sizeInCm(17, 20).create(); image.put("url", pictureRenderData); images.add(image); }); @@ -95,7 +92,7 @@ put("actualEndTime", productWorkOrderDto.getActualEndTime()); put("twoCode", Pictures.ofLocal(codePath).create()); put("deviceName", productWorkOrderDto.getDeviceName()); put("images", images.isEmpty()?null:images); put("images", images.isEmpty() ? null : images); }}); try { @@ -122,25 +119,13 @@ } @Override public String generateProductWorkOrder(String datePrefix,String processName, String npsNo) { datePrefix = StrUtil.isBlank(datePrefix) ? LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) : datePrefix; public String generateProductWorkOrder(String processName, String npsNo) { processName = StrUtil.isBlank(processName) ? "æªç¥" : processName; Assert.notNull(npsNo, "ç产订åå·ç¼å·ä¸è½ä¸ºç©º"); ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix); int sequenceNumber = 1; // é»è®¤åºå· if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) { String lastNo = lastWorkOrder.getWorkOrderNo().toString(); if (lastNo.startsWith(datePrefix)) { String seqStr = lastNo.substring(datePrefix.length()); try { sequenceNumber = Integer.parseInt(seqStr) + 1; } catch (NumberFormatException e) { sequenceNumber = 1; } } } String processPinyin = StringUtils.getProcessNo(processName); return StrUtil.format("{}{}",processPinyin,npsNo,String.format("%03d", sequenceNumber)); Integer maxNo = productWorkOrderMapper.selectMax(npsNo); int sequenceNumber = maxNo + 1; // é»è®¤åºå· String processPinyin = StringUtils.getProcessNo(processName); return StrUtil.format("{}{}", processPinyin, npsNo, String.format("%03d", sequenceNumber)); } } src/main/java/com/ruoyi/production/service/impl/ProductionPrintOrderServiceImpl.java
@@ -2,11 +2,17 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.basic.excel.ProductionPrintOrderExcel; import com.ruoyi.basic.service.CustomerFollowUpFileService; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.dto.SimplePersonDto; import com.ruoyi.production.dto.*; import com.ruoyi.production.mapper.ProductOrderMapper; @@ -15,9 +21,11 @@ import com.ruoyi.production.pojo.ProductionPrintOrder; import com.ruoyi.production.service.ProductionPrintOrderService; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.Nullable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -36,6 +44,7 @@ private final ProductOrderMapper productOrderMapper; private final ProcessRouteServiceImpl processRouteService; private final ProductionPrintOrderExcel productionPrintOrderExcel; private final CustomerFollowUpFileService customerFollowUpFileService; @Override @@ -58,7 +67,7 @@ pdto.setProcessRouteName(it.getProcessName()); pdto.setProcessRouteOpenNum(it.getOpenCount()); pdto.setProcessRouteNum(it.getProcessPositive()); pdto.setProcessRouteAddNum(it.getProcessPositive()); pdto.setProcessRouteAddNum(it.getAllowanceQty()); // pdto.setProcessRouteRequire(); å·¥èºè¦æ± pdto.setProductModelId(Long.valueOf(materialInfoDtoFirst.getProductModelId())); pdto.setUserIds(it.getReportWorkerList().stream().map(SimplePersonDto::getUserId).map(String::valueOf).collect(Collectors.joining(","))); @@ -111,6 +120,46 @@ map -> new ArrayList<>(map.values()) )); } @Override public void exportPrintExcelByWordId(@Nullable Long orderId) { ProductionPrintOrderDto printOrderDto = this.getByProductWordId(orderId); List<MaterialInfoDto> materialInfo = printOrderDto.getMaterialInfo(); Assert.isTrue(CollUtil.isNotEmpty(materialInfo),"æªæææä¿¡æ¯ï¼è¯·æ·»å æ¹ä¿¡æ¯!"); MaterialInfoDto materialInfoDto = materialInfo.get(0); ExportProductionPrintOrderDto exportProductionPrintOrderDto = BeanUtil.copyProperties(printOrderDto, ExportProductionPrintOrderDto.class); exportProductionPrintOrderDto.setNumSuffix(materialInfoDto.getNumSuffix()); exportProductionPrintOrderDto.setUnitSuffix(materialInfoDto.getUnitSuffix()); exportProductionPrintOrderDto.setPriceSuffix(materialInfoDto.getPriceSuffix()); StringUtils.fillStringNull(exportProductionPrintOrderDto); // æ¥æä¿®æ£ä¸º yyyyå¹´ MM æ mm æ¥ exportProductionPrintOrderDto.setPrintOrderTimeStr(DateUtil.format(exportProductionPrintOrderDto.getPrintOrderTime(),"yyyyå¹´ MM æ mm æ¥")); exportProductionPrintOrderDto.setFinishTimeStr(DateUtil.format(exportProductionPrintOrderDto.getFinishTime(),"yyyyå¹´ MM æ mm æ¥")); // ä»ç»ä¿¡ å¾éæ¡ String introductionLetter = exportProductionPrintOrderDto.getIntroductionLetter(); List<String> introductionLetterItem = StrUtil.split(introductionLetter, ","); exportProductionPrintOrderDto.setIntroductionLetter1(introductionLetterItem.contains("ä»ç»ä¿¡")?"R" : "£"); exportProductionPrintOrderDto.setIntroductionLetter2(introductionLetterItem.contains("åæ æ³¨å")?"R" : "£"); exportProductionPrintOrderDto.setIntroductionLetter3(introductionLetterItem.contains("å§å°å")?"R" : "£"); exportProductionPrintOrderDto.setIntroductionLetter4(introductionLetterItem.contains("书å·")?"R" : "£"); // åæå¾ç¤º exportProductionPrintOrderDto.setCuttingDiagramCheckout1("å¹³å¼ ".equals(exportProductionPrintOrderDto.getCuttingDiagramCheckout())?"R" : "£"); exportProductionPrintOrderDto.setCuttingDiagramCheckout2("å·ç".equals(exportProductionPrintOrderDto.getCuttingDiagramCheckout())?"R" : "£"); // 读åå¾çä¿¡æ¯ if(exportProductionPrintOrderDto.getCuttingFileVo() != null){ byte[] bytes = FileUtil.readBytes(exportProductionPrintOrderDto.getCuttingFileVo().getFileUrl()); exportProductionPrintOrderDto.setCuttingImage(bytes); } productionPrintOrderExcel.createPrintOrderTemplate(exportProductionPrintOrderDto, IoUtil.toStream(new File("/Users/ONEX/Downloads/printOrderTemp.xlsx"))); } } src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
@@ -118,7 +118,7 @@ productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId()); productWorkOrder.setProductOrderId(order.getId()); productWorkOrder.setPlanQuantity(order.getQuantity()); productWorkOrder.setWorkOrderNo("FG"+productWorkOrderService.generateProductWorkOrder(null, productProcessMap.getOrDefault(productProcessRouteItem.getProcessId(), new ProductProcess()).getName(), productOrder.getNpsNo())); productWorkOrder.setWorkOrderNo("FG"+productWorkOrderService.generateProductWorkOrder( productProcessMap.getOrDefault(productProcessRouteItem.getProcessId(), new ProductProcess()).getName(), productOrder.getNpsNo())); productWorkOrder.setStatus(1); productWorkOrderMapper.insert(productWorkOrder); } src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -308,7 +308,7 @@ productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId()); productWorkOrder.setProductOrderId(productOrder.getId()); productWorkOrder.setPlanQuantity(salesLedgerProduct.getQuantity()); productWorkOrder.setWorkOrderNo(productWorkOrderService.generateProductWorkOrder(null, productProcessMap.getOrDefault(productProcessRouteItem.getProcessId(),new ProductProcess()).getName(), productOrder.getNpsNo())); productWorkOrder.setWorkOrderNo(productWorkOrderService.generateProductWorkOrder( productProcessMap.getOrDefault(productProcessRouteItem.getProcessId(),new ProductProcess()).getName(), productOrder.getNpsNo())); productWorkOrder.setStatus(1); productWorkOrderMapper.insert(productWorkOrder); src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -28,6 +28,7 @@ sl.delivery_date, sl.actually_delivery_date, sl.execution_date, t6.id as print_id, CASE WHEN shipping_status_counts.total_count = 0 THEN false WHEN shipping_status_counts.unshipped_count = 0 THEN true @@ -47,6 +48,7 @@ left join sales_ledger_product slp on po.sale_ledger_product_id = slp.id and slp.type = 1 left join product_process_route ppr on po.id = ppr.product_order_id left join product_bom pb on pb.id = ppr.bom_id left join production_print_order as t6 on t6.product_order_id = po.id <where> <if test="c.npsNo != null and c.npsNo != ''"> and po.nps_no like concat('%',#{c.npsNo},'%') src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -92,12 +92,9 @@ actual_start_time >= #{startDate} AND actual_start_time <= #{endDate} </select> <select id="selectMax" resultType="com.ruoyi.production.pojo.ProductWorkOrder"> SELECT SUBSTRING(work_order_no, 3) as work_order_no <select id="selectMax" resultType="java.lang.Integer"> SELECT count(1) FROM product_work_order WHERE SUBSTRING(work_order_no, 3) like concat(#{datePrefix},'%') order by work_order_no desc limit 1 ; WHERE SUBSTRING(work_order_no, 3) like concat('%',#{datePrefix},'%') </select> </mapper>