1
heshaofeng
2026-01-20 5dfd83bd540c2e43af2e0449c246c79a22cb1296
1
已修改5个文件
1012 ■■■■■ 文件已修改
项目代码/Dashboard/src/views/Dashboard.vue 836 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/Home.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/basic/Dt_MesReturnRecord.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/MESOperation/FeedbackMesService.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_StockService/StockDetailByMaterielService.cs 123 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ÏîÄ¿´úÂë/Dashboard/src/views/Dashboard.vue
@@ -36,11 +36,13 @@
              <Box v-if="index === 0" />
              <Download v-else-if="index === 1" />
              <Upload v-else-if="index === 2" />
              <List v-else />
              <List v-else-if="index === 3" />
              <Box v-else-if="index === 4" />
              <Box v-else />
            </el-icon>
          </div>
          <div class="metric-content">
            <div class="metric-value">{{ item.value }}</div>
            <div class="metric-value">{{ formatNumber(item.value) }}</div>
            <div class="metric-label">{{ item.label }}</div>
            <div class="metric-trend" :class="item.trend > 0 ? 'up' : 'down'">
              <el-icon>
@@ -71,12 +73,32 @@
          <div ref="categoryChartRef" class="chart-container"></div>
        </div>
        <!-- ä½œä¸šæ•ˆçއ -->
        <!-- ç‰©æ–™ä¸´æœŸæ•°æ® -->
        <div class="chart-card">
          <div class="card-title">
            <span>作业效率统计</span>
            <span>物料临期数据</span>
            <span class="task-count">共 {{ nearExpirationList.length }} æ¡è®°å½•</span>
          </div>
          <div ref="efficiencyChartRef" class="chart-container"></div>
          <el-table
            :data="showNearExpirationList"
            style="width: 100%"
            :height="250"
            :empty-text="nearExpirationList.length === 0 ? '暂无临期数据' : ''"
          >
            <el-table-column prop="materielCode" label="物料编码" min-width="120" />
            <el-table-column prop="batchNo" label="批次号" min-width="100" />
            <el-table-column prop="palletCode" label="托盘编号" min-width="100" />
            <el-table-column prop="locationCode" label="库位" min-width="100" />
            <el-table-column prop="stockQuantity" label="库存数量" width="100" />
            <el-table-column prop="daysToExpiration" label="临期天数" width="100">
              <template #default="{ row }">
                <div :class="getExpirationClass(row.daysToExpiration)">
                  {{ row.daysToExpiration }}天
                </div>
              </template>
            </el-table-column>
            <el-table-column prop="validDate" label="有效期至" width="160" />
          </el-table>
        </div>
      </div>
@@ -85,10 +107,16 @@
        <div class="table-card">
          <div class="card-title">
            <span>实时作业任务</span>
            <span class="task-count">共 {{ taskList.length }} æ¡ä»»åŠ¡</span>
          </div>
          <el-table :data="showTaskList" style="width: 100%" :height="tableHeight">
            <el-table-column prop="taskNum" label="任务号" />
            <el-table-column prop="taskStatus" label="任务状态" width="120">
          <el-table
            :data="showTaskList"
            style="width: 100%"
            :height="tableHeight"
            :empty-text="taskList.length === 0 ? '暂无作业任务数据' : ''"
          >
            <el-table-column prop="taskNum" label="任务号" min-width="120" />
            <el-table-column prop="taskStatus" label="任务状态" width="140">
              <template #default="{ row }">
                <div class="status-container" :class="getStatusClass(row.taskStatus)">
                  <div class="status-dot"></div>
@@ -96,7 +124,7 @@
                </div>
              </template>
            </el-table-column>
            <el-table-column prop="taskType" label="任务类型" width="100">
            <el-table-column prop="taskType" label="任务类型" width="120">
              <template #default="{ row }">
                <div class="type-container" :class="getTypeClass(row.taskType)">
                  <el-icon class="type-icon">
@@ -109,10 +137,10 @@
                </div>
              </template>
            </el-table-column>
            <el-table-column prop="palletCode" label="托盘编号" />
            <el-table-column prop="sourceAddress" label="起点位置"/>
            <el-table-column prop="targetAddress" label="终点位置"/>
            <el-table-column prop="createDate" label="创建时间"/>
            <el-table-column prop="palletCode" label="托盘编号" min-width="100" />
            <el-table-column prop="sourceAddress" label="起点位置" min-width="100"/>
            <el-table-column prop="targetAddress" label="终点位置" min-width="100"/>
            <el-table-column prop="createDate" label="创建时间" width="180"/>
          </el-table>
        </div>
      </div>
@@ -121,7 +149,7 @@
</template>
<script>
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue'
import * as echarts from 'echarts'
import { http } from '@/utils/http'
import { formatDateTime } from '@/utils'
@@ -190,35 +218,49 @@
      110: "提升机执行中"
    }
    // å…³é”®æŒ‡æ ‡ï¼ˆå“åº”式)
    // å…³é”®æŒ‡æ ‡ï¼ˆå“åº”式)- ä¿®æ­£æ˜ å°„关系
    const metrics = ref([
      { 
        label: '总库存量',
        label: '待入库订单',
        value: 0, 
        icon: 'Box', 
        color: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', 
        trend: 8.5 
      },
      { 
        label: '今日入库',
        label: '待出库订单',
        value: 0, 
        icon: 'Download', 
        color: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)', 
        trend: 12.3 
      },
      { 
        label: '今日出库',
        label: '今日入库完成数',
        value: 0, 
        icon: 'Upload', 
        color: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)', 
        trend: -3.2 
      },
      { 
        label: '待处理任务',
        label: '今日出库完成数',
        value: 0, 
        icon: 'List', 
        color: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)', 
        trend: 5.7 
      },
      {
        label: '有货料箱',
        value: 0,
        icon: 'List',
        color: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)',
        trend: 2.1
      },
      {
        label: '空箱数量',
        value: 0,
        icon: 'List',
        color: 'linear-gradient(135deg, #8176af 0%, #c0b7e8 100%)',
        trend: -1.8
      }
    ])
@@ -228,6 +270,12 @@
    const currentTaskIndex = ref(7) // åˆå§‹ä»Žç¬¬8条开始(前7条默认显示)
    let taskCarouselTimer = null
    // ä¸´æœŸç‰©æ–™åˆ—表相关
    const nearExpirationList = ref([])
    const showNearExpirationList = ref([])
    const currentExpirationIndex = ref(7) // åˆå§‹ä»Žç¬¬8条开始(前7条默认显示)
    let expirationCarouselTimer = null
    // è‡ªåŠ¨åˆ·æ–°ç›¸å…³é…ç½®
    const lastInboundToday = ref(0)  // ä¸Šä¸€æ¬¡å½“天入库量
    const lastOutboundToday = ref(0) // ä¸Šä¸€æ¬¡å½“天出库量
