develop_cloud #1

Merged
dashixiong merged 234 commits from develop_cloud into main-cloud 2026-02-11 02:06:04 +00:00
99 changed files with 9786 additions and 30 deletions
Showing only changes of commit 2cd60ea105 - Show all commits

View File

@ -61,9 +61,9 @@ export function getClusterNameList({stackDeviceId,siteId}) {
})
}
//单体电池表格数据
export function getClusterDataInfoList({siteId, stackDeviceId, clusterDeviceId, pageSize, pageNum}) {
export function getClusterDataInfoList({siteId, stackDeviceId, clusterDeviceId,batteryId, pageSize, pageNum}) {
return request({
url: `/ems/siteMonitor/getClusterDataInfoList?clusterDeviceId=${clusterDeviceId}&siteId=${siteId}&stackDeviceId=${stackDeviceId}&pageSize=${pageSize}&pageNum=${pageNum}`,
url: `/ems/siteMonitor/getClusterDataInfoList?clusterDeviceId=${clusterDeviceId}&siteId=${siteId}&stackDeviceId=${stackDeviceId}&batteryId=${batteryId}&pageSize=${pageSize}&pageNum=${pageNum}`,
method: 'get'
})
}

View File

@ -1,35 +1,45 @@
<template>
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
<el-card
shadow="always"
class="common-card-container common-card-container-body-no-padding"
>
<div slot="header">
<span class="card-title">策略信息</span>
</div>
<!-- <el-empty :image-size="100" ></el-empty> -->
<div style="box-sizing: border-box; height: 250px;padding:20px 15px;" >
<div
style="
box-sizing: border-box;
height: 250px;
padding: 20px 15px;
overflow-y: auto;
"
>
<el-descriptions class="home-normal-info" :column="2">
<el-descriptions-item size="mini" label="模板名称">模板1</el-descriptions-item>
<el-descriptions-item size="mini" label="SOC限制">/</el-descriptions-item>
<el-descriptions-item size="mini" label="SOC下限">0%</el-descriptions-item>
<el-descriptions-item size="mini" label="SOC限">100%</el-descriptions-item>
<el-descriptions-item size="mini" label="模板名称">{{
info.mainStrategyName || "-"
}}</el-descriptions-item>
<el-descriptions-item size="mini" label="SOC限">{{
mainInfo.sdcLimit === 1 ? "开" : mainInfo.sdcLimit === 0 ? "关" : "-"
}}</el-descriptions-item>
<el-descriptions-item size="mini" label="SOC下限%">{{
formatNumber(mainInfo.sdcDown)
}}</el-descriptions-item>
<el-descriptions-item size="mini" label="SOC上限%">{{
formatNumber(mainInfo.sdcUp)
}}</el-descriptions-item>
</el-descriptions>
<el-table
:data="info.tableData || []"
:data="info.siteMonitorDataVo || []"
border
style="width: 100%;margin-top:15px;">
<el-table-column
prop="startTime"
label="开始时间">
size="mini"
style="width: 100%; margin-top: 15px"
>
<el-table-column prop="startTime" label="开始时间"> </el-table-column>
<el-table-column prop="endTime" label="结束时间"> </el-table-column>
<el-table-column prop="chargeDischargePower" label="充放功率kW">
</el-table-column>
<el-table-column
prop="endTime"
label="结束时间">
</el-table-column>
<el-table-column
prop="chargeDischargePower"
label="充放功率kW">
</el-table-column>
<el-table-column
prop="chargeStatus"
label="充电状态">
<el-table-column prop="chargeStatus" label="充电状态">
<template slot-scope="scope">
{{ chargeStatusOptions[scope.row.chargeStatus] }}
</template>
@ -39,33 +49,34 @@
</el-card>
</template>
<script>
import {mapState} from 'vuex'
import { mapState } from "vuex";
import { formatNumber } from "@/filters/ems";
export default {
props: {
info: {
require: true,
type: Object,
default: () => {
return {}
}
}
return {};
},
},
},
computed: {
...mapState({
chargeStatusOptions: state => state?.ems?.chargeStatusOptions || {},
chargeStatusOptions: (state) => state?.ems?.chargeStatusOptions || {},
}),
mainInfo() {
return this.info.siteMonitorDataVo.length > 0
? this.info.siteMonitorDataVo[0]
: {};
},
},
data() {
return {
}
return {};
},
methods: {
}
}
formatNumber,
},
};
</script>
<style lang="scss" scoped>
</style>
<style lang="scss" scoped></style>

