liulijun
6 天以前 4cf43750c41e1833143b557ecbbf6844656f49d6
添加成品库存详细页面物料条码字段

添加成品库存详细页面物料条码字段,解决了消息列表的删除消息异常
已添加1个文件
已修改5个文件
18775 ■■■■ 文件已修改
项目代码/BigScreen/package-lock.json 18465 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/BigScreen/src/views/index.vue 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS/WMSClient/src/main.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS/WMSClient/src/services/taskTimeout.js 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS/WMSClient/src/services/wcsTaskMonitor.js 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS/WMSClient/src/views/stock/ProStockView.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ÏîÄ¿´úÂë/BigScreen/package-lock.json
ÎļþÌ«´ó
ÏîÄ¿´úÂë/BigScreen/src/views/index.vue
@@ -74,7 +74,7 @@
            config: {
                header: [
                    '<span style="font-size:50px;">纸卷条码</span>',
                    '<span style="font-size:50px;">工单号</span>',
                    //'<span style="font-size:50px;">工单号</span>',
                    '<span style="font-size:50px;">代码</span>',
                    '<span style="font-size:50px;">上机位</span>',
                    '<span style="font-size:50px;">宽幅</span>',
@@ -83,22 +83,12 @@
                ],
                data: [
                    [
                        '<span style="color:#FF4500; font-size:60px;">705010</span>',
                        '<span style="color:#FF4500; font-size:60px;">015004</span>',
                        '<span style="color:#FF4500; font-size:60px;">X2</span>',
                        '<span style="color:#FF4500; font-size:60px;">1</span>',
                        '<span style="color:#FF4500; font-size:60px;">1200</span>',
                        '<span style="color:#FF4500; font-size:60px;;">4798</span>',
                        '<span style="color:#FF4500; font-size:60px;">180</span>',
                    ],
                    [
                        '<span style="color:#FF4500; font-size:60px;">705010</span>',
                        '<span style="color:#FF4500; font-size:60px;">015004</span>',
                        '<span style="color:#FF4500; font-size:60px;">X2</span>',
                        '<span style="color:#FF4500; font-size:60px;">2</span>',
                        '<span style="color:#FF4500; font-size:60px;">1200</span>',
                        '<span style="color:#FF4500; font-size:60px;;">4798</span>',
                        '<span style="color:#FF4500; font-size:60px;">180</span>',
                        '<span style="color:#FF4500; font-size:60px;">06D4BC6110</span>',
                        '<span style="color:#FF4500; font-size:60px;">I0</span>',
                        '<span style="color:#FF4500; font-size:60px;">糊车</span>',
                        '<span style="color:#FF4500; font-size:60px;">2450</span>',
                        '<span style="color:#FF4500; font-size:60px;">6976</span>',
                        '<span style="color:#FF4500; font-size:60px;;">1597</span>',
                    ],
                ],
                headerHeight: 60,
@@ -218,7 +208,7 @@
                        
                        // åˆ›å»ºåˆå¹¶åŽçš„单条记录
                        var item = [
                            '<span style="color:#FF4500; font-size:90px;">' + palletCode + '</span>',
                            '<span style="color:#FF4500; font-size:89px;">' + palletCode + '</span>',
                            //'<span style="color:#FF4500; font-size:55px;">' + orderNos + '</span>',
                            '<span style="color:#FF4500; font-size:90px;">' + firstItem.materielCode + '</span>',
                            '<span style="color:#FF4500; font-size:90px;">' + machineLastChar + '</span>',
@@ -245,7 +235,7 @@
                            evenRowBGC: "rgba(0, 0, 0, 0.6)",
                            headerBGC: "rgba(0, 0, 0, 0.6)",
                            waitTime: 5000,
                            columnWidth: [550, 200, 250, 250, 250, 300],
                            columnWidth: [560, 200, 250, 250, 250, 300],
                            rowNum: 10,
                            align: ["center", "center", "center", "center", "center", "center", "center"],
                        };
ÏîÄ¿´úÂë/WMS/WMSClient/src/main.js
@@ -15,6 +15,8 @@
import emptyPalletWarning from './services/emptyPalletWarning'
// å¼•入全局任务超时服务
import taskTimeoutService from './services/taskTimeout'
// å¼•å…¥WCS任务异常监控服务
import wcsTaskMonitorService from './services/wcsTaskMonitor'
@@ -79,8 +81,14 @@
emptyPalletWarning.init(app);
// åˆå§‹åŒ–全局任务超时服务
taskTimeoutService.init(app);
// // åˆå§‹åŒ–WCS任务异常监控服务
// wcsTaskMonitorService.init(app);
// å°†ä»»åŠ¡è¶…æ—¶æœåŠ¡æŒ‚è½½åˆ°å…¨å±€å±žæ€§ä¸Š
app.config.globalProperties.$taskTimeoutService = taskTimeoutService;
// // å°†WCS任务监控服务挂载到全局属性上
// app.config.globalProperties.$wcsTaskMonitorService = wcsTaskMonitorService;
// å°†ä»»åŠ¡è¶…æ—¶æœåŠ¡æŒ‚è½½åˆ°window对象上,方便在扩展组件中访问
window.$taskTimeoutService = taskTimeoutService;
// // å°†WCS任务监控服务挂载到window对象上,方便在扩展组件中访问
// window.$wcsTaskMonitorService = wcsTaskMonitorService;
ÏîÄ¿´úÂë/WMS/WMSClient/src/services/taskTimeout.js
@@ -92,21 +92,19 @@
    const globalObj = window.$global || {};
    // å¤„理消息删除逻辑,重置对应任务的定时器
    const deletedMessages = globalObj.messageDeleted || [];
    const deletedMessages = [...(globalObj.messageDeleted || [])];
    if (deletedMessages.length > 0) {
      const globalMessageList = globalObj.messageList || [];
      // æ¸…空已处理的删除消息列表,避免重复处理
      globalObj.messageDeleted = [];
      // éåŽ†è¢«åˆ é™¤çš„æ¶ˆæ¯ID,重置对应任务的定时器
      deletedMessages.forEach(deletedId => {
        const deletedMessage = globalMessageList.find(msg => msg.id === deletedId);
        if (deletedMessage?.businessType === 'task_timeout' && deletedMessage.taskNum && this.taskStatusMap[deletedMessage.taskNum]) {
          this.taskStatusMap[deletedMessage.taskNum] = now;
        }
        // ä¸éœ€è¦ä»ŽmessageList中查找,因为消息已经被删除
        // ç›´æŽ¥å¤„理任务状态重置
        // è¿™é‡Œä¸åšä»»ä½•操作,因为消息删除是用户主动行为
        // æˆ‘们只需要清空messageDeleted数组即可
      });
      // æ¸…空已处理的删除消息列表
      globalObj.messageDeleted = [];
    }
    // èŽ·å–å½“å‰æ‰€æœ‰ä»»åŠ¡å·å’ŒçŠ¶æ€
@@ -145,7 +143,7 @@
    const globalObj = window.$global || {};
    
    // èŽ·å–å…¨å±€æ¶ˆæ¯åˆ—è¡¨
    const globalMessageList = globalObj.messageList || [];
    const globalMessageList = [...(globalObj.messageList || [])];
    
    // æ‰¾å‡ºéœ€è¦æ¸…除的任务超时消息
    const taskTimeoutMessages = globalMessageList.filter(msg => msg.businessType === 'task_timeout');
@@ -156,32 +154,29 @@
      // æ£€æŸ¥æ¡ä»¶ï¼š
      // 1. ä»»åŠ¡ä¸åœ¨å½“å‰ä»»åŠ¡åˆ—è¡¨ä¸­ï¼ˆå·²å®Œæˆæˆ–è¢«ç§»é™¤ï¼‰
      // 2. ä»»åŠ¡åœ¨å½“å‰ä»»åŠ¡åˆ—è¡¨ä¸­ï¼Œä½†çŠ¶æ€å·²ä¸å†æ˜¯å †åž›æœºæ‰§è¡Œä¸­
      if (!currentTaskStatuses[taskNum] || currentTaskStatuses[taskNum] !== 210) {
      if (taskNum && (!currentTaskStatuses[taskNum] || currentTaskStatuses[taskNum] !== 210)) {
        // ä»»åŠ¡å·²å®Œæˆæˆ–çŠ¶æ€å·²æ”¹å˜ï¼Œæ¸…é™¤è¯¥æ¶ˆæ¯
        this.handleDeleteTaskMessage(msg);
        // ä½†è¦ç¡®ä¿åªåœ¨æ¶ˆæ¯ä»ç„¶å­˜åœ¨æ—¶æ‰åˆ é™¤
        if (globalObj.messageList && Array.isArray(globalObj.messageList)) {
          const index = globalObj.messageList.findIndex(m => m.id === msg.id);
          if (index !== -1) {
            globalObj.messageList.splice(index, 1);
          }
        }
      }
    });
  }
  // å¤„理删除单个任务消息
  handleDeleteTaskMessage(message) {
    // èŽ·å–å…¨å±€å¯¹è±¡
    const globalObj = window.$global || {};
    // ç›´æŽ¥ä»Žå…¨å±€æ¶ˆæ¯åˆ—表中删除该消息
    if (globalObj.messageList) {
      const index = globalObj.messageList.findIndex(msg => msg.id === message.id);
      if (index !== -1) {
        globalObj.messageList.splice(index, 1);
      }
    }
  }
  // å‘送任务警告消息
  sendTaskWarningMessage(task, duration) {
    // åˆ›å»ºå”¯ä¸€çš„æ¶ˆæ¯ID
    const messageId = Date.now() + Math.random().toString(36).substr(2, 9);
    // åˆ›å»ºè­¦å‘Šæ¶ˆæ¯
    const warningMessage = {
      id: Date.now(),
      id: messageId,
      title: '任务异常警告',
      message: `任务号 ${task.taskNum} å·²åœ¨å †åž›æœºæ‰§è¡Œä¸­çŠ¶æ€è¶…è¿‡${Math.round(duration)}分钟,请及时处理!`,
      type: 'warning',
@@ -206,7 +201,6 @@
    try {
      if (globalObj.messageList) {
        globalObj.messageList.push(warningMessage);
      }
    } catch (error) {
      // å‡ºé”™æ—¶ä½¿ç”¨æµè§ˆå™¨åŽŸç”Ÿalert作为最终备选
ÏîÄ¿´úÂë/WMS/WMSClient/src/services/wcsTaskMonitor.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,218 @@
// WCS系统任务异常监控服务
import http from '../api/http';
// WCS任务异常监控服务类
class WcsTaskMonitorService {
  constructor() {
    this.checkTaskStatusTimer = null;
    this.apiTaskData = []; // å­˜å‚¨é€šè¿‡API获取的任务数据
    this.apiRefreshTimer = null; // API数据刷新定时器
    this.apiRefreshInterval = 5000; // API数据刷新间隔,5秒
  }
  // åˆå§‹åŒ–WCS任务异常监控服务
  init(app) {
    // è®¾ç½®å®šæ—¶å™¨ï¼Œæ¯5秒检查一次
    this.checkTaskStatusTimer = setInterval(() => {
      this.checkTaskExceptions();
    }, 5000);
    // è®¾ç½®API数据刷新定时器,每5秒刷新一次任务数据
    this.apiRefreshTimer = setInterval(() => {
      this.refreshTaskDataFromApi();
    }, this.apiRefreshInterval);
    // åˆå§‹åˆ·æ–°ä¸€æ¬¡ä»»åŠ¡æ•°æ®
    this.refreshTaskDataFromApi();
    // ä¿å­˜å®šæ—¶å™¨å¼•用,方便后续清理
    if (app && app.config) {
      app.config.globalProperties.$global.wcsTaskMonitorTimer = this.checkTaskStatusTimer;
      app.config.globalProperties.$global.wcsTaskMonitorApiTimer = this.apiRefreshTimer;
    }
    // æ–¹ä¾¿æ‰‹åŠ¨æµ‹è¯•ï¼Œå°†check方法挂载到window对象
    window.testWcsTaskMonitor = () => {
      this.checkTaskExceptions();
    };
  }
  // ä»ŽAPI刷新任务数据
  async refreshTaskDataFromApi() {
    try {
      // è°ƒç”¨WCS专门的API获取异常任务数据
      const apiData = await http.post('http://localhost:9291/api/Task/GetTasksWithException', {});
      if (apiData && apiData.data) {
        this.apiTaskData = apiData.data;
      } else {
        this.apiTaskData = [];
      }
    } catch (error) {
      console.error('从API获取异常任务数据失败:', error);
      this.apiTaskData = [];
    }
  }
  // æ£€æŸ¥ä»»åС异叏
  checkTaskExceptions() {
    // ç›´æŽ¥ä½¿ç”¨ä»ŽAPI获取的异常任务数据
    const exceptionTasks = this.apiTaskData || [];
    // åŽ»é‡ï¼Œç¡®ä¿æ¯ä¸ªä»»åŠ¡åªå¤„ç†ä¸€æ¬¡
    const uniqueExceptionTasks = [];
    const taskNumSet = new Set();
    exceptionTasks.forEach(task => {
      if (task && task.taskNum && !taskNumSet.has(task.taskNum)) {
        uniqueExceptionTasks.push(task);
        taskNumSet.add(task.taskNum);
      }
    });
    // èŽ·å–å…¨å±€å¯¹è±¡
    const globalObj = window.$global || {};
    // å¤„理消息删除逻辑,重置对应任务的异常标记
    const deletedMessages = [...(globalObj.messageDeleted || [])];
    if (deletedMessages.length > 0) {
      // éåŽ†è¢«åˆ é™¤çš„æ¶ˆæ¯ID,重置对应任务的异常标记
      deletedMessages.forEach(deletedId => {
        // ç›´æŽ¥éåŽ†æ‰€æœ‰å·²å¤„ç†çš„å¼‚å¸¸ä»»åŠ¡
        // å› ä¸ºæ¶ˆæ¯å¯èƒ½å·²ç»è¢«ä»ŽmessageList中删除
        for (const taskNum of this.processedExceptions) {
          // è¿™é‡Œä¸ä¾èµ–messageList,直接重置所有可能的任务
          // ç¡®ä¿åˆ é™¤åŽèƒ½é‡æ–°å‘送消息
          this.processedExceptions.delete(taskNum);
        }
      });
      // æ¸…空已处理的删除消息列表,避免重复处理
      globalObj.messageDeleted = [];
    }
    // å¤„理异常任务
    uniqueExceptionTasks.forEach(task => {
      // ä¸ç®¡æ˜¯å¦å·²ç»å¤„理过,只要任务在异常列表中,就发送消息
      // è¿™æ ·ç¡®ä¿åˆ é™¤åŽèƒ½é‡æ–°å‘送消息
      this.sendTaskExceptionMessage(task);
      // ä¸éœ€è¦æ·»åŠ åˆ°processedExceptions,因为我们不再使用它来阻止重发
    });
    // æ¸…除已解决的任务异常消息
    this.clearResolvedTaskExceptionMessages(uniqueExceptionTasks);
  }
  // æ¸…除已解决的任务异常消息
  clearResolvedTaskExceptionMessages(currentExceptionTasks) {
    // èŽ·å–å…¨å±€å¯¹è±¡
    const globalObj = window.$global || {};
    // èŽ·å–å…¨å±€æ¶ˆæ¯åˆ—è¡¨
    const globalMessageList = [...(globalObj.messageList || [])];
    // æ‰¾å‡ºéœ€è¦æ¸…除的任务异常消息
    const taskExceptionMessages = globalMessageList.filter(msg => msg.businessType === 'wcs_task_exception');
    // æž„建当前异常任务集合
    const currentExceptionTaskNums = new Set();
    currentExceptionTasks.forEach(task => {
      if (task && task.taskNum) {
        currentExceptionTaskNums.add(task.taskNum);
      }
    });
    // éåŽ†æ‰€æœ‰ä»»åŠ¡å¼‚å¸¸æ¶ˆæ¯
    taskExceptionMessages.forEach(msg => {
      const taskNum = msg.taskNum;
      // æ£€æŸ¥ä»»åŠ¡æ˜¯å¦ä¸åœ¨å½“å‰å¼‚å¸¸ä»»åŠ¡åˆ—è¡¨ä¸­ï¼ˆè¯´æ˜Žå¼‚å¸¸å·²è§£å†³ï¼‰
      if (taskNum && !currentExceptionTaskNums.has(taskNum)) {
        // ä»»åŠ¡å¼‚å¸¸å·²è§£å†³ï¼Œæ¸…é™¤è¯¥æ¶ˆæ¯
        if (globalObj.messageList && Array.isArray(globalObj.messageList)) {
          const index = globalObj.messageList.findIndex(m => m.id === msg.id);
          if (index !== -1) {
            globalObj.messageList.splice(index, 1);
          }
        }
      }
    });
  }
  // å‘送任务异常消息
  sendTaskExceptionMessage(task) {
    // åˆ›å»ºå”¯ä¸€çš„æ¶ˆæ¯ID
    const messageId = Date.now() + Math.random().toString(36).substr(2, 9);
    // èŽ·å–å¼‚å¸¸æè¿°ï¼Œç¡®ä¿ä¸ä¸ºç©º
    const exceptionDescription = task.ExceptionMessage || '未知异常';
    // åˆ›å»ºå¼‚常消息
    const exceptionMessage = {
      id: messageId,
      title: '任务异常警告',
      message: `任务号 ${task.taskNum} å‡ºçŽ°å¼‚å¸¸ï¼š${exceptionDescription},请及时处理!`,
      type: 'error',
      businessType: 'wcs_task_exception',
      taskNum: task.taskNum,
      createTime: new Date().toLocaleString(),
      relatedData: {
        TaskNum: task.taskNum,
        ExceptionMessage: exceptionDescription,
        CreateDate: task.createDate
      }
    };
    // èŽ·å–å…¨å±€å¯¹è±¡
    const globalObj = window.$global || {};
    // æ£€æŸ¥æ˜¯å¦å·²ç»å­˜åœ¨ç›¸åŒçš„任务异常警告
    const globalMessageList = globalObj.messageList || [];
    const hasExistingWarning = globalMessageList.some(msg =>
      msg.businessType === 'wcs_task_exception' && msg.taskNum === task.taskNum
    );
    if (hasExistingWarning) return;
    // å‘送消息到全局消息列表
    try {
      if (globalObj.messageList) {
        globalObj.messageList.push(exceptionMessage);
      }
    } catch (error) {
      // å‡ºé”™æ—¶ä½¿ç”¨æµè§ˆå™¨åŽŸç”Ÿalert作为最终备选
      try {
        alert(`任务异常警告: ä»»åŠ¡å· ${task.taskNum} å‡ºçŽ°å¼‚å¸¸ï¼š${exceptionDescription},请及时处理!`);
      } catch (e) {
        // å¿½ç•¥æ‰€æœ‰é”™è¯¯
      }
    }
  }
  // æ‰‹åŠ¨æ£€æŸ¥ä»»åŠ¡å¼‚å¸¸ï¼ˆç”¨äºŽå¤–éƒ¨è°ƒç”¨ï¼‰
  manualCheckTaskExceptions() {
    this.checkTaskExceptions();
  }
  // æ¸…理资源
  cleanup() {
    if (this.checkTaskStatusTimer) {
      clearInterval(this.checkTaskStatusTimer);
      this.checkTaskStatusTimer = null;
    }
    if (this.apiRefreshTimer) {
      clearInterval(this.apiRefreshTimer);
      this.apiRefreshTimer = null;
    }
    this.apiTaskData = [];
    delete window.testWcsTaskMonitor;
  }
}
// åˆ›å»ºå•例实例
const wcsTaskMonitorService = new WcsTaskMonitorService();
export default wcsTaskMonitorService;
ÏîÄ¿´úÂë/WMS/WMSClient/src/views/stock/ProStockView.vue
@@ -48,6 +48,7 @@
          { title: "库存状态", field: "stockStatus",type: "selectList",dataKey: "stockStatusEmun",data: [],},
        ],
        [
          { title: "货位编号", field: "locationCode", type: "like" },
          { title: "所属仓库", field: "warehouseId",type: "select",dataKey: "warehouses",data: []},
          { title: "库存属性", field: "proStockAttribute" ,type: "selectList",dataKey: "proStockAttributeEnum",data: [],},
          { title: "创建时间", field: "createDate",type: "datetime",},
@@ -269,6 +270,13 @@
            align: "left",
          },
          {
            field: "productNo",
            title: "物料条码",
            type: "string",
            width: 150,
            align: "left",
          },
          {
            field: "lotNumber",
            title: "物料批号",
            type: "string",