|
@@ -27,6 +27,17 @@
|
|
|
</button>
|
|
</button>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="anomaly-detail-filters">
|
|
<div class="anomaly-detail-filters">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-if="displayFieldName || displayMachineType"
|
|
|
|
|
+ class="anomaly-detail-meta"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span v-if="displayFieldName" class="anomaly-detail-meta__item">
|
|
|
|
|
+ 风场名:{{ displayFieldName }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <span v-if="displayMachineType" class="anomaly-detail-meta__item">
|
|
|
|
|
+ 机型:{{ displayMachineType }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
<label class="anomaly-detail-filter">
|
|
<label class="anomaly-detail-filter">
|
|
|
风机:
|
|
风机:
|
|
|
<el-select
|
|
<el-select
|
|
@@ -91,15 +102,33 @@
|
|
|
</div>
|
|
</div>
|
|
|
<div class="anomaly-detail-toggle">
|
|
<div class="anomaly-detail-toggle">
|
|
|
<span
|
|
<span
|
|
|
- :class="{ active: trendRange[mod.key] === 7 }"
|
|
|
|
|
- @click="setTrendRange(mod.key, 7)"
|
|
|
|
|
- >近7天</span
|
|
|
|
|
|
|
+ v-for="preset in trendPresets"
|
|
|
|
|
+ :key="preset"
|
|
|
|
|
+ :class="{
|
|
|
|
|
+ active:
|
|
|
|
|
+ trendRange[mod.key] === preset &&
|
|
|
|
|
+ !isCustomTrend(mod.key),
|
|
|
|
|
+ }"
|
|
|
|
|
+ @click="setTrendRange(mod.key, preset)"
|
|
|
>
|
|
>
|
|
|
|
|
+ 近{{ preset }}天
|
|
|
|
|
+ </span>
|
|
|
<span
|
|
<span
|
|
|
- :class="{ active: trendRange[mod.key] === 30 }"
|
|
|
|
|
- @click="setTrendRange(mod.key, 30)"
|
|
|
|
|
- >近30天</span
|
|
|
|
|
|
|
+ :class="{ active: isCustomTrend(mod.key) }"
|
|
|
|
|
+ @click="openCustomTrend(mod.key)"
|
|
|
>
|
|
>
|
|
|
|
|
+ 自定义
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-if="isCustomTrend(mod.key)"
|
|
|
|
|
+ :value="trendRange[mod.key]"
|
|
|
|
|
+ :min="1"
|
|
|
|
|
+ :max="MAX_TREND_DAYS"
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ controls-position="right"
|
|
|
|
|
+ class="anomaly-detail-trend-custom"
|
|
|
|
|
+ @change="(val) => setCustomTrendRange(mod.key, val)"
|
|
|
|
|
+ />
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div
|
|
<div
|
|
@@ -180,6 +209,9 @@ const MODULE_DETAIL_TABS = [
|
|
|
},
|
|
},
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
|
|
+const TREND_PRESETS = [7, 30, 90];
|
|
|
|
|
+const MAX_TREND_DAYS = 90;
|
|
|
|
|
+
|
|
|
function emptyModuleData() {
|
|
function emptyModuleData() {
|
|
|
return {
|
|
return {
|
|
|
items: [],
|
|
items: [],
|
|
@@ -195,8 +227,10 @@ export default {
|
|
|
activeTab: "all",
|
|
activeTab: "all",
|
|
|
fieldCode: "",
|
|
fieldCode: "",
|
|
|
fieldId: "",
|
|
fieldId: "",
|
|
|
|
|
+ fieldName: "",
|
|
|
engineId: "",
|
|
engineId: "",
|
|
|
engineName: "",
|
|
engineName: "",
|
|
|
|
|
+ machineType: "",
|
|
|
datatime: "",
|
|
datatime: "",
|
|
|
moduleTabs: [
|
|
moduleTabs: [
|
|
|
{ key: "all", label: "异常趋势总览" },
|
|
{ key: "all", label: "异常趋势总览" },
|
|
@@ -211,6 +245,12 @@ export default {
|
|
|
acc[mod.key] = 7;
|
|
acc[mod.key] = 7;
|
|
|
return acc;
|
|
return acc;
|
|
|
}, {}),
|
|
}, {}),
|
|
|
|
|
+ trendCustom: MODULE_DETAIL_TABS.reduce((acc, mod) => {
|
|
|
|
|
+ acc[mod.key] = false;
|
|
|
|
|
+ return acc;
|
|
|
|
|
+ }, {}),
|
|
|
|
|
+ trendPresets: TREND_PRESETS,
|
|
|
|
|
+ MAX_TREND_DAYS,
|
|
|
engineOptions: [],
|
|
engineOptions: [],
|
|
|
windCards: [],
|
|
windCards: [],
|
|
|
trendCache: {},
|
|
trendCache: {},
|
|
@@ -218,6 +258,27 @@ export default {
|
|
|
overviewCharts: {},
|
|
overviewCharts: {},
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
|
|
+ computed: {
|
|
|
|
|
+ selectedWindCard() {
|
|
|
|
|
+ return (
|
|
|
|
|
+ this.windCards.find((card) => card.engineId === this.engineId) || null
|
|
|
|
|
+ );
|
|
|
|
|
+ },
|
|
|
|
|
+ displayFieldName() {
|
|
|
|
|
+ return (
|
|
|
|
|
+ this.selectedWindCard?.fieldName ||
|
|
|
|
|
+ this.fieldName ||
|
|
|
|
|
+ ""
|
|
|
|
|
+ );
|
|
|
|
|
+ },
|
|
|
|
|
+ displayMachineType() {
|
|
|
|
|
+ return (
|
|
|
|
|
+ this.selectedWindCard?.machineType ||
|
|
|
|
|
+ this.machineType ||
|
|
|
|
|
+ ""
|
|
|
|
|
+ );
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
created() {
|
|
created() {
|
|
|
this.initFromRoute();
|
|
this.initFromRoute();
|
|
|
this.bootstrap();
|
|
this.bootstrap();
|
|
@@ -237,8 +298,10 @@ export default {
|
|
|
const q = this.$route.query || {};
|
|
const q = this.$route.query || {};
|
|
|
this.fieldCode = q.fieldCode || "";
|
|
this.fieldCode = q.fieldCode || "";
|
|
|
this.fieldId = q.fieldId || q.fieldCode || "";
|
|
this.fieldId = q.fieldId || q.fieldCode || "";
|
|
|
|
|
+ this.fieldName = q.fieldName || "";
|
|
|
this.engineId = q.engineId || "";
|
|
this.engineId = q.engineId || "";
|
|
|
this.engineName = q.engineName || "";
|
|
this.engineName = q.engineName || "";
|
|
|
|
|
+ this.machineType = q.machineType || "";
|
|
|
this.datatime = q.datatime || "";
|
|
this.datatime = q.datatime || "";
|
|
|
if (q.tab === "all") {
|
|
if (q.tab === "all") {
|
|
|
this.activeTab = "all";
|
|
this.activeTab = "all";
|
|
@@ -289,6 +352,9 @@ export default {
|
|
|
if (!this.fieldId && windCards[0]?.fieldId) {
|
|
if (!this.fieldId && windCards[0]?.fieldId) {
|
|
|
this.fieldId = windCards[0].fieldId;
|
|
this.fieldId = windCards[0].fieldId;
|
|
|
}
|
|
}
|
|
|
|
|
+ const selected = this.selectedWindCard;
|
|
|
|
|
+ if (selected?.fieldName) this.fieldName = selected.fieldName;
|
|
|
|
|
+ if (selected?.machineType) this.machineType = selected.machineType;
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error("加载风机下拉列表失败:", error);
|
|
console.error("加载风机下拉列表失败:", error);
|
|
|
this.engineOptions = this.engineId
|
|
this.engineOptions = this.engineId
|
|
@@ -309,13 +375,37 @@ export default {
|
|
|
this.trendCache = {};
|
|
this.trendCache = {};
|
|
|
},
|
|
},
|
|
|
getSelectedWindCard() {
|
|
getSelectedWindCard() {
|
|
|
- return (
|
|
|
|
|
- this.windCards.find((card) => card.engineId === this.engineId) || null
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ return this.selectedWindCard;
|
|
|
},
|
|
},
|
|
|
getTrendCacheKey(moduleKey, range) {
|
|
getTrendCacheKey(moduleKey, range) {
|
|
|
return `${moduleKey}:${range}`;
|
|
return `${moduleKey}:${range}`;
|
|
|
},
|
|
},
|
|
|
|
|
+ normalizeTrendDays(days) {
|
|
|
|
|
+ const num = Number(days);
|
|
|
|
|
+ if (!Number.isFinite(num)) return 7;
|
|
|
|
|
+ return Math.min(MAX_TREND_DAYS, Math.max(1, Math.round(num)));
|
|
|
|
|
+ },
|
|
|
|
|
+ isCustomTrend(moduleKey) {
|
|
|
|
|
+ return !!this.trendCustom[moduleKey];
|
|
|
|
|
+ },
|
|
|
|
|
+ openCustomTrend(moduleKey) {
|
|
|
|
|
+ this.$set(this.trendCustom, moduleKey, true);
|
|
|
|
|
+ if (TREND_PRESETS.includes(this.trendRange[moduleKey])) {
|
|
|
|
|
+ this.$set(this.trendRange, moduleKey, this.trendRange[moduleKey]);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ async setCustomTrendRange(moduleKey, days) {
|
|
|
|
|
+ const range = this.normalizeTrendDays(days);
|
|
|
|
|
+ this.$set(this.trendCustom, moduleKey, true);
|
|
|
|
|
+ if (this.trendRange[moduleKey] === range) {
|
|
|
|
|
+ await this.fetchOverviewTrend(moduleKey, range);
|
|
|
|
|
+ this.renderOverviewChart(moduleKey);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.$set(this.trendRange, moduleKey, range);
|
|
|
|
|
+ await this.fetchOverviewTrend(moduleKey, range);
|
|
|
|
|
+ this.renderOverviewChart(moduleKey);
|
|
|
|
|
+ },
|
|
|
async fetchOverviewTrend(moduleKey, range) {
|
|
async fetchOverviewTrend(moduleKey, range) {
|
|
|
const cacheKey = this.getTrendCacheKey(moduleKey, range);
|
|
const cacheKey = this.getTrendCacheKey(moduleKey, range);
|
|
|
if (this.trendCache[cacheKey]) {
|
|
if (this.trendCache[cacheKey]) {
|
|
@@ -353,7 +443,6 @@ export default {
|
|
|
renderPieChart() {
|
|
renderPieChart() {
|
|
|
if (!this.pieChart) return;
|
|
if (!this.pieChart) return;
|
|
|
const pieData = mapWindCardToPieData(this.getSelectedWindCard());
|
|
const pieData = mapWindCardToPieData(this.getSelectedWindCard());
|
|
|
- console.log(pieData, "pieData");
|
|
|
|
|
this.pieChart.setOption(buildPieOption(pieData), true);
|
|
this.pieChart.setOption(buildPieOption(pieData), true);
|
|
|
},
|
|
},
|
|
|
applyMockModuleData() {
|
|
applyMockModuleData() {
|
|
@@ -424,12 +513,20 @@ export default {
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
async setTrendRange(moduleKey, range) {
|
|
async setTrendRange(moduleKey, range) {
|
|
|
- if (this.trendRange[moduleKey] === range) return;
|
|
|
|
|
- this.trendRange[moduleKey] = range;
|
|
|
|
|
- await this.fetchOverviewTrend(moduleKey, range);
|
|
|
|
|
|
|
+ const days = this.normalizeTrendDays(range);
|
|
|
|
|
+ this.$set(this.trendCustom, moduleKey, false);
|
|
|
|
|
+ if (this.trendRange[moduleKey] === days) {
|
|
|
|
|
+ this.renderOverviewChart(moduleKey);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.$set(this.trendRange, moduleKey, days);
|
|
|
|
|
+ await this.fetchOverviewTrend(moduleKey, days);
|
|
|
this.renderOverviewChart(moduleKey);
|
|
this.renderOverviewChart(moduleKey);
|
|
|
},
|
|
},
|
|
|
handleEngineChange() {
|
|
handleEngineChange() {
|
|
|
|
|
+ const selected = this.selectedWindCard;
|
|
|
|
|
+ if (selected?.fieldName) this.fieldName = selected.fieldName;
|
|
|
|
|
+ if (selected?.machineType) this.machineType = selected.machineType;
|
|
|
this.fetchAll();
|
|
this.fetchAll();
|
|
|
},
|
|
},
|
|
|
async handleDatatimeChange() {
|
|
async handleDatatimeChange() {
|