From a0914318549b357ef3c438d0c2a3714f58ea3487 Mon Sep 17 00:00:00 2001
From: yaowanxin <3588231647@qq.com>
Date: 星期五, 23 一月 2026 14:14:50 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New' into dev_New

---
 src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java                       |  128 --
 src/main/java/com/ruoyi/stock/pojo/StockInventory.java                                            |   68 +
 src/main/java/com/ruoyi/stock/controller/StockUninventoryController.java                          |   52 +
 src/main/java/com/ruoyi/stock/dto/StockOutRecordDto.java                                          |   28 
 src/main/java/com/ruoyi/stock/service/StockInventoryService.java                                  |   28 
 src/main/java/com/ruoyi/stock/mapper/StockOutRecordMapper.java                                    |   23 
 src/main/java/com/ruoyi/approve/pojo/KnowledgeBase.java                                           |    2 
 src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java                |    1 
 src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java                                            |   74 +
 src/main/java/com/ruoyi/collaborativeApproval/controller/NoticeTypeController.java                |    2 
 src/main/java/com/ruoyi/common/enums/StockUnQualifiedRecordTypeEnum.java                          |   25 
 src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java                                   |   86 +
 src/main/java/com/ruoyi/production/controller/ProductStructureController.java                     |    4 
 src/main/java/com/ruoyi/stock/service/StockInRecordService.java                                   |   20 
 src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java                          |   95 +
 src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java                                    |    4 
 src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java                             |   17 
 src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java                             |    5 
 src/main/resources/mapper/sales/SalesLedgerProductMapper.xml                                      |   51 
 src/main/java/com/ruoyi/device/controller/DeviceDefectRecordController.java                       |   12 
 src/main/resources/mapper/stock/StockUninventoryMapper.xml                                        |   60 +
 src/main/java/com/ruoyi/customervisits/service/CustomerVisitsService.java                         |    4 
 src/main/java/com/ruoyi/stock/service/StockUninventoryService.java                                |   24 
 src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java                        |   16 
 src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java                         |  121 ++
 src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java                             |    5 
 src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java                    |  106 +
 src/main/java/com/ruoyi/device/controller/DeviceRepairController.java                             |   16 
 src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java                                      |    3 
 src/main/resources/mapper/stock/StockOutRecordMapper.xml                                          |   48 +
 src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java                              |    6 
 src/main/java/com/ruoyi/CodeGenerator.java                                                        |    6 
 src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java                     |    8 
 src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java                                        |   18 
 src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java                         |   97 ++
 src/main/java/com/ruoyi/customervisits/service/impl/CustomerVisitsServiceImpl.java                |   20 
 src/main/resources/mapper/stock/StockInRecordMapper.xml                                           |   32 
 src/main/java/com/ruoyi/basic/dto/SelectOptionDTO.java                                            |   14 
 src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java                        |    8 
 src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java                          |   11 
 src/main/java/com/ruoyi/collaborativeApproval/controller/NoticeController.java                    |    4 
 src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java                  |    3 
 src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java                      |   10 
 src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java                   |  118 ++
 src/main/java/com/ruoyi/stock/service/StockOutRecordService.java                                  |   27 
 src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java                                 |    5 
 src/main/java/com/ruoyi/basic/utils/EnumUtils.java                                                |   45 
 src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java                              |   34 
 src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java                                    |   28 
 src/main/java/com/ruoyi/customervisits/controller/CustomerVisitsController.java                   |   31 
 src/main/java/com/ruoyi/common/enums/StockQualifiedRecordTypeEnum.java                            |   27 
 src/main/java/com/ruoyi/production/controller/ProductBomController.java                           |   17 
 src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java                                |    5 
 src/main/resources/mapper/purchase/InvoicePurchaseMapper.xml                                      |    2 
 src/main/java/com/ruoyi/home/controller/HomeController.java                                       |   96 +
 src/main/java/com/ruoyi/quality/service/IQualityUnqualifiedService.java                           |    3 
 src/main/java/com/ruoyi/sales/dto/LossProductModelDto.java                                        |   24 
 src/main/java/com/ruoyi/stock/controller/StockInRecordController.java                             |   44 
 src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java                               |    7 
 src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java                            |   61 +
 src/main/java/com/ruoyi/stock/mapper/StockInRecordMapper.java                                     |   12 
 src/main/java/com/ruoyi/common/enums/SalesLedgerType.java                                         |    6 
 src/main/resources/mapper/lavorissue/LavorIssueMapper.xml                                         |    4 
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java                            |   38 
 src/main/java/com/ruoyi/common/enums/StaffLeaveReason.java                                        |    6 
 src/main/java/com/ruoyi/basic/controller/EnumController.java                                      |   36 
 src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java                       |   17 
 src/main/java/com/ruoyi/collaborativeApproval/controller/SealApplicationManagementController.java |    2 
 src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java                                          |   19 
 src/main/java/com/ruoyi/stock/pojo/StockInRecord.java                                             |   65 +
 src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java             |  167 +-
 src/main/resources/mapper/stock/StockInventoryMapper.xml                                          |   62 +
 src/main/java/com/ruoyi/stock/mapper/StockUninventoryMapper.java                                  |   27 
 src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java                                    |    4 
 src/main/java/com/ruoyi/stock/controller/StockInventoryController.java                            |   62 +
 src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java                              |    4 
 src/main/java/com/ruoyi/stock/dto/StockInRecordDto.java                                           |   26 
 src/main/resources/mapper/quality/QualityInspectMapper.xml                                        |   26 
 src/main/java/com/ruoyi/common/enums/StorageAttachmentRecordType.java                             |    6 
 src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java                       |   89 +
 src/main/java/com/ruoyi/common/utils/EnumUtil.java                                                |  106 ++
 src/main/resources/mapper/production/ProductionProductMainMapper.xml                              |    8 
 src/main/java/com/ruoyi/common/enums/BaseEnum.java                                                |   58 +
 src/main/java/com/ruoyi/stock/pojo/StockUninventory.java                                          |   52 +
 src/main/java/com/ruoyi/common/enums/UserStatus.java                                              |    7 
 src/main/resources/mapper/collaborativeApproval/StaffContactsPersonalMapper.xml                   |    2 
 86 files changed, 2,442 insertions(+), 408 deletions(-)

