| | |
| | | el: "#app", |
| | | data: function () { |
| | | return { |
| | | rawPayload: null, |
| | | loading: true, |
| | | refreshing: false, |
| | | switchingSystem: false, |
| | | countdown: REFRESH_SECONDS, |
| | | countdownTimer: null, |
| | | resizeHandler: null, |
| | |
| | | }, |
| | | mounted: function () { |
| | | var self = this; |
| | | this.refreshDocumentTitle(); |
| | | if (window.WCS_I18N && typeof window.WCS_I18N.onReady === "function") { |
| | | window.WCS_I18N.onReady(function () { |
| | | self.refreshLocalizedState(); |
| | | }); |
| | | } |
| | | this.$nextTick(function () { |
| | | self.initCharts(); |
| | | self.loadDashboard(false); |
| | |
| | | this.disposeCharts(); |
| | | }, |
| | | methods: { |
| | | formatMessage: function (text, params) { |
| | | var list = Array.isArray(params) ? params : [params]; |
| | | return String(text == null ? "" : text).replace(/\{(\d+)\}/g, function (match, index) { |
| | | return list[index] == null ? "" : list[index]; |
| | | }); |
| | | }, |
| | | i18n: function (key, fallback, params) { |
| | | if (window.WCS_I18N && typeof window.WCS_I18N.t === "function") { |
| | | var translated = window.WCS_I18N.t(key, params); |
| | | if (translated && translated !== key) { |
| | | return translated; |
| | | } |
| | | } |
| | | return this.formatMessage(fallback || key, params); |
| | | }, |
| | | translateLegacyText: function (text) { |
| | | if (text == null || text === "") { |
| | | return text; |
| | | } |
| | | if (window.WCS_I18N && typeof window.WCS_I18N.tl === "function") { |
| | | return window.WCS_I18N.tl(String(text)); |
| | | } |
| | | return text; |
| | | }, |
| | | getCurrentLocale: function () { |
| | | if (window.WCS_I18N && typeof window.WCS_I18N.getLocale === "function") { |
| | | return window.WCS_I18N.getLocale(); |
| | | } |
| | | return "zh-CN"; |
| | | }, |
| | | refreshDocumentTitle: function () { |
| | | document.title = this.i18n("dashboard.title", "系统仪表盘"); |
| | | }, |
| | | refreshLocalizedState: function () { |
| | | this.refreshDocumentTitle(); |
| | | if (this.rawPayload) { |
| | | this.applyData(this.rawPayload); |
| | | return; |
| | | } |
| | | this.$forceUpdate(); |
| | | this.updateCharts(); |
| | | }, |
| | | loadDashboard: function (manual) { |
| | | var self = this; |
| | | if (this.refreshing) { |
| | |
| | | self.countdown = REFRESH_SECONDS; |
| | | return; |
| | | } |
| | | self.$message.error((res && res.msg) || "仪表盘数据加载失败"); |
| | | self.$message.error((res && res.msg) || self.i18n("dashboard.loadFailed", "仪表盘数据加载失败")); |
| | | }, |
| | | error: function () { |
| | | if (manual) { |
| | | self.$message.error("仪表盘数据加载失败,请检查接口状态"); |
| | | self.$message.error(self.i18n("dashboard.loadFailedDetail", "仪表盘数据加载失败,请检查接口状态")); |
| | | } |
| | | }, |
| | | complete: function () { |
| | |
| | | }); |
| | | }, |
| | | applyData: function (payload) { |
| | | this.overview = payload.overview || this.overview; |
| | | this.tasks = payload.tasks || this.tasks; |
| | | this.devices = payload.devices || this.devices; |
| | | this.network = payload.network || this.network; |
| | | this.ai = payload.ai || this.ai; |
| | | var tasks = payload && payload.tasks ? payload.tasks : {}; |
| | | var devices = payload && payload.devices ? payload.devices : {}; |
| | | var network = payload && payload.network ? payload.network : {}; |
| | | var ai = payload && payload.ai ? payload.ai : {}; |
| | | |
| | | this.rawPayload = payload || {}; |
| | | this.refreshDocumentTitle(); |
| | | this.overview = payload && payload.overview ? payload.overview : this.overview; |
| | | this.tasks = { |
| | | overview: tasks.overview || this.tasks.overview, |
| | | directionStats: this.normalizeTaskDirectionMetrics(tasks.directionStats), |
| | | stageStats: this.normalizeTaskStageMetrics(tasks.stageStats), |
| | | statusStats: this.normalizeMetricList(tasks.statusStats), |
| | | recentTasks: this.normalizeRecentTasks(tasks.recentTasks) |
| | | }; |
| | | this.devices = { |
| | | overview: devices.overview || this.devices.overview, |
| | | typeStats: this.normalizeDeviceTypeStats(devices.typeStats) |
| | | }; |
| | | this.network = { |
| | | overview: network.overview || this.network.overview, |
| | | samplingConfig: network.samplingConfig || this.network.samplingConfig, |
| | | statusStats: this.normalizeNetworkStatusMetrics(network.statusStats), |
| | | focusDevices: this.normalizeFocusDevices(network.focusDevices) |
| | | }; |
| | | this.ai = { |
| | | overview: ai.overview || this.ai.overview, |
| | | routeStats: this.normalizeAiRouteStats(ai.routeStats), |
| | | routeList: this.normalizeAiRouteList(ai.routeList) |
| | | }; |
| | | this.updateCharts(); |
| | | }, |
| | | normalizeTaskDirectionMetrics: function (list) { |
| | | var self = this; |
| | | return cloneMetricList(list).map(function (item) { |
| | | var result = Object.assign({}, item); |
| | | if (item && item.name === "入库任务") { |
| | | result.name = self.i18n("dashboard.taskDirectionInbound", "入库任务"); |
| | | } else if (item && item.name === "出库任务") { |
| | | result.name = self.i18n("dashboard.taskDirectionOutbound", "出库任务"); |
| | | } else if (item && item.name === "移库任务") { |
| | | result.name = self.i18n("dashboard.taskDirectionMove", "移库任务"); |
| | | } else { |
| | | result.name = self.translateLegacyText(item && item.name); |
| | | } |
| | | return result; |
| | | }); |
| | | }, |
| | | normalizeTaskStageMetrics: function (list) { |
| | | var self = this; |
| | | return cloneMetricList(list).map(function (item) { |
| | | var result = Object.assign({}, item); |
| | | if (item && item.name === "执行中") { |
| | | result.name = self.i18n("dashboard.taskRunningLabel", "执行中"); |
| | | } else if (item && item.name === "待人工") { |
| | | result.name = self.i18n("dashboard.taskManualLabel", "待人工"); |
| | | } else if (item && item.name === "已完成") { |
| | | result.name = self.i18n("dashboard.taskCompletedLabel", "已完成"); |
| | | } else if (item && item.name === "新建") { |
| | | result.name = self.i18n("dashboard.taskNewLabel", "新建"); |
| | | } else { |
| | | result.name = self.translateLegacyText(item && item.name); |
| | | } |
| | | return result; |
| | | }); |
| | | }, |
| | | normalizeMetricList: function (list) { |
| | | var self = this; |
| | | return cloneMetricList(list).map(function (item) { |
| | | var result = Object.assign({}, item); |
| | | result.name = self.translateLegacyText(item && item.name); |
| | | return result; |
| | | }); |
| | | }, |
| | | normalizeRecentTasks: function (list) { |
| | | var self = this; |
| | | return cloneMetricList(list).map(function (item) { |
| | | var result = Object.assign({}, item); |
| | | result.taskType = self.translateLegacyText(item && item.taskType); |
| | | result.status = self.translateLegacyText(item && item.status); |
| | | result.source = self.translateLegacyText(item && item.source); |
| | | result.target = self.translateLegacyText(item && item.target); |
| | | result.device = self.translateLegacyText(item && item.device); |
| | | return result; |
| | | }); |
| | | }, |
| | | normalizeAiRouteStats: function (list) { |
| | | var self = this; |
| | | return cloneMetricList(list).map(function (item) { |
| | | var result = Object.assign({}, item); |
| | | if (item && item.name === "可用") { |
| | | result.name = self.i18n("dashboard.aiRouteStatusAvailable", "可用"); |
| | | } else if (item && item.name === "冷却中") { |
| | | result.name = self.i18n("dashboard.aiRouteStatusCooling", "冷却中"); |
| | | } else if (item && item.name === "已禁用") { |
| | | result.name = self.i18n("dashboard.aiRouteStatusDisabled", "已禁用"); |
| | | } else { |
| | | result.name = self.translateLegacyText(item && item.name); |
| | | } |
| | | return result; |
| | | }); |
| | | }, |
| | | normalizeNetworkStatusMetrics: function (list) { |
| | | var self = this; |
| | | return cloneMetricList(list).map(function (item) { |
| | | var result = Object.assign({}, item); |
| | | if (item && item.name === "正常") { |
| | | result.name = self.i18n("dashboard.networkOkLabel", "正常"); |
| | | } else if (item && item.name === "波动") { |
| | | result.name = self.i18n("dashboard.networkUnstableLabel", "波动"); |
| | | } else if (item && item.name === "超时/异常") { |
| | | result.name = self.i18n("dashboard.networkOfflineLabel", "超时/异常"); |
| | | } else if (item && item.name === "暂无数据") { |
| | | result.name = self.i18n("dashboard.networkNoDataLabel", "暂无数据"); |
| | | } else { |
| | | result.name = self.translateLegacyText(item && item.name); |
| | | } |
| | | return result; |
| | | }); |
| | | }, |
| | | normalizeDeviceTypeStats: function (list) { |
| | | var self = this; |
| | | return cloneMetricList(list).map(function (item) { |
| | | var result = Object.assign({}, item); |
| | | result.name = self.translateLegacyText(item && item.name); |
| | | return result; |
| | | }); |
| | | }, |
| | | normalizeAiRouteList: function (list) { |
| | | var self = this; |
| | | return cloneMetricList(list).map(function (item) { |
| | | var result = Object.assign({}, item); |
| | | if (result.statusType === "success") { |
| | | result.statusText = self.i18n("dashboard.aiRouteStatusAvailable", "可用"); |
| | | } else if (result.statusType === "warning") { |
| | | result.statusText = self.i18n("dashboard.aiRouteStatusCooling", "冷却中"); |
| | | } else { |
| | | result.statusText = self.i18n("dashboard.aiRouteStatusDisabled", "已禁用"); |
| | | } |
| | | result.lastError = self.translateLegacyText(item && item.lastError); |
| | | return result; |
| | | }); |
| | | }, |
| | | normalizeFocusDevices: function (list) { |
| | | var self = this; |
| | | return cloneMetricList(list).map(function (item) { |
| | | var result = Object.assign({}, item); |
| | | if (result.statusType === "success") { |
| | | result.statusText = self.i18n("dashboard.networkOkLabel", "正常"); |
| | | } else if (result.statusType === "warning") { |
| | | result.statusText = self.i18n("dashboard.networkUnstableLabel", "波动"); |
| | | } else if (result.statusType === "danger") { |
| | | result.statusText = self.i18n("dashboard.networkOfflineLabel", "超时/异常"); |
| | | } else { |
| | | result.statusText = self.i18n("dashboard.networkNoDataLabel", "暂无数据"); |
| | | } |
| | | result.message = self.translateLegacyText(item && item.message); |
| | | return result; |
| | | }); |
| | | }, |
| | | initCharts: function () { |
| | | this.disposeCharts(); |
| | |
| | | }, |
| | | buildDeviceTypeOption: function () { |
| | | var data = cloneMetricList(this.devices.typeStats); |
| | | var onlineText = this.i18n("dashboard.deviceOnlineLegend", "在线"); |
| | | var offlineText = this.i18n("dashboard.deviceOfflineLegend", "离线"); |
| | | return { |
| | | color: ["#2fa38e", "#d8e2ec"], |
| | | legend: { |
| | |
| | | itemWidth: 10, |
| | | itemHeight: 10, |
| | | textStyle: { color: "#60778d", fontSize: 12 }, |
| | | data: ["在线", "离线"] |
| | | data: [onlineText, offlineText] |
| | | }, |
| | | grid: { |
| | | left: 76, |
| | |
| | | axisLabel: { color: "#60778d", fontSize: 12 } |
| | | }, |
| | | series: [{ |
| | | name: "在线", |
| | | name: onlineText, |
| | | type: "bar", |
| | | stack: "device", |
| | | barWidth: 18, |
| | |
| | | borderRadius: [9, 0, 0, 9] |
| | | } |
| | | }, { |
| | | name: "离线", |
| | | name: offlineText, |
| | | type: "bar", |
| | | stack: "device", |
| | | barWidth: 18, |
| | |
| | | left: "center", |
| | | top: "55%", |
| | | style: { |
| | | text: "可用路由", |
| | | text: this.i18n("dashboard.chartCenter.availableRoutes", "可用路由"), |
| | | fill: "#7c8fa4", |
| | | fontSize: 12 |
| | | } |
| | |
| | | left: "center", |
| | | top: "54%", |
| | | style: { |
| | | text: "需关注设备", |
| | | text: this.i18n("dashboard.chartCenter.attentionDevices", "需关注设备"), |
| | | fill: "#7c8fa4", |
| | | fontSize: 12 |
| | | } |
| | |
| | | if (!isFinite(num)) { |
| | | return "0"; |
| | | } |
| | | return num.toLocaleString("zh-CN"); |
| | | return num.toLocaleString(this.getCurrentLocale()); |
| | | }, |
| | | formatLatency: function (value) { |
| | | var num; |
| | |
| | | if (!isFinite(num)) { |
| | | return "--"; |
| | | } |
| | | return num.toLocaleString("zh-CN", { maximumFractionDigits: 2 }) + " ms"; |
| | | return num.toLocaleString(this.getCurrentLocale(), { maximumFractionDigits: 2 }) + " ms"; |
| | | }, |
| | | formatPercentValue: function (value) { |
| | | var num = Number(value); |
| | | if (!isFinite(num)) { |
| | | return "--"; |
| | | } |
| | | return num.toLocaleString(this.getCurrentLocale(), { maximumFractionDigits: 2 }) + "%"; |
| | | }, |
| | | formatPacketSize: function (value) { |
| | | var num = Number(value); |
| | | if (!isFinite(num) || num < 0) { |
| | | return "系统默认"; |
| | | return this.i18n("dashboard.systemDefaultPacketSize", "系统默认"); |
| | | } |
| | | return num + " B"; |
| | | return num.toLocaleString(this.getCurrentLocale()) + " B"; |
| | | }, |
| | | displayText: function (value, fallback) { |
| | | return value == null || value === "" ? (fallback || "") : value; |
| | | }, |
| | | showMessage: function (message, type) { |
| | | if (this.$message && typeof this.$message === "function") { |
| | | this.$message({ |
| | | message: message, |
| | | type: type || "info" |
| | | }); |
| | | return; |
| | | } |
| | | console[type === "error" ? "error" : "log"](message); |
| | | }, |
| | | networkSamplingText: function () { |
| | | var config = this.network && this.network.samplingConfig ? this.network.samplingConfig : {}; |
| | | return "采样 " + this.displayText(config.intervalMs, 0) + " ms / 超时 " + this.displayText(config.timeoutMs, 0) + |
| | | " ms / 每样本 " + this.displayText(config.probeCount, 0) + " 次 / 包大小 " + this.formatPacketSize(config.packetSize); |
| | | return this.i18n("dashboard.networkSampling", "采样 {0} ms / 超时 {1} ms / 每样本 {2} 次 / 包大小 {3}", [ |
| | | this.displayText(config.intervalMs, 0), |
| | | this.displayText(config.timeoutMs, 0), |
| | | this.displayText(config.probeCount, 0), |
| | | this.formatPacketSize(config.packetSize) |
| | | ]); |
| | | }, |
| | | startAutoRefresh: function () { |
| | | var self = this; |
| | |
| | | window.open(targetMenu && targetMenu.url ? targetMenu.url : this.resolveAbsoluteViewPath(targetPath), "_blank"); |
| | | }, |
| | | openMonitor: function () { |
| | | this.openParentMenuView("/views/watch/console.html", "监控画面", "监控画面", "监控系统"); |
| | | this.openParentMenuView( |
| | | "/views/watch/console.html", |
| | | this.i18n("dashboard.monitorView", "监控画面"), |
| | | this.translateLegacyText("监控画面"), |
| | | this.translateLegacyText("监控系统") |
| | | ); |
| | | }, |
| | | syncParentSystemRunning: function (status) { |
| | | try { |
| | | if (window.parent && window.parent !== window) { |
| | | window.parent.systemRunning = !!status; |
| | | } |
| | | } catch (e) { |
| | | } |
| | | }, |
| | | requestSystemSwitch: function (operatorType, password) { |
| | | var self = this; |
| | | this.switchingSystem = true; |
| | | $.ajax({ |
| | | url: baseUrl + "/console/system/switch", |
| | | headers: { |
| | | token: localStorage.getItem("token") |
| | | }, |
| | | data: { |
| | | operatorType: operatorType, |
| | | password: password || "" |
| | | }, |
| | | method: "POST", |
| | | success: function (res) { |
| | | var status; |
| | | if (res && res.code === 200) { |
| | | status = !!(res.data && res.data.status); |
| | | self.overview = Object.assign({}, self.overview, { |
| | | systemRunning: status |
| | | }); |
| | | self.syncParentSystemRunning(status); |
| | | self.showMessage( |
| | | status |
| | | ? self.i18n("dashboard.systemStarted", "系统已启动") |
| | | : self.i18n("dashboard.systemStopped", "系统已停止"), |
| | | "success" |
| | | ); |
| | | self.loadDashboard(false); |
| | | return; |
| | | } |
| | | if (res && res.code === 403) { |
| | | window.location.href = baseUrl + "/login"; |
| | | return; |
| | | } |
| | | self.showMessage( |
| | | (res && res.msg) || self.i18n("dashboard.systemSwitchFailed", "系统状态切换失败"), |
| | | "error" |
| | | ); |
| | | }, |
| | | error: function () { |
| | | self.showMessage( |
| | | self.i18n("dashboard.systemSwitchFailedDetail", "系统状态切换失败,请检查接口状态"), |
| | | "error" |
| | | ); |
| | | }, |
| | | complete: function () { |
| | | self.switchingSystem = false; |
| | | } |
| | | }); |
| | | }, |
| | | startSystem: function () { |
| | | if (this.overview.systemRunning || this.switchingSystem) { |
| | | return; |
| | | } |
| | | this.requestSystemSwitch(1); |
| | | }, |
| | | maskStopSystemPromptInput: function () { |
| | | setTimeout(function () { |
| | | var input = document.querySelector(".el-message-box__wrapper .el-message-box__input input"); |
| | | if (!input) { |
| | | return; |
| | | } |
| | | input.setAttribute("type", "text"); |
| | | input.setAttribute("name", "dashboard-stop-code"); |
| | | input.setAttribute("autocomplete", "new-password"); |
| | | input.setAttribute("autocapitalize", "off"); |
| | | input.setAttribute("autocorrect", "off"); |
| | | input.setAttribute("spellcheck", "false"); |
| | | input.setAttribute("data-form-type", "other"); |
| | | input.style.webkitTextSecurity = "disc"; |
| | | }, 30); |
| | | }, |
| | | stopSystem: function () { |
| | | var self = this; |
| | | var proceed = function (password) { |
| | | var cleanPassword = String(password == null ? "" : password).trim(); |
| | | if (!cleanPassword) { |
| | | self.showMessage(self.i18n("dashboard.stopSystemPasswordRequired", "请输入停止系统口令"), "warning"); |
| | | return; |
| | | } |
| | | self.requestSystemSwitch(0, cleanPassword); |
| | | }; |
| | | |
| | | if (!this.overview.systemRunning || this.switchingSystem) { |
| | | return; |
| | | } |
| | | |
| | | if (typeof this.$prompt === "function") { |
| | | this.$prompt( |
| | | this.i18n("dashboard.stopSystemPrompt", "请输入口令,并停止 WCS 系统"), |
| | | this.i18n("dashboard.stopSystemTitle", "停止系统"), |
| | | { |
| | | confirmButtonText: this.i18n("common.confirm", "确定"), |
| | | cancelButtonText: this.i18n("common.cancel", "取消"), |
| | | inputType: "text", |
| | | inputPattern: /\S+/, |
| | | inputErrorMessage: this.i18n("dashboard.stopSystemPasswordRequired", "请输入停止系统口令") |
| | | } |
| | | ).then(function (result) { |
| | | proceed(result && result.value); |
| | | }).catch(function () { |
| | | }); |
| | | this.maskStopSystemPromptInput(); |
| | | return; |
| | | } |
| | | |
| | | proceed(window.prompt(this.i18n("dashboard.stopSystemPrompt", "请输入口令,并停止 WCS 系统"), "")); |
| | | }, |
| | | toggleSystem: function () { |
| | | if (this.overview.systemRunning) { |
| | | this.stopSystem(); |
| | | return; |
| | | } |
| | | this.startSystem(); |
| | | }, |
| | | openDevicePingAnalysis: function () { |
| | | this.openParentMenuView("/views/devicePingLog/devicePingLog.html", "设备网络分析", "设备网络分析"); |
| | | this.openParentMenuView( |
| | | "/views/devicePingLog/devicePingLog.html", |
| | | this.i18n("devicePingLog.title", "设备网络分析"), |
| | | this.translateLegacyText("设备网络分析") |
| | | ); |
| | | } |
| | | } |
| | | }); |