From 931beabfe37a733b6d2fb92119dab3aabe869c98 Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期三, 11 三月 2026 11:08:34 +0800
Subject: [PATCH] Merge branch 'dev_宁夏_中盛建材' of http://114.132.189.42:9002/r/product-inventory-management-after into dev_宁夏_中盛建材

---
 src/main/java/com/ruoyi/productionPlan/mapper/ProductionPlanMapper.java            |    7 +
 src/main/java/com/ruoyi/productionPlan/controller/ProductionPlanController.java    |   10 ++
 src/main/java/com/ruoyi/productionPlan/service/impl/ProductionPlanServiceImpl.java |   61 ++++++++++++---
 src/main/java/com/ruoyi/productionPlan/dto/ProductionPlanSummaryDto.java           |   70 +++++++++++++++++
 src/main/resources/mapper/productionPlan/ProductionPlanMapper.xml                  |   29 +++++++
 src/main/java/com/ruoyi/productionPlan/service/ProductionPlanService.java          |    6 +
 6 files changed, 169 insertions(+), 14 deletions(-)

diff --git a/src/main/java/com/ruoyi/productionPlan/controller/ProductionPlanController.java b/src/main/java/com/ruoyi/productionPlan/controller/ProductionPlanController.java
index 5abb115..75f16b4 100644
--- a/src/main/java/com/ruoyi/productionPlan/controller/ProductionPlanController.java
+++ b/src/main/java/com/ruoyi/productionPlan/controller/ProductionPlanController.java
@@ -5,6 +5,7 @@
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.productionPlan.dto.ProductionPlanDto;
+import com.ruoyi.productionPlan.dto.ProductionPlanSummaryDto;
 import com.ruoyi.productionPlan.service.ProductionPlanService;
 import com.ruoyi.staff.dto.StaffLeaveDto;
 import io.swagger.annotations.Api;
@@ -38,6 +39,7 @@
     }
 
     @GetMapping("/loadProdData")
+    @ApiOperation("鎷夊彇閿�鍞敓浜ц鍒�")
     @Log(title = "鎷夊彇閿�鍞敓浜ц鍒�", businessType = BusinessType.INSERT)
     public AjaxResult loadProdData() {
         productionPlanService.loadProdData();
@@ -49,4 +51,12 @@
     public AjaxResult combine(@RequestBody ProductionPlanDto productionPlanDto) {
         return AjaxResult.success(productionPlanService.combine(productionPlanDto));
     }
+    
+    @GetMapping("/summaryByProductType")
+    @ApiOperation("鎸夌収浜у搧绫诲埆姹囨�荤粺璁¢渶姹傞噺")
+    @Log(title = "鎸夌収浜у搧绫诲埆姹囨�荤粺璁¢渶姹傞噺", businessType = BusinessType.OTHER)
+    public AjaxResult summaryByProductType(ProductionPlanSummaryDto query) {
+        List<ProductionPlanSummaryDto> list = productionPlanService.summaryByProductType(query);
+        return AjaxResult.success(list);
+    }
 }
