From 9dcd90dc8e329900e6058ac0a3aa44a9e7e04599 Mon Sep 17 00:00:00 2001
From: chenhj <1263187585@qq.com>
Date: 星期六, 14 六月 2025 15:45:24 +0800
Subject: [PATCH] 库存明细,以及库存数量更新方法,库存节点存储

---
 main-business/src/main/java/com/ruoyi/business/controller/OutputInventoryRecordController.java                     |   21 +
 main-business/src/main/java/com/ruoyi/business/service/OutputInventoryRecordService.java                           |   22 +
 main-business/src/main/resources/db/migration/postgresql/V20250614111811__create_table_inventory_summary.sql       |   30 +
 main-business/src/main/java/com/ruoyi/business/controller/InputInventoryRecordController.java                      |   21 +
 main-business/src/main/java/com/ruoyi/business/service/impl/InputInventoryRecordServiceImpl.java                   |   56 +++
 main-business/src/main/resources/mapper/InputInventoryRecordMapper.xml                                             |   24 +
 main-business/src/main/java/com/ruoyi/business/mapper/InventorySummaryMapper.java                                  |   20 +
 main-business/src/main/resources/mapper/OfficialInventoryMapper.xml                                                |   46 +-
 main-business/src/main/resources/db/migration/postgresql/V20250614110410__create_table_input_inventory_record.sql  |   29 +
 ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java                                                          |    2 
 main-business/src/main/java/com/ruoyi/business/service/impl/OutputInventoryRecordServiceImpl.java                  |   56 +++
 ruoyi-admin/src/main/java/com/ruoyi/PlusCodeGenerator.java                                                         |   12 
 main-business/src/main/java/com/ruoyi/business/entity/OutputInventoryRecord.java                                   |   56 +++
 main-business/src/main/resources/mapper/PendingInventoryMapper.xml                                                 |   40 +-
 main-business/src/main/java/com/ruoyi/business/service/impl/InventorySummaryServiceImpl.java                       |   99 +++++
 main-business/src/main/java/com/ruoyi/business/service/impl/PendingInventoryServiceImpl.java                       |    2 
 main-business/src/main/java/com/ruoyi/business/entity/InputInventoryRecord.java                                    |   56 +++
 main-business/src/main/java/com/ruoyi/business/mapper/OutputInventoryRecordMapper.java                             |   18 +
 main-business/src/main/java/com/ruoyi/business/task/InventorySummaryTask.java                                      |  144 ++++++++
 main-business/src/main/resources/mapper/InventorySummaryMapper.xml                                                 |   38 ++
 main-business/src/main/java/com/ruoyi/business/mapper/InputInventoryRecordMapper.java                              |   18 +
 main-business/src/main/resources/mapper/OutputInventoryRecordMapper.xml                                            |   24 +
 main-business/src/main/java/com/ruoyi/business/controller/InventorySummaryController.java                          |   21 +
 main-business/src/main/java/com/ruoyi/business/service/InventorySummaryService.java                                |   24 +
 main-business/src/main/resources/db/migration/postgresql/V20250614111500__create_table_output_inventory_record.sql |   29 +
 main-business/src/main/java/com/ruoyi/business/constant/InventoryRecordConstant.java                               |    8 
 main-business/src/main/java/com/ruoyi/business/mapper/PendingInventoryMapper.java                                  |    4 
 main-business/src/main/java/com/ruoyi/business/entity/InventorySummary.java                                        |   73 ++++
 main-business/src/main/java/com/ruoyi/business/service/InputInventoryRecordService.java                            |   22 +
 main-business/src/main/java/com/ruoyi/business/mapper/OfficialInventoryMapper.java                                 |    4 
 30 files changed, 974 insertions(+), 45 deletions(-)