diff --git a/src/main/java/com/ruoyi/CodeGenerator.java b/src/main/java/com/ruoyi/CodeGenerator.java
index cca67a2..f4efe04 100644
--- a/src/main/java/com/ruoyi/CodeGenerator.java
+++ b/src/main/java/com/ruoyi/CodeGenerator.java
@@ -19,11 +19,11 @@
 // 婕旂ず渚嬪瓙锛屾墽琛� main 鏂规硶鎺у埗鍙拌緭鍏ユā鍧楄〃鍚嶅洖杞﹁嚜鍔ㄧ敓鎴愬搴旈」鐩洰褰曚腑
 public class CodeGenerator {
 
-    public static String database_url = "jdbc:mysql://127.0.0.1:3306/product-inventory-management-new";
+    public static String database_url = "jdbc:mysql://1.15.17.182:9999/product-inventory-management-new";
     public static String database_username = "root";
-    public static String database_password= "123456";
+    public static String database_password= "xd@123456..";
     public static String author = "鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃";
-    public static String model = "account"; // 妯″潡
+    public static String model = "stock"; // 妯″潡
     public static String setParent = "com.ruoyi."+ model; // 鍖呰矾寰�
     public static String tablePrefix = ""; // 璁剧疆杩囨护琛ㄥ墠缂�
     public static void main(String[] args) {
diff --git a/src/main/java/com/ruoyi/approve/pojo/KnowledgeBase.java b/src/main/java/com/ruoyi/approve/pojo/KnowledgeBase.java
index a066e06..c21eb72 100644
--- a/src/main/java/com/ruoyi/approve/pojo/KnowledgeBase.java
+++ b/src/main/java/com/ruoyi/approve/pojo/KnowledgeBase.java
@@ -22,7 +22,7 @@
     /**
      * 鐭ヨ瘑绫诲瀷
      */
-    @Excel(name = "鐭ヨ瘑绫诲瀷",readConverterExp = "contract=鍚堝悓鐗规壒,approval=瀹℃壒妗堜緥,solution=瑙e喅鏂规,experience=缁忛獙鎬荤粨,guide=鎿嶄綔鎸囧崡")
+    @Excel(name = "鐭ヨ瘑绫诲瀷")
     private String type;
     /**
      * 閫傜敤鍦烘櫙
diff --git a/src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
index 4747ffe..9680b64 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
@@ -67,7 +67,7 @@
         LambdaQueryWrapper<ApproveProcess> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.eq(ApproveProcess::getApproveId, id);
         queryWrapper.eq(ApproveProcess::getApproveDelete, 0);
-        queryWrapper.eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId());
+//        queryWrapper.eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId());
         queryWrapper.last("limit 1");
         ApproveProcess one = approveProcessMapper.selectOne(queryWrapper);
         return one;
@@ -76,14 +76,12 @@
     @Override
     public void initApproveNodes(String approveUserIds,String approveID,Long tenantId) {
         Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
-        ApproveProcess approve = getApproveById(approveID);
         String[] names = approveUserIds.split(",");
-        String approveId = approve.getApproveId();
         for (int i = 0; i < names.length; i++) {
             SysUser sysUser = sysUserMapper.selectUserById(Long.parseLong(names[i]));
             if (sysUser == null) continue;
             ApproveNode approveNode = new ApproveNode();
-            approveNode.setApproveProcessId(approveId);
+            approveNode.setApproveProcessId(approveID);
             approveNode.setApproveNodeOrder(i +1);
             approveNode.setApproveNodeUser(sysUser.getNickName());
             approveNode.setApproveNodeUserId(sysUser.getUserId());
@@ -104,14 +102,12 @@
         LambdaQueryWrapper<ApproveNode> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.eq(ApproveNode::getApproveProcessId, id);
         queryWrapper.eq(ApproveNode::getDeleteFlag, 0);
-        queryWrapper.eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId());
         List<ApproveNode> list = list(queryWrapper);
         // 鎸夌収 approveNodeOrder 瀛楁鍗囧簭鎺掑簭
         list.sort(Comparator.comparingInt(ApproveNode::getApproveNodeOrder));
         LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>();
         approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveId, id)
                 .eq(ApproveProcess::getApproveDelete, 0)
-                .eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                 .last("limit 1");
         ApproveProcess approveProcess = approveProcessMapper.selectOne(approveProcessLambdaQueryWrapper);
         if(approveProcess != null && approveProcess.getApproveStatus() == 3){
@@ -137,7 +133,6 @@
         LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>();
         approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveId, approveNode.getApproveProcessId())
                 .eq(ApproveProcess::getApproveDelete, 0)
-                .eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                 .last("limit 1");
         ApproveProcess approveProcess = approveProcessMapper.selectOne(approveProcessLambdaQueryWrapper);
         if(approveProcess == null) throw new RuntimeException("瀹℃壒涓嶅瓨鍦�");
@@ -145,7 +140,6 @@
         approveNodeLambdaQueryWrapper.eq(ApproveNode::getApproveProcessId, approveNode.getApproveProcessId())
                 .eq(ApproveNode::getApproveNodeOrder, approveNode.getApproveNodeOrder() + 1)
                 .eq(ApproveNode::getDeleteFlag, 0)
-                .eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                 .last("limit 1");
         ApproveNode approveNode1 = approveNodeMapper.selectOne(approveNodeLambdaQueryWrapper);
         approveProcess.setApproveStatus(status);
@@ -206,7 +200,6 @@
                     sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                             approveNode.getApproveProcessId()+"娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
                             Arrays.asList(Long.valueOf(id)),
-                            approveNode.getTenantId(),
                             "/collaborativeApproval/approvalProcess?approveType="+approveProcess.getApproveType()+"&approveId="+approveNode.getApproveProcessId());
                 }
                 break;
diff --git a/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
index 48a3e9f..13c493a 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
@@ -3,6 +3,7 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.approve.mapper.ApproveNodeMapper;
@@ -126,7 +127,6 @@
         sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcessVO.getApproveType()),
                 approveID + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
                 Arrays.asList(Long.valueOf(id)),
-                approveProcessVO.getApproveDeptId(),
                 "/collaborativeApproval/approvalProcess?approveType=" + approveProcessVO.getApproveType() + "&approveId=" + approveID);
     }
 
@@ -189,12 +189,9 @@
 
     @Override
     public ApproveProcess getApproveById(String id) {
-        LambdaQueryWrapper<ApproveProcess> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(ApproveProcess::getApproveId, id);
-        queryWrapper.eq(ApproveProcess::getApproveDelete, 0);
-        queryWrapper.eq(ApproveProcess::getTenantId, SecurityUtils.getLoginUser().getTenantId());
-        queryWrapper.last("limit 1");
-        ApproveProcess one = getOne(queryWrapper);
+        ApproveProcess one = approveProcessMapper.selectList(Wrappers.<ApproveProcess>lambdaQuery()
+                .eq(ApproveProcess::getApproveId,id)
+                .eq(ApproveProcess::getApproveDelete,0)).get(0);
         one.setCommonFileList(commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
                 .eq(CommonFile::getCommonId, one.getId())
                 .eq(CommonFile::getType, FileNameType.ApproveProcess.getValue())));
@@ -232,7 +229,7 @@
         LambdaQueryWrapper<ApproveNode> approveNodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
         approveNodeLambdaQueryWrapper.eq(ApproveNode::getApproveProcessId, approveProcess.getApproveId())
                 .eq(ApproveNode::getDeleteFlag, 0)
-                .eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId())
+//                .eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                 .orderByAsc(ApproveNode::getApproveNodeOrder);
         approveNodeMapper.delete(approveNodeLambdaQueryWrapper);
         approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(), approveProcess.getApproveId(), approveProcess.getTenantId());
@@ -241,7 +238,6 @@
         sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                 approveProcess.getApproveId() + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
                 Arrays.asList(Long.valueOf(id)),
-                approveProcess.getApproveDeptId(),
                 "/collaborativeApproval/approvalProcess?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
     }
 
@@ -273,7 +269,7 @@
         LambdaQueryWrapper<ApproveNode> approveNodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
         approveNodeLambdaQueryWrapper.eq(ApproveNode::getApproveProcessId, approve.getApproveId())
                 .eq(ApproveNode::getDeleteFlag, 0)
-                .eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId())
+//                .eq(ApproveNode::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                 .orderByAsc(ApproveNode::getApproveNodeOrder);
         approveNodeMapper.delete(approveNodeLambdaQueryWrapper);
         approveNodeService.initApproveNodes(approveGetAndUpdateVo.getApproveUserIds(), approve.getApproveId(), approve.getTenantId());
@@ -300,7 +296,6 @@
         sysNoticeService.simpleNoticeByUser(approveProcessType(approve.getApproveType()),
                 approve.getApproveId() + "娴佺▼缂栧彿鐨勫鎵归渶瑕佹偍瀹℃牳!!!!!",
                 Arrays.asList(Long.valueOf(id)),
-                approve.getApproveDeptId(),
                 "/collaborativeApproval/approvalProcess?approveType=" + approve.getApproveType() + "&approveId=" + approve.getApproveId());
 
     }
diff --git a/src/main/java/com/ruoyi/basic/controller/EnumController.java b/src/main/java/com/ruoyi/basic/controller/EnumController.java
new file mode 100644
index 0000000..b02326a
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/controller/EnumController.java
@@ -0,0 +1,36 @@
+package com.ruoyi.basic.controller;
+
+import com.ruoyi.basic.utils.EnumUtils;
+import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
+import com.ruoyi.common.utils.EnumUtil;
+import com.ruoyi.framework.aspectj.lang.annotation.Anonymous;
+import com.ruoyi.framework.web.domain.R;
+import io.swagger.annotations.Api;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@Api(tags = "鏋氫妇鎺ュ彛")
+@RequestMapping("/basic/enum")
+public class EnumController {
+
+
+    //鑾峰彇搴撳瓨鏋氫妇
+    @GetMapping("/stockRecordType")
+    @Anonymous
+    public R  getStockRecordTypeEnum(){
+        List<Map<String, Object>> list = EnumUtil.toList(StockQualifiedRecordTypeEnum.class);
+        return R.ok(list);
+    }
+
+    @GetMapping("/{className}")
+    @Anonymous
+    public R test(@PathVariable String className){
+        return R.ok(EnumUtils.getOptions("com.ruoyi.common.enums." + className));
+    }
+}
diff --git a/src/main/java/com/ruoyi/basic/dto/SelectOptionDTO.java b/src/main/java/com/ruoyi/basic/dto/SelectOptionDTO.java
new file mode 100644
index 0000000..4323126
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/dto/SelectOptionDTO.java
@@ -0,0 +1,14 @@
+package com.ruoyi.basic.dto;
+
+import lombok.Data;
+
+@Data
+public class SelectOptionDTO<T> {
+    private T value;
+    private String label;
+
+    public SelectOptionDTO(T code, String value) {
+        this.value = code;
+        this.label = value;
+    }
+}
diff --git a/src/main/java/com/ruoyi/basic/utils/EnumUtils.java b/src/main/java/com/ruoyi/basic/utils/EnumUtils.java
new file mode 100644
index 0000000..5103ac5
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/utils/EnumUtils.java
@@ -0,0 +1,45 @@
+package com.ruoyi.basic.utils;
+
+import com.ruoyi.basic.dto.SelectOptionDTO;
+import com.ruoyi.common.enums.BaseEnum;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EnumUtils {
+    public static List<SelectOptionDTO<?>> getOptions(String className) {
+        try {
+            Class<?> clazz = Class.forName(className);
+            return getOptionsByClass(clazz);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static List<SelectOptionDTO<?>> getOptionsByClass(Class<?> clazz) {
+        if (!clazz.isEnum()) {
+            throw new RuntimeException("涓嶆槸鏋氫妇锛�" + clazz.getName());
+        }
+        if (!BaseEnum.class.isAssignableFrom(clazz)) {
+            throw new RuntimeException("鏈疄鐜� BaseEnum锛�" + clazz.getName());
+        }
+        return (List<SelectOptionDTO<?>>) getOptionsInternal((Class) clazz);
+    }
+
+    private static <T> List<SelectOptionDTO<T>> getOptionsInternal(
+            Class<? extends BaseEnum<T>> clazz) {
+
+        Enum<?>[] enums = (Enum<?>[]) clazz.getEnumConstants();
+        List<SelectOptionDTO<T>> list = new ArrayList<>();
+
+        for (Enum<?> e : enums) {
+            BaseEnum<T> option = (BaseEnum<T>) e;
+            list.add(new SelectOptionDTO<>(
+                    option.getCode(),
+                    option.getValue()
+            ));
+        }
+        return list;
+    }
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/controller/NoticeController.java b/src/main/java/com/ruoyi/collaborativeApproval/controller/NoticeController.java
index 77df424..8fe67d0 100644
--- a/src/main/java/com/ruoyi/collaborativeApproval/controller/NoticeController.java
+++ b/src/main/java/com/ruoyi/collaborativeApproval/controller/NoticeController.java
@@ -5,6 +5,7 @@
 import com.ruoyi.collaborativeApproval.dto.NoticeDTO;
 import com.ruoyi.collaborativeApproval.pojo.Notice;
 import com.ruoyi.collaborativeApproval.service.NoticeService;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.framework.aspectj.lang.annotation.Log;
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.controller.BaseController;
@@ -16,6 +17,7 @@
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 
+import java.security.Security;
 import java.util.List;
 
 @RestController
@@ -42,7 +44,6 @@
             //姝e紡鍙戝竷閫氱煡鎵�鏈変汉鐨勬秷鎭�氱煡
             sysNoticeService.simpleNoticeAll("閫氱煡鍏憡",
                     noticeDTO.getTitle(),
-                    noticeDTO.getTenantId(),
                     "/collaborativeApproval/noticeManagement?type="+noticeDTO.getType());
         }
         return AjaxResult.success(noticeService.save(noticeDTO));
@@ -57,7 +58,6 @@
             //姝e紡鍙戝竷閫氱煡鎵�鏈変汉鐨勬秷鎭�氱煡
             sysNoticeService.simpleNoticeAll("閫氱煡鍏憡",
                     notice.getTitle(),
-                    notice.getTenantId(),
                     "/collaborativeApproval/noticeManagement?type="+notice.getType());
         }
         return AjaxResult.success(noticeService.updateById(noticeDTO));
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/controller/NoticeTypeController.java b/src/main/java/com/ruoyi/collaborativeApproval/controller/NoticeTypeController.java
index 6f06563..53ae816 100644
--- a/src/main/java/com/ruoyi/collaborativeApproval/controller/NoticeTypeController.java
+++ b/src/main/java/com/ruoyi/collaborativeApproval/controller/NoticeTypeController.java
@@ -34,7 +34,7 @@
      */
     @PostMapping("/add")
     public AjaxResult add(@RequestBody NoticeType noticeType) {
-        return AjaxResult.success(noticeTypeService.save(noticeType));
+        return AjaxResult.success(noticeTypeService.saveOrUpdate(noticeType));
     }
 
     /**
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/controller/SealApplicationManagementController.java b/src/main/java/com/ruoyi/collaborativeApproval/controller/SealApplicationManagementController.java
index 0f7094d..9d2cb6f 100644
--- a/src/main/java/com/ruoyi/collaborativeApproval/controller/SealApplicationManagementController.java
+++ b/src/main/java/com/ruoyi/collaborativeApproval/controller/SealApplicationManagementController.java
@@ -4,6 +4,7 @@
 import com.ruoyi.approve.pojo.KnowledgeBase;
 import com.ruoyi.collaborativeApproval.pojo.SealApplicationManagement;
 import com.ruoyi.collaborativeApproval.service.SealApplicationManagementService;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.AjaxResult;
@@ -45,7 +46,6 @@
                 "鐢宠缂栧彿锛�"+sealApplicationManagement.getApplicationNum()+"\n"
                 +"鐢宠鏍囬锛�"+sealApplicationManagement.getTitle(),
                 Arrays.asList(sealApplicationManagement.getApproveUserId()),
-                sealApplicationManagement.getTenantId(),
                 "/collaborativeApproval/sealManagement?applicationNum="+sealApplicationManagement.getApplicationNum());
         return AjaxResult.success();
     }
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java
index 75cbc5a..9fa232a 100644
--- a/src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java
+++ b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java
@@ -186,7 +186,6 @@
                                 "浼氳鏃堕棿锛�" + application.getStartTime() + "-" + application.getEndTime() + "\n" +
                                 "鍙戣捣浜猴細" + application.getApplicant(),
                         userIds,
-                        application.getTenantId(),
                         ""
                 );
             }
diff --git a/src/main/java/com/ruoyi/common/enums/BaseEnum.java b/src/main/java/com/ruoyi/common/enums/BaseEnum.java
new file mode 100644
index 0000000..cf84dde
--- /dev/null
+++ b/src/main/java/com/ruoyi/common/enums/BaseEnum.java
@@ -0,0 +1,58 @@
+package com.ruoyi.common.enums;
+
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+public interface BaseEnum<T> {
+    @JsonValue
+    T getCode();
+    
+    String getValue();
+
+    /**
+     * 閫氱敤闈欐�佸伐鍏锋柟娉曪紙鍙鎵�鏈夋灇涓捐皟鐢級
+     */
+    /**
+     * 閫氱敤闈欐�佸伐鍏锋柟娉曪細鏀寔浠� Integer 鎴� String 绫诲瀷鐨� Code 杩涜鍙嶅簭鍒楀寲
+     */
+    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
+    static <E extends Enum<E> & BaseEnum<?>> E fromCode(Class<E> enumClass, Object code) {
+        if (code == null) {
+            return null;
+        }
+
+        // 鐩爣 Code 鐨勬暣鏁板��
+        Integer targetCode = null;
+
+        if (code instanceof Integer) {
+            // 1. 濡傛灉浼犲叆鐨勬槸鏁板瓧 (Integer)
+            targetCode = (Integer) code;
+        } else if (code instanceof String) {
+            // 2. 濡傛灉浼犲叆鐨勬槸瀛楃涓� ("1")
+            try {
+                // 灏濊瘯灏嗗瓧绗︿覆杞崲涓烘暣鏁�
+                targetCode = Integer.valueOf((String) code);
+            } catch (NumberFormatException e) {
+                // 濡傛灉瀛楃涓蹭笉鏄湁鏁堢殑鏁板瓧锛堜緥濡� "Unknown"锛夛紝鍒� targetCode 淇濇寔涓� null
+                // 鎮ㄤ篃鍙互鍦ㄨ繖閲岃褰曟棩蹇楁垨鎵ц鍏朵粬閿欒澶勭悊
+                // System.err.println("鏃犳硶灏嗗瓧绗︿覆 Code 杞崲涓烘暟瀛�: " + code);
+                return null; // 鎴栬�呭湪鎵句笉鍒板尮閰嶇殑鎯呭喌涓嬭繑鍥� null
+            }
+        }
+        // else if (code instanceof Long) { ... 鎮ㄤ篃鍙互娣诲姞瀵� Long 绫诲瀷鐨勬敮鎸� }
+
+        if (targetCode == null) {
+            return null;
+        }
+
+        // 浣跨敤鑾峰彇鍒扮殑鏁存暟鍊艰繘琛屾煡鎵�
+        for (E e : enumClass.getEnumConstants()) {
+            if (e.getCode().equals(targetCode)) {
+                return e;
+            }
+        }
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/common/enums/SalesLedgerType.java b/src/main/java/com/ruoyi/common/enums/SalesLedgerType.java
index cd76069..74a5eb6 100644
--- a/src/main/java/com/ruoyi/common/enums/SalesLedgerType.java
+++ b/src/main/java/com/ruoyi/common/enums/SalesLedgerType.java
@@ -1,7 +1,7 @@
 package com.ruoyi.common.enums;
 
 
-public enum SalesLedgerType {
+public enum SalesLedgerType implements BaseEnum<Integer>{
     SALES_LEDGER_TYPE_SALES_LEDGER(1, "閿�鍞彴璐�"),
     SALES_LEDGER_TYPE_PURCHASE_LEDGER(2, "閲囪喘鍙拌处");
 
@@ -13,11 +13,11 @@
         this.label = label;
     }
 
-    public Integer getValue() {
+    public Integer getCode() {
         return value;
     }
 
-    public String getLabel() {
+    public String getValue() {
         return label;
     }
 
diff --git a/src/main/java/com/ruoyi/common/enums/StaffLeaveReason.java b/src/main/java/com/ruoyi/common/enums/StaffLeaveReason.java
index 5c043fb..c802164 100644
--- a/src/main/java/com/ruoyi/common/enums/StaffLeaveReason.java
+++ b/src/main/java/com/ruoyi/common/enums/StaffLeaveReason.java
@@ -7,7 +7,7 @@
  *
  */
 @AllArgsConstructor
-public enum StaffLeaveReason {
+public enum StaffLeaveReason implements BaseEnum<String> {
     StaffLeaveReasonSalary("salary","钖祫寰呴亣"),
     StaffLeaveReasonCareerDevelopment("career_development","鑱屼笟鍙戝睍"),
     StaffLeaveReasonWorkEnvironment("work_environment","宸ヤ綔鐜"),
@@ -22,6 +22,10 @@
         return code;
     }
 
+    public String getValue() {
+        return info;
+    }
+
     public String getInfo() {
         return info;
     }
diff --git a/src/main/java/com/ruoyi/common/enums/StockQualifiedRecordTypeEnum.java b/src/main/java/com/ruoyi/common/enums/StockQualifiedRecordTypeEnum.java
new file mode 100644
index 0000000..e880782
--- /dev/null
+++ b/src/main/java/com/ruoyi/common/enums/StockQualifiedRecordTypeEnum.java
@@ -0,0 +1,27 @@
+package com.ruoyi.common.enums;
+
+import lombok.Getter;
+
+
+@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, "璐ㄦ-鍚堟牸鍏ュ簱");
+
+
+
+    private final Integer code;
+    private final String value;
+
+    StockQualifiedRecordTypeEnum(Integer 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
new file mode 100644
index 0000000..753c6e5
--- /dev/null
+++ b/src/main/java/com/ruoyi/common/enums/StockUnQualifiedRecordTypeEnum.java
@@ -0,0 +1,25 @@
+package com.ruoyi.common.enums;
+
+import lombok.Getter;
+
+
+@Getter
+public enum StockUnQualifiedRecordTypeEnum implements BaseEnum<Integer> {
+
+
+    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 value;
+
+    StockUnQualifiedRecordTypeEnum(Integer code, String value) {
+        this.code = code;
+        this.value = value;
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/common/enums/StorageAttachmentRecordType.java b/src/main/java/com/ruoyi/common/enums/StorageAttachmentRecordType.java
index 5f6cb9e..c8fdae5 100644
--- a/src/main/java/com/ruoyi/common/enums/StorageAttachmentRecordType.java
+++ b/src/main/java/com/ruoyi/common/enums/StorageAttachmentRecordType.java
@@ -7,7 +7,7 @@
  *
  */
 @AllArgsConstructor
-public enum StorageAttachmentRecordType {
+public enum StorageAttachmentRecordType implements BaseEnum<String> {
     // 渚嬪瓙 瀹為檯寮�鍙戣鍒犻櫎
     Template("Template","鑼冧緥"),
     Archives("Archives","鏂囨。绠$悊"),
@@ -23,6 +23,10 @@
         return code;
     }
 
+    public String getValue() {
+        return info;
+    }
+
     public String getInfo() {
         return info;
     }
diff --git a/src/main/java/com/ruoyi/common/enums/UserStatus.java b/src/main/java/com/ruoyi/common/enums/UserStatus.java
index a4613ff..3612f81 100644
--- a/src/main/java/com/ruoyi/common/enums/UserStatus.java
+++ b/src/main/java/com/ruoyi/common/enums/UserStatus.java
@@ -5,7 +5,7 @@
  * 
  * @author ruoyi
  */
-public enum UserStatus
+public enum UserStatus implements BaseEnum<String>
 {
     OK("0", "姝e父"), DISABLE("1", "鍋滅敤"), DELETED("2", "鍒犻櫎");
 
@@ -23,8 +23,13 @@
         return code;
     }
 
+    public String getValue() {
+        return info;
+    }
+
     public String getInfo()
     {
         return info;
     }
+
 }
diff --git a/src/main/java/com/ruoyi/common/utils/EnumUtil.java b/src/main/java/com/ruoyi/common/utils/EnumUtil.java
new file mode 100644
index 0000000..8fd3224
--- /dev/null
+++ b/src/main/java/com/ruoyi/common/utils/EnumUtil.java
@@ -0,0 +1,106 @@
+package com.ruoyi.common.utils;
+
+
+import com.ruoyi.common.enums.BaseEnum;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 閫氱敤鏋氫妇宸ュ叿绫�
+ * 閫傜敤浜庢墍鏈夊疄鐜� BaseEnum 鎺ュ彛鐨勬灇涓�
+ *
+ * @author Bu
+ */
+public class EnumUtil {
+
+    /**
+     * 鏍规嵁 code 鑾峰彇鏋氫妇瀹炰緥
+     */
+    public static <E extends Enum<E> & BaseEnum> E fromCode(Class<E> enumClass, int code) {
+        for (E e : enumClass.getEnumConstants()) {
+            if ((int)e.getCode() == code) {
+                return e;
+            }
+        }
+        throw new IllegalArgumentException("鏈煡鐨� code: " + code + " 瀵逛簬鏋氫妇 " + enumClass.getSimpleName());
+    }
+
+    public static <E extends Enum<E> & BaseEnum> E fromCodeHasNull(Class<E> enumClass, int code) {
+        for (E e : enumClass.getEnumConstants()) {
+            if ((int)e.getCode() == code) {
+                return e;
+            }
+        }
+        return null;
+    }
+
+    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) {
+                return e;
+            }
+        }
+        return defaultE;
+    }
+
+
+
+    /**
+     * 鏍规嵁 value 鑾峰彇鏋氫妇瀹炰緥
+     */
+    public static <E extends Enum<E> & BaseEnum> E fromValue(Class<E> enumClass, String value) {
+        for (E e : enumClass.getEnumConstants()) {
+            if (Objects.equals(e.getValue(), value)) {
+                return e;
+            }
+        }
+        throw new IllegalArgumentException("鏈煡鐨� value: " + value + " 瀵逛簬鏋氫妇 " + enumClass.getSimpleName());
+    }
+
+    /**
+     * 鑾峰彇鎵�鏈夋灇涓鹃」鍒楄〃
+     */
+    public static <E extends Enum<E> & BaseEnum> List<E> listAll(Class<E> enumClass) {
+        return Arrays.asList(enumClass.getEnumConstants());
+    }
+
+    /**
+     * 杞负 List<Map>锛堥�傚悎杩斿洖缁欏墠绔級
+     * 鏍煎紡: [{ "code": 1, "value": "缁炵嚎" }, ...]
+     */
+    public static <E extends Enum<E> & BaseEnum> List<Map<String, Object>> toList(Class<E> enumClass) {
+        return Arrays.stream(enumClass.getEnumConstants())
+                .map(e -> {
+                    Map<String, Object> map = new HashMap<>();
+                    map.put("key", e.getCode().toString());
+                    map.put("value", e.getValue());
+                    return map;
+                })
+                .collect(Collectors.toList());
+    }
+
+//    /**
+//     * 杞负 Map<Integer, String>
+//     * 鏍煎紡: { 1: "缁炵嚎", 0: "鎷変笣" }
+//     */
+//    public static <E extends Enum<E> & BaseEnum> Map<Integer, String> toMap(Class<E> enumClass) {
+//        return Arrays.stream(enumClass.getEnumConstants())
+//                .collect(Collectors.toMap((BaseEnum::getCode, BaseEnum::getValue));
+//    }
+//
+//
+//    public static void main(String[] args) {
+//        // 鉁� 1. 鏍规嵁 code 鑾峰彇鏋氫妇
+//        StockRecordTypeEnum status = EnumUtil.fromCode(StockRecordTypeEnum.class, 1);
+//        System.out.println(status.getValue()); // 缁炵嚎
+//
+//        // 鉁� 2. 杞垚 list (閫傚悎鍓嶇)
+//        System.out.println(EnumUtil.toList(StockRecordTypeEnum.class));
+//        // 杈撳嚭: [{code=1, value=缁炵嚎}, {code=0, value=鎷変笣}]
+//
+//        // 鉁� 3. 杞垚 map
+//        System.out.println(EnumUtil.toMap(StockRecordTypeEnum.class));
+//        // 杈撳嚭: {1=缁炵嚎, 0=鎷変笣}
+//    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/customervisits/controller/CustomerVisitsController.java b/src/main/java/com/ruoyi/customervisits/controller/CustomerVisitsController.java
index 3d26445..6f293d4 100644
--- a/src/main/java/com/ruoyi/customervisits/controller/CustomerVisitsController.java
+++ b/src/main/java/com/ruoyi/customervisits/controller/CustomerVisitsController.java
@@ -30,7 +30,7 @@
     @GetMapping("/listPage")
     @Log(title = "瀹㈡埛鎷滆-鍒嗛〉鏌ヨ", businessType = BusinessType.OTHER)
     @ApiOperation("瀹㈡埛鎷滆-鍒嗛〉鏌ヨ")
-    public AjaxResult listPage(Page page, CustomerVisits customerVisits){
+    public AjaxResult listPage(Page page, CustomerVisits customerVisits) {
         IPage<CustomerVisits> listPage = customerVisitsService.listPage(page, customerVisits);
         return AjaxResult.success(listPage);
     }
@@ -39,12 +39,37 @@
     @ApiOperation("瀹㈡埛鎷滆-娣诲姞")
     @PostMapping("/add")
     @Transactional(rollbackFor = Exception.class)
-    public AjaxResult add(@RequestBody CustomerVisits customerVisits){
+    public AjaxResult add(@RequestBody CustomerVisits customerVisits) {
         boolean save = customerVisitsService.save(customerVisits);
-        if (save){
+        if (save) {
             return AjaxResult.success("娣诲姞鎴愬姛");
         }
         return AjaxResult.error("娣诲姞澶辫触");
     }
 
+    @Log(title = "瀹㈡埛鎷滆-缂栬緫", businessType = BusinessType.UPDATE)
+    @ApiOperation("瀹㈡埛鎷滆-缂栬緫")
+    @PostMapping("update")
+    public AjaxResult updateCustomerVisit(@RequestBody CustomerVisits customerVisits) {
+        boolean updateResult = customerVisitsService.updateCustomerVisit(customerVisits);
+        if (updateResult) {
+            return AjaxResult.success("缂栬緫鎴愬姛");
+        }
+        return AjaxResult.error("缂栬緫澶辫触");
+    }
+
+    @Log(title = "瀹㈡埛鎷滆-鍒犻櫎", businessType = BusinessType.DELETE)
+    @ApiOperation("瀹㈡埛鎷滆-鍒犻櫎")
+    @DeleteMapping("{customerId}")
+    public AjaxResult deleteCustomerVisit(@PathVariable Integer customerId) {
+        if (customerId == null) {
+            return AjaxResult.error("瀹㈡埛ID涓嶈兘涓虹┖");
+        }
+        boolean deleteResult = customerVisitsService.removeById(customerId);
+        if (deleteResult) {
+            return AjaxResult.success("鍒犻櫎鎴愬姛");
+        }
+        return AjaxResult.error("鍒犻櫎澶辫触");
+    }
+
 }
diff --git a/src/main/java/com/ruoyi/customervisits/service/CustomerVisitsService.java b/src/main/java/com/ruoyi/customervisits/service/CustomerVisitsService.java
index f4463e2..1f8d1ef 100644
--- a/src/main/java/com/ruoyi/customervisits/service/CustomerVisitsService.java
+++ b/src/main/java/com/ruoyi/customervisits/service/CustomerVisitsService.java
@@ -4,6 +4,7 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.customervisits.pojo.CustomerVisits;
+import com.ruoyi.framework.web.domain.AjaxResult;
 
 /**
  * @author :yys
@@ -11,4 +12,7 @@
  */
 public interface CustomerVisitsService extends IService<CustomerVisits> {
     IPage<CustomerVisits> listPage(Page page, CustomerVisits customerVisits);
+
+    boolean updateCustomerVisit(CustomerVisits customerVisits);
+
 }
diff --git a/src/main/java/com/ruoyi/customervisits/service/impl/CustomerVisitsServiceImpl.java b/src/main/java/com/ruoyi/customervisits/service/impl/CustomerVisitsServiceImpl.java
index 5023c99..319d478 100644
--- a/src/main/java/com/ruoyi/customervisits/service/impl/CustomerVisitsServiceImpl.java
+++ b/src/main/java/com/ruoyi/customervisits/service/impl/CustomerVisitsServiceImpl.java
@@ -11,6 +11,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * @author :yys
@@ -26,10 +27,27 @@
     @Override
     public IPage<CustomerVisits> listPage(Page page, CustomerVisits customerVisits) {
         LambdaQueryWrapper<CustomerVisits> customerVisitsLambdaQueryWrapper = new LambdaQueryWrapper<>();
-        if(customerVisits != null && !StringUtils.isEmpty(customerVisits.getCustomerName())){
+        if (customerVisits != null && !StringUtils.isEmpty(customerVisits.getCustomerName())) {
             customerVisitsLambdaQueryWrapper.like(CustomerVisits::getCustomerName, customerVisits.getCustomerName());
         }
         Page page1 = customerVisitsMapper.selectPage(page, customerVisitsLambdaQueryWrapper);
         return page1;
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateCustomerVisit(CustomerVisits customerVisits) {
+        if (customerVisits == null || customerVisits.getId() == null) {
+            return false;
+        }
+
+        if (StringUtils.isEmpty(customerVisits.getCustomerName())
+                || StringUtils.isEmpty(customerVisits.getPurposeVisit())
+                || StringUtils.isEmpty(customerVisits.getVisitAddress())
+                || StringUtils.isEmpty(customerVisits.getPurposeDate())) {
+            return false;
+        }
+
+        return updateById(customerVisits);
+    }
 }
diff --git a/src/main/java/com/ruoyi/device/controller/DeviceDefectRecordController.java b/src/main/java/com/ruoyi/device/controller/DeviceDefectRecordController.java
index 2b87fb9..59b0b4f 100644
--- a/src/main/java/com/ruoyi/device/controller/DeviceDefectRecordController.java
+++ b/src/main/java/com/ruoyi/device/controller/DeviceDefectRecordController.java
@@ -6,7 +6,7 @@
 import com.ruoyi.device.service.DeviceDefectRecordService;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -16,12 +16,12 @@
 public class DeviceDefectRecordController {
     @Autowired
     private DeviceDefectRecordService deviceDefectRecordService;
-    @ApiModelProperty("璁惧缂洪櫡璁板綍鍒楄〃")
+    @ApiOperation("璁惧缂洪櫡璁板綍鍒楄〃")
     @GetMapping("/page")
     public AjaxResult page(Page page , DeviceDefectRecordDto deviceDefectRecordDto) {
         return AjaxResult.success(deviceDefectRecordService.listPage(page,deviceDefectRecordDto));
     }
-    @ApiModelProperty("璁惧id鏌ヨ璁惧缂洪櫡璁板綍鍒楄〃")
+    @ApiOperation("璁惧id鏌ヨ璁惧缂洪櫡璁板綍鍒楄〃")
     @GetMapping("/find/{deviceLedgerId}")
     public AjaxResult find(@PathVariable Long deviceLedgerId) {
         DeviceDefectRecordDto deviceDefectRecordDto = new DeviceDefectRecordDto();
@@ -30,17 +30,17 @@
     }
 
     @PostMapping("/add")
-    @ApiModelProperty("娣诲姞璁惧缂洪櫡璁板綍")
+    @ApiOperation("娣诲姞璁惧缂洪櫡璁板綍")
     public AjaxResult add(@RequestBody DeviceDefectRecord deviceDefectRecord) {
         return AjaxResult.success(deviceDefectRecordService.add(deviceDefectRecord));
     }
     @PostMapping("/update")
-    @ApiModelProperty("淇敼璁惧缂洪櫡璁板綍")
+    @ApiOperation("淇敼璁惧缂洪櫡璁板綍")
     public AjaxResult update(@RequestBody DeviceDefectRecord deviceDefectRecord) {
         return AjaxResult.success(deviceDefectRecordService.updateByDDR(deviceDefectRecord));
     }
     @DeleteMapping("/delete")
-    @ApiModelProperty("鍒犻櫎璁惧缂洪櫡璁板綍")
+    @ApiOperation("鍒犻櫎璁惧缂洪櫡璁板綍")
     public AjaxResult delete(@PathVariable Long id) {
         return AjaxResult.success(deviceDefectRecordService.removeById(id));
     }
diff --git a/src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java b/src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java
index f1e88ff..f79d4d2 100644
--- a/src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java
+++ b/src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java
@@ -12,7 +12,6 @@
 import com.ruoyi.framework.aspectj.lang.annotation.Anonymous;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -39,33 +38,33 @@
 
 
 
-    @ApiModelProperty("璁惧鍙拌处鍒楄〃")
+    @ApiOperation("璁惧鍙拌处鍒楄〃")
     @GetMapping("/page")
     public AjaxResult page(Page page , DeviceLedgerDto deviceLedger) {
         return AjaxResult.success(deviceLedgerService.queryPage(page,deviceLedger));
     }
 
     @PostMapping()
-    @ApiModelProperty("娣诲姞璁惧鍙拌处")
+    @ApiOperation("娣诲姞璁惧鍙拌处")
     public AjaxResult add(@RequestBody DeviceLedger deviceLedger) {
 
         return deviceLedgerService.saveDeviceLedger(deviceLedger);
     }
 
-    @ApiModelProperty("鏍规嵁id鏌ヨ璁惧鍙拌处")
+    @ApiOperation("鏍规嵁id鏌ヨ璁惧鍙拌处")
     @GetMapping("/{id}")
     public AjaxResult detail(@PathVariable Long id) {
         return AjaxResult.success(deviceLedgerService.getById(id));
     }
 
     @PutMapping ()
-    @ApiModelProperty("淇敼璁惧鍙拌处")
+    @ApiOperation("淇敼璁惧鍙拌处")
     public AjaxResult update(@RequestBody DeviceLedger deviceLedger) {
         return deviceLedgerService.updateDeviceLedger(deviceLedger);
     }
 
     @DeleteMapping("/{ids}")
-    @ApiModelProperty("鍒犻櫎璁惧鍙拌处")
+    @ApiOperation("鍒犻櫎璁惧鍙拌处")
     public AjaxResult delete(@PathVariable("ids") ArrayList<Long> ids) {
         boolean b = deviceLedgerService.removeBatchByIds(ids);
         if (!b) {
@@ -75,13 +74,13 @@
     }
 
     @PostMapping("export")
-    @ApiModelProperty("瀵煎嚭璁惧鍙拌处")
+    @ApiOperation("瀵煎嚭璁惧鍙拌处")
     public void export(HttpServletResponse response, Long[] ids) {
          deviceLedgerService.export(response, ids);
     }
 
     @PostMapping("import")
-    @ApiModelProperty("瀵煎叆璁惧鍙拌处")
+    @ApiOperation("瀵煎叆璁惧鍙拌处")
     public AjaxResult importData(MultipartFile file) throws IOException {
         Boolean b = deviceLedgerService.importData(file);
         if (b) {
@@ -92,7 +91,7 @@
 
 
     @GetMapping("getDeviceLedger")
-    @ApiModelProperty("鑾峰彇璁惧鍙拌处")
+    @ApiOperation("鑾峰彇璁惧鍙拌处")
     public AjaxResult getDeviceLedger( ) {
         return AjaxResult.success(deviceLedgerService.list(new QueryWrapper<DeviceLedger>().lambda()
                 .select(DeviceLedger::getId, DeviceLedger::getDeviceName,DeviceLedger::getDeviceModel)));
diff --git a/src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java b/src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java
index 09e7b22..0804b79 100644
--- a/src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java
+++ b/src/main/java/com/ruoyi/device/controller/DeviceMaintenanceController.java
@@ -9,7 +9,7 @@
 import com.ruoyi.device.service.IDeviceMaintenanceService;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -28,14 +28,14 @@
     @Autowired
     private IDeviceLedgerService deviceLedgerService;
 
-    @ApiModelProperty("璁惧淇濆吇鍒楄〃")
+    @ApiOperation("璁惧淇濆吇鍒楄〃")
     @GetMapping("/page")
     public AjaxResult page(Page page , DeviceMaintenanceDto deviceMaintenanceDto) {
         return AjaxResult.success(deviceMaintenanceService.queryPage(page,deviceMaintenanceDto));
     }
 
     @PostMapping()
-    @ApiModelProperty("娣诲姞璁惧淇濆吇")
+    @ApiOperation("娣诲姞璁惧淇濆吇")
     public AjaxResult add(@RequestBody DeviceMaintenance deviceMaintenance) {
         DeviceLedger byId = deviceLedgerService.getById(deviceMaintenance.getDeviceLedgerId());
         deviceMaintenance.setDeviceName(byId.getDeviceName());
@@ -43,14 +43,14 @@
         return deviceMaintenanceService.saveDeviceRepair(deviceMaintenance);
     }
 
-    @ApiModelProperty("鏍规嵁id鏌ヨ璁惧淇濆吇")
+    @ApiOperation("鏍规嵁id鏌ヨ璁惧淇濆吇")
     @GetMapping("/{id}")
     public AjaxResult detail(@PathVariable Long id) {
         return AjaxResult.success(deviceMaintenanceService.detailById(id));
     }
 
     @PutMapping ()
-    @ApiModelProperty("淇敼璁惧淇濆吇")
+    @ApiOperation("淇敼璁惧淇濆吇")
     public AjaxResult update(@RequestBody DeviceMaintenance deviceMaintenance) {
         DeviceLedger byId = deviceLedgerService.getById(deviceMaintenance.getDeviceLedgerId());
         deviceMaintenance.setDeviceName(byId.getDeviceName());
@@ -59,14 +59,14 @@
     }
 
     @PostMapping ("maintenance")
-    @ApiModelProperty("淇敼璁惧淇濆吇")
+    @ApiOperation("淇敼璁惧淇濆吇")
     public AjaxResult maintenance(@RequestBody DeviceMaintenance deviceMaintenance) {
         return deviceMaintenanceService.updateDeviceDeviceMaintenance(deviceMaintenance);
     }
 
 
     @DeleteMapping("/{ids}")
-    @ApiModelProperty("鍒犻櫎璁惧淇濆吇")
+    @ApiOperation("鍒犻櫎璁惧淇濆吇")
     public AjaxResult delete(@PathVariable("ids") Long[] ids) {
         boolean b = deviceMaintenanceService.removeBatchByIds(Arrays.asList(ids));
         if (!b) {
@@ -76,7 +76,7 @@
     }
 
     @PostMapping("export")
-    @ApiModelProperty("瀵煎嚭璁惧淇濆吇")
+    @ApiOperation("瀵煎嚭璁惧淇濆吇")
     public void export(HttpServletResponse response, Long[] ids) {
         deviceMaintenanceService.export(response, ids);
     }
diff --git a/src/main/java/com/ruoyi/device/controller/DeviceRepairController.java b/src/main/java/com/ruoyi/device/controller/DeviceRepairController.java
index d33b340..7ac0907 100644
--- a/src/main/java/com/ruoyi/device/controller/DeviceRepairController.java
+++ b/src/main/java/com/ruoyi/device/controller/DeviceRepairController.java
@@ -8,7 +8,7 @@
 import com.ruoyi.device.service.IDeviceRepairService;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -26,19 +26,19 @@
     @Autowired
     private IDeviceLedgerService deviceLedgerService;
 
-    @ApiModelProperty("璁惧鎶ヤ慨鍒楄〃")
+    @ApiOperation("璁惧鎶ヤ慨鍒楄〃")
     @GetMapping("/page")
     public AjaxResult page(Page page , DeviceRepairDto deviceRepairDto) {
         return AjaxResult.success(deviceRepairService.queryPage(page,deviceRepairDto));
     }
 
     @PostMapping()
-    @ApiModelProperty("娣诲姞璁惧鎶ヤ慨")
+    @ApiOperation("娣诲姞璁惧鎶ヤ慨")
     public AjaxResult add( @RequestBody DeviceRepair deviceRepair) {
         return deviceRepairService.saveDeviceRepair(deviceRepair);
     }
 
-    @ApiModelProperty("鏍规嵁id鏌ヨ璁惧鎶ヤ慨")
+    @ApiOperation("鏍规嵁id鏌ヨ璁惧鎶ヤ慨")
     @GetMapping("/{id}")
     public AjaxResult detail(@PathVariable Long id) {
         DeviceRepairDto byId = deviceRepairService.detailById(id);
@@ -46,19 +46,19 @@
     }
 
     @PutMapping ()
-    @ApiModelProperty("淇敼璁惧鎶ヤ慨")
+    @ApiOperation("淇敼璁惧鎶ヤ慨")
     public AjaxResult update( @RequestBody DeviceRepair deviceRepair) {
         return deviceRepairService.updateDeviceRepair(deviceRepair);
     }
 
     @PostMapping ("repair")
-    @ApiModelProperty("璁惧缁翠慨")
+    @ApiOperation("璁惧缁翠慨")
     public AjaxResult repair( @RequestBody DeviceRepair deviceRepair) {
         return deviceRepairService.updateDeviceRepair(deviceRepair);
     }
 
     @DeleteMapping("/{ids}")
-    @ApiModelProperty("鍒犻櫎璁惧鎶ヤ慨")
+    @ApiOperation("鍒犻櫎璁惧鎶ヤ慨")
     public AjaxResult delete(@PathVariable("ids") Long[] ids) {
         boolean b = deviceRepairService.removeBatchByIds(Arrays.asList(ids));
         if (!b) {
@@ -68,7 +68,7 @@
     }
 
     @PostMapping("export")
-    @ApiModelProperty("瀵煎嚭璁惧鎶ヤ慨")
+    @ApiOperation("瀵煎嚭璁惧鎶ヤ慨")
     public void export(HttpServletResponse response, Long[] ids) {
         deviceRepairService.export(response, ids);
     }
diff --git a/src/main/java/com/ruoyi/home/controller/HomeController.java b/src/main/java/com/ruoyi/home/controller/HomeController.java
index 3224c0f..edda887 100644
--- a/src/main/java/com/ruoyi/home/controller/HomeController.java
+++ b/src/main/java/com/ruoyi/home/controller/HomeController.java
@@ -36,6 +36,31 @@
     @Autowired
     private HomeService homeService;
 
+    /********************************************************鍩虹绫�*****************************************************/
+    @GetMapping("/todos")
+    @Log(title = "寰呭姙浜嬮」", businessType = BusinessType.OTHER)
+    @ApiOperation("寰呭姙浜嬮」")
+    public AjaxResult todos(ApproveProcess req) throws ParseException {
+        List<ApproveProcess> approveProcessList = homeService.todos();
+        return AjaxResult.success(approveProcessList);
+    }
+
+    @GetMapping("/approveAndDeviceTodos")
+    @ApiOperation("瀹℃壒鍗忓悓锛岃澶囨姤淇緟鍔炰簨椤�")
+    public AjaxResult approveAndDeviceTodos(){
+        Map<String, Object> map = homeService.approveAndDeviceTodos();
+        return AjaxResult.success(map);
+    }
+
+    @GetMapping("/noticesCount")
+    @ApiOperation("鏈繃鏈熺殑鍏憡鏁伴噺")
+    public AjaxResult noticesCount(){
+        Long count = homeService.noticesCount();
+        return AjaxResult.success(count);
+    }
+
+
+    /********************************************************钀ラ攢閲囪喘绫�**************************************************/
     @GetMapping("/business")
     @Log(title = "閿�鍞�-閲囪喘-搴撳瓨鏁版嵁", businessType = BusinessType.OTHER)
     @ApiOperation("閿�鍞�-閲囪喘-搴撳瓨鏁版嵁")
@@ -53,43 +78,8 @@
         return AjaxResult.success(analysisCustomerContractAmounts);
     }
 
-    @GetMapping("/qualityStatistics")
-    @Log(title = "璐ㄩ噺鍒嗘瀽", businessType = BusinessType.OTHER)
-    @ApiOperation("璐ㄩ噺鍒嗘瀽")
-    public AjaxResult qualityStatistics(QualityStatisticsDto req) {
-        QualityStatisticsDto qualityStatisticsDto = homeService.qualityStatistics();
-        return AjaxResult.success(qualityStatisticsDto);
-    }
 
-    @GetMapping("/todos")
-    @Log(title = "寰呭姙浜嬮」", businessType = BusinessType.OTHER)
-    @ApiOperation("寰呭姙浜嬮」")
-    public AjaxResult todos(ApproveProcess req) throws ParseException {
-        List<ApproveProcess> approveProcessList = homeService.todos();
-        return AjaxResult.success(approveProcessList);
-    }
-
-    @GetMapping("/statisticsReceivablePayable")
-    @Log(title = "搴旀敹搴斾粯缁熻", businessType = BusinessType.OTHER)
-    @ApiOperation("搴旀敹搴斾粯缁熻")
-    public AjaxResult statisticsReceivablePayable(StatisticsReceivablePayableDto req, @RequestParam(value = "type", defaultValue = "1") Integer type ) {
-        StatisticsReceivablePayableDto statisticsReceivablePayable = homeService.statisticsReceivablePayable(type);
-        return AjaxResult.success(statisticsReceivablePayable);
-    }
-
-    @GetMapping("/approveAndDeviceTodos")
-    @ApiOperation("瀹℃壒鍗忓悓锛岃澶囨姤淇緟鍔炰簨椤�")
-    public AjaxResult approveAndDeviceTodos(){
-        Map<String, Object> map = homeService.approveAndDeviceTodos();
-        return AjaxResult.success(map);
-    }
-
-    @GetMapping("/noticesCount")
-    @ApiOperation("鏈繃鏈熺殑鍏憡鏁伴噺")
-    public AjaxResult noticesCount(){
-        Long count = homeService.noticesCount();
-        return AjaxResult.success(count);
-    }
+    /********************************************************鐢熶骇绫�*****************************************************/
     @GetMapping("/progressStatistics")
     @ApiOperation("鍚勭敓浜ц鍗曠殑瀹屾垚杩涘害缁熻")
     public AjaxResult progressStatistics(){
@@ -102,4 +92,38 @@
         ProductionTurnoverDto productionTurnoverDto = homeService.workInProcessTurnover();
         return AjaxResult.success(productionTurnoverDto);
     }
+
+
+    /********************************************************璐ㄩ噺绫�*****************************************************/
+    @GetMapping("/qualityStatistics")
+    @Log(title = "璐ㄩ噺鍒嗘瀽", businessType = BusinessType.OTHER)
+    @ApiOperation("璐ㄩ噺鍒嗘瀽")
+    public AjaxResult qualityStatistics(QualityStatisticsDto req) {
+        QualityStatisticsDto qualityStatisticsDto = homeService.qualityStatistics();
+        return AjaxResult.success(qualityStatisticsDto);
+    }
+
+
+    /********************************************************璐㈠姟绫�*****************************************************/
+    @GetMapping("/statisticsReceivablePayable")
+    @Log(title = "搴旀敹搴斾粯缁熻", businessType = BusinessType.OTHER)
+    @ApiOperation("搴旀敹搴斾粯缁熻")
+    public AjaxResult statisticsReceivablePayable(StatisticsReceivablePayableDto req, @RequestParam(value = "type", defaultValue = "1") Integer type ) {
+        StatisticsReceivablePayableDto statisticsReceivablePayable = homeService.statisticsReceivablePayable(type);
+        return AjaxResult.success(statisticsReceivablePayable);
+    }
+
+
+    /********************************************************浠撳偍绫�*****************************************************/
+
+
+
+
+
+
+
+
+
+
+
 }
diff --git a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
index 4ff36ac..4ceed69 100644
--- a/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
+++ b/src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -400,8 +400,8 @@
         LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>();
         approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveDelete, 0)
                 .eq(ApproveProcess::getApproveUserCurrentId, loginUser.getUserId())
-                .ne(ApproveProcess::getApproveStatus, 2)
-                .eq(ApproveProcess::getTenantId, loginUser.getTenantId());
+                .ne(ApproveProcess::getApproveStatus, 2);
+//                .eq(ApproveProcess::getTenantId, loginUser.getTenantId());
         List<ApproveProcess> approveProcesses = approveProcessMapper.selectList(approveProcessLambdaQueryWrapper);
         if(CollectionUtils.isEmpty(approveProcesses)){
             approveProcesses = new ArrayList<>();
diff --git a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
index 0d61f87..f9a21d6 100644
--- a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
+++ b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -1,11 +1,21 @@
 package com.ruoyi.procurementrecord.utils;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
 import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
+import com.ruoyi.stock.dto.StockInRecordDto;
+import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.dto.StockUninventoryDto;
+import com.ruoyi.stock.pojo.StockInRecord;
+import com.ruoyi.stock.service.StockInRecordService;
+import com.ruoyi.stock.service.StockInventoryService;
+import com.ruoyi.stock.service.StockUninventoryService;
+import com.ruoyi.stock.service.impl.StockInRecordServiceImpl;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -14,6 +24,9 @@
 public class StockUtils {
     private final ProcurementRecordOutMapper procurementRecordOutMapper;
     private final ProcurementRecordMapper procurementRecordMapper;
+    private final StockUninventoryService stockUninventoryService;
+    private final StockInventoryService stockInventoryService;
+    private final StockInRecordService stockInRecordService;
 
     // 鑾峰彇鍟嗗搧鍏ュ簱鏁伴噺,鍑哄簱鏁伴噺,鍓╀綑搴撳瓨
     public Map<String, BigDecimal> getStockQuantity(Long productModelId) {
@@ -29,4 +42,77 @@
         stockMap.put("stockQuantity", stockQuantity);
         return stockMap;
     }
+
+    /**
+     * 涓嶅悎鏍煎叆搴�
+     * @param productModelId
+     * @param quantity
+     * @param recordType
+     * @param recordId
+     */
+    public void addUnStock(Long productModelId, BigDecimal quantity, Integer recordType,Long recordId) {
+        StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
+        stockUninventoryDto.setRecordId(recordId);
+        stockUninventoryDto.setRecordType(String.valueOf(recordType));
+        stockUninventoryDto.setQualitity(quantity);
+        stockUninventoryDto.setProductModelId(productModelId);
+        stockUninventoryService.addStockUninventory(stockUninventoryDto);
+    }
+
+    /**
+     * 涓嶅悎鏍煎嚭搴�
+     * @param productModelId
+     * @param quantity
+     * @param recordType
+     * @param recordId
+     */
+    public void subtractUnStock(Long productModelId, BigDecimal quantity, Integer recordType,Long recordId) {
+        StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
+        stockUninventoryDto.setRecordId(recordId);
+        stockUninventoryDto.setRecordType(String.valueOf(recordType));
+        stockUninventoryDto.setQualitity(quantity);
+        stockUninventoryDto.setProductModelId(productModelId);
+        stockUninventoryService.subtractStockUninventory(stockUninventoryDto);
+    }
+
+    /**
+     * 鍚堟牸鍏ュ簱
+     * @param productModelId
+     * @param quantity
+     * @param recordType
+     * @param recordId
+     */
+    public void addStock(Long productModelId, BigDecimal quantity, Integer recordType,Long recordId) {
+        StockInventoryDto stockInventoryDto = new StockInventoryDto();
+        stockInventoryDto.setRecordId(recordId);
+        stockInventoryDto.setRecordType(String.valueOf(recordType));
+        stockInventoryDto.setQualitity(quantity);
+        stockInventoryDto.setProductModelId(productModelId);
+        stockInventoryService.addstockInventory(stockInventoryDto);
+    }
+
+    /**
+     * 鍚堟牸鍑哄簱
+     * @param productModelId
+     * @param quantity
+     * @param recordType
+     * @param recordId
+     */
+    public void substractStock(Long productModelId, BigDecimal quantity, Integer recordType,Long recordId) {
+        StockInventoryDto stockInventoryDto = new StockInventoryDto();
+        stockInventoryDto.setRecordId(recordId);
+        stockInventoryDto.setRecordType(String.valueOf(recordType));
+        stockInventoryDto.setQualitity(quantity);
+        stockInventoryDto.setProductModelId(productModelId);
+        stockInventoryService.subtractStockInventory(stockInventoryDto);
+    }
+
+    //涓嶅悎鏍煎簱瀛樺垹闄�
+    public void deleteStockRecord(Long recordId, Integer recordType) {
+        StockInRecord one = stockInRecordService.getOne(new QueryWrapper<StockInRecord>()
+                .lambda().eq(StockInRecord::getRecordId, recordId)
+                .eq(StockInRecord::getRecordType, recordType));
+
+        stockInRecordService.batchDelete(Collections.singletonList(one.getId()));
+    }
 }
diff --git a/src/main/java/com/ruoyi/production/controller/ProductBomController.java b/src/main/java/com/ruoyi/production/controller/ProductBomController.java
index 7279862..b225685 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductBomController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductBomController.java
@@ -8,14 +8,9 @@
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.production.dto.ProductBomDto;
 import com.ruoyi.production.dto.ProductProcessDto;
-import com.ruoyi.production.pojo.ProcessRoute;
-import com.ruoyi.production.pojo.ProductBom;
-import com.ruoyi.production.pojo.ProductProcess;
-import com.ruoyi.production.pojo.ProductProcessRoute;
-import com.ruoyi.production.service.ProcessRouteService;
-import com.ruoyi.production.service.ProductBomService;
-import com.ruoyi.production.service.ProductProcessRouteService;
-import com.ruoyi.production.service.ProductProcessService;
+import com.ruoyi.production.pojo.*;
+import com.ruoyi.production.service.*;
+import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -34,6 +29,7 @@
  */
 @RestController
 @RequestMapping("/productBom")
+@Api(tags = "BOM")
 public class ProductBomController {
 
     @Autowired
@@ -44,6 +40,9 @@
 
     @Autowired
     private ProductProcessRouteService productProcessRouteService;
+
+    @Autowired
+    private ProductStructureService productStructureService;
 
     @GetMapping("/listPage")
     @Log(title = "BOM-鍒嗛〉鏌ヨ", businessType = BusinessType.OTHER)
@@ -79,6 +78,8 @@
         if(CollectionUtils.isEmpty(ids)){
             return AjaxResult.error("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
         }
+        //鍒犻櫎bom瀛愯〃
+        productStructureService.remove(Wrappers.<ProductStructure>lambdaQuery().in(ProductStructure::getBomId,ids));
         return AjaxResult.success(productBomService.removeBatchByIds(ids));
     }
 
diff --git a/src/main/java/com/ruoyi/production/controller/ProductStructureController.java b/src/main/java/com/ruoyi/production/controller/ProductStructureController.java
index 2f99a00..5d28332 100644
--- a/src/main/java/com/ruoyi/production/controller/ProductStructureController.java
+++ b/src/main/java/com/ruoyi/production/controller/ProductStructureController.java
@@ -26,13 +26,13 @@
     private ProductStructureService productStructureService;
 
 
-    @ApiOperation("鏂板BOM")
+    @ApiOperation("鏂板BOM瀛愰泦")
     @PostMapping()
     public R addOrUpdate(@RequestBody ProductStructureDto productStructureDto){
         return R.ok(productStructureService.addProductStructureDto(productStructureDto));
     }
 
-    @ApiOperation("BOM鏌ョ湅璇︽儏")
+    @ApiOperation("BOM鏌ョ湅瀛愰泦璇︽儏")
     @GetMapping("/listBybomId/{bomId}")
     public R listBybomId( @PathVariable("bomId") Long bomId){
         return R.ok(productStructureService.listBybomId(bomId));
diff --git a/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java b/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
index 843e4a6..08d65fa 100644
--- a/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
@@ -27,6 +27,10 @@
     @Excel(name = "鎶ュ伐鏁伴噺")
     private BigDecimal quantity;
 
+    @ApiModelProperty(value = "鎶ュ簾鏁伴噺")
+    @Excel(name = "鎶ュ簾鏁伴噺")
+    private BigDecimal scrapQty;
+
     //浜у搧鍚嶇О
     @Excel(name = "浜у搧鍚嶇О")
     private String productName;
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
index c9d1268..2bdefa3 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
@@ -4,6 +4,7 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.production.dto.ProductionProductMainDto;
+import com.ruoyi.production.pojo.ProductOrder;
 import com.ruoyi.production.pojo.ProductionProductMain;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
@@ -19,4 +20,11 @@
      * 鏍规嵁宸ュ崟ID鎵归噺鍒犻櫎鐢熶骇涓昏〃鏁版嵁
      */
     int deleteByWorkOrderIds(@Param("workOrderIds") List<Long> workOrderIds);
+
+    /**
+     * 鏍规嵁鎶ュ伐id鏌ヨ鐢熶骇璁㈠崟
+     * @param productMainId
+     * @return
+     */
+    ProductOrder getOrderByMainId(@Param("productMainId") Long productMainId);
 }
diff --git a/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java b/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
index 20e52ad..20417ae 100644
--- a/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
+++ b/src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
@@ -20,7 +20,8 @@
     @ApiModelProperty(value = "浜у搧id")
     private Long productModelId;
 
-    @ApiModelProperty(value = "鏁伴噺")
+    //鍚堟牸鏁伴噺=鎶ュ伐鏁伴噺-鎶ュ簾鏁伴噺
+    @ApiModelProperty(value = "鎶ュ伐鏁伴噺")
     private BigDecimal quantity;
 
     @ApiModelProperty(value = "鍒涘缓鏃堕棿")
@@ -29,4 +30,7 @@
     @ApiModelProperty(value = "绉熸埛ID")
     @TableField(fill = FieldFill.INSERT)
     private Long tenantId;
+
+    @ApiModelProperty(value = "鎶ュ簾鏁伴噺")
+    private BigDecimal scrapQty;
 }
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
index 5d1e454..24db6e4 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -2,8 +2,6 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -13,7 +11,8 @@
 import com.ruoyi.basic.mapper.ProductModelMapper;
 import com.ruoyi.basic.pojo.Product;
 import com.ruoyi.basic.pojo.ProductModel;
-import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
 import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut;
@@ -28,19 +27,15 @@
 import com.ruoyi.project.system.mapper.SysUserMapper;
 import com.ruoyi.quality.mapper.*;
 import com.ruoyi.quality.pojo.*;
-import io.swagger.models.auth.In;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import com.ruoyi.production.mapper.ProductionProductMainMapper;
-import oshi.driver.mac.net.NetStat;
 
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -189,82 +184,92 @@
         productionProductOutput.setProductMainId(productionProductMain.getId());
         productionProductOutput.setProductModelId(productProcessRouteItem.getProductModelId());
         productionProductOutput.setQuantity(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO);
+        productionProductOutput.setScrapQty(dto.getScrapQty() != null ? dto.getScrapQty() : BigDecimal.ZERO);
         productionProductOutputMapper.insert(productionProductOutput);
-        /*鏂板璐ㄦ*/
-        //瀵瑰簲鐨勮繃绋嬫鎴栬�呭嚭鍘傛
-        List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()));
-        int inspectType = 1;
-        String process = productProcess.getName();//宸ュ簭
-        if (productProcessRouteItem.getDragSort()==productProcessRouteItems.size()){
-            //鏈�鍚庝竴閬撳伐搴忕敓鎴愬嚭鍘傛
-            inspectType = 2;
-            process = null;
-        }
-        Product product = productMapper.selectById(productModel.getProductId());
-        QualityInspect qualityInspect = new QualityInspect();
-        qualityInspect.setProductId(product.getId());
-        qualityInspect.setProductName(product.getProductName());
-        qualityInspect.setModel(productModel.getModel());
-        qualityInspect.setUnit(productModel.getUnit());
-        qualityInspect.setQuantity(dto.getQuantity());
-        qualityInspect.setProcess(productProcess.getName());
-        qualityInspect.setInspectState(0);
-        qualityInspect.setInspectType(inspectType);
-        qualityInspect.setProductMainId(productionProductMain.getId());
-        qualityInspect.setProductModelId(productModel.getId());
-        qualityInspectMapper.insert(qualityInspect);
-        List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType,process);
-        if (qualityTestStandard.size()>0){
-            qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId());
-            qualityInspectMapper.updateById(qualityInspect);
-            qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery()
-                    .eq(QualityTestStandardParam::getTestStandardId,qualityTestStandard.get(0).getId()))//榛樿鑾峰彇鏈�鏂扮殑
-                    .forEach(qualityTestStandardParam -> {
-                QualityInspectParam param = new QualityInspectParam();
-                BeanUtils.copyProperties(qualityTestStandardParam, param);
-                param.setId(null);
-                param.setInspectId(qualityInspect.getId());
-                qualityInspectParamMapper.insert(param);
-            });
-        }
-        /*鏇存柊宸ュ崟鍜岀敓浜ц鍗�*/
-        ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId());
-        productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().add(dto.getQuantity()));
-        if (ObjectUtils.isNull(productWorkOrder.getActualStartTime())){
-            productWorkOrder.setActualStartTime(LocalDate.now());//瀹為檯寮�濮嬫椂闂�
-        }
-        if (productWorkOrder.getCompleteQuantity().compareTo(productWorkOrder.getPlanQuantity()) == 0){
-            productWorkOrder.setActualEndTime(LocalDate.now());//瀹為檯缁撴潫鏃堕棿
-        }
-        productWorkOrderMapper.updateById(productWorkOrder);
-        //鐢熶骇璁㈠崟
-        ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
-        if (ObjectUtils.isNull(productOrder.getStartTime())){
-            productOrder.setStartTime(LocalDateTime.now());//寮�濮嬫椂闂�
-        }
-        if (productProcessRouteItem.getDragSort()==productProcessRouteItems.size()){
-            //濡傛灉鏄渶鍚庝竴閬撳伐搴忔姤宸ヤ箣鍚庣敓浜ц鍗曞畬鎴愭暟閲�+
-            productOrder.setCompleteQuantity(productOrder.getCompleteQuantity().add(dto.getQuantity()));
-            if (productOrder.getCompleteQuantity().compareTo(productOrder.getQuantity()) == 0){
-                productOrder.setEndTime(LocalDateTime.now());//缁撴潫鏃堕棿
+        //鍚堟牸鏁伴噺=鎶ュ伐鏁伴噺-鎶ュ簾鏁伴噺
+        BigDecimal productQty = productionProductOutput.getQuantity().subtract(productionProductOutput.getScrapQty());
+        //鍙湁鍚堟牸鏁伴噺>0鎵嶈兘澧炲姞鐩稿簲鏁版嵁
+        if (productQty.compareTo(BigDecimal.ZERO)>0) {
+            /*鏂板璐ㄦ*/
+            //瀵瑰簲鐨勮繃绋嬫鎴栬�呭嚭鍘傛
+            List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()));
+            int inspectType = 1;
+            String process = productProcess.getName();//宸ュ簭
+            if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) {
+                //鏈�鍚庝竴閬撳伐搴忕敓鎴愬嚭鍘傛
+                inspectType = 2;
+                process = null;
             }
+            Product product = productMapper.selectById(productModel.getProductId());
+            QualityInspect qualityInspect = new QualityInspect();
+            qualityInspect.setProductId(product.getId());
+            qualityInspect.setProductName(product.getProductName());
+            qualityInspect.setModel(productModel.getModel());
+            qualityInspect.setUnit(productModel.getUnit());
+            qualityInspect.setQuantity(productQty);
+            qualityInspect.setProcess(productProcess.getName());
+            qualityInspect.setInspectState(0);
+            qualityInspect.setInspectType(inspectType);
+            qualityInspect.setProductMainId(productionProductMain.getId());
+            qualityInspect.setProductModelId(productModel.getId());
+            qualityInspectMapper.insert(qualityInspect);
+            List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process);
+            if (qualityTestStandard.size() > 0) {
+                qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId());
+                qualityInspectMapper.updateById(qualityInspect);
+                qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery()
+                        .eq(QualityTestStandardParam::getTestStandardId, qualityTestStandard.get(0).getId()))//榛樿鑾峰彇鏈�鏂扮殑
+                        .forEach(qualityTestStandardParam -> {
+                            QualityInspectParam param = new QualityInspectParam();
+                            BeanUtils.copyProperties(qualityTestStandardParam, param);
+                            param.setId(null);
+                            param.setInspectId(qualityInspect.getId());
+                            qualityInspectParamMapper.insert(param);
+                        });
+            }
+            /*鏇存柊宸ュ崟鍜岀敓浜ц鍗�*/
+            ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId());
+            productWorkOrder.setCompleteQuantity(productQty.add(dto.getQuantity()));
+            if (ObjectUtils.isNull(productWorkOrder.getActualStartTime())) {
+                productWorkOrder.setActualStartTime(LocalDate.now());//瀹為檯寮�濮嬫椂闂�
+            }
+            if (productWorkOrder.getCompleteQuantity().compareTo(productWorkOrder.getPlanQuantity()) == 0) {
+                productWorkOrder.setActualEndTime(LocalDate.now());//瀹為檯缁撴潫鏃堕棿
+            }
+            productWorkOrderMapper.updateById(productWorkOrder);
+            //鐢熶骇璁㈠崟
+            ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
+            if (ObjectUtils.isNull(productOrder.getStartTime())) {
+                productOrder.setStartTime(LocalDateTime.now());//寮�濮嬫椂闂�
+            }
+            if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) {
+                //濡傛灉鏄渶鍚庝竴閬撳伐搴忔姤宸ヤ箣鍚庣敓浜ц鍗曞畬鎴愭暟閲�+
+                productOrder.setCompleteQuantity(productOrder.getCompleteQuantity().add(productQty));
+                if (productOrder.getCompleteQuantity().compareTo(productOrder.getQuantity()) == 0) {
+                    productOrder.setEndTime(LocalDateTime.now());//缁撴潫鏃堕棿
+                }
+            }
+            productOrderMapper.updateById(productOrder);
+            /*娣诲姞鐢熶骇鏍哥畻*/
+            SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder()
+                    .salesLedgerWorkId(productionProductMain.getId())
+                    .salesLedgerSchedulingId(0L)
+                    .salesLedgerId(productOrder.getSalesLedgerId())
+                    .salesLedgerProductId(productOrder.getProductModelId())
+                    .schedulingUserId(user.getUserId())
+                    .schedulingUserName(user.getNickName())
+                    .finishedNum(productQty)
+                    .workHours(productProcess.getSalaryQuota())
+                    .process(productProcess.getName())
+                    .schedulingDate(LocalDate.now())
+                    .tenantId(dto.getTenantId())
+                    .build();
+            salesLedgerProductionAccountingMapper.insert(salesLedgerProductionAccounting);
         }
-        productOrderMapper.updateById(productOrder);
-        /*娣诲姞鐢熶骇鏍哥畻*/
-        SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder()
-                .salesLedgerWorkId(productionProductMain.getId())
-                .salesLedgerSchedulingId(0L)
-                .salesLedgerId(productOrder.getSalesLedgerId())
-                .salesLedgerProductId(productOrder.getProductModelId())
-                .schedulingUserId(user.getUserId())
-                .schedulingUserName(user.getNickName())
-                .finishedNum(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO)
-                .workHours(productProcess.getSalaryQuota())
-                .process(productProcess.getName())
-                .schedulingDate(LocalDate.now())
-                .tenantId(dto.getTenantId())
-                .build();
-        salesLedgerProductionAccountingMapper.insert(salesLedgerProductionAccounting);
+        //濡傛灉鎶ュ簾鏁伴噺>0,闇�瑕佽繘鍏ユ姤搴熺殑搴撳瓨
+        if (dto.getScrapQty().compareTo(BigDecimal.ZERO) > 0) {
+            stockUtils.addUnStock(productModel.getId(), dto.getScrapQty(), StockUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(), productionProductMain.getId());
+        }
         return true;
     }
 
@@ -311,6 +316,8 @@
                 .eq(ProcurementRecordOut::getSalesLedgerProductId, productionProductMain.getId()));
         productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>()
                 .eq(ProductionProductInput::getProductMainId, productionProductMain.getId()));
