合并develop最新代码

This commit is contained in:
2025-08-20 17:53:26 +08:00
45 changed files with 3485 additions and 1325 deletions

View File

@ -2,7 +2,7 @@
<template>
<!-- 6个方块-->
<el-row :gutter="10">
<el-col :xs="12" :sm="8" :lg="4" class="single-square-box-container" v-for="(item,index) in singleZdSqaure" :key="index+'singleSquareBox'">
<el-col :xs="12" :sm="8" :lg="4" style="margin-bottom: 10px;" class="single-square-box-container" v-for="(item,index) in singleZdSqaure" :key="index+'singleSquareBox'">
<single-square-box :data="{...item,value:formatNumber(data[item.attr])}" ></single-square-box>
</el-col>
</el-row>
@ -64,5 +64,10 @@ export default {
<style scoped lang="scss">
@media only screen and (min-width: 1200px) {
.single-square-box-container {
min-width: 16.6666666667%;
width: fit-content;
}
}
</style>

View File

@ -61,6 +61,10 @@
<span>{{scope.row.maxCellVoltage}} V</span>
</template>
</el-table-column>
<el-table-column
prop="maxCellVoltageId"
label="电池号码">
</el-table-column>
<el-table-column
prop="minVoltage"
label="单体最低电压">
@ -68,12 +72,20 @@
<span>{{scope.row.minCellVoltage}} V</span>
</template>
</el-table-column>
<el-table-column
prop="minCellVoltageId"
label="电池号码">
</el-table-column>
<el-table-column
label="单体最高温度">
<template slot-scope="scope">
<span>{{scope.row.maxCellTemp}} &#8451;</span>
</template>
</el-table-column>
<el-table-column
prop="maxCellTempId"
label="电池号码">
</el-table-column>
<el-table-column
prop="minTemperature"
label="单体最低温度">
@ -81,6 +93,10 @@
<span>{{scope.row.minCellTemp}} &#8451;</span>
</template>
</el-table-column>
<el-table-column
prop="minCellTempId"
label="电池号码">
</el-table-column>
</el-table>
</el-card>

View File

@ -1,134 +1,140 @@
<template>
<div v-loading="loading">
<el-card shadow="always" class="common-card-container" :class="zbInfo.emsCommunicationStatus === '1' ? 'zb-common-card-container' : 'cnb-common-card-container'">
<div slot="header">
<span class="large-title">1#{{zbInfo.deviceName}}</span>
<div class="status">
<div>{{$store.state.ems.communicationStatusOptions[zbInfo.emsCommunicationStatus]}}</div>
<div>数据更新时间{{zbInfo.dataUpdateTime}}</div>
</div>
<div v-loading="loading">
<el-card
shadow="always"
class="common-card-container"
:class="
zbInfo.emsCommunicationStatus !== '0'
? 'zb-common-card-container'
: 'cnb-common-card-container'
"
>
<div slot="header">
<span class="large-title">1#{{ zbInfo.deviceName }}</span>
<div class="status">
<div>
{{
$store.state.ems.communicationStatusOptions[
zbInfo.emsCommunicationStatus
]
}}
</div>
<el-table
class="common-table"
:data="zbInfo.loadDataDetailInfo"
stripe
style="width: 100%;">
<el-table-column
prop="category"
label="类别">
</el-table-column>
<el-table-column
prop="totalKwh"
label="总/kWh"
>
</el-table-column>
<el-table-column
prop="peakKwh"
label="尖/kWh">
</el-table-column>
<el-table-column
prop="highKwh"
label="峰/kWh">
</el-table-column>
<el-table-column
prop="flatKwh"
label="平/kWh">
</el-table-column>
<el-table-column
prop="valleyKwh"
label="谷/kWh">
</el-table-column>
</el-table>
</el-card>
<el-card shadow="always" class="common-card-container" style="margin-top:20px" :class="cnbInfo.emsCommunicationStatus === '1' ? 'zb-common-card-container' : 'cnb-common-card-container'">
<div slot="header">
<span class="large-title">2#{{cnbInfo.deviceName}}</span>
<div class="status">
<div>{{$store.state.ems.communicationStatusOptions[cnbInfo.emsCommunicationStatus]}}</div>
<div>数据更新时间{{cnbInfo.dataUpdateTime}}</div>
</div>
</div>
<el-table
class="common-table"
:data="cnbInfo.meteDataDetailInfo"
stripe
style="width: 100%;">
<el-table-column
prop="category"
label="类别">
</el-table-column>
<el-table-column
prop="activePower"
label="有功功率"
>
</el-table-column>
<el-table-column
prop="reactivePower"
label="无功功率">
</el-table-column>
</el-table>
</el-card>
<div>数据更新时间{{ zbInfo.dataUpdateTime }}</div>
</div>
</div>
<el-table
class="common-table"
:data="zbInfo.loadDataDetailInfo"
stripe
style="width: 100%"
>
<el-table-column prop="category" label="类别"> </el-table-column>
<el-table-column prop="totalKwh" label="总/kWh"> </el-table-column>
<el-table-column prop="peakKwh" label="尖/kWh"> </el-table-column>
<el-table-column prop="highKwh" label="峰/kWh"> </el-table-column>
<el-table-column prop="flatKwh" label="平/kWh"> </el-table-column>
<el-table-column prop="valleyKwh" label="谷/kWh"> </el-table-column>
</el-table>
</el-card>
<el-card
shadow="always"
class="common-card-container"
style="margin-top: 20px"
:class="
cnbInfo.emsCommunicationStatus !== '0'
? 'zb-common-card-container'
: 'cnb-common-card-container'
"
>
<div slot="header">
<span class="large-title">2#{{ cnbInfo.deviceName }}</span>
<div class="status">
<div>
{{
$store.state.ems.communicationStatusOptions[
cnbInfo.emsCommunicationStatus
]
}}
</div>
<div>数据更新时间{{ cnbInfo.dataUpdateTime }}</div>
</div>
</div>
<el-table
class="common-table"
:data="cnbInfo.meteDataDetailInfo"
stripe
style="width: 100%"
>
<el-table-column prop="category" label="类别"> </el-table-column>
<el-table-column prop="activePower" label="有功功率"> </el-table-column>
<el-table-column prop="reactivePower" label="无功功率">
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script>
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
import {getAmmeterDataList} from '@/api/ems/dzjk'
import { getAmmeterDataList } from "@/api/ems/dzjk";
export default {
name:'DzjkSbjkDb',
mixins:[getQuerySiteId],
name: "DzjkSbjkDb",
mixins: [getQuerySiteId],
data() {
return {
loading:false,
zbInfo:{},
cnbInfo:{},
}
loading: false,
zbInfo: {},
cnbInfo: {},
};
},
methods:{
init(){
this.loading = true
getAmmeterDataList(this.siteId).then(response => {
this.zbInfo =JSON.parse(JSON.stringify(response?.data?.ammeterLoadData || {}));
this.cnbInfo =JSON.parse(JSON.stringify(response?.data?.ammeterMeteData || {}));
}).finally(() => {this.loading = false})
}
methods: {
init() {
this.loading = true;
getAmmeterDataList(this.siteId)
.then((response) => {
this.zbInfo = JSON.parse(
JSON.stringify(response?.data?.ammeterLoadData || {})
);
this.cnbInfo = JSON.parse(
JSON.stringify(response?.data?.ammeterMeteData || {})
);
})
.finally(() => {
this.loading = false;
});
},
},
mounted(){
}
}
mounted() {},
};
</script>
<style scoped lang="scss">
.zb-common-card-container,.cnb-common-card-container{
::v-deep{
.el-card__header{
padding:10px 14px;
background-color: #FC6B69;
color:#ffffff;
.zb-common-card-container,
.cnb-common-card-container {
::v-deep {
.el-card__header {
padding: 10px 14px;
background-color: #fc6b69;
color: #ffffff;
position: relative;
}
}
}
.cnb-common-card-container{
margin-top:25px;
::v-deep{
.el-card__header{
background-color: #05AEA3;
.cnb-common-card-container {
margin-top: 25px;
::v-deep {
.el-card__header {
background-color: #05aea3;
}
}
}
.status{
.status {
position: absolute;
right:14px;
top:50%;
right: 14px;
top: 50%;
transform: translateY(-50%);
color: #ffffff;
font-size: 12px;
line-height: 20px;
}
</style>

View File

@ -20,8 +20,9 @@
start-placeholder="开始时间"
value-format="yyyy-MM-dd"
:picker-options="pickerOptions"
:default-value="defaultDateRange"
end-placeholder="结束时间">
end-placeholder="结束时间"
:clearable="false"
>
</el-date-picker>
</el-form-item>
<el-form-item>
@ -29,145 +30,181 @@
<el-button @click="onReset">重置</el-button>
</el-form-item>
</el-form>
<div id="lineChart" style="height: 360px;width: 100%;"></div>
<div id="lineChart" style="height: 360px; width: 100%"></div>
</div>
</el-dialog>
</template>
<script>
import * as echarts from 'echarts'
import resize from '@/mixins/ems/resize'
import {getSingleBatteryData} from '@/api/ems/dzjk'
import * as echarts from "echarts";
import resize from "@/mixins/ems/resize";
import { getSingleBatteryData } from "@/api/ems/dzjk";
import { formatDate } from "@/filters/ems";
export default {
mixins: [resize],
data() {
return {
loading: false,
siteId:'',
deviceId:'',
clusterDeviceId:'',
dataType:'',//展示的数据类型 空值展示所有数据
pickerOptions:{
siteId: "",
deviceId: "",
clusterDeviceId: "",
dataType: "", //展示的数据类型 空值展示所有数据
pickerOptions: {
disabledDate(time) {
return time.getTime() > Date.now();
},
},
dialogTableVisible: false,
dateRange: [],
defaultDateRange:[]
}
defaultDateRange: [],
};
},
methods: {
handleColsed(done){
if (!this.chart) {
return done()
}
this.chart.dispose()
this.chart = null
done()
resetDefaultDateRange() {
const now = new Date(),
formatNow = formatDate(now);
const weekAgo = formatDate(
new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)
);
this.dateRange = [weekAgo, formatNow];
this.defaultDateRange = [weekAgo, formatNow];
},
getData(){
if(this.loading) return
handleColsed(done) {
if (!this.chart) {
return done();
}
this.chart.dispose();
this.chart = null;
done();
},
getData() {
if (this.loading) return;
this.loading = true;
this.chart.showLoading()
const {siteId, deviceId,clusterDeviceId,dateRange:[startDate='',endDate='']}=this;
getSingleBatteryData({siteId, deviceId,clusterDeviceId,startDate,endDate}).then(response => {
this.setOption(response?.data || [])
}).finally(()=>{
this.loading = false;
this.chart.hideLoading()
this.chart.showLoading();
const {
siteId,
deviceId,
clusterDeviceId,
dateRange: [startDate = "", endDate = ""],
} = this;
getSingleBatteryData({
siteId,
deviceId,
clusterDeviceId,
startDate,
endDate,
})
.then((response) => {
this.setOption(response?.data || []);
})
.finally(() => {
this.loading = false;
this.chart.hideLoading();
});
},
// 重置
onReset(){
this.dateRange=[]
this.getData()
onReset() {
this.dateRange = this.defaultDateRange;
this.getData();
},
initChart({siteId, clusterDeviceId, deviceId},dataType) {
this.siteId=siteId
this.clusterDeviceId=clusterDeviceId
this.deviceId=deviceId
this.dataType=dataType
this.dateRange=[]
this.dialogTableVisible = true
this.$nextTick(()=>{
!this.chart && (this.chart = echarts.init(document.querySelector('#lineChart')))
this.getData()
})
initChart({ siteId, clusterDeviceId, deviceId }, dataType) {
this.siteId = siteId;
this.clusterDeviceId = clusterDeviceId;
this.deviceId = deviceId;
this.dataType = dataType;
this.resetDefaultDateRange();
this.dialogTableVisible = true;
this.$nextTick(() => {
!this.chart &&
(this.chart = echarts.init(document.querySelector("#lineChart")));
this.getData();
});
},
setOption(data) {
const obj = {
voltage:'电压',
temperature:'温度',
soc:'SOC',
soh:'SOH',
}
let source,series,{dataType} = this
if(dataType){
source = [['日期',obj[dataType]]]
data.forEach(item => {
source.push([item.dataTimestamp,item[dataType]])
})
series=[{
name:obj[dataType],
type: 'line',
}]
}else{
source = [['日期','电压','温度','SOC','SOH']]
data.forEach(item => {
source.push([item.dataTimestamp,item.voltage,item.temperature,item.soc,item.soh])
})
series=[
voltage: "电压",
temperature: "温度",
soc: "SOC",
soh: "SOH",
};
let source,
series,
{ dataType } = this;
if (dataType) {
source = [["日期", obj[dataType]]];
data.forEach((item) => {
source.push([item.dataTimestamp, item[dataType]]);
});
series = [
{
name:'电压',
type: 'line',
},{
name:'温度',
type: 'line',
name: obj[dataType],
type: "line",
},
];
} else {
source = [["日期", "电压", "温度", "SOC", "SOH"]];
data.forEach((item) => {
source.push([
item.dataTimestamp,
item.voltage,
item.temperature,
item.soc,
item.soh,
]);
});
series = [
{
name: "电压",
type: "line",
},
{
name:'SOC',
type: 'line',
},{
name:'SOH',
type: 'line',
}]
name: "温度",
type: "line",
},
{
name: "SOC",
type: "line",
},
{
name: "SOH",
type: "line",
},
];
}
this.chart && this.chart.setOption({
color:['#FFBD00','#3C81FF','#05AEA3','#F86F70'],
legend: {
bottom: '10',
},
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
textStyle:{
color:"#333333",
},
xAxis: {
type: 'category',
},
yAxis: {
type: 'value',
},
dataset:{
source
},
series
})
}
this.chart &&
this.chart.setOption({
color: ["#FFBD00", "#3C81FF", "#05AEA3", "#F86F70"],
grid: {
containLabel: true,
},
legend: {
left: "center",
bottom: "15",
},
tooltip: {
trigger: "axis",
axisPointer: {
// 坐标轴指示器,坐标轴触发有效
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
},
},
textStyle: {
color: "#333333",
},
xAxis: {
type: "category",
},
yAxis: {
type: "value",
},
dataset: {
source,
},
series,
});
},
},
mounted(){
const now = new Date();
const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
this.defaultDateRange = [lastMonth, now];
}
}
mounted() {},
};
</script>

View File

@ -0,0 +1,191 @@
<template>
<div>
<template v-if="totalSize.length === 0">
<el-empty :size="200"></el-empty>
</template>
<template v-else>
<div class="lists-container clearfix">
<div
class="lists"
v-for="(item, index) in tableData"
:key="index + 'dtdcList'"
:class="handleListClass(item)"
@click="chartDetail(item)"
>
<div style="font-size: 10px; font-weight: 600">
{{ item.clusterDeviceId }}
</div>
<div>#{{ item.deviceId }}</div>
<div class="dy">{{ item.voltage }}V</div>
<div class="wd">{{ item.temperature }}</div>
</div>
</div>
<!-- <el-pagination
v-show="tableData.length > 0"
background
@size-change="(val) => $emit('handleSizeChange', val)"
@current-change="(val) => $emit('handleCurrentChange', val)"
:current-page="pageNum"
:page-size="pageSize"
:page-sizes="[10, 20, 30, 40]"
layout="total, sizes, prev, pager, next, jumper"
:total="totalSize"
style="margin-top: 15px; text-align: center"
>
</el-pagination> -->
</template>
</div>
</template>
<script>
export default {
props: {
pointIdList: {
require: true,
type: Object,
default: () => {
return {};
},
},
tableData: {
require: true,
type: Array,
default: () => {
return [];
},
},
totalSize: {
require: true,
type: Number,
default: 0,
},
// pageNum: {
// require: true,
// type: Number,
// default: 1,
// },
// pageSize: {
// require: true,
// type: Number,
// default: 10,
// },
},
data() {
return {
//最低单体温度 最高温度 最低电压 最高电压 todo 这里的顺序需要和图形组件里的顺序保持一致,
colorMap: {
0: "minwd",
1: "maxwd",
2: "mindy",
3: "maxdy",
},
};
},
methods: {
//处理图形class 对应高亮设置
handleListClass(item) {
let className = "";
const { clusterDeviceId, deviceId } = item,
clusterIdList = Object.keys(this.pointIdList);
if (clusterIdList.includes(clusterDeviceId)) {
const index = this.pointIdList[clusterDeviceId].findIndex(
(ids) => ids === parseInt(deviceId)
);
if (index > -1) {
className = this.colorMap[index];
}
}
return className;
},
//查看表格行图表
chartDetail(row, dataType = "") {
const { clusterDeviceId, deviceId } = row;
this.$emit("chart", { clusterDeviceId, deviceId, dataType });
},
},
};
</script>
<style lang="scss" scoped>
.lists-container {
padding: 20px 0;
.lists {
margin: 10px 5px;
padding: 5px 9px;
font-size: 11px;
line-height: 20px;
border: 1.6px solid #09ada3;
border-radius: 5px;
position: relative;
color: #333333;
float: left;
box-sizing: content-box;
min-width: 60px;
width: auto;
cursor: pointer;
&::before {
display: block;
content: "";
top: -7px;
left: 50%;
transform: translateX(-50%);
position: absolute;
width: 45%;
height: 0;
border-bottom: 7px solid #09ada3;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
}
&.minwd {
border-color: #3794ff;
.wd {
color: #3794ff;
}
&::before {
border-bottom-color: #3794ff;
}
}
&.maxwd {
border-color: #ff3a3b;
.wd {
color: #ff3a3b;
}
&::before {
border-bottom-color: #ff3a3b;
}
}
&.mindy {
border-color: #de6902;
.dy {
color: #de6902;
}
&::before {
border-bottom-color: #de6902;
}
}
&.maxdy {
border-color: #ffb521;
.dy {
color: #ffb521;
}
&::before {
border-bottom-color: #ffb521;
}
}
}
}
.dtdc-pagination {
::v-deep {
.el-button {
padding: 2px 10px !important;
font-size: 11px;
line-height: 16px;
}
.activeBtn {
background-color: #09ada3;
border-color: #09ada3;
}
}
}
</style>

View File

@ -0,0 +1,125 @@
<template>
<div>
<el-table
class="common-table"
:data="tableData"
stripe
style="width: 100%; margin-top: 25px"
>
<el-table-column prop="deviceId" label="单体编号"> </el-table-column>
<el-table-column prop="clusterDeviceId" label="簇号"> </el-table-column>
<el-table-column prop="voltage" label="电压V">
<template slot-scope="scope">
<el-button
@click="chartDetail(scope.row, 'voltage')"
type="text"
size="small"
>
{{ scope.row.voltage }}
</el-button>
</template>
</el-table-column>
<el-table-column prop="temperature" label="温度(℃)">
<template slot-scope="scope">
<el-button
@click="chartDetail(scope.row, 'temperature')"
type="text"
size="small"
>
{{ scope.row.temperature }}
</el-button>
</template>
</el-table-column>
<el-table-column prop="soc" label="SOC%">
<template slot-scope="scope">
<el-button
@click="chartDetail(scope.row, 'soc')"
type="text"
size="small"
>
{{ scope.row.soc }}
</el-button>
</template>
</el-table-column>
<el-table-column prop="soh" label="SOH%">
<template slot-scope="scope">
<el-button
@click="chartDetail(scope.row, 'soh')"
type="text"
size="small"
>
{{ scope.row.soh }}
</el-button>
</template>
</el-table-column>
<el-table-column label="曲线图">
<template slot-scope="scope">
<el-button @click="chartDetail(scope.row)" type="text" size="small">
展示
</el-button>
</template>
</el-table-column>
</el-table>
<!-- <el-pagination
v-show="tableData.length > 0"
background
@size-change="(val) => $emit('handleSizeChange', val)"
@current-change="(val) => $emit('handleCurrentChange', val)"
:current-page="pageNum"
:page-size="pageSize"
:page-sizes="[10, 20, 30, 40]"
layout="total, sizes, prev, pager, next, jumper"
:total="totalSize"
style="margin-top: 15px; text-align: center"
>
</el-pagination> -->
</div>
</template>
<script>
export default {
props: {
tableData: {
require: true,
type: Array,
default: () => {
return [];
},
},
pointIdList: {
require: true,
type: Object,
default: () => {
return {};
},
},
totalSize: {
require: true,
type: Number,
default: 0,
},
// pageNum: {
// require: true,
// type: Number,
// default: 1,
// },
// pageSize: {
// require: true,
// type: Number,
// default: 10,
// },
},
data() {
return {};
},
methods: {
//查看表格行图表
chartDetail(row, dataType = "") {
const { clusterDeviceId, deviceId } = row;
this.$emit("chart", { clusterDeviceId, deviceId, dataType });
},
},
};
</script>
<style></style>

View File

@ -1,224 +1,335 @@
<template>
<el-card v-loading="loading" shadow="always" class="common-card-container common-card-container-no-title-bg">
<div slot="header">
<span class="large-title">单体电池实时数据</span>
</div>
<!-- 搜索栏-->
<el-form :inline="true" class="select-container">
<el-form-item label="电池堆">
<el-select v-model="search.stackId" placeholder="请选择" @change="changeStackId">
<el-option :label="item.deviceName" :value="item.id" v-for="(item,index) in stackOptions" :key="index+'stackOptions'"></el-option>
</el-select>
</el-form-item>
<el-form-item label="电池簇">
<el-select v-model="search.clusterId" :no-data-text="!search.stackId && stackOptions.length > 0 ? '请先选择电池堆':'无数据'" placeholder="请选择" :loading="clusterloading" loading-text="正在加载数据">
<el-option :label="item.deviceName" :value="item.id" v-for="(item,index) in clusterOptions" :key="index+'clusterOptions'"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSearch" native-type="button">搜索</el-button>
</el-form-item>
<el-form-item>
<el-button @click="onReset" native-type="button">重置</el-button>
</el-form-item>
</el-form>
<!-- 图表-->
<!-- <div style="margin:30px 0;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);">-->
<!-- <el-row style="background:#fff;margin:30px 0;">-->
<!-- <el-col :xs="24" :sm="24" :lg="24">-->
<!-- <bar-chart ref="barChart"/>-->
<!-- </el-col>-->
<!-- </el-row>-->
<!-- </div>-->
<el-table
class="common-table"
:data="tableData"
stripe
style="width: 100%;margin-top: 25px">
<el-table-column
prop="deviceId"
label="单体编号">
</el-table-column>
<el-table-column
prop="clusterDeviceId"
label="簇号">
</el-table-column>
<el-table-column
prop="voltage"
label="电压V"
>
<template slot-scope="scope">
<el-button
@click="chartDetail(scope.row,'voltage')"
type="text"
size="small">
{{scope.row.voltage}}
</el-button>
</template>
</el-table-column>
<el-table-column
prop="temperature"
label="温度(℃)">
<template slot-scope="scope">
<el-button
@click="chartDetail(scope.row,'temperature')"
type="text"
size="small">
{{scope.row.temperature}}
</el-button>
</template>
</el-table-column>
<el-table-column
prop="soc"
label="SOC%">
<template slot-scope="scope">
<el-button
@click="chartDetail(scope.row,'soc')"
type="text"
size="small">
{{scope.row.soc}}
</el-button>
</template>
</el-table-column>
<el-table-column
prop="soh"
label="SOH%">
<template slot-scope="scope">
<el-button
@click="chartDetail(scope.row,'soh')"
type="text"
size="small">
{{scope.row.soh}}
</el-button>
</template>
</el-table-column>
<el-table-column
label="曲线图">
<template slot-scope="scope">
<el-button
@click="chartDetail(scope.row)"
type="text"
size="small">
展示
</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-show="tableData.length>0"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-size="pageSize"
:page-sizes="[10, 20, 30, 40]"
layout="total, sizes, prev, pager, next, jumper"
:total="totalSize"
style="margin-top:15px;text-align: center"
>
</el-pagination>
<chart-detail ref="chartDetail"/>
</el-card>
<el-card
v-loading="loading"
shadow="always"
class="common-card-container common-card-container-no-title-bg"
>
<div slot="header">
<span class="large-title">单体电池实时数据</span>
</div>
<!-- 搜索栏-->
<el-form :inline="true" class="select-container">
<el-form-item label="编号">
<el-input
v-model="search.batteryId"
placeholder="请输入"
clearable
style="width: 150px"
/>
</el-form-item>
<el-form-item label="电池堆">
<el-select
v-model="search.stackId"
placeholder="请选择"
@change="changeStackId"
>
<el-option
:label="item.deviceName"
:value="item.id"
v-for="(item, index) in stackOptions"
:key="index + 'stackOptions'"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="电池簇">
<el-select
v-model="search.clusterId"
:no-data-text="
!search.stackId && stackOptions.length > 0
? '请先选择电池堆'
: '无数据'
"
placeholder="请选择"
:loading="clusterloading"
loading-text="正在加载数据"
>
<el-option
:label="item.deviceName"
:value="item.id"
v-for="(item, index) in clusterOptions"
:key="index + 'clusterOptions'"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSearch" native-type="button"
>搜索</el-button
>
</el-form-item>
<el-form-item>
<el-button @click="onReset" native-type="button">重置</el-button>
</el-form-item>
</el-form>
<!-- 切换 -->
<div class="tip-container">
<div class="color-tip" v-show="activeBtn === 'list'">
单体信息
<span class="tip minwd">最低单体温度</span>
<span class="tip maxwd">最高单体温度</span>
<span class="tip mindy">单体最低电压</span>
<span class="tip maxdy">单体最高电压</span>
</div>
<el-button-group class="ems-btns-group">
<el-button
:class="{ activeBtn: activeBtn === 'table' }"
@click="changeMenu('table')"
>图表</el-button
>
<el-button
:class="{ activeBtn: activeBtn === 'list' }"
@click="changeMenu('list')"
>图形</el-button
>
</el-button-group>
</div>
<component
:is="activeBtn === 'table' ? 'DtdcTable' : 'DtdcList'"
:tableData="tableData"
:totalSize="totalSize"
:pointIdList="pointIdList"
@chart="chartDetail"
></component>
<el-pagination
v-show="tableData.length > 0"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-size="pageSize"
:page-sizes="[10, 20, 30, 40]"
layout="total, sizes, prev, pager, next, jumper"
:total="totalSize"
style="margin-top: 15px; text-align: center"
>
</el-pagination>
<chart-detail ref="chartDetail" />
</el-card>
</template>
<script>
import BarChart from './BarChart'
import {getStackNameList, getClusterNameList, getClusterDataInfoList} from '@/api/ems/dzjk'
import BarChart from "./BarChart";
import {
getStackNameList,
getClusterNameList,
getClusterDataInfoList,
} from "@/api/ems/dzjk";
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
import ChartDetail from "./ChartDetail.vue";
import Table from "./Table.vue";
import List from "./List.vue";
export default {
name:'DzjkSbjkDtdc',
mixins:[getQuerySiteId],
components:{BarChart, ChartDetail},
name: "DzjkSbjkDtdc",
mixins: [getQuerySiteId],
components: { BarChart, ChartDetail, DtdcTable: Table, DtdcList: List },
computed: {
pointIdList() {
let obj = {};
this.pointData.forEach((item) => {
const {
maxCellTempId,
maxCellVoltageId,
minCellTempId,
minCellVoltageId,
} = item;
obj[item.clusterId] = [
parseInt(minCellTempId || 0),
parseInt(maxCellTempId || 0),
parseInt(minCellVoltageId || 0),
parseInt(maxCellVoltageId || 0),
]; //最低单体温度 最高温度 最低电压 最高电压 todo 这里的顺序需要和图形组件里的顺序保持一致,
});
return obj;
},
},
data() {
return {
loading:false,
clusterloading:false,
search:{stackId:'',clusterId:''},
stackOptions:[],//{id:'',deviceName:''}
clusterOptions:[],//{id:'',deviceName:''}
tableData:[],
pageSize:10,//分页栏当前每个数据总数
pageNum:1,//分页栏当前
totalSize:0,//table表格数据总
}
loading: false,
clusterloading: false,
search: { stackId: "", clusterId: "", batteryId: "" },
stackOptions: [], //{id:'',deviceName:''}
clusterOptions: [], //{id:'',deviceName:''}
tableData: [],
pointData: [],
pageSize: 40, //分页栏当前每个数据总
pageNum: 1, //分页栏当前页
totalSize: 0, //table表格数据总数
activeBtn: "table",
};
},
methods:{
methods: {
changeMenu(menu) {
const { activeBtn } = this;
activeBtn !== menu && (this.activeBtn = menu);
},
//查看表格行图表
chartDetail(row,dataType = ''){
const { clusterDeviceId, deviceId} = row,{siteId} = this
this.$refs.chartDetail.initChart({siteId,clusterDeviceId,deviceId},dataType)
chartDetail({ clusterDeviceId, deviceId, dataType = "" }) {
const { siteId } = this;
this.$refs.chartDetail.initChart(
{ siteId, clusterDeviceId, deviceId },
dataType
);
},
// 分页
handleSizeChange(val) {
this.pageSize = val;
this.$nextTick(()=>{
this.getTableData()
})
this.$nextTick(() => {
this.getTableData();
});
},
handleCurrentChange(val) {
this.pageNum = val
this.$nextTick(()=>{
this.getTableData()
})
this.pageNum = val;
this.$nextTick(() => {
this.getTableData();
});
},
// 搜索
onSearch(){
this.pageNum =1//每次搜索从1开始搜索
this.getTableData()
onSearch() {
this.pageNum = 1; //每次搜索从1开始搜索
this.getTableData();
},
// 重置
// 清空搜索栏选中数据
// 清空电池簇列表,保留电池堆列表
onReset(){
this.search={stackId:'',clusterId:''}
this.clusterOptions=[]
this.pageNum = 1
this.getTableData()
onReset() {
this.search = { stackId: "", clusterId: "", batteryId: "" };
this.clusterOptions = [];
this.pageNum = 1;
this.getTableData();
},
changeStackId(val){
if(val){
console.log('选择了电池堆,需要获取对应的电池簇',val,this.search.stackId)
this.search.clusterId=''
this.getClusterList()
changeStackId(val) {
if (val) {
console.log(
"选择了电池堆需要获取对应的电池簇",
val,
this.search.stackId
);
this.search.clusterId = "";
this.getClusterList();
}
},
//表格数据
getTableData(){
this.loading=true;
const {stackId:stackDeviceId,clusterId:clusterDeviceId} =this.search
const {siteId,pageNum,pageSize}=this
getClusterDataInfoList({stackDeviceId,clusterDeviceId,siteId,pageNum,pageSize}).then(response => {
this.tableData=response?.rows || [];
this.totalSize = response?.total || 0
}).finally(()=>{
this.loading=false;
getTableData() {
this.loading = true;
const {
stackId: stackDeviceId,
clusterId: clusterDeviceId,
batteryId,
} = this.search;
const { siteId, pageNum, pageSize } = this;
getClusterDataInfoList({
stackDeviceId,
clusterDeviceId,
siteId,
batteryId,
pageNum,
pageSize,
})
.then((response) => {
this.tableData = response?.rows?.[0]?.batteryList || []; //todo check
this.pointData = response?.rows?.[0]?.clusterList || []; //todo check
this.totalSize = response?.total || 0;
})
.finally(() => {
this.loading = false;
});
},
getStackList(){
getStackNameList(this.siteId).then(response => {
this.stackOptions = JSON.parse(JSON.stringify(response?.data || []))
getStackList() {
getStackNameList(this.siteId).then((response) => {
this.stackOptions = JSON.parse(JSON.stringify(response?.data || []));
});
},
getClusterList() {
this.clusterloading = true;
getClusterNameList({
stackDeviceId: this.search.stackId,
siteId: this.siteId,
})
.then((response) => {
this.clusterOptions = JSON.parse(
JSON.stringify(response?.data || [])
);
})
.finally(() => {
this.clusterloading = false;
});
},
getClusterList(){
this.clusterloading =true
getClusterNameList(this.search.stackId).then(response => {
this.clusterOptions = JSON.parse(JSON.stringify(response?.data || []))
}).finally(() => {this.clusterloading =false})
},
init(){
init() {
// 只有页面初次加载或切换站点的时候调用电池堆列表,其他情况不需要
this.search={stackId:'',clusterId:''}//保证切换站点时,清空选择项
this.getStackList()
this.getTableData()
}
this.search = { stackId: "", clusterId: "", batteryId: "" }; //保证切换站点时,清空选择项
this.clusterOptions = [];
this.pageNum = 1;
this.totalSize = 0;
this.getStackList();
this.getTableData();
},
},
mounted(){
mounted() {},
};
</script>
<style scoped lang="scss">
.tip-container {
text-align: right;
position: relative;
.color-tip {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
font-size: 11px;
line-height: 12px;
color: #333;
.tip {
padding-left: 30px;
position: relative;
&::before {
display: block;
content: "";
position: absolute;
left: 14px;
top: 50%;
transform: translateY(-50%);
width: 8px;
height: 8px;
border-radius: 50%;
}
&.minwd {
color: #3794ff;
&::before {
background: #3794ff;
}
}
&.maxwd {
color: #ff3a3b;
&::before {
background: #ff3a3b;
}
}
&.mindy {
color: #de6902;
&::before {
background: #de6902;
}
}
&.maxdy {
color: #ffb521;
&::before {
background: #ffb521;
}
}
}
}
::v-deep {
.el-button-group.ems-btns-group {
& > .el-button {
padding: 5px 30px !important;
font-size: 11px;
line-height: 16px;
// padding-left: 50px;
// padding-right: 50px;
// font-size: 16px;
// line-height: 24px;
}
}
}
}
</script>
</style>

View File

@ -1,5 +1,7 @@
<template>
<div class="ems-dashboard-editor-container ems-content-container-padding sbjk-ems-dashboard-editor-container">
<div
class="ems-dashboard-editor-container ems-content-container-padding sbjk-ems-dashboard-editor-container ems-third-menu-container"
>
<el-menu
class="ems-third-menu"
:default-active="$route.name"
@ -7,50 +9,58 @@
text-color="#666666"
active-text-color="#ffffff"
>
<el-menu-item :index="item.name" v-for="(item,index) in childrenRoute" :key="index+'dzjkChildrenRoute'">
<router-link style="height: 100%;width: 100%;display: block" :to="{path:item.path,query:$route.query}">
{{item.meta.title}}
<el-menu-item
:index="item.name"
v-for="(item, index) in childrenRoute"
:key="index + 'dzjkChildrenRoute'"
>
<router-link
style="height: 100%; width: 100%; display: block"
:to="{ path: item.path, query: $route.query }"
>
{{ item.meta.title }}
</router-link>
</el-menu-item>
</el-menu>
<div class="ems-content-container ems-content-container-padding sbjk-ems-content-container">
<div
class="ems-content-container ems-content-container-padding sbjk-ems-content-container"
>
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>
</div>
</template>
<script>
import { dzjk } from '@/router/ems'
const childrenRoute = dzjk[0].children.find(item=> item.name==='DzjkSbjk').children//获取到单站监控-设备监控下面的字路由
console.log('设备监控子路由',childrenRoute)
import { dzjk } from "@/router/ems";
const childrenRoute = dzjk[0].children.find(
(item) => item.name === "DzjkSbjk"
).children; //获取到单站监控-设备监控下面的字路由
console.log("设备监控子路由", childrenRoute);
export default {
name:'DzjkSbjk',
data(){
name: "DzjkSbjk",
data() {
return {
childrenRoute,
activeMenu:''
}
activeMenu: "",
};
},
mounted() {
console.log('当前设备监控页面路由',this.$route)
}
}
console.log("当前设备监控页面路由", this.$route);
},
};
</script>
<style scoped lang="scss">
.sbjk-ems-dashboard-editor-container{
.sbjk-ems-dashboard-editor-container {
display: flex;
background: #FFFFFF;
background: #ffffff;
}
.sbjk-ems-content-container{
margin-top:0;
padding-top:0;
.sbjk-ems-content-container {
margin-top: 0;
padding-top: 0;
padding-right: 0;
flex: 1;
}
</style>

View File

@ -12,10 +12,11 @@
<div>{{$store.state.ems.communicationStatusOptions[pcsItem.communicationStatus]}}</div>
<div>数据更新时间{{pcsItem.dataUpdateTime}}</div>
</div>
<!-- <div class="pcs-btns">-->
<!-- <el-button type="warning" size="small" @click="problemSaved">故障复位</el-button>-->
<!-- <el-button size="small" @click="machineClosed">关机</el-button>-->
<!-- </div>-->
<div class="pcs-btns">
<el-badge :value="pcsItem.alarmNum || 0" class="item">
<i class="el-icon-message-solid" style="font-size: 26px;color: #fff;display: block;"></i>
</el-badge>
</div>
</el-header>
<el-main style="padding: 0">
<div class="descriptions-main">
@ -91,11 +92,8 @@ export default {
if (action === 'confirm') {
instance.confirmButtonLoading = true;
setTimeout(() => {
// todo 调用接口如果关机成功 调用done方法 否则不关闭弹窗
done();
// setTimeout(() => {
instance.confirmButtonLoading = false;
// }, 300);
}, 3000);
} else {
done();
@ -122,11 +120,8 @@ export default {
if (action === 'confirm') {
instance.confirmButtonLoading = true;
setTimeout(() => {
// todo 调用接口如果关机成功 调用done方法 否则不关闭弹窗
done();
// setTimeout(() => {
instance.confirmButtonLoading = false;
// }, 300);
}, 3000);
} else {
done();

View File

@ -57,7 +57,7 @@ export default {
top: '10',
},
grid: {
left: "15%"
containLabel: true
},
tooltip: {
trigger: 'axis',

View File

@ -61,7 +61,7 @@ export default {
}
},
grid: {
left: "15%"
containLabel: true
},
textStyle:{
color:"#333333",

View File

@ -62,7 +62,7 @@ export default {
}
},
grid: {
left: "15%"
containLabel: true
},
textStyle:{
color:"#333333",

View File

@ -58,7 +58,7 @@ export default {
}
},
grid: {
left: "15%"
containLabel: true
},
textStyle:{
color:"#333333",

View File

@ -1,7 +1,6 @@
<template>
<div v-loading="loading">
<!-- todo 判断条件是否需要更新-->
<div class="yl-item-container" :class="{'yl-warn-item-container':item.workMode !== '0'}" v-for="(item,index) in list" :key="index+'ylLise'">
<div class="header">
<div class="header-title">{{item.systemName}}</div>