新增设备:TCP设备新增从站地址

策略配置:新增放电状态、可输入负数、开始、结束时间组件更换
This commit is contained in:
白菜
2025-12-26 20:19:20 +08:00
parent f3fda19c64
commit 84bc29410a
3 changed files with 453 additions and 359 deletions

View File

@ -17,7 +17,7 @@ const ems = {
deviceTypeOptions: {'TCP': 'TCP', 'RTU': 'RTU'},//设备类型 deviceTypeOptions: {'TCP': 'TCP', 'RTU': 'RTU'},//设备类型
ticketStatusOptions: {1: '待处理', 2: '处理中', 3: '已处理'},//工单处理状态 ticketStatusOptions: {1: '待处理', 2: '处理中', 3: '已处理'},//工单处理状态
strategyStatusOptions: {'0': '未启用', '1': '已运行', '2': '已暂停', '3': '禁用', '4': '删除'},//策略状态 strategyStatusOptions: {'0': '未启用', '1': '已运行', '2': '已暂停', '3': '禁用', '4': '删除'},//策略状态
chargeStatusOptions: {'1': '充电', '2': '待机'},//冲放状态 chargeStatusOptions: {'1': '充电', '2': '待机', '3': '放电'},//冲放状态
comparisonOperatorOptions: {'>': '>', '<': '<', '=': '=', '>=': '>=', '<=': '<='}, comparisonOperatorOptions: {'>': '>', '<': '<', '=': '=', '>=': '>=', '<=': '<='},
relationWithPoint: {'||': '||', '&&': '&&'} relationWithPoint: {'||': '||', '&&': '&&'}
}, },

View File