+        //鍒犻櫎鎶ュ簾鐨勫叆搴撹褰�
+        stockUtils.deleteStockRecord(productionProductMain.getId(), StockUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
         // 鍒犻櫎涓昏〃
         productionProductMainMapper.deleteById(productionProductMain.getId());
         return true;
diff --git a/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java b/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java
index ac4ba6f..ab5d333 100644
--- a/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java
+++ b/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java
@@ -70,10 +70,9 @@
      * 閫氳繃鎸囧畾浜哄彂閫佹彁閱�
      * @param title 鏍囬
      * @param message 娑堟伅
-     * @param tenantId 绉熸埛id
      * @param jumpPath 璺宠浆鍦板潃
      */
-    void simpleNoticeByUser(final String title, final String message, final List<Long> consigneeId, final Long tenantId, final String jumpPath);
+    void simpleNoticeByUser(final String title, final String message, final List<Long> consigneeId,  final String jumpPath);
 
     /**
      * 閫氳繃鎵�鏈変汉 鍙戦�佹彁閱�
@@ -81,6 +80,6 @@
      * @param message 娑堟伅
      * @param jumpPath 璺宠浆鍦板潃
      */
-    void simpleNoticeAll(final String title, final String message,final Long tenantId,final String jumpPath);
+    void simpleNoticeAll(final String title, final String message,final String jumpPath);
 
 }