@@ -236,24 +284,38 @@
    let lastRefreshTime = ref(0) // ä¸Šä¸€æ¬¡åˆ·æ–°æ—¶é—´
    let autoRefreshTimer = null // è‡ªåŠ¨åˆ·æ–°å®šæ—¶å™¨
    // æ•°å­—格式化
    const formatNumber = (num) => {
      if (num === undefined || num === null || isNaN(num)) return '0';
      return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    }
    // èŽ·å–ä»»åŠ¡çŠ¶æ€æ–‡æœ¬
    const getTaskStatusText = (statusNum) => {
      if (statusNum === undefined || statusNum === null || isNaN(statusNum)) {
        return "未知状态";
      }
      return taskStatusMap[statusNum] || "未知状态";
      return taskStatusMap[statusNum] || `未知状态(${statusNum})`;
    }
    // å¯åŠ¨ä»»åŠ¡è½®æ’­
    const startTaskCarousel = () => {
      // æ¸…除旧定时器
      if (taskCarouselTimer) clearInterval(taskCarouselTimer);
      const totalTask = bigscreendata.value.taskList.length;
      if (totalTask <= 7) { // ä»»åŠ¡æ•°<=7时不轮播
        showTaskList.value = [...bigscreendata.value.taskList];
      const totalTask = taskList.value.length;
      // ä»»åŠ¡æ•°<=7时不轮播
      if (totalTask <= 7) {
        showTaskList.value = [...taskList.value];
        return;
      }
      // é‡ç½®ç´¢å¼•
      currentTaskIndex.value = 7;
      // åˆå§‹æ˜¾ç¤ºå‰7条
      showTaskList.value = taskList.value.slice(0, 7);
      // å¯åŠ¨è½®æ’­
      taskCarouselTimer = setInterval(() => {
        const tableElement = document.querySelector('.el-table');
        if (tableElement) {
@@ -264,7 +326,7 @@
        }
        
        // æ–°å¢žä¸‹1条,删除最前1条(保持7条显示)
        showTaskList.value.push(bigscreendata.value.taskList[currentTaskIndex.value]);
        showTaskList.value.push(taskList.value[currentTaskIndex.value]);
        showTaskList.value.shift();
        
        // å¾ªçŽ¯ç´¢å¼•
@@ -273,6 +335,62 @@
          currentTaskIndex.value = 0;
        }
      }, 5000); // 5秒轮播一次
    }
    // åœæ­¢ä»»åŠ¡è½®æ’­
    const stopTaskCarousel = () => {
      if (taskCarouselTimer) {
        clearInterval(taskCarouselTimer);
        taskCarouselTimer = null;
      }
    }
    // å¯åŠ¨ä¸´æœŸç‰©æ–™è½®æ’­
    const startExpirationCarousel = () => {
      // æ¸…除旧定时器
      if (expirationCarouselTimer) clearInterval(expirationCarouselTimer);
      const totalExpiration = nearExpirationList.value.length;
      // è®°å½•æ•°<=7时不轮播
      if (totalExpiration <= 7) {
        showNearExpirationList.value = [...nearExpirationList.value];
        return;
      }
      // é‡ç½®ç´¢å¼•
      currentExpirationIndex.value = 7;
      // åˆå§‹æ˜¾ç¤ºå‰7条
      showNearExpirationList.value = nearExpirationList.value.slice(0, 7);
      // å¯åŠ¨è½®æ’­
      expirationCarouselTimer = setInterval(() => {
        // æ–°å¢žä¸‹1条,删除最前1条(保持7条显示)
        showNearExpirationList.value.push(nearExpirationList.value[currentExpirationIndex.value]);
        showNearExpirationList.value.shift();
        // å¾ªçŽ¯ç´¢å¼•
        currentExpirationIndex.value++;
        if (currentExpirationIndex.value >= totalExpiration) {
          currentExpirationIndex.value = 0;
        }
      }, 5000); // 5秒轮播一次
    }
    // åœæ­¢ä¸´æœŸç‰©æ–™è½®æ’­
    const stopExpirationCarousel = () => {
      if (expirationCarouselTimer) {
        clearInterval(expirationCarouselTimer);
        expirationCarouselTimer = null;
      }
    }
    // èŽ·å–ä¸´æœŸå¤©æ•°æ ·å¼ç±»
    const getExpirationClass = (days) => {
      if (days === undefined || days === null || isNaN(days)) return "exp-unknown";
      if (days <= 0) return "exp-expired"; // å·²è¿‡æœŸ
      if (days <= 7) return "exp-critical"; // 7天内临期
      if (days <= 30) return "exp-warning"; // 30天内临期
      return "exp-normal"; // æ­£å¸¸
    }
    // èŽ·å–ä»»åŠ¡ç±»åž‹æ–‡æœ¬
@@ -291,14 +409,12 @@
        return "status-unknown";
      }
      
      if (statusNum >= 900) return "status-completed"; // å®Œæˆ
      if (statusNum >= 400) return "status-processing"; // è¾“送线执行中
      if (statusNum >= 300) return "status-processing"; // AGV执行中
      if (statusNum >= 200) return "status-processing"; // å †åž›æœºæ‰§è¡Œä¸­
      if (statusNum >= 100) return "status-pending"; // æ–°å»ºã€å·²å‘送
      if (statusNum === 900) return "status-completed"; // å®Œæˆ
      if (statusNum === 970) return "status-suspended"; // æŒ‚èµ·
      if (statusNum === 980) return "status-canceled"; // å–消
      if (statusNum === 990) return "status-error"; // å¼‚常
      if (statusNum >= 200 && statusNum < 900) return "status-processing"; // æ‰§è¡Œä¸­
      if (statusNum >= 100 && statusNum < 200) return "status-pending"; // æ–°å»ºã€å·²å‘送
      
      return "status-unknown";
    }
