1
heshaofeng
2026-01-23 228f757634d7427f4b7bea72053a81d7a4723e62
1
已删除2个文件
已修改10个文件
1140 ■■■■■ 文件已修改
项目代码/WIDESEA_WMSClient/src/views/Home.vue 957 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/stock/stockInfo.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/stock/stockInfoDetail.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/stock/stockInfoDetailByMaterielSum.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/system/Sys_Role.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/system/Sys_User.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.1204.46620/CodeChunks.db 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.1204.46620/SemanticSymbols.db 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/BigGreenService/BigGreenService.cs 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_StockService/StockDetailByMaterielService.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoDetailService.cs 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/Home.vue
@@ -5,9 +5,7 @@
      <el-col :span="4">
        <div class="stats-card">
          <div class="metric-icon">
            <el-icon :size="32">
              <Box />
            </el-icon>
            <el-icon :size="32"><Box /></el-icon>
          </div>
          <div class="card-title">待入库订单</div>
          <div class="card-value">{{ bigscreendata.unInBoundOrderCount }}</div>
@@ -16,9 +14,7 @@
      <el-col :span="4">
        <div class="stats-card">
          <div class="metric-icon">
            <el-icon :size="32">
              <Document />
            </el-icon>
            <el-icon :size="32"><Document /></el-icon>
          </div>
          <div class="card-title">待出库订单</div>
          <div class="card-value">{{ bigscreendata.unOutBoundOrderCount }}</div>
@@ -27,9 +23,7 @@
      <el-col :span="4">
        <div class="stats-card">
          <div class="metric-icon">
            <el-icon :size="32">
              <Download />
            </el-icon>
            <el-icon :size="32"><Download /></el-icon>
          </div>
          <div class="card-title">今日入库完成箱数</div>
          <div class="card-value">{{ bigscreendata.inboundCount }}</div>
@@ -38,9 +32,7 @@
      <el-col :span="4">
        <div class="stats-card">
          <div class="metric-icon">
            <el-icon :size="32">
              <Upload />
            </el-icon>
            <el-icon :size="32"><Upload /></el-icon>
          </div>
          <div class="card-title">今日出库完成箱数</div>
          <div class="card-value">{{ bigscreendata.outboundCount }}</div>
@@ -49,9 +41,7 @@
      <el-col :span="4">
        <div class="stats-card">
          <div class="metric-icon">
            <el-icon :size="32">
              <Box />
            </el-icon>
            <el-icon :size="32"><Box /></el-icon>
          </div>
          <div class="card-title">有货料箱</div>
          <div class="card-value">{{ formatNumber(bigscreendata.inStockPallet) }}</div>
@@ -60,9 +50,7 @@
      <el-col :span="4">
        <div class="stats-card">
          <div class="metric-icon">
            <el-icon :size="32">
              <Box />
            </el-icon>
            <el-icon :size="32"><Box /></el-icon>
          </div>
          <div class="card-title">空箱数量</div>
          <div class="card-value">{{ formatNumber(bigscreendata.freeStockPallet) }}</div>
@@ -114,32 +102,29 @@
      </el-col>
      <el-col :span="8">
        <div class="chart-card">
          <div class="chart-title">近7日出入库单据趋势(图像化走势)</div>
          <div class="chart-title">近7日出入库单据趋势</div>
          <div ref="stockTrendRef" class="chart-container"></div>
        </div>
      </el-col>
    </el-row>
    <!-- å›¾è¡¨åŒºåŸŸï¼ˆç¬¬äºŒè¡Œï¼‰ -->
    <el-row :gutter="20" class="chart-row">
    </el-row>
    <!-- è¡¨æ ¼åŒºåŸŸ - å®žæ—¶ä½œä¸šç›‘控 -->
    <!-- è¡¨æ ¼åŒºåŸŸ - å®žæ—¶ä½œä¸šç›‘控(区分正常/失败作业) -->
    <el-row :gutter="20" class="table-row" width="100%">
      <el-col :span="24">
      <!-- å·¦ä¾§ï¼šå½“天正常作业单据 -->
      <el-col :span="12">
        <div class="table-card">
          <div class="table-title">实时作业监控</div>
          <div class="table-title">实时作业监控(正常单据)</div>
          <el-table 
            :data="showTaskList"
            :data="normalShowTaskList"
            border 
            style="width: 100%;"
            :empty-text="showTaskList.length === 0 ? '暂无作业数据' : ''"
            :empty-text="normalShowTaskList.length === 0 ? '暂无正常作业数据' : ''"
          >
            <el-table-column prop="upperOrderNo" label="单据编号" />
            <el-table-column label="单据状态" >
              <template #default="{ row }">
                <span class="task-status" :class="getStatusClass(row.taskStatus)">
                  {{ getTaskStatusText(row.taskStatus) }}
                  {{ getTaskStatusText(row.taskStatus, row.taskType) }}
                </span>
              </template>
            </el-table-column>
@@ -163,7 +148,62 @@
            <el-table-column prop="modifyDate" label="修改时间"/>
          </el-table>
          <div class="table-pagination">
            <el-pagination layout="prev, pager, next, jumper" :current-page="1" :total="mergedTaskList.length" />
            <el-pagination
              layout="prev, pager, next, jumper"
              v-model:current-page="normalCurrentPage"
              :page-size="5"
              :total="normalTaskList.length"
              @current-change="handleNormalPageChange"
            />
          </div>
        </div>
      </el-col>
      <!-- å³ä¾§ï¼šè¿‘3天回传失败/部分失败单据 -->
      <el-col :span="12">
        <div class="table-card">
          <div class="table-title">实时作业监控(回传失败)</div>
          <el-table
            :data="failShowTaskList"
            border
            style="width: 100%;"
            :empty-text="failShowTaskList.length === 0 ? '暂无回传失败数据' : ''"
          >
            <el-table-column prop="upperOrderNo" label="单据编号" />
            <el-table-column label="单据状态" >
              <template #default="{ row }">
                <span class="task-status" :class="getStatusClass(row.taskStatus)">
                  {{ getTaskStatusText(row.taskStatus, row.taskType) }}
                </span>
              </template>
            </el-table-column>
            <el-table-column label="单据类型" >
              <template #default="{ row }">
                <span class="task-type" :class="getTypeClass(row.taskType)">
                  {{ getTaskTypeText(row) }}
                </span>
              </template>
            </el-table-column>
            <el-table-column label="回传MES状态" >
              <template #default="{ row }">
                <span class="task-status" :class="getMESStatusClass(row.returnToMESStatus)">
                  {{ getMESStatusText(row.returnToMESStatus) }}
                </span>
              </template>
            </el-table-column>
            <el-table-column prop="remark" label="失败原因" show-overflow-tooltip />
            <el-table-column prop="factoryArea" label="厂区" />
            <el-table-column prop="modifier" label="修改人" />
            <el-table-column prop="createDate" label="创建时间"/>
            <el-table-column prop="modifyDate" label="修改时间"/>
          </el-table>
          <div class="table-pagination">
            <el-pagination
              layout="prev, pager, next, jumper"
              v-model:current-page="failCurrentPage"
              :page-size="5"
              :total="failTaskList.length"
              @current-change="handleFailPageChange"
            />
          </div>
        </div>
      </el-col>