diff --git a/src/main/java/com/ruoyi/productionPlan/dto/ProductionPlanSummaryDto.java b/src/main/java/com/ruoyi/productionPlan/dto/ProductionPlanSummaryDto.java
new file mode 100644
index 0000000..0831d89
--- /dev/null
+++ b/src/main/java/com/ruoyi/productionPlan/dto/ProductionPlanSummaryDto.java
@@ -0,0 +1,70 @@
+package com.ruoyi.productionPlan.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * <br>
+ * 閿�鍞敓浜ч渶姹� - 浜у搧绫诲瀷姹囨�籇TO
+ * </br>
+ *
+ * @author deslrey
+ * @version 1.0
+ * @since 2026/03/11 10:24
+ */
+@Data
+@ApiModel("鐢熶骇闇�姹備骇鍝佹眹鎬�")
+public class ProductionPlanSummaryDto {
+
+    /**
+     * 鐗╂枡缂栫爜
+     */
+    @ApiModelProperty("鐗╂枡缂栫爜")
+    private String materialCode;
+
+    /**
+     * 浜у搧鍚嶇О
+     */
+    @ApiModelProperty("浜у搧鍚嶇О")
+    private String productName;
+
+    /**
+     * 浜у搧瑙勬牸
+     */
+    @ApiModelProperty("浜у搧瑙勬牸")
+    private String productSpec;
+
+    /**
+     * 浜у搧闀垮害
+     */
+    @ApiModelProperty("浜у搧闀垮害")
+    private Integer length;
+
+    /**
+     * 浜у搧瀹藉害
+     */
+    @ApiModelProperty("浜у搧瀹藉害")
+    private Integer width;
+
+    /**
+     * 浜у搧楂樺害
+     */
+    @ApiModelProperty("浜у搧楂樺害")
+    private Integer height;
+
+    /**
+     * 姹囨�诲潡鏁�
+     */
+    @ApiModelProperty("姹囨�诲潡鏁�")
+    private Integer quantity;
+
+    /**
+     * 姹囨�绘柟鏁�
+     */
+    @ApiModelProperty("姹囨�绘柟鏁�")
+    private BigDecimal volume;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/productionPlan/mapper/ProductionPlanMapper.java b/src/main/java/com/ruoyi/productionPlan/mapper/ProductionPlanMapper.java
index b7b863b..d6a7577 100644
--- a/src/main/java/com/ruoyi/productionPlan/mapper/ProductionPlanMapper.java
+++ b/src/main/java/com/ruoyi/productionPlan/mapper/ProductionPlanMapper.java
@@ -4,9 +4,11 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.productionPlan.dto.ProductionPlanDto;
+import com.ruoyi.productionPlan.dto.ProductionPlanSummaryDto;
 import com.ruoyi.productionPlan.pojo.ProductionPlan;
-import com.ruoyi.staff.dto.StaffLeaveDto;
 import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <br>
@@ -19,4 +21,7 @@
  */
 public interface ProductionPlanMapper extends BaseMapper<ProductionPlan> {
     IPage<ProductionPlanDto> listPage(Page page, @Param("c") ProductionPlanDto productionPlanDto);
+
+    List<ProductionPlanSummaryDto> selectSummaryByProductType(ProductionPlanSummaryDto query);
+
 }
diff --git a/src/main/java/com/ruoyi/productionPlan/service/ProductionPlanService.java b/src/main/java/com/ruoyi/productionPlan/service/ProductionPlanService.java
index 4302d93..b90f165 100644
--- a/src/main/java/com/ruoyi/productionPlan/service/ProductionPlanService.java
+++ b/src/main/java/com/ruoyi/productionPlan/service/ProductionPlanService.java
@@ -4,6 +4,7 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.productionPlan.dto.ProductionPlanDto;
+import com.ruoyi.productionPlan.dto.ProductionPlanSummaryDto;
 import com.ruoyi.productionPlan.pojo.ProductionPlan;
 
 import java.util.List;
@@ -34,4 +35,9 @@
      * 鍚堝苟鐢熶骇璁″垝
      */
     boolean combine(ProductionPlanDto productionPlanDto);
+
+    /**
+     * 鎸夌収浜у搧绫诲埆姹囨�荤粺璁¢渶姹傞噺
+     */
+    List<ProductionPlanSummaryDto> summaryByProductType(ProductionPlanSummaryDto query);
 }
diff --git a/src/main/java/com/ruoyi/productionPlan/service/impl/ProductionPlanServiceImpl.java b/src/main/java/com/ruoyi/productionPlan/service/impl/ProductionPlanServiceImpl.java
index 595db7e..f2e238c 100644
--- a/src/main/java/com/ruoyi/productionPlan/service/impl/ProductionPlanServiceImpl.java
+++ b/src/main/java/com/ruoyi/productionPlan/service/impl/ProductionPlanServiceImpl.java
@@ -14,6 +14,7 @@
 import com.ruoyi.production.pojo.ProductOrder;
 import com.ruoyi.production.service.ProductOrderService;
 import com.ruoyi.productionPlan.dto.ProductionPlanDto;
+import com.ruoyi.productionPlan.dto.ProductionPlanSummaryDto;
 import com.ruoyi.productionPlan.mapper.ProductionPlanMapper;
 import com.ruoyi.productionPlan.pojo.ProductionPlan;
 import com.ruoyi.productionPlan.service.ProductionPlanService;