diff --git a/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java b/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
index 2d21535..bf794b5 100644
--- a/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
+++ b/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
@@ -139,20 +139,20 @@
     }
 
     @Override
-    public void simpleNoticeByUser(String title, String message,  List<Long> consigneeId, Long tenantId,
-                                    String jumpPath) {
+    public void simpleNoticeByUser(String title, String message,  List<Long> consigneeId, String jumpPath) {
         Long userId = SecurityUtils.getLoginUser().getUserId();
+        Long tenantId = SecurityUtils.getLoginUser().getTenantId();
         List<SysNotice> sysNotices = consigneeId.stream().map(it -> convertSysNotice(title, message, it,tenantId, jumpPath, userId)).collect(Collectors.toList());
         sysNoticeService.saveBatch(sysNotices);
     }
 
     @Override
-    public void simpleNoticeAll(String title, String message, Long rootDeptId, String jumpPath) {
+    public void simpleNoticeAll(String title, String message,  String jumpPath) {
         Long userId = SecurityUtils.getLoginUser().getUserId();
         if (userId == null) {
             return;
         }
-
+        Long rootDeptId = SecurityUtils.getLoginUser().getTenantId();
         //  鏌ユ墍鏈夊瓙閮ㄩ棬
         List<SysDept> childrenDepts = deptMapper.selectChildrenDeptById(rootDeptId);
 
diff --git a/src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java b/src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
index 1406667..ec8716f 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
@@ -30,7 +30,6 @@
 import com.ruoyi.sales.mapper.CommonFileMapper;
 import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
 import com.ruoyi.sales.pojo.CommonFile;
-import com.ruoyi.sales.pojo.InvoiceRegistrationProduct;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.sales.service.ISalesLedgerProductService;
 import lombok.RequiredArgsConstructor;
@@ -458,7 +457,7 @@
         BeanUtils.copyProperties(purchaseLedger, purchaseLedgerDto);
         SalesLedgerProduct salesLedgerProduct = new SalesLedgerProduct();
         salesLedgerProduct.setSalesLedgerId(id);
-        salesLedgerProduct.setType(SalesLedgerType.SALES_LEDGER_TYPE_SALES_LEDGER.getValue());
+        salesLedgerProduct.setType(SalesLedgerType.SALES_LEDGER_TYPE_SALES_LEDGER.getCode());
         List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductService.selectSalesLedgerProductList(salesLedgerProduct);
         purchaseLedgerDto.setProductData(salesLedgerProducts);
         List<CommonFile> commonFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java b/src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java
index 7a42873..1cce084 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java
@@ -86,5 +86,15 @@
         qualityUnqualifiedService.qualityUnqualifiedExport(response, qualityUnqualified);
     }
 
+    /**
+     * 涓嶅悎鏍肩鐞嗗鐞�
+     * @param qualityUnqualified
+     * @return
+     */
+    @PostMapping("/deal")
+    public AjaxResult deal(@RequestBody QualityUnqualified qualityUnqualified) {
+        return AjaxResult.success(qualityUnqualifiedService.deal(qualityUnqualified));
+    }
+
 
 }
diff --git a/src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java b/src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java
index 5636c2f..eaebece 100644
--- a/src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java
+++ b/src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java
@@ -133,5 +133,6 @@
     @TableField(fill = FieldFill.INSERT)
     private Long tenantId;
 
-
+    @ApiModelProperty("鍏宠仈妫�娴媔d")
+    private Long inspectId;
 }
diff --git a/src/main/java/com/ruoyi/quality/service/IQualityUnqualifiedService.java b/src/main/java/com/ruoyi/quality/service/IQualityUnqualifiedService.java
index 3aed832..7cd7f79 100644
--- a/src/main/java/com/ruoyi/quality/service/IQualityUnqualifiedService.java
+++ b/src/main/java/com/ruoyi/quality/service/IQualityUnqualifiedService.java
@@ -14,4 +14,7 @@
     IPage<QualityUnqualified> qualityUnqualifiedListPage(Page page, QualityUnqualified qualityUnqualified);
 
     void qualityUnqualifiedExport(HttpServletResponse response, QualityUnqualified qualityUnqualified);
+
+    int deal(QualityUnqualified qualityUnqualified);
+
 }
diff --git a/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java b/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
index 48b055b..bdcff3a 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -8,15 +8,11 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.deepoove.poi.XWPFTemplate;
 import com.deepoove.poi.config.Configure;
-import com.ruoyi.common.exception.base.BaseException;
+import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
 import com.ruoyi.common.utils.HackLoopTableRenderPolicy;
-import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
-import com.ruoyi.framework.security.LoginUser;
-import com.ruoyi.procurementrecord.dto.Details;
-import com.ruoyi.procurementrecord.dto.ProcurementAddDto;
-import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
 import com.ruoyi.procurementrecord.service.ProcurementRecordService;
+import com.ruoyi.procurementrecord.utils.StockUtils;
 import com.ruoyi.quality.dto.QualityInspectDto;
 import com.ruoyi.quality.mapper.QualityInspectMapper;
 import com.ruoyi.quality.mapper.QualityTestStandardMapper;
@@ -27,7 +23,6 @@
 import com.ruoyi.quality.service.IQualityInspectParamService;
 import com.ruoyi.quality.service.IQualityInspectService;
 import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
-import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import lombok.AllArgsConstructor;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
@@ -36,10 +31,7 @@
 import javax.servlet.http.HttpServletResponse;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.math.BigDecimal;
 import java.net.URLEncoder;
-import java.time.LocalDateTime;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -47,8 +39,9 @@
 @AllArgsConstructor
 @Service
 @Transactional(rollbackFor = Exception.class)
-public class QualityInspectServiceImpl extends ServiceImpl<QualityInspectMapper, QualityInspect>  implements IQualityInspectService {
+public class QualityInspectServiceImpl extends ServiceImpl<QualityInspectMapper, QualityInspect> implements IQualityInspectService {
 
+    private final StockUtils stockUtils;
     private QualityInspectMapper qualityInspectMapper;
 
     private IQualityInspectParamService qualityInspectParamService;
@@ -64,7 +57,7 @@
     @Override
     public int add(QualityInspectDto qualityInspectDto) {
         QualityInspect qualityInspect = new QualityInspect();
-        BeanUtils.copyProperties(qualityInspectDto,qualityInspect);
+        BeanUtils.copyProperties(qualityInspectDto, qualityInspect);
         qualityInspect.setInspectState(0);//榛樿鏈彁浜�
         qualityInspectMapper.insert(qualityInspect);
         for (QualityInspectParam qualityInspectParam : qualityInspectDto.getQualityInspectParams()) {
@@ -79,7 +72,7 @@
         QualityInspect qualityInspect = qualityInspectMapper.selectById(id);
         List<QualityInspectParam> qualityInspectParams = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, id));
         QualityInspectDto qualityInspectDto = new QualityInspectDto();
-        BeanUtils.copyProperties(qualityInspect,qualityInspectDto);
+        BeanUtils.copyProperties(qualityInspect, qualityInspectDto);
         qualityInspectDto.setQualityInspectParams(qualityInspectParams);
         return qualityInspectDto;
     }
@@ -89,91 +82,18 @@
     public int submit(QualityInspect inspect) {
         QualityInspect qualityInspect = qualityInspectMapper.selectById(inspect.getId());
         /*鍒ゆ柇涓嶅悎鏍�*/
-        if (ObjectUtils.isNotNull(qualityInspect.getCheckResult()) && qualityInspect.getCheckResult().equals("涓嶅悎鏍�")){
+        if (ObjectUtils.isNotNull(qualityInspect.getCheckResult()) && qualityInspect.getCheckResult().equals("涓嶅悎鏍�")) {
             QualityUnqualified qualityUnqualified = new QualityUnqualified();
-            BeanUtils.copyProperties(qualityInspect,qualityUnqualified);
+            BeanUtils.copyProperties(qualityInspect, qualityUnqualified);
             qualityUnqualified.setInspectState(0);//寰呭鐞�
             List<QualityInspectParam> inspectParams = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, inspect.getId()));
             String text = inspectParams.stream().map(QualityInspectParam::getParameterItem).collect(Collectors.joining(","));
-            qualityUnqualified.setDefectivePhenomena(text+"杩欎簺鎸囨爣涓瓨鍦ㄤ笉鍚堟牸");//涓嶅悎鏍肩幇璞�
+            qualityUnqualified.setDefectivePhenomena(text + "杩欎簺鎸囨爣涓瓨鍦ㄤ笉鍚堟牸");//涓嶅悎鏍肩幇璞�
+            qualityUnqualified.setInspectId(qualityInspect.getId());
             qualityUnqualifiedMapper.insert(qualityUnqualified);
-        }
-
-        LoginUser loginUser = SecurityUtils.getLoginUser();
-        if (qualityInspect.getInspectType() == 0) {
-            if ("鍚堟牸".equals(qualityInspect.getCheckResult())) {
-                ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
-                procurementRecordOutAdd.setType(1);
-                procurementRecordOutAdd.setTypeName("閲囪喘鍘熸潗鏂欐楠屽悎鏍煎叆搴�");
-                procurementRecordOutAdd.setNickName(loginUser.getNickName());
-                procurementRecordOutAdd.setPurchaseLedgerId(Math.toIntExact(qualityInspect.getPurchaseLedgerId()));
-                if (qualityInspect.getPurchaseLedgerId() == null) {
-                    throw new BaseException("璇烽�夋嫨閲囪喘鍗�");
-                }
-                SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(qualityInspect.getProductId());
-
-                ArrayList<Details> detailss = new ArrayList<>();
-                Details details = new Details();
-                details.setId(Math.toIntExact(salesLedgerProduct.getId()));
-                details.setInboundQuantity(qualityInspect.getQuantity());
-                details.setWarnNum(salesLedgerProduct.getWarnNum());
-                details.setUnitPrice(salesLedgerProduct.getTaxInclusiveUnitPrice());
-                details.setTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice());
-                details.setProductModelId(qualityInspect.getProductModelId());
-                detailss.add( details);
-                procurementRecordOutAdd.setDetails(detailss);
-                procurementRecordOutAdd.setQualityInspectId(qualityInspect.getId());
-                procurementRecordService.add(procurementRecordOutAdd);
-            }
-        }else if (qualityInspect.getInspectType() == 1) {
-            //鏌ヨUnitPrice/TotalPrice
-            ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
-            procurementRecordOutAdd.setType(2);
-            procurementRecordOutAdd.setTypeName("鐢熶骇杩囩▼妫�楠屽悎鏍煎叆搴�");
-            procurementRecordOutAdd.setNickName(loginUser.getNickName());
-            List<Details> details = new ArrayList<>();
-            Details details1 = new Details();
-            details1.setInboundQuantity(qualityInspect.getQuantity());
-            details1.setProductModelId(qualityInspect.getProductModelId());
-            procurementRecordOutAdd.setDetails(details);
-
-            ProcurementRecordStorage.ProcurementRecordStorageBuilder procurementRecordBuilder = ProcurementRecordStorage.builder()
-                    .salesLedgerProductId(0)
-                    .inboundBatches( "鐢熶骇鍗婃垚鍝佸叆搴�")
-                    .inboundNum(details1.getInboundQuantity())
-                    .type(2)
-                    .warnNum(new BigDecimal(0))
-                    .unitPrice(new BigDecimal(0))
-                    .totalPrice(new BigDecimal(0))
-                    .createTime(LocalDateTime.now())
-                    .createUser(loginUser.getUserId())
-                    .updateTime(LocalDateTime.now())
-                    .updateUser(loginUser.getUserId())
-                    .createBy(procurementRecordOutAdd.getNickName())
-                    .productModelId(details1.getProductModelId())
-                    .qualityInspectId(qualityInspect.getId());
-            procurementRecordService.save(procurementRecordBuilder.build());
-
-
-
-        }else if (qualityInspect.getInspectType() == 2) {
-            //鏌ヨUnitPrice/TotalPrice
-            SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectSalesLedgerProductByMainId(qualityInspect.getProductMainId());
-            ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
-            procurementRecordOutAdd.setType(2);
-            procurementRecordOutAdd.setTypeName("鐢熶骇鍑哄巶妫�楠屽悎鏍煎叆搴�");
-            procurementRecordOutAdd.setNickName(loginUser.getNickName());
-            List<Details> details = new ArrayList<>();
-            Details details1 = new Details();
-            details1.setInboundQuantity(qualityInspect.getQuantity());
-            details1.setId(Math.toIntExact(salesLedgerProduct.getId()));
-            details1.setUnitPrice(salesLedgerProduct.getTaxInclusiveUnitPrice());
-            details1.setTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice());
-            details1.setProductModelId(salesLedgerProduct.getProductModelId());
-            details.add(details1);
-            procurementRecordOutAdd.setDetails(details);
-            procurementRecordOutAdd.setQualityInspectId(qualityInspect.getId());
-            procurementRecordService.add(procurementRecordOutAdd);
+        } else {
+            //鍚堟牸鐩存帴鍏ュ簱
+            stockUtils.addStock(inspect.getProductModelId(), inspect.getQuantity(), StockQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode(), inspect.getId());
         }
         qualityInspect.setInspectState(1);//宸叉彁浜�
         return qualityInspectMapper.updateById(qualityInspect);