@@ -172,13 +212,13 @@
</template>
<script setup>
import { ref, onMounted, onUnmounted, nextTick, computed } from 'vue';
import { ref, onMounted, onUnmounted, nextTick, computed, watch } from 'vue';
import * as echarts from 'echarts';
import http from "@/api/http.js";
import { Box, Document, Download, Upload } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
// å“åº”式数据 - æ–°å¢ž completeTask å­—段
// å“åº”式数据
const bigscreendata = ref({
  totalStockQuantity: 0,
  unOutBoundOrderCount: 0,
@@ -189,7 +229,7 @@
  inStockPallet: 0,
  freeStockPallet: 0,
  dailyInOutBoundList: [],
  completeTask: [], // æ–°å¢žï¼šåŽç«¯è¿”回的嵌套任务数据
  completeTask: [], // åŽç«¯è¿”回的任务数据(当天正常+近3天失败)
  inboundCount: 0,
  outboundCount: 0,
  inventoryLocationDist: [], 
@@ -202,30 +242,18 @@
  const expirationList = bigscreendata.value.nearExpirationList || [];
  const uniqueMap = new Map();
  expirationList.forEach(item => {
    const uniqueKey = [
      item.materielCode,
      item.batchNo,
      item.palletCode,
    ].join('|');
    if (!uniqueMap.has(uniqueKey)) {
      uniqueMap.set(uniqueKey, item);
    }
    const uniqueKey = [item.materielCode, item.batchNo, item.palletCode].join('|');
    if (!uniqueMap.has(uniqueKey)) uniqueMap.set(uniqueKey, item);
  });
  const uniqueExpirationList = Array.from(uniqueMap.values());
  return uniqueExpirationList.map(item => {
    const daysToExpiration = item.daysToExpiration || 0;
    let expireLevel = '';
    if (daysToExpiration < 0) {
      expireLevel = '已过期';
    } else if (daysToExpiration <= 7) {
      expireLevel = '7天内临期';
    } else if (daysToExpiration <= 15) {
      expireLevel = '15天内临期';
    } else if (daysToExpiration <= 30) {
      expireLevel = '30天内临期';
    } else {
      expireLevel = '30天以上';
    }
    if (daysToExpiration < 0) expireLevel = '已过期';
    else if (daysToExpiration <= 7) expireLevel = '7天内临期';
    else if (daysToExpiration <= 15) expireLevel = '15天内临期';
    else if (daysToExpiration <= 30) expireLevel = '30天内临期';
    else expireLevel = '30天以上';
    return {
      materielCode: item.materielCode,
      materielName: item.materielName,
@@ -241,13 +269,11 @@
  });
});
// ç©ºæ•°æ®æç¤ºæ–‡æœ¬ï¼ˆä¿æŒä¸å˜ï¼‰
const emptyText = computed(() => {
  const expirationList = bigscreendata.value.nearExpirationList || [];
  return expirationList.length === 0 ? '暂无临期物料数据' : '';
});
// èŽ·å–ä¸´æœŸç­‰çº§æ ·å¼ç±»ï¼ˆä¿æŒä¸å˜ï¼‰
const getExpireLevelClass = (level) => {
  switch(level) {
    case '已过期': return 'expire-level expired';
@@ -259,38 +285,22 @@
  }
};
// æ ¸å¿ƒï¼šå…¥åº“/出库业务类型枚举映射
// ä¸šåŠ¡ç±»åž‹æ˜ å°„
const inboundBusinessTypeMap = {
  11: "采购入库",
  12: "杂收单",
  13: "生产退料单",
  14: "外协退料单",
  15: "销售退库单",
  3: "调拨入库单"
  11: "采购入库", 12: "杂收单", 13: "生产退料单",
  14: "外协退料单", 15: "销售退库单", 3: "调拨入库单"
};
const outboundBusinessTypeMap = {
  21: "工单领料出库单",
  22: "杂发单",
  23: "退货单",
  24: "销售出库单",
  25: "外协领料申请单",
  2: "调拨出库单",
  21: "工单领料出库单", 22: "杂发单", 23: "退货单",
  24: "销售出库单", 25: "外协领料申请单", 2: "调拨出库单"
};
// æ ¸å¿ƒä¿®æ”¹ï¼šä»Ž completeTask ä¸­æå–订单数据
const mergedTaskList = computed(() => {
  // 1. èŽ·å– completeTask æ•°ç»„,处理空值
  const completeTaskList = bigscreendata.value.completeTask || [];
  // 2. å–第一个元素(后端返回数组长度为1)
  const taskData = completeTaskList[0] || {};
  // 3. æå–入库/出库订单,处理空值
// æ‹†åˆ†ï¼šå½“天正常作业单据
const normalTaskList = computed(() => {
  const taskData = (bigscreendata.value.completeTask[0] || {});
  const inboundOrders = taskData.inboundOrders || [];
  const outboundOrders = taskData.outboundOrders || [];
  console.log('从completeTask提取的入库订单:', inboundOrders);
  console.log('从completeTask提取的出库订单:', outboundOrders);
  // æ ¼å¼åŒ–入库订单
  const formattedInbound = inboundOrders.map(item => ({
    upperOrderNo: item.upperOrderNo || item.inboundOrderNo,
@@ -298,12 +308,13 @@
    taskType: 'inbound',
    businessType: item.businessType || '',
    returnToMESStatus: item.returnToMESStatus || 0,
    factoryArea: item.factoryArea,
    modifier: item.modifier,
    createDate: item.createDate,
    modifyDate: item.modifyDate
    factoryArea: item.factoryArea || '',
    modifier: item.modifier || '',
    createDate: item.createDate || '',
    modifyDate: item.modifyDate || '',
    remark: item.remark || ''
  }));
  // æ ¼å¼åŒ–出库订单
  const formattedOutbound = outboundOrders.map(item => ({
    upperOrderNo: item.upperOrderNo || item.orderNo,
@@ -311,106 +322,106 @@
    taskType: 'outbound',
    businessType: item.businessType || '',
    returnToMESStatus: item.returnToMESStatus || 0,
    factoryArea: item.factoryArea,
    modifier: item.modifier,
    createDate: item.createDate,
    modifyDate: item.modifyDate
    factoryArea: item.factoryArea || '',
    modifier: item.modifier || '',
    createDate: item.createDate || '',
    modifyDate: item.modifyDate || '',
    remark: item.remark || ''
  }));
  const merged = [...formattedInbound, ...formattedOutbound];
  console.log('最终合并的作业列表:', merged);
  return merged;
  return [...formattedInbound, ...formattedOutbound];
});
// è®¢å•状态映射
const orderStatusMap = {
  0: "未开始",
};
// æ‹†åˆ†ï¼šè¿‘3天回传失败/部分失败单据
const failTaskList = computed(() => {
  const taskData = (bigscreendata.value.completeTask[0] || {});
  const inboundFailOrders = taskData.inboundReturnFailOrders || [];
  const outboundFailOrders = taskData.outboundReturnFailOrders || [];
  const formattedInboundFail = inboundFailOrders.map(item => ({
    upperOrderNo: item.upperOrderNo || item.inboundOrderNo,
    taskStatus: item.orderStatus || 0,
    taskType: 'inbound',
    businessType: item.businessType || '',
    returnToMESStatus: item.returnToMESStatus || 0,
    factoryArea: item.factoryArea || '',
    modifier: item.modifier || '',
    createDate: item.createDate || '',
    modifyDate: item.modifyDate || '',
    remark: item.remark || ''
  }));
  const formattedOutboundFail = outboundFailOrders.map(item => ({
    upperOrderNo: item.upperOrderNo || item.orderNo,
    taskStatus: item.orderStatus || 0,
    taskType: 'outbound',
    businessType: item.businessType || '',
    returnToMESStatus: item.returnToMESStatus || 0,
    factoryArea: item.factoryArea || '',
    modifier: item.modifier || '',
    createDate: item.createDate || '',
    modifyDate: item.modifyDate || '',
    remark: item.remark || ''
  }));
  return [...formattedInboundFail, ...formattedOutboundFail];
});
// èŽ·å–è®¢å•çŠ¶æ€æ–‡æœ¬
const getTaskStatusText = (statusNum) => {
  if (statusNum === 1) {
    if (statusNum.taskType === 'inbound') {
      return "入库中";
    } else if (statusNum.taskType === 'outbound') {
      return "出库中";
    } else {
      return "处理中";
    }
  }
  return orderStatusMap[statusNum];
// åˆ†é¡µ&轮播相关响应式变量
const normalCurrentPage = ref(1);
const failCurrentPage = ref(1);
const normalShowTaskList = ref([]);
const failShowTaskList = ref([]);
let normalCarouselTimer = null;
let failCarouselTimer = null;
// ä¿®å¤ï¼šå•据状态文本(新增taskType参数)
const getTaskStatusText = (statusNum, taskType) => {
  const statusMap = {
    0: "未开始",
    1: taskType === 'inbound' ? "入库中" : (taskType === 'outbound' ? "出库中" : "处理中"),
    2: "处理中",
    3: "已完成",
    4: "已取消",
    5: "异常"
  };
  return statusMap[statusNum] ;
};
// MES回传状态映射
const mesStatusMap = {
  0: "未回传",
  1: "回传成功",
  2: "回传失败",
  3: "部分回传成功",
  4: "部分回传失败",
  0: "未回传", 1: "回传成功", 2: "回传失败",
  3: "部分回传成功", 4: "部分回传失败"
};
// èŽ·å–MES回传状态文本
const getMESStatusText = (statusNum) => {
  if (statusNum === undefined || statusNum === null || isNaN(statusNum)) {
    return "未知状态";
  }
  if (statusNum === undefined || statusNum === null || isNaN(statusNum)) return "未知状态";
  return mesStatusMap[statusNum] || `未知状态(${statusNum})`;
};
// èŽ·å–MES回传状态样式类
const getMESStatusClass = (statusNum) => {
  if (statusNum === undefined || statusNum === null || isNaN(statusNum)) {
    return "status-unknown";
  }
  if (statusNum === 0) return "status-pending";
  if (statusNum === 1) return "status-completed";
  if (statusNum === 2) return "status-error";
  if (statusNum === 3) return "status-processing";
  if (statusNum === 4) return "status-error";
  return "status-unknown";
  if (statusNum === undefined || statusNum === null || isNaN(statusNum)) return "status-unknown";
  const classMap = { 0: "status-pending", 1: "status-completed", 2: "status-error", 3: "status-processing", 4: "status-error" };
  return classMap[statusNum] || "status-unknown";
};
// èŽ·å–å•æ®ç±»åž‹æ–‡æœ¬
// å•据类型文本/样式
const getTaskTypeText = (row) => {
  const businessType = Number(row.businessType) || 0;
  if (row.taskType === 'inbound') {
    const typeName = inboundBusinessTypeMap[businessType] || `未知类型(${businessType})`;
    return `${typeName}`;
    return inboundBusinessTypeMap[businessType] || `未知类型(${businessType})`;
  } else if (row.taskType === 'outbound') {
    const typeName = outboundBusinessTypeMap[businessType] || `未知类型(${businessType})`;
    return `${typeName}`;
  } else {
    return "其他作业";
    return outboundBusinessTypeMap[businessType] || `未知类型(${businessType})`;
  }
  return "其他作业";
};
// èŽ·å–ä»»åŠ¡çŠ¶æ€æ ·å¼ç±»
const getStatusClass = (statusNum) => {
  if (statusNum === undefined || statusNum === null || isNaN(statusNum)) {
    return "status-unknown";
  }
  if (statusNum === 3) return "status-completed";
  if (statusNum === 2) return "status-processing";
  if (statusNum === 0) return "status-pending";
  if (statusNum === 4) return "status-canceled";
  if (statusNum === 5) return "status-error";
  if (statusNum === 1) return "status-completed";
  return "status-unknown";
  if (statusNum === undefined || statusNum === null || isNaN(statusNum)) return "status-unknown";
  const classMap = { 0: "status-pending", 1: "status-processing", 2: "status-processing", 3: "status-completed", 4: "status-canceled", 5: "status-error" };
  return classMap[statusNum] || "status-unknown";
};
// èŽ·å–ä»»åŠ¡ç±»åž‹æ ·å¼ç±»
const getTypeClass = (taskType) => {
  if (taskType === 'inbound') return "type-inbound";
  if (taskType === 'outbound') return "type-outbound";
  return "type-other";
  const classMap = { 'inbound': "type-inbound", 'outbound': "type-outbound" };
  return classMap[taskType] || "type-other";
};
// è¡¨æ ¼æ˜¾ç¤ºçš„任务列表(轮播用)
const showTaskList = ref([]);
const currentTaskIndex = ref(0);
let taskCarouselTimer = null;
// æ•°å­—格式化
const formatNumber = (num) => {
@@ -418,41 +429,71 @@
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
};
// è½®æ’­é€»è¾‘
const startTaskCarousel = () => {
  if (taskCarouselTimer) clearInterval(taskCarouselTimer);
// åˆå§‹åŒ–表格数据(分页+轮播)
const initTableData = () => {
  // åœæ­¢æ—§å®šæ—¶å™¨
  clearInterval(normalCarouselTimer);
  clearInterval(failCarouselTimer);
  const totalTask = mergedTaskList.value.length;
  console.log('作业列表总数:', totalTask);
  // æ­£å¸¸å•据分页/轮播
  const loadNormalData = (page) => {
    const start = (page - 1) * 5;
    const end = start + 5;
    normalShowTaskList.value = normalTaskList.value.slice(start, end);
  };
  loadNormalData(normalCurrentPage.value);
  if (totalTask <= 5) {
    showTaskList.value = [...mergedTaskList.value];
  } else {
    showTaskList.value = mergedTaskList.value.slice(0, 5);
    currentTaskIndex.value = 5;
  // å¤±è´¥å•据分页/轮播
  const loadFailData = (page) => {
    const start = (page - 1) * 5;
    const end = start + 5;
    failShowTaskList.value = failTaskList.value.slice(start, end);
  };
  loadFailData(failCurrentPage.value);
  // è½®æ’­é€»è¾‘(仅数据超过5条时开启)
  if (normalTaskList.value.length > 5) {
    normalCarouselTimer = setInterval(() => {
      normalCurrentPage.value = normalCurrentPage.value >= Math.ceil(normalTaskList.value.length / 5) ? 1 : normalCurrentPage.value + 1;
      loadNormalData(normalCurrentPage.value);
    }, 5000);
  }
  if (totalTask > 5) {
    taskCarouselTimer = setInterval(() => {
      showTaskList.value.shift();
      showTaskList.value.push(mergedTaskList.value[currentTaskIndex.value]);
      currentTaskIndex.value++;
      if (currentTaskIndex.value >= totalTask) {
        currentTaskIndex.value = 0;
      }
  if (failTaskList.value.length > 5) {
    failCarouselTimer = setInterval(() => {
      failCurrentPage.value = failCurrentPage.value >= Math.ceil(failTaskList.value.length / 5) ? 1 : failCurrentPage.value + 1;
      loadFailData(failCurrentPage.value);
    }, 5000);
  }
};
// åˆ†é¡µåˆ‡æ¢äº‹ä»¶
const handleNormalPageChange = (page) => {
  clearInterval(normalCarouselTimer); // æ‰‹åŠ¨åˆ‡æ¢åˆ†é¡µæ—¶åœæ­¢è½®æ’­
  normalCurrentPage.value = page;
  const start = (page - 1) * 5;
  const end = start + 5;
  normalShowTaskList.value = normalTaskList.value.slice(start, end);
};
const handleFailPageChange = (page) => {
  clearInterval(failCarouselTimer);
  failCurrentPage.value = page;
  const start = (page - 1) * 5;
  const end = start + 5;
  failShowTaskList.value = failTaskList.value.slice(start, end);
};
// ç›‘听数据变化,重新初始化表格
watch([normalTaskList, failTaskList], () => {
  initTableData();
}, { deep: true });
// èŽ·å–åŽç«¯æ•°æ®
const fetchBigGreenData = async () => {
  try {
    const res = await http.get('/api/BigScreen/GetBigGreenData');
    console.log('后端原始数据:', res.data);
    bigscreendata.value = res.data || res;
    nextTick(() => {
      startTaskCarousel();
      initTableData();
      refreshCharts();
    });
  } catch (error) {
@@ -461,141 +502,29 @@
  }
};
// å¤‡ç”¨æ¨¡æ‹Ÿæ•°æ®
const operationList = ref([
  { opNo: 'JW251224001', opType: '入库', operator: '张三', startTime: '15:30:22', status: '处理中' },
  { opNo: 'CK251224002', opType: '出库', operator: '李四', startTime: '15:25:10', status: '已完成' },
  { opNo: 'PD251224003', opType: '盘点', operator: '王五', startTime: '15:20:05', status: '待确认' },
  { opNo: 'SC251224005', opType: '上架', operator: '孙七', startTime: '15:10:18', status: '异常' }
]);
// å›¾è¡¨ç›¸å…³æ–¹æ³•(保持不变)
const inventoryPieRef = ref(null);
// å›¾è¡¨ç›¸å…³ï¼ˆç²¾ç®€å†—余逻辑)
const stockTrendRef = ref(null);
const locationRateRef = ref(null);
const exceptionTrendRef = ref(null);
let inventoryPieChart = null;
let stockTrendChart = null;
let locationRateChart = null;
let exceptionTrendChart = null;
const initInventoryPie= () => {
  if (!inventoryPieRef.value) return;
  if (inventoryPieChart) {
    inventoryPieChart.dispose();
  }
  inventoryPieChart = echarts.init(inventoryPieRef.value);
  const locationData = bigscreendata.value.inventoryLocationDist.length
    ? bigscreendata.value.inventoryLocationDist
    : [
        { value: 48.7, name: '常温区A区', itemStyle: { color: '#5470c6' } },
        { value: 29.2, name: '冷藏区B区', itemStyle: { color: '#91cc75' } },
        { value: 21.9, name: '保税区C区', itemStyle: { color: '#fac858' } },
        { value: 2.2, name: '残次品区D区', itemStyle: { color: '#ee6666' } }
      ];
  const option = {
    tooltip: {
      trigger: 'item',
      formatter: '{a} <br/>{b}: {c}%'
    },
    legend: {
      bottom: 0,
      left: 'center',
      data: locationData.map(item => item.name)
    },
    series: [{
      name: '库存库位分布',
      type: 'pie',
      radius: ['40%', '70%'],
      center: ['50%', '40%'],
      avoidLabelOverlap: false,
      itemStyle: {
        borderRadius: 10,
        borderColor: '#fff',
        borderWidth: 2
      },
      label: {
        show: false,
        position: 'center'
      },
      emphasis: {
        label: {
          show: true,
          fontSize: 20,
          fontWeight: 'bold'
        }
      },
      labelLine: {
        show: false
      },
      data: locationData
    }]
  };
  inventoryPieChart.setOption(option);
  return inventoryPieChart;
};
const initStockTrend = () => {
  if (!stockTrendRef.value) return;
  if (stockTrendChart) {
    stockTrendChart.dispose();
  }
  if (stockTrendChart) stockTrendChart.dispose();
  stockTrendChart = echarts.init(stockTrendRef.value);
  const trendData = bigscreendata.value.dailyInOutBoundList;
  const maxInbound = trendData.length ? Math.max(...trendData.map(item => item.dailyInboundQuantity || 0)) : 0;
  const maxOutbound = trendData.length ? Math.max(...trendData.map(item => item.dailyOutboundQuantity || 0)) : 0;
  const maxValue = Math.max(maxInbound, maxOutbound);
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross'
      }
    },
    legend: {
      data: ['入库量', '出库量'],
      top: 10
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      top: '15%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      boundaryGap: true,
      data: trendData.map(item => item.date)
    },
    yAxis: {
      type: 'value',
      name: '数量',
      min: 0,
      max: maxValue > 0 ? Math.ceil(maxValue * 1.2) : 10
    },
    tooltip: { trigger: 'axis', axisPointer: { type: 'cross' } },
    legend: { data: ['入库量', '出库量'], top: 10 },
    grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true },
    xAxis: { type: 'category', boundaryGap: true, data: trendData.map(item => item.date) },
    yAxis: { type: 'value', name: '数量', min: 0, max: maxValue > 0 ? Math.ceil(maxValue * 1.2) : 10 },
    series: [
      {
        name: '入库量',
        type: 'bar',
        barWidth: '30%',
        data: trendData.map(item => item.dailyInboundQuantity),
        itemStyle: {
          color: '#52c41a',
          borderRadius: [4, 4, 0, 0]
        }
      },
      {
        name: '出库量',
        type: 'bar',
        barWidth: '30%',
        data: trendData.map(item => item.dailyOutboundQuantity),
        itemStyle: {
          color: '#1890ff',
          borderRadius: [4, 4, 0, 0]
        }
      }
      { name: '入库量', type: 'bar', barWidth: '30%', data: trendData.map(item => item.dailyInboundQuantity), itemStyle: { color: '#52c41a', borderRadius: [4, 4, 0, 0] } },
      { name: '出库量', type: 'bar', barWidth: '30%', data: trendData.map(item => item.dailyOutboundQuantity), itemStyle: { color: '#1890ff', borderRadius: [4, 4, 0, 0] } }
    ]
  };
  stockTrendChart.setOption(option);
@@ -604,206 +533,67 @@
const initLocationRate = () => {
  if (!locationRateRef.value) return;
  if (locationRateChart) {
    locationRateChart.dispose();
  }
  if (locationRateChart) locationRateChart.dispose();
  locationRateChart = echarts.init(locationRateRef.value);
  const utilizationRate = bigscreendata.value.locationUtilizationRate || 0;
  const freeRate = 100 - utilizationRate;
  const option = {
    tooltip: {
      trigger: 'item',
      formatter: '{b}: {c}%'
    },
    legend: {
      bottom: 0,
      left: 'center',
      data: ['已占用库位', '空闲库位'],
      textStyle: { fontSize: 12, color: '#666' }
    },
    tooltip: { trigger: 'item', formatter: '{b}: {c}%' },
    legend: { bottom: 0, left: 'center', data: ['已占用库位', '空闲库位'], textStyle: { fontSize: 12, color: '#666' } },
    graphic: [
      {
        type: 'text',
        left: 'right',
        top: '10%',
        style: {
          text: `${utilizationRate}%`,
          fontSize: 24,
          fontWeight: 'bold',
          fill: '#333'
        }
      },
      {
        type: 'text',
        left: 'right',
        top: '25%',
        style: {
          text: '库位利用率',
          fontSize: 14,
          fill: '#666'
        }
      }
      { type: 'text', left: 'right', top: '10%', style: { text: `${utilizationRate}%`, fontSize: 24, fontWeight: 'bold', fill: '#333' } },
      { type: 'text', left: 'right', top: '25%', style: { text: '库位利用率', fontSize: 14, fill: '#666' } }
    ],
    series: [
      {
        type: 'pie',
        radius: ['50%', '70%'],
        center: ['40%', '50%'],
        avoidLabelOverlap: false,
        label: { show: false },
        labelLine: { show: false },
        data: [
          { value: utilizationRate, name: '已占用库位', itemStyle: { color: '#1890ff' } },
          { value: freeRate, name: '空闲库位', itemStyle: { color: '#e5e9f2' } }
        ]
      }
    ]
    series: [{
      type: 'pie', radius: ['50%', '70%'], center: ['40%', '50%'],
      avoidLabelOverlap: false, label: { show: false }, labelLine: { show: false },
      data: [
        { value: utilizationRate, name: '已占用库位', itemStyle: { color: '#1890ff' } },
        { value: freeRate, name: '空闲库位', itemStyle: { color: '#e5e9f2' } }
      ]
    }]
  };
  locationRateChart.setOption(option);
  return locationRateChart;
};
const initExceptionTrend = () => {
  if (!exceptionTrendRef.value) return;
  if (exceptionTrendChart) {
    exceptionTrendChart.dispose();
  }
  exceptionTrendChart = echarts.init(exceptionTrendRef.value);
  const exceptionData = bigscreendata.value.exceptionTypeTrend.length
    ? bigscreendata.value.exceptionTypeTrend
    : {
        dates: ['12-18', '12-19', '12-20', '12-21', '12-22', '12-23', '12-24'],
        stockShort: [10, 11, 9, 12, 10, 13, 12],
        orderTimeout: [8, 9, 7, 8, 7, 9, 8],
        locationException: [4, 5, 2, 4, 3, 5, 4],
        checkDiff: [2, 3, 1, 2, 1, 3, 2]
      };
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross'
      }
    },
    legend: {
      data: ['库存不足', '订单超时', '库位异常', '盘点差异'],
      top: 10
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      top: '15%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: exceptionData.dates
    },
    yAxis: {
      type: 'value',
      name: '异常数量'
    },
    series: [
      {
        name: '库存不足',
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 8,
        data: exceptionData.stockShort,
        itemStyle: { color: '#ff4d4f' },
        lineStyle: { width: 3 }
      },
      {
        name: '订单超时',
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 8,
        data: exceptionData.orderTimeout,
        itemStyle: { color: '#faad14' },
        lineStyle: { width: 3 }
      },
      {
        name: '库位异常',
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 8,
        data: exceptionData.locationException,
        itemStyle: { color: '#722ed1' },
        lineStyle: { width: 3 }
      },
      {
        name: '盘点差异',
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 8,
        data: exceptionData.checkDiff,
        itemStyle: { color: '#13c2c2' },
        lineStyle: { width: 3 }
      }
    ]
  };
  exceptionTrendChart.setOption(option);
  return exceptionTrendChart;
};
const refreshCharts = () => {
  const charts = [
    initStockTrend,
    initLocationRate
  ];
  charts.forEach(initFunc => {
  [initStockTrend, initLocationRate].forEach(initFunc => {
    const chart = initFunc();
    if (chart) {
      chart.resize();
    }
    if (chart) chart.resize();
  });
};
// é˜²æŠ–处理resize事件
let resizeTimer = null;
const handleResize = () => {
  const charts = [
    inventoryPieChart,
    stockTrendChart,
    locationRateChart,
    exceptionTrendChart
  ];
  charts.forEach(chart => {
    if (chart) {
      chart.resize();
    }
  });
  clearTimeout(resizeTimer);
  resizeTimer = setTimeout(() => {
    [stockTrendChart, locationRateChart].forEach(chart => {
      if (chart) chart.resize();
    });
  }, 200);
};
// ç»„件生命周期
// ç”Ÿå‘½å‘¨æœŸ
onMounted(() => {
  fetchBigGreenData();
  nextTick(() => {
    initInventoryPie();
    initStockTrend();
    initLocationRate();
    initExceptionTrend();
    window.addEventListener('resize', handleResize);
  });
});
onUnmounted(() => {
  const charts = [
    inventoryPieChart,
    stockTrendChart,
    locationRateChart,
    exceptionTrendChart
  ];
  charts.forEach(chart => {
    if (chart) {
      chart.dispose();
    }
  // é”€æ¯å›¾è¡¨å’Œå®šæ—¶å™¨
  [stockTrendChart, locationRateChart].forEach(chart => {
    if (chart) chart.dispose();
  });
  clearInterval(taskCarouselTimer);
  [normalCarouselTimer, failCarouselTimer, resizeTimer].forEach(timer => {
    clearInterval(timer);
    clearTimeout(timer);
  });
  window.removeEventListener('resize', handleResize);
});
</script>
@@ -817,20 +607,7 @@
  font-family: "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  background: white;
  padding: 15px 20px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.stats-card-row,
.chart-row,
.table-row {
.stats-card-row, .chart-row, .table-row {
  margin-bottom: 20px;
}
@@ -896,10 +673,6 @@
  background-clip: text;
}
.card-change {
  margin-top: 3px;
}
.chart-card {
  height: 400px;
  padding: 24px;
@@ -945,44 +718,16 @@
  font-size: 12px;
  font-weight: 500;
}
.expire-level.expired {
  background-color: #fff2f0;
  color: #ff4d4f;
  border: 1px solid #ffccc7;
}
.expire-level.urgent {
  background-color: #fff7e6;
  color: #fa8c16;
  border: 1px solid #ffd591;
}
.expire-level.warning {
  background-color: #f6ffed;
  color: #52c41a;
  border: 1px solid #b7eb8f;
}
.expire-level.normal {
  background-color: #e6f7ff;
  color: #1890ff;
  border: 1px solid #91d5ff;
}
.expire-level.low {
  background-color: #f0f2f5;
  color: #666666;
  border: 1px solid #d9d9d9;
}
.expire-level.default {
  background-color: #fafafa;
  color: #8c8c8c;
  border: 1px solid #e8e8e8;
}
.expire-level.expired { background-color: #fff2f0; color: #ff4d4f; border: 1px solid #ffccc7; }
.expire-level.urgent { background-color: #fff7e6; color: #fa8c16; border: 1px solid #ffd591; }
.expire-level.warning { background-color: #f6ffed; color: #52c41a; border: 1px solid #b7eb8f; }
.expire-level.normal { background-color: #e6f7ff; color: #1890ff; border: 1px solid #91d5ff; }
.expire-level.low { background-color: #f0f2f5; color: #666666; border: 1px solid #d9d9d9; }
.expire-level.default { background-color: #fafafa; color: #8c8c8c; border: 1px solid #e8e8e8; }
.text-red {
  color: #ff4d4f;
  font-weight: 500;
}
.text-red { color: #ff4d4f; font-weight: 500; }
.chart-title,
.table-title {
.chart-title, .table-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
@@ -994,10 +739,6 @@
  border-left: 4px solid #409eff;
  position: relative;
  letter-spacing: 0.5px;
}
.view-btn {
  font-size: 12px;
}
.table-card {
@@ -1029,67 +770,26 @@
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
:deep(.el-table th) { background-color: #f5f7fa; color: #606266; font-weight: 600; padding: 12px 0; }
:deep(.el-table td) { padding: 12px 0; }
:deep(.el-table--border) { border-radius: 6px; }
:deep(.el-table--border::after), :deep(.el-table--group::after), :deep(.el-table::before), :deep(.el-table__fixed-right::before), :deep(.el-table__fixed::before) { display: none; }
:deep(.el-table th) {
  background-color: #f5f7fa;
  color: #606266;
  font-weight: 600;
  padding: 12px 0;
}
:deep(.el-table td) {
  padding: 12px 0;
}
:deep(.el-table--border) {
  border-radius: 6px;
}
:deep(.el-table--border::after) {
  display: none;
}
:deep(.el-table--group::after) {
  display: none;
}
:deep(.el-table::before) {
  display: none;
}
:deep(.el-table__fixed-right::before) {
  display: none;
}
:deep(.el-table__fixed::before) {
  display: none;
}
:deep(.el-pagination) {
  margin-top: 10px;
}
:deep(.el-pagination .btn-prev),
:deep(.el-pagination .btn-next),
:deep(.el-pagination .el-pager li) {
:deep(.el-pagination .btn-prev), :deep(.el-pagination .btn-next), :deep(.el-pagination .el-pager li) {
  border-radius: 4px;
  margin: 0 2px;
  transition: all 0.3s;
}
:deep(.el-pagination .btn-prev:hover),
:deep(.el-pagination .btn-next:hover),
:deep(.el-pagination .el-pager li:hover) {
:deep(.el-pagination .btn-prev:hover), :deep(.el-pagination .btn-next:hover), :deep(.el-pagination .el-pager li:hover) {
  transform: translateY(-2px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
:deep(.el-pagination .el-pager li.active) {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: #fff;
}
.task-status {
.task-status, .task-type {
  display: inline-block;
  padding: 6px 12px;
  border-radius: 20px;
@@ -1102,94 +802,17 @@
  letter-spacing: 0.5px;
}
.status-pending {
  background-color: rgba(64, 158, 255, 0.1);
  color: #409eff;
  border: 1px solid rgba(64, 158, 255, 0.2);
}
.status-pending { background-color: rgba(64, 158, 255, 0.1); color: #409eff; border: 1px solid rgba(64, 158, 255, 0.2); }
.status-processing { background-color: rgba(103, 194, 58, 0.1); color: #67c23a; border: 1px solid rgba(103, 194, 58, 0.2); }
.status-completed { background-color: rgba(103, 194, 58, 0.1); color: #67c23a; border: 1px solid rgba(103, 194, 58, 0.2); }
.status-suspended { background-color: rgba(230, 162, 60, 0.1); color: #e6a23c; border: 1px solid rgba(230, 162, 60, 0.2); }
.status-canceled { background-color: rgba(144, 147, 153, 0.1); color: #909399; border: 1px solid rgba(144, 147, 153, 0.2); }
.status-error { background-color: rgba(245, 108, 108, 0.1); color: #f56c6c; border: 1px solid rgba(245, 108, 108, 0.2); }
.status-unknown { background-color: rgba(144, 147, 153, 0.1); color: #909399; border: 1px solid rgba(144, 147, 153, 0.2); }
.status-processing {
  background-color: rgba(103, 194, 58, 0.1);
  color: #67c23a;
  border: 1px solid rgba(103, 194, 58, 0.2);
}
.status-completed {
  background-color: rgba(103, 194, 58, 0.1);
  color: #67c23a;
  border: 1px solid rgba(103, 194, 58, 0.2);
}
.status-suspended {
  background-color: rgba(230, 162, 60, 0.1);
  color: #e6a23c;
  border: 1px solid rgba(230, 162, 60, 0.2);
}
.status-canceled {
  background-color: rgba(144, 147, 153, 0.1);
  color: #909399;
  border: 1px solid rgba(144, 147, 153, 0.2);
}
.status-error {
  background-color: rgba(245, 108, 108, 0.1);
  color: #f56c6c;
  border: 1px solid rgba(245, 108, 108, 0.2);
}
.status-unknown {
  background-color: rgba(144, 147, 153, 0.1);
  color: #909399;
  border: 1px solid rgba(144, 147, 153, 0.2);
}
.task-type {
  display: inline-block;
  padding: 6px 12px;
  border-radius: 20px;
  font-size: 13px;
  font-weight: 500;
  text-align: center;
  min-width: 80px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  transition: all 0.2s ease;
  letter-spacing: 0.5px;
}
.type-inbound {
  background-color: rgba(64, 158, 255, 0.1);
  color: #409eff;
  border: 1px solid rgba(64, 158, 255, 0.2);
}
.type-outbound {
  background-color: rgba(103, 194, 58, 0.1);
  color: #67c23a;
  border: 1px solid rgba(103, 194, 58, 0.2);
}
.type-transfer {
  background-color: rgba(230, 162, 60, 0.1);
  color: #e6a23c;
  border: 1px solid rgba(230, 162, 60, 0.2);
}
.type-other {
  background-color: rgba(144, 147, 153, 0.1);
  color: #909399;
  border: 1px solid rgba(144, 147, 153, 0.2);
}
.type-unknown {
  background-color: rgba(144, 147, 153, 0.1);
  color: #909399;
  border: 1px solid rgba(144, 147, 153, 0.2);
}
.btn-group {
  margin-left: 10px;
}
.type-inbound { background-color: rgba(64, 158, 255, 0.1); color: #409eff; border: 1px solid rgba(64, 158, 255, 0.2); }
.type-outbound { background-color: rgba(103, 194, 58, 0.1); color: #67c23a; border: 1px solid rgba(103, 194, 58, 0.2); }
.type-transfer { background-color: rgba(230, 162, 60, 0.1); color: #e6a23c; border: 1px solid rgba(230, 162, 60, 0.2); }
.type-other { background-color: rgba(144, 147, 153, 0.1); color: #909399; border: 1px solid rgba(144, 147, 153, 0.2); }
.type-unknown { background-color: rgba(144, 147, 153, 0.1); color: #909399; border: 1px solid rgba(144, 147, 153, 0.2); }
</style>
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/stock/stockInfo.vue
@@ -41,7 +41,7 @@
    const searchFormOptions = ref([
      [
        { title: "托盘编号", field: "palletCode", type: 'like' },
        { title: "货位编号", field: "locationCode", type: "like" },
        { title: "货位编号", field: "locationCode", type: 'like' },
        { title: "托盘类型", field: "palletType", type: "select", dataKey: "palletType", data: [] },
      ],
    ]);
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/stock/stockInfoDetail.vue
@@ -75,7 +75,7 @@
      ],
      [
        { title: "库存状态", field: "status", type: 'select', dataKey: "stockStatusEmun", data: [] },
        { title: "仓库", field: "warehouseCode", type: 'select', dataKey: "wareHouse", data: [] },
        { title: "仓库", field: "warehouseCode", type: 'select', dataKey: "warehouse", data: [] },
      ],
    ]);
    const columns = ref([
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/stock/stockInfoDetailByMaterielSum.vue
@@ -71,7 +71,7 @@
        { title: "供应商编号", field: "supplyCode", type: 'like' },
      ],
      [
        { title: "仓库", field: "warehouseCode", type: 'select', dataKey: "wareHouse", data: [] },
        { title: "仓库", field: "warehouseCode", type: 'select', dataKey: "warehouse", data: [] },
      ]
    ]);
    const columns = ref([
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/system/Sys_Role.vue
@@ -80,8 +80,8 @@
    });
    const searchFormOptions = ref([
      [
        { title: "角色名称", field: "roleName", type: "text" },
        { title: "部门ID", field: "deptId", type: "text" },
        { title: "角色名称", field: "roleName", type: "like" },
        { title: "部门ID", field: "deptId", type: "like" },
        {
          dataKey: "enable",
          data: [],
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/system/Sys_User.vue
@@ -101,8 +101,8 @@
    });
    const searchFormOptions = ref([
      [
        { title: "帐号", field: "userName" },
        { title: "姓名", field: "userTrueName" },
        { title: "帐号", field: "userName", type:'like' },
        { title: "姓名", field: "userTrueName", type:'like'  },
        {
          dataKey: "gender",
          data: [],
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.1204.46620/CodeChunks.db
Binary files differ
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.1204.46620/SemanticSymbols.db
Binary files differ
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/BigGreenService/BigGreenService.cs
@@ -164,22 +164,46 @@
        public List<SimpleStatisticsDTO> SimpleStatistics()
        {
            var targetStatuses = new List<int>
            {
                (int)InOrderStatusEnum.入库中,
                (int)InOrderStatusEnum.未开始,
                (int)OutOrderStatusEnum.未开始,
                (int)OutOrderStatusEnum.出库中
            };
            var inboundList = _inboundRepository.QueryData(x => x.CreateDate.ToString("MM-dd") == DateTime.Now.ToString("MM-dd") && targetStatuses.Contains(x.OrderStatus)).ToList();
            var outboundList = _outBoundOrderRepository.QueryData(x => x.CreateDate.ToString("MM-dd") == DateTime.Now.ToString("MM-dd") && targetStatuses.Contains(x.OrderStatus)).ToList();
            var today = DateTime.Now.Date;
            var threeDaysAgo = today.AddDays(-3);
            var stats = new List<SimpleStatisticsDTO> { new SimpleStatisticsDTO
            {
                inboundOrders =inboundList,
                outboundOrders = outboundList
            } };
            return stats;
            var targetStatuses = new List<int> { (int)InOrderStatusEnum.入库中, (int)InOrderStatusEnum.未开始,
                                         (int)OutOrderStatusEnum.未开始, (int)OutOrderStatusEnum.出库中 };
            var failReturnStatuses = new List<int> {4,2};
            var inboundToday = QueryInboundOrders(today, today, targetStatuses);
            var outboundToday = QueryOutboundOrders(today, today, targetStatuses);
            var inboundFail3Days = QueryInboundOrders(threeDaysAgo, today, failReturnStatuses, isReturnStatus: true);
            var outboundFail3Days = QueryOutboundOrders(threeDaysAgo, today, failReturnStatuses, isReturnStatus: true);
            return new List<SimpleStatisticsDTO> { new()
    {
        inboundOrders = inboundToday,
        outboundOrders = outboundToday,
        inboundReturnFailOrders = inboundFail3Days,
        outboundReturnFailOrders = outboundFail3Days
    }};
        }
        private List<Dt_InboundOrder> QueryInboundOrders(DateTime startDate, DateTime endDate,
                                                      List<int> statusList, bool isReturnStatus = false)
        {
            return _inboundRepository.QueryData(x =>
                x.CreateDate.Date >= startDate &&
                x.CreateDate.Date <= endDate &&
                (isReturnStatus ? statusList.Contains(x.ReturnToMESStatus) : statusList.Contains(x.OrderStatus))).ToList();
        }
        private List<Dt_OutboundOrder> QueryOutboundOrders(DateTime startDate, DateTime endDate,
                                                        List<int> statusList, bool isReturnStatus = false)
        {
            return _outBoundOrderRepository.QueryData(x =>
                x.CreateDate.Date >= startDate &&
                x.CreateDate.Date <= endDate &&
                (isReturnStatus ? statusList.Contains(x.ReturnToMESStatus) : statusList.Contains(x.OrderStatus))).ToList();
        }
        /// <summary>
@@ -277,6 +301,8 @@
        {
            public List<Dt_InboundOrder> inboundOrders { get; set; }
            public List<Dt_OutboundOrder> outboundOrders { get; set; }
            public List<Dt_InboundOrder> inboundReturnFailOrders { get; set; }
            public List<Dt_OutboundOrder> outboundReturnFailOrders { get; set; }
        }
        
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_StockService/StockDetailByMaterielService.cs
@@ -58,15 +58,14 @@
                            searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.MaterielName).FirstLetterToLower());
                            if (searchParameters != null)
                            {
                                sugarQueryable1 = sugarQueryable1.LeftJoin(sugarQueryable3, (d, m) => d.MaterielCode == m.MaterielCode)
                                                                 .Where((d, m) => m.MaterielName.Equals(searchParameters.Value));
                                sugarQueryable1 = sugarQueryable1.Where(x => x.MaterielName.Contains(searchParameters.Value));
                            }
                           
                            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.Contains(searchParameters.Value));
                            }
                            
                            searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.SupplyCode).FirstLetterToLower());
@@ -74,6 +73,7 @@
                            {
                                sugarQueryable1 = sugarQueryable1.Where(x => x.SupplyCode.Contains(searchParameters.Value));
                            }
                        }
                    }
                    catch (Exception ex)
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoDetailService.cs
@@ -37,8 +37,6 @@
        public PageGridData<StockInfoDetailWithPalletDto> GetPageData2(PageDataOptions options)
        {
            string wheres = ValidatePageOptions(options);
            var sugarQueryable = Db.Queryable<Dt_StockInfoDetail>().InnerJoin<Dt_StockInfo>((detail, item) => detail.StockId == item.Id)
                .Where((detail, item) => item.StockStatus == StockStatusEmun.入库完成.ObjToInt());
@@ -84,6 +82,54 @@
                            {
                                sugarQueryable = sugarQueryable.Where((detail, item) => item.PalletCode.Contains(param.Value));
                            }
                            if (param.Name.Equals(nameof(Dt_StockInfoDetail.MaterielCode).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase)
                                && !string.IsNullOrEmpty(param.Value?.ToString()))
                            {
                                string queryValue = param.Value.ToString().Trim();
                                sugarQueryable = sugarQueryable.Where((detail, item) => detail.MaterielCode.Contains(queryValue));
                            }
                            if (param.Name.Equals(nameof(Dt_StockInfoDetail.MaterielName).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase)
                                && !string.IsNullOrEmpty(param.Value?.ToString()))
                            {
                                string queryValue = param.Value.ToString().Trim();
                                sugarQueryable = sugarQueryable.Where((detail, item) => detail.MaterielName.Contains(queryValue));
                            }
                            if (param.Name.Equals(nameof(Dt_StockInfoDetail.OrderNo).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase)
                                && !string.IsNullOrEmpty(param.Value?.ToString()))
                            {
                                string queryValue = param.Value.ToString().Trim();
                                sugarQueryable = sugarQueryable.Where((detail, item) => detail.OrderNo.Contains(queryValue));
                            }
                            if (param.Name.Equals(nameof(Dt_StockInfoDetail.BatchNo).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase)
                                && !string.IsNullOrEmpty(param.Value?.ToString()))
                            {
                                string queryValue = param.Value.ToString().Trim();
                                sugarQueryable = sugarQueryable.Where((detail, item) => detail.BatchNo.Contains(queryValue));
                            }
                            if (param.Name.Equals(nameof(Dt_StockInfoDetail.Barcode).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase)
                                && !string.IsNullOrEmpty(param.Value?.ToString()))
                            {
                                string queryValue = param.Value.ToString().Trim();
                                sugarQueryable = sugarQueryable.Where((detail, item) => detail.Barcode.Contains(queryValue));
                            }
                            if (param.Name.Equals(nameof(Dt_StockInfoDetail.MaterielCode).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase)
                                && !string.IsNullOrEmpty(param.Value?.ToString()))
                            {
                                string queryValue = param.Value.ToString().Trim();
                                sugarQueryable = sugarQueryable.Where((detail, item) => detail.MaterielCode.Contains(queryValue));
                            }
                            if (param.Name.Equals(nameof(Dt_StockInfoDetail.Status).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase)
                                && !string.IsNullOrEmpty(param.Value?.ToString()))
                            {
                                string queryValue = param.Value.ToString().Trim();
                                sugarQueryable = sugarQueryable.Where((detail, item) => detail.Status.Equals(queryValue));
                            }
                            if (param.Name.Equals(nameof(Dt_StockInfoDetail.WarehouseCode).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase)
                                && !string.IsNullOrEmpty(param.Value?.ToString()))
                            {
                                string queryValue = param.Value.ToString().Trim();
                                sugarQueryable = sugarQueryable.Where((detail, item) => detail.WarehouseCode.Equals(queryValue));
                            }
                        }
                    }
                }
@@ -92,7 +138,6 @@
                }
            }          
            var data = sugarQueryable
             .WhereIF(!wheres.IsNullOrEmpty(), wheres)
             .OrderBy(orderByModels)
             .Select((detail, item) => new StockInfoDetailWithPalletDto
             {
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs
@@ -552,31 +552,47 @@
        public override PageGridData<Dt_StockInfo> GetPageData(PageDataOptions options)
        {
            string wheres = ValidatePageOptions(options);
            //获取排序字段
            Dictionary<string, SqlSugar.OrderByType> orderbyDic = GetPageDataSort(options, TProperties);
            ISugarQueryable<Dt_StockInfo> sugarQueryable = Db.Queryable<Dt_StockInfo>();
            ValidatePageOptions(options, ref sugarQueryable);
            List<OrderByModel> orderByModels = new List<OrderByModel>();
            foreach (var item in orderbyDic)
            if (OrderByParameters != null)
            {
                OrderByModel orderByModel = new()
                foreach (var item in OrderByParameters)
                {
                    FieldName = item.Key,
                    OrderByType = item.Value
                };
                orderByModels.Add(orderByModel);
                    OrderByModel orderByModel = new OrderByModel()
                    {
                        FieldName = item.Key,
                        OrderByType = item.Value
                    };
                    orderByModels.Add(orderByModel);
                }
            }
            ISugarQueryable<Dt_StockInfo> sugarQueryable1 = BaseDal.Db.Queryable<Dt_StockInfo>();
            if (EnableWebOrderBy)
            {
                //获取排序字段
                Dictionary<string, SqlSugar.OrderByType> orderbyDic = GetPageDataSort(options, TProperties);
            int totalCount = 0;
            List<SearchParameters> searchParametersList = new List<SearchParameters>();
            var data = sugarQueryable1
                .WhereIF(!wheres.IsNullOrEmpty(), wheres)
                .Where(x => !string.IsNullOrEmpty(x.LocationCode))
                .OrderBy(orderByModels)
                .ToPageList(options.Page, options.Rows, ref totalCount);
                foreach (var item in orderbyDic)
                {
                    OrderByModel orderByModel = new OrderByModel()
                    {
                        FieldName = item.Key,
                        OrderByType = item.Value
                    };
                    orderByModels.Add(orderByModel);
                }
            }
            return new PageGridData<Dt_StockInfo>(totalCount, data);
            int total = 0;
            PageGridData<Dt_StockInfo> pageGridData = new PageGridData<Dt_StockInfo>();
            sugarQueryable = sugarQueryable.OrderBy(orderByModels);
            pageGridData.Rows = sugarQueryable.ToPageList(options.Page, options.Rows, ref total);
            pageGridData.Total = total;
            return pageGridData;
        }
    }
}