View File

@ -1,38 +1,61 @@
<template>
<div v-loading="loading">
<el-row style="background:#fff;" class="row-container" :gutter="15">
<el-row style="background: #fff" class="row-container" :gutter="15">
<el-col v-if="tableData.length > 0" :xs="24" :sm="24" :lg="24">
<alarm-table :tableData="tableData" />
</el-col>
<el-col :xs="24" :sm="24" :lg="6">
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
<el-card
shadow="always"
class="common-card-container common-card-container-body-no-padding"
>
<div slot="header">
<span class="card-title">静态信息</span>
</div>
<div style="box-sizing: border-box; height: 250px;padding:20px 15px;" >
<div
style="box-sizing: border-box; height: 250px; padding: 20px 15px"
>
<el-descriptions class="home-normal-info" :column="1">
<el-descriptions-item size="mini" v-for="(item,index) in singleZdInfo" :key="index+'singleZdInfo'" :label="item.title">{{info[item.attr] | formatNumber }}</el-descriptions-item>
<el-descriptions-item
size="mini"
v-for="(item, index) in singleZdInfo"
:key="index + 'singleZdInfo'"
:label="item.title"
>{{ info[item.attr] | formatNumber }}</el-descriptions-item
>
</el-descriptions>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="24" :lg="8">
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding">
<el-card
shadow="always"
class="common-card-container common-card-container-body-no-padding"
>
<div slot="header">
<span class="card-title">总累计运行数据</span>
</div>
<div style="box-sizing: border-box; height: 250px;padding:20px 15px;" >
<div
style="box-sizing: border-box; height: 250px; padding: 20px 15px"
>
<el-row :gutter="20">
<el-col :span="12" v-for="(item,index) in sjglData" :key="index+'sjglData'" class="sjgl-data">
<el-col
:span="12"
v-for="(item, index) in sjglData"
:key="index + 'sjglData'"
class="sjgl-data"
>
<div class="sjgl-title">{{ item.title }}</div>
<div class="sjgl-value">{{runningInfo[item.attr] | formatNumber}}</div>
<div class="sjgl-value">
{{ runningInfo[item.attr] | formatNumber }}
</div>
</el-col>
</el-row>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="24" :lg="10">
<cl-info :info="{}"/>
<cl-info :info="runningInfo.strategyTempInfo" />
</el-col>
<el-col :xs="24" :sm="24" :lg="24">
<week-chart ref="weekChart" />
@ -41,87 +64,98 @@
<active-chart ref="activeChart" />
</el-col>
</el-row>
</div>
</template>
<script>
import {getSingleSiteBaseInfo} from '@/api/ems/zddt'
import {getDzjkHomeView} from '@/api/ems/dzjk'
import { getSingleSiteBaseInfo } from "@/api/ems/zddt";
import { getDzjkHomeView } from "@/api/ems/dzjk";
import WeekChart from "./WeekChart.vue";
import ActiveChart from "./ActiveChart.vue";
import AlarmTable from "./AlarmTable.vue";
import ClInfo from './ClInfo.vue';
import getQuerySiteId from '@/mixins/ems/getQuerySiteId'
import ClInfo from "./ClInfo.vue";
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
export default {
name:'DzjkSbjkHome',
name: "DzjkSbjkHome",
components: { WeekChart, ActiveChart, AlarmTable, ClInfo },
mixins: [getQuerySiteId],
data() {
return {
loading: false,
singleZdInfo:[{
title:'电站位置',
attr:'siteAddress'
},{
title:'投运时间',
attr:'runningTime'
},{
title:'装机功率(MW)',
attr:'installPower'
},{
title:'装机容量(MW)',
attr:'installCapacity',
}],
sjglData:[{
title:'今日充电量MWh',
attr:'dayChargedCap'
},{
title:'今日放电量MWh',
attr:'dayDisChargedCap'
},{
title:'总充电量MWh',
attr:'totalChargedCap'
},{
title:'总放电量MWh',
attr:'totalDischargedCap'
}],
singleZdInfo: [
{
title: "电站位置",
attr: "siteAddress",
},
{
title: "投运时间",
attr: "runningTime",
},
{
title: "装机功率(MW)",
attr: "installPower",
},
{
title: "装机容量(MW)",
attr: "installCapacity",
},
],
sjglData: [
{
title: "今日充电量MWh",
attr: "dayChargedCap",
},
{
title: "今日放电量MWh",
attr: "dayDisChargedCap",
},
{
title: "总充电量MWh",
attr: "totalChargedCap",
},
{
title: "总放电量MWh",
attr: "totalDischargedCap",
},
],
info: {}, //基本信息
runningInfo: {}, //总累计运行数据+报警表格
}
};
},
computed: {
tableData() {
console.log('this.runningInfo?.siteMonitorHomeAlarmVo ',this.runningInfo?.siteMonitorHomeAlarmVo )
return this.runningInfo?.siteMonitorHomeAlarmVo || []
}
console.log(
"this.runningInfo?.siteMonitorHomeAlarmVo ",
this.runningInfo?.siteMonitorHomeAlarmVo
);
return this.runningInfo?.siteMonitorHomeAlarmVo || [];
},
},
methods: {
getBaseInfo() {
return getSingleSiteBaseInfo(this.siteId).then(response => {
this.info = response?.data || {}
})
return getSingleSiteBaseInfo(this.siteId).then((response) => {
this.info = response?.data || {};
});
},
getRunningInfo() {
return getDzjkHomeView(this.siteId).then(response => {
this.runningInfo = response?.data || {}
})
return getDzjkHomeView(this.siteId).then((response) => {
this.runningInfo = response?.data || {};
});
},
init() {
this.loading = true
this.loading = true;
// 功率曲线
this.$refs.activeChart.init(this.siteId)
this.$refs.activeChart.init(this.siteId);
// 一周冲放曲线
this.$refs.weekChart.init(this.siteId)
this.$refs.weekChart.init(this.siteId);
// 静态信息 this.getBaseInfo()
// 总累计运行数据+故障告警 this.getRunningInfo()
Promise.all([this.getBaseInfo(), this.getRunningInfo()]).finally(() => {
this.loading = false
})
}
this.loading = false;
});
},
}
},
};
</script>
<style scoped lang="scss">
@ -134,7 +168,8 @@ export default {
//数据概览
.sjgl-data {
text-align: center;
&:nth-child(1),&:nth-child(2){
&:nth-child(1),
&:nth-child(2) {
margin-bottom: 25px;
}
.sjgl-title {
@ -150,7 +185,6 @@ export default {
word-wrap: break-word;
}
}
</style>
<style lang="scss">
@ -181,5 +215,4 @@ export default {
}
}
}
</style>

View File

@ -0,0 +1,188 @@
<template>
<div>
<template v-if="totalSize === 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>#{{ 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 [];
},
},
// pageNum: {
// require: true,
// type: Number,
// default: 1,
// },
// pageSize: {
// require: true,
// type: Number,
// default: 10,
// },
// totalSize: {
// require: true,
// type: Number,
// default: 0,
// },
},
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);
console.log("啊啊啊啊啊", clusterDeviceId, deviceId, clusterIdList);
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: 10px;
border: 1.6px solid #09ada3;
border-radius: 5px;
position: relative;
color: #333333;
line-height: 20px;
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