@@ -183,16 +103,16 @@
     @Override
     public void down(HttpServletResponse response, QualityInspect qualityInspect) {
         QualityInspect inspect = qualityInspectMapper.selectById(qualityInspect.getId());
-        String inspectType="";
-        switch (inspect.getInspectType()){
+        String inspectType = "";
+        switch (inspect.getInspectType()) {
             case 0:
-                inspectType="鍘熸潗鏂欐楠�";
+                inspectType = "鍘熸潗鏂欐楠�";
                 break;
             case 1:
-                inspectType="杩囩▼妫�楠�";
+                inspectType = "杩囩▼妫�楠�";
                 break;
             case 2:
-                inspectType="鍑哄巶妫�楠�";
+                inspectType = "鍑哄巶妫�楠�";
                 break;
         }
         List<QualityInspectParam> paramList = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, inspect.getId()));
@@ -234,31 +154,31 @@
     @Override
     public int updateQualityInspect(QualityInspectDto qualityInspectDto) {
         if (ObjectUtils.isNotNull(qualityInspectDto.getQualityInspectParams())) {
-            qualityInspectParamService.remove(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId,qualityInspectDto.getId()));
+            qualityInspectParamService.remove(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, qualityInspectDto.getId()));
             for (QualityInspectParam qualityInspectParam : qualityInspectDto.getQualityInspectParams()) {
                 qualityInspectParam.setInspectId(qualityInspectDto.getId());
             }
             qualityInspectParamService.saveBatch(qualityInspectDto.getQualityInspectParams());
         }
         QualityInspect qualityInspect = new QualityInspect();
-        BeanUtils.copyProperties(qualityInspectDto,qualityInspect);
+        BeanUtils.copyProperties(qualityInspectDto, qualityInspect);
         return qualityInspectMapper.updateById(qualityInspect);
     }
 
     @Override
     public IPage<QualityInspect> qualityInspectListPage(Page page, QualityInspect qualityInspect) {
-        return qualityInspectMapper.qualityInspectListPage(page,qualityInspect);
+        return qualityInspectMapper.qualityInspectListPage(page, qualityInspect);
     }
 
     @Override
     public void qualityInspectExport(HttpServletResponse response, QualityInspect qualityInspect) {
-        List<QualityInspect> qualityInspects =qualityInspectMapper.qualityInspectExport(qualityInspect);
+        List<QualityInspect> qualityInspects = qualityInspectMapper.qualityInspectExport(qualityInspect);
         ExcelUtil<QualityInspect> util = new ExcelUtil<QualityInspect>(QualityInspect.class);
-        switch (qualityInspect.getInspectType()){
+        switch (qualityInspect.getInspectType()) {
             case 0:
                 util.exportExcel(response, qualityInspects, "鍘熸潗鏂欐楠屽鍑�");
                 break;
-            case  1:
+            case 1:
                 util.exportExcel(response, qualityInspects, "杩囩▼妫�楠屽鍑�");
                 break;
             case 2:
diff --git a/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java b/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
index a080dd3..b33ba5c 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
@@ -1,38 +1,146 @@
 package com.ruoyi.quality.service.impl;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 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.utils.bean.BeanUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
-import com.ruoyi.quality.mapper.QualityInspectMapper;
+import com.ruoyi.procurementrecord.utils.StockUtils;
+import com.ruoyi.production.mapper.ProductProcessRouteItemMapper;
+import com.ruoyi.production.mapper.ProductProcessRouteMapper;
+import com.ruoyi.production.mapper.ProductWorkOrderMapper;
+import com.ruoyi.production.mapper.ProductionProductMainMapper;
+import com.ruoyi.production.pojo.*;
+import com.ruoyi.production.service.ProductOrderService;
 import com.ruoyi.quality.mapper.QualityUnqualifiedMapper;
 import com.ruoyi.quality.pojo.QualityInspect;
-import com.ruoyi.quality.pojo.QualityTestStandard;
 import com.ruoyi.quality.pojo.QualityUnqualified;
 import com.ruoyi.quality.service.IQualityInspectService;
 import com.ruoyi.quality.service.IQualityUnqualifiedService;
+import com.ruoyi.stock.service.StockUninventoryService;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 
 import javax.servlet.http.HttpServletResponse;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
 import java.util.List;
 
 @AllArgsConstructor
 @Service
-public class QualityUnqualifiedServiceImpl extends ServiceImpl<QualityUnqualifiedMapper, QualityUnqualified>  implements IQualityUnqualifiedService {
+public class QualityUnqualifiedServiceImpl extends ServiceImpl<QualityUnqualifiedMapper, QualityUnqualified> implements IQualityUnqualifiedService {
 
+    private final StockUtils stockUtils;
     private QualityUnqualifiedMapper qualityUnqualifiedMapper;
+    private IQualityInspectService qualityInspectService;
+    private ProductOrderService productOrderService;
+    private ProductionProductMainMapper productionProductMainMapper;
+    private ProductProcessRouteMapper productProcessRouteMapper;
+    private ProductProcessRouteItemMapper productProcessRouteItemMapper;
+    private ProductWorkOrderMapper productWorkOrderMapper;
+    private StockUninventoryService stockUninventoryService;
 
     @Override
     public IPage<QualityUnqualified> qualityUnqualifiedListPage(Page page, QualityUnqualified qualityUnqualified) {
-        return qualityUnqualifiedMapper.qualityUnqualifiedListPage(page,qualityUnqualified);
+        return qualityUnqualifiedMapper.qualityUnqualifiedListPage(page, qualityUnqualified);
     }
 
     @Override
     public void qualityUnqualifiedExport(HttpServletResponse response, QualityUnqualified qualityUnqualified) {
-        List<QualityUnqualified> qualityUnqualifieds =qualityUnqualifiedMapper.qualityUnqualifiedExport(qualityUnqualified);
+        List<QualityUnqualified> qualityUnqualifieds = qualityUnqualifiedMapper.qualityUnqualifiedExport(qualityUnqualified);
         ExcelUtil<QualityUnqualified> util = new ExcelUtil<QualityUnqualified>(QualityUnqualified.class);
         util.exportExcel(response, qualityUnqualifieds, "涓嶅悎鏍肩鐞嗗鍑�");
     }
+
+    @Override
+    public int deal(QualityUnqualified qualityUnqualified) {
+        QualityUnqualified unqualified = qualityUnqualifiedMapper.selectById(qualityUnqualified.getId());
+        QualityInspect qualityInspect = qualityInspectService.getById(unqualified.getInspectId());
+        switch (qualityUnqualified.getDealResult()) {
+            case "杩斾慨":
+            case "杩斿伐":
+                //鍒ゆ柇璐ㄦ琛ㄦ槸鍚︽湁鐩稿叧鐨勬姤宸d,濡傛灉鏈夋姤宸d,閭d箞杩斿伐闇�瑕侀噸鏂板垱寤虹敓浜ц鍗曢噸鏂扮敓浜�
+                if (ObjectUtils.isNotNull(qualityInspect.getProductMainId())) {
+                    //杩斿伐闇�瑕侀噸鏂板垱寤虹敓浜ц鍗曢噸鏂扮敓浜�
+                    ProductOrder productOrder = productionProductMainMapper.getOrderByMainId(qualityInspect.getProductMainId());
+                    ProductOrder order = new ProductOrder();
+                    BeanUtils.copyProperties(productOrder, order);
+                    order.setId(null);
+                    order.setQuantity(unqualified.getQuantity());
+                    order.setCompleteQuantity(BigDecimal.ZERO);
+                    order.setStartTime(null);
+                    order.setEndTime(null);
+                    productOrderService.save(order);
+                    //鏂板鐢熶骇璁㈠崟涓嬬殑宸ヨ壓璺嚎涓昏〃
+                    ProductProcessRoute productProcessRoute = productProcessRouteMapper.selectList(Wrappers.<ProductProcessRoute>lambdaQuery().eq(ProductProcessRoute::getProductOrderId, productOrder.getId()).orderByDesc(ProductProcessRoute::getId)).get(0);
+                    ProductProcessRoute newProcessRoute = new ProductProcessRoute();
+                    BeanUtils.copyProperties(productProcessRoute, newProcessRoute);
+                    newProcessRoute.setId(null);
+                    newProcessRoute.setProductOrderId(order.getId());
+                    productProcessRouteMapper.insert(newProcessRoute);
+                    //鏂板鐢熶骇璁㈠崟涓嬬殑宸ヨ壓璺嚎瀛愯〃
+                    List<ProductProcessRouteItem> processRouteItems = productProcessRouteItemMapper.selectList(new QueryWrapper<ProductProcessRouteItem>().lambda().eq(ProductProcessRouteItem::getProductRouteId, productProcessRoute.getId()));
+                    // 鐢熸垚褰撳墠鏃ユ湡鐨勫墠缂�锛氬勾鏈堟棩
+                    String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+                    for (ProductProcessRouteItem processRouteItem : processRouteItems) {
+                        ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
+                        BeanUtils.copyProperties(processRouteItem, productProcessRouteItem);
+                        productProcessRouteItem.setId(null);
+                        productProcessRouteItem.setProductRouteId(newProcessRoute.getId());
+                        int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
+                        if (insert > 0) {
+                            // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
+                            QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
+                            queryWrapper.likeRight("work_order_no", datePrefix)
+                                    .orderByDesc("work_order_no")
+                                    .last("LIMIT 1");
+                            ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
+                            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 workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
+                            ProductWorkOrder productWorkOrder = new ProductWorkOrder();
+                            productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
+                            productWorkOrder.setProductOrderId(order.getId());
+                            productWorkOrder.setPlanQuantity(order.getQuantity());
+                            productWorkOrder.setWorkOrderNo(workOrderNoStr);
+                            productWorkOrder.setStatus(1);
+                            productWorkOrderMapper.insert(productWorkOrder);
+                        }
+                    }
+                }
+                break;
+            case "鎶ュ簾":
+                //璋冪敤涓嶅悎鏍煎簱瀛樻帴鍙� 鍏ヤ笉鍚堟牸搴�
+                stockUtils.addUnStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockUnQualifiedRecordTypeEnum.DEFECTIVE_SCRAP.getCode(),unqualified.getId());
+                break;
+            case "璁╂鏀捐":
+                //璋冪敤鎻愪氦鍚堟牸鐨勬帴鍙�
+                stockUtils.addStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockQualifiedRecordTypeEnum.DEFECTIVE_PASS.getCode(),unqualified.getId());
+                qualityInspect.setCheckResult("鍚堟牸");
+                qualityInspectService.submit(qualityInspect);
+                break;
+            default:
+                break;
+        }
+        qualityUnqualified.setInspectState(1);//宸插鐞�
+        return qualityUnqualifiedMapper.updateById(qualityUnqualified);
+    }
 }
diff --git a/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java b/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
index ad0b5e2..016141c 100644
--- a/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
+++ b/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -9,6 +9,7 @@
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.controller.BaseController;
 import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.framework.web.domain.R;
 import com.ruoyi.framework.web.page.TableDataInfo;
 import com.ruoyi.sales.dto.InvoiceLedgerDto;
 import com.ruoyi.sales.dto.SalesLedgerDto;
@@ -284,4 +285,10 @@
 
         return iPage;
     }
+
+    @ApiOperation("鏌ヨ閿�鍞彴璐︽秷鑰楃墿鏂欎俊鎭�")
+    @GetMapping("/getSalesLedgerWithProductsLoss")
+    public R getSalesLedgerWithProductsLoss(Long salesLedgerId) {
+        return R.ok(salesLedgerService.getSalesLedgerWithProductsLoss(salesLedgerId));
+    }
 }
diff --git a/src/main/java/com/ruoyi/sales/dto/LossProductModelDto.java b/src/main/java/com/ruoyi/sales/dto/LossProductModelDto.java
new file mode 100644
index 0000000..29706a8
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/dto/LossProductModelDto.java
@@ -0,0 +1,24 @@
+package com.ruoyi.sales.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class LossProductModelDto {
+
+    private String productName;
+
+    private String model;
+
+    private String unit;
+
+    //娑堣�楁�婚噺
+    private BigDecimal lossNum;
+
+    //鍗曚綅鐢ㄩ噺
+    private BigDecimal unitQuantity;
+
+    //鍗曚釜鐢ㄩ噺
+    private BigDecimal singleQuantity;
+}
diff --git a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
index e765f71..514f6cd 100644
--- a/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
+++ b/src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
@@ -3,11 +3,14 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.config.MyBaseMapper;
+import com.ruoyi.production.dto.ProductStructureDto;
 import com.ruoyi.purchase.dto.ProcurementBusinessSummaryDto;
+import com.ruoyi.sales.dto.LossProductModelDto;
 import com.ruoyi.sales.dto.SalesLedgerProductDto;
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import org.apache.ibatis.annotations.Param;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -26,4 +29,6 @@
     IPage<SalesLedgerProductDto> listPagePurchaseLedger(Page page,@Param("req") SalesLedgerProductDto salesLedgerProduct);
 
     IPage<ProcurementBusinessSummaryDto> procurementBusinessSummaryListPage(Page page,@Param("req") ProcurementBusinessSummaryDto procurementBusinessSummaryDto);
+
+    List<LossProductModelDto> selectProductBomStructure(@Param("salesLedegerId") Long salesLedegerId);
 }
diff --git a/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java b/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
index cb1f2e0..8c973b3 100644
--- a/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
+++ b/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
@@ -4,6 +4,7 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.sales.dto.LossProductModelDto;
 import com.ruoyi.sales.dto.MonthlyAmountDto;
 import com.ruoyi.sales.dto.SalesLedgerDto;
 import com.ruoyi.sales.pojo.SalesLedger;
@@ -39,4 +40,7 @@
     IPage<SalesLedger> selectSalesLedgerListPage(Page page, SalesLedgerDto salesLedgerDto);
 
     AjaxResult importData(MultipartFile file);
+
+    List<LossProductModelDto> getSalesLedgerWithProductsLoss(Long salesLedgerId);
+
 }
