1.一周充放曲线改为了时间聚合柱状图。

2.PCS最高温度修复bug展示多PCS设备的数据
3.PCS的状态根据状态枚举映射配置的内容显示
4.BMS的总览,增加工作状态、与PCS通讯、与EMS通讯的配置,及关联展示
5.增加批量导入单体电池点位的功能
6.修复计算点可能会出现id与code在一个池子内的问题,再次计算后数据正常
7.计算点增加小数位限制的功能,实时计算与7天历史接口都已经按照配置的小数位进行限制
8.统计报表中的功率曲线改为了按照分钟显示
9.功率曲线出现断点的问题是因为数据计算太密集了导致的,增加了前端连线不断的显示
10.PCS和电池堆的曲线与配置增加了关联设备显示
11.点位映射中的电池温度,增加了多设备
12.收益报表增加升序排列,合并当月所有合计
13.增加业务报表备注功能,可以根据业务设计开发,目前电表报表与收益报表均有备注列可以修改
This commit is contained in:
xiaoyang
2026-04-12 15:18:00 +08:00
parent fd860597de
commit 20df411925
17 changed files with 1272 additions and 460 deletions

View File

@ -56,7 +56,7 @@
:class="{ 'field-disabled': !hasFieldPointId(baseInfo, 'workStatus') }"
@click="handleFieldClick(baseInfo, 'workStatus', '工作状态')"
>
{{ CLUSTERWorkStatusOptions[baseInfo.workStatus] || '-' }}
{{ formatDictValue(clusterWorkStatusOptions, baseInfo.workStatus) }}
</span>
</el-descriptions-item>
<el-descriptions-item contentClassName="descriptions-direction"
@ -66,7 +66,7 @@
:class="{ 'field-disabled': !hasFieldPointId(baseInfo, 'pcsCommunicationStatus') }"
@click="handleFieldClick(baseInfo, 'pcsCommunicationStatus', '与PCS通信')"
>
{{ (($store.state.ems && $store.state.ems.communicationStatusOptions) || {})[baseInfo.pcsCommunicationStatus] || '-' }}
{{ formatDictValue(clusterPcsCommunicationStatusOptions, baseInfo.pcsCommunicationStatus) }}
</span>
</el-descriptions-item>
<el-descriptions-item contentClassName="descriptions-direction"
@ -76,7 +76,7 @@
:class="{ 'field-disabled': !hasFieldPointId(baseInfo, 'emsCommunicationStatus') }"
@click="handleFieldClick(baseInfo, 'emsCommunicationStatus', '与EMS通信')"
>
{{ (($store.state.ems && $store.state.ems.communicationStatusOptions) || {})[baseInfo.emsCommunicationStatus] || '-' }}
{{ formatDictValue(clusterEmsCommunicationStatusOptions, baseInfo.emsCommunicationStatus) }}
</span>
</el-descriptions-item>
</el-descriptions>
@ -205,7 +205,7 @@ import {getProjectDisplayData, getStackNameList, getClusterNameList} from '@/api
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
import intervalUpdate from "@/mixins/ems/intervalUpdate";
import {mapState} from "vuex";
import {getPointConfigCurve} from "@/api/ems/site";
import {getPointConfigCurve, getSingleMonitorWorkStatusEnumMappings} from "@/api/ems/site";
export default {
name: 'DzjkSbjkBmsdcc',
@ -215,6 +215,15 @@ export default {
...mapState({
CLUSTERWorkStatusOptions: state => state?.ems?.CLUSTERWorkStatusOptions || {},
}),
clusterWorkStatusOptions() {
return this.getEnumOptions("CLUSTER", "workStatus", this.CLUSTERWorkStatusOptions || {});
},
clusterPcsCommunicationStatusOptions() {
return this.getEnumOptions("CLUSTER", "pcsCommunicationStatus", (this.$store.state.ems && this.$store.state.ems.communicationStatusOptions) || {});
},
clusterEmsCommunicationStatusOptions() {
return this.getEnumOptions("CLUSTER", "emsCommunicationStatus", (this.$store.state.ems && this.$store.state.ems.communicationStatusOptions) || {});
},
filteredBaseInfoList() {
if (!this.selectedClusterId) {
return this.baseInfoList || [];
@ -227,6 +236,7 @@ export default {
loading: false,
displayData: [],
clusterDeviceList: [],
siteEnumOptionMap: {},
selectedClusterId: "",
curveDialogVisible: false,
curveDialogTitle: "点位曲线",
@ -286,9 +296,69 @@ export default {
isPointLoading(value) {
return this.loading && (value === undefined || value === null || value === "" || value === "-");
},
normalizeDictKey(value) {
const raw = String(value == null ? "" : value).trim();
if (!raw) return "";
if (/^-?\d+(\.0+)?$/.test(raw)) {
return String(parseInt(raw, 10));
}
return raw;
},
formatDictValue(options, value) {
const dict = (options && typeof options === "object") ? options : {};
const key = this.normalizeDictKey(value);
if (!key) return "-";
return dict[key] || key;
},
buildEnumScopeKey(deviceCategory, matchField) {
return `${String(deviceCategory || "").trim()}|${String(matchField || "").trim()}`;
},
buildSiteEnumOptionMap(mappings = []) {
return (mappings || []).reduce((acc, item) => {
const scopeKey = this.buildEnumScopeKey(item?.deviceCategory, item?.matchField);
const dataEnumCode = this.normalizeDictKey(item?.dataEnumCode);
const enumCode = this.normalizeDictKey(item?.enumCode);
const enumName = String(item?.enumName || "").trim();
const optionKey = dataEnumCode || enumCode;
if (!scopeKey || !optionKey || !enumName) {
return acc;
}
if (!acc[scopeKey]) {
acc[scopeKey] = {};
}
acc[scopeKey][optionKey] = enumName;
return acc;
}, {});
},
loadSiteEnumOptions() {
if (!this.siteId) {
this.siteEnumOptionMap = {};
return Promise.resolve({});
}
return getSingleMonitorWorkStatusEnumMappings(this.siteId).then(response => {
const optionMap = this.buildSiteEnumOptionMap(response?.data || []);
this.siteEnumOptionMap = optionMap;
return optionMap;
}).catch(() => {
this.siteEnumOptionMap = {};
return {};
});
},
getEnumOptions(deviceCategory, matchField, fallback = {}) {
const scopeKey = this.buildEnumScopeKey(deviceCategory, matchField);
const siteOptions = this.siteEnumOptionMap[scopeKey];
if (siteOptions && Object.keys(siteOptions).length > 0) {
return siteOptions;
}
return fallback || {};
},
handleCardClass(item) {
const {workStatus = ''} = item
return !(Object.keys(this.CLUSTERWorkStatusOptions).includes(item.workStatus)) ? "timing-card-container" : workStatus === '9' ? 'warning-card-container' : 'running-card-container'
const workStatus = this.normalizeDictKey((item && item.workStatus) || "");
const statusOptions = (this.clusterWorkStatusOptions && typeof this.clusterWorkStatusOptions === "object")
? this.clusterWorkStatusOptions
: {};
const hasStatus = Object.prototype.hasOwnProperty.call(statusOptions, workStatus);
return !hasStatus ? "timing-card-container" : workStatus === '9' ? 'warning-card-container' : 'running-card-container';
},
// 查看设备电位表格
pointDetail(row, dataType) {
@ -596,6 +666,7 @@ export default {
Promise.all([
getProjectDisplayData(this.siteId),
this.getClusterDeviceList(),
this.loadSiteEnumOptions(),
]).then(([response]) => {
this.displayData = response?.data || [];
this.buildBaseInfoList();

View File

@ -50,19 +50,19 @@
contentClassName="descriptions-direction work-status"
label="工作状态" labelClassName="descriptions-label">
<span class="pointer" @click="handleStatusFieldClick(baseInfo, 'workStatus', '工作状态')">
{{ STACKWorkStatusOptions[baseInfo.workStatus] || '-' }}
{{ formatDictValue(stackWorkStatusOptions, baseInfo.workStatus) }}
</span>
</el-descriptions-item>
<el-descriptions-item :span="1" contentClassName="descriptions-direction" label="与PCS通信"
labelClassName="descriptions-label">
<span class="pointer" @click="handleStatusFieldClick(baseInfo, 'pcsCommunicationStatus', '与PCS通信')">
{{ (($store.state.ems && $store.state.ems.communicationStatusOptions) || {})[baseInfo.pcsCommunicationStatus] || '-' }}
{{ formatDictValue(stackPcsCommunicationStatusOptions, baseInfo.pcsCommunicationStatus) }}
</span>
</el-descriptions-item>
<el-descriptions-item :span="1" contentClassName="descriptions-direction" label="与EMS通信"
labelClassName="descriptions-label">
<span class="pointer" @click="handleStatusFieldClick(baseInfo, 'emsCommunicationStatus', '与EMS通信')">
{{ (($store.state.ems && $store.state.ems.communicationStatusOptions) || {})[baseInfo.emsCommunicationStatus] || '-' }}
{{ formatDictValue(stackEmsCommunicationStatusOptions, baseInfo.emsCommunicationStatus) }}
</span>
</el-descriptions-item>
</el-descriptions>
@ -123,7 +123,7 @@
<script>
import * as echarts from "echarts";
import {getProjectDisplayData, getStackNameList} from '@/api/ems/dzjk'
import {getPointConfigCurve} from "@/api/ems/site";
import {getPointConfigCurve, getSingleMonitorWorkStatusEnumMappings} from "@/api/ems/site";
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
import intervalUpdate from "@/mixins/ems/intervalUpdate";
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
@ -137,6 +137,15 @@ export default {
...mapState({
STACKWorkStatusOptions: state => state?.ems?.STACKWorkStatusOptions || {},
}),
stackWorkStatusOptions() {
return this.getEnumOptions("STACK", "workStatus", this.STACKWorkStatusOptions || {});
},
stackPcsCommunicationStatusOptions() {
return this.getEnumOptions("STACK", "pcsCommunicationStatus", (this.$store.state.ems && this.$store.state.ems.communicationStatusOptions) || {});
},
stackEmsCommunicationStatusOptions() {
return this.getEnumOptions("STACK", "emsCommunicationStatus", (this.$store.state.ems && this.$store.state.ems.communicationStatusOptions) || {});
},
filteredBaseInfoList() {
if (!this.selectedStackId) {
return this.baseInfoList || [];
@ -149,6 +158,7 @@ export default {
loading: false,
displayData: [],
stackDeviceList: [],
siteEnumOptionMap: {},
selectedStackId: "",
curveDialogVisible: false,
curveDialogTitle: "点位曲线",
@ -191,9 +201,69 @@ export default {
isPointLoading(value) {
return this.loading && (value === undefined || value === null || value === "" || value === "-");
},
normalizeDictKey(value) {
const raw = String(value == null ? "" : value).trim();
if (!raw) return "";
if (/^-?\d+(\.0+)?$/.test(raw)) {
return String(parseInt(raw, 10));
}
return raw;
},
formatDictValue(options, value) {
const dict = (options && typeof options === "object") ? options : {};
const key = this.normalizeDictKey(value);
if (!key) return "-";
return dict[key] || key;
},
buildEnumScopeKey(deviceCategory, matchField) {
return `${String(deviceCategory || "").trim()}|${String(matchField || "").trim()}`;
},
buildSiteEnumOptionMap(mappings = []) {
return (mappings || []).reduce((acc, item) => {
const scopeKey = this.buildEnumScopeKey(item?.deviceCategory, item?.matchField);
const dataEnumCode = this.normalizeDictKey(item?.dataEnumCode);
const enumCode = this.normalizeDictKey(item?.enumCode);
const enumName = String(item?.enumName || "").trim();
const optionKey = dataEnumCode || enumCode;
if (!scopeKey || !optionKey || !enumName) {
return acc;
}
if (!acc[scopeKey]) {
acc[scopeKey] = {};
}
acc[scopeKey][optionKey] = enumName;
return acc;
}, {});
},
loadSiteEnumOptions() {
if (!this.siteId) {
this.siteEnumOptionMap = {};
return Promise.resolve({});
}
return getSingleMonitorWorkStatusEnumMappings(this.siteId).then(response => {
const optionMap = this.buildSiteEnumOptionMap(response?.data || []);
this.siteEnumOptionMap = optionMap;
return optionMap;
}).catch(() => {
this.siteEnumOptionMap = {};
return {};
});
},
getEnumOptions(deviceCategory, matchField, fallback = {}) {
const scopeKey = this.buildEnumScopeKey(deviceCategory, matchField);
const siteOptions = this.siteEnumOptionMap[scopeKey];
if (siteOptions && Object.keys(siteOptions).length > 0) {
return siteOptions;
}
return fallback || {};
},
handleCardClass(item) {
const {workStatus = ''} = item
return !Object.keys(this.STACKWorkStatusOptions).find(i => i === workStatus) ? "timing-card-container" : workStatus === '9' ? 'warning-card-container' : 'running-card-container'
const workStatus = this.normalizeDictKey((item && item.workStatus) || "");
const statusOptions = (this.stackWorkStatusOptions && typeof this.stackWorkStatusOptions === "object")
? this.stackWorkStatusOptions
: {};
const hasStatus = Object.prototype.hasOwnProperty.call(statusOptions, workStatus);
return !hasStatus ? "timing-card-container" : workStatus === '9' ? 'warning-card-container' : 'running-card-container';
},
// 查看设备电位表格
@ -487,6 +557,7 @@ export default {
Promise.all([
getProjectDisplayData(this.siteId),
this.getStackDeviceList(),
this.loadSiteEnumOptions(),
]).then(([displayResponse]) => {
this.displayData = displayResponse?.data || [];
this.buildBaseInfoList();

View File

@ -64,7 +64,7 @@
:class="{ 'field-disabled': !hasFieldPointId(pcsItem, 'workStatus') }"
@click="handlePcsFieldClick(pcsItem, 'workStatus', '工作状态')"
>
{{ formatDictValue((PCSWorkStatusOptions || {}), pcsItem.workStatus) }}
{{ formatDictValue(pcsWorkStatusOptions, pcsItem.workStatus) }}
</span>
</el-descriptions-item
>
@ -79,7 +79,7 @@
:class="{ 'field-disabled': !hasFieldPointId(pcsItem, 'gridStatus') }"
@click="handlePcsFieldClick(pcsItem, 'gridStatus', '并网状态')"
>
{{ formatDictValue((($store.state.ems && $store.state.ems.gridStatusOptions) || {}), pcsItem.gridStatus) }}
{{ formatDictValue(pcsGridStatusOptions, pcsItem.gridStatus) }}
</span>
</el-descriptions-item
>
@ -96,7 +96,7 @@
:class="{ 'field-disabled': !hasFieldPointId(pcsItem, 'deviceStatus') }"
@click="handlePcsFieldClick(pcsItem, 'deviceStatus', '设备状态')"
>
{{ formatDictValue((($store.state.ems && $store.state.ems.deviceStatusOptions) || {}), pcsItem.deviceStatus) }}
{{ formatDictValue(pcsDeviceStatusOptions, pcsItem.deviceStatus) }}
</span>
</el-descriptions-item
>
@ -111,7 +111,7 @@
:class="{ 'field-disabled': !hasFieldPointId(pcsItem, 'controlMode') }"
@click="handlePcsFieldClick(pcsItem, 'controlMode', '控制模式')"
>
{{ formatDictValue((($store.state.ems && $store.state.ems.controlModeOptions) || {}), pcsItem.controlMode) }}
{{ formatDictValue(pcsControlModeOptions, pcsItem.controlMode) }}
</span>
</el-descriptions-item
>
@ -242,7 +242,7 @@ import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
import {getPcsNameList, getProjectDisplayData} from "@/api/ems/dzjk";
import intervalUpdate from "@/mixins/ems/intervalUpdate";
import {mapState} from "vuex";
import {getPointConfigCurve} from "@/api/ems/site";
import {getPointConfigCurve, getSingleMonitorWorkStatusEnumMappings} from "@/api/ems/site";
export default {
name: "DzjkSbjkPcs",
@ -252,6 +252,18 @@ export default {
...mapState({
PCSWorkStatusOptions: state => state?.ems?.PCSWorkStatusOptions || {},
}),
pcsWorkStatusOptions() {
return this.getEnumOptions("PCS", "workStatus", this.PCSWorkStatusOptions || {});
},
pcsGridStatusOptions() {
return this.getEnumOptions("PCS", "gridStatus", (this.$store.state.ems && this.$store.state.ems.gridStatusOptions) || {});
},
pcsDeviceStatusOptions() {
return this.getEnumOptions("PCS", "deviceStatus", (this.$store.state.ems && this.$store.state.ems.deviceStatusOptions) || {});
},
pcsControlModeOptions() {
return this.getEnumOptions("PCS", "controlMode", (this.$store.state.ems && this.$store.state.ems.controlModeOptions) || {});
},
filteredPcsList() {
if (!this.selectedPcsId) {
return this.pcsList || [];
@ -264,6 +276,7 @@ export default {
loading: false,
displayData: [],
pcsDeviceList: [],
siteEnumOptionMap: {},
selectedPcsId: "",
curveDialogVisible: false,
curveDialogTitle: "点位曲线",
@ -388,10 +401,52 @@ export default {
normalizeDeviceId(value) {
return String(value == null ? "" : value).trim().toUpperCase();
},
buildEnumScopeKey(deviceCategory, matchField) {
return `${String(deviceCategory || "").trim()}|${String(matchField || "").trim()}`;
},
buildSiteEnumOptionMap(mappings = []) {
return (mappings || []).reduce((acc, item) => {
const scopeKey = this.buildEnumScopeKey(item?.deviceCategory, item?.matchField);
const dataEnumCode = this.normalizeDictKey(item?.dataEnumCode);
const enumCode = this.normalizeDictKey(item?.enumCode);
const enumName = String(item?.enumName || "").trim();
const optionKey = dataEnumCode || enumCode;
if (!scopeKey || !optionKey || !enumName) {
return acc;
}
if (!acc[scopeKey]) {
acc[scopeKey] = {};
}
acc[scopeKey][optionKey] = enumName;
return acc;
}, {});
},
loadSiteEnumOptions() {
if (!this.siteId) {
this.siteEnumOptionMap = {};
return Promise.resolve({});
}
return getSingleMonitorWorkStatusEnumMappings(this.siteId).then(response => {
const optionMap = this.buildSiteEnumOptionMap(response?.data || []);
this.siteEnumOptionMap = optionMap;
return optionMap;
}).catch(() => {
this.siteEnumOptionMap = {};
return {};
});
},
getEnumOptions(deviceCategory, matchField, fallback = {}) {
const scopeKey = this.buildEnumScopeKey(deviceCategory, matchField);
const siteOptions = this.siteEnumOptionMap[scopeKey];
if (siteOptions && Object.keys(siteOptions).length > 0) {
return siteOptions;
}
return fallback || {};
},
handleCardClass(item) {
const workStatus = this.normalizeDictKey((item && item.workStatus) || "");
const statusOptions = (this.PCSWorkStatusOptions && typeof this.PCSWorkStatusOptions === 'object')
? this.PCSWorkStatusOptions
const statusOptions = (this.pcsWorkStatusOptions && typeof this.pcsWorkStatusOptions === 'object')
? this.pcsWorkStatusOptions
: {};
const hasStatus = Object.prototype.hasOwnProperty.call(statusOptions, workStatus);
return workStatus === '1' || !hasStatus
@ -651,6 +706,7 @@ export default {
Promise.all([
getProjectDisplayData(this.siteId),
this.getPcsDeviceList(),
this.loadSiteEnumOptions(),
]).then(([displayResponse]) => {
this.displayData = displayResponse?.data || [];
this.buildPcsList();

View File

@ -68,7 +68,7 @@ export default {
.then((response) => {
const list = response?.data || [];
return {
name: row.fieldName || row.fieldCode || pointId,
name: (row.deviceName || "") + (row.fieldName || row.fieldCode || pointId),
data: list
.map((item) => [
this.parseToTimestamp(item.dataTime),

View File

@ -41,33 +41,38 @@ export default {
methods: {
init(siteId,timeRange) {
const [startTime='', endTime=''] = timeRange;
const row = (this.displayData || []).find(
const query = {
siteId,
rangeType: "custom",
startTime: this.normalizeDateTime(startTime, false),
endTime: this.normalizeDateTime(endTime, true)
};
const rows = (this.displayData || []).filter(
(item) =>
item &&
item.fieldCode === "SBJK_SSYX__curveBatteryAveSoc" &&
item.useFixedDisplay !== 1 &&
item.dataPoint
);
const pointId = String(row?.dataPoint || "").trim();
if (!pointId) {
this.setOption([]);
return;
}
getPointConfigCurve({
siteId,
pointId,
rangeType: "custom",
startTime: this.normalizeDateTime(startTime, false),
endTime: this.normalizeDateTime(endTime, true)
})
.then((response) => {
const list = response?.data || [];
this.setOption(
list
.map((item) => [this.parseToTimestamp(item.dataTime), Number(item.pointValue)])
.filter((item) => item[0] && !Number.isNaN(item[1]))
);
});
const tasks = rows.map((row) => {
const pointId = String(row.dataPoint || "").trim();
if(!pointId) return Promise.resolve(null);
return getPointConfigCurve({
...query,
pointId
}).then((response) => {
const list = response?.data || [];
return {
name: (row.deviceName || "") + (row.fieldName || row.fieldCode || pointId),
data: list
.map((item) => [this.parseToTimestamp(item.dataTime), Number(item.pointValue)])
.filter((item) => item[0] && !Number.isNaN(item[1]))
};
}).catch(() => null);
});
Promise.all(tasks).then((series) => {
this.setOption((series || []).filter(Boolean));
});
},
normalizeDateTime(value, endOfDay) {
const raw = String(value || "").trim();
@ -80,7 +85,7 @@ export default {
const t = new Date(value).getTime();
return Number.isNaN(t) ? null : t;
},
setOption(data = []) {
setOption(seriesData = []) {
this.chart && this.chart.setOption({
legend: {
left: "center",
@ -119,18 +124,16 @@ export default {
end: 100,
},
],
series: [
{
type: "line",
name: `平均SOC`,
showSymbol: false,
smooth: true,
areaStyle: {
opacity: 0.35
},
data,
series: seriesData.map(item => ({
type: "line",
name: item.name,
showSymbol: false,
smooth: true,
areaStyle: {
opacity: 0.35
},
],
data: item.data
})),
},true);
},
},

View File

@ -42,33 +42,38 @@ export default {
methods: {
init(siteId,timeRange) {
const [startTime='', endTime=''] = timeRange;
const row = (this.displayData || []).find(
const query = {
siteId,
rangeType: "custom",
startTime: this.normalizeDateTime(startTime, false),
endTime: this.normalizeDateTime(endTime, true)
};
const rows = (this.displayData || []).filter(
(item) =>
item &&
item.fieldCode === "SBJK_SSYX__curveBatteryAveTemp" &&
item.useFixedDisplay !== 1 &&
item.dataPoint
);
const pointId = String(row?.dataPoint || "").trim();
if (!pointId) {
this.setOption([]);
return;
}
getPointConfigCurve({
siteId,
pointId,
rangeType: "custom",
startTime: this.normalizeDateTime(startTime, false),
endTime: this.normalizeDateTime(endTime, true)
})
.then((response) => {
const list = response?.data || [];
this.setOption(
list
.map((item) => [this.parseToTimestamp(item.dataTime), Number(item.pointValue)])
.filter((item) => item[0] && !Number.isNaN(item[1]))
);
});
const tasks = rows.map((row) => {
const pointId = String(row.dataPoint || "").trim();
if(!pointId) return Promise.resolve(null);
return getPointConfigCurve({
...query,
pointId
}).then((response) => {
const list = response?.data || [];
return {
name: (row.deviceName || "") + (row.fieldName || row.fieldCode || pointId),
data: list
.map((item) => [this.parseToTimestamp(item.dataTime), Number(item.pointValue)])
.filter((item) => item[0] && !Number.isNaN(item[1]))
};
}).catch(() => null);
});
Promise.all(tasks).then((series) => {
this.setOption((series || []).filter(Boolean));
});
},
normalizeDateTime(value, endOfDay) {
const raw = String(value || "").trim();
@ -81,7 +86,7 @@ export default {
const t = new Date(value).getTime();
return Number.isNaN(t) ? null : t;
},
setOption(data = []) {
setOption(seriesData = []) {
this.chart && this.chart.setOption({
legend: {
left: "center",
@ -120,18 +125,16 @@ export default {
end: 100,
},
],
series: [
{
type: "line",
name: `电池平均温度`,
showSymbol: false,
smooth: true,
areaStyle: {
opacity: 0.35
},
data,
series: seriesData.map(item => ({
type: "line",
name: item.name,
showSymbol: false,
smooth: true,
areaStyle: {
opacity: 0.35
},
],
data: item.data
})),
},true);
},
},

View File

@ -27,7 +27,6 @@ export default {
data() {
return {
chart: null,
seriesName: "PCS最高温度"
};
},
mounted() {
@ -43,34 +42,38 @@ export default {
methods: {
init(siteId,timeRange) {
const [startTime='', endTime=''] = timeRange;
const row = (this.displayData || []).find(
const query = {
siteId,
rangeType: "custom",
startTime: this.normalizeDateTime(startTime, false),
endTime: this.normalizeDateTime(endTime, true)
};
const rows = (this.displayData || []).filter(
(item) =>
item &&
item.fieldCode === "SBJK_SSYX__curvePcsMaxTemp" &&
item.useFixedDisplay !== 1 &&
item.dataPoint
);
const pointId = String(row?.dataPoint || "").trim();
this.seriesName = row?.fieldName || "PCS最高温度";
if (!pointId) {
this.setOption([]);
return;
}
getPointConfigCurve({
siteId,
pointId,
rangeType: "custom",
startTime: this.normalizeDateTime(startTime, false),
endTime: this.normalizeDateTime(endTime, true)
})
.then((response) => {
const list = response?.data || [];
this.setOption(
list
.map((item) => [this.parseToTimestamp(item.dataTime), Number(item.pointValue)])
.filter((item) => item[0] && !Number.isNaN(item[1]))
);
});
const tasks = rows.map((row) => {
const pointId = String(row.dataPoint || "").trim();
if(!pointId) return Promise.resolve(null);
return getPointConfigCurve({
...query,
pointId
}).then((response) => {
const list = response?.data || [];
return {
name: (row.deviceName || "") + (row.fieldName || row.fieldCode || pointId),
data: list
.map((item) => [this.parseToTimestamp(item.dataTime), Number(item.pointValue)])
.filter((item) => item[0] && !Number.isNaN(item[1]))
};
}).catch(() => null);
});
Promise.all(tasks).then((series) => {
this.setOption((series || []).filter(Boolean));
});
},
normalizeDateTime(value, endOfDay) {
const raw = String(value || "").trim();
@ -83,7 +86,7 @@ export default {
const t = new Date(value).getTime();
return Number.isNaN(t) ? null : t;
},
setOption(data = []) {
setOption(seriesData = []) {
this.chart && this.chart.setOption({
legend: {
left: "center",
@ -122,18 +125,16 @@ export default {
end: 100,
},
],
series: [
{
type: "line",
name: this.seriesName,
showSymbol: false,
smooth: true,
areaStyle: {
opacity: 0.35
},
data
}
],
series: seriesData.map(item => ({
type: "line",
name: item.name,
showSymbol: false,
smooth: true,
areaStyle: {
opacity: 0.35
},
data: item.data
})),
},true);
},
},