Преглед изворни кода

产品总量接口
未完成工单数统计接口
所有未完成工单的产品(相同产品合并)统计接口
半年内每月工单统计和逾期工单统计

wangpx пре 8 месеци
родитељ
комит
f66977e355

+ 1 - 2
src/main/java/cn/com/GogoApplication.java

@@ -1,12 +1,11 @@
 package cn.com;
 
-import cn.com.v2.util.DataSourceUtil;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 
 @SpringBootApplication
-@MapperScan({"cn.com.v2.mapper", "cn.com.energy.mapper", "cn.com.oa.mapper"})
+@MapperScan({"cn.com.v2.mapper", "cn.com.mes.mapper", "cn.com.energy.mapper", "cn.com.oa.mapper"})
 public class GogoApplication {
 
 	public static void main(String[] args) {

+ 281 - 0
src/main/java/cn/com/mes/controller/BigViewMesController.java

@@ -0,0 +1,281 @@
+package cn.com.mes.controller;
+
+import cn.com.v2.common.base.BaseController;
+import cn.com.v2.common.domain.AjaxResult;
+import cn.com.mes.service.IBigViewMesService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * MES大屏统计接口控制器
+ * 
+ * @author system
+ * @date 2024-12-19
+ */
+@Api(tags = "MES大屏统计")
+@RestController
+@RequestMapping("/api/mes")
+public class BigViewMesController extends BaseController {
+    
+    @Autowired
+    private IBigViewMesService bigViewStatisticsService;
+
+    /**
+     * 1. 产品总量接口
+     *  预计生产总量, 当前生产总量, 排产总量
+     */
+    @ApiOperation(value = "获取产品总量统计", notes = "获取产品总量统计数据")
+    @GetMapping("/productTotal")
+    public AjaxResult getProductTotal() {
+        try {
+            Map<String, Object> result = bigViewStatisticsService.getProductTotal();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取产品总量统计失败", e);
+            return AjaxResult.error("获取产品总量统计失败:" + e.getMessage());
+        }
+    }
+
+   /**
+    * 2. 未完成工单数统计接口
+    */
+   @ApiOperation(value = "获取未完成工单详情统计", notes = "获取未完成工单详情统计数据")
+   @GetMapping("/incompleteWorkordersTotal")
+   public AjaxResult getIncompleteWorkordersTotal() {
+       try {
+           Map<String, Object> result = bigViewStatisticsService.getIncompleteWorkorders();
+           return success().put("data", result);
+       } catch (Exception e) {
+//            logger.error("获取未完成工单统计失败", e);
+           return AjaxResult.error("获取未完成工单统计失败:" + e.getMessage());
+       }
+   }
+
+    /**
+     * 3. 所有未完成工单的产品(相同产品合并)统计接口
+     */
+    @ApiOperation(value = "获取未完成工单产品统计", notes = "获取未完成工单产品统计数据,相同产品合并")
+    @GetMapping("/incompleteWorkorderProducts")
+    public AjaxResult getIncompleteWorkorderProducts() {
+        try {
+            List<Map<String, Object>> result = bigViewStatisticsService.getIncompleteWorkorderProducts();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取未完成工单产品统计失败", e);
+            return AjaxResult.error("获取未完成工单产品统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 3. 半年内每月工单统计和逾期工单统计
+     * 查找半年内每月工单的总工单和完成时间finish_date超过预期时间request_date的逾期工单
+     * 当当前时间超过request_date的也是逾期工单
+     */
+    @ApiOperation(value = "获取半年内每月工单统计和逾期工单统计", notes = "获取半年内每月工单统计和逾期工单统计数据")
+    @GetMapping("/monthlyOverdueWorkorderStatistics")
+    public AjaxResult getMonthlyOverdueWorkorderStatistics() {
+        try {
+            List<Map<String, Object>> result = bigViewStatisticsService.getMonthlyOverdueWorkorderStatistics();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取半年内每月工单统计和逾期工单统计失败", e);
+            return AjaxResult.error("获取半年内每月工单统计和逾期工单统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 4.生产工单统计(一周内每天不同产品的数据)
+     * 查询pro_workorder表中status不为NULL且不为PREPARE的所有数据
+     * 传入产品ids,按日期和产品分组统计,返回一周内每天每个产品的汇总信息
+     */
+    @ApiOperation(value = "根据产品IDs获取生产工单统计", notes = "获取一周内每天不同产品的生产工单统计数据")
+    @GetMapping("/productionWorkorderStatisticsByProductIds")
+    public AjaxResult getProductionWorkorderStatisticsByProductIds(@RequestParam String productIds) {
+        try {
+            List<Map<String, Object>> result = bigViewStatisticsService.getProductionWorkorderStatisticsByProductIds(productIds);
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取生产工单统计失败", e);
+            return AjaxResult.error("获取生产工单统计失败:" + e.getMessage());
+        }
+    }
+
+    // TODO
+    /**
+     * 2. 月预计工单完成总量接口
+     */
+    @ApiOperation(value = "获取月预计工单完成总量", notes = "获取月预计工单完成总量统计数据")
+    @GetMapping("/monthlyWorkorderCompletion")
+    public AjaxResult getMonthlyWorkorderCompletion() {
+        try {
+            Map<String, Object> result = bigViewStatisticsService.getMonthlyWorkorderCompletion();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取月预计工单完成总量统计失败", e);
+            return AjaxResult.error("获取月预计工单完成总量统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 3. 月交易总额(采购金额+销售总额)接口
+     */
+    @GetMapping("/monthlyTransactionTotal")
+    public AjaxResult getMonthlyTransactionTotal() {
+        try {
+            Map<String, Object> result = bigViewStatisticsService.getMonthlyTransactionTotal();
+            return success().put("data", result);
+        } catch (Exception e) {
+            return AjaxResult.error("获取月交易总额统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 4. 月未完成工单数接口
+     */
+    @ApiOperation(value = "获取月未完成工单数", notes = "获取月未完成工单数统计数据")
+    @GetMapping("/monthlyIncompleteOrders")
+    public AjaxResult getMonthlyIncompleteOrders() {
+        try {
+            Map<String, Object> result = bigViewStatisticsService.getMonthlyIncompleteOrders();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取月未完成订单数统计失败", e);
+            return AjaxResult.error("获取月未完成订单数统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 8.1 当月出货统计接口
+     */
+    @ApiOperation(value = "获取出货统计", notes = "获取当月出货统计数据")
+    @GetMapping("/shipmentStatistics")
+    public AjaxResult getShipmentStatistics() {
+        try {
+            Map<String, Object> result = bigViewStatisticsService.getShipmentStatistics();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取出货统计失败", e);
+            return AjaxResult.error("获取出货统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 8.2 年度出货统计接口
+     */
+    @ApiOperation(value = "获取年度出货统计", notes = "获取年度出货统计数据")
+    @GetMapping("/monthlyShipmentStatistics")
+    public AjaxResult getMonthlyShipmentStatistics() {
+        try {
+            List<Map<String, Object>> result = bigViewStatisticsService.getMonthlyShipmentStatistics();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取出货统计失败", e);
+            return AjaxResult.error("获取出货统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 9. 人员周考勤统计接口
+     */
+    @ApiOperation(value = "获取人员周考勤统计", notes = "获取人员周考勤统计数据")
+    @GetMapping("/weeklyAttendanceStatistics")
+    public AjaxResult getWeeklyAttendanceStatistics() {
+        try {
+            Map<String, Object> result = bigViewStatisticsService.getWeeklyAttendanceStatistics();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取人员周考勤统计失败", e);
+            return AjaxResult.error("获取人员周考勤统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 10. 设备预处理统计接口
+     */
+    @ApiOperation(value = "获取设备预处理统计", notes = "获取设备预处理统计数据")
+    @GetMapping("/equipmentPreprocessingStatistics")
+    public AjaxResult getEquipmentPreprocessingStatistics() {
+        try {
+            Map<String, Object> result = bigViewStatisticsService.getEquipmentPreprocessingStatistics();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取设备预处理统计失败", e);
+            return AjaxResult.error("获取设备预处理统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 1. 生产工单统计
+     */
+    @ApiOperation(value = "获取生产工单统计", notes = "获取生产工单统计数据")
+    @GetMapping("/productionWorkorderStatistics")
+    public AjaxResult getProductionWorkorderStatistics() {
+        try {
+            List<Map<String, Object>> result = bigViewStatisticsService.getProductionWorkorderStatistics();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取生产工单统计失败", e);
+            return AjaxResult.error("获取生产工单统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 2. 当日未完成工单的产品统计(相同产品合并)
+     * 查询当日pro_workorder表中status不为NULL且不在('PREPARE', 'FINISHED')的所有数据
+     * 按产品分组统计,返回每个产品的汇总信息
+     */
+    @ApiOperation(value = "获取当日未完成工单产品统计", notes = "获取当日未完成工单产品统计数据,相同产品合并")
+    @GetMapping("/dailyIncompleteWorkorderProducts")
+    public AjaxResult getDailyIncompleteWorkorderProducts() {
+        try {
+            List<Map<String, Object>> result = bigViewStatisticsService.getDailyIncompleteWorkorderProducts();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取当日未完成工单产品统计失败", e);
+            return AjaxResult.error("获取当日未完成工单产品统计失败:" + e.getMessage());
+        }
+    }
+
+
+    /**
+     * 5. 未排产工单统计
+     * 查询pro_workorder表中status不为NULL且不为PREPARE和FINISHED的所有数据
+     * 一月内每周的未排产工单统计
+     */
+    @ApiOperation(value = "获取未排产工单统计", notes = "获取一月内每周的未排产工单统计数据")
+    @GetMapping("/unplannedWorkorderStatistics")
+    public AjaxResult getUnplannedWorkorderStatistics() {
+        try {
+            List<Map<String, Object>> result = bigViewStatisticsService.getUnplannedWorkorderStatistics();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取未排产工单统计失败", e);
+            return AjaxResult.error("获取未排产工单统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 6. 一周内工单合格率统计
+     * 查询pro_workorder表中status不为NULL且不为PREPARE的所有数据
+     * 传入合格率,按日期分组统计,返回一周内每个日期低于合格率的工单数据
+     */
+    @ApiOperation(value = "获取一周内工单合格率统计", notes = "获取一周内工单合格率统计数据")
+    @GetMapping("/weeklyQualifiedWorkorderStatistics")
+    public AjaxResult getWeeklyQualifiedWorkorderStatistics(@RequestParam String qualifiedRate) {
+        try {
+           List<Map<String, Object>> result = bigViewStatisticsService.getWeeklyQualifiedWorkorderStatistics(qualifiedRate);
+           return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取一周内工单合格率统计失败", e);
+            return AjaxResult.error("获取一周内工单合格率统计失败:" + e.getMessage());
+        }
+    }
+}

+ 150 - 0
src/main/java/cn/com/mes/controller/BigViewWmsController.java

@@ -0,0 +1,150 @@
+package cn.com.mes.controller;
+
+import cn.com.v2.common.base.BaseController;
+import cn.com.v2.common.domain.AjaxResult;
+import cn.com.mes.service.IBigViewWmsService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * WMS大屏统计接口控制器
+ * 
+ * @author system
+ * @date 2024-12-19
+ */
+@Api(tags = "WMS大屏统计")
+@RestController
+@RequestMapping("/api/wms")
+public class BigViewWmsController extends BaseController {
+    
+    @Autowired
+    private IBigViewWmsService bigViewWmsService;
+
+    /**
+     * 1. 当日入库数据接口
+     */
+    @ApiOperation(value = "获取当日入库数据", notes = "获取当日入库数据统计")
+    @GetMapping("/dailyInboundData")
+    public AjaxResult getDailyInboundData() {
+        try {
+            Map<String, Object> result = bigViewWmsService.getDailyInboundData();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取当日入库数据统计失败", e);
+            return AjaxResult.error("获取当日入库数据统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 2. 当日出库数据接口
+     */
+    @ApiOperation(value = "获取当日出库数据", notes = "获取当日出库数据统计")
+    @GetMapping("/dailyOutboundData")
+    public AjaxResult getDailyOutboundData() {
+        try {
+            Map<String, Object> result = bigViewWmsService.getDailyOutboundData();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取当日出库数据统计失败", e);
+            return AjaxResult.error("获取当日出库数据统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 3. 本周物料单统计接口(每日)
+     */
+    @ApiOperation(value = "获取本周物料单统计", notes = "获取本周物料单统计数据(每日)")
+    @GetMapping("/weeklyMaterialOrderStatistics")
+    public AjaxResult getWeeklyMaterialOrderStatistics() {
+        try {
+            Map<String, Object> result = bigViewWmsService.getWeeklyMaterialOrderStatistics();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取本周物料单统计失败", e);
+            return AjaxResult.error("获取本周物料单统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 4. 本周吞吐量统计接口(每日)
+     */
+    @ApiOperation(value = "获取本周吞吐量统计", notes = "获取本周吞吐量统计数据(每日)")
+    @GetMapping("/weeklyThroughputStatistics")
+    public AjaxResult getWeeklyThroughputStatistics() {
+        try {
+            Map<String, Object> result = bigViewWmsService.getWeeklyThroughputStatistics();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取本周吞吐量统计失败", e);
+            return AjaxResult.error("获取本周吞吐量统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 5. 剩余库位统计接口
+     */
+    @ApiOperation(value = "获取剩余库位统计", notes = "获取剩余库位统计数据")
+    @GetMapping("/remainingStorageLocations")
+    public AjaxResult getRemainingStorageLocations() {
+        try {
+            Map<String, Object> result = bigViewWmsService.getRemainingStorageLocations();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取剩余库位统计失败", e);
+            return AjaxResult.error("获取剩余库位统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 6. 剩余料箱统计接口(智能仓)
+     */
+    @ApiOperation(value = "获取剩余料箱统计", notes = "获取剩余料箱统计数据(智能仓)")
+    @GetMapping("/remainingSmartBins")
+    public AjaxResult getRemainingSmartBins() {
+        try {
+            Map<String, Object> result = bigViewWmsService.getRemainingSmartBins();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取剩余料箱统计失败", e);
+            return AjaxResult.error("获取剩余料箱统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 7. 库位统计接口(按仓库统计)
+     */
+    @ApiOperation(value = "获取库位统计", notes = "获取库位统计数据(按仓库统计)")
+    @GetMapping("/storageLocationStatistics")
+    public AjaxResult getStorageLocationStatistics() {
+        try {
+            Map<String, Object> result = bigViewWmsService.getStorageLocationStatistics();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取库位统计失败", e);
+            return AjaxResult.error("获取库位统计失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 8. 仓库事件列表接口(滚动展示)
+     * 包含:产品名称、所属工单、操作设备、类型、物料位置
+     */
+    @ApiOperation(value = "获取仓库事件列表", notes = "获取仓库事件列表(滚动展示)")
+    @GetMapping("/warehouseEvents")
+    public AjaxResult getWarehouseEvents() {
+        try {
+            List<Map<String, Object>> result = bigViewWmsService.getWarehouseEvents();
+            return success().put("data", result);
+        } catch (Exception e) {
+//            logger.error("获取仓库事件列表失败", e);
+            return AjaxResult.error("获取仓库事件列表失败:" + e.getMessage());
+        }
+    }
+}

+ 111 - 0
src/main/java/cn/com/mes/mapper/BigViewMesMapper.java

@@ -0,0 +1,111 @@
+package cn.com.mes.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 大屏统计Mapper接口
+ * 
+ * @author system
+ * @date 2024-12-19
+ */
+@Mapper
+public interface BigViewMesMapper {
+    
+    /**
+     * 获取产品总量统计
+     * @return 包含总量、已生产量、排产量、变更量的统计数据
+     */
+    Map<String, Object> getProductTotal();
+
+    /**
+     * 获取未完成工单统计数据
+     */
+    int getCountIncompleteWorkorders();
+
+    /**
+     * 查询未完成工单列表
+     */
+    List<Map<String, Object>> selectIncompleteWorkorders();
+
+    /**
+     * 统计月预计工单完成总量
+     */
+    int countMonthlyWorkorders();
+    
+    /**
+     * 获取月交易总额统计
+     */
+    Map<String, Object> getMonthlyTransactionTotal();
+    
+    /**
+     * 统计月未完成工单数
+     */
+    int countMonthlyIncompleteWorkorders();
+
+    
+    /**
+     * 查询未完成工单产品统计(相同产品合并)
+     */
+    List<Map<String, Object>> selectIncompleteWorkorderProductsGroup();
+
+    /**
+     * 获取出货统计
+     */
+    Map<String, Object> getShipmentStatistics();
+    
+    /**
+     * 获取人员周考勤统计
+     */
+    Map<String, Object> getWeeklyAttendanceStatistics();
+    
+    /**
+     * 获取设备预处理统计
+     */
+    Map<String, Object> getEquipmentPreprocessingStatistics();
+    
+    /**
+     * 获取年度出货统计
+     */
+    List<Map<String, Object>> getMonthlyShipmentStatistics();
+    
+    /**
+     * 获取生产工单统计
+     */
+    List<Map<String, Object>> selectProductionWorkorderStatistics();
+    
+    /**
+     * 获取当日未完成工单产品统计(相同产品合并)
+     */
+    List<Map<String, Object>> selectDailyIncompleteWorkorderProducts();
+    
+    /**
+     * 获取半年内每月工单统计和逾期工单统计
+     */
+    List<Map<String, Object>> selectMonthlyOverdueWorkorderStatistics();
+    
+    /**
+     * 根据产品IDs获取生产工单统计(一周内每天不同产品的数据)
+     * 
+     * @param productIds 产品ID列表,逗号分隔
+     */
+    List<Map<String, Object>> selectProductionWorkorderStatisticsByProductIds(@Param("productIds") String productIds);
+    
+    /**
+     * 获取一周内工单合格率统计
+     * 
+     * @param qualifiedRate 合格率阈值
+     */
+    List<Map<String, Object>> selectWeeklyQualifiedWorkorderStatistics(@Param("qualifiedRate") String qualifiedRate);
+    
+    /**
+     * 获取未排产工单统计
+     */
+    List<Map<String, Object>> selectUnplannedWorkorderStatistics();
+
+    List<Map<String, Object>> selectWmProductSalseLineList();
+
+}

+ 56 - 0
src/main/java/cn/com/mes/mapper/BigViewWmsMapper.java

@@ -0,0 +1,56 @@
+package cn.com.mes.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * WMS大屏统计Mapper接口
+ * 
+ * @author system
+ * @date 2024-12-19
+ */
+@Mapper
+public interface BigViewWmsMapper {
+    
+    /**
+     * 获取当日入库数据统计
+     */
+    Map<String, Object> getDailyInboundData();
+    
+    /**
+     * 获取当日出库数据统计
+     */
+    Map<String, Object> getDailyOutboundData();
+    
+    /**
+     * 获取本周物料单统计(每日)
+     */
+    Map<String, Object> getWeeklyMaterialOrderStatistics();
+    
+    /**
+     * 获取本周吞吐量统计(每日)
+     */
+    Map<String, Object> getWeeklyThroughputStatistics();
+    
+    /**
+     * 获取剩余库位统计
+     */
+    Map<String, Object> getRemainingStorageLocations();
+    
+    /**
+     * 获取剩余料箱统计(智能仓)
+     */
+    Map<String, Object> getRemainingSmartBins();
+    
+    /**
+     * 获取库位统计(按仓库统计)
+     */
+    Map<String, Object> getStorageLocationStatistics();
+    
+    /**
+     * 获取仓库事件列表(滚动展示)
+     */
+    List<Map<String, Object>> getWarehouseEvents();
+}

+ 103 - 0
src/main/java/cn/com/mes/service/IBigViewMesService.java

@@ -0,0 +1,103 @@
+package cn.com.mes.service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 大屏统计服务接口
+ * 
+ * @author system
+ * @date 2024-12-19
+ */
+public interface IBigViewMesService {
+    
+    /**
+     * 获取产品总量统计
+     */
+    Map<String, Object> getProductTotal();
+
+    Map<String, Object> getIncompleteWorkorders();
+    
+    /**
+     * 获取月预计工单完成总量统计
+     */
+    Map<String, Object> getMonthlyWorkorderCompletion();
+    
+    /**
+     * 获取月交易总额统计
+     */
+    Map<String, Object> getMonthlyTransactionTotal();
+    
+    /**
+     * 获取月未完成订单数统计
+     */
+    Map<String, Object> getMonthlyIncompleteOrders();
+    
+    /**
+     * 获取未完成工单的产品统计(相同产品合并)
+     */
+    List<Map<String, Object>> getIncompleteWorkorderProducts();
+
+    /**
+     * 获取出货统计
+     */
+    Map<String, Object> getShipmentStatistics();
+    
+    /**
+     * 获取人员周考勤统计
+     */
+    Map<String, Object> getWeeklyAttendanceStatistics();
+    
+    /**
+     * 获取设备预处理统计
+     */
+    Map<String, Object> getEquipmentPreprocessingStatistics();
+
+    /**
+     * 获取年度出货统计
+     */
+    List<Map<String, Object>> getMonthlyShipmentStatistics();
+
+    /**
+     * 获取生产工单统计
+     */
+    List<Map<String, Object>> getProductionWorkorderStatistics();
+    
+    /**
+     * 获取当日未完成工单的产品统计(相同产品合并)
+     */
+    List<Map<String, Object>> getDailyIncompleteWorkorderProducts();
+    
+    /**
+     * 获取半年内每月工单统计和逾期工单统计
+     * 包括每月总工单数和逾期工单数(finish_date超过request_date或当前时间超过request_date)
+     */
+    List<Map<String, Object>> getMonthlyOverdueWorkorderStatistics();
+    
+    /**
+     * 根据产品IDs获取生产工单统计(一周内每天不同产品的数据)
+     * 查询pro_workorder表中status不为NULL且不为PREPARE的所有数据
+     * 传入产品ids,按日期和产品分组统计,返回一周内每天每个产品的汇总信息
+     * @param productIds 产品ID列表,逗号分隔
+     * @return 按日期和产品分组的工单统计列表
+     */
+    List<Map<String, Object>> getProductionWorkorderStatisticsByProductIds(String productIds);
+    
+    /**
+     * 获取一周内工单合格率统计
+     * 查询qc_ipqc、qc_oqc、qc_iqc表中status为FINISHED或CONFIRMED的数据
+     * 传入合格率,按日期分组统计,返回一周内每个日期低于合格率的工单数据
+     * @param qualifiedRate 合格率阈值
+     * @return 一周内低于合格率的工单统计列表
+     */
+    List<Map<String, Object>> getWeeklyQualifiedWorkorderStatistics(String qualifiedRate);
+    
+    /**
+     * 获取未排产工单统计
+     * 查询pro_workorder表中status不为NULL且不为PREPARE的所有数据
+     * 一月内每周的未排产工单统计
+     * @return 一月内每周的未排产工单统计列表
+     */
+    List<Map<String, Object>> getUnplannedWorkorderStatistics();
+
+}

+ 54 - 0
src/main/java/cn/com/mes/service/IBigViewWmsService.java

@@ -0,0 +1,54 @@
+package cn.com.mes.service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * WMS大屏统计服务接口
+ * 
+ * @author system
+ * @date 2024-12-19
+ */
+public interface IBigViewWmsService {
+    
+    /**
+     * 获取当日入库数据统计
+     */
+    Map<String, Object> getDailyInboundData();
+    
+    /**
+     * 获取当日出库数据统计
+     */
+    Map<String, Object> getDailyOutboundData();
+    
+    /**
+     * 获取本周物料单统计(每日)
+     */
+    Map<String, Object> getWeeklyMaterialOrderStatistics();
+    
+    /**
+     * 获取本周吞吐量统计(每日)
+     */
+    Map<String, Object> getWeeklyThroughputStatistics();
+    
+    /**
+     * 获取剩余库位统计
+     */
+    Map<String, Object> getRemainingStorageLocations();
+    
+    /**
+     * 获取剩余料箱统计(智能仓)
+     */
+    Map<String, Object> getRemainingSmartBins();
+    
+    /**
+     * 获取库位统计(按仓库统计)
+     */
+    Map<String, Object> getStorageLocationStatistics();
+    
+    /**
+     * 获取仓库事件列表(滚动展示)
+     * 包含:产品名称、所属工单、操作设备、类型、物料位置
+     */
+    List<Map<String, Object>> getWarehouseEvents();
+}

+ 344 - 0
src/main/java/cn/com/mes/service/impl/BigViewMesServiceImpl.java

@@ -0,0 +1,344 @@
+package cn.com.mes.service.impl;
+
+import cn.com.mes.mapper.BigViewMesMapper;
+import cn.com.mes.service.IBigViewMesService;
+import cn.hutool.core.date.DateUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 大屏统计服务实现类
+ * 
+ * @author system
+ * @date 2024-12-19
+ */
+@Service
+public class BigViewMesServiceImpl implements IBigViewMesService {
+    
+    @Autowired
+    private BigViewMesMapper bigViewMesMapper;
+
+    @Override
+    public Map<String, Object> getProductTotal() {
+
+        // 直接从mapper查询产品总量
+        Map<String, Object> result = bigViewMesMapper.getProductTotal();
+
+        result.put("statisticsTime", DateUtil.now());
+        
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getIncompleteWorkorders() {
+        // 获取未完成工单统计数据
+        int total = bigViewMesMapper.getCountIncompleteWorkorders();
+        
+        // 获取未完成工单详细列表
+        List<Map<String, Object>> workorderList = bigViewMesMapper.selectIncompleteWorkorders();
+        
+        // 合并统计数据和详细列表
+        Map<String, Object> result = new HashMap<>();
+        result.put("total", total);
+        result.put("workorderList", workorderList);
+        result.put("statisticsTime", DateUtil.now());
+        
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getMonthlyWorkorderCompletion() {
+        Map<String, Object> result = new HashMap<>();
+        
+        // 获取当前月份
+        LocalDate now = LocalDate.now();
+        int currentMonth = now.getMonthValue();
+        int currentYear = now.getYear();
+
+        int expectedCompletion = bigViewMesMapper.countMonthlyWorkorders();
+        
+        result.put("month", currentMonth);
+        result.put("year", currentYear);
+        result.put("expectedCompletion", expectedCompletion);
+        result.put("statisticsTime", DateUtil.now());
+        
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getMonthlyTransactionTotal() {
+        Map<String, Object> result = new HashMap<>();
+
+        // 获取当前月份
+        LocalDate now = LocalDate.now();
+        int currentMonth = now.getMonthValue();
+        int currentYear = now.getYear();
+
+        // 统计本月销售总额
+        List<Map<String, Object>> salesLines = bigViewMesMapper.selectWmProductSalseLineList();
+        BigDecimal salesTotal = salesLines.stream()
+                .map(line -> {
+                    BigDecimal price = line.get("price") != null ? (BigDecimal) line.get("price") : BigDecimal.ZERO;
+                    BigDecimal quantity = line.get("quantitySalse") != null ? (BigDecimal) line.get("quantitySalse") : BigDecimal.ZERO;
+                    return price.multiply(quantity);
+                })
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+        // 采购金额统计(这里需要根据实际的采购数据表来实现)
+        BigDecimal purchaseTotal = BigDecimal.ZERO; // 暂时设为0,需要根据实际采购表来实现
+
+        BigDecimal totalTransaction = salesTotal.add(purchaseTotal);
+
+        result.put("month", currentMonth);
+        result.put("year", currentYear);
+        result.put("salesTotal", salesTotal);
+        result.put("purchaseTotal", purchaseTotal);
+        result.put("totalTransaction", totalTransaction);
+        result.put("statisticsTime", DateUtil.now());
+
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getMonthlyIncompleteOrders() {
+        Map<String, Object> result = new HashMap<>();
+        
+        // 获取当前月份
+        LocalDate now = LocalDate.now();
+        int currentMonth = now.getMonthValue();
+        int currentYear = now.getYear();
+
+        int incompleteOrders = bigViewMesMapper.countMonthlyIncompleteWorkorders();
+        
+        result.put("month", currentMonth);
+        result.put("year", currentYear);
+        result.put("incompleteOrders", incompleteOrders);
+        result.put("statisticsTime", DateUtil.now());
+        
+        return result;
+    }
+
+//    @Override
+//    public List<Map<String, Object>> getIncompleteWorkorders() {
+//        List<Map<String, Object>> result = bigViewMesMapper.selectIncompleteWorkorders();
+//
+//        // 为每个未完成工单添加统计时间
+//        for (Map<String, Object> workorderInfo : result) {
+//            workorderInfo.put("statisticsTime", DateUtil.now());
+//        }
+//
+//        return result;
+//    }
+
+    @Override
+    public List<Map<String, Object>> getIncompleteWorkorderProducts() {
+        List<Map<String, Object>> result = bigViewMesMapper.selectIncompleteWorkorderProductsGroup();
+        
+        // 为每个产品统计添加统计时间
+        for (Map<String, Object> productStat : result) {
+            productStat.put("statisticsTime", DateUtil.now());
+        }
+        
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getShipmentStatistics() {
+        Map<String, Object> result = new HashMap<>();
+        
+        // 获取当前月份
+        LocalDate now = LocalDate.now();
+        int currentMonth = now.getMonthValue();
+        int currentYear = now.getYear();
+        
+        // 获取出货统计数据
+        Map<String, Object> shipmentData = bigViewMesMapper.getShipmentStatistics();
+        BigDecimal finishedQuantity = (BigDecimal) shipmentData.getOrDefault("finishedQuantity", BigDecimal.ZERO);
+        BigDecimal plannedQuantity = (BigDecimal) shipmentData.getOrDefault("plannedQuantity", BigDecimal.ZERO);
+        
+        result.put("month", currentMonth);
+        result.put("year", currentYear);
+        result.put("finishedQuantity", finishedQuantity);
+        result.put("plannedQuantity", plannedQuantity);
+        result.put("totalQuantity", finishedQuantity.add(plannedQuantity));
+        result.put("statisticsTime", DateUtil.now());
+        
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getWeeklyAttendanceStatistics() {
+        Map<String, Object> result = new HashMap<>();
+        
+        // 获取当前周的数据
+        LocalDate now = LocalDate.now();
+        LocalDate weekStart = now.with(java.time.DayOfWeek.MONDAY);
+        LocalDate weekEnd = weekStart.plusDays(6);
+        
+        // 获取考勤统计数据
+        Map<String, Object> attendanceData = bigViewMesMapper.getWeeklyAttendanceStatistics();
+        
+        result.put("weekStart", weekStart.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        result.put("weekEnd", weekEnd.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        result.putAll(attendanceData);
+        result.put("statisticsTime", DateUtil.now());
+        
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getEquipmentPreprocessingStatistics() {
+        Map<String, Object> result = bigViewMesMapper.getEquipmentPreprocessingStatistics();
+        result.put("statisticsTime", DateUtil.now());
+        
+        return result;
+    }
+
+    @Override
+    public List<Map<String, Object>> getMonthlyShipmentStatistics() {
+        List<Map<String, Object>> result = bigViewMesMapper.getMonthlyShipmentStatistics();
+        
+        // 为每个月份统计添加统计时间
+        for (Map<String, Object> monthStat : result) {
+            monthStat.put("statisticsTime", DateUtil.now());
+        }
+        
+        return result;
+    }
+
+    @Override
+    public List<Map<String, Object>> getProductionWorkorderStatistics() {
+        List<Map<String, Object>> result = bigViewMesMapper.selectProductionWorkorderStatistics();
+        
+        // 为每个统计添加统计时间
+        for (Map<String, Object> stat : result) {
+            stat.put("statisticsTime", DateUtil.now());
+        }
+        
+        return result;
+    }
+    
+    @Override
+    public List<Map<String, Object>> getDailyIncompleteWorkorderProducts() {
+        List<Map<String, Object>> result = bigViewMesMapper.selectDailyIncompleteWorkorderProducts();
+        
+        // 为每个产品统计添加统计时间
+        for (Map<String, Object> productStat : result) {
+            productStat.put("statisticsTime", DateUtil.now());
+        }
+        
+        return result;
+    }
+    
+    @Override
+    public List<Map<String, Object>> getMonthlyOverdueWorkorderStatistics() {
+        List<Map<String, Object>> result = bigViewMesMapper.selectMonthlyOverdueWorkorderStatistics();
+        
+        // 为每个月份统计添加统计时间
+        for (Map<String, Object> monthStat : result) {
+            monthStat.put("statisticsTime", DateUtil.now());
+        }
+        
+        return result;
+    }
+    
+    @Override
+    public List<Map<String, Object>> getProductionWorkorderStatisticsByProductIds(String productIds) {
+        // 获取原始数据
+        List<Map<String, Object>> rawData = bigViewMesMapper.selectProductionWorkorderStatisticsByProductIds(productIds);
+        
+        // 按日期分组
+        Map<String, Map<String, Object>> groupedByDate = new HashMap<>();
+        Set<String> productNames = new HashSet<>();
+        
+        // 第一次遍历:收集所有产品名称并按日期分组
+        for (Map<String, Object> record : rawData) {
+            String date = (String) record.get("statisticsDate");
+            String productName = (String) record.get("productName");
+            productNames.add(productName);
+            
+            // 初始化或获取该日期的数据
+            Map<String, Object> dayData = groupedByDate.computeIfAbsent(date, k -> {
+                Map<String, Object> newDay = new HashMap<>();
+                newDay.put("date", date);
+                // 获取星期几
+                try {
+                    LocalDate localDate = LocalDate.parse(date);
+                    String dayOfWeek = localDate.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.CHINESE);
+                    newDay.put("dayOfWeek", dayOfWeek);
+                } catch (Exception e) {
+                    newDay.put("dayOfWeek", "未知");
+                }
+                return newDay;
+            });
+            
+            // 将产品数据添加到日期数据中
+            dayData.put(productName, new HashMap<String, Object>() {{
+                put("workorderCount", record.get("workorderCount"));
+                put("totalQuantity", record.get("totalQuantity"));
+                put("totalProducedQuantity", record.get("totalProducedQuantity"));
+                put("totalIncompleteQuantity", record.get("totalIncompleteQuantity"));
+            }});
+        }
+        
+        // 确保每天都有所有产品的数据,没有的补零
+        for (Map<String, Object> dayData : groupedByDate.values()) {
+            for (String productName : productNames) {
+                if (!dayData.containsKey(productName)) {
+                    dayData.put(productName, new HashMap<String, Object>() {{
+                        put("workorderCount", 0);
+                        put("totalQuantity", 0);
+                        put("totalProducedQuantity", 0);
+                        put("totalIncompleteQuantity", 0);
+                    }});
+                }
+            }
+        }
+        
+        // 转换为列表并按日期排序
+        List<Map<String, Object>> result = new ArrayList<>(groupedByDate.values());
+        result.sort((a, b) -> ((String) a.get("date")).compareTo((String) b.get("date")));
+        
+        return result;
+    }
+    
+    @Override
+    public List<Map<String, Object>> getWeeklyQualifiedWorkorderStatistics(String qualifiedRate) {
+        List<Map<String, Object>> result = bigViewMesMapper.selectWeeklyQualifiedWorkorderStatistics(qualifiedRate);
+        
+        // 为每个统计添加统计时间
+        for (Map<String, Object> qualifiedStat : result) {
+            qualifiedStat.put("statisticsTime", DateUtil.now());
+        }
+        
+        return result;
+    }
+    
+    @Override
+    public List<Map<String, Object>> getUnplannedWorkorderStatistics() {
+        List<Map<String, Object>> result = bigViewMesMapper.selectUnplannedWorkorderStatistics();
+        
+        // 为每个统计添加统计时间
+        for (Map<String, Object> unplannedStat : result) {
+            unplannedStat.put("statisticsTime", DateUtil.now());
+        }
+        
+        return result;
+    }
+
+}

+ 106 - 0
src/main/java/cn/com/mes/service/impl/BigViewWmsServiceImpl.java

@@ -0,0 +1,106 @@
+package cn.com.mes.service.impl;
+
+import cn.com.mes.mapper.BigViewWmsMapper;
+import cn.com.mes.service.IBigViewWmsService;
+import cn.hutool.core.date.DateUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * WMS大屏统计服务实现类
+ * 
+ * @author system
+ * @date 2024-12-19
+ */
+@Service
+public class BigViewWmsServiceImpl implements IBigViewWmsService {
+    
+    @Autowired
+    private BigViewWmsMapper bigViewWmsMapper;
+
+    @Override
+    public Map<String, Object> getDailyInboundData() {
+        Map<String, Object> result = bigViewWmsMapper.getDailyInboundData();
+        result.put("statisticsTime", DateUtil.now());
+        result.put("statisticsDate", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getDailyOutboundData() {
+        Map<String, Object> result = bigViewWmsMapper.getDailyOutboundData();
+        result.put("statisticsTime", DateUtil.now());
+        result.put("statisticsDate", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getWeeklyMaterialOrderStatistics() {
+        Map<String, Object> result = bigViewWmsMapper.getWeeklyMaterialOrderStatistics();
+        
+        // 获取当前周的数据
+        LocalDate now = LocalDate.now();
+        LocalDate weekStart = now.with(java.time.DayOfWeek.MONDAY);
+        LocalDate weekEnd = weekStart.plusDays(6);
+        
+        result.put("weekStart", weekStart.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        result.put("weekEnd", weekEnd.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        result.put("statisticsTime", DateUtil.now());
+        
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getWeeklyThroughputStatistics() {
+        Map<String, Object> result = bigViewWmsMapper.getWeeklyThroughputStatistics();
+        
+        // 获取当前周的数据
+        LocalDate now = LocalDate.now();
+        LocalDate weekStart = now.with(java.time.DayOfWeek.MONDAY);
+        LocalDate weekEnd = weekStart.plusDays(6);
+        
+        result.put("weekStart", weekStart.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        result.put("weekEnd", weekEnd.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        result.put("statisticsTime", DateUtil.now());
+        
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getRemainingStorageLocations() {
+        Map<String, Object> result = bigViewWmsMapper.getRemainingStorageLocations();
+        result.put("statisticsTime", DateUtil.now());
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getRemainingSmartBins() {
+        Map<String, Object> result = bigViewWmsMapper.getRemainingSmartBins();
+        result.put("statisticsTime", DateUtil.now());
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> getStorageLocationStatistics() {
+        Map<String, Object> result = bigViewWmsMapper.getStorageLocationStatistics();
+        result.put("statisticsTime", DateUtil.now());
+        return result;
+    }
+
+    @Override
+    public List<Map<String, Object>> getWarehouseEvents() {
+        List<Map<String, Object>> result = bigViewWmsMapper.getWarehouseEvents();
+        
+        // 为每个事件添加统计时间
+        for (Map<String, Object> event : result) {
+            event.put("statisticsTime", DateUtil.now());
+        }
+        
+        return result;
+    }
+}

+ 12 - 0
src/main/java/cn/com/v2/common/config/DataSourceConfig.java

@@ -50,6 +50,17 @@ public class DataSourceConfig {
         return DataSourceBuilder.create().build();
     }
 
+    /**
+     * 数据源4
+     * spring.datasource.db2:application.properteis中对应属性的前缀
+     * @return
+     */
+    @Bean(name = "mes")
+    @ConfigurationProperties(prefix = "spring.datasource.mes")
+    public DataSource dataSourceFour() {
+        return DataSourceBuilder.create().build();
+    }
+
     /**
      * 动态数据源: 通过AOP在不同数据源之间动态切换
      * @return
@@ -65,6 +76,7 @@ public class DataSourceConfig {
         dsMap.put("v2", dataSourceOne());
         dsMap.put("energy", dataSourceTwo());
         dsMap.put("oa", dataSourceThree());
+        dsMap.put("mes", dataSourceFour());
         dynamicDataSource.setTargetDataSources(dsMap);
         return dynamicDataSource;
     }

+ 14 - 2
src/main/resources/application-hnyz.yml

@@ -19,7 +19,7 @@ spring:
 
     energy:
       driver-class-name: com.mysql.cj.jdbc.Driver
-      jdbc-url: jdbc:mysql://192.168.254.253:9906/yz_emcs?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+      jdbc-url: jdbc:mysql://localhost:9906/yz_emcs?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
       username: root
       password: 11rrRRvv90)*9&FuuI}{
       druid:
@@ -31,7 +31,19 @@ spring:
 
     oa:
       driver-class-name: com.mysql.cj.jdbc.Driver
-      jdbc-url: jdbc:mysql://192.168.254.253:9906/ygtx_oa?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+      jdbc-url: jdbc:mysql://localhost:9906/ygtx_oa?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+      username: root
+      password: 11rrRRvv90)*9&FuuI}{
+      druid:
+        initial-size: 10
+        max-active: 100
+        min-idle: 30
+        max-wait: 40
+        validation-query: SELECT 1
+
+    mes:
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://localhost:9906/ygtx_emcs?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
       username: root
       password: 11rrRRvv90)*9&FuuI}{
       druid:

+ 431 - 0
src/main/resources/mapper/mes/BigViewMesMapper.xml

@@ -0,0 +1,431 @@
+<?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="cn.com.mes.mapper.BigViewMesMapper">
+
+    <!-- 统计产品总量 -->
+    <select id="getProductTotal" resultType="java.util.Map">
+        SELECT COALESCE(SUM(quantity), 0) as totalProducts,
+               COALESCE(SUM(quantity_produced), 0) as totalProducedProducts,
+               COALESCE(SUM(quantity_scheduled), 0) as totalScheduledProducts,
+               COALESCE(SUM(quantity_changed), 0) as totalChangedProducts
+        FROM pro_workorder 
+        WHERE status IS NOT NULL
+            AND status NOT IN ('PREPARE')
+    </select>
+
+    <!-- 获取未完成工单统计数据 -->
+    <select id="getCountIncompleteWorkorders" resultType="int">
+        SELECT
+            COUNT(workorder_id) as totalIncomplete
+        FROM pro_workorder
+        WHERE status IS NOT NULL
+          AND status NOT IN ('PREPARE', 'FINISHED')
+    </select>
+
+    <!-- 查询未完成工单列表 -->
+    <select id="selectIncompleteWorkorders" resultType="java.util.Map">
+        SELECT
+            workorder_id as workorderId,
+            workorder_code as workorderCode,
+            workorder_name as workorderName,
+            product_name as productName,
+            status,
+            request_date as requestDate,
+            finish_date as finishDate,
+            quantity as totalQuantity,
+            COALESCE(quantity_produced, 0) as producedQuantity,
+            COALESCE(quantity_scheduled, 0) as scheduledQuantity,
+            COALESCE(quantity_changed, 0) as changedQuantity,
+            (quantity - COALESCE(quantity_produced, 0)) as incompleteQuantity,
+            CASE
+                WHEN quantity > 0 THEN ROUND((COALESCE(quantity_produced, 0) / quantity) * 100, 2)
+                ELSE 0
+                END as completionRate,
+            CASE
+                WHEN quantity > 0 THEN ROUND((COALESCE(quantity_scheduled, 0) / quantity) * 100, 2)
+                ELSE 0
+                END as schedulingRate
+        FROM pro_workorder
+        WHERE status IS NOT NULL
+          AND status NOT IN ('PREPARE', 'FINISHED')
+        ORDER BY create_time DESC
+    </select>
+
+    <!-- 查询未完成工单产品统计(相同产品合并) -->
+    <select id="selectIncompleteWorkorderProductsGroup" resultType="java.util.Map">
+        SELECT
+            product_name as productName,
+            product_id as productId,
+            COUNT(*) as workorderCount,
+            SUM(quantity) as totalQuantity,
+            SUM(COALESCE(quantity_produced, 0)) as totalProducedQuantity,
+            SUM(COALESCE(quantity_scheduled, 0)) as totalScheduledQuantity,
+            SUM(quantity - COALESCE(quantity_produced, 0)) as totalIncompleteQuantity,
+            CASE
+                WHEN SUM(quantity) > 0 THEN ROUND((SUM(COALESCE(quantity_produced, 0)) / SUM(quantity)) * 100, 2)
+                ELSE 0
+                END as averageCompletionRate,
+            CASE
+                WHEN SUM(quantity) > 0 THEN ROUND((SUM(COALESCE(quantity_scheduled, 0)) / SUM(quantity)) * 100, 2)
+                ELSE 0
+                END as averageSchedulingRate
+        FROM pro_workorder
+        WHERE status IS NOT NULL
+          AND status NOT IN ('PREPARE', 'FINISHED')
+        GROUP BY product_id, product_name
+        ORDER BY totalIncompleteQuantity DESC
+    </select>
+
+    <!-- 获取半年内每月工单统计和逾期工单统计 -->
+    <select id="selectMonthlyOverdueWorkorderStatistics" resultType="java.util.Map">
+        SELECT
+            DATE_FORMAT(d.stat_date, '%Y-%m') AS month_year_str,
+            YEAR(d.stat_date) AS stat_year,
+            MONTH(d.stat_date) AS stat_month,
+            COALESCE(w.total_workorders, 0) AS total_workorders,
+            COALESCE(w.overdue_workorders, 0) AS overdue_workorders,
+            CASE
+            WHEN COALESCE(w.total_workorders, 0) > 0
+            THEN ROUND(COALESCE(w.overdue_workorders, 0) * 100.0 / w.total_workorders, 2)
+            ELSE 0.00
+        END AS overdue_rate
+        FROM (
+            SELECT DATE_SUB(CURDATE(), INTERVAL nums.n MONTH) AS stat_date
+            FROM (
+                SELECT 0 AS n UNION ALL
+                SELECT 1 UNION ALL
+                SELECT 2 UNION ALL
+                SELECT 3 UNION ALL
+                SELECT 4 UNION ALL
+                SELECT 5
+            ) nums
+        ) d
+        LEFT JOIN (
+            SELECT
+                DATE_FORMAT(request_date, '%Y-%m') AS stat_month_year,
+            COUNT(*) AS total_workorders,
+            SUM(CASE
+                    WHEN (finish_date IS NOT NULL AND finish_date > request_date)
+                        OR (finish_date IS NULL AND NOW() > request_date)
+                        THEN 1
+                    ELSE 0
+                END) AS overdue_workorders
+        FROM pro_workorder
+        WHERE request_date >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
+          AND status IS NOT NULL
+        GROUP BY DATE_FORMAT(request_date, '%Y-%m')
+        ) w ON DATE_FORMAT(d.stat_date, '%Y-%m') = w.stat_month_year
+        ORDER BY d.stat_date ASC
+    </select>
+
+    <!-- 根据产品IDs获取生产工单统计(一周内每天不同产品的数据) -->
+    <select id="selectProductionWorkorderStatisticsByProductIds" resultType="java.util.Map" parameterType="string">
+        SELECT
+        DATE_FORMAT(d.stat_date, '%Y-%m-%d') as stat_date_str,
+        YEAR(d.stat_date) as stat_year,
+        MONTH(d.stat_date) as stat_month,
+        DAY(d.stat_date) as stat_day,
+        DATE_FORMAT(d.stat_date, '%Y-%m') as month_year_str,
+        DAYOFWEEK(d.stat_date) as day_of_week,
+        CASE DAYOFWEEK(d.stat_date)
+        WHEN 1 THEN '周日'
+        WHEN 2 THEN '周一'
+        WHEN 3 THEN '周二'
+        WHEN 4 THEN '周三'
+        WHEN 5 THEN '周四'
+        WHEN 6 THEN '周五'
+        WHEN 7 THEN '周六'
+        END as day_name,
+        COALESCE(w.product_id, 0) as product_id,
+        COALESCE(w.product_code, '') as product_code,
+        COALESCE(w.product_name, '') as product_name,
+        COALESCE(w.product_spc, '') as product_spc,
+        COALESCE(w.unit_of_measure, '') as unit_of_measure,
+        COALESCE(w.workorder_count, 0) as workorder_count,
+        COALESCE(w.total_quantity, 0) as total_quantity,
+        COALESCE(w.total_produced_quantity, 0) as total_produced_quantity,
+        COALESCE(w.total_scheduled_quantity, 0) as total_scheduled_quantity,
+        COALESCE(w.total_changed_quantity, 0) as total_changed_quantity,
+        COALESCE(w.total_incomplete_quantity, 0) as total_incomplete_quantity,
+        COALESCE(w.completion_rate, 0.00) as completion_rate,
+        COALESCE(w.scheduling_rate, 0.00) as scheduling_rate,
+        w.earliest_request_date,
+        w.latest_request_date,
+        COALESCE(w.all_statuses, '') as all_statuses
+        FROM (
+        SELECT DATE_SUB(CURDATE(), INTERVAL nums.n DAY) AS stat_date
+        FROM (
+        SELECT 0 AS n UNION ALL
+        SELECT 1 UNION ALL
+        SELECT 2 UNION ALL
+        SELECT 3 UNION ALL
+        SELECT 4 UNION ALL
+        SELECT 5 UNION ALL
+        SELECT 6
+        ) nums
+        ) d
+        LEFT JOIN (
+        SELECT
+        DATE(create_time) as work_date,
+        product_id,
+        product_code,
+        product_name,
+        product_spc,
+        unit_of_measure,
+        COUNT(*) as workorder_count,
+        SUM(quantity) as total_quantity,
+        SUM(COALESCE(quantity_produced, 0)) as total_produced_quantity,
+        SUM(COALESCE(quantity_scheduled, 0)) as total_scheduled_quantity,
+        SUM(COALESCE(quantity_changed, 0)) as total_changed_quantity,
+        SUM(quantity - COALESCE(quantity_produced, 0)) as total_incomplete_quantity,
+        CASE
+        WHEN SUM(quantity) > 0
+        THEN ROUND(SUM(COALESCE(quantity_produced, 0)) * 100.0 / SUM(quantity), 2)
+        ELSE 0.00
+        END as completion_rate,
+        CASE
+        WHEN SUM(quantity) > 0
+        THEN ROUND(SUM(COALESCE(quantity_scheduled, 0)) * 100.0 / SUM(quantity), 2)
+        ELSE 0.00
+        END as scheduling_rate,
+        MIN(request_date) as earliest_request_date,
+        MAX(request_date) as latest_request_date,
+        GROUP_CONCAT(DISTINCT status) as all_statuses
+        FROM pro_workorder
+        WHERE status IS NOT NULL
+        AND status NOT IN ('PREPARE', 'FINISHED')
+        AND create_time >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
+        <if test="productIds != null and productIds != ''">
+            AND product_id IN
+            <foreach collection="productIds.split(',')" item="productId" open="(" separator="," close=")">
+                #{productId}
+            </foreach>
+        </if>
+        GROUP BY DATE(create_time), product_id, product_code, product_name, product_spc, unit_of_measure
+        ) w ON d.stat_date = w.work_date
+        ORDER BY d.stat_date DESC, w.product_id ASC
+    </select>
+
+    <!-- TODO -->
+    <!-- 统计月预计工单完成总量 -->
+    <select id="countMonthlyWorkorders" resultType="int">
+        SELECT COUNT(*) 
+        FROM pro_workorder 
+        WHERE status IS NOT NULL 
+            AND DATE_FORMAT(create_time, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
+    </select>
+
+    <!-- 获取月交易总额统计 -->
+    <select id="getMonthlyTransactionTotal" resultType="java.util.Map">
+        SELECT 
+            COALESCE(SUM(CASE WHEN wps.status = 'FINISHED' THEN wpsl.price * wpsl.quantity_salse ELSE 0 END), 0) as salesTotal,
+            0 as purchaseTotal
+        FROM wm_product_salse wps
+        LEFT JOIN wm_product_salse_line wpsl ON wps.salse_id = wpsl.salse_id
+        WHERE DATE_FORMAT(wps.salse_date, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
+    </select>
+
+    <!-- 统计月未完成工单数 -->
+    <select id="countMonthlyIncompleteWorkorders" resultType="int">
+        SELECT COUNT(*) 
+        FROM pro_workorder 
+        WHERE status IS NOT NULL 
+            AND status NOT IN ('PREPARE', 'FINISHED')
+            AND DATE_FORMAT(create_time, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
+    </select>
+
+
+    <!-- 获取出货统计 -->
+    <select id="getShipmentStatistics" resultType="java.util.Map">
+        SELECT 
+            COALESCE(SUM(CASE WHEN status = 'FINISHED' THEN 1 ELSE 0 END), 0) as finishedQuantity,
+            COALESCE(COUNT(*), 0) as plannedQuantity
+        FROM wm_product_salse 
+        WHERE DATE_FORMAT(salse_date, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
+    </select>
+
+    <!-- 获取人员周考勤统计 -->
+    <select id="getWeeklyAttendanceStatistics" resultType="java.util.Map">
+        <![CDATA[
+        SELECT 
+            COUNT(DISTINCT user_name) as totalEmployees,
+            COUNT(*) as totalAttendanceDays,
+            CASE 
+                WHEN COUNT(DISTINCT user_name) > 0 
+                THEN ROUND(COUNT(*) / COUNT(DISTINCT user_name), 2)
+                ELSE 0 
+            END as averageAttendanceDays
+        FROM pro_workrecord 
+        WHERE operation_time >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
+            AND operation_time < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL 7 DAY)
+        ]]>
+    </select>
+
+    <!-- 获取设备预处理统计 -->
+    <select id="getEquipmentPreprocessingStatistics" resultType="java.util.Map">
+        SELECT 
+            COUNT(*) as totalEquipment,
+            COUNT(CASE WHEN status = 'NORMAL' THEN 1 END) as normalEquipment,
+            COUNT(CASE WHEN status = 'MAINTENANCE' THEN 1 END) as maintenanceEquipment,
+            COUNT(CASE WHEN status = 'OFFLINE' THEN 1 END) as offlineEquipment,
+            CASE 
+                WHEN COUNT(*) > 0 
+                THEN ROUND((COUNT(CASE WHEN status = 'NORMAL' THEN 1 END) / COUNT(*)) * 100, 2)
+                ELSE 0 
+            END as utilizationRate
+        FROM dv_machinery
+    </select>
+
+    <!-- 获取年度出货统计 -->
+    <select id="getMonthlyShipmentStatistics" resultType="java.util.Map">
+        SELECT 
+            DATE_FORMAT(salse_date, '%Y-%m') as month,
+            COUNT(*) as totalOrders,
+            COUNT(CASE WHEN status = 'FINISHED' THEN 1 END) as finishedOrders,
+            COALESCE(SUM(total_amount), 0) as totalAmount
+        FROM wm_product_salse 
+        WHERE salse_date >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)
+        GROUP BY DATE_FORMAT(salse_date, '%Y-%m')
+        ORDER BY month DESC
+    </select>
+
+    <!-- 获取生产工单统计 -->
+    <select id="selectProductionWorkorderStatistics" resultType="java.util.Map">
+        SELECT 
+            DATE_FORMAT(create_time, '%Y-%m-%d') as statisticsDate,
+            COUNT(*) as totalWorkorders,
+            COUNT(CASE WHEN status = 'FINISHED' THEN 1 END) as finishedWorkorders,
+            COUNT(CASE WHEN status NOT IN ('PREPARE', 'FINISHED') THEN 1 END) as inProgressWorkorders,
+            SUM(quantity) as totalQuantity,
+            SUM(COALESCE(quantity_produced, 0)) as totalProducedQuantity
+        FROM pro_workorder 
+        WHERE status IS NOT NULL 
+            AND status != 'PREPARE'
+            AND create_time >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
+        GROUP BY DATE_FORMAT(create_time, '%Y-%m-%d')
+        ORDER BY statisticsDate DESC
+    </select>
+
+    <!-- 获取当日未完成工单产品统计(相同产品合并) -->
+    <select id="selectDailyIncompleteWorkorderProducts" resultType="java.util.Map">
+        SELECT 
+            product_name as productName,
+            product_id as productId,
+            COUNT(*) as workorderCount,
+            SUM(quantity) as totalQuantity,
+            SUM(COALESCE(quantity_produced, 0)) as totalProducedQuantity,
+            SUM(quantity - COALESCE(quantity_produced, 0)) as totalIncompleteQuantity,
+            CASE 
+                WHEN SUM(quantity) > 0 THEN ROUND((SUM(COALESCE(quantity_produced, 0)) / SUM(quantity)) * 100, 2)
+                ELSE 0 
+            END as completionRate
+        FROM pro_workorder 
+        WHERE status IS NOT NULL 
+            AND status NOT IN ('PREPARE', 'FINISHED')
+            AND DATE_FORMAT(create_time, '%Y-%m-%d') = DATE_FORMAT(CURDATE(), '%Y-%m-%d')
+        GROUP BY product_id, product_name
+        ORDER BY totalIncompleteQuantity DESC
+    </select>
+
+
+
+
+    <!-- 获取一周内工单合格率统计 -->
+    <select id="selectWeeklyQualifiedWorkorderStatistics" resultType="java.util.Map">
+        SELECT
+        item_code AS itemCode,
+        item_name AS itemName,
+        workstation_name AS workName,
+        quantity_check AS checkQty,
+        quantity_unqualified AS fail,
+        quantity_qualified AS pass,
+        inspect_date,
+        CASE
+        WHEN quantity_check > 0
+        THEN ROUND(quantity_qualified * 100.0 / quantity_check, 2)
+        ELSE 0.00
+        END AS qualified_rate
+        FROM qc_ipqc
+        WHERE status = 'FINISHED'
+        AND inspect_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
+        <if test="qualifiedRate != null and qualifiedRate != ''">
+            AND CASE
+            WHEN quantity_check > 0
+            THEN ROUND(quantity_qualified * 100.0 / quantity_check, 2)
+            ELSE 0.00
+            END &lt; #{qualifiedRate}
+        </if>
+        ORDER BY inspect_date DESC,
+        CASE
+        WHEN quantity_check > 0
+        THEN ROUND(quantity_qualified * 100.0 / quantity_check, 2)
+        ELSE 0.00
+        END ASC
+    </select>
+
+    <!-- 获取未排产工单统计 -->
+    <select id="selectUnplannedWorkorderStatistics" resultType="java.util.Map">
+        <![CDATA[
+        SELECT 
+            d.week_start_date,
+            d.week_end_date, 
+            d.week_number,
+            d.year_week,
+            COALESCE(w.total_unplanned_workorders, 0) AS total_unplanned_workorders,
+            COALESCE(w.total_unplanned_quantity, 0) AS total_unplanned_quantity,
+            GROUP_CONCAT(DISTINCT w.status ORDER BY w.status) AS unplanned_statuses
+        FROM (
+            SELECT 
+                0 AS week_offset,
+                DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 DAY) AS week_start_date,
+                DATE_ADD(DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 DAY), INTERVAL 6 DAY) AS week_end_date,
+                WEEK(DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 DAY), 1) AS week_number,
+                DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 DAY), '%Y-%u') AS year_week
+            UNION ALL
+            SELECT 
+                1 AS week_offset,
+                DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 + 7 DAY) AS week_start_date,
+                DATE_ADD(DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 + 7 DAY), INTERVAL 6 DAY) AS week_end_date,
+                WEEK(DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 + 7 DAY), 1) AS week_number,
+                DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 + 7 DAY), '%Y-%u') AS year_week
+            UNION ALL
+            SELECT 
+                2 AS week_offset,
+                DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 + 14 DAY) AS week_start_date,
+                DATE_ADD(DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 + 14 DAY), INTERVAL 6 DAY) AS week_end_date,
+                WEEK(DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 + 14 DAY), 1) AS week_number,
+                DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 + 14 DAY), '%Y-%u') AS year_week
+            UNION ALL
+            SELECT 
+                3 AS week_offset,
+                DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 + 21 DAY) AS week_start_date,
+                DATE_ADD(DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 + 21 DAY), INTERVAL 6 DAY) AS week_end_date,
+                WEEK(DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 + 21 DAY), 1) AS week_number,
+                DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) - 2 + 7) % 7 + 21 DAY), '%Y-%u') AS year_week
+        ) d
+        LEFT JOIN (
+            SELECT 
+                DATE_FORMAT(create_time, '%Y-%u') AS year_week,
+                COUNT(*) AS total_unplanned_workorders,
+                SUM(quantity) AS total_unplanned_quantity,
+                status
+            FROM pro_workorder 
+            WHERE status IS NOT NULL 
+                AND status NOT IN ('PREPARE', 'FINISHED')
+                AND create_time >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
+            GROUP BY DATE_FORMAT(create_time, '%Y-%u'), status
+        ) w ON d.year_week = w.year_week
+        GROUP BY d.week_start_date, d.week_end_date, d.week_number, d.year_week
+        ORDER BY d.week_start_date DESC
+        ]]>
+    </select>
+
+    <select id="selectWmProductSalseLineList" resultType="java.util.Map">
+        select line_id, salse_id, material_stock_id, item_id, item_code, item_name, specification, unit_of_measure, (select measure_name from md_unit_measure where measure_code = unit_of_measure) measure_name
+        , quantity_salse, batch_code, warehouse_id, warehouse_code, warehouse_name, location_id, location_code, location_name, area_id, area_code, area_name, oqc_check,oqc_id,oqc_code
+        , remark, price, cess, attr1, attr2, attr3, attr4, create_by, create_time, update_by, update_time from wm_product_salse_line
+        order by create_time desc
+    </select>
+</mapper>

+ 196 - 0
src/main/resources/mapper/mes/BigViewWmsMapper.xml

@@ -0,0 +1,196 @@
+<?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="cn.com.mes.mapper.BigViewWmsMapper">
+
+    <!-- 获取当日入库数据统计 -->
+    <select id="getDailyInboundData" resultType="java.util.Map">
+        SELECT 
+            COUNT(*) as totalInboundOrders,
+            COALESCE(SUM(quantity_recieved), 0) as totalInboundQuantity,
+            COUNT(CASE WHEN status = 'FINISHED' THEN 1 END) as completedInboundOrders,
+            COUNT(CASE WHEN status != 'FINISHED' THEN 1 END) as pendingInboundOrders,
+            COALESCE(AVG(quantity_recieved), 0) as averageInboundQuantity
+        FROM wm_item_recpt 
+        WHERE DATE_FORMAT(recpt_date, '%Y-%m-%d') = DATE_FORMAT(CURDATE(), '%Y-%m-%d')
+    </select>
+
+    <!-- 获取当日出库数据统计 -->
+    <select id="getDailyOutboundData" resultType="java.util.Map">
+        SELECT 
+            COUNT(*) as totalOutboundOrders,
+            COALESCE(SUM(quantity_issued), 0) as totalOutboundQuantity,
+            COUNT(CASE WHEN status = 'FINISHED' THEN 1 END) as completedOutboundOrders,
+            COUNT(CASE WHEN status != 'FINISHED' THEN 1 END) as pendingOutboundOrders,
+            COALESCE(AVG(quantity_issued), 0) as averageOutboundQuantity
+        FROM wm_item_issue 
+        WHERE DATE_FORMAT(issue_date, '%Y-%m-%d') = DATE_FORMAT(CURDATE(), '%Y-%m-%d')
+    </select>
+
+    <!-- 获取本周物料单统计(每日) -->
+    <select id="getWeeklyMaterialOrderStatistics" resultType="java.util.Map">
+        <![CDATA[
+        SELECT 
+            DATE_FORMAT(create_time, '%Y-%m-%d') as statisticsDate,
+            COUNT(*) as totalMaterialOrders,
+            COUNT(CASE WHEN status = 'FINISHED' THEN 1 END) as completedOrders,
+            COUNT(CASE WHEN status = 'PREPARE' THEN 1 END) as prepareOrders,
+            COUNT(CASE WHEN status = 'CONFIRMED' THEN 1 END) as confirmedOrders,
+            COALESCE(SUM(quantity), 0) as totalQuantity
+        FROM (
+            SELECT create_time, status, quantity FROM wm_item_recpt 
+            WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
+                AND create_time < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL 7 DAY)
+            UNION ALL
+            SELECT create_time, status, quantity_issued as quantity FROM wm_item_issue 
+            WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
+                AND create_time < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL 7 DAY)
+        ) material_orders
+        GROUP BY DATE_FORMAT(create_time, '%Y-%m-%d')
+        ORDER BY statisticsDate
+        ]]>
+    </select>
+
+    <!-- 获取本周吞吐量统计(每日) -->
+    <select id="getWeeklyThroughputStatistics" resultType="java.util.Map">
+        <![CDATA[
+        SELECT 
+            DATE_FORMAT(operation_date, '%Y-%m-%d') as statisticsDate,
+            COALESCE(SUM(inbound_quantity), 0) as dailyInboundQuantity,
+            COALESCE(SUM(outbound_quantity), 0) as dailyOutboundQuantity,
+            COALESCE(SUM(inbound_quantity) + SUM(outbound_quantity), 0) as dailyTotalThroughput
+        FROM (
+            SELECT 
+                recpt_date as operation_date,
+                quantity_recieved as inbound_quantity,
+                0 as outbound_quantity
+            FROM wm_item_recpt 
+            WHERE recpt_date >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
+                AND recpt_date < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL 7 DAY)
+                AND status = 'FINISHED'
+            UNION ALL
+            SELECT 
+                issue_date as operation_date,
+                0 as inbound_quantity,
+                quantity_issued as outbound_quantity
+            FROM wm_item_issue 
+            WHERE issue_date >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY)
+                AND issue_date < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL 7 DAY)
+                AND status = 'FINISHED'
+        ) throughput_data
+        GROUP BY DATE_FORMAT(operation_date, '%Y-%m-%d')
+        ORDER BY statisticsDate
+        ]]>
+    </select>
+
+    <!-- 获取剩余库位统计 -->
+    <select id="getRemainingStorageLocations" resultType="java.util.Map">
+        SELECT 
+            COUNT(*) as totalStorageLocations,
+            COUNT(CASE WHEN status = 'FREE' THEN 1 END) as freeStorageLocations,
+            COUNT(CASE WHEN status = 'OCCUPIED' THEN 1 END) as occupiedStorageLocations,
+            COUNT(CASE WHEN status = 'LOCKED' THEN 1 END) as lockedStorageLocations,
+            CASE 
+                WHEN COUNT(*) > 0 
+                THEN ROUND((COUNT(CASE WHEN status = 'FREE' THEN 1 END) / COUNT(*)) * 100, 2)
+                ELSE 0 
+            END as freeLocationRate,
+            CASE 
+                WHEN COUNT(*) > 0 
+                THEN ROUND((COUNT(CASE WHEN status = 'OCCUPIED' THEN 1 END) / COUNT(*)) * 100, 2)
+                ELSE 0 
+            END as occupiedLocationRate
+        FROM wm_storage_location
+    </select>
+
+    <!-- 获取剩余料箱统计(智能仓) -->
+    <select id="getRemainingSmartBins" resultType="java.util.Map">
+        SELECT 
+            COUNT(*) as totalSmartBins,
+            COUNT(CASE WHEN status = 'FREE' THEN 1 END) as freeSmartBins,
+            COUNT(CASE WHEN status = 'OCCUPIED' THEN 1 END) as occupiedSmartBins,
+            COUNT(CASE WHEN status = 'MAINTENANCE' THEN 1 END) as maintenanceSmartBins,
+            CASE 
+                WHEN COUNT(*) > 0 
+                THEN ROUND((COUNT(CASE WHEN status = 'FREE' THEN 1 END) / COUNT(*)) * 100, 2)
+                ELSE 0 
+            END as freeBinRate,
+            CASE 
+                WHEN COUNT(*) > 0 
+                THEN ROUND((COUNT(CASE WHEN status = 'OCCUPIED' THEN 1 END) / COUNT(*)) * 100, 2)
+                ELSE 0 
+            END as occupiedBinRate
+        FROM wm_storage_location 
+        WHERE location_type = 'SMART_BIN'
+    </select>
+
+    <!-- 获取库位统计(按仓库统计) -->
+    <select id="getStorageLocationStatistics" resultType="java.util.Map">
+        SELECT 
+            warehouse_name,
+            warehouse_id,
+            COUNT(*) as totalLocations,
+            COUNT(CASE WHEN status = 'FREE' THEN 1 END) as freeLocations,
+            COUNT(CASE WHEN status = 'OCCUPIED' THEN 1 END) as occupiedLocations,
+            COUNT(CASE WHEN status = 'LOCKED' THEN 1 END) as lockedLocations,
+            CASE 
+                WHEN COUNT(*) > 0 
+                THEN ROUND((COUNT(CASE WHEN status = 'FREE' THEN 1 END) / COUNT(*)) * 100, 2)
+                ELSE 0 
+            END as utilizationRate
+        FROM wm_storage_location wsl
+        LEFT JOIN wm_warehouse ww ON wsl.warehouse_id = ww.warehouse_id
+        GROUP BY warehouse_id, warehouse_name
+        ORDER BY warehouse_name
+    </select>
+
+    <!-- 获取仓库事件列表(滚动展示) -->
+    <select id="getWarehouseEvents" resultType="java.util.Map">
+        SELECT 
+            event_type,
+            product_name,
+            workorder_code,
+            equipment_name,
+            location_code,
+            operation_user,
+            operation_time,
+            remark
+        FROM (
+            -- 入库事件
+            SELECT 
+                'INBOUND' as event_type,
+                wi.item_name as product_name,
+                wir.workorder_code,
+                '' as equipment_name,
+                wsl.location_code,
+                wir.create_by as operation_user,
+                wir.create_time as operation_time,
+                CONCAT('入库数量:', wir.quantity_recieved) as remark
+            FROM wm_item_recpt wir
+            LEFT JOIN wm_item wi ON wir.item_id = wi.item_id
+            LEFT JOIN wm_storage_location wsl ON wir.location_id = wsl.location_id
+            WHERE wir.create_time >= DATE_SUB(NOW(), INTERVAL 2 HOUR)
+            
+            UNION ALL
+            
+            -- 出库事件
+            SELECT 
+                'OUTBOUND' as event_type,
+                wi.item_name as product_name,
+                wii.workorder_code,
+                '' as equipment_name,
+                wsl.location_code,
+                wii.create_by as operation_user,
+                wii.create_time as operation_time,
+                CONCAT('出库数量:', wii.quantity_issued) as remark
+            FROM wm_item_issue wii
+            LEFT JOIN wm_item wi ON wii.item_id = wi.item_id
+            LEFT JOIN wm_storage_location wsl ON wii.location_id = wsl.location_id
+            WHERE wii.create_time >= DATE_SUB(NOW(), INTERVAL 2 HOUR)
+        ) warehouse_events
+        ORDER BY operation_time DESC
+        LIMIT 50
+    </select>
+
+</mapper>