@@ -316,35 +432,50 @@
    // ä»ŽåŽç«¯èŽ·å–æ•°æ®
    const fetchBigGreenData = async () => {
  try {
    const res = await http.get('/api/BigScreen/GetBigGreenData');
    console.log('大屏数据', res);
    bigscreendata.value = res.data || res;
      try {
        // é˜²æŠ–处理:避免短时间内多次请求
        const now = Date.now();
        if (now - lastRefreshTime.value < minRefreshGap.value) {
          return;
        }
        lastRefreshTime.value = now;
    updateMetrics();
        const res = await http.get('/api/BigScreen/GetBigGreenData');
        console.log('大屏数据', res);
        bigscreendata.value = res.data || res;
    taskList.value = bigscreendata.value.taskList || [];
    showTaskList.value = taskList.value.slice(0, 7);
    startTaskCarousel();
        updateMetrics();
    // æ•°æ®åŠ è½½å®ŒæˆåŽåˆå§‹åŒ–å›¾è¡¨
    nextTick(() => {
      initEfficiencyChart();
      initTrendChart();
      initCategoryChart();
    });
  } catch (error) {
    console.error('获取大屏数据失败:', error);
    ElMessage.error('获取数据失败,请稍后重试');
  }
};
        // æ›´æ–°ä»»åŠ¡åˆ—è¡¨
        taskList.value = Array.isArray(bigscreendata.value.taskList) ? bigscreendata.value.taskList : [];
        // é‡å¯è½®æ’­
        stopTaskCarousel();
        startTaskCarousel();
    // æ›´æ–°å…³é”®æŒ‡æ ‡
        // æ›´æ–°ä¸´æœŸç‰©æ–™åˆ—表
        nearExpirationList.value = Array.isArray(bigscreendata.value.nearExpirationList) ? bigscreendata.value.nearExpirationList : [];
        // é‡å¯ä¸´æœŸç‰©æ–™è½®æ’­
        stopExpirationCarousel();
        startExpirationCarousel();
        // æ•°æ®åŠ è½½å®ŒæˆåŽåˆ·æ–°å›¾è¡¨
        nextTick(() => {
          refreshCharts(true);
        });
      } catch (error) {
        console.error('获取大屏数据失败:', error);
        ElMessage.error('获取数据失败,请稍后重试');
      }
    };
    // æ›´æ–°å…³é”®æŒ‡æ ‡ - ä¿®æ­£æ•°æ®æ˜ å°„
    const updateMetrics = () => {
      metrics.value[0].value = bigscreendata.value.totalStockQuantity || 0
      metrics.value[1].value = bigscreendata.value.inboundCount || 0
      metrics.value[2].value = bigscreendata.value.outboundCount || 0
      metrics.value[3].value = bigscreendata.value.unOutBoundOrderCount || 0
      metrics.value[0].value = bigscreendata.value.unInBoundOrderCount || 0; // å¾…入库订单
      metrics.value[1].value = bigscreendata.value.unOutBoundOrderCount || 0; // å¾…出库订单
      metrics.value[2].value = bigscreendata.value.inboundCount || 0; // ä»Šæ—¥å…¥åº“完成数
      metrics.value[3].value = bigscreendata.value.outboundCount || 0; // ä»Šæ—¥å‡ºåº“完成数
      metrics.value[4].value = bigscreendata.value.inStockPallet || 0; // æœ‰è´§æ–™ç®±
      metrics.value[5].value = bigscreendata.value.freeStockPallet || 0; // ç©ºç®±æ•°é‡
    }
    // æ›´æ–°æ—¶é—´
@@ -353,32 +484,42 @@
      currentTime.value = formatDateTime(new Date())
    }
    // åˆå§‹åŒ–趋势图(直接使用后端日期)
    // åˆå§‹åŒ–趋势图
    const initTrendChart = () => {
      if (!trendChartRef.value) return
      if (!trendChartRef.value) return;
      trendChart.value = echarts.init(trendChartRef.value)
      // ç›´æŽ¥ä»ŽåŽç«¯èŽ·å–æ—¥æœŸå’Œæ•°æ®
      const dates = []
      const inboundData = []
      const outboundData = []
      if (bigscreendata.value.dailyInOutBoundList && bigscreendata.value.dailyInOutBoundList.length > 0) {
        bigscreendata.value.dailyInOutBoundList.forEach(item => {
          dates.push(item.date) // ç›´æŽ¥ä½¿ç”¨åŽç«¯è¿”回的日期
          inboundData.push(item.dailyInboundQuantity || 0)
          outboundData.push(item.dailyOutboundQuantity || 0)
        })
      // é”€æ¯æ—§å®žä¾‹
      if (trendChart.value) {
        trendChart.value.dispose();
      }
      const hasData = dates.length > 0
      trendChart.value = echarts.init(trendChartRef.value);
      // ç›´æŽ¥ä»ŽåŽç«¯èŽ·å–æ—¥æœŸå’Œæ•°æ®
      const dates = [];
      const inboundData = [];
      const outboundData = [];
      if (Array.isArray(bigscreendata.value.dailyInOutBoundList) && bigscreendata.value.dailyInOutBoundList.length > 0) {
        bigscreendata.value.dailyInOutBoundList.forEach(item => {
          dates.push(item.date || ''); // ç›´æŽ¥ä½¿ç”¨åŽç«¯è¿”回的日期
          inboundData.push(item.dailyInboundQuantity || 0);
          outboundData.push(item.dailyOutboundQuantity || 0);
        });
      }
      const hasData = dates.length > 0;
      const option = {
        backgroundColor: 'transparent',
        tooltip: {
          trigger: 'axis',
          textStyle: { color: '#fff', fontSize: 12 },
          backgroundColor: 'rgba(0,0,0,0.7)'
        },
        legend: {
          data: ['入库量', '出库量'],
          textStyle: { color: '#fff' }
          textStyle: { color: '#e0e0e0', fontSize: 12 }
        },
        grid: {
          left: '3%',
@@ -390,15 +531,15 @@
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: dates,
          axisLine: { lineStyle: { color: '#fff' } },
          axisLabel: { color: '#fff' }
          data: hasData ? dates : ['暂无数据'],
          axisLine: { lineStyle: { color: '#666' } },
          axisLabel: { color: '#e0e0e0', fontSize: 11 }
        },
        yAxis: {
          type: 'value',
          axisLine: { lineStyle: { color: '#fff' } },
          axisLine: { lineStyle: { color: '#666' } },
          splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } },
          axisLabel: { color: '#fff' },
          axisLabel: { color: '#e0e0e0', fontSize: 11 },
          min: 0
        },
        series: [
@@ -406,7 +547,7 @@
            name: '入库量',
            type: 'line',
            smooth: true,
            data: inboundData,
            data: hasData ? inboundData : [0],
            itemStyle: { color: '#5470c6' },
            lineStyle: { color: '#5470c6' },
            areaStyle: {
@@ -423,7 +564,7 @@
            name: '出库量',
            type: 'line',
            smooth: true,
            data: outboundData,
            data: hasData ? outboundData : [0],
            itemStyle: { color: '#91cc75' },
            lineStyle: { color: '#91cc75' },
            areaStyle: {
@@ -436,27 +577,46 @@
            symbol: 'circle',
            symbolSize: 6
          }
        ],
      }
        ]
      };
      trendChart.value.setOption(option)
      return trendChart.value
      trendChart.value.setOption(option);
      return trendChart.value;
    }
    // åˆå§‹åŒ–分类占比图
    const initCategoryChart = () => {
      if (!categoryChartRef.value) return
      if (!categoryChartRef.value) return;
      
      categoryChart.value = echarts.init(categoryChartRef.value)
      // é”€æ¯æ—§å®žä¾‹
      if (categoryChart.value) {
        categoryChart.value.dispose();
      }
      categoryChart.value = echarts.init(categoryChartRef.value);
      const chartData = Array.isArray(bigscreendata.value.inventoryLocationDist) && bigscreendata.value.inventoryLocationDist.length > 0
        ? bigscreendata.value.inventoryLocationDist
        : [
            { value: 3580, name: '原材料', itemStyle: { color: '#5470c6' } },
            { value: 2840, name: '半成品', itemStyle: { color: '#91cc75' } },
            { value: 4120, name: '成品', itemStyle: { color: '#fac858' } },
            { value: 2040, name: '辅料', itemStyle: { color: '#ee6666' } }
          ];
      
      const option = {
        tooltip: { trigger: 'item' },
        backgroundColor: 'transparent',
        tooltip: {
          trigger: 'item',
          textStyle: { color: '#fff', fontSize: 12 },
          backgroundColor: 'rgba(0,0,0,0.7)',
          formatter: '{b}: {c} ({d}%)'
        },
        legend: {
          orient: 'vertical',
          right: '10%',
          top: 'center',
          textStyle: { color: '#fff' }
          textStyle: { color: '#e0e0e0', fontSize: 12 }
        },
        series: [
          {
@@ -472,230 +632,241 @@
            },
            label: { show: false },
            emphasis: {
              label: { show: true, fontSize: 16, fontWeight: 'bold' }
              label: { show: true, fontSize: 14, fontWeight: 'bold', color: '#fff' }
            },
            data: bigscreendata.value.inventoryLocationDist.length > 0
              ? bigscreendata.value.inventoryLocationDist
              : [
                  { value: 3580, name: '原材料', itemStyle: { color: '#5470c6' } },
                  { value: 2840, name: '半成品', itemStyle: { color: '#91cc75' } },
                  { value: 4120, name: '成品', itemStyle: { color: '#fac858' } },
                  { value: 2040, name: '辅料', itemStyle: { color: '#ee6666' } }
                ]
            data: chartData
          }
        ]
      }
      };
      
      categoryChart.value.setOption(option)
      return categoryChart.value
      categoryChart.value.setOption(option);
      return categoryChart.value;
    }
    // åˆå§‹åŒ–效率统计图
    // åˆå§‹åŒ–效率统计图
