From 720e0926fa1c94b952c26e111206c5d6e1ed5ba2 Mon Sep 17 00:00:00 2001
From: lsh <lsh@163.com>
Date: 星期二, 21 四月 2026 15:59:49 +0800
Subject: [PATCH] Merge branch 'master' of http://47.97.1.152:5880/r/zy-wcs-master

---
 src/main/webapp/static/js/deviceLogs/deviceLogs.js |  274 +++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 215 insertions(+), 59 deletions(-)

diff --git a/src/main/webapp/static/js/deviceLogs/deviceLogs.js b/src/main/webapp/static/js/deviceLogs/deviceLogs.js
index 62667fc..74f2d44 100644
--- a/src/main/webapp/static/js/deviceLogs/deviceLogs.js
+++ b/src/main/webapp/static/js/deviceLogs/deviceLogs.js
@@ -16,6 +16,7 @@
         },
         selectedDay: '',
         searchDeviceNo: '',
+        searchStationId: '',
         activeType: '',
         viewMode: 'picker',
         deviceSummary: {
@@ -31,6 +32,9 @@
 
         selectedType: '',
         selectedDeviceNo: '',
+        selectedStationId: '',
+        selectedStationLabel: '',
+        visualFocusStationId: '',
         activeDeviceKey: '',
 
         timelineMeta: {
@@ -62,6 +66,10 @@
         jumpTime: null,
         detailTab: 'logs',
         rawTab: 'wcs',
+
+        systemLogType: 'info',
+        systemLogRange: [],
+        systemLogDialogVisible: false,
 
         downloadDialogVisible: false,
         buildProgress: 0,
@@ -123,12 +131,38 @@
         filteredDevices: function () {
             var group = this.activeGroup;
             var devices = group && group.devices ? group.devices.slice() : [];
-            var keyword = String(this.searchDeviceNo || '').trim();
-            if (!keyword) {
-                return devices;
-            }
-            return devices.filter(function (item) {
-                return String(item.deviceNo).indexOf(keyword) >= 0;
+            var deviceKeyword = String(this.searchDeviceNo || '').trim();
+            var stationKeyword = String(this.searchStationId || '').trim();
+            return devices.map(function (item) {
+                var matchedStationIds = [];
+                var matchesDeviceNo = !deviceKeyword || String(item.deviceNo).indexOf(deviceKeyword) >= 0;
+                var matchesStation = true;
+                if (stationKeyword) {
+                    matchesStation = false;
+                    if (item.type === 'Devp') {
+                        if (item.stationId && String(item.stationId).indexOf(stationKeyword) >= 0) {
+                            matchesStation = true;
+                            matchedStationIds = [String(item.stationId)];
+                        } else {
+                            var stationIds = Array.isArray(item.stationIds) ? item.stationIds : [];
+                            for (var i = 0; i < stationIds.length; i++) {
+                                if (String(stationIds[i]).indexOf(stationKeyword) >= 0) {
+                                    matchesStation = true;
+                                    matchedStationIds.push(String(stationIds[i]));
+                                }
+                            }
+                        }
+                    }
+                }
+                if (!matchesDeviceNo || !matchesStation) {
+                    return null;
+                }
+                return Object.assign({}, item, {
+                    matchedStationIds: matchedStationIds,
+                    matchedStationId: matchedStationIds.length === 1 ? matchedStationIds[0] : ''
+                });
+            }).filter(function (item) {
+                return !!item;
             });
         },
         selectedDeviceSummary: function () {
@@ -136,7 +170,7 @@
             var found = null;
             (this.deviceGroups || []).forEach(function (group) {
                 (group.devices || []).forEach(function (device) {
-                    if (this.buildDeviceKey(device.type, device.deviceNo) === key) {
+                    if (this.buildDeviceKey(device.type, device.deviceNo, device.stationId) === key) {
                         found = device;
                     }
                 }, this);
@@ -228,6 +262,9 @@
             return this.selectedLogRow ? this.selectedLogRow._visualItems : [];
         },
         visualParam: function () {
+            if (this.selectedType === 'Devp') {
+                return this.buildVisualParam(this.selectedType, this.selectedDeviceNo, this.resolveVisualStationId(this.selectedLogRow));
+            }
             return this.selectedLogRow ? this.selectedLogRow._visualParam : {};
         },
         activeRawText: function () {
@@ -259,6 +296,9 @@
         },
         canDownload: function () {
             return !!(this.selectedDay && this.selectedType && this.selectedDeviceNo);
+        },
+        canDownloadSystemLog: function () {
+            return !!(this.selectedDay && this.systemLogType && this.systemLogRange && this.systemLogRange.length === 2 && this.systemLogRange[0] && this.systemLogRange[1]);
         },
         canPlay: function () {
             return !!(this.selectedDeviceSummary && this.timelineMeta.startTime && this.timelineMeta.endTime && this.sliderMax > 0);
@@ -420,6 +460,7 @@
             }
             this.selectedDay = day;
             this.searchDeviceNo = '';
+            this.searchStationId = '';
             this.pause();
             this.summaryLoading = true;
             this.resetSelectionState();
@@ -471,6 +512,10 @@
                             type: device.type,
                             typeLabel: device.typeLabel || self.typeLabels[device.type] || device.type,
                             deviceNo: String(device.deviceNo),
+                            stationId: device.stationId == null ? '' : String(device.stationId),
+                            stationIds: (device.stationIds || []).map(function (stationId) { return String(stationId); }),
+                            matchedStationIds: [],
+                            matchedStationId: '',
                             fileCount: device.fileCount || 0,
                             firstTime: device.firstTime || 0,
                             lastTime: device.lastTime || 0
@@ -536,6 +581,9 @@
             this.viewMode = 'picker';
             this.selectedType = '';
             this.selectedDeviceNo = '';
+            this.selectedStationId = '';
+            this.selectedStationLabel = '';
+            this.visualFocusStationId = '';
             this.activeDeviceKey = '';
             this.detailTab = 'logs';
             this.rawTab = 'wcs';
@@ -553,7 +601,7 @@
             if (!device) {
                 return;
             }
-            var nextKey = this.buildDeviceKey(device.type, device.deviceNo);
+            var nextKey = this.buildDeviceKey(device.type, device.deviceNo, device.stationId);
             if (this.activeDeviceKey === nextKey && this.logRows.length) {
                 return;
             }
@@ -562,6 +610,11 @@
             this.activeType = device.type;
             this.selectedType = device.type;
             this.selectedDeviceNo = String(device.deviceNo);
+            this.selectedStationId = device.stationId == null ? '' : String(device.stationId);
+            this.selectedStationLabel = device.stationId == null || String(device.stationId) === ''
+                ? (device.matchedStationId == null ? '' : String(device.matchedStationId))
+                : String(device.stationId);
+            this.visualFocusStationId = this.selectedStationLabel;
             this.activeDeviceKey = nextKey;
             this.detailTab = 'raw';
             this.rawTab = 'wcs';
@@ -571,7 +624,29 @@
             this.loadingOffsets = {};
             this.selectedTimestamp = 0;
             this.logLoadError = '';
+            if (this.selectedType === 'Devp' && !this.selectedStationId) {
+                return;
+            }
             this.loadTimeline();
+        },
+        resolveVisualStationId: function (logItem) {
+            if (this.selectedType !== 'Devp') {
+                return '';
+            }
+            if (logItem && logItem.stationId != null && String(logItem.stationId) !== '') {
+                return String(logItem.stationId);
+            }
+            if (this.visualFocusStationId) {
+                return String(this.visualFocusStationId);
+            }
+            var selected = this.selectedDeviceSummary;
+            if (selected && selected.stationId) {
+                return String(selected.stationId);
+            }
+            if (selected && selected.matchedStationId) {
+                return String(selected.matchedStationId);
+            }
+            return '';
         },
         returnToSelector: function () {
             this.pause();
@@ -590,7 +665,8 @@
                 method: 'GET',
                 data: {
                     type: this.selectedType,
-                    deviceNo: this.selectedDeviceNo
+                    deviceNo: this.selectedDeviceNo,
+                    stationId: this.selectedStationId || undefined
                 },
                 success: function (res) {
                     self.timelineLoading = false;
@@ -627,6 +703,7 @@
             timeline.type = data.type || this.selectedType;
             timeline.typeLabel = data.typeLabel || this.typeLabels[timeline.type] || timeline.type;
             timeline.deviceNo = String(data.deviceNo || this.selectedDeviceNo || '');
+            timeline.stationId = data.stationId == null ? this.selectedStationId : String(data.stationId || '');
             timeline.startTime = data.startTime || 0;
             timeline.endTime = data.endTime || 0;
             timeline.totalFiles = data.totalFiles || 0;
@@ -685,6 +762,7 @@
                 data: {
                     type: this.selectedType,
                     deviceNo: this.selectedDeviceNo,
+                    stationId: this.selectedStationId || undefined,
                     offset: offset,
                     limit: batchSize
                 },
@@ -741,12 +819,13 @@
             var protocol = this.safeParse(logItem && logItem.wcsData);
             var visualItems = this.buildVisualItems(protocol, this.selectedType);
             return Object.assign({}, logItem, {
+                stationId: logItem && logItem.stationId == null ? this.selectedStationId : logItem.stationId,
                 _ts: this.parseTimestamp(logItem && logItem.createTime),
                 _key: this.buildLogRowKey(logItem),
                 _segmentOffset: segmentOffset,
                 _protocol: protocol,
                 _visualItems: visualItems,
-                _visualParam: this.buildVisualParam(this.selectedType, this.selectedDeviceNo),
+                _visualParam: this.buildVisualParam(this.selectedType, this.selectedDeviceNo, this.resolveVisualStationId(logItem)),
                 _summary: this.buildLogSummary(this.selectedType, visualItems, protocol)
             });
         },
@@ -795,36 +874,17 @@
                 };
             }
             if (type === 'Devp') {
-                var stations = visualItems || [];
-                var autoCount = 0;
-                var taskCount = 0;
-                var loadingCount = 0;
-                var errorStations = [];
-                var canInCount = 0;
-                for (var i = 0; i < stations.length; i++) {
-                    if (this.toBool(stations[i].autoing)) {
-                        autoCount += 1;
-                    }
-                    if (stations[i].taskNo != null && stations[i].taskNo !== '' && Number(stations[i].taskNo) !== 0) {
-                        taskCount += 1;
-                    }
-                    if (this.toBool(stations[i].loading)) {
-                        loadingCount += 1;
-                    }
-                    if (this.toBool(stations[i].inEnable)) {
-                        canInCount += 1;
-                    }
-                    if (stations[i].error || stations[i].errorMsg) {
-                        errorStations.push(stations[i].stationId);
-                    }
-                }
-                var statusLabel = errorStations.length ? '鏁呴殰' : (autoCount === stations.length && stations.length ? '鑷姩' : '鎵嬪姩');
+                var station = visualItems[0] || this.transformData(protocol, type) || {};
+                var hasError = !!(station.error || station.errorMsg);
+                var autoing = this.toBool(station.autoing);
+                var loading = this.toBool(station.loading);
+                var statusLabel = hasError ? '鏁呴殰' : (autoing ? '鑷姩' : '鎵嬪姩');
                 return {
                     statusLabel: statusLabel,
                     tone: MonitorCardKit.statusTone(statusLabel),
-                    title: stations.length + ' 涓珯鐐� 路 浠诲姟 ' + taskCount + ' 路 鏈夌墿 ' + loadingCount,
-                    detail: '鑷姩 ' + autoCount + ' / 鎵嬪姩 ' + Math.max(0, stations.length - autoCount) + ' / 鍙叆 ' + canInCount,
-                    hint: errorStations.length ? ('寮傚父绔欑偣 ' + errorStations.slice(0, 6).join(', ')) : ('绔欑偣鏁扮粍澶у皬 ' + stations.length)
+                    title: '绔欑偣 ' + MonitorCardKit.orDash(station.stationId) + ' 路 浠诲姟 ' + MonitorCardKit.orDash(station.taskNo),
+                    detail: '鐩爣绔欑偣 ' + MonitorCardKit.orDash(station.targetStaNo) + ' / 杞借揣 ' + (loading ? '鏈夌墿' : '鏃犵墿') + ' / 鎵樼洏楂樺害 ' + MonitorCardKit.orDash(station.palletHeight) + ' / 鏉$爜 ' + MonitorCardKit.orDash(station.barcode),
+                    hint: hasError ? (MonitorCardKit.orDash(station.error) + (station.errorMsg ? (' 路 ' + station.errorMsg) : '')) : ('鑷姩 ' + (autoing ? '鏄�' : '鍚�') + ' / 鍏佽鍏ュ簱 ' + (this.toBool(station.inEnable) ? '鏄�' : '鍚�'))
                 };
             }
             return fallback;
@@ -833,27 +893,38 @@
             if (!protocol) {
                 return [];
             }
-            if (type === 'Devp' && Array.isArray(protocol)) {
-                var self = this;
-                return protocol.map(function (item) {
-                    return self.transformData(item, type);
-                }).sort(function (a, b) {
-                    return (a.stationId || 0) - (b.stationId || 0);
-                });
+            if (type === 'Devp') {
+                return [this.transformData(protocol, type)];
             }
             if (type !== 'Devp') {
                 return [this.transformData(protocol, type)];
             }
             return [];
         },
-        buildVisualParam: function (type, deviceNo) {
+        buildVisualParam: function (type, deviceNo, stationId) {
             if (type === 'Crn' || type === 'DualCrn') {
                 return { crnNo: Number(deviceNo) };
             }
             if (type === 'Rgv') {
                 return { rgvNo: Number(deviceNo) };
             }
+            if (type === 'Devp' && stationId) {
+                return { stationId: Number(stationId) };
+            }
             return {};
+        },
+        normalizeVisualValue: function (value) {
+            if (value == null || value === '') {
+                return value;
+            }
+            if (Array.isArray(value) || Object.prototype.toString.call(value) === '[object Object]') {
+                try {
+                    return JSON.stringify(value);
+                } catch (e) {
+                    return String(value);
+                }
+            }
+            return value;
         },
         transformData: function (protocol, type) {
             if (!protocol) {
@@ -945,18 +1016,23 @@
                     targetStaNo: protocol.targetStaNo,
                     autoing: protocol.autoing,
                     loading: protocol.loading,
+                    ioMode: protocol.ioMode,
                     inEnable: protocol.inEnable,
                     outEnable: protocol.outEnable,
                     emptyMk: protocol.emptyMk,
                     fullPlt: protocol.fullPlt,
                     runBlock: protocol.runBlock,
                     enableIn: protocol.enableIn,
+                    inBarcodeError: protocol.inBarcodeError,
                     palletHeight: protocol.palletHeight,
                     barcode: protocol.barcode,
                     weight: protocol.weight,
+                    taskWriteIdx: protocol.taskWriteIdx,
+                    taskBufferItems: Array.isArray(protocol.taskBufferItems) ? protocol.taskBufferItems : [],
                     error: protocol.error,
                     errorMsg: protocol.errorMsg,
-                    extend: protocol.extend
+                    systemWarning: this.normalizeVisualValue(protocol.systemWarning),
+                    extend: this.normalizeVisualValue(protocol.extend)
                 };
             }
             return protocol;
@@ -1013,6 +1089,7 @@
             return [
                 this.selectedType,
                 this.selectedDeviceNo,
+                this.selectedStationId,
                 logItem && logItem.createTime ? logItem.createTime : '',
                 this.hashString(logItem && logItem.originData ? logItem.originData : ''),
                 this.hashString(logItem && logItem.wcsData ? logItem.wcsData : '')
@@ -1290,6 +1367,7 @@
                 data: {
                     type: this.selectedType,
                     deviceNo: this.selectedDeviceNo,
+                    stationId: this.selectedStationId || undefined,
                     timestamp: timestamp
                 },
                 success: function (res) {
@@ -1331,9 +1409,39 @@
             return this.formatTimestamp(this.timelineMeta.startTime + value, true);
         },
         handleCurrentDeviceDownload: function () {
-            this.doDownload(this.selectedDay, this.selectedType, this.selectedDeviceNo);
+            this.doDownload(this.selectedDay, this.selectedType, this.selectedDeviceNo, this.selectedStationId);
         },
-        doDownload: function (day, type, deviceNo) {
+        openSystemLogDialog: function () {
+            if (!this.selectedDay) {
+                this.$message.warning('璇峰厛閫夋嫨鏃ュ織鏃ユ湡');
+                return;
+            }
+            if (!this.systemLogRange || this.systemLogRange.length !== 2) {
+                var start = this.formatDayText(this.selectedDay) + ' 00:00:00';
+                var end = this.formatDayText(this.selectedDay) + ' 23:59:59';
+                this.systemLogRange = [start, end];
+            }
+            this.systemLogDialogVisible = true;
+        },
+        handleSystemLogDownload: function () {
+            if (!this.canDownloadSystemLog) {
+                this.$message.warning('璇烽�夋嫨鏃ュ織绫诲瀷鍜屾椂闂磋寖鍥�');
+                return;
+            }
+            var startTime = this.systemLogRange[0];
+            var endTime = this.systemLogRange[1];
+            if (!startTime || !endTime) {
+                this.$message.warning('璇烽�夋嫨瀹屾暣鏃堕棿鑼冨洿');
+                return;
+            }
+            if (new Date(startTime).getTime() > new Date(endTime).getTime()) {
+                this.$message.warning('寮�濮嬫椂闂翠笉鑳芥櫄浜庣粨鏉熸椂闂�');
+                return;
+            }
+            this.systemLogDialogVisible = false;
+            this.doSystemLogDownload(this.systemLogType, startTime, endTime);
+        },
+        doDownload: function (day, type, deviceNo, stationId) {
             if (!day || !type || !deviceNo) {
                 return;
             }
@@ -1345,7 +1453,8 @@
                 data: JSON.stringify({
                     day: day,
                     type: type,
-                    deviceNo: deviceNo
+                    deviceNo: deviceNo,
+                    stationId: stationId || undefined
                 }),
                 dataType: 'json',
                 contentType: 'application/json;charset=UTF-8',
@@ -1356,7 +1465,34 @@
                     }
                     var pid = res.data.progressId;
                     self.startDownloadProgress(pid);
-                    self.performDownloadRequest(day, type, deviceNo, pid);
+                    self.performDownloadRequest(day, type, deviceNo, stationId, pid);
+                },
+                error: function () {
+                    self.$message.error('鍒濆鍖栧け璐�');
+                }
+            });
+        },
+        doSystemLogDownload: function (logType, startTime, endTime) {
+            var self = this;
+            $.ajax({
+                url: baseUrl + '/deviceLog/system/download/init/auth',
+                headers: { token: localStorage.getItem('token') },
+                method: 'POST',
+                data: JSON.stringify({
+                    logType: logType,
+                    startTime: startTime,
+                    endTime: endTime
+                }),
+                dataType: 'json',
+                contentType: 'application/json;charset=UTF-8',
+                success: function (res) {
+                    if (!res || res.code !== 200) {
+                        self.$message.error((res && res.msg) || '鍒濆鍖栧け璐�');
+                        return;
+                    }
+                    var pid = res.data.progressId;
+                    self.startDownloadProgress(pid);
+                    self.performSystemLogDownloadRequest(logType, startTime, endTime, pid);
                 },
                 error: function () {
                     self.$message.error('鍒濆鍖栧け璐�');
@@ -1386,10 +1522,26 @@
                 });
             }, 500);
         },
-        performDownloadRequest: function (day, type, deviceNo, pid) {
+        performDownloadRequest: function (day, type, deviceNo, stationId, pid) {
+            var self = this;
+            var query = '?type=' + encodeURIComponent(type) + '&deviceNo=' + encodeURIComponent(deviceNo);
+            if (stationId) {
+                query += '&stationId=' + encodeURIComponent(stationId);
+            }
+            query += '&progressId=' + encodeURIComponent(pid);
+            this.performBlobDownload(baseUrl + '/deviceLog/day/' + day + '/download/auth' + query, type + '_' + deviceNo + '_' + day + '.zip', 'application/zip');
+        },
+        performSystemLogDownloadRequest: function (logType, startTime, endTime, pid) {
+            var query = '?logType=' + encodeURIComponent(logType)
+                + '&startTime=' + encodeURIComponent(startTime)
+                + '&endTime=' + encodeURIComponent(endTime)
+                + '&progressId=' + encodeURIComponent(pid);
+            this.performBlobDownload(baseUrl + '/deviceLog/system/download/auth' + query, logType + '_system_logs.zip', 'application/zip');
+        },
+        performBlobDownload: function (url, fallbackFilename, mimeType) {
             var self = this;
             $.ajax({
-                url: baseUrl + '/deviceLog/day/' + day + '/download/auth?type=' + encodeURIComponent(type) + '&deviceNo=' + encodeURIComponent(deviceNo) + '&progressId=' + encodeURIComponent(pid),
+                url: url,
                 headers: { token: localStorage.getItem('token') },
                 method: 'GET',
                 xhrFields: { responseType: 'blob' },
@@ -1404,22 +1556,22 @@
                 },
                 success: function (data, status, xhr) {
                     var disposition = xhr.getResponseHeader('Content-Disposition') || '';
-                    var filename = type + '_' + deviceNo + '_' + day + '.zip';
+                    var filename = fallbackFilename;
                     var match = /filename=(.+)/.exec(disposition);
                     if (match && match[1]) {
                         filename = decodeURIComponent(match[1]);
                     }
                     self.buildProgress = 100;
                     self.receiveProgress = 100;
-                    var blob = new Blob([data], { type: 'application/zip' });
+                    var blob = new Blob([data], { type: mimeType || 'application/octet-stream' });
                     var link = document.createElement('a');
-                    var url = window.URL.createObjectURL(blob);
-                    link.href = url;
+                    var objectUrl = window.URL.createObjectURL(blob);
+                    link.href = objectUrl;
                     link.download = filename;
                     document.body.appendChild(link);
                     link.click();
                     document.body.removeChild(link);
-                    window.URL.revokeObjectURL(url);
+                    window.URL.revokeObjectURL(objectUrl);
                     if (self.downloadTimer) {
                         clearInterval(self.downloadTimer);
                         self.downloadTimer = null;
@@ -1438,8 +1590,12 @@
                 }
             });
         },
-        buildDeviceKey: function (type, deviceNo) {
-            return String(type || '') + ':' + String(deviceNo || '');
+        buildDeviceKey: function (type, deviceNo, stationId) {
+            var key = String(type || '') + ':' + String(deviceNo || '');
+            if (String(type || '') === 'Devp') {
+                key += ':' + String(stationId || '');
+            }
+            return key;
         },
         parseDeviceNo: function (deviceNo) {
             var n = parseInt(deviceNo, 10);

--
Gitblit v1.9.1