From 2cf52f66f3e7ffd415dbf49eb74aed441871f3a4 Mon Sep 17 00:00:00 2001
From: maven <2163098428@qq.com>
Date: 星期五, 23 一月 2026 17:52:21 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New' into dev_New

---
 src/main/java/com/ruoyi/stock/controller/StockUninventoryController.java         |    8 
 src/main/java/com/ruoyi/stock/service/StockInventoryService.java                 |    6 
 src/main/java/com/ruoyi/stock/mapper/StockOutRecordMapper.java                   |    5 
 src/main/java/com/ruoyi/stock/execl/StockInRecordExportData.java                 |   32 ++
 src/main/java/com/ruoyi/production/pojo/ProductStructure.java                    |    5 
 src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java                       |    3 
 src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java |  152 ++++++++++-
 src/main/java/com/ruoyi/common/enums/StockUnQualifiedRecordTypeEnum.java         |   16 
 src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java                  |    8 
 src/main/java/com/ruoyi/stock/service/StockInRecordService.java                  |    2 
 src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java         |   21 +
 src/main/java/com/ruoyi/stock/controller/StockInRecordController.java            |    8 
 src/main/resources/mapper/sales/SalesLedgerProductMapper.xml                     |   16 +
 src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java           |   10 
 src/main/java/com/ruoyi/stock/mapper/StockInRecordMapper.java                    |    5 
 src/main/resources/mapper/stock/StockUninventoryMapper.xml                       |   13 +
 src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java       |   14 
 src/main/java/com/ruoyi/stock/service/StockUninventoryService.java               |    4 
 src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java        |   49 ++-
 src/main/resources/mapper/stock/StockOutRecordMapper.xml                         |   27 ++
 src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java       |   45 +++
 src/main/resources/mapper/stock/StockInventoryMapper.xml                         |   15 +
 src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java        |   21 +
 src/main/java/com/ruoyi/stock/mapper/StockUninventoryMapper.java                 |    5 
 src/main/resources/mapper/stock/StockInRecordMapper.xml                          |   29 ++
 src/main/java/com/ruoyi/stock/controller/StockInventoryController.java           |   24 +
 src/main/java/com/ruoyi/stock/execl/StockOutRecordExportData.java                |   31 ++
 src/main/java/com/ruoyi/stock/service/StockOutRecordService.java                 |    3 
 src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java                |   33 ++
 src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java                   |    6 
 src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java      |   12 +
 src/main/java/com/ruoyi/common/utils/EnumUtil.java                               |    6 
 src/main/java/com/ruoyi/common/enums/StockQualifiedRecordTypeEnum.java           |   24 -
 src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java               |    2 
 src/main/java/com/ruoyi/production/dto/ProductStructureDto.java                  |   14 +
 35 files changed, 588 insertions(+), 86 deletions(-)

diff --git a/src/main/java/com/ruoyi/common/enums/StockQualifiedRecordTypeEnum.java b/src/main/java/com/ruoyi/common/enums/StockQualifiedRecordTypeEnum.java
index e880782..8c3c2b1 100644
--- a/src/main/java/com/ruoyi/common/enums/StockQualifiedRecordTypeEnum.java
+++ b/src/main/java/com/ruoyi/common/enums/StockQualifiedRecordTypeEnum.java
@@ -4,22 +4,20 @@
 
 
 @Getter