// åˆå§‹åŒ–效率统计图(修复版)
const initEfficiencyChart = () => {
  if (!efficiencyChartRef.value) {
    console.warn('效率图表容器不存在!');
    return;
  }
  // ç¡®ä¿å®¹å™¨æœ‰é«˜åº¦
  efficiencyChartRef.value.style.height = '250px';
  efficiencyChartRef.value.style.width = '100%';
  // é”€æ¯æ—§å®žä¾‹
  if (efficiencyChart.value) {
    efficiencyChart.value.dispose();
  }
  // åˆå§‹åŒ– ECharts
  efficiencyChart.value = echarts.init(efficiencyChartRef.value);
  // æ•°æ®å¤„理
  const taskData = {
    '入库': 0,
    '出库': 0
  };
  bigscreendata.value.completeTask.forEach(item => {
    if (item.taskType && typeof item.count === 'number') {
      taskData[item.taskType] = item.count;
    }
  });
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: params => {
        return params.map(p => `${p.seriesName}: ${p.value || 0} å•`).join('<br/>');
    const initEfficiencyChart = () => {
      if (!efficiencyChartRef.value) {
        console.warn('效率图表容器不存在!');
        return;
      }
    },
    grid: {
      left: '5%',
      right: '5%',
      bottom: '10%',
      top: '15%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: ['入库作业', '出库作业'],
      axisLine: { lineStyle: { color: '#fff' } },
      axisLabel: { color: '#fff' }
    },
    yAxis: {
      type: 'value',
      name: '完成数量(单)',
      nameTextStyle: { color: '#fff' },
      axisLine: { lineStyle: { color: '#fff' } },
      splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } },
      axisLabel: { color: '#fff' },
      min: 0
    },
    series: [
      {
        name: '作业数量',
        data: [taskData['入库'], taskData['出库']],
        type: 'bar',
        barWidth: '40%',
        itemStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: '#83bff6' },
            { offset: 1, color: '#188df0' }
          ]),
          borderRadius: [5, 5, 0, 0]
      // ç¡®ä¿å®¹å™¨æœ‰é«˜åº¦
      efficiencyChartRef.value.style.height = '250px';
      efficiencyChartRef.value.style.width = '100%';
      // é”€æ¯æ—§å®žä¾‹
      if (efficiencyChart.value) {
        efficiencyChart.value.dispose();
      }
      // åˆå§‹åŒ– ECharts
      efficiencyChart.value = echarts.init(efficiencyChartRef.value);
      // æ•°æ®å¤„理
      const taskData = {
        '入库': 0,
        '出库': 0
      };
      if (Array.isArray(bigscreendata.value.completeTask)) {
        bigscreendata.value.completeTask.forEach(item => {
          if (item.taskType && typeof item.count === 'number') {
            taskData[item.taskType] = item.count;
          }
        });
      }
      const hasData = taskData.入库 > 0 || taskData.出库 > 0;
      const option = {
        backgroundColor: 'transparent',
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'shadow' },
          textStyle: { color: '#fff', fontSize: 12 },
          backgroundColor: 'rgba(0,0,0,0.7)',
          formatter: params => {
            return params.map(p => `${p.seriesName}: ${p.value || 0} å•`).join('<br/>');
          }
        },
        label: {
          show: true,
          position: 'top',
          color: '#fff',
          fontSize: 12
        }
      }
    ]
  };
        grid: {
          left: '5%',
          right: '5%',
          bottom: '10%',
          top: '15%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: hasData ? ['入库作业', '出库作业'] : ['暂无数据'],
          axisLine: { lineStyle: { color: '#666' } },
          axisLabel: { color: '#e0e0e0', fontSize: 11 }
        },
        yAxis: {
          type: 'value',
          name: '完成数量(单)',
          nameTextStyle: { color: '#e0e0e0', fontSize: 12 },
          axisLine: { lineStyle: { color: '#666' } },
          splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } },
          axisLabel: { color: '#e0e0e0', fontSize: 11 },
          min: 0
        },
        series: [
          {
            name: '作业数量',
            data: hasData ? [taskData['入库'], taskData['出库']] : [0],
            type: 'bar',
            barWidth: '40%',
            itemStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: '#83bff6' },
                { offset: 1, color: '#188df0' }
              ]),
              borderRadius: [5, 5, 0, 0]
            },
            label: {
              show: hasData,
              position: 'top',
              color: '#ffffff',
              fontSize: 12,
              fontWeight: 600
            }
          }
        ]
      };
  efficiencyChart.value.setOption(option, true);
  console.log('效率图表渲染完成,数据:', taskData);
};
      efficiencyChart.value.setOption(option, true);
      console.log('效率图表渲染完成,数据:', taskData);
    };
    // åˆ·æ–°å›¾è¡¨æ•°æ®ï¼ˆisDataChange:是否是数据变化导致的刷新)
    // åˆ·æ–°å›¾è¡¨æ•°æ®
    const refreshCharts = (isDataChange = false) => {
      // æ•°æ®å˜åŒ–时添加闪烁效果
      if (isDataChange) {
        const chartElements = [trendChartRef.value, categoryChartRef.value, efficiencyChartRef.value]
        const chartElements = [trendChartRef.value, categoryChartRef.value, efficiencyChartRef.value];
        chartElements.forEach(el => {
          if (el) {
            el.classList.add('flash-effect');
            setTimeout(() => el.classList.remove('flash-effect'), 600);
          }
        })
        });
      }
      // é”€æ¯æ—§å›¾è¡¨å®žä¾‹
      if (trendChart.value) trendChart.value.dispose()
      if (categoryChart.value) categoryChart.value.dispose()
      if (efficiencyChart.value) efficiencyChart.value.dispose()
      // é‡æ–°åˆå§‹åŒ–图表
      initTrendChart()
      initCategoryChart()
      initEfficiencyChart()
      initTrendChart();
      initCategoryChart();
      initEfficiencyChart();
    }
    // æ‰‹åŠ¨åˆ·æ–°æ•°æ®
    const refreshData = () => {
      fetchBigGreenData()
      fetchBigGreenData();
    }
    // å¯åŠ¨è‡ªåŠ¨åˆ·æ–°
    const startAutoRefresh = () => {
      if (autoRefreshTimer) clearInterval(autoRefreshTimer)
      if (autoRefreshTimer) clearInterval(autoRefreshTimer);
      autoRefreshTimer = setInterval(() => {
        console.log('定时刷新数据:', new Date().toLocaleString())
        fetchBigGreenData()
      }, refreshInterval.value)
        console.log('定时刷新数据:', new Date().toLocaleString());
        fetchBigGreenData();
      }, refreshInterval.value);
    }
    // åœæ­¢è‡ªåŠ¨åˆ·æ–°
    const stopAutoRefresh = () => {
      if (autoRefreshTimer) {
        clearInterval(autoRefreshTimer);
        autoRefreshTimer = null;
      }
    }
    // çª—口大小改变时重绘图表和调整表格高度
    const handleResize = () => {
      try {
        const windowHeight = window.innerHeight
        const headerHeight = 60
        const navHeight = 50
        const metricsHeight = 120
        const chartsHeight = 300
        const padding = 80
        const windowHeight = window.innerHeight;
        const headerHeight = 60;
        const navHeight = 50;
        const metricsHeight = 120;
        const chartsHeight = 300;
        const padding = 80;
        
        const availableHeight = windowHeight - headerHeight - navHeight - metricsHeight - chartsHeight - padding
        tableHeight.value = Math.max(200, Math.min(availableHeight, 400))
        const availableHeight = windowHeight - headerHeight - navHeight - metricsHeight - chartsHeight - padding;
        tableHeight.value = Math.max(200, Math.min(availableHeight, 400));
        
        // é‡ç»˜å›¾è¡¨
        const charts = [trendChart.value, categoryChart.value, efficiencyChart.value]
        const charts = [trendChart.value, categoryChart.value, efficiencyChart.value];
        charts.forEach(chart => {
          if (chart) chart.resize()
        })
          if (chart) chart.resize();
        });
      } catch (error) {
        console.warn('图表重绘时出错:', error)
        console.warn('图表重绘时出错:', error);
      }
    }
    onMounted(() => {
      // åˆå§‹åŒ–æ—¶é—´
      updateTime()
      timer = setInterval(updateTime, 1000)
      updateTime();
      timer = setInterval(updateTime, 1000);
      // åˆå§‹åŒ–数据和图表
      fetchBigGreenData()
      // åˆå§‹åŒ–数据
      fetchBigGreenData();
      
      nextTick(() => {
        initTrendChart()
        initCategoryChart()
        initEfficiencyChart()
        handleResize()
        startAutoRefresh() // å¯åŠ¨è‡ªåŠ¨åˆ·æ–°
      })
        handleResize();
        startAutoRefresh(); // å¯åŠ¨è‡ªåŠ¨åˆ·æ–°
      });
      
      // ç›‘听窗口大小变化
      window.addEventListener('resize', handleResize)
    })
      window.addEventListener('resize', handleResize);
    });
    onUnmounted(() => {
      // æ¸…除所有定时器
      clearInterval(timer)
      if (taskCarouselTimer) clearInterval(taskCarouselTimer)
      if (autoRefreshTimer) clearInterval(autoRefreshTimer)
      clearInterval(timer);
      stopTaskCarousel();
      stopExpirationCarousel();
      stopAutoRefresh();
      
      // ç§»é™¤çª—口监听
      window.removeEventListener('resize', handleResize)
      window.removeEventListener('resize', handleResize);
      // é”€æ¯å›¾è¡¨å®žä¾‹
      try {
        if (trendChart.value) trendChart.value.dispose()
        if (categoryChart.value) categoryChart.value.dispose()
        if (efficiencyChart.value) efficiencyChart.value.dispose()
        if (trendChart.value) trendChart.value.dispose();
        if (categoryChart.value) categoryChart.value.dispose();
        if (efficiencyChart.value) efficiencyChart.value.dispose();
      } catch (error) {
        console.warn('图表销毁时出错:', error)
        console.warn('图表销毁时出错:', error);
      }
    })
    });
    // ç›‘听任务列表变化,自动重启轮播
    watch(taskList, () => {
      stopTaskCarousel();
      startTaskCarousel();
    }, { deep: true });
    return {
      currentTime,
      metrics,
      taskList,
      showTaskList,
      nearExpirationList,
      showNearExpirationList,
      trendChartRef,
      categoryChartRef,
      efficiencyChartRef,
      tableHeight,
      formatNumber,
      getTaskTypeText,
      getTaskStatusText,
      getStatusClass,
      getTypeClass,
      getExpirationClass,
      refreshData
    }
    };
  }
}
};
</script>
<style scoped>
@@ -718,7 +889,7 @@
  height: 60px;
  background: linear-gradient(90deg, rgba(30, 58, 138, 0.5) 0%, rgba(30, 58, 138, 0.1) 100%);
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.15);
}
.title {
@@ -727,11 +898,14 @@
  background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  margin: 0;
}
.datetime {
  font-size: 16px;
  color: #4facfe;
  font-weight: 600;
  font-family: 'Consolas', monospace;
}
.nav-menu {
@@ -746,9 +920,9 @@
  gap: 8px;
  padding: 10px 25px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 8px;
  color: #fff;
  color: #e0e0e0;
  text-decoration: none;
  transition: all 0.3s;
  cursor: pointer;
@@ -757,11 +931,14 @@
.nav-item:hover {
  background: rgba(79, 172, 254, 0.2);
  border-color: #4facfe;
  transform: translateY(-1px);
}
.nav-item.active {
  background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
  border-color: transparent;
  color: #fff;
  box-shadow: 0 4px 12px rgba(79, 172, 254, 0.3);
}
.main-content {
@@ -771,9 +948,10 @@
  gap: 15px;
}
/* å…³é”®æŒ‡æ ‡å¡ç‰‡ - ä¼˜åŒ–网格布局和样式对比度 */
.metrics-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 15px;
}
@@ -783,7 +961,7 @@
  gap: 20px;
  padding: 20px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 10px;
  transition: all 0.3s;
}
@@ -791,6 +969,7 @@
.metric-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
  border-color: rgba(79, 172, 254, 0.5);
}
.metric-icon {
@@ -808,23 +987,26 @@
}
.metric-value {
  font-size: 28px;
  font-weight: bold;
  color: #fff;
  font-size: 32px;
  font-weight: 700;
  color: #ffffff;
  margin-bottom: 5px;
  text-shadow: 0 0 8px rgba(255,255,255,0.2);
}
.metric-label {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.6);
  color: #cccccc;
  margin-bottom: 5px;
  font-weight: 500;
}
.metric-trend {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-size: 13px;
  font-weight: 600;
}
.metric-trend.up {
@@ -835,17 +1017,20 @@
  color: #f56c6c;
}
/* å›¾è¡¨åŒºåŸŸ - ä¼˜åŒ–布局和样式 */
.charts-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
  gap: 15px;
}
.chart-card {
  padding: 20px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 10px;
  display: flex;
  flex-direction: column;
}
.card-title {
@@ -854,15 +1039,23 @@
  align-items: center;
  margin-bottom: 15px;
  font-size: 16px;
  font-weight: bold;
  font-weight: 600;
  color: #4facfe;
}
.chart-container {
  width: 100%;
  height: 250px;
.task-count {
  font-size: 12px;
  color: #cccccc;
  font-weight: normal;
}
.chart-container {
  flex: 1;
  width: 100%;
  min-height: 250px;
}
/* è¡¨æ ¼åŒºåŸŸ */
.table-row {
  flex: 1;
}
@@ -871,24 +1064,31 @@
  height: 100%;
  padding: 20px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 10px;
  display: flex;
  flex-direction: column;
}
/* Element Plus Table æ ·å¼è¦†ç›– */
/* Element Plus Table æ ·å¼æ·±åº¦ä¼˜åŒ– */
:deep(.el-table) {
  background: transparent !important;
  color: #e0e0e0;
  font-size: 13px;
}
:deep(.el-table th) {
  background: rgba(255, 255, 255, 0.1) !important;
  color: #fff !important;
  border-color: rgba(255, 255, 255, 0.1) !important;
  background: rgba(255, 255, 255, 0.15) !important;
  color: #ffffff !important;
  border-color: rgba(255, 255, 255, 0.2) !important;
  font-weight: 600;
  padding: 10px 0;
}
:deep(.el-table td) {
  border-color: rgba(255, 255, 255, 0.1) !important;
  color: rgba(255, 255, 255, 0.9) !important;
  color: #e0e0e0 !important;
  padding: 12px 0;
}
:deep(.el-table tr) {
@@ -896,14 +1096,18 @@
}
:deep(.el-table__row:hover td) {
  background: rgba(255, 255, 255, 0.05) !important;
  background: rgba(255, 255, 255, 0.08) !important;
}
:deep(.el-table--enable-row-hover .el-table__body tr:hover > td) {
  background: rgba(255, 255, 255, 0.05) !important;
:deep(.el-table--border) {
  border: 1px solid rgba(255,255,255,0.15) !important;
}
/* ä»»åŠ¡çŠ¶æ€æ ·å¼ */
:deep(.el-table__empty-text) {
  color: #cccccc !important;
}
/* ä»»åŠ¡çŠ¶æ€æ ·å¼ - é«˜å¯¹æ¯”度优化 */
.status-container {
  display: flex;
  align-items: center;
@@ -912,7 +1116,7 @@
  position: relative;
  overflow: hidden;
  font-size: 12px;
  font-weight: 500;
  font-weight: 600;
}
.status-dot {
@@ -936,7 +1140,7 @@
  white-space: nowrap;
}
/* ä¸åŒçŠ¶æ€çš„é¢œè‰² */
/* ä¸åŒçŠ¶æ€çš„é¢œè‰² - æ·±è‰²ä¸»é¢˜é«˜å¯¹æ¯”度 */
.status-completed {
  background: rgba(103, 194, 58, 0.15);
  color: #67c23a;
@@ -1015,7 +1219,20 @@
  background: rgba(245, 108, 108, 0.5);
}
/* ä»»åŠ¡ç±»åž‹æ ·å¼ */
.status-unknown {
  background: rgba(75, 85, 99, 0.15);
  color: #9ca3af;
}
.status-unknown .status-dot {
  background: #9ca3af;
}
.status-unknown .status-dot::after {
  background: rgba(156, 163, 175, 0.5);
}
/* ä»»åŠ¡ç±»åž‹æ ·å¼ - é«˜å¯¹æ¯”度优化 */
.type-container {
  display: flex;
  align-items: center;
@@ -1023,7 +1240,7 @@
  border-radius: 20px;
  position: relative;
  font-size: 12px;
  font-weight: 500;
  font-weight: 600;
}
.type-icon {
@@ -1054,6 +1271,37 @@
.type-other {
  background: rgba(144, 147, 153, 0.15);
  color: #909399;
}
.type-unknown {
  background: rgba(75, 85, 99, 0.15);
  color: #9ca3af;
}
/* ä¸´æœŸå¤©æ•°æ ·å¼ */
.exp-expired {
  color: #f56c6c;
  font-weight: 600;
}
.exp-critical {
  color: #e6a23c;
  font-weight: 600;
}
.exp-warning {
  color: #f0ad4e;
  font-weight: 500;
}
.exp-normal {
  color: #67c23a;
  font-weight: 500;
}
.exp-unknown {
  color: #909399;
  font-weight: 400;
}
/* åŠ¨ç”»æ•ˆæžœ */
@@ -1098,36 +1346,28 @@
  }
}
/* å“åº”式适配 */
/* å“åº”式适配增强 */
@media screen and (max-width: 1920px) {
  .metric-value {
    font-size: 24px;
    font-size: 28px;
  }
  .chart-container {
    height: 220px;
    min-height: 220px;
  }
}
@media screen and (max-width: 1600px) {
  .metrics-row {
    grid-template-columns: repeat(2, 1fr);
  }
  .charts-row {
    grid-template-columns: repeat(2, 1fr);
  }
  .title {
    font-size: 20px;
  }
  .metric-value {
    font-size: 20px;
    font-size: 24px;
  }
  .chart-container {
    height: 200px;
    min-height: 200px;
  }
}
@@ -1150,22 +1390,12 @@
    font-size: 14px;
  }
  .metrics-row {
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
  }
  .metric-card {
    padding: 15px;
  }
  .metric-value {
    font-size: 18px;
  }
  .charts-row {
    grid-template-columns: 1fr;
    gap: 10px;
    font-size: 22px;
  }
  .chart-card {
@@ -1173,23 +1403,7 @@
  }
  .chart-container {
    height: 180px;
  }
}
@media screen and (max-width: 1024px) {
  .metrics-row {
    grid-template-columns: 1fr 1fr;
  }
  .nav-menu {
    flex-wrap: wrap;
  }
  .nav-item {
    flex: 1;
    min-width: 100px;
    justify-content: center;
    min-height: 180px;
  }
}
@@ -1216,17 +1430,17 @@
  .nav-menu {
    gap: 8px;
    padding: 0;
    flex-wrap: wrap;
  }
  .nav-item {
    padding: 6px 12px;
    font-size: 12px;
    flex: 1;
    min-width: 80px;
    justify-content: center;
    flex-direction: column;
    gap: 4px;
  }
  .metrics-row {
    grid-template-columns: 1fr;
  }
  .metric-card {
@@ -1240,8 +1454,8 @@
    height: 45px;
  }
  .chart-container {
    height: 150px;
  .metric-trend {
    justify-content: center;
  }
}
</style>
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/Home.vue
@@ -299,9 +299,9 @@
    businessType: item.businessType || '',
    returnToMESStatus: item.returnToMESStatus || 0,
    factoryArea: item.factoryArea || '未知厂区',
    modifier: item.modifier || '未知修改人',
    createDate: item.createDate || '未知时间',
    modifyDate: item.modifyDate || '未知时间'
    modifier: item.modifier,
    createDate: item.createDate,
    modifyDate: item.modifyDate
  }));
  // æ ¼å¼åŒ–出库订单
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/basic/Dt_MesReturnRecord.vue
@@ -171,23 +171,16 @@
      [
        { title: "单据编号", field: "orderNo", type: "like" },
        {
          title: "回传类型",
          field: "returnType",
          type: "select",
          data: [
            { label: "整单", value: 1 },
            { label: "分批", value: 2 },
          ],
          title: "APi请求地址",
          field: "apiUrl",
          type: "like",
        },
        {
          title: "回传接口类型",
          field: "interfaceType",
          type: "select",
          data: [
            { label: "出库", value: 1 },
            { label: "入库", value: 2 },
            { label: "调拨", value: 3 },
          ],
          dataKey:"interfaceType",
          data: [],
        },
      ],
      [
@@ -195,12 +188,28 @@
          title: "回传状态",
          field: "returnStatus",
          type: "select",
          data: [
            { label: "回传成功", value: 1 },
            { label: "回传失败", value: 2 },
          ],
          dataKey:"returnStatus",
          data: [],
        },
        {
          title: "http状态码",
          field: "httpStatusCode",
          type: "int",
        },
        { title: "请求代码", field: "requestCode", type: "like" },
      ],
      [
        {
          title: "最后回传时间",
          field: "lastReturnTime",
          type: "datetime",
        },
        {
          title: "成功时间",
          field: "successTime",
          type: "datetime",
        },
        { title: "回传数据", field: "requestData", type: "like" },
      ],
    ]);
