新增策略页面

This commit is contained in:
白菜
2025-06-26 01:29:16 +08:00
parent 89711b6a07
commit 1b19a91d74
8 changed files with 550 additions and 9 deletions

View File

@ -162,3 +162,8 @@
.select-container.el-form--inline .el-form-item{ .select-container.el-form--inline .el-form-item{
margin-right: 15px; margin-right: 15px;
} }
//红色背景颜色按钮
.alarm-btn,.alarm-btn:hover, .alarm-btn:focus{
background-color: #FC6B69;
border-color: #FC6B69;
}

View File

@ -0,0 +1,109 @@
<template>
<el-container class="clyx-container">
<el-header class="clyx-header">
<div class="clyx-title">策略状态<span class="clyx-status save">已运行</span></div>
<div class="clyx-btns">
<el-button v-if="!hideSettingBtn" size="small" @click="$refs.setting.dialogFormVisible = true">配置</el-button>
<el-button type="warning" class="alarm-btn" size="small" @click='close'>停止策略</el-button>
</div>
</el-header>
<el-main class="clyx-main">
<slot name="default"></slot>
<setting ref="setting"/>
</el-main>
</el-container>
</template>
<script>
import Setting from './Setting.vue'
export default {
name:'DzjkClpzClContainer',
components:{Setting},
props:{
hideSettingBtn:{
type:Boolean,
default:false
}
},
data() {
return {
}
},
methods:{
close(){
this.$confirm('确认要停止策略吗?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
showClose:false,
closeOnClickModal:false,
type: 'warning',
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
instance.confirmButtonLoading = true;
setTimeout(() => {
// todo 调用接口如果关机成功 调用done方法 否则不关闭弹窗
done();
// setTimeout(() => {
instance.confirmButtonLoading = false;
// }, 300);
}, 3000);
} else {
done();
}
}
}).then(() => {
//只有在故障复位成功的情况下会走到这里
this.$message({
type: 'success',
message: '停止策略成功!'
});
}).catch(() => {
//取消复位
});
}
},
mounted(){
}
}
</script>
<style scoped lang="scss">
.clyx-container{
border:1px solid #eee;
.clyx-header{
background: #F1F5FB;
display: flex;
position: relative;
justify-content: flex-start;
align-items: center;
padding: 0;
height: 60px;
border-radius: 6px 6px 0 0;
.clyx-title{
color: #333333;
line-height: 20px;
padding: 0 50px 0 25px;
.clyx-status{
font-weight: 500;
font-size: 16px;
&.danger{
color:#FC6B69;
}
&.save{
color:#09ADA3;
}
&.keep{
color:#3C81FF;
}
}
}
.clyx-btns{
position: absolute;
right: 25px;
top: 50%;
transform: translateY(-50%);
}
}
}
</style>

View File