@ -60,11 +60,11 @@
</template>
</el-table-column>
</el-table>
<el-pagination
<!-- <el-pagination
v-show="tableData.length > 0"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
@size-change="(val) => $emit('handleSizeChange', val)"
@current-change="(val) => $emit('handleCurrentChange', val)"
:current-page="pageNum"
:page-size="pageSize"
:page-sizes="[10, 20, 30, 40]"
@ -72,7 +72,7 @@
:total="totalSize"
style="margin-top: 15px; text-align: center"
>
</el-pagination>
</el-pagination> -->
</div>
</template>
@ -86,21 +86,21 @@ export default {
return [];
},
},
pageNum: {
require: true,
type: Number,
default: 1,
},
pageSize: {
require: true,
type: Number,
default: 10,
},
totalSize: {
require: true,
type: Number,
default: 0,
},
// pageNum: {
// require: true,
// type: Number,
// default: 1,
// },
// pageSize: {
// require: true,
// type: Number,
// default: 10,
// },
// totalSize: {
// require: true,
// type: Number,
// default: 0,
// },
},
data() {
return {};
@ -111,13 +111,6 @@ export default {
const { clusterDeviceId, deviceId } = row;
this.$emit("chart", { clusterDeviceId, deviceId, dataType });
},
// 分页
handleSizeChange(val) {
this.$emit("handleSizeChange", val);
},
handleCurrentChange(val) {
this.$emit("handleCurrentChange", val);
},
},
};
</script>