diff --git a/src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java
index 1d71938..d1ec847 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/InvoiceRegistrationServiceImpl.java
@@ -54,53 +54,85 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void invoiceRegistrationSave(SalesLedgerDto salesLedgerDto) {
+        //  鏂板寮�绁ㄧ櫥璁颁富琛�
         InvoiceRegistration invoiceRegistration = new InvoiceRegistration();
         BeanUtils.copyProperties(salesLedgerDto, invoiceRegistration);
         invoiceRegistration.setId(null);
         invoiceRegistration.setCustomerId(salesLedgerDto.getCustomerId().intValue());
         invoiceRegistration.setSalesLedgerId(salesLedgerDto.getId().intValue());
         invoiceRegistrationMapper.insert(invoiceRegistration);
+
         List<SalesLedgerProduct> productData = salesLedgerDto.getProductData();
-        BigDecimal invoiceAmountTotal = BigDecimal.ZERO;
-        if(CollectionUtils.isNotEmpty(productData)){
-            for (SalesLedgerProduct productDatum : productData) {
-                // 濡傛灉寮�绁ㄦ暟涓�0 璺宠繃
-                BigDecimal currentInvoiceNum = productDatum.getCurrentInvoiceNum();
-                if(null == currentInvoiceNum || BigDecimal.ZERO.compareTo(currentInvoiceNum) == 0){
-                    continue;
-                }
-                invoiceAmountTotal = invoiceAmountTotal.add(currentInvoiceNum);
-                InvoiceRegistrationProduct invoiceRegistrationProduct = new InvoiceRegistrationProduct();
-                BeanUtils.copyProperties(productDatum, invoiceRegistrationProduct);
-                //鏇存柊宸插紑绁ㄥ墿浣欐湭寮�绁ㄦ暟
-                invoiceRegistrationProductMapper.update(
-                        null,
-                        new LambdaUpdateWrapper<InvoiceRegistrationProduct>()
-                                .eq(InvoiceRegistrationProduct::getSalesLedgerId, salesLedgerDto.getId())
-                                .set(InvoiceRegistrationProduct::getNoInvoiceAmount, productDatum.getNoInvoiceAmount())
-                );
-                invoiceRegistrationProduct.setId(null);
-                invoiceRegistrationProduct.setSalesLedgerId(salesLedgerDto.getId().intValue());
-                invoiceRegistrationProduct.setInvoiceRegistrationId(invoiceRegistration.getId());
-                invoiceRegistrationProduct.setInvoiceAmount(productDatum.getCurrentInvoiceAmount());
-                invoiceRegistrationProduct.setInvoiceNum(productDatum.getCurrentInvoiceNum());
-                invoiceRegistrationProduct.setSalesLedgerProductId(productDatum.getId().intValue());
+        if (CollectionUtils.isEmpty(productData)) {
+            return;
+        }
 
-                invoiceRegistrationProductMapper.insert(invoiceRegistrationProduct);
-                productDatum.setInvoiceNum(currentInvoiceNum);
-                productDatum.setInvoiceAmount(productDatum.getCurrentInvoiceAmount());
-                salesLedgerProductMapper.updateById(productDatum);
-                // 鏂板涓�鏉″紑绁ㄥ彴璐︽暟鎹�
-                InvoiceLedger invoiceLedger = new InvoiceLedger();
-                invoiceLedger.setInvoiceDate(salesLedgerDto.getIssueDate());
-                invoiceLedger.setInvoiceRegistrationProductId(invoiceRegistrationProduct.getId());
-                invoiceLedger.setInvoiceTotal(invoiceRegistrationProduct.getInvoiceAmount());
-                invoiceLedger.setInvoiceNo(salesLedgerDto.getInvoiceNo());
-                invoiceLedger.setCreateUser(SecurityUtils.getUserId().intValue());
-                invoiceLedger.setInvoicePerson(productDatum.getRegister());
+        for (SalesLedgerProduct productDatum : productData) {
+            //  鏈寮�绁ㄦ暟 / 閲戦
+            BigDecimal currentInvoiceNum = productDatum.getCurrentInvoiceNum();
+            BigDecimal currentInvoiceAmount = productDatum.getCurrentInvoiceAmount();
 
-                invoiceLedgerMapper.insert(invoiceLedger);
+            if (currentInvoiceNum == null || BigDecimal.ZERO.compareTo(currentInvoiceNum) == 0) {
+                continue;
             }
+
+            LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductLambdaQueryWrapper = new LambdaQueryWrapper<SalesLedgerProduct>()
+                    .eq(SalesLedgerProduct::getId, productDatum.getId())
+                    .eq(SalesLedgerProduct::getSalesLedgerId, productDatum.getSalesLedgerId());
+            SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectOne(salesLedgerProductLambdaQueryWrapper);
+
+            if (dbProduct == null) {
+                throw new RuntimeException("閿�鍞彴璐︿骇鍝佷笉瀛樺湪锛孖D锛�" + productDatum.getId());
+            }
+
+            //  璁$畻绱寮�绁�
+            BigDecimal newInvoiceNum = dbProduct.getInvoiceNum().add(currentInvoiceNum);
+
+            BigDecimal newInvoiceAmount = dbProduct.getInvoiceAmount().add(currentInvoiceAmount);
+
+            //  璁$畻鏈紑绁�
+            BigDecimal newNoInvoiceNum = dbProduct.getQuantity().subtract(newInvoiceNum);
+
+            BigDecimal newNoInvoiceAmount = dbProduct.getTaxInclusiveTotalPrice().subtract(newInvoiceAmount);
+
+            if (newNoInvoiceNum.compareTo(BigDecimal.ZERO) < 0
+                    || newNoInvoiceAmount.compareTo(BigDecimal.ZERO) < 0) {
+                throw new RuntimeException("寮�绁ㄦ暟閲忔垨閲戦瓒呰繃鍚堝悓鎬婚噺");
+            }
+
+            //  鏇存柊 sales_ledger_product
+            salesLedgerProductMapper.update(
+                    null,
+                    new LambdaUpdateWrapper<SalesLedgerProduct>()
+                            .eq(SalesLedgerProduct::getId, dbProduct.getId())
+                            .set(SalesLedgerProduct::getInvoiceNum, newInvoiceNum)
+                            .set(SalesLedgerProduct::getInvoiceAmount, newInvoiceAmount)
+                            .set(SalesLedgerProduct::getNoInvoiceNum, newNoInvoiceNum)
+                            .set(SalesLedgerProduct::getNoInvoiceAmount, newNoInvoiceAmount)
+            );
+
+            InvoiceRegistrationProduct invoiceRegistrationProduct = new InvoiceRegistrationProduct();
+            BeanUtils.copyProperties(dbProduct, invoiceRegistrationProduct);
+
+            invoiceRegistrationProduct.setId(null);
+            invoiceRegistrationProduct.setSalesLedgerId(salesLedgerDto.getId().intValue());
+            invoiceRegistrationProduct.setInvoiceRegistrationId(invoiceRegistration.getId());
+            invoiceRegistrationProduct.setSalesLedgerProductId(dbProduct.getId().intValue());
+            invoiceRegistrationProduct.setInvoiceNum(currentInvoiceNum);
+            invoiceRegistrationProduct.setInvoiceAmount(currentInvoiceAmount);
+            invoiceRegistrationProduct.setNoInvoiceAmount(newNoInvoiceAmount);
+
+            invoiceRegistrationProductMapper.insert(invoiceRegistrationProduct);
+
+            InvoiceLedger invoiceLedger = new InvoiceLedger();
+            invoiceLedger.setInvoiceDate(salesLedgerDto.getIssueDate());
+            invoiceLedger.setInvoiceRegistrationProductId(invoiceRegistrationProduct.getId());
+            invoiceLedger.setInvoiceTotal(currentInvoiceAmount);
+            invoiceLedger.setInvoiceNo(salesLedgerDto.getInvoiceNo());
+            invoiceLedger.setCreateUser(SecurityUtils.getUserId().intValue());
+            invoiceLedger.setInvoicePerson(dbProduct.getRegister());
+
+            invoiceLedgerMapper.insert(invoiceLedger);
         }
     }
 
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index e297168..85d05cc 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -35,10 +35,7 @@
 import com.ruoyi.project.system.mapper.SysUserMapper;
 import com.ruoyi.quality.mapper.QualityInspectMapper;
 import com.ruoyi.quality.pojo.QualityInspect;
-import com.ruoyi.sales.dto.MonthlyAmountDto;
-import com.ruoyi.sales.dto.SalesLedgerDto;
-import com.ruoyi.sales.dto.SalesLedgerImportDto;
-import com.ruoyi.sales.dto.SalesLedgerProductImportDto;
+import com.ruoyi.sales.dto.*;
 import com.ruoyi.sales.mapper.*;
 import com.ruoyi.sales.pojo.*;
 import com.ruoyi.sales.service.ISalesLedgerProductService;
@@ -234,8 +231,8 @@
         // 鏌ヨ鍘熷鏁版嵁
         LambdaQueryWrapper<SalesLedger> queryWrapper = Wrappers.lambdaQuery();
         queryWrapper.select(SalesLedger::getCustomerId,
-                SalesLedger::getCustomerName,
-                SalesLedger::getContractAmount)
+                        SalesLedger::getCustomerName,
+                        SalesLedger::getContractAmount)
                 .orderByDesc(SalesLedger::getContractAmount);
         List<SalesLedger> records = salesLedgerMapper.selectList(queryWrapper);
 
@@ -243,7 +240,7 @@
         Map<Long, GroupedCustomer> groupedMap = new LinkedHashMap<>(); // 浣跨敤LinkedHashMap淇濇寔鎺掑簭
         for (SalesLedger record : records) {
             groupedMap.computeIfAbsent(record.getCustomerId(),
-                    k -> new GroupedCustomer(record.getCustomerId(), record.getCustomerName()))
+                            k -> new GroupedCustomer(record.getCustomerId(), record.getCustomerName()))
                     .addAmount(record.getContractAmount());
         }
 
@@ -350,13 +347,13 @@
         try {
             InputStream inputStream = file.getInputStream();
             ExcelUtil<SalesLedgerImportDto> salesLedgerImportDtoExcelUtil = new ExcelUtil<>(SalesLedgerImportDto.class);
-            Map<String, List<SalesLedgerImportDto>> stringListMap = salesLedgerImportDtoExcelUtil.importExcelMultiSheet(Arrays.asList("閿�鍞彴璐︽暟鎹�","閿�鍞骇鍝佹暟鎹�"), inputStream, 0);
-            if(CollectionUtils.isEmpty(stringListMap)) return AjaxResult.error("閿�鍞〃鏍间负绌猴紒");
+            Map<String, List<SalesLedgerImportDto>> stringListMap = salesLedgerImportDtoExcelUtil.importExcelMultiSheet(Arrays.asList("閿�鍞彴璐︽暟鎹�", "閿�鍞骇鍝佹暟鎹�"), inputStream, 0);
+            if (CollectionUtils.isEmpty(stringListMap)) return AjaxResult.error("閿�鍞〃鏍间负绌猴紒");
             // 涓氬姟灞傚悎骞�
             List<SalesLedgerImportDto> salesLedgerImportDtoList = stringListMap.get("閿�鍞彴璐︽暟鎹�");
-            if(CollectionUtils.isEmpty(salesLedgerImportDtoList)) return AjaxResult.error("閿�鍞彴璐︽暟鎹负绌猴紒");
+            if (CollectionUtils.isEmpty(salesLedgerImportDtoList)) return AjaxResult.error("閿�鍞彴璐︽暟鎹负绌猴紒");
             List<SalesLedgerImportDto> salesLedgerProductImportDtoList = stringListMap.get("閿�鍞骇鍝佹暟鎹�");
-            if(CollectionUtils.isEmpty(salesLedgerProductImportDtoList)) return AjaxResult.error("閿�鍞骇鍝佹暟鎹负绌猴紒");
+            if (CollectionUtils.isEmpty(salesLedgerProductImportDtoList)) return AjaxResult.error("閿�鍞骇鍝佹暟鎹负绌猴紒");
             // 瀹㈡埛鏁版嵁
             List<Customer> customers = customerMapper.selectList(new LambdaQueryWrapper<Customer>().in(Customer::getCustomerName,
                     salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getCustomerName).toArray(String[]::new)));
@@ -388,14 +385,16 @@
                         .findFirst()
                         .map(SysUser::getUserId)
                         .orElse(null);
-                if(aLong == null) throw new RuntimeException("褰曞叆浜�:"+salesLedger.getEntryPerson()+",鏃犲搴旂敤鎴凤紒");
+                if (aLong == null)
+                    throw new RuntimeException("褰曞叆浜�:" + salesLedger.getEntryPerson() + ",鏃犲搴旂敤鎴凤紒");
                 salesLedger.setEntryPerson(aLong.toString());
                 salesLedgerMapper.insert(salesLedger);
                 // 閿�鍞骇鍝佹暟鎹粦瀹氾紝閫氳繃閿�鍞崟鍙疯幏鍙栧搴旈攢鍞骇鍝佹暟鎹�
                 List<SalesLedgerProductImportDto> salesLedgerProductImportDtos = salesLedgerProductImportDtoList.stream()
                         .filter(salesLedgerProductImportDto -> salesLedgerProductImportDto.getSalesContractNo().equals(salesLedger.getSalesContractNo()))
                         .collect(Collectors.toList());
-                if(CollectionUtils.isEmpty(salesLedgerProductImportDtos)) throw new RuntimeException("閿�鍞崟鍙�:"+salesLedgerImportDto.getSalesContractNo()+",鏃犲搴斾骇鍝佹暟鎹紒");
+                if (CollectionUtils.isEmpty(salesLedgerProductImportDtos))
+                    throw new RuntimeException("閿�鍞崟鍙�:" + salesLedgerImportDto.getSalesContractNo() + ",鏃犲搴斾骇鍝佹暟鎹紒");
                 for (SalesLedgerProductImportDto salesLedgerProductImportDto : salesLedgerProductImportDtos) {
                     SalesLedgerProduct salesLedgerProduct = new SalesLedgerProduct();
                     BeanUtils.copyProperties(salesLedgerProductImportDto, salesLedgerProduct);
@@ -427,12 +426,23 @@
             }
 
             return AjaxResult.success("瀵煎叆鎴愬姛");
-        }catch (Exception e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
         return AjaxResult.success("瀵煎叆澶辫触");
     }
 
