重构
This commit is contained in:
@ -51,15 +51,33 @@
|
||||
<el-descriptions-item
|
||||
contentClassName="descriptions-direction work-status"
|
||||
:span="1" label="工作状态">
|
||||
{{ CLUSTERWorkStatusOptions[baseInfo.workStatus] || '-' }}
|
||||
<span
|
||||
class="pointer"
|
||||
:class="{ 'field-disabled': !hasFieldPointId(baseInfo, 'workStatus') }"
|
||||
@click="handleFieldClick(baseInfo, 'workStatus', '工作状态')"
|
||||
>
|
||||
{{ CLUSTERWorkStatusOptions[baseInfo.workStatus] || '-' }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item contentClassName="descriptions-direction"
|
||||
:span="1" label="与PCS通信">
|
||||
{{ (($store.state.ems && $store.state.ems.communicationStatusOptions) || {})[baseInfo.pcsCommunicationStatus] || '-' }}
|
||||
<span
|
||||
class="pointer"
|
||||
:class="{ 'field-disabled': !hasFieldPointId(baseInfo, 'pcsCommunicationStatus') }"
|
||||
@click="handleFieldClick(baseInfo, 'pcsCommunicationStatus', '与PCS通信')"
|
||||
>
|
||||
{{ (($store.state.ems && $store.state.ems.communicationStatusOptions) || {})[baseInfo.pcsCommunicationStatus] || '-' }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item contentClassName="descriptions-direction"
|
||||
:span="1" label="与EMS通信">
|
||||
{{ (($store.state.ems && $store.state.ems.communicationStatusOptions) || {})[baseInfo.emsCommunicationStatus] || '-' }}
|
||||
<span
|
||||
class="pointer"
|
||||
:class="{ 'field-disabled': !hasFieldPointId(baseInfo, 'emsCommunicationStatus') }"
|
||||
@click="handleFieldClick(baseInfo, 'emsCommunicationStatus', '与EMS通信')"
|
||||
>
|
||||
{{ (($store.state.ems && $store.state.ems.communicationStatusOptions) || {})[baseInfo.emsCommunicationStatus] || '-' }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
@ -68,7 +86,11 @@
|
||||
<el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction"
|
||||
v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :span="1"
|
||||
:label="item.label">
|
||||
<span class="pointer" @click="showChart(item.pointName || '',baseInfo.deviceId)">
|
||||
<span
|
||||
class="pointer"
|
||||
:class="{ 'field-disabled': !hasFieldPointId(baseInfo, item.attr) }"
|
||||
@click="handleFieldClick(baseInfo, item.attr, item.label)"
|
||||
>
|
||||
<i v-if="isPointLoading(baseInfo[item.attr])" class="el-icon-loading point-loading-icon"></i>
|
||||
<span v-else>{{ displayValue(baseInfo[item.attr]) | formatNumber }}</span>
|
||||
<span v-if="item.unit" v-html="item.unit"></span>
|
||||
@ -80,7 +102,11 @@
|
||||
<div class="process-line-bg">
|
||||
<div class="process-line" :style="{height:baseInfo.currentSoc+'%'}"></div>
|
||||
</div>
|
||||
<div class="process pointer" @click="showChart( '当前SOC',baseInfo.deviceId)">当前SOC :
|
||||
<div
|
||||
class="process pointer"
|
||||
:class="{ 'field-disabled': !hasFieldPointId(baseInfo, 'currentSoc') }"
|
||||
@click="handleFieldClick(baseInfo, 'currentSoc', '当前SOC')"
|
||||
>当前SOC :
|
||||
{{ baseInfo.currentSoc }}%
|
||||
</div>
|
||||
</div>
|
||||
@ -103,7 +129,8 @@
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer"
|
||||
@click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],baseInfo.deviceId)">{{
|
||||
:class="{ 'field-disabled': !hasTableFieldPointId(baseInfo, scope.row.dataName, scope.column.label) }"
|
||||
@click="handleTableFieldClick(baseInfo, scope.row.dataName, scope.column.label)">{{
|
||||
scope.row.avgData
|
||||
}}</span>
|
||||
</template>
|
||||
@ -113,7 +140,8 @@
|
||||
label="单体最小值">
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer"
|
||||
@click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],baseInfo.deviceId)">{{
|
||||
:class="{ 'field-disabled': !hasTableFieldPointId(baseInfo, scope.row.dataName, scope.column.label) }"
|
||||
@click="handleTableFieldClick(baseInfo, scope.row.dataName, scope.column.label)">{{
|
||||
scope.row.minData
|
||||
}}</span>
|
||||
</template>
|
||||
@ -127,7 +155,8 @@
|
||||
label="单体最大值">
|
||||
<template slot-scope="scope">
|
||||
<span class="pointer "
|
||||
@click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],baseInfo.deviceId)">{{
|
||||
:class="{ 'field-disabled': !hasTableFieldPointId(baseInfo, scope.row.dataName, scope.column.label) }"
|
||||
@click="handleTableFieldClick(baseInfo, scope.row.dataName, scope.column.label)">{{
|
||||
scope.row.maxData
|
||||
}}</span>
|
||||
</template>
|
||||
@ -139,24 +168,49 @@
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
<point-chart ref="pointChart" :site-id="siteId"/>
|
||||
<point-table ref="pointTable"/>
|
||||
<el-dialog
|
||||
:visible.sync="curveDialogVisible"
|
||||
:title="curveDialogTitle"
|
||||
width="1000px"
|
||||
append-to-body
|
||||
class="ems-dialog"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
@opened="handleCurveDialogOpened"
|
||||
@closed="handleCurveDialogClosed"
|
||||
>
|
||||
<div class="curve-tools">
|
||||
<el-date-picker
|
||||
v-model="curveCustomRange"
|
||||
type="datetimerange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
style="width: 440px"
|
||||
/>
|
||||
<el-button type="primary" size="mini" :loading="curveLoading" @click="loadCurveData">查询</el-button>
|
||||
</div>
|
||||
<div v-loading="curveLoading" ref="curveChartRef" style="height: 380px;"></div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import pointChart from "./../PointChart.vue";
|
||||
import * as echarts from "echarts";
|
||||
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
|
||||
import {getProjectDisplayData, getStackNameList, getClusterNameList} from '@/api/ems/dzjk'
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import intervalUpdate from "@/mixins/ems/intervalUpdate";
|
||||
import {mapState} from "vuex";
|
||||
import {getPointConfigCurve} from "@/api/ems/site";
|
||||
|
||||
export default {
|
||||
name: 'DzjkSbjkBmsdcc',
|
||||
mixins: [getQuerySiteId, intervalUpdate],
|
||||
components: {PointTable, pointChart},
|
||||
components: {PointTable},
|
||||
computed: {
|
||||
...mapState({
|
||||
CLUSTERWorkStatusOptions: state => state?.ems?.CLUSTERWorkStatusOptions || {},
|
||||
@ -174,6 +228,19 @@ export default {
|
||||
displayData: [],
|
||||
clusterDeviceList: [],
|
||||
selectedClusterId: "",
|
||||
curveDialogVisible: false,
|
||||
curveDialogTitle: "点位曲线",
|
||||
curveChart: null,
|
||||
curveLoading: false,
|
||||
curveCustomRange: [],
|
||||
curveQuery: {
|
||||
siteId: "",
|
||||
pointId: "",
|
||||
pointType: "data",
|
||||
rangeType: "custom",
|
||||
startTime: "",
|
||||
endTime: "",
|
||||
},
|
||||
unitObj: {
|
||||
'电压': 'V',
|
||||
'温度': '℃',
|
||||
@ -228,8 +295,172 @@ export default {
|
||||
const {siteId, deviceId} = row
|
||||
this.$refs.pointTable.showTable({siteId, deviceId, deviceCategory: 'CLUSTER'}, dataType)
|
||||
},
|
||||
showChart(pointName, deviceId) {
|
||||
pointName && this.$refs.pointChart.showChart({pointName, deviceCategory: 'CLUSTER', deviceId})
|
||||
hasFieldPointId(baseInfo, fieldName) {
|
||||
const row = this.getFieldRow(baseInfo, fieldName);
|
||||
return !!String(row?.dataPoint || "").trim();
|
||||
},
|
||||
hasTableFieldPointId(baseInfo, dataName, columnLabel) {
|
||||
const pointName = this.tablePointNameMap[String(dataName || "") + String(columnLabel || "")];
|
||||
if (!pointName) {
|
||||
return false;
|
||||
}
|
||||
return this.hasFieldPointId(baseInfo, pointName);
|
||||
},
|
||||
getFieldRow(baseInfo, fieldName) {
|
||||
const key = String(fieldName || "").trim();
|
||||
const map = baseInfo?._fieldRowMap || {};
|
||||
return map[key] || null;
|
||||
},
|
||||
handleFieldClick(baseInfo, fieldName, title) {
|
||||
const row = this.getFieldRow(baseInfo, fieldName);
|
||||
const pointId = String(row?.dataPoint || "").trim();
|
||||
this.openCurveDialogByPointId(pointId, title || fieldName);
|
||||
},
|
||||
handleTableFieldClick(baseInfo, dataName, columnLabel) {
|
||||
const pointName = this.tablePointNameMap[String(dataName || "") + String(columnLabel || "")];
|
||||
if (!pointName) {
|
||||
this.$message.warning("该字段未配置点位,无法查询曲线");
|
||||
return;
|
||||
}
|
||||
this.handleFieldClick(baseInfo, pointName, pointName);
|
||||
},
|
||||
openCurveDialogByPointId(pointId, title) {
|
||||
const normalizedPointId = String(pointId || "").trim();
|
||||
if (!normalizedPointId) {
|
||||
this.$message.warning("该字段未配置点位,无法查询曲线");
|
||||
return;
|
||||
}
|
||||
const range = this.getDefaultCurveRange();
|
||||
this.curveCustomRange = range;
|
||||
this.curveDialogTitle = `点位曲线 - ${title || normalizedPointId}`;
|
||||
this.curveQuery = {
|
||||
siteId: this.siteId,
|
||||
pointId: normalizedPointId,
|
||||
pointType: "data",
|
||||
rangeType: "custom",
|
||||
startTime: range[0],
|
||||
endTime: range[1],
|
||||
};
|
||||
this.curveDialogVisible = true;
|
||||
},
|
||||
handleCurveDialogOpened() {
|
||||
if (!this.curveChart && this.$refs.curveChartRef) {
|
||||
this.curveChart = echarts.init(this.$refs.curveChartRef);
|
||||
}
|
||||
this.loadCurveData();
|
||||
},
|
||||
handleCurveDialogClosed() {
|
||||
if (this.curveChart) {
|
||||
this.curveChart.dispose();
|
||||
this.curveChart = null;
|
||||
}
|
||||
this.curveLoading = false;
|
||||
},
|
||||
getDefaultCurveRange() {
|
||||
const end = new Date();
|
||||
const start = new Date(end.getTime() - 24 * 60 * 60 * 1000);
|
||||
return [this.formatDateTime(start), this.formatDateTime(end)];
|
||||
},
|
||||
formatDateTime(date) {
|
||||
const d = new Date(date);
|
||||
const p = (n) => String(n).padStart(2, "0");
|
||||
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
|
||||
},
|
||||
formatCurveTime(value) {
|
||||
if (value === undefined || value === null || value === "") {
|
||||
return "";
|
||||
}
|
||||
const raw = String(value).trim();
|
||||
const normalized = raw
|
||||
.replace("T", " ")
|
||||
.replace(/\.\d+/, "")
|
||||
.replace(/Z$/, "")
|
||||
.replace(/([+-]\d{2}:?\d{2})$/, "")
|
||||
.trim();
|
||||
const matched = normalized.match(/^(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2})/);
|
||||
if (matched) {
|
||||
return `${matched[1]} ${matched[2]}`;
|
||||
}
|
||||
return normalized.slice(0, 16);
|
||||
},
|
||||
loadCurveData() {
|
||||
if (!this.curveQuery.siteId || !this.curveQuery.pointId) {
|
||||
this.$message.warning("点位信息不完整,无法查询曲线");
|
||||
return;
|
||||
}
|
||||
if (!this.curveCustomRange || this.curveCustomRange.length !== 2) {
|
||||
this.$message.warning("请选择查询时间范围");
|
||||
return;
|
||||
}
|
||||
this.curveQuery.startTime = this.curveCustomRange[0];
|
||||
this.curveQuery.endTime = this.curveCustomRange[1];
|
||||
const query = {
|
||||
siteId: this.curveQuery.siteId,
|
||||
pointId: this.curveQuery.pointId,
|
||||
pointType: "data",
|
||||
rangeType: "custom",
|
||||
startTime: this.curveQuery.startTime,
|
||||
endTime: this.curveQuery.endTime,
|
||||
};
|
||||
this.curveLoading = true;
|
||||
getPointConfigCurve(query).then((response) => {
|
||||
const rows = response?.data || [];
|
||||
this.renderCurveChart(rows);
|
||||
}).catch(() => {
|
||||
this.renderCurveChart([]);
|
||||
}).finally(() => {
|
||||
this.curveLoading = false;
|
||||
});
|
||||
},
|
||||
renderCurveChart(rows = []) {
|
||||
if (!this.curveChart) return;
|
||||
const xData = rows.map(item => this.formatCurveTime(item.dataTime));
|
||||
const yData = rows.map(item => item.pointValue);
|
||||
this.curveChart.clear();
|
||||
this.curveChart.setOption({
|
||||
legend: {},
|
||||
grid: {
|
||||
containLabel: true,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "cross",
|
||||
},
|
||||
},
|
||||
textStyle: {
|
||||
color: "#333333",
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: xData,
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
},
|
||||
dataZoom: [
|
||||
{
|
||||
type: "inside",
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: this.curveDialogTitle,
|
||||
type: "line",
|
||||
data: yData,
|
||||
connectNulls: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
if (!rows.length) {
|
||||
this.$message.warning("当前时间范围暂无曲线数据");
|
||||
}
|
||||
},
|
||||
handleTagClick(deviceId) {
|
||||
this.selectedClusterId = deviceId || "";
|
||||
@ -248,13 +479,28 @@ export default {
|
||||
return index >= 0 ? raw.slice(index + 2) : raw;
|
||||
},
|
||||
getFieldMap(rows = [], deviceId = "") {
|
||||
const rowMap = this.getFieldRowMap(rows, deviceId);
|
||||
return Object.keys(rowMap).reduce((acc, fieldName) => {
|
||||
const row = rowMap[fieldName];
|
||||
if (acc[fieldName] === undefined) {
|
||||
acc[fieldName] = row?.fieldValue;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
},
|
||||
getFieldRowMap(rows = [], deviceId = "") {
|
||||
const map = {};
|
||||
const targetDeviceId = String(deviceId || "");
|
||||
rows.forEach(item => {
|
||||
if (!item || !item.fieldCode) return;
|
||||
const itemDeviceId = String(item.deviceId || "");
|
||||
if (itemDeviceId !== targetDeviceId) return;
|
||||
map[this.getFieldName(item.fieldCode)] = item.fieldValue;
|
||||
const fieldName = this.getFieldName(item.fieldCode);
|
||||
map[fieldName] = item;
|
||||
const displayName = String(item.fieldName || "").trim();
|
||||
if (displayName && !map[displayName]) {
|
||||
map[displayName] = item;
|
||||
}
|
||||
});
|
||||
rows.forEach(item => {
|
||||
if (!item || !item.fieldCode) return;
|
||||
@ -262,7 +508,11 @@ export default {
|
||||
if (itemDeviceId !== "") return;
|
||||
const fieldName = this.getFieldName(item.fieldCode);
|
||||
if (map[fieldName] === undefined || map[fieldName] === null || map[fieldName] === "") {
|
||||
map[fieldName] = item.fieldValue;
|
||||
map[fieldName] = item;
|
||||
}
|
||||
const displayName = String(item.fieldName || "").trim();
|
||||
if (displayName && !map[displayName]) {
|
||||
map[displayName] = item;
|
||||
}
|
||||
});
|
||||
return map;
|
||||
@ -323,6 +573,11 @@ export default {
|
||||
pcsCommunicationStatus: statusMap.pcsCommunicationStatus,
|
||||
emsCommunicationStatus: statusMap.emsCommunicationStatus,
|
||||
currentSoc: isNaN(currentSoc) ? 0 : currentSoc,
|
||||
_fieldRowMap: {
|
||||
...this.getFieldRowMap(this.getModuleRows('SBJK_BMSDCC', '簇信息'), id),
|
||||
...this.getFieldRowMap(this.getModuleRows('SBJK_BMSDCC', '状态'), id),
|
||||
...this.getFieldRowMap(this.getModuleRows('SBJK_BMSDCC', '单体数据'), id),
|
||||
},
|
||||
};
|
||||
})(),
|
||||
siteId: this.siteId,
|
||||
@ -348,7 +603,13 @@ export default {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.curveChart) {
|
||||
this.curveChart.dispose();
|
||||
this.curveChart = null;
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user