diff --git a/main-business/src/main/java/com/ruoyi/business/constant/InventoryRecordConstant.java b/main-business/src/main/java/com/ruoyi/business/constant/InventoryRecordConstant.java
new file mode 100644
index 0000000..7f05f6a
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/constant/InventoryRecordConstant.java
@@ -0,0 +1,8 @@
+package com.ruoyi.business.constant;
+
+public class InventoryRecordConstant {
+    // 寰呭叆搴�
+    public static String PENDING_INVENTORY = "PENDING_INVENTORY";
+    // 姝e紡搴�
+    public static String OFFICIAL_INVENTORY = "OFFICIAL_INVENTORY";
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/controller/InputInventoryRecordController.java b/main-business/src/main/java/com/ruoyi/business/controller/InputInventoryRecordController.java
new file mode 100644
index 0000000..ec8e4f1
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/controller/InputInventoryRecordController.java
@@ -0,0 +1,21 @@
+package com.ruoyi.business.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import lombok.AllArgsConstructor;
+    import org.springframework.web.bind.annotation.RestController;
+
+/**
+* <p>
+    * 鍏ュ簱璁板綍琛� 鍓嶇鎺у埗鍣�
+    * </p>
+*
+* @author chenhj
+* @since 2025-06-14
+*/
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/business/inputInventoryRecord")
+        public class InputInventoryRecordController {
+
+    }
diff --git a/main-business/src/main/java/com/ruoyi/business/controller/InventorySummaryController.java b/main-business/src/main/java/com/ruoyi/business/controller/InventorySummaryController.java
new file mode 100644
index 0000000..80f24d8
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/controller/InventorySummaryController.java
@@ -0,0 +1,21 @@
+package com.ruoyi.business.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import lombok.AllArgsConstructor;
+    import org.springframework.web.bind.annotation.RestController;
+
+/**
+* <p>
+    * 搴撳瓨姹囨�昏〃 鍓嶇鎺у埗鍣�
+    * </p>
+*
+* @author chenhj
+* @since 2025-06-14
+*/
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/business/inventorySummary")
+        public class InventorySummaryController {
+
+    }
diff --git a/main-business/src/main/java/com/ruoyi/business/controller/OutputInventoryRecordController.java b/main-business/src/main/java/com/ruoyi/business/controller/OutputInventoryRecordController.java
new file mode 100644
index 0000000..53afe61
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/controller/OutputInventoryRecordController.java
@@ -0,0 +1,21 @@
+package com.ruoyi.business.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import lombok.AllArgsConstructor;
+    import org.springframework.web.bind.annotation.RestController;
+
+/**
+* <p>
+    * 鍑哄簱璁板綍琛� 鍓嶇鎺у埗鍣�
+    * </p>
+*
+* @author chenhj
+* @since 2025-06-14
+*/
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/business/outputInventoryRecord")
+        public class OutputInventoryRecordController {
+
+    }
diff --git a/main-business/src/main/java/com/ruoyi/business/entity/InputInventoryRecord.java b/main-business/src/main/java/com/ruoyi/business/entity/InputInventoryRecord.java
new file mode 100644
index 0000000..4ae92fd
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/entity/InputInventoryRecord.java
@@ -0,0 +1,56 @@
+package com.ruoyi.business.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 鍏ュ簱璁板綍琛� 瀹炰綋绫�
+ *
+ * @author chenhj
+ * @date 2025-06-14
+ */
+@Data
+@TableName("input_inventory_record")
+public class InputInventoryRecord implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓婚敭ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+    /**
+     * 搴搃d
+     */
+    @TableField(value = "inventory_id")
+    private Long inventoryId;
+    /**
+     * 搴撶被鍨�
+     */
+    @TableField(value = "inventory_type")
+    private String inventoryType;
+    /**
+     * 璁板綍鏁伴噺
+     */
+    @TableField(value = "quantity")
+    private BigDecimal quantity;
+
+    /** 閫昏緫鍒犻櫎瀛楁 */
+    @TableLogic
+    private Integer deleted;
+
+    /** 鍒涘缓鑰� */
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
+
+    /** 鍒涘缓鏃堕棿 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/main-business/src/main/java/com/ruoyi/business/entity/InventorySummary.java b/main-business/src/main/java/com/ruoyi/business/entity/InventorySummary.java
new file mode 100644
index 0000000..b9d288a
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/entity/InventorySummary.java
@@ -0,0 +1,73 @@
+package com.ruoyi.business.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 搴撳瓨姹囨�昏〃 瀹炰綋绫�
+ *
+ * @author chenhj
+ * @date 2025-06-14
+ */
+@Data
+@TableName("inventory_summary")
+public class InventorySummary implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓婚敭ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+    /**
+     * 搴搃d
+     */
+    @TableField(value = "inventory_id")
+    private Long inventoryId;
+    /**
+     * 搴撶被鍨�
+     */
+    @TableField(value = "inventory_type")
+    private String inventoryType;
+    /**
+     * 搴撳瓨鏁伴噺
+     */
+    @TableField(value = "inventory_quantity")
+    private BigDecimal inventoryQuantity;
+    /**
+     * 鍏ュ簱涓鏄庣粏璁板綍id
+     */
+    @TableField(value = "input_end_record_id")
+    private Long inputEndRecordId;
+    /**
+     * 鍑哄簱涓鏄庣粏璁板綍id
+     */
+    @TableField(value = "output_end_record_id")
+    private Long outputEndRecordId;
+
+    /**
+     * 閫昏緫鍒犻櫎瀛楁
+     */
+    @TableLogic
+    private Integer deleted;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime createTime;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+}
\ No newline at end of file
diff --git a/main-business/src/main/java/com/ruoyi/business/entity/OutputInventoryRecord.java b/main-business/src/main/java/com/ruoyi/business/entity/OutputInventoryRecord.java
new file mode 100644
index 0000000..c636d80
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/entity/OutputInventoryRecord.java
@@ -0,0 +1,56 @@
+package com.ruoyi.business.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 鍑哄簱璁板綍琛� 瀹炰綋绫�
+ *
+ * @author chenhj
+ * @date 2025-06-14
+ */
+@Data
+@TableName("output_inventory_record")
+public class OutputInventoryRecord implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓婚敭ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+    /**
+     * 搴搃d
+     */
+    @TableField(value = "inventory_id")
+    private Long inventoryId;
+    /**
+     * 搴撶被鍨�
+     */
+    @TableField(value = "inventory_type")
+    private String inventoryType;
+    /**
+     * 璁板綍鏁伴噺
+     */
+    @TableField(value = "quantity")
+    private BigDecimal quantity;
+
+    /** 閫昏緫鍒犻櫎瀛楁 */
+    @TableLogic
+    private Integer deleted;
+
+    /** 鍒涘缓鑰� */
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
+
+    /** 鍒涘缓鏃堕棿 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT, updateStrategy = FieldStrategy.NEVER)
+    private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/main-business/src/main/java/com/ruoyi/business/mapper/InputInventoryRecordMapper.java b/main-business/src/main/java/com/ruoyi/business/mapper/InputInventoryRecordMapper.java
new file mode 100644
index 0000000..5565edc
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/mapper/InputInventoryRecordMapper.java
@@ -0,0 +1,18 @@
+package com.ruoyi.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.business.entity.InputInventoryRecord;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 鍏ュ簱璁板綍琛� Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author chenhj
+ * @since 2025-06-14
+ */
+@Mapper
+public interface InputInventoryRecordMapper extends BaseMapper<InputInventoryRecord> {
+
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/mapper/InventorySummaryMapper.java b/main-business/src/main/java/com/ruoyi/business/mapper/InventorySummaryMapper.java
new file mode 100644
index 0000000..be03d54
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/mapper/InventorySummaryMapper.java
@@ -0,0 +1,20 @@
+package com.ruoyi.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.business.entity.InventorySummary;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ * 搴撳瓨姹囨�昏〃 Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author chenhj
+ * @since 2025-06-14
+ */
+@Mapper
+public interface InventorySummaryMapper extends BaseMapper<InventorySummary> {
+    InventorySummary getInventorySummaryForUpdateById(@Param("id") Long id);
+    InventorySummary getInventorySummaryForUpdateByInventoryIdAndType(@Param("inventoryId") Long inventoryId, @Param("type") String type);
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/mapper/OfficialInventoryMapper.java b/main-business/src/main/java/com/ruoyi/business/mapper/OfficialInventoryMapper.java
index 8282d64..fe7895d 100644
--- a/main-business/src/main/java/com/ruoyi/business/mapper/OfficialInventoryMapper.java
+++ b/main-business/src/main/java/com/ruoyi/business/mapper/OfficialInventoryMapper.java
@@ -3,6 +3,7 @@
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.ruoyi.business.entity.OfficialInventory;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * <p>
@@ -14,5 +15,6 @@
  */
 @Mapper
 public interface OfficialInventoryMapper extends BaseMapper<OfficialInventory> {
-
+    // 鑾峰彇姝e紡搴撹褰�
+    OfficialInventory getOfficialInventoryForUpdateById(@Param("id") Long id);
 }
diff --git a/main-business/src/main/java/com/ruoyi/business/mapper/OutputInventoryRecordMapper.java b/main-business/src/main/java/com/ruoyi/business/mapper/OutputInventoryRecordMapper.java
new file mode 100644
index 0000000..b71a759
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/mapper/OutputInventoryRecordMapper.java
@@ -0,0 +1,18 @@
+package com.ruoyi.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.business.entity.OutputInventoryRecord;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 鍑哄簱璁板綍琛� Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author chenhj
+ * @since 2025-06-14
+ */
+@Mapper
+public interface OutputInventoryRecordMapper extends BaseMapper<OutputInventoryRecord> {
+
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/mapper/PendingInventoryMapper.java b/main-business/src/main/java/com/ruoyi/business/mapper/PendingInventoryMapper.java
index 44b3272..0ae2786 100644
--- a/main-business/src/main/java/com/ruoyi/business/mapper/PendingInventoryMapper.java
+++ b/main-business/src/main/java/com/ruoyi/business/mapper/PendingInventoryMapper.java
@@ -3,6 +3,7 @@
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.ruoyi.business.entity.PendingInventory;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * <p>
@@ -14,5 +15,6 @@
  */
 @Mapper
 public interface PendingInventoryMapper extends BaseMapper<PendingInventory> {
-
+    // 鑾峰彇寰呭叆搴撹褰�
+    PendingInventory  getPendingInventoryForUpdateById(@Param("id") Long id);
 }
diff --git a/main-business/src/main/java/com/ruoyi/business/service/InputInventoryRecordService.java b/main-business/src/main/java/com/ruoyi/business/service/InputInventoryRecordService.java
new file mode 100644
index 0000000..f825ad4
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/service/InputInventoryRecordService.java
@@ -0,0 +1,22 @@
+package com.ruoyi.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.business.dto.OfficialInventoryDto;
+import com.ruoyi.business.dto.PendingInventoryDto;
+import com.ruoyi.business.entity.InputInventoryRecord;
+
+import java.math.BigDecimal;
+
+/**
+ * <p>
+ * 鍏ュ簱璁板綍琛� 鏈嶅姟绫�
+ * </p>
+ *
+ * @author chenhj
+ * @since 2025-06-14
+ */
+public interface InputInventoryRecordService extends IService<InputInventoryRecord> {
+
+    // 娣诲姞鍏ュ簱璁板綍
+    int insertInputInventoryRecord(PendingInventoryDto pendingInventoryDto, OfficialInventoryDto officialInventoryDto, BigDecimal quantity);
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/service/InventorySummaryService.java b/main-business/src/main/java/com/ruoyi/business/service/InventorySummaryService.java
new file mode 100644
index 0000000..82d8d24
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/service/InventorySummaryService.java
@@ -0,0 +1,24 @@
+package com.ruoyi.business.service;
+
+import com.ruoyi.business.dto.OfficialInventoryDto;
+import com.ruoyi.business.dto.PendingInventoryDto;
+import com.ruoyi.business.entity.InventorySummary;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 搴撳瓨姹囨�昏〃 鏈嶅姟绫�
+ * </p>
+ *
+ * @author chenhj
+ * @since 2025-06-14
+ */
+public interface InventorySummaryService extends IService<InventorySummary> {
+
+    /**
+     * 鏇存柊搴撳瓨
+     * @param pendingInventoryDto 寰呭鐞嗗簱瀛�
+     * @param officialInventoryDto 姝e紡搴撳瓨
+     */
+    int updateInventory(PendingInventoryDto pendingInventoryDto, OfficialInventoryDto officialInventoryDto);
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/service/OutputInventoryRecordService.java b/main-business/src/main/java/com/ruoyi/business/service/OutputInventoryRecordService.java
new file mode 100644
index 0000000..dafd0d5
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/service/OutputInventoryRecordService.java
@@ -0,0 +1,22 @@
+package com.ruoyi.business.service;
+
+import com.ruoyi.business.dto.OfficialInventoryDto;
+import com.ruoyi.business.dto.PendingInventoryDto;
+import com.ruoyi.business.entity.OutputInventoryRecord;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.math.BigDecimal;
+
+/**
+ * <p>
+ * 鍑哄簱璁板綍琛� 鏈嶅姟绫�
+ * </p>
+ *
+ * @author chenhj
+ * @since 2025-06-14
+ */
+public interface OutputInventoryRecordService extends IService<OutputInventoryRecord> {
+
+    // 娣诲姞鍑哄簱璁板綍
+    int insertOutputInventoryRecord(PendingInventoryDto pendingInventoryDto, OfficialInventoryDto officialInventoryDto, BigDecimal quantity);
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/InputInventoryRecordServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/InputInventoryRecordServiceImpl.java
new file mode 100644
index 0000000..ac0a847
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/service/impl/InputInventoryRecordServiceImpl.java
@@ -0,0 +1,56 @@
+package com.ruoyi.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.business.dto.OfficialInventoryDto;
+import com.ruoyi.business.dto.PendingInventoryDto;
+import com.ruoyi.business.entity.InputInventoryRecord;
+import com.ruoyi.business.mapper.InputInventoryRecordMapper;
+import com.ruoyi.business.service.InputInventoryRecordService;
+import com.ruoyi.business.service.InventorySummaryService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+
+import static com.ruoyi.business.constant.InventoryRecordConstant.OFFICIAL_INVENTORY;
+import static com.ruoyi.business.constant.InventoryRecordConstant.PENDING_INVENTORY;
+
+/**
+ * <p>
+ * 鍏ュ簱璁板綍琛� 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author chenhj
+ * @since 2025-06-14
+ */
+@Service
+@RequiredArgsConstructor
+public class InputInventoryRecordServiceImpl extends ServiceImpl<InputInventoryRecordMapper, InputInventoryRecord> implements InputInventoryRecordService {
+    @Autowired
+    private InputInventoryRecordMapper inputInventoryRecordMapper;
+    @Autowired
+    private InventorySummaryService inventorySummaryService;
+
+    @Override
+    public int insertInputInventoryRecord(PendingInventoryDto pendingInventoryDto, OfficialInventoryDto officialInventoryDto, BigDecimal quantity) {
+        if ((pendingInventoryDto != null && officialInventoryDto != null) || (pendingInventoryDto == null && officialInventoryDto == null)) {
+            throw new RuntimeException("搴撳瓨璁板綍寮傚父");
+        }
+
+        InputInventoryRecord inputInventoryRecord = new InputInventoryRecord();
+        if (officialInventoryDto != null) {
+            inputInventoryRecord.setInventoryType(OFFICIAL_INVENTORY);
+            inputInventoryRecord.setId(officialInventoryDto.getId());
+        } else {
+            inputInventoryRecord.setInventoryType(PENDING_INVENTORY);
+            inputInventoryRecord.setId(pendingInventoryDto.getId());
+        }
+        inputInventoryRecord.setQuantity(quantity);
+
+        inputInventoryRecordMapper.insert(inputInventoryRecord);
+
+        // 鏇存柊搴撳瓨
+        return inventorySummaryService.updateInventory(pendingInventoryDto, officialInventoryDto);
+    }
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/InventorySummaryServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/InventorySummaryServiceImpl.java
new file mode 100644
index 0000000..b24f537
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/service/impl/InventorySummaryServiceImpl.java
@@ -0,0 +1,99 @@
+package com.ruoyi.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.business.dto.OfficialInventoryDto;
+import com.ruoyi.business.dto.PendingInventoryDto;
+import com.ruoyi.business.entity.*;
+import com.ruoyi.business.mapper.InventorySummaryMapper;
+import com.ruoyi.business.mapper.OfficialInventoryMapper;
+import com.ruoyi.business.mapper.PendingInventoryMapper;
+import com.ruoyi.business.service.InputInventoryRecordService;
+import com.ruoyi.business.service.InventorySummaryService;
+import com.ruoyi.business.service.OutputInventoryRecordService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import static com.ruoyi.business.constant.InventoryRecordConstant.OFFICIAL_INVENTORY;
+import static com.ruoyi.business.constant.InventoryRecordConstant.PENDING_INVENTORY;
+
+/**
+ * <p>
+ * 搴撳瓨姹囨�昏〃 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author chenhj
+ * @since 2025-06-14
+ */
+@Service
+@RequiredArgsConstructor
+public class InventorySummaryServiceImpl extends ServiceImpl<InventorySummaryMapper, InventorySummary> implements InventorySummaryService {
+    @Autowired
+    private InventorySummaryMapper inventorySummaryMapper;
+    @Autowired
+    private InputInventoryRecordService inputInventoryRecordService;
+    @Autowired
+    private OutputInventoryRecordService outputInventoryRecordService;
+    @Autowired
+    private PendingInventoryMapper pendingInventoryMapper;
+    @Autowired
+    private OfficialInventoryMapper officialInventoryMapper;
+
+    @Override
+    public int updateInventory(PendingInventoryDto pendingInventoryDto, OfficialInventoryDto officialInventoryDto) {
+        if ((pendingInventoryDto != null && officialInventoryDto != null) || (pendingInventoryDto == null && officialInventoryDto == null)) {
+            throw new RuntimeException("搴撳瓨璁板綍寮傚父");
+        }
+
+        String inventoryType = pendingInventoryDto != null ? PENDING_INVENTORY : OFFICIAL_INVENTORY;
+        Long inventoryId = pendingInventoryDto != null ? pendingInventoryDto.getId() : officialInventoryDto.getId();
+        Long inputEndRecordId = 0L;
+        Long outputEndRecordId = 0L;
+
+        InventorySummary inventorySummary = inventorySummaryMapper.selectOne(new LambdaQueryWrapper<InventorySummary>()
+                .eq(InventorySummary::getInventoryId, inventoryId)
+                .eq(InventorySummary::getInventoryType, inventoryType));
+        if (inventorySummary != null) {
+            inputEndRecordId = inventorySummary.getInputEndRecordId();
+            outputEndRecordId  = inventorySummary.getOutputEndRecordId();
+        }
+        // 鏌ヨ鑺傜偣浠ュ悗鎵�鏈夊叆搴撹褰�
+        List<InputInventoryRecord> inputInventoryRecords = inputInventoryRecordService.list(new LambdaQueryWrapper<InputInventoryRecord>()
+                .eq(InputInventoryRecord::getInventoryId, inventoryId)
+                .eq(InputInventoryRecord::getInventoryType, inventoryType)
+                .gt(InputInventoryRecord::getId, inputEndRecordId));
+        // 鏌ヨ鑺傜偣浠ュ悗鎵�鏈夊嚭搴撹褰�
+        List<OutputInventoryRecord> outputInventoryRecords = outputInventoryRecordService.list(new LambdaQueryWrapper<OutputInventoryRecord>()
+                .eq(OutputInventoryRecord::getInventoryId, inventoryId)
+                .eq(OutputInventoryRecord::getInventoryType, inventoryType)
+                .gt(OutputInventoryRecord::getId, outputEndRecordId));
+
+        // 濡傛灉鍏ュ簱鏁伴噺澶т簬鍑哄簱鏁伴噺锛屽垯搴撳瓨鏁伴噺涓哄叆搴撴暟閲忓噺鍘诲嚭搴撴暟閲忥紝鍙嶄箣鍒欎负0
+        BigDecimal quantity = BigDecimal.ZERO;
+        BigDecimal totalInputQuantity = inputInventoryRecords.stream().map(InputInventoryRecord::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal totalOutputQuantity = outputInventoryRecords.stream().map(OutputInventoryRecord::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
+        if (totalInputQuantity.compareTo(totalOutputQuantity) > 0) {
+            quantity = totalInputQuantity.subtract(totalOutputQuantity);
+        }
+        if (inventoryType.equals(PENDING_INVENTORY)) {
+            // 鍙樻洿寰呭叆搴撳��
+            PendingInventory pendingInventory = pendingInventoryMapper.getPendingInventoryForUpdateById(pendingInventoryDto.getId());
+            if (pendingInventory == null) {
+                throw new RuntimeException("搴撳瓨璁板綍涓嶅瓨鍦�");
+            }
+            pendingInventory.setInventoryQuantity(quantity);
+           return pendingInventoryMapper.updateById(pendingInventory);
+        } else {
+            OfficialInventory officialInventory = officialInventoryMapper.getOfficialInventoryForUpdateById(officialInventoryDto.getId());
+            if (officialInventory == null) {
+                throw new RuntimeException("搴撳瓨璁板綍涓嶅瓨鍦�");
+            }
+            officialInventory.setInventoryQuantity(quantity);
+            return officialInventoryMapper.updateById(officialInventory);
+        }
+    }
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/OutputInventoryRecordServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/OutputInventoryRecordServiceImpl.java
new file mode 100644
index 0000000..79f120f
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/service/impl/OutputInventoryRecordServiceImpl.java
@@ -0,0 +1,56 @@
+package com.ruoyi.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.business.dto.OfficialInventoryDto;
+import com.ruoyi.business.dto.PendingInventoryDto;
+import com.ruoyi.business.entity.OutputInventoryRecord;
+import com.ruoyi.business.mapper.OutputInventoryRecordMapper;
+import com.ruoyi.business.service.InventorySummaryService;
+import com.ruoyi.business.service.OutputInventoryRecordService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+
+import static com.ruoyi.business.constant.InventoryRecordConstant.OFFICIAL_INVENTORY;
+import static com.ruoyi.business.constant.InventoryRecordConstant.PENDING_INVENTORY;
+
+/**
+ * <p>
+ * 鍑哄簱璁板綍琛� 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author chenhj
+ * @since 2025-06-14
+ */
+@Service
+@RequiredArgsConstructor
+public class OutputInventoryRecordServiceImpl extends ServiceImpl<OutputInventoryRecordMapper, OutputInventoryRecord> implements OutputInventoryRecordService {
+    @Autowired
+    private OutputInventoryRecordMapper outputInventoryRecordMapper;
+    @Autowired
+    private InventorySummaryService inventorySummaryService;
+
+    @Override
+    public int insertOutputInventoryRecord(PendingInventoryDto pendingInventoryDto, OfficialInventoryDto officialInventoryDto, BigDecimal quantity) {
+        if ((pendingInventoryDto != null && officialInventoryDto != null) || (pendingInventoryDto == null && officialInventoryDto == null)) {
+            throw new RuntimeException("搴撳瓨璁板綍寮傚父");
+        }
+
+        OutputInventoryRecord outputInventoryRecord = new OutputInventoryRecord();
+        if (officialInventoryDto != null) {
+            outputInventoryRecord.setInventoryType(OFFICIAL_INVENTORY);
+            outputInventoryRecord.setId(officialInventoryDto.getId());
+        } else {
+            outputInventoryRecord.setInventoryType(PENDING_INVENTORY);
+            outputInventoryRecord.setId(pendingInventoryDto.getId());
+        }
+        outputInventoryRecord.setQuantity(quantity);
+
+        outputInventoryRecordMapper.insert(outputInventoryRecord);
+
+        // 鍙樻洿鍘熷簱瀛樹俊鎭�
+        return inventorySummaryService.updateInventory(pendingInventoryDto, officialInventoryDto);
+    }
+}
diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/PendingInventoryServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/PendingInventoryServiceImpl.java
index adbc5e9..784b846 100644
--- a/main-business/src/main/java/com/ruoyi/business/service/impl/PendingInventoryServiceImpl.java
+++ b/main-business/src/main/java/com/ruoyi/business/service/impl/PendingInventoryServiceImpl.java
@@ -136,6 +136,8 @@
                 pendingInventoryMapper.deleteById(pendingInventoryDto.getPId());
             }
             officialInventoryMapper.delete(new LambdaQueryWrapper<OfficialInventory>().eq(OfficialInventory::getPendingId, pendingInventoryDto.getPId()));
+
+
             OfficialInventory officialInventory = new OfficialInventory();
             BeanUtils.copyProperties(pendingInventory, officialInventory);
             officialInventory.setId(null);
diff --git a/main-business/src/main/java/com/ruoyi/business/task/InventorySummaryTask.java b/main-business/src/main/java/com/ruoyi/business/task/InventorySummaryTask.java
new file mode 100644
index 0000000..3268f1c
--- /dev/null
+++ b/main-business/src/main/java/com/ruoyi/business/task/InventorySummaryTask.java
@@ -0,0 +1,144 @@
+package com.ruoyi.business.task;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.ruoyi.business.entity.*;
+import com.ruoyi.business.mapper.*;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.session.ResultContext;
+import org.apache.ibatis.session.ResultHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static com.ruoyi.business.constant.InventoryRecordConstant.OFFICIAL_INVENTORY;
+import static com.ruoyi.business.constant.InventoryRecordConstant.PENDING_INVENTORY;
+
+@Slf4j
+@Component
+public class InventorySummaryTask {
+    @Autowired
+    private PendingInventoryMapper pendingInventoryMapper;
+    @Autowired
+    private OfficialInventoryMapper officialInventoryMapper;
+    @Autowired
+    private InventorySummaryMapper inventorySummaryMapper;
+    @Autowired
+    private InputInventoryRecordMapper inputInventoryRecordMapper;
+    @Autowired
+    private OutputInventoryRecordMapper outputInventoryRecordMapper;
+
+    private final ExecutorService executor = Executors.newFixedThreadPool(5);
+
+    // 姣忛殧10澶╃殑鍑屾櫒3鐐规墽琛�
+    @Scheduled(cron = "0 0 3 1/10 * ?")
+    @Transactional
+    public void updateInventorySummary() {
+        log.info("寮�濮嬫墽琛屽簱瀛樿妭鐐圭粺璁″畾鏃朵换鍔�: " + System.currentTimeMillis());
+        log.info("鏇存柊寰呭叆搴撳簱瀛樿妭鐐�");
+        updatePendingInventory();
+        log.info("鏇存柊姝e紡搴撳瓨鑺傜偣");
+        updateOfficialInventory();
+        log.info("缁撴潫鎵ц搴撳瓨鑺傜偣缁熻瀹氭椂浠诲姟: " + System.currentTimeMillis());
+    }
+
+    // 鏇存柊寰呭叆搴撳簱瀛樿妭鐐�
+    private void updatePendingInventory() {
+        pendingInventoryMapper.selectList(Wrappers.emptyWrapper(), new ResultHandler<PendingInventory>() {
+
+            @Override
+            public void handleResult(ResultContext<? extends PendingInventory> resultContext) {
+                PendingInventory pendingInventory = resultContext.getResultObject();
+                executor.submit(() -> {
+                    handleInventorySummary(pendingInventory, null);
+                });
+
+            }
+        });
+    }
+
+    // 鏇存柊姝e紡搴撳瓨鑺傜偣
+    private void updateOfficialInventory() {
+        officialInventoryMapper.selectList(Wrappers.emptyWrapper(), new ResultHandler<OfficialInventory>() {
+
+            @Override
+            public void handleResult(ResultContext<? extends OfficialInventory> resultContext) {
+                OfficialInventory officialInventory = resultContext.getResultObject();
+                executor.submit(() -> {
+                    handleInventorySummary(null, officialInventory);
+                });
+
+            }
+        });
+    }
+
+    // 鏇存柊鑺傜偣鏁版嵁
+    private void handleInventorySummary(PendingInventory pendingInventory, OfficialInventory officialInventory) {
+        InventorySummary inventorySummary = null;
+        List<InputInventoryRecord> inputInventoryRecordList = new ArrayList<>();
+        List<OutputInventoryRecord> outputInventoryRecordList = new ArrayList<>();
+
+        if (pendingInventory != null) {
+            inventorySummary = inventorySummaryMapper.getInventorySummaryForUpdateByInventoryIdAndType(pendingInventory.getId(), PENDING_INVENTORY);
+            inputInventoryRecordList = inputInventoryRecordMapper.selectList(new LambdaQueryWrapper<InputInventoryRecord>()
+                    .eq(InputInventoryRecord::getInventoryId, pendingInventory.getId())
+                    .eq(InputInventoryRecord::getInventoryType, PENDING_INVENTORY)
+                    .gt(InputInventoryRecord::getId, inventorySummary == null ? 0 : inventorySummary.getInputEndRecordId()));
+            outputInventoryRecordList = outputInventoryRecordMapper.selectList(new LambdaQueryWrapper<OutputInventoryRecord>()
+                    .eq(OutputInventoryRecord::getInventoryId, pendingInventory.getId())
+                    .eq(OutputInventoryRecord::getInventoryType, PENDING_INVENTORY)
+                    .gt(OutputInventoryRecord::getId, inventorySummary == null ? 0 : inventorySummary.getOutputEndRecordId()));
+
+            if (inventorySummary == null) {
+                inventorySummary = new InventorySummary();
+                inventorySummary.setInventoryQuantity(BigDecimal.ZERO);
+                inventorySummary.setInventoryId(pendingInventory.getId());
+                inventorySummary.setInventoryType(PENDING_INVENTORY);
+            }
+        }
+        if (officialInventory != null) {
+            inventorySummary = inventorySummaryMapper.getInventorySummaryForUpdateByInventoryIdAndType(officialInventory.getId(), OFFICIAL_INVENTORY);
+            inputInventoryRecordList = inputInventoryRecordMapper.selectList(new LambdaQueryWrapper<InputInventoryRecord>()
+                    .eq(InputInventoryRecord::getInventoryId, officialInventory.getId())
+                    .eq(InputInventoryRecord::getInventoryType, OFFICIAL_INVENTORY)
+                    .gt(InputInventoryRecord::getId, inventorySummary == null ? 0 : inventorySummary.getInputEndRecordId()));
+            outputInventoryRecordList = outputInventoryRecordMapper.selectList(new LambdaQueryWrapper<OutputInventoryRecord>()
+                    .eq(OutputInventoryRecord::getInventoryId, officialInventory.getId())
+                    .eq(OutputInventoryRecord::getInventoryType, OFFICIAL_INVENTORY)
+                    .gt(OutputInventoryRecord::getId, inventorySummary == null ? 0 : inventorySummary.getOutputEndRecordId()));
+            if (inventorySummary == null) {
+                inventorySummary = new InventorySummary();
+                inventorySummary.setInventoryQuantity(BigDecimal.ZERO);
+                inventorySummary.setInventoryId(officialInventory.getId());
+                inventorySummary.setInventoryType(OFFICIAL_INVENTORY);
+            }
+        }
+        BigDecimal total = inventorySummary.getInventoryQuantity();
+
+        BigDecimal inputTotal = BigDecimal.ZERO;
+        if (CollectionUtils.isNotEmpty(inputInventoryRecordList)) {
+            inputTotal = inputInventoryRecordList.stream().map(InputInventoryRecord::getQuantity).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
+            inventorySummary.setInputEndRecordId(inputInventoryRecordList.get(inputInventoryRecordList.size() - 1).getId());
+        }
+        BigDecimal outputTotal = BigDecimal.ZERO;
+        if (CollectionUtils.isNotEmpty(outputInventoryRecordList)) {
+            outputTotal = outputInventoryRecordList.stream().map(OutputInventoryRecord::getQuantity).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
+            inventorySummary.setOutputEndRecordId(outputInventoryRecordList.get(outputInventoryRecordList.size() - 1).getId());
+        }
+
+        if (inputTotal.compareTo(outputTotal) > 0) {
+            total = total.add(inputTotal.subtract(outputTotal));
+        }
+        inventorySummary.setInventoryQuantity(total);
+
+        inventorySummaryMapper.insertOrUpdate(inventorySummary);
+    }
+}
diff --git a/main-business/src/main/resources/db/migration/postgresql/V20250614110410__create_table_input_inventory_record.sql b/main-business/src/main/resources/db/migration/postgresql/V20250614110410__create_table_input_inventory_record.sql
new file mode 100644
index 0000000..fc23098
--- /dev/null
+++ b/main-business/src/main/resources/db/migration/postgresql/V20250614110410__create_table_input_inventory_record.sql
@@ -0,0 +1,29 @@
+DROP TABLE IF EXISTS input_inventory_record;
+
+-- 鍒涘缓鍏ュ簱璁板綍琛�
+CREATE TABLE input_inventory_record
+(
+    id             BIGSERIAL PRIMARY KEY,             -- 涓婚敭ID
+    inventory_id   bigint         not null default 0,
+    inventory_type varchar(10)    not null default '',
+    quantity       DECIMAL(10, 2) not null default 0,
+    deleted        INT            NOT NULL DEFAULT 0, -- 杞垹闄ゆ爣蹇楋細0=鏈垹闄わ紝1=宸插垹闄�
+    create_by      VARCHAR(255),                      -- 鍒涘缓浜虹敤鎴峰悕
+    create_time    TIMESTAMP WITHOUT TIME ZONE        -- 鍒涘缓鏃堕棿锛岄粯璁ゅ綋鍓嶆椂闂�
+
+);
+-- 鍒涘缓绱㈠紩
+create index index_inventory_id_and_inventory_type_and_quantity_for_input_inventory_record on input_inventory_record (inventory_id, inventory_type, quantity);
+
+
+-- 娣诲姞琛ㄦ敞閲�
+COMMENT ON TABLE input_inventory_record IS '鍏ュ簱璁板綍琛�';
+
+-- 娣诲姞瀛楁娉ㄩ噴
+COMMENT ON COLUMN input_inventory_record.id IS '涓婚敭ID';
+COMMENT ON COLUMN input_inventory_record.inventory_id IS '搴搃d';
+COMMENT ON COLUMN input_inventory_record.inventory_type IS '搴撶被鍨�';
+COMMENT ON COLUMN input_inventory_record.quantity IS '璁板綍鏁伴噺';
+COMMENT ON COLUMN input_inventory_record.deleted IS '杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�';
+COMMENT ON COLUMN input_inventory_record.create_by IS '鍒涘缓璇ヨ褰曠殑鐢ㄦ埛';
+COMMENT ON COLUMN input_inventory_record.create_time IS '璁板綍鍒涘缓鏃堕棿';
diff --git a/main-business/src/main/resources/db/migration/postgresql/V20250614111500__create_table_output_inventory_record.sql b/main-business/src/main/resources/db/migration/postgresql/V20250614111500__create_table_output_inventory_record.sql
new file mode 100644
index 0000000..735d2a0
--- /dev/null
+++ b/main-business/src/main/resources/db/migration/postgresql/V20250614111500__create_table_output_inventory_record.sql
@@ -0,0 +1,29 @@
+DROP TABLE IF EXISTS output_inventory_record;
+
+-- 鍒涘缓鍑哄簱璁板綍琛�
+CREATE TABLE output_inventory_record
+(
+    id             BIGSERIAL PRIMARY KEY,             -- 涓婚敭ID
+    inventory_id   bigint         not null default 0,
+    inventory_type varchar(10)    not null default '',
+    quantity       DECIMAL(10, 2) not null default 0,
+    deleted        INT            NOT NULL DEFAULT 0, -- 杞垹闄ゆ爣蹇楋細0=鏈垹闄わ紝1=宸插垹闄�
+    create_by      VARCHAR(255),                      -- 鍒涘缓浜虹敤鎴峰悕
+    create_time    TIMESTAMP WITHOUT TIME ZONE        -- 鍒涘缓鏃堕棿锛岄粯璁ゅ綋鍓嶆椂闂�
+
+);
+-- 鍒涘缓绱㈠紩
+create index index_inventory_id_and_inventory_type_and_quantity_for_output_inventory_record on output_inventory_record (inventory_id, inventory_type, quantity);
+
+
+-- 娣诲姞琛ㄦ敞閲�
+COMMENT ON TABLE output_inventory_record IS '鍑哄簱璁板綍琛�';
+
+-- 娣诲姞瀛楁娉ㄩ噴
+COMMENT ON COLUMN output_inventory_record.id IS '涓婚敭ID';
+COMMENT ON COLUMN output_inventory_record.inventory_id IS '搴搃d';
+COMMENT ON COLUMN output_inventory_record.inventory_type IS '搴撶被鍨�';
+COMMENT ON COLUMN output_inventory_record.quantity IS '璁板綍鏁伴噺';
+COMMENT ON COLUMN output_inventory_record.deleted IS '杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�';
+COMMENT ON COLUMN output_inventory_record.create_by IS '鍒涘缓璇ヨ褰曠殑鐢ㄦ埛';
+COMMENT ON COLUMN output_inventory_record.create_time IS '璁板綍鍒涘缓鏃堕棿';
diff --git a/main-business/src/main/resources/db/migration/postgresql/V20250614111811__create_table_inventory_summary.sql b/main-business/src/main/resources/db/migration/postgresql/V20250614111811__create_table_inventory_summary.sql
new file mode 100644
index 0000000..4c13ab3
--- /dev/null
+++ b/main-business/src/main/resources/db/migration/postgresql/V20250614111811__create_table_inventory_summary.sql
@@ -0,0 +1,30 @@
+DROP TABLE IF EXISTS inventory_summary;
+
+-- 鍒涘缓搴撳瓨姹囨�昏〃
+CREATE TABLE inventory_summary
+(
+    id                 BIGSERIAL PRIMARY KEY,             -- 涓婚敭ID
+    inventory_id       bigint         not null default 0,
+    inventory_type     varchar(10)    not null default '',
+    inventory_quantity DECIMAL(10, 2) not null default 0,
+    input_end_record_id      bigint         not null default 0,
+    output_end_record_id      bigint         not null default 0,
+    deleted            INT            NOT NULL DEFAULT 0, -- 杞垹闄ゆ爣蹇楋細0=鏈垹闄わ紝1=宸插垹闄�
+    create_time        TIMESTAMP WITHOUT TIME ZONE,       -- 鍒涘缓鏃堕棿锛岄粯璁ゅ綋鍓嶆椂闂�
+    update_time        TIMESTAMP WITHOUT TIME ZONE        -- 鏈�鍚庢洿鏂版椂闂达紝榛樿褰撳墠鏃堕棿
+);
+
+
+-- 娣诲姞琛ㄦ敞閲�
+COMMENT ON TABLE inventory_summary IS '搴撳瓨姹囨�昏〃';
+
+-- 娣诲姞瀛楁娉ㄩ噴
+COMMENT ON COLUMN inventory_summary.id IS '涓婚敭ID';
+COMMENT ON COLUMN inventory_summary.inventory_id IS '搴搃d';
+COMMENT ON COLUMN inventory_summary.inventory_type IS '搴撶被鍨�';
+COMMENT ON COLUMN inventory_summary.inventory_quantity IS '搴撳瓨鏁伴噺';
+COMMENT ON COLUMN inventory_summary.input_end_record_id IS '鍏ュ簱涓鏄庣粏璁板綍id';
+COMMENT ON COLUMN inventory_summary.output_end_record_id IS '鍑哄簱涓鏄庣粏璁板綍id';
+COMMENT ON COLUMN inventory_summary.deleted IS '杞垹闄ゆ爣蹇楋紝0=鏈垹闄わ紝1=宸插垹闄�';
+COMMENT ON COLUMN inventory_summary.create_time IS '璁板綍鍒涘缓鏃堕棿';
+COMMENT ON COLUMN inventory_summary.update_time IS '璁板綍鏈�鍚庢洿鏂版椂闂�';
diff --git a/main-business/src/main/resources/mapper/InputInventoryRecordMapper.xml b/main-business/src/main/resources/mapper/InputInventoryRecordMapper.xml
new file mode 100644
index 0000000..ef4d4a8
--- /dev/null
+++ b/main-business/src/main/resources/mapper/InputInventoryRecordMapper.xml
@@ -0,0 +1,24 @@
+<?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.business.mapper.InputInventoryRecordMapper">
+
+        <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+        <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.InputInventoryRecord">
+                    <id column="id" property="id" />
+                <result column="deleted" property="deleted" />
+                <result column="create_by" property="createBy" />
+                <result column="create_time" property="createTime" />
+                    <result column="inventory_id" property="inventoryId" />
+                    <result column="inventory_type" property="inventoryType" />
+                    <result column="quantity" property="quantity" />
+        </resultMap>
+
+        <!-- 閫氱敤鏌ヨ缁撴灉鍒� -->
+        <sql id="Base_Column_List">
+                deleted,
+                create_by,
+                create_time,
+            id, inventory_id, inventory_type, quantity
+        </sql>
+
+</mapper>
\ No newline at end of file
diff --git a/main-business/src/main/resources/mapper/InventorySummaryMapper.xml b/main-business/src/main/resources/mapper/InventorySummaryMapper.xml
new file mode 100644
index 0000000..20e5a2c
--- /dev/null
+++ b/main-business/src/main/resources/mapper/InventorySummaryMapper.xml
@@ -0,0 +1,38 @@
+<?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.business.mapper.InventorySummaryMapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.InventorySummary">
+        <id column="id" property="id"/>
+        <result column="deleted" property="deleted"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="inventory_id" property="inventoryId"/>
+        <result column="inventory_type" property="inventoryType"/>
+        <result column="inventory_quantity" property="inventoryQuantity"/>
+        <result column="input_end_record_id" property="inputEndRecordId"/>
+        <result column="output_end_record_id" property="outputEndRecordId"/>
+    </resultMap>
+
+    <!-- 閫氱敤鏌ヨ缁撴灉鍒� -->
+        <sql id="Base_Column_List">
+                deleted,
+                create_time,
+                update_time,
+            id, inventory_id, inventory_type, inventory_quantity, input_end_record_id, output_end_record_id
+        </sql>
+
+    <select id="getInventorySummaryForUpdateById" resultType="com.ruoyi.business.entity.InventorySummary">
+        select *
+        from inventory_summary
+        where id = #{id} for update
+    </select>
+
+    <select id="getInventorySummaryForUpdateByInventoryIdAndType" resultType="com.ruoyi.business.entity.InventorySummary">
+        select *
+        from inventory_summary
+        where inventory_id = #{inventoryId} and inventory_type = #{type} for update
+    </select>
+
+</mapper>
\ No newline at end of file
diff --git a/main-business/src/main/resources/mapper/OfficialInventoryMapper.xml b/main-business/src/main/resources/mapper/OfficialInventoryMapper.xml
index cc25283..7474896 100644
--- a/main-business/src/main/resources/mapper/OfficialInventoryMapper.xml
+++ b/main-business/src/main/resources/mapper/OfficialInventoryMapper.xml
@@ -3,32 +3,38 @@
 <mapper namespace="com.ruoyi.business.mapper.OfficialInventoryMapper">
 
         <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
-        <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.OfficialInventory">
-                    <id column="id" property="id" />
-                <result column="deleted" property="deleted" />
-                <result column="create_by" property="createBy" />
-                <result column="create_time" property="createTime" />
-                <result column="update_by" property="updateBy" />
-                <result column="update_time" property="updateTime" />
-                    <result column="supplier_name" property="supplierName" />
-                    <result column="coal" property="coal" />
-                    <result column="unit" property="unit" />
-                    <result column="inventory_quantity" property="inventoryQuantity" />
-                    <result column="price_including_tax" property="priceIncludingTax" />
-                    <result column="total_price_including_tax" property="totalPriceIncludingTax" />
-                    <result column="pending_replenishment" property="pendingReplenishment" />
-                    <result column="registrant_id" property="registrantId" />
-                    <result column="registration_date" property="registrationDate" />
-        </resultMap>
+    <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.OfficialInventory">
+        <id column="id" property="id"/>
+        <result column="deleted" property="deleted"/>
+        <result column="create_by" property="createBy"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_by" property="updateBy"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="supplier_name" property="supplierName"/>
+        <result column="coal" property="coal"/>
+        <result column="unit" property="unit"/>
+        <result column="inventory_quantity" property="inventoryQuantity"/>
+        <result column="price_including_tax" property="priceIncludingTax"/>
+        <result column="total_price_including_tax" property="totalPriceIncludingTax"/>
+        <result column="pending_replenishment" property="pendingReplenishment"/>
+        <result column="registrant_id" property="registrantId"/>
+        <result column="registration_date" property="registrationDate"/>
+    </resultMap>
 
         <!-- 閫氱敤鏌ヨ缁撴灉鍒� -->
-        <sql id="Base_Column_List">
-                deleted,
+    <sql id="Base_Column_List">
+        deleted,
                 create_by,
                 create_time,
                 update_by,
                 update_time,
             id, supplier_name, coal, unit, inventory_quantity, price_including_tax, total_price_including_tax, pending_replenishment, registrant_id, registration_date
-        </sql>
+    </sql>
+
+    <select id="getOfficialInventoryForUpdateById" resultType="com.ruoyi.business.entity.OfficialInventory">
+        select *
+        from official_inventory
+        where id = #{id} for update
+    </select>
 
 </mapper>
\ No newline at end of file
diff --git a/main-business/src/main/resources/mapper/OutputInventoryRecordMapper.xml b/main-business/src/main/resources/mapper/OutputInventoryRecordMapper.xml
new file mode 100644
index 0000000..64f20b5
--- /dev/null
+++ b/main-business/src/main/resources/mapper/OutputInventoryRecordMapper.xml
@@ -0,0 +1,24 @@
+<?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.business.mapper.OutputInventoryRecordMapper">
+
+        <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+        <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.OutputInventoryRecord">
+                    <id column="id" property="id" />
+                <result column="deleted" property="deleted" />
+                <result column="create_by" property="createBy" />
+                <result column="create_time" property="createTime" />
+                    <result column="inventory_id" property="inventoryId" />
+                    <result column="inventory_type" property="inventoryType" />
+                    <result column="quantity" property="quantity" />
+        </resultMap>
+
+        <!-- 閫氱敤鏌ヨ缁撴灉鍒� -->
+        <sql id="Base_Column_List">
+                deleted,
+                create_by,
+                create_time,
+            id, inventory_id, inventory_type, quantity
+        </sql>
+
+</mapper>
\ No newline at end of file
diff --git a/main-business/src/main/resources/mapper/PendingInventoryMapper.xml b/main-business/src/main/resources/mapper/PendingInventoryMapper.xml
index 5c503b8..3e7b6b9 100644
--- a/main-business/src/main/resources/mapper/PendingInventoryMapper.xml
+++ b/main-business/src/main/resources/mapper/PendingInventoryMapper.xml
@@ -2,23 +2,23 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ruoyi.business.mapper.PendingInventoryMapper">
 
-        <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
-        <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.PendingInventory">
-                    <id column="id" property="id" />
-                <result column="deleted" property="deleted" />
-                <result column="create_by" property="createBy" />
-                <result column="create_time" property="createTime" />
-                <result column="update_by" property="updateBy" />
-                <result column="update_time" property="updateTime" />
-                    <result column="supplier_name" property="supplierName" />
-                    <result column="coal" property="coal" />
-                    <result column="unit" property="unit" />
-                    <result column="inventory_quantity" property="inventoryQuantity" />
-                    <result column="price_including_tax" property="priceIncludingTax" />
-                    <result column="total_price_including_tax" property="totalPriceIncludingTax" />
-                    <result column="registrant_id" property="registrantId" />
-                    <result column="registration_date" property="registrationDate" />
-        </resultMap>
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.PendingInventory">
+        <id column="id" property="id"/>
+        <result column="deleted" property="deleted"/>
+        <result column="create_by" property="createBy"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_by" property="updateBy"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="supplier_name" property="supplierName"/>
+        <result column="coal" property="coal"/>
+        <result column="unit" property="unit"/>
+        <result column="inventory_quantity" property="inventoryQuantity"/>
+        <result column="price_including_tax" property="priceIncludingTax"/>
+        <result column="total_price_including_tax" property="totalPriceIncludingTax"/>
+        <result column="registrant_id" property="registrantId"/>
+        <result column="registration_date" property="registrationDate"/>
+    </resultMap>
 
         <!-- 閫氱敤鏌ヨ缁撴灉鍒� -->
         <sql id="Base_Column_List">
@@ -30,4 +30,10 @@
             id, supplier_name, coal, unit, inventory_quantity, price_including_tax, total_price_including_tax, registrant, registration_time
         </sql>
 
+    <select id="getPendingInventoryForUpdateById" resultType="com.ruoyi.business.entity.PendingInventory">
+        select *
+        from pending_inventory
+        where id = #{id} for update
+    </select>
+
 </mapper>
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/PlusCodeGenerator.java b/ruoyi-admin/src/main/java/com/ruoyi/PlusCodeGenerator.java
index ffd4834..3a2f71d 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/PlusCodeGenerator.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/PlusCodeGenerator.java
@@ -28,18 +28,18 @@
 public class PlusCodeGenerator {
 
     // 鏁版嵁搴撻厤缃�
-    private static final String DB_URL = "jdbc:postgresql://localhost:5432/ruoyi-zd";
+    private static final String DB_URL = "jdbc:postgresql://192.168.1.35:5432/ruoyi-zd";
     private static final String DB_USERNAME = "postgres";
     private static final String DB_PASSWORD = "123456";
 
     // 椤圭洰鍩虹閰嶇疆
     private static final String BASE_PACKAGE = "com.ruoyi";
-    private static final String MODULE_NAME = "basic"; // 妯″潡鍚�
+    private static final String MODULE_NAME = "business"; // 妯″潡鍚�
 
     public static void main(String[] args) {
         String projectPath = System.getProperty("user.dir"); // 鑾峰彇椤圭洰鏍硅矾寰�
-        String path = "basic-server"; // 妯″潡鍚嶇О
-        String table = "coal_info"; // 琛ㄥ悕锛屽涓〃閫楀彿闅斿紑
+        String path = "main-business"; // 妯″潡鍚嶇О
+        String table = "input_inventory_record,output_inventory_record,inventory_summary"; // 琛ㄥ悕锛屽涓〃閫楀彿闅斿紑
 
         // 浠g爜杈撳嚭璺緞閰嶇疆
         String outputBasePath = Paths.get(projectPath, path, "src", "main", "java").toString();
@@ -48,7 +48,7 @@
         // 浠g爜鐢熸垚鏍稿績閰嶇疆
         FastAutoGenerator.create(DB_URL, DB_USERNAME, DB_PASSWORD)
                 .globalConfig(builder -> {
-                    builder.author("ld") // 浣滆�呬俊鎭�
+                    builder.author("chenhj") // 浣滆�呬俊鎭�
                             .outputDir(outputBasePath) // 浠g爜杈撳嚭鐩綍
                             .dateType(DateType.ONLY_DATE) // 鏃ユ湡绫诲瀷
                             .commentDate("yyyy-MM-dd") // 娉ㄩ噴鏃ユ湡鏍煎紡
@@ -128,7 +128,7 @@
                     )); // 鍩虹被瀛楁
                     customMap.put("idType", "AUTO"); // 涓婚敭绫诲瀷
                     customMap.put("superEntityClass", "com.ruoyi.common.core.domain.MyBaseEntity"); // 鍩虹被鍏ㄨ矾寰�
-                    customMap.put("author", "ruoyi"); // 浣滆�呬俊鎭�
+                    customMap.put("author", "chenhj"); // 浣滆�呬俊鎭�
                     customMap.put("packageName", BASE_PACKAGE + "." + MODULE_NAME); // 鍖呭悕
                     customMap.put("tableName", table); // 琛ㄥ悕
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
index 32ae45f..ee23598 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
@@ -3,6 +3,7 @@
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 /**
  * 鍚姩绋嬪簭
@@ -10,6 +11,7 @@
  * @author ruoyi
  */
 @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
+@EnableScheduling
 public class RuoYiApplication
 {
     public static void main(String[] args)

--
Gitblit v1.9.3