+    @Override
+    public List<LossProductModelDto> getSalesLedgerWithProductsLoss(Long salesLedgerId) {
+
+
+        List<LossProductModelDto> lossProductModelDtos = salesLedgerProductMapper.selectProductBomStructure(salesLedgerId);
+
+
+        return lossProductModelDtos;
+    }
+
+
     // 鍐呴儴绫荤敤浜庡瓨鍌ㄨ仛鍚堢粨鏋�
     private static class GroupedCustomer {
         private final Long customerId;
diff --git a/src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java
index 13a440c..24abcfc 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java
@@ -16,7 +16,9 @@
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 @AllArgsConstructor
 @Service
@@ -29,16 +31,32 @@
 
     @Override
     public List<StaffLeaveDto> staffLeaveReasonAnalytics() {
-        List<StaffLeaveDto> result = staffLeaveMapper.staffLeaveReasonAnalytics();
-        result.forEach(dto -> {
+        List<StaffLeaveDto> dbResult = staffLeaveMapper.staffLeaveReasonAnalytics();
+
+        // 鍒涘缓涓�涓狹ap鐢ㄤ簬瀛樺偍鎵�鏈夋灇涓惧師鍥犵殑鏁伴噺锛岄粯璁ゅ�间负0
+        Map<String, Integer> reasonCountMap = new HashMap<>();
+        for (StaffLeaveReason reasonEnum : StaffLeaveReason.values()) {
+            reasonCountMap.put(reasonEnum.getCode(), 0);
+        }
+
+        // 灏嗘暟鎹簱鏌ヨ缁撴灉鍚堝苟鍒癕ap涓�
+        for (StaffLeaveDto dto : dbResult) {
             String reasonCode = dto.getReason();
-            StaffLeaveReason reasonEnum = StaffLeaveReason.getByCode(reasonCode);
-            if (reasonEnum != null) {
-                dto.setReasonText(reasonEnum.getInfo());
-            } else {
-                dto.setReasonText("鏈煡鍘熷洜");
+            if (reasonCountMap.containsKey(reasonCode)) {
+                reasonCountMap.put(reasonCode, dto.getCount());
             }
-        });
+        }
+
+        // 灏哅ap杞崲涓篖ist<StaffLeaveDto>
+        List<StaffLeaveDto> result = new ArrayList<>();
+        for (StaffLeaveReason reasonEnum : StaffLeaveReason.values()) {
+            StaffLeaveDto dto = new StaffLeaveDto();
+            dto.setReason(reasonEnum.getCode());
+            dto.setCount(reasonCountMap.get(reasonEnum.getCode()));
+            dto.setReasonText(reasonEnum.getInfo());
+            result.add(dto);
+        }
+
         return result;
     }
 
diff --git a/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
index ff8faa5..ac9792c 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
@@ -54,9 +54,10 @@
         // 鏂板绂昏亴璁板綍
         StaffLeave staffLeave = new StaffLeave();
         staffLeave.setStaffOnJobId(staffLeaveDto.getStaffOnJobId());
+        staffLeave.setReason(staffLeaveDto.getReason());
         String reason = staffLeaveDto.getReason();
-        if (!StaffLeaveReasonOther.getCode().equals(reason)){
-            staffLeave.setRemark("");
+        if (StaffLeaveReasonOther.getCode().equals(reason)){
+            staffLeave.setRemark(staffLeaveDto.getRemark());
         }
         staffLeaveMapper.insert(staffLeave);
 
diff --git a/src/main/java/com/ruoyi/stock/controller/StockInRecordController.java b/src/main/java/com/ruoyi/stock/controller/StockInRecordController.java
new file mode 100644
index 0000000..c56c923
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/controller/StockInRecordController.java
@@ -0,0 +1,44 @@
+package com.ruoyi.stock.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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.service.StockInRecordService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@Api(tags = "鍏ュ簱")
+@RequestMapping("/stockInRecord")
+public class StockInRecordController {
+    @Autowired
+    private StockInRecordService stockInRecordService;
+
+    @GetMapping("/listPage")
+    @Log(title = "鐢熶骇鍏ュ簱-鍏ュ簱绠$悊-鍒楄〃", businessType = BusinessType.OTHER)
+    @ApiOperation(value = "鍏ュ簱绠$悊鍒楄〃")
+    public AjaxResult listPage(Page page, StockInRecordDto stockInRecordDto) {
+        IPage<StockInRecordDto> result = stockInRecordService.listPage(page, stockInRecordDto);
+        return AjaxResult.success(result);
+    }
+
+
+
+    @DeleteMapping("")
+    @Log(title = "鍏ュ簱绠$悊-鍒犻櫎鍏ュ簱", businessType = BusinessType.DELETE)
+    public AjaxResult delete(@RequestBody List<Long> ids) {
+        if(CollectionUtils.isEmpty(ids)){
+            return AjaxResult.error("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
+        }
+        return AjaxResult.success(stockInRecordService.batchDelete(ids));
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java b/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
new file mode 100644
index 0000000..445ac81
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
@@ -0,0 +1,62 @@
+package com.ruoyi.stock.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.stock.dto.StockInventoryDto;
+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;
+
+/**
+ * <p>
+ * 搴撳瓨琛� 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-21 04:16:36
+ */
+@RestController
+@RequestMapping("/stockInventory")
+@Api(tags = "搴撳瓨琛�")
+public class StockInventoryController {
+
+    @Autowired
+    private StockInventoryService stockInventoryService;
+
+    @GetMapping("/pagestockInventory")
+    @ApiOperation("鍒嗛〉鏌ヨ搴撳瓨")
+    public R pagestockInventory(Page page, StockInventoryDto stockInventoryDto) {
+        IPage<StockInventoryDto> stockInventoryDtoIPage = stockInventoryService.pagestockInventory(page, stockInventoryDto);
+        return R.ok(stockInventoryDtoIPage);
+    }
+
+    @PostMapping("/addstockInventory")
+    @ApiOperation("鏂板搴撳瓨")
+    public R addstockInventory(@RequestBody StockInventoryDto stockInventoryDto) {
+        stockInventoryDto.setRecordType(String.valueOf(StockQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_IN.getCode()));
+        stockInventoryDto.setRecordId(0L);
+        return R.ok(stockInventoryService.addstockInventory(stockInventoryDto));
+    }
+
+
+    @PostMapping("/subtractStockInventory")
+    @ApiOperation("鎵e噺搴撳瓨")
+    public R subtractStockInventory(@RequestBody StockInventoryDto stockInventoryDto) {
+        stockInventoryDto.setRecordType(String.valueOf(StockQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_OUT.getCode()));
+        stockInventoryDto.setRecordId(0L);
+        return R.ok(stockInventoryService.subtractStockInventory(stockInventoryDto));
+    }
+
+
+    @GetMapping("importStockInventory")
+    @ApiOperation("瀵煎叆搴撳瓨")
+    public R importStockInventory(MultipartFile  file) {
+        return R.ok(stockInventoryService.importStockInventory(file));
+
+    }
+}
diff --git a/src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java b/src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java
new file mode 100644
index 0000000..df82379
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java
@@ -0,0 +1,61 @@
+package com.ruoyi.stock.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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.StockOutRecordDto;
+import com.ruoyi.stock.service.StockOutRecordService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 鍑哄簱璁板綍琛� 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-21 05:27:04
+ */
+@Api(tags = "鍑哄簱")
+@RestController
+@RequestMapping("/stockOutRecord")
+public class StockOutRecordController {
+    @Autowired
+    private StockOutRecordService stockOutRecordService;
+
+    @GetMapping("/listPage")
+    @Log(title = "鐢熶骇鍑哄簱-鍑哄簱绠$悊-鍒楄〃", businessType = BusinessType.OTHER)
+    @ApiOperation(value = "鍑哄簱绠$悊鍒楄〃")
+    public AjaxResult listPage(Page page, StockOutRecordDto stockOutRecordDto) {
+        IPage<StockOutRecordDto> result = stockOutRecordService.listPage(page, stockOutRecordDto);
+        return AjaxResult.success(result);
+    }
+
+    @PostMapping("")
+    @Log(title = "鍑哄簱绠$悊-鏂板鍑哄簱", businessType = BusinessType.INSERT)
+    public AjaxResult add(@RequestBody StockOutRecordDto stockOutRecordDto) {
+        return AjaxResult.success(stockOutRecordService.add(stockOutRecordDto));
+    }
+
+    @PutMapping("/{id}")
+    @Log(title = "鍑哄簱绠$悊-鏇存柊鍑哄簱", businessType = BusinessType.UPDATE)
+    public AjaxResult update(@PathVariable("id") Long id, @RequestBody StockOutRecordDto stockOutRecordDto) {
+        return AjaxResult.success(stockOutRecordService.update(id, stockOutRecordDto));
+    }
+
+    @DeleteMapping("")
+    @Log(title = "鍑哄簱绠$悊-鍒犻櫎鍑哄簱", businessType = BusinessType.DELETE)
+    public AjaxResult delete(@RequestBody List<Long> ids) {
+        if(CollectionUtils.isEmpty(ids)){
+            return AjaxResult.error("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
+        }
+        return AjaxResult.success(stockOutRecordService.batchDelete(ids));
+    }
+}
diff --git a/src/main/java/com/ruoyi/stock/controller/StockUninventoryController.java b/src/main/java/com/ruoyi/stock/controller/StockUninventoryController.java
new file mode 100644
index 0000000..e43604f
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/controller/StockUninventoryController.java
@@ -0,0 +1,52 @@
+package com.ruoyi.stock.controller;
+
+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.enums.StockUnQualifiedRecordTypeEnum;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.stock.dto.StockUninventoryDto;
+import com.ruoyi.stock.service.StockUninventoryService;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * <p>
+ * 涓嶅悎鏍煎簱瀛樿〃 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-22 10:17:45
+ */
+@RestController
+@RequestMapping("/stockUninventory")
+public class StockUninventoryController {
+    @Autowired
+    private StockUninventoryService stockUninventoryService;
+
+    @GetMapping("/pagestockUninventory")
+    @ApiOperation("鍒嗛〉鏌ヨ搴撳瓨")
+    public R pagestockUninventory(Page page, StockUninventoryDto stockUninventoryDto) {
+        IPage<StockUninventoryDto> stockUninventoryDtoIPage = stockUninventoryService.pageStockUninventory(page, stockUninventoryDto);
+        return R.ok(stockUninventoryDtoIPage);
+    }
+
+    @PostMapping("/addstockUninventory")
+    @ApiOperation("鏂板搴撳瓨")
+    public R addstockUninventory(@RequestBody StockUninventoryDto stockUninventoryDto) {
+        stockUninventoryDto.setRecordType(String.valueOf(StockUnQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_IN.getCode()));
+        stockUninventoryDto.setRecordId(0L);
+        return R.ok(stockUninventoryService.addStockUninventory(stockUninventoryDto));
+    }
+
+
+    @PostMapping("/subtractstockUninventory")
+    @ApiOperation("鎵e噺搴撳瓨")
+    public R subtractstockUninventory(@RequestBody StockUninventoryDto stockUninventoryDto) {
+        stockUninventoryDto.setRecordType(String.valueOf(StockUnQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_OUT.getCode()));
+        stockUninventoryDto.setRecordId(0L);
+        return R.ok(stockUninventoryService.subtractStockUninventory(stockUninventoryDto));
+    }
+
+}
diff --git a/src/main/java/com/ruoyi/stock/dto/StockInRecordDto.java b/src/main/java/com/ruoyi/stock/dto/StockInRecordDto.java
new file mode 100644
index 0000000..4d6540c
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/dto/StockInRecordDto.java
@@ -0,0 +1,26 @@
+package com.ruoyi.stock.dto;
+
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import com.ruoyi.stock.pojo.StockInRecord;
+import lombok.Data;
+
+
+@Data
+public class StockInRecordDto extends StockInRecord {
+    /**
+     * 浜у搧鍚嶇О
+     */
+    private String productName;
+    /**
+     * 浜у搧瑙勬牸
+     */
+    private String model;
+    /**
+     * 浜у搧鍗曚綅
+     */
+    private String unit;
+
+    private String timeStr;
+
+    private String createBy;
+}
diff --git a/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java b/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
new file mode 100644
index 0000000..709facf
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
@@ -0,0 +1,19 @@
+package com.ruoyi.stock.dto;
+
+import com.ruoyi.stock.pojo.StockInventory;
+import lombok.Data;
+
+@Data
+public class StockInventoryDto extends StockInventory {
+
+    private String productName;
+    private String model;
+    private String unit;
+
+
+    //鍏ュ簱绫诲瀷
+    private String recordType;
+
+    //鍏ュ簱绫诲瀷瀵瑰簲鐨刬d
+    private Long recordId;
+}
diff --git a/src/main/java/com/ruoyi/stock/dto/StockOutRecordDto.java b/src/main/java/com/ruoyi/stock/dto/StockOutRecordDto.java
new file mode 100644
index 0000000..3e3abf9
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/dto/StockOutRecordDto.java
@@ -0,0 +1,28 @@
+package com.ruoyi.stock.dto;
+
+import com.ruoyi.stock.pojo.StockOutRecord;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class StockOutRecordDto extends StockOutRecord {
+    /**
+     * 浜у搧鍚嶇О
+     */
+    private String productName;
+    /**
+     * 浜у搧瑙勬牸
+     */
+    private String model;
+    /**
+     * 浜у搧鍗曚綅
+     */
+    private String unit;
+
+    private String timeStr;
+
+    private String createBy;
+}
diff --git a/src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java b/src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java
new file mode 100644
index 0000000..e496352
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java
@@ -0,0 +1,18 @@
+package com.ruoyi.stock.dto;
+
+import com.ruoyi.stock.pojo.StockUninventory;
+import lombok.Data;
+
+@Data
+public class StockUninventoryDto  extends StockUninventory {
+    private String productName;
+    private String model;
+    private String unit;
+
+
+    //鍏ュ簱绫诲瀷
+    private String recordType;
+
+    //鍏ュ簱绫诲瀷瀵瑰簲鐨刬d
+    private Long recordId;
+}
diff --git a/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java b/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java
new file mode 100644
index 0000000..c917d30
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java
@@ -0,0 +1,5 @@
+package com.ruoyi.stock.execl;
+
+public class StockInventoryExportData {
+
+}
diff --git a/src/main/java/com/ruoyi/stock/mapper/StockInRecordMapper.java b/src/main/java/com/ruoyi/stock/mapper/StockInRecordMapper.java
new file mode 100644
index 0000000..8b7b543
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/mapper/StockInRecordMapper.java
@@ -0,0 +1,12 @@
+package com.ruoyi.stock.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+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.pojo.StockInRecord;
+import org.apache.ibatis.annotations.Param;
+
+public interface StockInRecordMapper extends BaseMapper<StockInRecord> {
+    IPage<StockInRecordDto> listPage(Page page, @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
new file mode 100644
index 0000000..3463cc3
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
@@ -0,0 +1,28 @@
+package com.ruoyi.stock.mapper;
+
+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.pojo.StockInventory;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ * 搴撳瓨琛� Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-21 04:16:36
+ */
+@Mapper
+public interface StockInventoryMapper extends BaseMapper<StockInventory> {
+
+    IPage<StockInventoryDto> pagestockInventory(Page page, @Param("ew") StockInventoryDto stockInventoryDto);
+
+
+    int updateAddStockInventory(@Param("ew") StockInventoryDto stockInventoryDto);
+
+    int updateSubtractStockInventory(@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
new file mode 100644
index 0000000..04aeb71
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/mapper/StockOutRecordMapper.java
@@ -0,0 +1,23 @@
+package com.ruoyi.stock.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+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.pojo.StockOutRecord;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ * 鍑哄簱璁板綍琛� Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-21 05:27:04
+ */
+@Mapper
+public interface StockOutRecordMapper extends BaseMapper<StockOutRecord> {
+    IPage<StockOutRecordDto> listPage(Page page, @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
new file mode 100644
index 0000000..64ecc2c
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/mapper/StockUninventoryMapper.java
@@ -0,0 +1,27 @@
+package com.ruoyi.stock.mapper;
+
+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.pojo.StockUninventory;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ * 涓嶅悎鏍煎簱瀛樿〃 Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-22 10:17:45
+ */
+@Mapper
+public interface StockUninventoryMapper extends BaseMapper<StockUninventory> {
+
+    IPage<StockUninventoryDto> pageStockUninventory(Page page, @Param("ew") StockUninventoryDto stockUninventoryDto);
+
+    int updateSubtractStockUnInventory(StockUninventoryDto stockUninventoryDto);
+
+    int updateAddStockUnInventory(StockUninventoryDto stockUninventoryDto);
+}
diff --git a/src/main/java/com/ruoyi/stock/pojo/StockInRecord.java b/src/main/java/com/ruoyi/stock/pojo/StockInRecord.java
new file mode 100644
index 0000000..395d18f
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/pojo/StockInRecord.java
@@ -0,0 +1,65 @@
+package com.ruoyi.stock.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("stock_in_record")
+@ApiModel("鍏ュ簱绠$悊")
+public class StockInRecord {
+
+    private static final long serialVersionUID = 1L;
+    /**
+     * 搴忓彿
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty(value = "鍏ュ簱鎵规")
+    private String inboundBatches;
+
+    @ApiModelProperty(value = "鍏ュ簱鏁伴噺")
+    private BigDecimal stockInNum;
+
+    @ApiModelProperty(value = "璁板綍绫诲瀷  鏋氫妇")
+    private String recordType;
+
+    @ApiModelProperty(value = "璁板綍ID  ")
+    private Long recordId;
+
+    @ApiModelProperty(value = "浜у搧瑙勬牸ID")
+    private Long productModelId;
+
+    @ApiModelProperty(value = "澶囨敞")
+    private String remark;
+
+    @ApiModelProperty(value = "绫诲瀷  0鍚堟牸鍏ュ簱 1涓嶅悎鏍煎叆搴�")
+    private String type;
+
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "鍒涘缓鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+
+    @ApiModelProperty(value = "淇敼鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty(value = "淇敼鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+}
diff --git a/src/main/java/com/ruoyi/stock/pojo/StockInventory.java b/src/main/java/com/ruoyi/stock/pojo/StockInventory.java
new file mode 100644
index 0000000..4568dcc
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/pojo/StockInventory.java
@@ -0,0 +1,68 @@
+package com.ruoyi.stock.pojo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.lang.Nullable;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * <p>
+ * 搴撳瓨琛�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-21 04:16:36
+ */
+@Getter
+@Setter
+@TableName("stock_inventory")
+@ApiModel(value = "StockInventory瀵硅薄", description = "搴撳瓨琛�")
+public class StockInventory implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("涓婚敭id")
+    private Long id;
+
+    @ApiModelProperty("瑙勬牸id")
+    @NotBlank(message = "涓嶈兘涓虹┖")
+    private Long productModelId;
+
+    @ApiModelProperty("鏁伴噺")
+    private BigDecimal qualitity;
+
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("鐗堟湰鍙�")
+    private Integer version;
+
+    @ApiModelProperty("琚鍗曢攣瀹氭暟閲�")
+    private BigDecimal lockedQuantity;
+
+    @ApiModelProperty("棰勮鏁伴噺")
+    private Integer warnNum;
+
+    @ApiModelProperty("澶囨敞")
+    private String remark;
+}
diff --git a/src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java b/src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java
new file mode 100644
index 0000000..7fba29a
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java
@@ -0,0 +1,74 @@
+package com.ruoyi.stock.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 鍑哄簱璁板綍琛�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-21 05:27:04
+ */
+@Getter
+@Setter
+@TableName("stock_out_record")
+@ApiModel(value = "StockOutRecord瀵硅薄", description = "鍑哄簱璁板綍琛�")
+public class StockOutRecord implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty("鍏ュ簱鎵规")
+    private String outboundBatches;
+
+    @ApiModelProperty("鍏ュ簱鏁伴噺")
+    private BigDecimal stockOutNum;
+
+    @ApiModelProperty("鍏ュ簱鏉ユ簮id")
+    private Long recordId;
+
+    @ApiModelProperty("鍏ュ簱绫诲瀷")
+    private String recordType;
+
+    @ApiModelProperty("浜у搧瑙勬牸id")
+    private Long productModelId;
+
+    @ApiModelProperty("澶囨敞")
+    private String remark;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("鍒涘缓浜�")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+
+    @ApiModelProperty("鏇存柊浜�")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+
+    @ApiModelProperty(value = "绫诲瀷  0鍚堟牸鍏ュ簱 1涓嶅悎鏍煎叆搴�")
+    private String type;
+}
diff --git a/src/main/java/com/ruoyi/stock/pojo/StockUninventory.java b/src/main/java/com/ruoyi/stock/pojo/StockUninventory.java
new file mode 100644
index 0000000..6403dba
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/pojo/StockUninventory.java
@@ -0,0 +1,52 @@
+package com.ruoyi.stock.pojo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 涓嶅悎鏍煎簱瀛樿〃
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-22 10:17:45
+ */
+@Getter
+@Setter
+@TableName("stock_uninventory")
+@ApiModel(value = "StockUninventory瀵硅薄", description = "涓嶅悎鏍煎簱瀛樿〃")
+public class StockUninventory implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("涓婚敭id")
+    private Long id;
+
+    @ApiModelProperty("瑙勬牸id")
+    private Long productModelId;
+
+    @ApiModelProperty("鏁伴噺")
+    private BigDecimal qualitity;
+
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateTime;
+
+    @ApiModelProperty("鐗堟湰鍙�")
+    private Integer version;
+
+    @ApiModelProperty("澶囨敞")
+    private String remark;
+
+}
diff --git a/src/main/java/com/ruoyi/stock/service/StockInRecordService.java b/src/main/java/com/ruoyi/stock/service/StockInRecordService.java
new file mode 100644
index 0000000..affb300
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/service/StockInRecordService.java
@@ -0,0 +1,20 @@
+package com.ruoyi.stock.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.stock.dto.StockInRecordDto;
+import com.ruoyi.stock.pojo.StockInRecord;
+
+import java.util.List;
+
+public interface StockInRecordService extends IService<StockInRecord> {
+    IPage<StockInRecordDto> listPage(Page page, StockInRecordDto stockInRecordDto);
+
+    int add(StockInRecordDto stockInRecordDto);
+
+    int update(Long id, StockInRecordDto stockInRecordDto);
+
+    int batchDelete(List<Long> ids);
+
+}
diff --git a/src/main/java/com/ruoyi/stock/service/StockInventoryService.java b/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
new file mode 100644
index 0000000..0dc849c
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
@@ -0,0 +1,28 @@
+package com.ruoyi.stock.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.pojo.StockInventory;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * <p>
+ * 搴撳瓨琛� 鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-21 04:16:36
+ */
+public interface StockInventoryService extends IService<StockInventory> {
+
+    IPage<StockInventoryDto> pagestockInventory(Page page, StockInventoryDto stockInventoryDto);
+
+    Boolean addstockInventory(StockInventoryDto stockInventoryDto);
+
+    Boolean subtractStockInventory(StockInventoryDto stockInventoryDto);
+
+    Boolean importStockInventory(MultipartFile file);
+}
diff --git a/src/main/java/com/ruoyi/stock/service/StockOutRecordService.java b/src/main/java/com/ruoyi/stock/service/StockOutRecordService.java
new file mode 100644
index 0000000..6317e3a
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/service/StockOutRecordService.java
@@ -0,0 +1,27 @@
+package com.ruoyi.stock.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.stock.dto.StockOutRecordDto;
+import com.ruoyi.stock.pojo.StockOutRecord;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 鍑哄簱璁板綍琛� 鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-21 05:27:04
+ */
+public interface StockOutRecordService extends IService<StockOutRecord> {
+    IPage<StockOutRecordDto> listPage(Page page, StockOutRecordDto stockOutRecordDto);
+
+    int add(StockOutRecordDto stockOutRecordDto);
+
+    int update(Long id, StockOutRecordDto stockOutRecordDto);
+
+    int batchDelete(List<Long> ids);
+}
diff --git a/src/main/java/com/ruoyi/stock/service/StockUninventoryService.java b/src/main/java/com/ruoyi/stock/service/StockUninventoryService.java
new file mode 100644
index 0000000..e4b8d83
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/service/StockUninventoryService.java
@@ -0,0 +1,24 @@
+package com.ruoyi.stock.service;
+
+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.pojo.StockUninventory;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 涓嶅悎鏍煎簱瀛樿〃 鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-22 10:17:45
+ */
+public interface StockUninventoryService extends IService<StockUninventory> {
+
+    IPage<StockUninventoryDto> pageStockUninventory(Page page, StockUninventoryDto stockUninventoryDto);
+
+    Integer addStockUninventory(StockUninventoryDto stockUninventoryDto);
+
+    Integer subtractStockUninventory(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
new file mode 100644
index 0000000..4cef388
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
@@ -0,0 +1,95 @@
+package com.ruoyi.stock.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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.exception.base.BaseException;
+import com.ruoyi.common.utils.OrderUtils;
+import com.ruoyi.common.utils.bean.BeanUtils;
+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.mapper.StockInRecordMapper;
+import com.ruoyi.stock.mapper.StockInventoryMapper;
+import com.ruoyi.stock.mapper.StockUninventoryMapper;
+import com.ruoyi.stock.pojo.StockInRecord;
+import com.ruoyi.stock.pojo.StockInventory;
+import com.ruoyi.stock.pojo.StockUninventory;
+import com.ruoyi.stock.service.StockInRecordService;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+public class StockInRecordServiceImpl extends ServiceImpl<StockInRecordMapper, StockInRecord> implements StockInRecordService {
+
+    private StockInRecordMapper stockInRecordMapper;
+    private StockInventoryMapper stockInventoryMapper;
+    private StockUninventoryMapper stockUninventoryMapper;
+
+    @Override
+    public IPage<StockInRecordDto> listPage(Page page, StockInRecordDto stockInRecordDto) {
+        return stockInRecordMapper.listPage(page, stockInRecordDto);
+    }
+
+    // 鏂板鍏ュ簱
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int add(StockInRecordDto stockInRecordDto) {
+        String no = OrderUtils.countTodayByCreateTime(stockInRecordMapper, "RK");
+        stockInRecordDto.setInboundBatches(no);
+        StockInRecord stockInRecord = new StockInRecord();
+        BeanUtils.copyProperties(stockInRecordDto, stockInRecord);
+        return stockInRecordMapper.insert(stockInRecord);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int update(Long id, StockInRecordDto stockInRecordDto) {
+        // 鍒ゆ柇瀵硅薄鏄惁瀛樺湪
+        StockInRecord stockInRecord = stockInRecordMapper.selectById(id);
+        if (stockInRecord == null){
+            throw new BaseException("璇ュ叆搴撹褰曚笉瀛樺湪,鏃犳硶鏇存柊!!!");
+        }
+
+        String[] ignoreProperties = {"id", "inbound_batches"};//鎺掗櫎id灞炴��
+        BeanUtils.copyProperties(stockInRecordDto, stockInRecord, ignoreProperties);
+        return stockInRecordMapper.updateById(stockInRecord);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int batchDelete(List<Long> ids) {
+        for (Long id : ids) {
+            StockInRecord stockInRecord = stockInRecordMapper.selectById(id);
+            if (stockInRecord.getType().equals("0")) {
+                StockInventory stockInventory = stockInventoryMapper.selectOne(new LambdaQueryWrapper<StockInventory>().eq(StockInventory::getProductModelId, stockInRecord.getProductModelId()));
+                if (stockInventory == null) {
+                    throw new BaseException("搴撳瓨璁板綍涓病鏈夊搴旂殑浜у搧,鏃犳硶鍒犻櫎!!!");
+                }else {
+                    StockInventoryDto stockInRecordDto = new StockInventoryDto();
+                    stockInRecordDto.setProductModelId(stockInventory.getProductModelId());
+                    stockInRecordDto.setQualitity(stockInRecord.getStockInNum());
+                    stockInventoryMapper.updateAddStockInventory(stockInRecordDto);
+                }
+            }else if (stockInRecord.getType().equals("1")) {
+                StockUninventory stockUninventory = stockUninventoryMapper.selectOne(new LambdaQueryWrapper<StockUninventory>().eq(StockUninventory::getProductModelId, stockInRecord.getProductModelId()));
+                if (stockUninventory == null) {
+                    throw new BaseException("搴撳瓨璁板綍涓病鏈夊搴旂殑浜у搧,鏃犳硶鍒犻櫎!!!");
+                }else {
+                    StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
+                    stockUninventoryDto.setProductModelId(stockUninventory.getProductModelId());
+                    stockUninventoryDto.setQualitity(stockInRecord.getStockInNum());
+                    stockUninventoryMapper.updateAddStockUnInventory(stockUninventoryDto);
+                }
+            }
+        }
+        return stockInRecordMapper.deleteBatchIds(ids);
+    }
+}
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
new file mode 100644
index 0000000..d30e7bc
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -0,0 +1,121 @@
+package com.ruoyi.stock.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+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.common.utils.poi.ExcelUtil;
+import com.ruoyi.framework.web.domain.R;
+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;
+import com.ruoyi.stock.service.StockInventoryService;
+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 java.util.List;
+
+/**
+ * <p>
+ * 搴撳瓨琛� 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-21 04:16:36
+ */
+@Service
+@AllArgsConstructor
+public class StockInventoryServiceImpl extends ServiceImpl<StockInventoryMapper, StockInventory> implements StockInventoryService {
+
+    private  StockInventoryMapper stockInventoryMapper;
+    private StockInRecordService stockInRecordService;
+    private StockOutRecordService stockOutRecordService;
+
+    @Override
+    public IPage<StockInventoryDto> pagestockInventory(Page page, StockInventoryDto stockInventoryDto) {
+        return stockInventoryMapper.pagestockInventory(page, stockInventoryDto);
+    }
+
+    //鍏ュ簱璋冪敤
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean addstockInventory(StockInventoryDto stockInventoryDto) {
+        //鏂板鍏ュ簱璁板綍鍐嶆坊鍔犲簱瀛�
+        StockInRecordDto stockInRecordDto = new StockInRecordDto();
+        stockInRecordDto.setRecordId(stockInventoryDto.getRecordId());
+        stockInRecordDto.setRecordType(stockInventoryDto.getRecordType());
+        stockInRecordDto.setStockInNum(stockInventoryDto.getQualitity());
+        stockInRecordDto.setProductModelId(stockInventoryDto.getProductModelId());
+        stockInRecordDto.setType("0");
+        stockInRecordService.add(stockInRecordDto);
+        //鍐嶈繘琛屾柊澧炲簱瀛樻暟閲忓簱瀛�
+        //鍏堟煡璇㈠簱瀛樿〃涓殑浜у搧鏄惁瀛樺湪锛屼笉瀛樺湪鏂板锛屽瓨鍦ㄦ洿鏂�
+        StockInventory oldStockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId()));
+        if (ObjectUtils.isEmpty(oldStockInventory)) {
+            StockInventory newStockInventory = new StockInventory();
+            newStockInventory.setProductModelId(stockInventoryDto.getProductModelId());
+            newStockInventory.setQualitity(stockInventoryDto.getQualitity());
+            newStockInventory.setVersion(1);
+            newStockInventory.setRemark(stockInventoryDto.getRemark());
+            stockInventoryMapper.insert(newStockInventory);
+        }else {
+             stockInventoryMapper.updateAddStockInventory(stockInventoryDto);
+        }
+        return true;
+    }
+
+    //鍑哄簱璋冪敤
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean subtractStockInventory(StockInventoryDto stockInventoryDto) {
+            //  鏂板鍑哄簱璁板綍
+        StockOutRecordDto stockOutRecordDto = new StockOutRecordDto();
+        stockOutRecordDto.setRecordId(stockInventoryDto.getRecordId());
+        stockOutRecordDto.setRecordType(stockInventoryDto.getRecordType());
+        stockOutRecordDto.setStockOutNum(stockInventoryDto.getQualitity());
+        stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId());
+        stockOutRecordDto.setType("0");
+        stockOutRecordService.add(stockOutRecordDto);
+        StockInventory oldStockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId()));
+        if (ObjectUtils.isEmpty(oldStockInventory)) {
+            throw new RuntimeException("浜у搧搴撳瓨涓嶅瓨鍦�");
+        }else {
+            stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto);
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean importStockInventory(MultipartFile file) {
+        try {
+            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 娣诲姞鍏ュ簱璁板綍
+            });
+
+            this.saveOrUpdateBatch(stockInventories);
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return false;
+    }
+}
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
new file mode 100644
index 0000000..a9c48ed
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
@@ -0,0 +1,97 @@
+package com.ruoyi.stock.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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.exception.base.BaseException;
+import com.ruoyi.common.utils.OrderUtils;
+import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.dto.StockOutRecordDto;
+import com.ruoyi.stock.dto.StockUninventoryDto;
+import com.ruoyi.stock.mapper.StockInventoryMapper;
+import com.ruoyi.stock.mapper.StockOutRecordMapper;
+import com.ruoyi.stock.mapper.StockUninventoryMapper;
+import com.ruoyi.stock.pojo.StockInRecord;
+import com.ruoyi.stock.pojo.StockInventory;
+import com.ruoyi.stock.pojo.StockOutRecord;
+import com.ruoyi.stock.pojo.StockUninventory;
+import com.ruoyi.stock.service.StockOutRecordService;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 鍑哄簱璁板綍琛� 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-21 05:27:04
+ */
+@Service
+@AllArgsConstructor
+public class StockOutRecordServiceImpl extends ServiceImpl<StockOutRecordMapper, StockOutRecord> implements StockOutRecordService {
+    private StockOutRecordMapper stockOutRecordMapper;
+    private StockInventoryMapper stockInventoryMapper;
+    private StockUninventoryMapper stockUninventoryMapper;
+
+    @Override
+    public IPage<StockOutRecordDto> listPage(Page page, StockOutRecordDto stockOutRecordDto) {
+        return stockOutRecordMapper.listPage(page, stockOutRecordDto);
+    }
+
+    @Override
+    public int add(StockOutRecordDto stockOutRecordDto) {
+        String no = OrderUtils.countTodayByCreateTime(stockOutRecordMapper, "CK");
+        stockOutRecordDto.setOutboundBatches(no);
+        StockInRecord stockInRecord = new StockInRecord();
+        BeanUtils.copyProperties(stockOutRecordDto, stockInRecord);
+        return stockOutRecordMapper.insert(stockOutRecordDto);
+    }
+
+    @Override
+    public int update(Long id, StockOutRecordDto stockOutRecordDto) {
+        // 鍒ゆ柇瀵硅薄鏄惁瀛樺湪
+        StockOutRecord stockOutRecord = stockOutRecordMapper.selectById(id);
+        if (stockOutRecord == null){
+            throw new BaseException("璇ュ嚭搴撹褰曚笉瀛樺湪,鏃犳硶鏇存柊!!!");
+        }
+
+        String[] ignoreProperties = {"id", "outbound_batches"};//鎺掗櫎id灞炴��
+        BeanUtils.copyProperties(stockOutRecordDto, stockOutRecord, ignoreProperties);
+        return stockOutRecordMapper.updateById(stockOutRecord);
+    }
+
+    @Override
+    public int batchDelete(List<Long> ids) {
+        for (Long id : ids) {
+            StockOutRecord stockOutRecord = stockOutRecordMapper.selectById(id);
+            if (stockOutRecord.getType().equals("0")) {
+                StockInventory stockInventory = stockInventoryMapper.selectOne(new LambdaQueryWrapper<StockInventory>().eq(StockInventory::getProductModelId, stockOutRecord.getProductModelId()));
+                if (stockInventory == null) {
+                    throw new BaseException("搴撳瓨璁板綍涓病鏈夊搴旂殑浜у搧,鏃犳硶鍒犻櫎!!!");
+                }else {
+                    StockInventoryDto stockInRecordDto = new StockInventoryDto();
+                    stockInRecordDto.setProductModelId(stockInventory.getProductModelId());
+                    stockInRecordDto.setQualitity(stockOutRecord.getStockOutNum());
+                    stockInventoryMapper.updateAddStockInventory(stockInRecordDto);
+                }
+            }else if (stockOutRecord.getType().equals("1")) {
+                StockUninventory stockUninventory = stockUninventoryMapper.selectOne(new LambdaQueryWrapper<StockUninventory>().eq(StockUninventory::getProductModelId, stockOutRecord.getProductModelId()));
+                if (stockUninventory == null) {
+                    throw new BaseException("搴撳瓨璁板綍涓病鏈夊搴旂殑浜у搧,鏃犳硶鍒犻櫎!!!");
+                }else {
+                    StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
+                    stockUninventoryDto.setProductModelId(stockUninventory.getProductModelId());
+                    stockUninventoryDto.setQualitity(stockOutRecord.getStockOutNum());
+                    stockUninventoryMapper.updateAddStockUnInventory(stockUninventoryDto);
+                }
+            }
+        }
+        return stockOutRecordMapper.deleteBatchIds(ids);
+    }
+}
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
new file mode 100644
index 0000000..c896821
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
@@ -0,0 +1,89 @@
+package com.ruoyi.stock.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+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.stock.dto.StockInRecordDto;
+import com.ruoyi.stock.dto.StockOutRecordDto;
+import com.ruoyi.stock.dto.StockUninventoryDto;
+import com.ruoyi.stock.pojo.StockInventory;
+import com.ruoyi.stock.pojo.StockUninventory;
+import com.ruoyi.stock.mapper.StockUninventoryMapper;
+import com.ruoyi.stock.service.StockInRecordService;
+import com.ruoyi.stock.service.StockOutRecordService;
+import com.ruoyi.stock.service.StockUninventoryService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * <p>
+ * 涓嶅悎鏍煎簱瀛樿〃 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-01-22 10:17:45
+ */
+@Service
+@AllArgsConstructor
+public class StockUninventoryServiceImpl extends ServiceImpl<StockUninventoryMapper, StockUninventory> implements StockUninventoryService {
+
+    private StockUninventoryMapper stockUninventoryMapper;
+    private StockOutRecordService stockOutRecordService;
+    private StockInRecordService stockInRecordService;
+
+    @Override
+    public IPage<StockUninventoryDto> pageStockUninventory(Page page, StockUninventoryDto stockUninventoryDto) {
+        return stockUninventoryMapper.pageStockUninventory(page, stockUninventoryDto);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Integer addStockUninventory(StockUninventoryDto stockUninventoryDto) {
+        //鏂板鍏ュ簱璁板綍鍐嶆坊鍔犲簱瀛�
+        StockInRecordDto stockInRecordDto = new StockInRecordDto();
+        stockInRecordDto.setRecordId(stockUninventoryDto.getRecordId());
+        stockInRecordDto.setRecordType(stockUninventoryDto.getRecordType());
+        stockInRecordDto.setStockInNum(stockUninventoryDto.getQualitity());
+        stockInRecordDto.setProductModelId(stockUninventoryDto.getProductModelId());
+        stockInRecordDto.setType("1");
+        stockInRecordService.add(stockInRecordDto);
+        //鍐嶈繘琛屾柊澧炲簱瀛樻暟閲忓簱瀛�
+        //鍏堟煡璇㈠簱瀛樿〃涓殑浜у搧鏄惁瀛樺湪锛屼笉瀛樺湪鏂板锛屽瓨鍦ㄦ洿鏂�
+        StockUninventory oldStockUnInventory = stockUninventoryMapper.selectOne(new QueryWrapper<StockUninventory>().lambda().eq(StockUninventory::getProductModelId, stockUninventoryDto.getProductModelId()));
+        if (ObjectUtils.isEmpty(oldStockUnInventory)) {
+            StockUninventory newStockUnInventory = new StockUninventory();
+            newStockUnInventory.setProductModelId(stockUninventoryDto.getProductModelId());
+            newStockUnInventory.setQualitity(stockUninventoryDto.getQualitity());
+            newStockUnInventory.setVersion(1);
+            newStockUnInventory.setRemark(stockUninventoryDto.getRemark());
+            stockUninventoryMapper.insert(newStockUnInventory);
+        }else {
+            stockUninventoryMapper.updateAddStockUnInventory(stockUninventoryDto);
+        }
+        return 1;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Integer subtractStockUninventory(StockUninventoryDto stockUninventoryDto) {
+
+        //  鏂板鍑哄簱璁板綍
+        StockOutRecordDto stockOutRecordDto = new StockOutRecordDto();
+        stockOutRecordDto.setRecordId(stockUninventoryDto.getRecordId());
+        stockOutRecordDto.setRecordType(stockUninventoryDto.getRecordType());
+        stockOutRecordDto.setStockOutNum(stockUninventoryDto.getQualitity());
+        stockOutRecordDto.setProductModelId(stockUninventoryDto.getProductModelId());
+        stockOutRecordDto.setType("1");
+        stockOutRecordService.add(stockOutRecordDto);
+        StockUninventory oldStockInventory = stockUninventoryMapper.selectOne(new QueryWrapper<StockUninventory>().lambda().eq(StockUninventory::getProductModelId, stockUninventoryDto.getProductModelId()));
+        if (ObjectUtils.isEmpty(oldStockInventory)) {
+            throw new RuntimeException("浜у搧搴撳瓨涓嶅瓨鍦�");
+        }else {
+            stockUninventoryMapper.updateSubtractStockUnInventory(stockUninventoryDto);
+        }
+        return 1;
+    }
+}
diff --git a/src/main/resources/mapper/collaborativeApproval/StaffContactsPersonalMapper.xml b/src/main/resources/mapper/collaborativeApproval/StaffContactsPersonalMapper.xml
index 36ce60d..5003a8d 100644
--- a/src/main/resources/mapper/collaborativeApproval/StaffContactsPersonalMapper.xml
+++ b/src/main/resources/mapper/collaborativeApproval/StaffContactsPersonalMapper.xml
@@ -17,7 +17,7 @@
             sjlr.phone,
             scp.create_time
         FROM staff_contacts_personal scp
-            LEFT JOIN (select * from staff_join_leave_record WHERE staff_state = 1) sjlr ON scp.contact_id=sjlr.id
+            LEFT JOIN (select * from staff_on_job WHERE staff_state = 1) sjlr ON scp.contact_id=sjlr.id
         where 1=1
         <if test="staffContactsPersonalDTO.staffName != null and staffContactsPersonalDTO.staffName != ''">
             and sjlr.staff_name like concat('%',#{staffContactsPersonalDTO.staffName},'%')
diff --git a/src/main/resources/mapper/lavorissue/LavorIssueMapper.xml b/src/main/resources/mapper/lavorissue/LavorIssueMapper.xml
index 81cf11d..5d447e1 100644
--- a/src/main/resources/mapper/lavorissue/LavorIssueMapper.xml
+++ b/src/main/resources/mapper/lavorissue/LavorIssueMapper.xml
@@ -10,7 +10,7 @@
                t3.dict_label as dictName,
                t4.dict_label as dictTypeName
         from labor_issue t1
-        left join staff_join_leave_record t2 on t1.staff_id = t2.id
+        left join staff_on_job t2 on t1.staff_id = t2.id
         left join sys_dict_data t3 on t1.dict_id = t3.dict_value
         left join sys_dict_data t4 on t1.dict_type = t4.dict_value
         <where>
@@ -45,7 +45,7 @@
             t3.dict_label as dictName,
             t4.dict_label as dictTypeName
         from labor_issue t1
-                 left join staff_join_leave_record t2 on t1.staff_id = t2.id
+                 left join staff_on_job t2 on t1.staff_id = t2.id
                  left join sys_dict_data t3 on t1.dict_id = t3.dict_value
                  left join sys_dict_data t4 on t1.dict_type = t4.dict_value
         <where>
diff --git a/src/main/resources/mapper/production/ProductionProductMainMapper.xml b/src/main/resources/mapper/production/ProductionProductMainMapper.xml
index 1d98782..5c64617 100644
--- a/src/main/resources/mapper/production/ProductionProductMainMapper.xml
+++ b/src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -20,6 +20,7 @@
                p.product_name as productName,
                pm.model as productModelName,
                ppo.quantity,
+               ppo.scrap_qty,
                pm.unit,
                sl.sales_contract_no salesContractNo
         from
@@ -48,6 +49,13 @@
         order by ppm.id
 
     </select>
+    <select id="getOrderByMainId" resultType="com.ruoyi.production.pojo.ProductOrder">
+        select po.*
+        from product_order po
+        left join  product_work_order pwo on po.id = pwo.product_order_id
+        left join production_product_main pm on work_order_id=pwo.id
+        where pm.id=#{productMainId}
+    </select>
 
     <delete id="deleteByWorkOrderIds" parameterType="java.util.List">
         DELETE FROM production_product_main
diff --git a/src/main/resources/mapper/purchase/InvoicePurchaseMapper.xml b/src/main/resources/mapper/purchase/InvoicePurchaseMapper.xml
index b5baf13..c5a99f9 100644
--- a/src/main/resources/mapper/purchase/InvoicePurchaseMapper.xml
+++ b/src/main/resources/mapper/purchase/InvoicePurchaseMapper.xml
@@ -27,7 +27,7 @@
         sl.customer_name,
         sl.contract_amount
         ORDER BY
-        sl.sales_contract_no;
+        sl.sales_contract_no
     </select>
     <select id="listVat" resultType="com.ruoyi.purchase.dto.VatDto">
         select *
diff --git a/src/main/resources/mapper/quality/QualityInspectMapper.xml b/src/main/resources/mapper/quality/QualityInspectMapper.xml
index ba7e8b8..8058455 100644
--- a/src/main/resources/mapper/quality/QualityInspectMapper.xml
+++ b/src/main/resources/mapper/quality/QualityInspectMapper.xml
@@ -312,29 +312,35 @@
     </select>
 
     <select id="getTopParameters" resultType="com.ruoyi.quality.dto.QualityParameterStatDto">
-        WITH parameter_counts AS (SELECT qip.parameter_item AS name, COUNT(*) AS count
-                                  FROM quality_inspect_param qip
-                                           JOIN quality_inspect qi ON qip.inspect_id = qi.id
+        WITH parameter_counts AS (SELECT qip.parameter_item            AS name,
+                                         SUM(COALESCE(qi.quantity, 0)) AS count
+                                  FROM quality_inspect qi
+                                           JOIN quality_inspect_param qip ON qip.inspect_id = qi.id
                                   WHERE qi.inspect_type = #{inspectType}
                                   GROUP BY qip.parameter_item),
-             total AS (SELECT SUM(count) as total_count
-                       FROM parameter_counts),
-             ranked AS (SELECT name, count, ROW_NUMBER() OVER (ORDER BY count DESC) as rn
-                        FROM parameter_counts)
+             ranked AS (SELECT name,
+                               count,
+                               ROW_NUMBER() OVER (ORDER BY count DESC) AS rn
+                        FROM parameter_counts),
+             total AS (SELECT SUM(count) AS total_count
+                       FROM parameter_counts)
         SELECT name,
                count,
                CASE
                    WHEN (SELECT total_count FROM total) = 0 THEN 0
                    ELSE ROUND(count / (SELECT total_count FROM total) * 100, 2)
-                   END as percentage
+                   END AS percentage
         FROM (SELECT name, count, rn
               FROM ranked
               WHERE rn &lt;= 4
               UNION ALL
-              SELECT '鍏朵粬' as name, SUM(count) as count, 5 as rn
+              SELECT '鍏朵粬妫�娴�' AS name,
+                     SUM(count) AS count,
+                     5          AS rn
               FROM ranked
               WHERE rn &gt; 4
-              HAVING count &gt; 0) sub
+              HAVING SUM(count) &gt; 0) t
         ORDER BY rn
     </select>
+
 </mapper>
diff --git a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
index 2579a18..67c56c7 100644
--- a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -15,10 +15,10 @@
         <where>
             1=1
             <if test="salesLedgerProduct.salesLedgerId != null and salesLedgerProduct.salesLedgerId != '' ">
-                AND  T1.sales_ledger_id = #{salesLedgerProduct.salesLedgerId}
+                AND T1.sales_ledger_id = #{salesLedgerProduct.salesLedgerId}
             </if>
             <if test="salesLedgerProduct.type != null and salesLedgerProduct.type != '' ">
-                AND  T1.type = #{salesLedgerProduct.type}
+                AND T1.type = #{salesLedgerProduct.type}
             </if>
         </where>
     </select>
@@ -27,7 +27,7 @@
         from quality_inspect qi
                  left join production_product_main ppm on qi.product_main_id = ppm.id
                  left join product_work_order pwo on ppm.work_order_id = pwo.id
-                 left join product_order  po on pwo.product_order_id = po.id
+                 left join product_order po on pwo.product_order_id = po.id
                  left join sales_ledger_product slp on po.product_model_id = slp.id
         where qi.product_main_id = #{productMainId}
 
@@ -44,22 +44,22 @@
         <where>
             slp.type = 1
             <if test="req.salesContractNo != null and req.salesContractNo != '' ">
-                AND  sl.sales_contract_no like concat('%',#{req.salesContractNo},'%')
+                AND sl.sales_contract_no like concat('%',#{req.salesContractNo},'%')
             </if>
             <if test="req.customerContractNo != null and req.customerContractNo != '' ">
-                AND  sl.customer_contract_no like concat('%',#{req.customerContractNo},'%')
+                AND sl.customer_contract_no like concat('%',#{req.customerContractNo},'%')
             </if>
             <if test="req.projectName != null and req.projectName != '' ">
-                AND  sl.project_name like concat('%',#{req.projectName},'%')
+                AND sl.project_name like concat('%',#{req.projectName},'%')
             </if>
             <if test="req.customerName != null and req.customerName != '' ">
-                AND  sl.customer_name like concat('%',#{req.customerName},'%')
+                AND sl.customer_name like concat('%',#{req.customerName},'%')
             </if>
             <if test="req.productCategory != null and req.productCategory != '' ">
-                AND  slp.product_category like concat('%',#{req.productCategory},'%')
+                AND slp.product_category like concat('%',#{req.productCategory},'%')
             </if>
             <if test="req.status != null and req.status ">
-                AND  slp.pending_invoice_total &gt; 0
+                AND slp.pending_invoice_total &gt; 0
             </if>
         </where>
         order by slp.register_date desc
@@ -76,22 +76,22 @@
         <where>
             slp.type = 2
             <if test="req.purchaseContractNumber != null and req.purchaseContractNumber != '' ">
-                AND  sl.purchase_contract_number like concat('%',#{req.purchaseContractNumber},'%')
+                AND sl.purchase_contract_number like concat('%',#{req.purchaseContractNumber},'%')
             </if>
             <if test="req.customerContractNo != null and req.customerContractNo != '' ">
-                AND  sl.customer_contract_no like concat('%',#{req.customerContractNo},'%')
+                AND sl.customer_contract_no like concat('%',#{req.customerContractNo},'%')
             </if>
             <if test="req.projectName != null and req.projectName != '' ">
-                AND  sl.project_name like concat('%',#{req.projectName},'%')
+                AND sl.project_name like concat('%',#{req.projectName},'%')
             </if>
             <if test="req.customerName != null and req.customerName != '' ">
-                AND  sl.customer_name like concat('%',#{req.customerName},'%')
+                AND sl.customer_name like concat('%',#{req.customerName},'%')
             </if>
             <if test="req.productCategory != null and req.productCategory != '' ">
-                AND  slp.product_category like concat('%',#{req.productCategory},'%')
+                AND slp.product_category like concat('%',#{req.productCategory},'%')
             </if>
             <if test="req.status != null and req.status ">
-                AND  slp.pending_invoice_total &gt; 0
+                AND slp.pending_invoice_total &gt; 0
             </if>
         </where>
         order by slp.register_date desc
@@ -126,4 +126,25 @@
         <!-- 鎸変骇鍝佸ぇ绫绘帓搴� -->
         ORDER BY slp.product_category
     </select>
+    <select id="selectProductBomStructure" resultType="com.ruoyi.sales.dto.LossProductModelDto">
+        select
+            a.model,
+            a.product_name,
+            a.unit,
+            sum(a.single_quantity) AS loss_num
+        from (SELECT ps.unit,
+                     ps.unit_quantity,
+                     pm1.model,
+                     p.product_name,
+                     ps.unit_quantity * slp.quantity AS single_quantity
+              FROM sales_ledger sl
+                       LEFT JOIN sales_ledger_product slp ON slp.sales_ledger_id = sl.id
+                       LEFT JOIN product_model pm ON pm.id = slp.product_model_id
+                       LEFT JOIN product_bom pb ON pb.product_model_id = pm.id
+                       LEFT JOIN product_structure ps ON pb.id = ps.bom_id
+                       LEFT JOIN product_model pm1 ON pm1.id = ps.product_model_id
+                       LEFT JOIN product p ON p.id = pm1.product_id
+              WHERE sl.id = #{salesLedegerId}) A
+        group by a.model, a.product_name, a.unit
+    </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
new file mode 100644
index 0000000..0eee4f3
--- /dev/null
+++ b/src/main/resources/mapper/stock/StockInRecordMapper.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.stock.mapper.StockInRecordMapper">
+
+    <select id="listPage" resultType="com.ruoyi.stock.dto.StockInRecordDto">
+        SELECT
+        sir.*,
+        p.product_name as productName,
+        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>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/stock/StockInventoryMapper.xml b/src/main/resources/mapper/stock/StockInventoryMapper.xml
new file mode 100644
index 0000000..b39d329
--- /dev/null
+++ b/src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.stock.mapper.StockInventoryMapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ruoyi.stock.pojo.StockInventory">
+        <result column="id" property="id" />
+        <result column="product_model_id" property="productModelId" />
+        <result column="qualitity" property="qualitity" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+        <result column="version" property="version" />
+        <result column="locked_quantity" property="lockedQuantity" />
+        <result column="warn_num" property="warnNum" />
+    </resultMap>
+    <update id="updateAddStockInventory">
+        update stock_inventory
+        <set>
+            <if test="ew.qualitity != null">
+                qualitity = qualitity + #{ew.qualitity},
+            </if>
+           <if test="ew.version != null">
+               version = version + 1,
+            </if>
+            <if test="ew.remark != null and ew.remark !=''">
+                remark = #{ew.remark},
+            </if>
+            update_time = now()
+        </set>
+        where product_model_id = #{ew.productModelId}
+    </update>
+    <update id="updateSubtractStockInventory">
+        update stock_inventory
+        <set>
+            <if test="ew.qualitity != null">
+                qualitity = qualitity - #{ew.qualitity},
+            </if>
+            <if test="ew.version != null">
+                version = version + 1,
+            </if>
+            <if test="ew.remark != null and ew.remark !=''">
+                remark = #{ew.remark},
+            </if>
+            update_time = now()
+        </set>
+        where product_model_id = #{ew.productModelId} and qualitity >= #{ew.qualitity}
+    </update>
+    <select id="pagestockInventory" resultType="com.ruoyi.stock.dto.StockInventoryDto">
+        select si.*,
+               pm.model,
+               pm.unit,
+               p.product_name
+        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
new file mode 100644
index 0000000..b021e71
--- /dev/null
+++ b/src/main/resources/mapper/stock/StockOutRecordMapper.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.stock.mapper.StockOutRecordMapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ruoyi.stock.pojo.StockOutRecord">
+        <id column="id" property="id" />
+        <result column="outbound_batches" property="outboundBatches" />
+        <result column="stock_out_num" property="stockOutNum" />
+        <result column="record_id" property="recordId" />
+        <result column="record_type" property="recordType" />
+        <result column="product_model_id" property="productModelId" />
+        <result column="remark" property="remark" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+        <result column="create_user" property="createUser" />
+        <result column="update_user" property="updateUser" />
+    </resultMap>
+
+    <select id="listPage" resultType="com.ruoyi.stock.dto.StockOutRecordDto">
+        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
new file mode 100644
index 0000000..70b4471
--- /dev/null
+++ b/src/main/resources/mapper/stock/StockUninventoryMapper.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.stock.mapper.StockUninventoryMapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ruoyi.stock.pojo.StockUninventory">
+        <result column="id" property="id" />
+        <result column="product_model_id" property="productModelId" />
+        <result column="qualitity" property="qualitity" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+        <result column="version" property="version" />
+    </resultMap>
+    <update id="updateSubtractStockUnInventory">
+        update stock_inventory
+        <set>
+            <if test="ew.qualitity != null">
+                qualitity = qualitity - #{ew.qualitity},
+            </if>
+            <if test="ew.version != null">
+                version = version + 1,
+            </if>
+            <if test="ew.remark != null and ew.remark !=''">
+                remark = #{ew.remark},
+            </if>
+            update_time = now()
+        </set>
+        where product_model_id = #{ew.productModelId} and qualitity >= #{ew.qualitity}
+    </update>
+    <update id="updateAddStockUnInventory">
+        update stock_inventory
+        <set>
+            <if test="ew.qualitity != null">
+                qualitity = qualitity + #{ew.qualitity},
+            </if>
+            <if test="ew.version != null">
+                version = version + 1,
+            </if>
+            <if test="ew.remark != null and ew.remark !=''">
+                remark = #{ew.remark},
+            </if>
+            update_time = now()
+        </set>
+        where product_model_id = #{ew.productModelId}
+    </update>
+    <select id="pageStockUninventory" resultType="com.ruoyi.stock.dto.StockUninventoryDto">
+        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