@ -1,5 +1,6 @@
<template> <template>
<el-dialog :visible.sync="dialogTableVisible" class="ems-dialog" :title="mode === 'add'?'新增模板':`编辑模板` "> <el-dialog :visible.sync="dialogTableVisible" class="ems-dialog add-template-dialog"
:title="mode === 'add'?'新增模板':`编辑模板` ">
<el-form ref="addTempForm" :model="formData" :rules="rules" size="medium" label-width="100px"> <el-form ref="addTempForm" :model="formData" :rules="rules" size="medium" label-width="100px">
<el-form-item label="模板名称" prop="templateName"> <el-form-item label="模板名称" prop="templateName">
<el-input v-model="formData.templateName" placeholder="请输入" clearable :style="{width: '100%'}"> <el-input v-model="formData.templateName" placeholder="请输入" clearable :style="{width: '100%'}">
@ -21,36 +22,52 @@
<!-- 新增时间段表单--> <!-- 新增时间段表单-->
<el-collapse-transition> <el-collapse-transition>
<el-card v-show="showAddTime" shadow="always" class="common-card-container" style="margin-top:25px;"> <el-card v-show="showAddTime" shadow="always" class="common-card-container" style="margin-top:25px;">
<el-form class="add-time-form transition-box" ref="addTimeForm" :model="formInline" :rules="formInlineRule" label-width="100px" style="margin-top:25px"> <el-form class="add-time-form transition-box" ref="addTimeForm" :model="formInline" :rules="formInlineRule"
<el-form-item label="开始时间" prop="startTime"> label-width="100px" style="margin-top:25px">
<el-time-select <!-- <el-form-item label="开始时间" prop="startTime">-->
placeholder="开始时间" <!-- <el-time-select-->
v-model="formInline.startTime" <!-- placeholder="开始时间"-->
:picker-options="{ <!-- v-model="formInline.startTime"-->
start: '00:00', <!-- :picker-options="{-->
step: '01:00', <!-- start: '00:00',-->
end: '23:00', <!-- step: '00:01',-->
}"> <!-- end: '23:00',-->
</el-time-select> <!-- }">-->
</el-form-item> <!-- </el-time-select>-->
<el-form-item label="结束时间" prop="endTime"> <!-- </el-form-item>-->
<el-time-select <!-- <el-form-item label="结束时间" prop="endTime">-->
placeholder="结束时间" <!-- <el-time-select-->
v-model="formInline.endTime" <!-- placeholder="结束时间"-->
:picker-options="{ <!-- v-model="formInline.endTime"-->
start: '00:00', <!-- :picker-options="{-->
step: '01:00', <!-- start: '00:00',-->
end: '23:00', <!-- step: '00:01',-->
minTime: formInline.startTime <!-- end: '23:00',-->
}"> <!-- minTime: formInline.startTime-->
</el-time-select> <!-- }">-->
<!-- </el-time-select>-->
<!-- </el-form-item>-->
<el-form-item label="时间范围" prop="timeRange">
<el-time-picker
is-range
v-model="formInline.timeRange"
range-separator=""
start-placeholder="开始时间"
end-placeholder="结束时间"
placeholder="选择时间范围"
format="HH:mm"
value-format="HH:mm"
:style="{width: '100%'}">
</el-time-picker>
</el-form-item> </el-form-item>
<el-form-item label="冲放功率" prop="chargeDischargePower"> <el-form-item label="冲放功率" prop="chargeDischargePower">
<el-input v-model="formInline.chargeDischargePower" placeholder="请输入"></el-input> <el-input v-model="formInline.chargeDischargePower" placeholder="请输入"
:style="{width: '100%'}"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="充电状态" prop="chargeStatus"> <el-form-item label="充电状态" prop="chargeStatus">
<el-select v-model="formInline.chargeStatus" placeholder="请选择"> <el-select v-model="formInline.chargeStatus" placeholder="请选择" :style="{width: '100%'}">
<el-option v-for="(value,key) in chargeStatusOptions" :key="key+'chargeStatusOptions'" :label="value" :value="key"></el-option> <el-option v-for="(value,key) in chargeStatusOptions" :key="key+'chargeStatusOptions'" :label="value"
:value="key"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
@ -64,7 +81,6 @@
:data="tableData" :data="tableData"
border border
style="width: 100%;margin-top:25px"> style="width: 100%;margin-top:25px">
<!-- todo 如果要在span-method中使用column.property 在表格中必须定义prop="xxx"属性-->
<el-table-column <el-table-column
prop="startTime" prop="startTime"
label="开始时间"> label="开始时间">
@ -107,13 +123,18 @@
<script> <script>
import {mapState} from 'vuex' import {mapState} from 'vuex'
import {addStrategyTemp, editStrategyTemp, getStrategyTempDetail} from '@/api/ems/dzjk' import {addStrategyTemp, editStrategyTemp, getStrategyTempDetail} from '@/api/ems/dzjk'
export default { export default {
inject: ['$home'], inject: ['$home'],
data() { data() {
const now = new Date()
const year = now.getFullYear(), month = now.getMonth(), day = now.getDate()
const range = [new Date(year, month, day, 0), new Date(year, month, day, 23)]
return { return {
mode: '', mode: '',
editTempId: '', editTempId: '',
dialogTableVisible: false, dialogTableVisible: false,
secondRange: range,
formData: { formData: {
templateName: '', templateName: '',
sdcLimit: false, sdcLimit: false,
@ -137,17 +158,14 @@ export default {
}, },
showAddTime: false, showAddTime: false,
formInline: { formInline: {
startTime:'',endTime:'',chargeDischargePower:'',chargeStatus:'' timeRange: range,
chargeDischargePower: '',
chargeStatus: ''
}, },
formInlineRule: { formInlineRule: {
startTime: [{ timeRange: [{
required: true, required: true,
message: '请选择开始时间', message: '请选择时间范围',
trigger: 'change'
}],
endTime: [{
required: true,
message: '请选择结束时间',
trigger: 'change' trigger: 'change'
}], }],
chargeDischargePower: [{ chargeDischargePower: [{
@ -155,7 +173,7 @@ export default {
message: '请输入冲放功率', message: '请输入冲放功率',
trigger: 'blur' trigger: 'blur'
}, },
{ pattern: /^(0|[1-9]\d*)(\.\d+)?$/, message: '请输入合法数字或小数' } {pattern: /^-?\d*\.?\d*$/, message: '请输入合法数字或小数'}
], ],
chargeStatus: [{ chargeStatus: [{
required: true, required: true,
@ -172,20 +190,6 @@ export default {
chargeStatusOptions: state => state?.ems?.chargeStatusOptions || {}, chargeStatusOptions: state => state?.ems?.chargeStatusOptions || {},
}) })
}, },
watch: {
"formInline.startTime":{
handler(newVal){
if(newVal && this.formInline.endTime){
const endTime = parseInt((this.formInline.endTime).split(':')[0] || 0)
const startTime =parseInt(newVal.split(':')[0])
if(endTime<=startTime){
this.formInline.endTime = `${startTime+1 <=9 ? '0'+(startTime+1) : startTime+1}:00`
}
}
},
deep:true
},
},
methods: { methods: {
changeSiteId() { changeSiteId() {
this.dialogTableVisible = false this.dialogTableVisible = false
@ -198,8 +202,8 @@ export default {
sdcUp: '', sdcUp: '',
} }
this.formInline = { this.formInline = {
startTime:'',endTime:'',chargeDischargePower:'',chargeStatus:'' timeRange: this.secondRange, chargeDischargePower: '', chargeStatus: ''
} }//startTime: '', endTime: '',
this.showAddTime = false this.showAddTime = false
this.tableData = [] this.tableData = []
}, },
@ -238,14 +242,18 @@ export default {
cancelAddTime() { cancelAddTime() {
this.$refs.addTimeForm.resetFields() this.$refs.addTimeForm.resetFields()
this.showAddTime = false this.showAddTime = false
this.formInline = {startTime:'',endTime:'',chargeDischargePower:'',chargeStatus:''} this.formInline = {timeRange: this.secondRange, chargeDischargePower: '', chargeStatus: ''}//startTime: '', endTime: '',
}, },
saveTime() { saveTime() {
//表单校验校验成功添加到tableData里 //表单校验校验成功添加到tableData里
this.$refs.addTimeForm.validate(valid => { this.$refs.addTimeForm.validate(valid => {
if (!valid) return if (!valid) return
this.tableData.push(JSON.parse(JSON.stringify(this.formInline))); const {timeRange: [startTime, endTime], chargeDischargePower, chargeStatus} = this.formInline
this.$nextTick(() => {this.cancelAddTime()})
this.tableData.push({startTime, endTime, chargeDischargePower, chargeStatus})
this.$nextTick(() => {
this.cancelAddTime()
})
}) })
}, },
deleteRow(index) { deleteRow(index) {
@ -280,7 +288,16 @@ export default {
const {siteId, updateStrategyId} = this.$home const {siteId, updateStrategyId} = this.$home
const {tableData} = this const {tableData} = this
if (this.mode === 'edit') { if (this.mode === 'edit') {
editStrategyTemp({siteId,strategyId:updateStrategyId,templateId:this.editTempId,templateName,sdcLimit,sdcDown,sdcUp,timeConfigList:tableData}).then(response=>{ editStrategyTemp({
siteId,
strategyId: updateStrategyId,
templateId: this.editTempId,
templateName,
sdcLimit,
sdcDown,
sdcUp,
timeConfigList: tableData
}).then(response => {
if (response?.code === 200) { if (response?.code === 200) {
this.closeDialog() this.closeDialog()
this.$emit('update') this.$emit('update')
@ -288,7 +305,15 @@ export default {
} }
}) })
} else { } else {
addStrategyTemp({siteId,strategyId:updateStrategyId,templateName,sdcLimit,sdcDown,sdcUp,timeConfigList:tableData}).then(response=>{ addStrategyTemp({
siteId,
strategyId: updateStrategyId,
templateName,
sdcLimit,
sdcDown,
sdcUp,
timeConfigList: tableData
}).then(response => {
if (response?.code === 200) { if (response?.code === 200) {
this.closeDialog() this.closeDialog()
this.$emit('update') this.$emit('update')
@ -314,3 +339,9 @@ export default {
} }
</script> </script>
<style lang="scss" scoped>
.add-template-dialog {
max-height: 90vh;
overflow-y: auto;
}
</style>

View File

@ -1,9 +1,12 @@
<template> <template>
<el-dialog :visible.sync="dialogTableVisible" :close-on-press-escape="false" :close-on-click-modal="false" :show-close="false" destroy-on-close lock-scroll append-to-body width="600px" class="ems-dialog" :title="mode === 'add'?'新增设备':`编辑设备` " > <el-dialog :visible.sync="dialogTableVisible" :close-on-press-escape="false" :close-on-click-modal="false"
:show-close="false" destroy-on-close lock-scroll append-to-body width="600px" class="ems-dialog"
:title="mode === 'add'?'新增设备':`编辑设备` ">
<el-form v-loading="loading>0" ref="addTempForm" :model="formData" :rules="rules" size="medium" label-width="140px"> <el-form v-loading="loading>0" ref="addTempForm" :model="formData" :rules="rules" size="medium" label-width="140px">
<el-form-item label="站点" prop="siteId"> <el-form-item label="站点" prop="siteId">
<el-select v-model="formData.siteId" placeholder="请选择" :style="{width: '100%'}" @change="changeType"> <el-select v-model="formData.siteId" placeholder="请选择" :style="{width: '100%'}" @change="changeType">
<el-option :label="item.siteName" :value="item.siteId" v-for="(item,index) in siteList" :key="index+'siteOptions'"></el-option> <el-option :label="item.siteName" :value="item.siteId" v-for="(item,index) in siteList"
:key="index+'siteOptions'"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="设备id" prop="deviceId"> <el-form-item label="设备id" prop="deviceId">
@ -15,27 +18,34 @@
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item label="设备描述" prop="description"> <el-form-item label="设备描述" prop="description">
<el-input v-model="formData.description" type="textarea" placeholder="请输入" clearable :style="{width: '100%'}"> <el-input v-model="formData.description" type="textarea" placeholder="请输入" clearable
:style="{width: '100%'}">
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item label="工作状态" prop="communicationStatus"> <el-form-item label="工作状态" prop="communicationStatus">
<el-select v-model="formData.communicationStatus" placeholder="请选择" :style="{width: '100%'}"> <el-select v-model="formData.communicationStatus" placeholder="请选择" :style="{width: '100%'}">
<el-option :label="value" :value="key" v-for="(value,key) in communicationStatusOptions" :key="key+'communicationStatusOptions'"></el-option> <el-option :label="value" :value="key" v-for="(value,key) in communicationStatusOptions"
:key="key+'communicationStatusOptions'"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="设备类型" prop="deviceType"> <el-form-item label="设备类型" prop="deviceType">
<el-select v-model="formData.deviceType" placeholder="请选择" :style="{width: '100%'}"> <el-select v-model="formData.deviceType" placeholder="请选择" :style="{width: '100%'}">
<el-option :label="value" :value="key" v-for="(value,key) in deviceTypeOptions" :key="key+'deviceTypeOptions'"></el-option> <el-option :label="value" :value="key" v-for="(value,key) in deviceTypeOptions"
:key="key+'deviceTypeOptions'"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="设备类别" prop="deviceCategory"> <el-form-item label="设备类别" prop="deviceCategory">
<el-select v-model="formData.deviceCategory" placeholder="请选择" :style="{width: '100%'}" @change="changeType"> <el-select v-model="formData.deviceCategory" placeholder="请选择" :style="{width: '100%'}" @change="changeType">
<el-option :label="item.name" :value="item.code" v-for="(item,index) in deviceCategoryList" :key="index+'deviceCategoryList'"></el-option> <el-option :label="item.name" :value="item.code" v-for="(item,index) in deviceCategoryList"
:key="index+'deviceCategoryList'"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="上级设备" prop="parentId" v-if="dccDeviceCategoryList.includes(formData.deviceCategory)"> <el-form-item label="上级设备" prop="parentId" v-if="dccDeviceCategoryList.includes(formData.deviceCategory)">
<el-select v-model="formData.parentId" :placeholder="parentDeviceList.length === 0 && !formData.siteId ? '请先选择站点' : '请选择'" :style="{width: '100%'}"> <el-select v-model="formData.parentId"
<el-option :label="item.deviceName" :value="item.id" v-for="(item,index) in parentDeviceList" :key="index+'parentDeviceList'" ></el-option> :placeholder="parentDeviceList.length === 0 && !formData.siteId ? '请先选择站点' : '请选择'"
:style="{width: '100%'}">
<el-option :label="item.deviceName" :value="item.id" v-for="(item,index) in parentDeviceList"
:key="index+'parentDeviceList'"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="TCP设备的ip地址" prop="ipAddress" v-if="formData.deviceType === 'TCP'"> <el-form-item label="TCP设备的ip地址" prop="ipAddress" v-if="formData.deviceType === 'TCP'">
@ -46,7 +56,10 @@
<el-input v-model="formData.ipPort" placeholder="请输入" clearable :style="{width: '100%'}"> <el-input v-model="formData.ipPort" placeholder="请输入" clearable :style="{width: '100%'}">
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item label="从站地址" prop="slaveId" v-if="formData.deviceType === 'TCP'">
<el-input v-model="formData.slaveId" placeholder="请输入" clearable :style="{width: '100%'}">
</el-input>
</el-form-item>
<el-form-item label="串口路径" prop="serialPort"> <el-form-item label="串口路径" prop="serialPort">
<el-input v-model="formData.serialPort" placeholder="请输入" clearable :style="{width: '100%'}"> <el-input v-model="formData.serialPort" placeholder="请输入" clearable :style="{width: '100%'}">
</el-input> </el-input>
@ -82,8 +95,9 @@
import {mapState} from "vuex"; import {mapState} from "vuex";
import {getAllSites} from '@/api/ems/zddt' import {getAllSites} from '@/api/ems/zddt'
import {validText} from '@/utils/validate' import {validText} from '@/utils/validate'
import {getDeviceDetailInfo,updateDevice,addDevice,getParentDeviceId} from "@/api/ems/site"; import {addDevice, getDeviceDetailInfo, getParentDeviceId, updateDevice} from "@/api/ems/site";
import {getAllDeviceCategory} from '@/api/ems/search' import {getAllDeviceCategory} from '@/api/ems/search'
export default { export default {
props: { props: {
mode: { mode: {
@ -135,6 +149,7 @@ export default {
stopBits: '',//停止位 stopBits: '',//停止位
parity: '',//校验位 parity: '',//校验位
pictureUrl: '',//设备图片 pictureUrl: '',//设备图片
slaveId: '',//从站地址
}, },
rules: { rules: {
siteId: [ siteId: [
@ -167,6 +182,9 @@ export default {
ipPort: [ ipPort: [
{validator: validateText, trigger: 'blur'} {validator: validateText, trigger: 'blur'}
], ],
slaveId: [
{validator: validateText, trigger: 'blur'}
],
serialPort: [ serialPort: [
{validator: validateText, trigger: 'blur'} {validator: validateText, trigger: 'blur'}
], ],
@ -214,7 +232,9 @@ export default {
if (this.dccDeviceCategoryList.includes(this.formData.deviceCategory)) { if (this.dccDeviceCategoryList.includes(this.formData.deviceCategory)) {
this.getParentDeviceList(true) this.getParentDeviceList(true)
} }
}).finally(() => {this.loading-=1}) }).finally(() => {
this.loading -= 1
})
} }
}, },
immediate: true, immediate: true,
@ -234,14 +254,18 @@ export default {
this.loading += 1 this.loading += 1
getAllSites().then(response => { getAllSites().then(response => {
this.siteList = response?.data || [] this.siteList = response?.data || []
}).finally(() => {this.loading-=1}) }).finally(() => {
this.loading -= 1
})
}, },
// 获取设备类别 // 获取设备类别
getDeviceCategoryList() { getDeviceCategoryList() {
this.loading += 1 this.loading += 1
getAllDeviceCategory().then(response => { getAllDeviceCategory().then(response => {
this.deviceCategoryList = response?.data || [] this.deviceCategoryList = response?.data || []
}).finally(() => {this.loading-=1}) }).finally(() => {
this.loading -= 1
})
}, },
//获取上级id列表 //获取上级id列表
getParentDeviceList(init = false) { getParentDeviceList(init = false) {
@ -278,9 +302,28 @@ export default {
stopBits = '',//停止位 stopBits = '',//停止位
parity = '',//校验位 parity = '',//校验位
pictureUrl = '',//设备图片 pictureUrl = '',//设备图片
slaveId = '',//从站地址
} = this.formData; } = this.formData;
if (this.mode === 'add') { if (this.mode === 'add') {
addDevice({siteId,deviceId,deviceName,description,communicationStatus,deviceType,deviceCategory,parentId,ipAddress,ipPort,serialPort,baudRate,dataBits,stopBits,parity,pictureUrl}).then(response => { addDevice({
siteId,
deviceId,
deviceName,
description,
communicationStatus,
deviceType,
deviceCategory,
parentId,
ipAddress,
ipPort,
serialPort,
baudRate,
dataBits,
stopBits,
parity,
pictureUrl,
slaveId
}).then(response => {
if (response.code === 200) { if (response.code === 200) {
//新增成功 //新增成功
// 关闭弹窗 更新表格 // 关闭弹窗 更新表格
@ -291,7 +334,26 @@ export default {
this.loading -= 1 this.loading -= 1
}) })
} else { } else {
updateDevice({id,siteId,deviceId,deviceName,description,communicationStatus,deviceType,deviceCategory,parentId,ipAddress,ipPort,serialPort,baudRate,dataBits,stopBits,parity,pictureUrl}).then(response => { updateDevice({
id,
siteId,
deviceId,
deviceName,
description,
communicationStatus,
deviceType,
deviceCategory,
parentId,
ipAddress,
ipPort,
serialPort,
baudRate,
dataBits,
stopBits,
parity,
pictureUrl,
slaveId
}).then(response => {
if (response.code === 200) { if (response.code === 200) {
//新增成功 //新增成功
// 关闭弹窗 更新表格 // 关闭弹窗 更新表格
@ -326,6 +388,7 @@ export default {
stopBits: '',//停止位 stopBits: '',//停止位
parity: '',//校验位 parity: '',//校验位
pictureUrl: '',//设备图片 pictureUrl: '',//设备图片
slaveId: '',//从站地址
} }
this.$refs.addTempForm.resetFields() this.$refs.addTempForm.resetFields()
this.dialogTableVisible = false this.dialogTableVisible = false