View File

@ -11,7 +11,7 @@
<el-form :inline="true" class="select-container">
<el-form-item label="编号">
<el-input
v-model="search.deviceId"
v-model="search.batteryId"
placeholder="请输入"
clearable
style="width: 150px"
@ -60,16 +60,47 @@
<el-button @click="onReset" native-type="button">重置</el-button>
</el-form-item>
</el-form>
<!-- 表格 -->
<dtdc-table
<!-- 切换 -->
<div class="tip-container">
<div class="color-tip">
单体信息
<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"
:pageNum="pageNum"
:pageSize="pageSize"
:totalSize="totalSize"
:pointIdList="pointIdList"
@chart="chartDetail"
@handleSizeChange="handleSizeChange"
@handleCurrentChange="handleCurrentChange"
/>
></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>
@ -84,24 +115,51 @@ import {
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, DtdcTable: Table },
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: "", deviceId: "" },
search: { stackId: "", clusterId: "", batteryId: "" },
stackOptions: [], //{id:'',deviceName:''}
clusterOptions: [], //{id:'',deviceName:''}
tableData: [],
pageSize: 10, //分页栏当前每个数据总数
pointData: [],
pageSize: 40, //分页栏当前每个数据总数
pageNum: 1, //分页栏当前页数
totalSize: 0, //table表格数据总数
activeBtn: "table",
};
},
methods: {
changeMenu(menu) {
const { activeBtn } = this;
activeBtn !== menu && (this.activeBtn = menu);
},
//查看表格行图表
chartDetail({ clusterDeviceId, deviceId, dataType = "" }) {
const { siteId } = this;
@ -113,6 +171,7 @@ export default {
// 分页
handleSizeChange(val) {
this.pageSize = val;
if (this.pageSize * this.pageNum > this.totalSize) this.pageNum = 1; //todo
this.$nextTick(() => {
this.getTableData();
});
@ -132,7 +191,7 @@ export default {
// 清空搜索栏选中数据
// 清空电池簇列表,保留电池堆列表
onReset() {
this.search = { stackId: "", clusterId: "", deviceId: "" };
this.search = { stackId: "", clusterId: "", batteryId: "" };
this.clusterOptions = [];
this.pageNum = 1;
this.getTableData();
@ -154,19 +213,20 @@ export default {
const {
stackId: stackDeviceId,
clusterId: clusterDeviceId,
deviceId,
batteryId,
} = this.search;
const { siteId, pageNum, pageSize } = this;
getClusterDataInfoList({
stackDeviceId,
clusterDeviceId,
siteId,
// deviceId,
batteryId,
pageNum,
pageSize,
})
.then((response) => {
this.tableData = response?.rows || [];
this.tableData = response?.rows?.[0]?.batteryList || []; //todo check
this.pointData = response?.rows?.[0]?.clusterList || []; //todo check
this.totalSize = response?.total || 0;
})
.finally(() => {
@ -203,3 +263,70 @@ export default {
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;
}
}
}
}
</style>