From 1e123568c2f561013f5636e45dc0db30b17a3517 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 10 九月 2026 16:39:26 +0800
Subject: [PATCH] feat(basic): 添加产品条码功能并完善生产统计报表

---
 src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java |   68 ++++++++++++++++++++++++++++++++++
 1 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java
index 51e5441..50d8f4a 100644
--- a/src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java
+++ b/src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java
@@ -18,8 +18,11 @@
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.sales.dto.LossProductModelDto;
 import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import com.ruoyi.technology.mapper.TechnologyBomMapper;
+import com.ruoyi.technology.pojo.TechnologyBom;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -27,6 +30,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -43,15 +47,19 @@
 
     private final ProductMapper productMapper;
     private final SalesLedgerProductMapper salesLedgerProductMapper;
+    private final TechnologyBomMapper technologyBomMapper;
     private ProductModelMapper productModelMapper;
 
     @Override
     public int addOrEditProductModel(ProductModelDto productModelDto) {
         String model = StringUtils.trim(productModelDto.getModel());
         String productCode = StringUtils.trim(productModelDto.getProductCode());
+        String barcode = StringUtils.trim(productModelDto.getBarcode());
         productModelDto.setModel(model);
         productModelDto.setProductCode(productCode);
+        productModelDto.setBarcode(barcode);
         checkModelAndProductCodeUnique(model, productCode, productModelDto.getId());
+        checkBarcodeUnique(barcode, productModelDto.getId());
 
         if (productModelDto.getId() == null) {
             ProductModel productModel = new ProductModel();
@@ -77,6 +85,19 @@
         }
     }
 
+    private void checkBarcodeUnique(String barcode, Long currentId) {
+        if (StringUtils.isEmpty(barcode)) {
+            return;
+        }
+        LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(ProductModel::getBarcode, barcode)
+                .ne(currentId != null, ProductModel::getId, currentId)
+                .last("limit 1");
+        if (productModelMapper.selectOne(queryWrapper) != null) {
+            throw new ServiceException("鏉″舰鐮�" + barcode + "宸茬粡瀛樺湪");
+        }
+    }
+
 
     @Override
     public int delProductModel(Long[] ids) {
@@ -86,6 +107,14 @@
 
             throw new RuntimeException("宸茬粡瀛樺湪璇ヤ骇鍝佺殑閿�鍞彴璐﹀拰閲囪喘鍙拌处");
         }
+
+        // 鏄惁瀛樺湪BOM
+        List<TechnologyBom> technologyBoms = technologyBomMapper.selectList(new QueryWrapper<TechnologyBom>()
+                .lambda().in(TechnologyBom::getProductModelId, ids));
+        if (CollectionUtils.isNotEmpty(technologyBoms)) {
+            throw new RuntimeException("宸茬粡瀛樺湪璇ヤ骇鍝佺殑BOM鏁版嵁");
+        }
+
         return productModelMapper.deleteBatchIds(Arrays.asList(ids));
     }
 
@@ -134,6 +163,17 @@
             List<ProductModel> existingModels = list(new LambdaQueryWrapper<ProductModel>().eq(ProductModel::getProductId, productId));
             Set<String> existingModelNames = existingModels.stream().map(ProductModel::getModel).collect(Collectors.toSet());
 
+            //  宸插瓨鍦ㄤ簬鏁版嵁搴撲腑鐨勬潯鐮侊紙鍏ㄥ眬鏌ラ噸锛�
+            List<String> importBarcodes = productModelList.stream()
+                    .map(item -> StringUtils.trim(item.getBarcode()))
+                    .filter(StringUtils::isNotEmpty)
+                    .distinct()
+                    .collect(Collectors.toList());
+            Set<String> dbBarcodeSet = importBarcodes.isEmpty() ? new HashSet<>()
+                    : list(new LambdaQueryWrapper<ProductModel>().in(ProductModel::getBarcode, importBarcodes))
+                    .stream().map(ProductModel::getBarcode).collect(Collectors.toSet());
+            Set<String> fileBarcodes = new HashSet<>();
+
             List<ProductModel> waitToSaveList = new ArrayList<>();
             int skipCount = 0;
 
@@ -149,6 +189,16 @@
                 }
                 if (StringUtils.isEmpty(item.getUnit())) {
                     return AjaxResult.error("绗� " + rowNum + " 琛屽鍏ュけ璐�: [鍗曚綅] 涓嶈兘涓虹┖");
+                }
+
+                item.setBarcode(StringUtils.trim(item.getBarcode()));
+                if (StringUtils.isNotEmpty(item.getBarcode())) {
+                    if (!fileBarcodes.add(item.getBarcode())) {
+                        return AjaxResult.error("绗� " + rowNum + " 琛屽鍏ュけ璐�: 鏉″舰鐮� " + item.getBarcode() + " 鍦ㄦ枃浠朵腑閲嶅");
+                    }
+                    if (dbBarcodeSet.contains(item.getBarcode())) {
+                        return AjaxResult.error("绗� " + rowNum + " 琛屽鍏ュけ璐�: 鏉″舰鐮� " + item.getBarcode() + " 宸插瓨鍦�");
+                    }
                 }
 
                 //  鍘婚噸,濡傛灉宸插寘鍚鍨嬪彿,鍒欒烦杩�
@@ -177,4 +227,22 @@
             throw new ServiceException("瀵煎叆澶辫触");
         }
     }
+
+    @Override
+    public ProductModel selectByBarcode(String barcode) {
+        if (StringUtils.isEmpty(barcode)) {
+            return null;
+        }
+        LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(ProductModel::getBarcode, StringUtils.trim(barcode))
+                .last("limit 1");
+        ProductModel productModel = productModelMapper.selectOne(queryWrapper);
+        if (productModel != null && productModel.getProductId() != null) {
+            Product product = productMapper.selectById(productModel.getProductId());
+            if (product != null) {
+                productModel.setProductName(product.getProductName());
+            }
+        }
+        return productModel;
+    }
 }

--
Gitblit v1.9.3