#
Junjie
昨天 7a0470e331a978ee206cd8fcf3dfd5642f14eb83
src/main/webapp/static/js/devicePingLog/devicePingLog.js
@@ -49,6 +49,9 @@
    el: "#app",
    data: function () {
      return {
        lastOptionsData: null,
        lastOverviewData: null,
        lastTrendData: null,
        overviewLoading: false,
        detailLoading: false,
        devices: [],
@@ -111,11 +114,21 @@
      },
      samplingConfigText: function () {
        var config = this.samplingConfig || createEmptySamplingConfig();
        return "采样 " + config.intervalMs + " ms / 超时 " + config.timeoutMs + " ms / 每样本 " + config.probeCount + " 次";
        return this.i18n("devicePingLog.samplingConfigText", "采样 {0} ms / 超时 {1} ms / 每样本 {2} 次", [
          this.formatNumber(config.intervalMs),
          this.formatNumber(config.timeoutMs),
          this.formatNumber(config.probeCount)
        ]);
      }
    },
    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.loadOptions();
        self.loadOverview();
@@ -132,6 +145,126 @@
      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("devicePingLog.title", "设备网络分析");
      },
      refreshLocalizedState: function () {
        this.refreshDocumentTitle();
        if (this.lastOptionsData) {
          this.applyOptionsData(this.lastOptionsData);
        }
        if (this.lastOverviewData) {
          this.applyOverviewData(this.lastOverviewData);
        }
        if (this.lastTrendData) {
          this.applyTrendData(this.lastTrendData);
        } else {
          this.$forceUpdate();
          this.updateCharts();
        }
      },
      resolveStatusText: function (status) {
        var code = status == null ? "" : String(status).toUpperCase();
        if (code === "OK") {
          return this.i18n("devicePingLog.status.ok", "正常");
        }
        if (code === "UNSTABLE") {
          return this.i18n("devicePingLog.status.unstable", "波动");
        }
        if (code === "TIMEOUT") {
          return this.i18n("devicePingLog.status.timeout", "超时");
        }
        if (code === "ERROR") {
          return this.i18n("devicePingLog.status.error", "异常");
        }
        if (code === "NO_DATA") {
          return this.i18n("devicePingLog.status.noData", "暂无数据");
        }
        if (!code) {
          return "--";
        }
        return this.translateLegacyText(status);
      },
      applyOptionsData: function (data) {
        this.lastOptionsData = data || {};
        this.refreshDocumentTitle();
        this.devices = (data && data.devices) || [];
        this.availableDays = (data && data.days) || [];
        this.samplingConfig = Object.assign(createEmptySamplingConfig(), data && data.samplingConfig ? data.samplingConfig : {});
      },
      applyOverviewData: function (data) {
        this.lastOverviewData = data || {};
        this.overviewSummary = Object.assign(createEmptyOverviewSummary(), data && data.summary ? data.summary : {});
        this.overviewRows = this.normalizeOverviewRows(data && data.devices ? data.devices : []);
      },
      applyTrendData: function (data) {
        this.lastTrendData = data || {};
        this.detailSummary = this.normalizeDetailSummary(data && data.summary ? data.summary : {});
        this.series = (data && data.series) || [];
        this.alerts = this.normalizeAlerts(data && data.alerts ? data.alerts : []);
        this.updateCharts();
      },
      normalizeOverviewRows: function (rows) {
        var self = this;
        return (rows || []).map(function (item) {
          var result = Object.assign({}, item);
          result.statusText = self.resolveStatusText(item && item.status);
          result.message = self.translateLegacyText(item && item.message);
          result.label = self.translateLegacyText(item && item.label);
          return result;
        });
      },
      normalizeDetailSummary: function (summary) {
        var result = Object.assign(createEmptyDetailSummary(), summary || {});
        result.latestStatus = this.resolveStatusText(result.latestStatus);
        return result;
      },
      normalizeAlerts: function (alerts) {
        var self = this;
        return (alerts || []).map(function (item) {
          var result = Object.assign({}, item);
          result.status = self.resolveStatusText(item && item.status);
          result.message = self.translateLegacyText(item && item.message);
          return result;
        });
      },
      formatNumber: function (value) {
        var num = Number(value || 0);
        if (!isFinite(num)) {
          return "0";
        }
        return num.toLocaleString(this.getCurrentLocale());
      },
      loadOptions: function () {
        var self = this;
        $.ajax({
@@ -141,15 +274,13 @@
          success: function (res) {
            if (res && res.code === 200) {
              var data = res.data || {};
              self.devices = data.devices || [];
              self.availableDays = data.days || [];
              self.samplingConfig = Object.assign(createEmptySamplingConfig(), data.samplingConfig || {});
              self.applyOptionsData(data);
              return;
            }
            self.$message.error((res && res.msg) || "设备配置加载失败");
            self.$message.error((res && res.msg) || self.i18n("devicePingLog.optionsLoadFailed", "设备配置加载失败"));
          },
          error: function () {
            self.$message.error("设备配置加载失败");
            self.$message.error(self.i18n("devicePingLog.optionsLoadFailed", "设备配置加载失败"));
          }
        });
      },