@@ -30,9 +31,9 @@
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
 
 /**
  * <br>
@@ -186,8 +187,8 @@
                 List<ProductionPlan> list = parseProductionPlans(dataArr, dataSyncType, totalCount);
                 if (!list.isEmpty()) {
                     //  澶勭悊鏇存柊鎴栨柊澧�
-                    processSaveOrUpdate(list);
-                    totalSynced += list.size();
+                    int affected = processSaveOrUpdate(list);
+                    totalSynced += affected;
                 }
 
                 //  鍒ゆ柇鏄惁杩樻湁涓嬩竴椤�
@@ -330,19 +331,48 @@
         return list;
     }
 
-    private void processSaveOrUpdate(List<ProductionPlan> list) {
+    private int processSaveOrUpdate(List<ProductionPlan> list) {
+        if (list == null || list.isEmpty()) {
+            return 0;
+        }
+        int affected = 0;
+
+        //  鍘婚噸 formInstanceId
+        Set<String> formIds = list.stream()
+                .map(ProductionPlan::getFormInstanceId)
+                .collect(Collectors.toSet());
+
+        //  鏌ヨ鏁版嵁搴撳凡鏈夋暟鎹�
+        List<ProductionPlan> existList = this.list(new LambdaQueryWrapper<ProductionPlan>().in(ProductionPlan::getFormInstanceId, formIds));
+
+        //  Map (formInstanceId + materialCode)
+        Map<String, ProductionPlan> existMap = new HashMap<>();
+        for (ProductionPlan p : existList) {
+            String key = p.getFormInstanceId() + "_" + p.getMaterialCode();
+            existMap.put(key, p);
+        }
+
+        //  閬嶅巻鍚屾鏁版嵁
         for (ProductionPlan plan : list) {
-            LambdaQueryWrapper<ProductionPlan> queryWrapper = new LambdaQueryWrapper<>();
-            queryWrapper.eq(ProductionPlan::getFormInstanceId, plan.getFormInstanceId())
-                    .eq(ProductionPlan::getMaterialCode, plan.getMaterialCode());
-            ProductionPlan existing = this.getOne(queryWrapper);
-            if (existing != null) {
-                plan.setId(existing.getId());
-                this.updateById(plan);
-            } else {
+            String key = plan.getFormInstanceId() + "_" + plan.getMaterialCode();
+            ProductionPlan exist = existMap.get(key);
+            if (exist == null) {
+                // 鏂板
                 this.save(plan);
+                affected++;
+                log.info("鏂板鏁版嵁 formInstanceId={}, materialCode={}", plan.getFormInstanceId(), plan.getMaterialCode());
+            } else {
+                // 鍒ゆ柇鏄惁闇�瑕佹洿鏂�
+                if (exist.getFormModifiedTime() == null || !exist.getFormModifiedTime().equals(plan.getFormModifiedTime())) {
+                    plan.setId(exist.getId());
+                    plan.setCreateTime(exist.getCreateTime());
+                    this.updateById(plan);
+                    affected++;
+                    log.info("鏇存柊鏁版嵁 formInstanceId={}, materialCode={}", plan.getFormInstanceId(), plan.getMaterialCode());
+                }
             }
         }
+        return affected;
     }
 
     private LocalDateTime parseUtcTime(String utcString) {
@@ -357,4 +387,9 @@
             return null;
         }
     }
+
+    @Override
+    public List<ProductionPlanSummaryDto> summaryByProductType(ProductionPlanSummaryDto query) {
+        return baseMapper.selectSummaryByProductType(query);
+    }
 }
diff --git a/src/main/resources/mapper/productionPlan/ProductionPlanMapper.xml b/src/main/resources/mapper/productionPlan/ProductionPlanMapper.xml
index 1fc9456..0b205d6 100644
--- a/src/main/resources/mapper/productionPlan/ProductionPlanMapper.xml
+++ b/src/main/resources/mapper/productionPlan/ProductionPlanMapper.xml
@@ -44,4 +44,33 @@
         WHERE 1 = 1
     </select>
 
+    <select id="selectSummaryByProductType" resultType="com.ruoyi.productionPlan.dto.ProductionPlanSummaryDto">
+        SELECT
+        material_code,
+        product_name,
+        product_spec,
+        length,
+        width,
+        height,
+        COALESCE(SUM(quantity),0) AS quantity,
+        COALESCE(SUM(volume),0) AS volume
+        FROM production_plan
+        <where>
+            <if test="materialCode != null and materialCode != ''">
+                AND material_code LIKE CONCAT('%', #{materialCode}, '%')
+            </if>
+
+            <if test="productName != null and productName != ''">
+                AND product_name LIKE CONCAT('%', #{productName}, '%')
+            </if>
+        </where>
+        GROUP BY
+        material_code,
+        product_name,
+        product_spec,
+        length,
+        width,
+        height
+    </select>
+
 </mapper>
\ No newline at end of file

--
Gitblit v1.9.3