@@ -229,7 +238,6 @@
        width: 120,
        align: "left",
      },
      {
        field: "interfaceType",
        title: "接口类型",
@@ -297,7 +305,7 @@
      },
      {
        field: "failureReason",
        title: "失败原因",
        title: "第一次失败原因",
        type: "string",
        width: 200,
        align: "left",
@@ -309,7 +317,6 @@
        type: "string",
        width: 150,
        align: "left",
        hidden: true, // å¤§æ–‡æœ¬é»˜è®¤éšè—ï¼Œå¯é€šè¿‡åˆ—配置显示
      },
      {
        field: "responseData",
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_BasicService/MESOperation/FeedbackMesService.cs
@@ -497,7 +497,7 @@
                Dt_MesReturnRecord mesReturnRecord = new Dt_MesReturnRecord()
                {
                    ApiUrl = httpResponseResult.ApiUrl,
                    InterfaceType = 1,
                    InterfaceType = 4,
                    OrderId = materialCodeInfo.OrderId ?? 0,
                    OrderNo = materialCodeInfo.OrderNo ?? "",
                    RequestCode = reqCode,
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_StockService/StockDetailByMaterielService.cs
@@ -30,11 +30,11 @@
        {
            try
            {
                List<StockDetailByMateriel> materielnfoStatistics = new List<StockDetailByMateriel>();
                ISugarQueryable<Dt_StockInfoDetail> sugarQueryable1 = _dbBase.Queryable<Dt_StockInfoDetail>();
                ISugarQueryable<Dt_StockInfo> sugarQueryable = _dbBase.Queryable<Dt_StockInfo>();
                ISugarQueryable<Dt_MaterielInfo> sugarQueryable3 = _dbBase.Queryable<Dt_MaterielInfo>();
                if (!string.IsNullOrEmpty(options.Wheres))
                {
                    try
@@ -42,85 +42,80 @@
                        List<SearchParameters> searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
                        if (searchParametersList.Count > 0)
                        {
                            SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.MaterielCode).FirstLetterToLower());
                            if (searchParameters != null)
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.MaterielCode).FirstLetterToLower());
                                if (searchParameters != null)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.MaterielCode.Contains(searchParameters.Value));
                                }
                                sugarQueryable1 = sugarQueryable1.Where(x => x.MaterielCode.Contains(searchParameters.Value));
                            }
                            searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.WarehouseCode).FirstLetterToLower());
                            if (searchParameters != null)
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.WarehouseCode).FirstLetterToLower());
                                if (searchParameters != null)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.WarehouseCode.Contains(searchParameters.Value));
                                }
                                sugarQueryable1 = sugarQueryable1.Where(x => x.WarehouseCode.Contains(searchParameters.Value));
                            }
                            searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.MaterielName).FirstLetterToLower());
                            if (searchParameters != null)
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.MaterielName).FirstLetterToLower());
                                if (searchParameters != null)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.MaterielName.Equals(searchParameters.Value));
                                }
                                sugarQueryable1 = sugarQueryable1.LeftJoin(sugarQueryable3, (d, m) => d.MaterielCode == m.MaterielCode)
                                                                 .Where((d, m) => m.MaterielName.Equals(searchParameters.Value));
                            }
                            searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.BatchNo).FirstLetterToLower());
                            if (searchParameters != null)
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.BatchNo).FirstLetterToLower());
                                if (searchParameters != null)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.BatchNo.Equals(searchParameters.Value));
                                }
                                sugarQueryable1 = sugarQueryable1.Where(x => x.BatchNo.Equals(searchParameters.Value));
                            }
                            searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.SupplyCode).FirstLetterToLower());
                            if (searchParameters != null)
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.SupplyCode).FirstLetterToLower());
                                if (searchParameters != null)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.SupplyCode.Contains(searchParameters.Value));
                                }
                                sugarQueryable1 = sugarQueryable1.Where(x => x.SupplyCode.Contains(searchParameters.Value));
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                    }
                }
                ISugarQueryable<StockDetailByMateriel> sugarQueryable2 = sugarQueryable1.InnerJoin(sugarQueryable, (b, a) => b.StockId == a.Id).Where((b, a) => a.LocationCode != "" && a.LocationCode != null).Select((b, a)
                    => new StockDetailByMateriel
                ISugarQueryable<StockDetailByMateriel> sugarQueryable2 = sugarQueryable1
                    .InnerJoin(sugarQueryable, (detail, stock) => detail.StockId == stock.Id)
                    .LeftJoin(sugarQueryable3, (detail, stock, materiel) => detail.MaterielCode == materiel.MaterielCode)
                    .Where((detail, stock, materiel) => !string.IsNullOrEmpty(stock.LocationCode))
                    .Select((detail, stock, materiel) => new StockDetailByMateriel
                    {
                       StockId = b.StockId,
                        MaterielCode = b.MaterielCode,
                        MaterielName = b.MaterielName,
                        StockQuantity = (decimal)b.StockQuantity,
                        OutboundQuantity = (decimal)b.OutboundQuantity,
                        OrderNo = b.OrderNo,
                        BatchNo = b.BatchNo,
                        SerialNumber = b.SerialNumber,
                        SupplyCode = b.SupplyCode,
                        WarehouseCode = b.WarehouseCode,
                        Barcode = b.Barcode,
                        Unit = b.Unit,
                        Creater = b.Creater,
                        CreateDate= b.CreateDate,
                        Modifier = b.Modifier,
                        ModifyDate = b.ModifyDate,
                        Remark = a.Remark,
                        StockId = detail.StockId,
                        MaterielCode = detail.MaterielCode,
                        MaterielName = materiel.MaterielName ==null ?detail.MaterielName:materiel.MaterielName,
                        StockQuantity = (decimal)detail.StockQuantity,
                        OutboundQuantity = (decimal)detail.OutboundQuantity,
                        OrderNo = detail.OrderNo,
                        BatchNo = detail.BatchNo,
                        SerialNumber = detail.SerialNumber,
                        SupplyCode = detail.SupplyCode,
                        WarehouseCode = detail.WarehouseCode,
                        Barcode = detail.Barcode,
                        Unit = detail.Unit,
                        Creater = detail.Creater,
                        CreateDate = detail.CreateDate,
                        Modifier = detail.Modifier,
                        ModifyDate = detail.ModifyDate,
                        Remark = stock.Remark
                    });
                // èŽ·å–æ‰€æœ‰æ•°æ®
                var allData = sugarQueryable2.ToList();
                // ä½¿ç”¨å­—典进行分组汇总
                var groupedData = new Dictionary<string, StockDetailByMateriel>();
                foreach (var item in allData)
                {
                    string groupKey = $"{item.MaterielCode}|{item.SupplyCode}|{item.BatchNo}|{item.WarehouseCode}";
                    // ç¡®ä¿åˆå§‹å€¼ä¸ºdecimal类型
                    if (groupedData.ContainsKey(groupKey))
                    {
                        groupedData[groupKey].StockQuantity += Convert.ToDecimal(item.StockQuantity);
@@ -151,24 +146,26 @@
                    }
                }
                // è½¬æ¢ä¸ºåˆ—表
                materielnfoStatistics = groupedData.Values.ToList();
                // åˆ†é¡µå¤„理
                int startIndex = (options.Page - 1) * options.Rows;
                int endIndex = Math.Min(startIndex + options.Rows, materielnfoStatistics.Count);
                materielnfoStatistics = materielnfoStatistics.GetRange(startIndex, endIndex - startIndex);
                if (startIndex < materielnfoStatistics.Count)
                {
                    materielnfoStatistics = materielnfoStatistics.GetRange(startIndex, endIndex - startIndex);
                }
                else
                {
                    materielnfoStatistics = new List<StockDetailByMateriel>();
                }
                int count = groupedData.Count;
                return new PageGridData<StockDetailByMateriel>(count, materielnfoStatistics);
            }
            catch (Exception ex)
            {
                return new PageGridData<StockDetailByMateriel>();
            }
            return new PageGridData<StockDetailByMateriel>();
        }
    }
}