@@ -162,19 +293,17 @@
          method: "GET",
          success: function (res) {
            if (res && res.code === 200) {
              var data = res.data || {};
              self.overviewSummary = Object.assign(createEmptyOverviewSummary(), data.summary || {});
              self.overviewRows = data.devices || [];
              self.applyOverviewData(res.data || {});
              return;
            }
            self.overviewSummary = createEmptyOverviewSummary();
            self.overviewRows = [];
            self.$message.error((res && res.msg) || "总览数据加载失败");
            self.$message.error((res && res.msg) || self.i18n("devicePingLog.overviewLoadFailed", "总览数据加载失败"));
          },
          error: function () {
            self.overviewSummary = createEmptyOverviewSummary();
            self.overviewRows = [];
            self.$message.error("总览数据加载失败");
            self.$message.error(self.i18n("devicePingLog.overviewLoadFailed", "总览数据加载失败"));
          },
          complete: function () {
            self.overviewLoading = false;
@@ -204,12 +333,12 @@
          return;
        }
        if (!this.detailFilters.range || this.detailFilters.range.length !== 2) {
          this.$message.warning("请选择时间范围");
          this.$message.warning(this.i18n("devicePingLog.selectTimeRange", "请选择时间范围"));
          return;
        }
        var parts = this.detailFilters.deviceKey.split("#");
        if (parts.length !== 2) {
          this.$message.warning("设备信息无效");
          this.$message.warning(this.i18n("devicePingLog.invalidDevice", "设备信息无效"));
          return;
        }
        var self = this;
@@ -226,25 +355,21 @@
          },
          success: function (res) {
            if (res && res.code === 200) {
              var data = res.data || {};
              self.detailSummary = Object.assign(createEmptyDetailSummary(), data.summary || {});
              self.series = data.series || [];
              self.alerts = data.alerts || [];
              self.updateCharts();
              self.applyTrendData(res.data || {});
              return;
            }
            self.detailSummary = createEmptyDetailSummary();
            self.series = [];
            self.alerts = [];
            self.updateCharts();
            self.$message.error((res && res.msg) || "设备详情加载失败");
            self.$message.error((res && res.msg) || self.i18n("devicePingLog.detailLoadFailed", "设备详情加载失败"));
          },
          error: function () {
            self.detailSummary = createEmptyDetailSummary();
            self.series = [];
            self.alerts = [];
            self.updateCharts();
            self.$message.error("设备详情加载失败");
            self.$message.error(self.i18n("devicePingLog.detailLoadFailed", "设备详情加载失败"));
          },
          complete: function () {
            self.detailLoading = false;
@@ -336,21 +461,21 @@
            bottom: 10
          }],
          series: [{
            name: "平均",
            name: this.i18n("devicePingLog.chart.latency.avg", "平均"),
            type: "line",
            showSymbol: false,
            sampling: "lttb",
            data: this.series.map(function (item) { return item.avgLatencyMs; }),
            lineStyle: { width: 2 }
          }, {
            name: "最小",
            name: this.i18n("devicePingLog.chart.latency.min", "最小"),
            type: "line",
            showSymbol: false,
            sampling: "lttb",
            data: this.series.map(function (item) { return item.minLatencyMs; }),
            lineStyle: { width: 1.5 }
          }, {
            name: "最大",
            name: this.i18n("devicePingLog.chart.latency.max", "最大"),
            type: "line",
            showSymbol: false,
            sampling: "lttb",
@@ -389,14 +514,14 @@
          },
          yAxis: [{
            type: "value",
            name: "失败",
            name: this.i18n("devicePingLog.chart.availability.failAxis", "失败"),
            splitLine: { lineStyle: { color: "#edf2f7" } },
            axisLine: { show: false },
            axisTick: { show: false },
            axisLabel: { color: "#7f92a5" }
          }, {
            type: "value",
            name: "成功率%",
            name: this.i18n("devicePingLog.chart.availability.successRateAxis", "成功率%"),
            min: 0,
            max: 100,
            splitLine: { show: false },
@@ -412,7 +537,7 @@
            bottom: 10
          }],
          series: [{
            name: "失败次数",
            name: this.i18n("devicePingLog.chart.availability.failCount", "失败次数"),
            type: "bar",
            yAxisIndex: 0,
            barMaxWidth: 18,
@@ -421,7 +546,7 @@
              borderRadius: [6, 6, 0, 0]
            }
          }, {
            name: "成功率",
            name: this.i18n("devicePingLog.chart.availability.successRate", "成功率"),
            type: "line",
            yAxisIndex: 1,
            showSymbol: false,
@@ -444,22 +569,33 @@
        return "offline";
      },
      formatLatency: function (value) {
        var num;
        if (value === null || value === undefined || value === "") {
          return "--";
        }
        return value + " ms";
        num = Number(value);
        if (!isFinite(num)) {
          return "--";
        }
        return num.toLocaleString(this.getCurrentLocale(), { maximumFractionDigits: 2 }) + " ms";
      },
      formatPercent: function (value) {
        var num;
        if (value === null || value === undefined || value === "") {
          return "--";
        }
        return value + "%";
        num = Number(value);
        if (!isFinite(num)) {
          return "--";
        }
        return num.toLocaleString(this.getCurrentLocale(), { maximumFractionDigits: 2 }) + "%";
      },
      formatPacketSize: function (value) {
        if (value === null || value === undefined || value === "" || value < 0) {
          return "系统默认";
        var num = Number(value);
        if (!isFinite(num) || num < 0) {
          return this.i18n("devicePingLog.systemDefaultPacketSize", "系统默认");
        }
        return value + " B";
        return num.toLocaleString(this.getCurrentLocale()) + " B";
      }
    }
  });