@ -0,0 +1,66 @@
<template>
<el-dialog
title="主从策略配置"
custom-class="ems-dialog"
:visible.sync="dialogFormVisible"
width="420px"
:close-on-click-modal="false"
:close-on-press-escape="false"
@close="cancel"
>
<el-form :model="form" label-width="100px">
<el-form-item label="主策略">
<el-select v-model="form.main" placeholder="请选择">
<el-option label="主策略一" value="1"></el-option>
<el-option label="主策略二" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="辅助策略">
<el-select v-model="form.assis" placeholder="请选择">
<el-option label="辅助策略一" value="1"></el-option>
<el-option label="辅助策略二" value="2"></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible=false"> </el-button>
<el-button type="primary" :loading="loading" @click="sure"> </el-button>
</div>
</el-dialog>
</template>
<script>
export default {
data(){
return {
loading:false,
dialogFormVisible:false,
form:{
main:'',
assis:''
}
}
},
methods:{
cancel(){
this.form.main='';
this.form.assis='';
},
sure(){
if(this.form.main===''||this.form.assis===''){
return this.$alert('请选择正确的策略');
}
this.loading = true
setTimeout(()=>{
this.loading = false
//如果接口调用成功 关闭弹窗
this.dialogFormVisible = false;
},3000)
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@ -1,21 +1,34 @@
<template> <template>
<div style="width:100%"> <cl-container>
策略运行 <template v-slot:default>
</div> <div class="cl-items cl-items-main">
<div class="cl-header">主策略</div>
<div class="cl-content">
<div class="cl-name">削峰填谷</div>
</div>
</div>
<div class="cl-items">
<div class="cl-header">辅助策略</div>
<div class="cl-content">
<div class="cl-name">需量控制</div>
</div>
</div>
</template>
</cl-container>
</template> </template>
<script> <script>
import ClContainer from './../ClContainer.vue'
export default { export default {
name:'DzjkClpzClyx', name:'DzjkClpzClyx',
components:{ClContainer},
data() { data() {
return { return {
} }
}, },
methods:{
},
mounted(){ mounted(){
} }
@ -23,5 +36,44 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.clyx-main{
padding:0 12px 0 12px;
.cl-items{
width: 228px;
height: 156px;
display: inline-block;
margin:24px 12px 0 12px;
font-size:14px;
color:#333333;
border: 1px solid #eeeeee;
.cl-header{
background: #FFE5AC;
text-align: center;
font-size:16px;
line-height: 40px;
height: 40px;
width: 100%;
}
.cl-content{
background-color: #ffffff;
position: relative;
height: 114px;
width: 100%;
.cl-name{
position: absolute;
top:50%;
left:50%;
transform: translate(-50%,-50%);
}
}
&.cl-items-main{
.cl-header{
background: #FFBE29;
}
.cl-content{
background-color: #FFF2CB;
}
}
}
}
</style> </style>

View File

@ -0,0 +1,87 @@
<template>
<el-card shadow="always" class="common-card-container common-card-container-body-no-padding" style="margin-top:25px;">
<div slot="header">
<span class="card-title">策略模板曲线展示</span>
</div>
<div style="height: 360px" id="tempChart"/>
</el-card>
</template>
<style scoped lang="scss"></style>
<script>
import * as echarts from 'echarts'
import resize from '@/mixins/ems/resize'
export default {
mixins: [resize],
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(document.querySelector('#tempChart'))
this.setOptions()
},
setOptions() {
this.chart.setOption({
color:['#FFBD00','#3C81FF'],
legend: {
left: 'center',
bottom: '10',
},
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
textStyle:{
color:"#333333",
},
xAxis: {
data: ['01:00','02:00','03:00','05:00','06:00','07:00','08:00','09:00','10:00'],
axisLine: {
lineStyle:{
color: '#333333',
}
}
},
yAxis: {
type: 'value',
axisLine: {
lineStyle:{
color: '#333333',
}
}
},
series: [
{
name:'模板一',
data: [80,92,1,34,90,130,320,80,9,91],
type: 'line',
},{
name:'模板二',
data: [820,932,901,934,1290,1330,1320,820,932,901],
type: 'line',
}]
})
}
}
}
</script>

View File

@ -0,0 +1,123 @@
<template>
<el-card shadow="always" class="common-card-container">
<div slot="header">
<span class="card-title">新增模板</span>
<div style="float: right; padding: 3px 0">
<el-button type="primary" size="mini">新增</el-button>
<el-button type="warning" size="mini">编辑</el-button>
<el-button type="primary" class="alarm-btn" size="mini">删除</el-button>
</div>
</div>
<div>
<el-button-group class="ems-btns-group">
<el-button v-for="(item,index) in tempList" :key="index+'tempList'" :class="{'activeBtn' : activeBtn === item.id}" type="small" @click="changeTemp(item.id)">{{item.name}}</el-button>
</el-button-group>
<el-table
:data="tableData"
:span-method="tableSpanFilter"
border
style="width: 100%;">
<!-- todo 如果要在span-method中使用column.property 在表格中必须定义prop="xxx"属性-->
<el-table-column
prop="name"
label="模板名称"
width="180">
</el-table-column>
<el-table-column
prop="status"
label="SOC限制">
<template slot-scope="scope">
<el-switch
:value="scope.row.status === 1"
disabled>
</el-switch>
</template>
</el-table-column>
<el-table-column
prop="min"
label="SOC下限">
<template slot-scope="scope">
{{scope.row.min}}%
</template>
</el-table-column>
<el-table-column
prop="max"
label="SOC上限">
<template slot-scope="scope">
{{scope.row.max}}%
</template>
</el-table-column>
<el-table-column
prop="startTime"
label="开始时间">
</el-table-column>
<el-table-column
prop="endTime"
label="结束时间">
</el-table-column>
<el-table-column
prop="cfgl"
label="充放功率kW">
</el-table-column>
<el-table-column
prop="powerStatus"
label="充电状态">
</el-table-column>
</el-table>
</div>
</el-card>
</template>
<style scoped lang="scss">
</style>
<script>
export default {
data() {
return {
activeBtn:1,
tempList:[
{name:'模板1',id:1},
{name:'模板2',id:2},
{name:'模板3',id:3},
],
tableData:[
{name:'模板一',status:1,min:10,max:90,startTime:'2023/05/07',endTime:'2030/05/07',cfgl:100,powerStatus:'充电'},
{name:'模板一',status:1,min:10,max:90,startTime:'2024/06/07',endTime:'2030/05/07',cfgl:110,powerStatus:'充电'},
{name:'模板一',status:1,min:10,max:90,startTime:'2023/07/07',endTime:'2030/05/07',cfgl:120,powerStatus:'充电'},
{name:'模板一',status:1,min:10,max:90,startTime:'2023/08/07',endTime:'2030/05/07',cfgl:130,powerStatus:'充电'},
{name:'模板一',status:1,min:10,max:90,startTime:'2023/09/07',endTime:'2030/05/07',cfgl:140,powerStatus:'充电'},
],
mixinPrototype:['name','status','min','max']
}
},
methods:{
changeTemp(id){
//切换模板 更新数据
if(id !== this.activeBtn){
this.activeBtn=id;
}
},
tableSpanFilter({ row, column, rowIndex, columnIndex }){
if(!this.mixinPrototype.includes(column.property)) return { rowspan: 1,colspan: 1 }
if(rowIndex===0){
return {
rowspan: this.tableData.length,
colspan: 1
};
}else{
return {
rowspan: 0,
colspan: 0
}
}
}
},
mounted(){
}
}
</script>

View File

@ -0,0 +1,80 @@
<template>
<el-card shadow="always" class="common-card-container" style="margin-top:25px;">
<div slot="header">
<span class="card-title">策略配置削峰填谷</span>
<div style="float: right; padding: 3px 0">
<el-button type="warning" size="mini">编辑</el-button>
</div>
</div>
<el-form :inline="true" class="select-container">
<el-form-item label="时间配置">
<el-select v-model="timeType" placeholder="请选择" :loading="loading" loading-text="正在加载数据">
<el-option :label="item.name" :value="item.id" v-for="(item,index) in timeOptions" :key="index+'timeOptions'"></el-option>
</el-select>
</el-form-item>
</el-form>
<div style="padding:0 6px 12px 6px;">
<div class="cl-items" v-for="item in 12" :key="item+'lclf'">
<div class="cl-header">{{item}}</div>
<div class="cl-content">
<div class="cl-name">两放两冲</div>
</div>
</div>
</div>
</el-card>
</template>
<style scoped lang="scss">
.cl-items{
width: 144px;
height: 90px;
line-height: 16px;
display: inline-block;
margin:12px 6px 0 6px;
font-size:14px;
color:#333333;
border: 1px solid #eeeeee;
.cl-header{
background: #FFE5AC;
text-align: center;
font-size:16px;
line-height: 40px;
height: 40px;
width: 100%;
}
.cl-content{
background-color: #ffffff;
position: relative;
height: 48px;
width: 100%;
.cl-name{
position: absolute;
top:50%;
left:50%;
transform: translate(-50%,-50%);
}
}
}
</style>
<script>
export default {
data() {
return {
loading:false,
timeType:1,
timeOptions:[
{name:'按日',id:1},
{name:'按月',id:2},
{name:'按年',id:3},
]
}
},
methods:{
},
mounted(){
}
}
</script>

View File

@ -1,14 +1,23 @@
<template> <template>
<div style="width:100%"> <cl-container :hideSettingBtn="true">
削峰填谷 <template v-slot:default>
</div> <temp-table/>
<time-setting/>
<temp-power-chart/>
</template>
</cl-container>
</template> </template>
<script> <script>
import ClContainer from './../ClContainer.vue'
import TempTable from "./TempTable.vue";
import TimeSetting from "./TimeSetting.vue";
import TempPowerChart from "./TempPowerChart.vue";
export default { export default {
name:'DzjkClpzXftg', name:'DzjkClpzXftg',
components:{ClContainer,TempTable,TimeSetting,TempPowerChart},
data() { data() {
return { return {
@ -23,5 +32,15 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
::v-deep{
.common-card-container .el-card__header{
padding:5px 20px;
height:44px;
.card-title{
line-height: 34px;
}
}
}
</style> </style>