-public enum StockQualifiedRecordTypeEnum implements BaseEnum<Integer> {
-    CUSTOMIZATION_STOCK_IN(0, "鍚堟牸鑷畾涔夊叆搴�"),
-    CUSTOMIZATION_STOCK_OUT(1, "鍚堟牸鑷畾涔夊嚭搴�"),
-    PRODUCTION_REPORT_STOCK_IN(2, "鐢熶骇鎶ュ伐-鍏ュ簱"),
-    PRODUCTION_REPORT_STOCK_OUT(3, "鐢熶骇鎶ュ伐-鍑哄簱"),
-    DEFECTIVE_PASS(6, "涓嶅悎鏍煎鐞�-璁╂鏀捐"),
-    PURCHASE_STOCK_IN(7, "閲囪喘-鍏ュ簱"),
-    SALE_STOCK_OUT(8, "閿�鍞�-鍑哄簱"),
-    QUALITYINSPECT_STOCK_IN(11, "璐ㄦ-鍚堟牸鍏ュ簱");
+public enum StockQualifiedRecordTypeEnum implements BaseEnum<String> {
+    CUSTOMIZATION_STOCK_IN("0", "鍚堟牸鑷畾涔夊叆搴�"),
+    CUSTOMIZATION_STOCK_OUT("1", "鍚堟牸鑷畾涔夊嚭搴�"),
+    PRODUCTION_REPORT_STOCK_IN("2", "鐢熶骇鎶ュ伐-鍏ュ簱"),
+    PRODUCTION_REPORT_STOCK_OUT("3", "鐢熶骇鎶ュ伐-鍑哄簱"),
+    DEFECTIVE_PASS("6", "涓嶅悎鏍煎鐞�-璁╂鏀捐"),
+    PURCHASE_STOCK_IN("7", "閲囪喘-鍏ュ簱"),
+    SALE_STOCK_OUT("8", "閿�鍞�-鍑哄簱"),
+    QUALITYINSPECT_STOCK_IN("11", "璐ㄦ-鍚堟牸鍏ュ簱");
 
-
-
-    private final Integer code;
+    private final String code;
     private final String value;
 
-    StockQualifiedRecordTypeEnum(Integer code, String value) {
+    StockQualifiedRecordTypeEnum(String code, String value) {
         this.code = code;
         this.value = value;
     }
diff --git a/src/main/java/com/ruoyi/common/enums/StockUnQualifiedRecordTypeEnum.java b/src/main/java/com/ruoyi/common/enums/StockUnQualifiedRecordTypeEnum.java
index 753c6e5..8a39c56 100644
--- a/src/main/java/com/ruoyi/common/enums/StockUnQualifiedRecordTypeEnum.java
+++ b/src/main/java/com/ruoyi/common/enums/StockUnQualifiedRecordTypeEnum.java
@@ -4,20 +4,20 @@
 
 
 @Getter
-public enum StockUnQualifiedRecordTypeEnum implements BaseEnum<Integer> {
+public enum StockUnQualifiedRecordTypeEnum implements BaseEnum<String> {
 
 
-    PRODUCTION_SCRAP(4, "鐢熶骇鎶ュ伐-鎶ュ簾"),
-    DEFECTIVE_SCRAP(5, "涓嶅悎鏍煎鐞�-鎶ュ簾"),
-    CUSTOMIZATION_UNSTOCK_IN(9, "涓嶅悎鏍艰嚜瀹氫箟鍏ュ簱"),
-    CUSTOMIZATION_UNSTOCK_OUT(10, "涓嶅悎鏍艰嚜瀹氫箟鍑哄簱"),
-    QUALITYINSPECT_UNSTOCK_IN(12, "璐ㄦ-涓嶅悎鏍煎叆搴�");
+    PRODUCTION_SCRAP("4", "鐢熶骇鎶ュ伐-鎶ュ簾"),
+    DEFECTIVE_SCRAP("5", "涓嶅悎鏍煎鐞�-鎶ュ簾"),
+    CUSTOMIZATION_UNSTOCK_IN("9", "涓嶅悎鏍艰嚜瀹氫箟鍏ュ簱"),
+    CUSTOMIZATION_UNSTOCK_OUT("10", "涓嶅悎鏍艰嚜瀹氫箟鍑哄簱"),
+    QUALITYINSPECT_UNSTOCK_IN("12", "璐ㄦ-涓嶅悎鏍煎叆搴�");
 
 
-    private final Integer code;
+    private final String code;
     private final String value;
 
-    StockUnQualifiedRecordTypeEnum(Integer code, String value) {
+    StockUnQualifiedRecordTypeEnum(String code, String value) {
         this.code = code;
         this.value = value;
     }
diff --git a/src/main/java/com/ruoyi/common/utils/EnumUtil.java b/src/main/java/com/ruoyi/common/utils/EnumUtil.java
index 8fd3224..931fd1c 100644
--- a/src/main/java/com/ruoyi/common/utils/EnumUtil.java
+++ b/src/main/java/com/ruoyi/common/utils/EnumUtil.java
@@ -19,7 +19,7 @@
      */
     public static <E extends Enum<E> & BaseEnum> E fromCode(Class<E> enumClass, int code) {
         for (E e : enumClass.getEnumConstants()) {
-            if ((int)e.getCode() == code) {
+            if (Integer.parseInt(String.valueOf(e.getCode())) == code) {
                 return e;
             }
         }
@@ -28,7 +28,7 @@
 
     public static <E extends Enum<E> & BaseEnum> E fromCodeHasNull(Class<E> enumClass, int code) {
         for (E e : enumClass.getEnumConstants()) {
-            if ((int)e.getCode() == code) {
+            if (Integer.parseInt(String.valueOf(e.getCode())) == code) {
                 return e;
             }
         }
@@ -37,7 +37,7 @@
 
     public static <E extends Enum<E> & BaseEnum> E fromCodeHasDefault(Class<E> enumClass, int code,E defaultE) {
         for (E e : enumClass.getEnumConstants()) {
-            if ((int)e.getCode() == code) {
+            if (Integer.parseInt(String.valueOf(e.getCode())) == code) {
                 return e;
             }
         }
diff --git a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
index f9a21d6..2ae9406 100644
--- a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
+++ b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -50,7 +50,7 @@
      * @param recordType
      * @param recordId
      */
-    public void addUnStock(Long productModelId, BigDecimal quantity, Integer recordType,Long recordId) {
+    public void addUnStock(Long productModelId, BigDecimal quantity, String recordType,Long recordId) {
         StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
         stockUninventoryDto.setRecordId(recordId);
         stockUninventoryDto.setRecordType(String.valueOf(recordType));
@@ -82,7 +82,7 @@
      * @param recordType
      * @param recordId
      */
-    public void addStock(Long productModelId, BigDecimal quantity, Integer recordType,Long recordId) {
+    public void addStock(Long productModelId, BigDecimal quantity, String recordType,Long recordId) {
         StockInventoryDto stockInventoryDto = new StockInventoryDto();
         stockInventoryDto.setRecordId(recordId);
         stockInventoryDto.setRecordType(String.valueOf(recordType));
@@ -98,7 +98,7 @@
      * @param recordType
      * @param recordId
      */
-    public void substractStock(Long productModelId, BigDecimal quantity, Integer recordType,Long recordId) {
+    public void substractStock(Long productModelId, BigDecimal quantity, String recordType,Long recordId) {
         StockInventoryDto stockInventoryDto = new StockInventoryDto();
         stockInventoryDto.setRecordId(recordId);
         stockInventoryDto.setRecordType(String.valueOf(recordType));
@@ -108,7 +108,7 @@
     }
 
     //涓嶅悎鏍煎簱瀛樺垹闄�
-    public void deleteStockRecord(Long recordId, Integer recordType) {
+    public void deleteStockRecord(Long recordId, String recordType) {
         StockInRecord one = stockInRecordService.getOne(new QueryWrapper<StockInRecord>()
                 .lambda().eq(StockInRecord::getRecordId, recordId)
                 .eq(StockInRecord::getRecordType, recordType));
diff --git a/src/main/java/com/ruoyi/production/dto/ProductStructureDto.java b/src/main/java/com/ruoyi/production/dto/ProductStructureDto.java
index 24b783c..ec43eef 100644
--- a/src/main/java/com/ruoyi/production/dto/ProductStructureDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProductStructureDto.java
@@ -1,22 +1,34 @@
 package com.ruoyi.production.dto;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.ruoyi.production.pojo.ProductStructure;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 import java.util.List;
 
 @Data
+@EqualsAndHashCode(callSuper = true)
 public class ProductStructureDto extends ProductStructure {
 
     @ApiModelProperty(value = "宸ヨ壓鍚嶇О")
     private String processName;
+
     @ApiModelProperty(value = "浜у搧鍚嶇О")
     private String productName;
+
     @ApiModelProperty(value = "浜у搧id")
     private Long productId;
 
     private String model;
 
-    private List<ProductStructure> productStructureList;
+    @TableField(exist = false)
+    private String tempId;
+
+    @TableField(exist = false)
+    private String parentTempId;
+
+    @TableField(exist = false)
+    private List<ProductStructureDto> children;
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductStructure.java b/src/main/java/com/ruoyi/production/pojo/ProductStructure.java
index de0d605..34a3ee3 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductStructure.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductStructure.java
@@ -52,5 +52,8 @@
      */
     private Long bomId;
 
-
+    /**
+     * 鐖惰妭鐐笽D
+     */
+    private Long parentId;
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
index d519593..06d4d09 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
@@ -1,19 +1,23 @@
 package com.ruoyi.production.service.impl;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.basic.pojo.ProductModel;
+import com.ruoyi.basic.service.IProductModelService;
+import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.production.dto.ProductBomDto;
-import com.ruoyi.production.dto.ProductProcessDto;
-import com.ruoyi.production.pojo.ProductBom;
 import com.ruoyi.production.mapper.ProductBomMapper;
-import com.ruoyi.production.pojo.ProductProcess;
+import com.ruoyi.production.mapper.ProductStructureMapper;
+import com.ruoyi.production.pojo.ProductBom;
+import com.ruoyi.production.pojo.ProductStructure;
 import com.ruoyi.production.service.ProductBomService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
 
 /**
  * <p>
@@ -29,12 +33,19 @@
     @Autowired
     private ProductBomMapper productBomMapper;
 
+    @Autowired
+    private IProductModelService productModelService;
+
+    @Autowired
+    private ProductStructureMapper productStructureMapper;
+
     @Override
     public IPage<ProductBomDto> listPage(Page page, ProductBomDto productBomDto) {
-        return productBomMapper.listPage(page,productBomDto);
+        return productBomMapper.listPage(page, productBomDto);
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public AjaxResult add(ProductBom productBom) {
         boolean save = productBomMapper.insert(productBom) > 0;
         if (save) {
@@ -42,6 +53,26 @@
             String no = "BM." + String.format("%05d", productBom.getId());
             productBom.setBomNo(no);
             productBomMapper.updateById(productBom);
+
+            //  鏌ヨ鍑轰骇鍝佹ā鍨嬩俊鎭�
+            if (productBom.getProductModelId() == null) {
+                throw new ServiceException("璇烽�夋嫨浜у搧妯″瀷");
+            }
+
+            ProductModel productModel = productModelService.getById(productBom.getProductModelId());
+            if (productModel == null) {
+                throw new ServiceException("閫夋嫨鐨勪骇鍝佹ā鍨嬩笉瀛樺湪");
+            }
+
+            //  娣诲姞鍒濆鐨勪骇鍝佺粨鏋�
+            ProductStructure productStructure = new ProductStructure();
+            productStructure.setProductModelId(productBom.getProductModelId());
+            productStructure.setUnit(productModel.getUnit());
+            productStructure.setUnitQuantity(BigDecimal.valueOf(1));
+            productStructure.setBomId(Long.valueOf(productBom.getId()));
+
+            productStructureMapper.insert(productStructure);
+
             return AjaxResult.success();
         }
         return AjaxResult.error();
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java
index 310a723..6b43c18 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java
@@ -1,51 +1,157 @@
 package com.ruoyi.production.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ruoyi.basic.dto.ProductModelDto;
-import com.ruoyi.basic.dto.ProductTreeDto;
-import com.ruoyi.basic.mapper.ProductMapper;
-import com.ruoyi.basic.mapper.ProductModelMapper;
-import com.ruoyi.basic.pojo.Product;
-import com.ruoyi.basic.pojo.ProductModel;
 import com.ruoyi.production.dto.ProductStructureDto;
-import com.ruoyi.production.mapper.ProductBomMapper;
 import com.ruoyi.production.mapper.ProductStructureMapper;
 import com.ruoyi.production.pojo.ProductStructure;
 import com.ruoyi.production.service.ProductStructureService;
-import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
-@Service
-@RequiredArgsConstructor
 @Slf4j
+@Service
 public class ProductStructureServiceImpl extends ServiceImpl<ProductStructureMapper, ProductStructure> implements ProductStructureService {
 
     @Autowired
-    private  ProductStructureMapper productStructureMapper;
-
+    private ProductStructureMapper productStructureMapper;
 
 
     @Override
-    public Boolean addProductStructureDto(ProductStructureDto productStructureDto) {
-        this.remove(new QueryWrapper<ProductStructure>().lambda().eq(ProductStructure::getBomId, productStructureDto.getBomId()));
-        productStructureDto.getProductStructureList().forEach(productStructure -> {
-            productStructure.setBomId(productStructureDto.getBomId());
-        });
-        return this.saveBatch(productStructureDto.getProductStructureList());
+    @Transactional
+    public Boolean addProductStructureDto(ProductStructureDto dto) {
+
+        Long bomId = dto.getBomId();
+
+        //  灏嗘爲鎵佸钩鍖�
+        List<ProductStructureDto> flatDtoList = new ArrayList<>();
+        flattenTree(dto.getChildren(), flatDtoList);
+
+        //  鏌ヨ鏁版嵁搴撲腑宸叉湁鐨� BOM 鏁版嵁
+        List<ProductStructure> dbList = this.list(new LambdaQueryWrapper<ProductStructure>().eq(ProductStructure::getBomId, bomId));
+
+        //  鏌ユ壘宸插瓨鍦ㄧ殑鑺傜偣 - ID
+        Set<Long> frontendIds = flatDtoList.stream()
+                .map(ProductStructureDto::getId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+        //  闇�瑕佸垹闄ょ殑鑺傜偣 - ID
+        Set<Long> deleteIds = dbList.stream()
+                .map(ProductStructure::getId)
+                .filter(id -> !frontendIds.contains(id))
+                .collect(Collectors.toSet());
+
+        if (!deleteIds.isEmpty()) {
+            this.removeByIds(deleteIds);
+        }
+
+        //  鏂板 / 鏇存柊
+        List<ProductStructure> insertList = new ArrayList<>();
+        List<ProductStructure> updateList = new ArrayList<>();
+
+        // 鐢ㄤ簬鍥炲啓 parentId
+        Map<String, ProductStructure> tempEntityMap = new HashMap<>();
+
+        for (ProductStructureDto psDto : flatDtoList) {
+            ProductStructure entity = new ProductStructure();
+            BeanUtils.copyProperties(psDto, entity);
+            entity.setBomId(bomId);
+
+            if (psDto.getId() == null) {
+                // 鏂板
+                entity.setId(null);
+                entity.setParentId(null);
+                insertList.add(entity);
+                tempEntityMap.put(psDto.getTempId(), entity);
+            } else {
+                // 鏇存柊
+                updateList.add(entity);
+            }
+        }
+
+        //  鎻掑叆鏂拌妭鐐�
+        if (!insertList.isEmpty()) {
+            this.saveBatch(insertList);
+        }
+
+        //  鍥炲啓鏂板鑺傜偣 parentId
+        List<ProductStructure> parentFixList = new ArrayList<>();
+        //  鐪熷疄鐨勭埗鑺傜偣 ID
+        Long realParentId;
+        for (ProductStructureDto psDto : flatDtoList) {
+            if (psDto.getId() == null && psDto.getParentTempId() != null) {
+                ProductStructure child = tempEntityMap.get(psDto.getTempId());
+                if (tempEntityMap.containsKey(psDto.getParentTempId())) {
+                    // 鐖惰妭鐐规槸鏂拌妭鐐�
+                    realParentId = tempEntityMap.get(psDto.getParentTempId()).getId();
+                } else {
+                    // 鐖惰妭鐐规槸鑰佽妭鐐�
+                    realParentId = Long.valueOf(psDto.getParentTempId());
+                }
+
+                child.setParentId(realParentId);
+                parentFixList.add(child);
+            }
+        }
+
+        if (!parentFixList.isEmpty()) {
+            this.updateBatchById(parentFixList);
+        }
+
+        if (!updateList.isEmpty()) {
+            this.updateBatchById(updateList);
+        }
+
+        return true;
     }
+
+    /**
+     * 灏嗗墠绔紶鍏ョ殑鏍戣繘琛屾墎骞冲寲
+     *
+     * @param source 鏁版嵁鏍�
+     * @param result 鎵佸钩鍖栨暟鎹�
+     */
+    private void flattenTree(List<ProductStructureDto> source, List<ProductStructureDto> result) {
+        if (source == null) {
+            return;
+        }
+        for (ProductStructureDto node : source) {
+            result.add(node);
+            flattenTree(node.getChildren(), result);
+        }
+    }
+
 
     @Override
     public List<ProductStructureDto> listBybomId(Long bomId) {
-        List<ProductStructureDto> tree = productStructureMapper.listBybomId(bomId);
-        return tree;
+        List<ProductStructureDto> list = productStructureMapper.listBybomId(bomId);
 
+        Map<Long, ProductStructureDto> map = new HashMap<>();
+        for (ProductStructureDto node : list) {
+            node.setChildren(new ArrayList<>());
+            map.put(node.getId(), node);
+        }
+
+        List<ProductStructureDto> tree = new ArrayList<>();
+        for (ProductStructureDto node : list) {
+            Long parentId = node.getParentId();
+            if (parentId == null || parentId == 0) {
+                tree.add(node);
+            } else {
+                ProductStructureDto parent = map.get(parentId);
+                if (parent != null) {
+                    parent.getChildren().add(node);
+                }
+            }
+        }
+        return tree;
     }
+
 }
diff --git a/src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java b/src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
index 79e6cb5..8632313 100644
--- a/src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
+++ b/src/main/java/com/ruoyi/sales/controller/SalesLedgerProductController.java
@@ -86,14 +86,16 @@
 //            procurementDto.setSalesLedgerProductId(item.getId());
 //            procurementDto.setProductCategory(item.getProductCategory());
 //            IPage<ProcurementPageDtoCopy> result = procurementRecordService.listPageCopyByProduction(new Page<>(1,-1), procurementDto);
-            BigDecimal stockQuantity = stockUtils.getStockQuantity(item.getProductModelId()).get("stockQuantity");
-            if(stockQuantity != null) {
+//            BigDecimal stockQuantity = stockUtils.getStockQuantity(item.getProductModelId()).get("stockQuantity");
+
 //                ProcurementPageDtoCopy procurementDtoCopy = result.getRecords().get(0);
-                if (item.getQuantity().compareTo(stockQuantity) <= 0 && item.getApproveStatus() == 0) {
-                    item.setApproveStatus(1);
-                    salesLedgerProductService.addOrUpdateSalesLedgerProduct(item);
+                if (item.getApproveStatus() != 2) {
+                    if (item.getHasSufficientStock() == 0) {
+                        item.setApproveStatus(0);
+                    }else {
+                        item.setApproveStatus(1);
+                    }
                 }
-            }
         });
         return AjaxResult.success(list);
     }
diff --git a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
index 514f6cd..9db21f5 100644
--- a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
+++ b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
@@ -20,6 +20,8 @@
  * @date 2025-05-08
  */
 public interface SalesLedgerProductMapper extends MyBaseMapper<SalesLedgerProduct> {
+     List<SalesLedgerProduct> selectProduct() ;
+
     List<SalesLedgerProduct> selectSalesLedgerProductList(@Param("salesLedgerProduct") SalesLedgerProduct salesLedgerProduct);
 
     SalesLedgerProduct selectSalesLedgerProductByMainId(@Param("productMainId") Long productMainId);
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
index 2a05597..3966071 100644
--- a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -224,4 +224,7 @@
 
     @ApiModelProperty(value = "鏄惁璐ㄦ")
     private Boolean isChecked;
+
+    @TableField(exist = false)
+    private Integer hasSufficientStock;
 }
diff --git a/src/main/java/com/ruoyi/stock/controller/StockInRecordController.java b/src/main/java/com/ruoyi/stock/controller/StockInRecordController.java
index c56c923..94e4669 100644
--- a/src/main/java/com/ruoyi/stock/controller/StockInRecordController.java
+++ b/src/main/java/com/ruoyi/stock/controller/StockInRecordController.java
@@ -6,6 +6,7 @@
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.stock.dto.StockInRecordDto;
+import com.ruoyi.stock.dto.StockInventoryDto;
 import com.ruoyi.stock.service.StockInRecordService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -13,6 +14,7 @@
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 @RestController
@@ -41,4 +43,10 @@
         return AjaxResult.success(stockInRecordService.batchDelete(ids));
     }
 
+    @PostMapping("/exportStockInRecord")
+    @ApiOperation("瀵煎嚭鍏ュ簱璁板綍")
+    public void exportStockInRecord(HttpServletResponse response, StockInRecordDto stockInRecordDto) {
+        stockInRecordService.exportStockInRecord(response,stockInRecordDto);
+    }
+
 }
diff --git a/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java b/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
index 445ac81..7807de1 100644
--- a/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
+++ b/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
@@ -3,14 +3,23 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.compensationperformance.pojo.CompensationPerformance;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.execl.StockInventoryExportData;
 import com.ruoyi.stock.service.StockInventoryService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * <p>
@@ -56,7 +65,20 @@
     @GetMapping("importStockInventory")
     @ApiOperation("瀵煎叆搴撳瓨")
     public R importStockInventory(MultipartFile  file) {
-        return R.ok(stockInventoryService.importStockInventory(file));
+        return stockInventoryService.importStockInventory(file);
+    }
 
+    @Log(title = "涓嬭浇搴撳瓨瀵煎叆妯℃澘", businessType = BusinessType.EXPORT)
+    @PostMapping("/downloadStockInventory")
+    public void downloadStockInventory(HttpServletResponse response) {
+        List<StockInventoryExportData> list = new ArrayList<>();
+        ExcelUtil<StockInventoryExportData> util = new ExcelUtil<>(StockInventoryExportData.class);
+        util.exportExcel(response, list, "搴撳瓨妯℃澘");
+    }
+
+    @PostMapping("/exportStockInventory")
+    @ApiOperation("瀵煎嚭搴撳瓨")
+    public void exportStockInventory(HttpServletResponse response,StockInventoryDto stockInventoryDto) {
+         stockInventoryService.exportStockInventory(response,stockInventoryDto);
     }
 }
diff --git a/src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java b/src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java
index df82379..755084c 100644
--- a/src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java
+++ b/src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java
@@ -5,7 +5,9 @@
 import com.ruoyi.framework.aspectj.lang.annotation.Log;
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.stock.dto.StockInRecordDto;
 import com.ruoyi.stock.dto.StockOutRecordDto;
+import com.ruoyi.stock.pojo.StockOutRecord;
 import com.ruoyi.stock.service.StockOutRecordService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -13,6 +15,7 @@
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -58,4 +61,11 @@
         }
         return AjaxResult.success(stockOutRecordService.batchDelete(ids));
     }
+
+    @PostMapping("/exportStockOutRecord")
+    @ApiOperation("瀵煎嚭鍑哄簱璁板綍")
+    public void exportStockOutRecord(HttpServletResponse response, StockOutRecordDto stockOutRecordDto) {
+        stockOutRecordService.exportStockOutRecord(response,stockOutRecordDto);
+    }
+
 }
diff --git a/src/main/java/com/ruoyi/stock/controller/StockUninventoryController.java b/src/main/java/com/ruoyi/stock/controller/StockUninventoryController.java
index e43604f..b2950db 100644
--- a/src/main/java/com/ruoyi/stock/controller/StockUninventoryController.java
+++ b/src/main/java/com/ruoyi/stock/controller/StockUninventoryController.java
@@ -11,6 +11,8 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletResponse;
+
 /**
  * <p>
  * 涓嶅悎鏍煎簱瀛樿〃 鍓嶇鎺у埗鍣�
@@ -49,4 +51,10 @@
         return R.ok(stockUninventoryService.subtractStockUninventory(stockUninventoryDto));
     }
 
+    @PostMapping("/exportStockUninventory")
+    @ApiOperation("瀵煎嚭搴撳瓨")
+    public void exportStockUninventory(HttpServletResponse response, StockUninventoryDto stockUninventoryDto) {
+        stockUninventoryService.exportStockUninventory(response,stockUninventoryDto);
+    }
+
 }
diff --git a/src/main/java/com/ruoyi/stock/execl/StockInRecordExportData.java b/src/main/java/com/ruoyi/stock/execl/StockInRecordExportData.java
new file mode 100644
index 0000000..d705110
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/execl/StockInRecordExportData.java
@@ -0,0 +1,32 @@
+package com.ruoyi.stock.execl;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+@Data
+public class StockInRecordExportData {
+
+    @Excel(name = "鍏ュ簱鎵规")
+    private String inboundBatches;
+    @Excel(name = "浜у搧鍚嶇О")
+    private String productName;
+    @Excel(name = "瑙勬牸鍨嬪彿")
+    private String model;
+    @Excel(name = "鍗曚綅")
+    private String unit;
+    @Excel(name = "鍏ュ簱鏉ユ簮")
+    private String recordType;
+    @Excel(name = "鍏ュ簱鏁伴噺")
+    private String stockInNum;
+    @Excel(name = "鍏ュ簱鏃堕棿")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    @Excel(isExport = false)
+    private String type;
+}
diff --git a/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java b/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java
index c917d30..e95ccf2 100644
--- a/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java
+++ b/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java
@@ -1,5 +1,38 @@
 package com.ruoyi.stock.execl;
 
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+@Data
 public class StockInventoryExportData {
 
+
+
+    @Excel(name = "浜у搧鍚嶇О")
+    private String productName;
+
+    @Excel(name = "瑙勬牸")
+    private String model;
+
+    @Excel(name = "鍗曚綅")
+    private String unit;
+
+    @Excel(name = "搴撳瓨鏁伴噺")
+    private BigDecimal qualitity;
+
+    @Excel(name = "澶囨敞")
+    private String remark;
+
+    @Excel(name = "鏈�鏂版洿鏂版椂闂�")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
 }
diff --git a/src/main/java/com/ruoyi/stock/execl/StockOutRecordExportData.java b/src/main/java/com/ruoyi/stock/execl/StockOutRecordExportData.java
new file mode 100644
index 0000000..f120817
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/execl/StockOutRecordExportData.java
@@ -0,0 +1,31 @@
+package com.ruoyi.stock.execl;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+@Data
+public class StockOutRecordExportData {
+    @Excel(name = "鍑哄簱鎵规")
+    private String outboundBatches;
+    @Excel(name = "浜у搧鍚嶇О")
+    private String productName;
+    @Excel(name = "瑙勬牸鍨嬪彿")
+    private String model;
+    @Excel(name = "鍗曚綅")
+    private String unit;
+    @Excel(name = "鍑哄簱鏉ユ簮")
+    private String recordType;
+    @Excel(name = "鍑哄簱鏁伴噺")
+    private String stockInNum;
+    @Excel(name = "鍑哄簱鏃堕棿")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    @Excel(isExport = false)
+    private String type;
+}
diff --git a/src/main/java/com/ruoyi/stock/mapper/StockInRecordMapper.java b/src/main/java/com/ruoyi/stock/mapper/StockInRecordMapper.java
index 8b7b543..afc30ae 100644
--- a/src/main/java/com/ruoyi/stock/mapper/StockInRecordMapper.java
+++ b/src/main/java/com/ruoyi/stock/mapper/StockInRecordMapper.java
@@ -4,9 +4,14 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.stock.dto.StockInRecordDto;
+import com.ruoyi.stock.execl.StockInRecordExportData;
 import com.ruoyi.stock.pojo.StockInRecord;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 public interface StockInRecordMapper extends BaseMapper<StockInRecord> {
     IPage<StockInRecordDto> listPage(Page page, @Param("params") StockInRecordDto stockInRecordDto);
+
+    List<StockInRecordExportData> listStockInRecordExportData(@Param("params") StockInRecordDto stockInRecordDto);
 }
diff --git a/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java b/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
index 3463cc3..fd14b37 100644
--- a/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
+++ b/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
@@ -3,10 +3,13 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.execl.StockInventoryExportData;
 import com.ruoyi.stock.pojo.StockInventory;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <p>
@@ -25,4 +28,7 @@
     int updateAddStockInventory(@Param("ew") StockInventoryDto stockInventoryDto);
 
     int updateSubtractStockInventory(@Param("ew") StockInventoryDto stockInventoryDto);
+
+    List<StockInventoryExportData> listStockInventoryExportData(@Param("ew") StockInventoryDto stockInventoryDto);
+
 }
diff --git a/src/main/java/com/ruoyi/stock/mapper/StockOutRecordMapper.java b/src/main/java/com/ruoyi/stock/mapper/StockOutRecordMapper.java
index 04aeb71..d180ef9 100644
--- a/src/main/java/com/ruoyi/stock/mapper/StockOutRecordMapper.java
+++ b/src/main/java/com/ruoyi/stock/mapper/StockOutRecordMapper.java
@@ -4,9 +4,12 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.stock.dto.StockOutRecordDto;
+import com.ruoyi.stock.execl.StockOutRecordExportData;
 import com.ruoyi.stock.pojo.StockOutRecord;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <p>
@@ -20,4 +23,6 @@
 public interface StockOutRecordMapper extends BaseMapper<StockOutRecord> {
     IPage<StockOutRecordDto> listPage(Page page, @Param("params") StockOutRecordDto stockOutRecordDto);
 
+    List<StockOutRecordExportData> listStockOutRecordExportData(@Param("params") StockOutRecordDto stockOutRecordDto);
+
 }
diff --git a/src/main/java/com/ruoyi/stock/mapper/StockUninventoryMapper.java b/src/main/java/com/ruoyi/stock/mapper/StockUninventoryMapper.java
index 64ecc2c..58ab250 100644
--- a/src/main/java/com/ruoyi/stock/mapper/StockUninventoryMapper.java
+++ b/src/main/java/com/ruoyi/stock/mapper/StockUninventoryMapper.java
@@ -3,10 +3,13 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.stock.dto.StockUninventoryDto;
+import com.ruoyi.stock.execl.StockInventoryExportData;
 import com.ruoyi.stock.pojo.StockUninventory;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <p>
@@ -24,4 +27,6 @@
     int updateSubtractStockUnInventory(StockUninventoryDto stockUninventoryDto);
 
     int updateAddStockUnInventory(StockUninventoryDto stockUninventoryDto);
+
+    List<StockInventoryExportData> listStockInventoryExportData(@Param("ew") StockUninventoryDto stockUninventoryDto);
 }
diff --git a/src/main/java/com/ruoyi/stock/service/StockInRecordService.java b/src/main/java/com/ruoyi/stock/service/StockInRecordService.java
index affb300..29ba7e5 100644
--- a/src/main/java/com/ruoyi/stock/service/StockInRecordService.java
+++ b/src/main/java/com/ruoyi/stock/service/StockInRecordService.java
@@ -6,6 +6,7 @@
 import com.ruoyi.stock.dto.StockInRecordDto;
 import com.ruoyi.stock.pojo.StockInRecord;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 public interface StockInRecordService extends IService<StockInRecord> {
@@ -17,4 +18,5 @@
 
     int batchDelete(List<Long> ids);
 
+    void exportStockInRecord(HttpServletResponse response, StockInRecordDto stockInRecordDto);
 }
diff --git a/src/main/java/com/ruoyi/stock/service/StockInventoryService.java b/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
index 0dc849c..37571f6 100644
--- a/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
+++ b/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
@@ -8,6 +8,8 @@
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletResponse;
+
 /**
  * <p>
  * 搴撳瓨琛� 鏈嶅姟绫�
@@ -24,5 +26,7 @@
 
     Boolean subtractStockInventory(StockInventoryDto stockInventoryDto);
 
-    Boolean importStockInventory(MultipartFile file);
+    R importStockInventory(MultipartFile file);
+
+    void exportStockInventory(HttpServletResponse response, StockInventoryDto stockInventoryDto);
 }
diff --git a/src/main/java/com/ruoyi/stock/service/StockOutRecordService.java b/src/main/java/com/ruoyi/stock/service/StockOutRecordService.java
index 6317e3a..f18d50c 100644
--- a/src/main/java/com/ruoyi/stock/service/StockOutRecordService.java
+++ b/src/main/java/com/ruoyi/stock/service/StockOutRecordService.java
@@ -6,6 +6,7 @@
 import com.ruoyi.stock.dto.StockOutRecordDto;
 import com.ruoyi.stock.pojo.StockOutRecord;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -24,4 +25,6 @@
     int update(Long id, StockOutRecordDto stockOutRecordDto);
 
     int batchDelete(List<Long> ids);
+
+    void exportStockOutRecord(HttpServletResponse response, StockOutRecordDto stockOutRecordDto);
 }
diff --git a/src/main/java/com/ruoyi/stock/service/StockUninventoryService.java b/src/main/java/com/ruoyi/stock/service/StockUninventoryService.java
index e4b8d83..7f435fa 100644
--- a/src/main/java/com/ruoyi/stock/service/StockUninventoryService.java
+++ b/src/main/java/com/ruoyi/stock/service/StockUninventoryService.java
@@ -6,6 +6,8 @@
 import com.ruoyi.stock.pojo.StockUninventory;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import javax.servlet.http.HttpServletResponse;
+
 /**
  * <p>
  * 涓嶅悎鏍煎簱瀛樿〃 鏈嶅姟绫�
@@ -21,4 +23,6 @@
     Integer addStockUninventory(StockUninventoryDto stockUninventoryDto);
 
     Integer subtractStockUninventory(StockUninventoryDto stockUninventoryDto);
+
+    void exportStockUninventory(HttpServletResponse response, StockUninventoryDto stockUninventoryDto);
 }
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
index 4cef388..e622dd7 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
@@ -4,13 +4,19 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum;
 import com.ruoyi.common.exception.base.BaseException;
+import com.ruoyi.common.utils.EnumUtil;
 import com.ruoyi.common.utils.OrderUtils;
 import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.staff.pojo.StaffOnJob;
 import com.ruoyi.stock.dto.StockInRecordDto;
 import com.ruoyi.stock.dto.StockInventoryDto;
 import com.ruoyi.stock.dto.StockUninventoryDto;
+import com.ruoyi.stock.execl.StockInRecordExportData;
+import com.ruoyi.stock.execl.StockInventoryExportData;
 import com.ruoyi.stock.mapper.StockInRecordMapper;
 import com.ruoyi.stock.mapper.StockInventoryMapper;
 import com.ruoyi.stock.mapper.StockUninventoryMapper;
@@ -23,6 +29,7 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 @Service
@@ -92,4 +99,18 @@
         }
         return stockInRecordMapper.deleteBatchIds(ids);
     }
+
+    @Override
+    public void exportStockInRecord(HttpServletResponse response, StockInRecordDto stockInRecordDto) {
+        List<StockInRecordExportData> list = stockInRecordMapper.listStockInRecordExportData(stockInRecordDto);
+        for (StockInRecordExportData stockInRecordExportData : list) {
+            if (stockInRecordExportData.getType().equals("0")) {
+                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
+            }else {
+                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockUnQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
+            }
+        }
+        ExcelUtil<StockInRecordExportData> util = new ExcelUtil<>(StockInRecordExportData.class);
+        util.exportExcel(response,list, "鍏ュ簱璁板綍淇℃伅");
+    }
 }
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
index d30e7bc..35e2f13 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -4,16 +4,16 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.basic.excel.SupplierManageExcelDto;
-import com.ruoyi.basic.pojo.SupplierManage;
-import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.account.pojo.BorrowInfo;
+import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.stock.dto.StockInRecordDto;
 import com.ruoyi.stock.dto.StockInventoryDto;
 import com.ruoyi.stock.dto.StockOutRecordDto;
 import com.ruoyi.stock.execl.StockInventoryExportData;
-import com.ruoyi.stock.pojo.StockInRecord;
 import com.ruoyi.stock.pojo.StockInventory;
 import com.ruoyi.stock.mapper.StockInventoryMapper;
 import com.ruoyi.stock.service.StockInRecordService;
@@ -21,14 +21,11 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.stock.service.StockOutRecordService;
 import lombok.AllArgsConstructor;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.time.LocalDate;
-import java.util.ArrayList;
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -46,7 +43,7 @@
     private  StockInventoryMapper stockInventoryMapper;
     private StockInRecordService stockInRecordService;
     private StockOutRecordService stockOutRecordService;
-
+    private SalesLedgerProductMapper salesLedgerProductMapper;
     @Override
     public IPage<StockInventoryDto> pagestockInventory(Page page, StockInventoryDto stockInventoryDto) {
         return stockInventoryMapper.pagestockInventory(page, stockInventoryDto);
@@ -102,20 +99,40 @@
     }
 
     @Override
-    public Boolean importStockInventory(MultipartFile file) {
+    public R importStockInventory(MultipartFile file) {
         try {
+            final StringBuffer[] errorMsg = {new StringBuffer()};
+            //鏌ヨ鎵�鏈夌殑浜у搧
+            List<SalesLedgerProduct> salesLedgerProducts =salesLedgerProductMapper.selectProduct();
+
             ExcelUtil<StockInventoryExportData> util = new ExcelUtil<StockInventoryExportData>(StockInventoryExportData.class);
             List<StockInventoryExportData> list = util.importExcel(file.getInputStream());
-            ArrayList<StockInventory> stockInventories = new ArrayList<>();
             list.stream().forEach(dto -> {
-               // TODO: 2026/1/21 娣诲姞鍏ュ簱璁板綍
+                salesLedgerProducts.stream().forEach(item->{
+                    if (item.getProductCategory().equals(dto.getProductName())&&item.getSpecificationModel().equals(dto.getModel())) {
+                            //鏇存柊搴撳瓨
+                        StockInventoryDto stockInventoryDto = new StockInventoryDto();
+                        stockInventoryDto.setRecordId(0L);
+                        stockInventoryDto.setRecordType(StockQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_IN.getCode());
+                        stockInventoryDto.setQualitity(dto.getQualitity());
+                        stockInventoryDto.setProductModelId(item.getProductModelId());
+                        this.addstockInventory(stockInventoryDto);                    }else {
+                        errorMsg[0] = errorMsg[0].append("浜у搧鍚嶇О锛�"+dto.getProductName()+"瑙勬牸锛�"+dto.getModel()+"涓嶅瓨鍦�").append("\n");
+                    }
+                });
             });
-
-            this.saveOrUpdateBatch(stockInventories);
-            return true;
+            return R.ok(errorMsg[0]);
         }catch (Exception e){
             e.printStackTrace();
         }
-        return false;
+        return R.fail();
+    }
+
+    @Override
+    public void exportStockInventory(HttpServletResponse response, StockInventoryDto stockInventoryDto) {
+
+        List<StockInventoryExportData> list = stockInventoryMapper.listStockInventoryExportData(stockInventoryDto);
+        ExcelUtil<StockInventoryExportData> util = new ExcelUtil<>(StockInventoryExportData.class);
+        util.exportExcel(response,list, "搴撳瓨淇℃伅");
     }
 }
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
index a9c48ed..76dc175 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
@@ -4,12 +4,18 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum;
 import com.ruoyi.common.exception.base.BaseException;
+import com.ruoyi.common.utils.EnumUtil;
 import com.ruoyi.common.utils.OrderUtils;
 import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.stock.dto.StockInventoryDto;
 import com.ruoyi.stock.dto.StockOutRecordDto;
 import com.ruoyi.stock.dto.StockUninventoryDto;
+import com.ruoyi.stock.execl.StockInRecordExportData;
+import com.ruoyi.stock.execl.StockOutRecordExportData;
 import com.ruoyi.stock.mapper.StockInventoryMapper;
 import com.ruoyi.stock.mapper.StockOutRecordMapper;
 import com.ruoyi.stock.mapper.StockUninventoryMapper;
@@ -22,6 +28,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -94,4 +101,18 @@
         }
         return stockOutRecordMapper.deleteBatchIds(ids);
     }
+
+    @Override
+    public void exportStockOutRecord(HttpServletResponse response, StockOutRecordDto stockOutRecordDto) {
+        List<StockOutRecordExportData> list = stockOutRecordMapper.listStockOutRecordExportData(stockOutRecordDto);
+        for (StockOutRecordExportData stockInRecordExportData : list) {
+            if (stockInRecordExportData.getType().equals("0")) {
+                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
+            }else {
+                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockUnQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
+            }
+        }
+        ExcelUtil<StockOutRecordExportData> util = new ExcelUtil<>(StockOutRecordExportData.class);
+        util.exportExcel(response,list, "鍑哄簱璁板綍淇℃伅");
+    }
 }
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
index c896821..fae9248 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
@@ -4,9 +4,11 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.stock.dto.StockInRecordDto;
 import com.ruoyi.stock.dto.StockOutRecordDto;
 import com.ruoyi.stock.dto.StockUninventoryDto;
+import com.ruoyi.stock.execl.StockInventoryExportData;
 import com.ruoyi.stock.pojo.StockInventory;
 import com.ruoyi.stock.pojo.StockUninventory;
 import com.ruoyi.stock.mapper.StockUninventoryMapper;
@@ -17,6 +19,9 @@
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
 
 /**
  * <p>
@@ -86,4 +91,11 @@
         }
         return 1;
     }
+
+    @Override
+    public void exportStockUninventory(HttpServletResponse response, StockUninventoryDto stockUninventoryDto) {
+        List<StockInventoryExportData> list = stockUninventoryMapper.listStockInventoryExportData(stockUninventoryDto);
+        ExcelUtil<StockInventoryExportData> util = new ExcelUtil<>(StockInventoryExportData.class);
+        util.exportExcel(response,list, "涓嶅悎鏍煎簱瀛樹俊鎭�");
+    }
 }
diff --git a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
index e432bc9..e27d27e 100644
--- a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -10,9 +10,15 @@
         t3.shipping_car_number,
         t3.shipping_date,
         t3.status as shippingStatus
+        t3.shipping_date,
+        CASE
+        WHEN t2.qualitity > T1.quantity THEN 1
+        ELSE 0
+        END as has_sufficient_stock
         FROM
         sales_ledger_product T1
-        left join shipping_info t3 on T1.id = t3.sales_ledger_product_id
+        LEFT JOIN stock_inventory t2 ON T1.product_model_id = t2.product_model_id
+        LEFT JOIN shipping_info t3 ON T1.id = t3.sales_ledger_product_id
         <where>
             1=1
             <if test="salesLedgerProduct.salesLedgerId != null and salesLedgerProduct.salesLedgerId != '' ">
@@ -148,4 +154,12 @@
               WHERE sl.id = #{salesLedegerId}) A
         group by a.model, a.product_name, a.unit
     </select>
+    <select id="selectProduct" resultType="com.ruoyi.sales.pojo.SalesLedgerProduct">
+        select
+            p.product_name as product_category,
+            pm.model as specification_model,
+            pm.id
+        from product_model pm
+        left join product p on pm.product_id = p.id
+    </select>
 </mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/stock/StockInRecordMapper.xml b/src/main/resources/mapper/stock/StockInRecordMapper.xml
index 0eee4f3..d5c3f38 100644
--- a/src/main/resources/mapper/stock/StockInRecordMapper.xml
+++ b/src/main/resources/mapper/stock/StockInRecordMapper.xml
@@ -5,7 +5,34 @@
     <select id="listPage" resultType="com.ruoyi.stock.dto.StockInRecordDto">
         SELECT
         sir.*,
-        p.product_name as productName,
+        p.product_name as product_name,
+        pm.model,
+        pm.unit,
+        u.nick_name as createBy
+        FROM stock_in_record as sir
+        LEFT JOIN product_model as pm on sir.product_model_id = pm.id
+        LEFT JOIN product as p on pm.product_id = p.id
+        LEFT JOIN sys_user as u on sir.create_user = u.user_id
+        <where>
+            <if test="params.timeStr != null and params.timeStr != ''">
+                and sir.create_time like concat('%',#{params.timeStr},'%')
+            </if>
+            <if test="params.productName != null and params.productName != ''">
+                and p.product_name like concat('%',#{params.productName},'%')
+            </if>
+            <if test="params.type != null and params.type != ''">
+                and sir.type = #{params.type}
+            </if>
+            <if test="params.recordType != null and params.recordType != ''">
+                and sir.record_type = #{params.recordType}
+            </if>
+        </where>
+        order by sir.id desc
+    </select>
+    <select id="listStockInRecordExportData" resultType="com.ruoyi.stock.execl.StockInRecordExportData">
+        SELECT
+        sir.*,
+        p.product_name as product_name,
         pm.model,
         pm.unit,
         u.nick_name as createBy
diff --git a/src/main/resources/mapper/stock/StockInventoryMapper.xml b/src/main/resources/mapper/stock/StockInventoryMapper.xml
index b39d329..1f729f2 100644
--- a/src/main/resources/mapper/stock/StockInventoryMapper.xml
+++ b/src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -58,5 +58,20 @@
             and p.product_name like concat('%',#{ew.productName},'%')
         </if>
     </select>
+    <select id="listStockInventoryExportData" resultType="com.ruoyi.stock.execl.StockInventoryExportData">
+        select si.qualitity,
+        pm.model,
+        pm.unit,
+        p.product_name,
+        si.remark,
+        si.update_time
+        from stock_inventory si
+        left join product_model pm on si.product_model_id = pm.id
+        left join product p on pm.product_id = p.id
+        where 1 = 1
+        <if test="ew.productName != null and ew.productName !=''">
+            and p.product_name like concat('%',#{ew.productName},'%')
+        </if>
+    </select>
 
 </mapper>
diff --git a/src/main/resources/mapper/stock/StockOutRecordMapper.xml b/src/main/resources/mapper/stock/StockOutRecordMapper.xml
index b021e71..a441de9 100644
--- a/src/main/resources/mapper/stock/StockOutRecordMapper.xml
+++ b/src/main/resources/mapper/stock/StockOutRecordMapper.xml
@@ -44,5 +44,32 @@
         </where>
         order by sor.id desc
     </select>
+    <select id="listStockOutRecordExportData" resultType="com.ruoyi.stock.execl.StockOutRecordExportData">
+        SELECT
+        sor.*,
+        p.product_name as productName,
+        pm.model,
+        pm.unit,
+        u.nick_name as createBy
+        FROM stock_out_record as sor
+        LEFT JOIN product_model as pm on sor.product_model_id = pm.id
+        LEFT JOIN product as p on pm.product_id = p.id
+        LEFT JOIN sys_user as u on sor.create_user = u.user_id
+        <where>
+            <if test="params.timeStr != null and params.timeStr != ''">
+                and sor.create_time like concat('%',#{params.timeStr},'%')
+            </if>
+            <if test="params.productName != null and params.productName != ''">
+                and p.product_name like concat('%',#{params.productName},'%')
+            </if>
+            <if test="params.type != null and params.type != ''">
+                and sor.type = #{params.type}
+            </if>
+            <if test="params.recordType != null and params.recordType != ''">
+                and sor.record_type = #{params.recordType}
+            </if>
+        </where>
+        order by sor.id desc
+    </select>
 
 </mapper>
diff --git a/src/main/resources/mapper/stock/StockUninventoryMapper.xml b/src/main/resources/mapper/stock/StockUninventoryMapper.xml
index 70b4471..2c0737f 100644
--- a/src/main/resources/mapper/stock/StockUninventoryMapper.xml
+++ b/src/main/resources/mapper/stock/StockUninventoryMapper.xml
@@ -56,5 +56,18 @@
             and p.product_name like concat('%',#{ew.productName},'%')
         </if>
     </select>
+    <select id="listStockInventoryExportData" resultType="com.ruoyi.stock.execl.StockInventoryExportData">
+        select su.*,
+        pm.model,
+        pm.unit,
+        p.product_name
+        from stock_uninventory su
+        left join product_model pm on su.product_model_id = pm.id
+        left join product p on pm.product_id = p.id
+        where 1 = 1
+        <if test="ew.productName != null and ew.productName !=''">
+            and p.product_name like concat('%',#{ew.productName},'%')
+        </if>
+    </select>
 
 </mapper>

--
Gitblit v1.9.3