wangsixiang
2 weeks ago
14 changed files with 1489 additions and 5 deletions
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,319 @@ |
|||
<template> |
|||
<Dialog v-model="modelVisible" title="设备操作" width="550px"> |
|||
<div class="DeviceControlDialog"> |
|||
<!-- <DeviceParams :dialogData="dialogData" /> --> |
|||
<div class="control-unit"> |
|||
<span>监控控制开关:</span> |
|||
<el-switch active-color="#13ce66" inactive-color="#ff4949" v-model="swicthLight" active-text="开启" |
|||
inactive-text="关闭" @change="switchTopState" > </el-switch> |
|||
</div> |
|||
<el-select v-model="controlObject" placeholder="请选择" @change="onControlObjectChange"> |
|||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> |
|||
</el-option> |
|||
</el-select> |
|||
<el-input type="text" v-model="openingPoint" @input="validateInput" maxlength="3" |
|||
show-word-limit placeholder="请输入" clearable ></el-input> |
|||
<p v-if="errorMessage" style="color: yellow; font-size: 16px;">{{ errorMessage }}</p> |
|||
<ButtonGradient @click.native="submitForm"> |
|||
确认 |
|||
</ButtonGradient> |
|||
</div> |
|||
|
|||
|
|||
</Dialog> |
|||
</template> |
|||
<!-- <input class="contentBoard" type="text" v-model="openingPoint" @input="validateInput" maxlength="3" |
|||
show-word-limit placeholder="请输入" clearable ></input> --> |
|||
|
|||
<!-- <el-col :span="24"> |
|||
<input class="contentBoard" placeholder="请输入文字" v-model="openingPoint"></input> |
|||
<ButtonGradient class="btn" style="margin-left: 5px;" @click.native="$emit('onContentEdit', {field:'executeConfig',index,type:'cancel'})"> |
|||
<i class="el-icon-refresh-left"></i> |
|||
</ButtonGradient> |
|||
<ButtonGradient class="btn" style="margin-left: 5px;" @click.native="$emit('onContentEdit', {field:'executeConfig',index,type:'confirm'})"> |
|||
<i class="el-icon-check"></i> |
|||
</ButtonGradient> |
|||
</el-col> --> |
|||
<script> |
|||
import Button from "@screen/components/Buttons/Button.vue"; |
|||
import Dialog from "@screen/components/Dialog/index.vue"; |
|||
import DeviceParams from "./DeviceParams.vue"; |
|||
import request from "@/utils/request"; |
|||
import ButtonGradient from "@screen/components/Buttons/ButtonGradient.vue"; |
|||
export default { |
|||
name: "DeviceControlDialog", |
|||
components: { |
|||
Dialog, |
|||
DeviceParams, |
|||
Button, |
|||
ButtonGradient, |
|||
}, |
|||
model: { |
|||
prop: "visible", |
|||
event: "update:value", |
|||
}, |
|||
props: { |
|||
index: Number, |
|||
type: Number, |
|||
visible: Boolean, |
|||
dialogData: { |
|||
type: Object, |
|||
default: () => ({}), |
|||
}, |
|||
}, |
|||
computed: { |
|||
modelVisible: { |
|||
get() { |
|||
if(this.visible==true){ |
|||
this.AddMethods(); |
|||
} |
|||
return this.visible; |
|||
}, |
|||
set(val) { |
|||
this.$emit("update:value", val); |
|||
}, |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
OOODValue:'', |
|||
OOOEValue:'', |
|||
OOOFValue:'', |
|||
OO1OValue:'', |
|||
options: [{ |
|||
value: '000D', |
|||
label: '制冷开启温度' |
|||
}, { |
|||
value: '000E', |
|||
label: '制冷停止温度' |
|||
}, { |
|||
value: '000F', |
|||
label: '加热开启温度' |
|||
}, { |
|||
value: '0010', |
|||
label: '加热停止温度' |
|||
}], |
|||
controlObject: '', |
|||
openingPoint:'', |
|||
errorMessage:'', |
|||
rangeLimits: { |
|||
'000D': { min: 20, max: 55 }, |
|||
'000E': { min: 15, max: 35 }, |
|||
'000F': { min: -30, max: 15 }, |
|||
'0010': { min: 0, max: 23 }, |
|||
// 可以继续添加其他选项及其对应的范围 |
|||
}, |
|||
iotDeviceIdValue:"", |
|||
swicthLight:false, |
|||
secondLoading: true, |
|||
devicesList: [], |
|||
devicesData: {}, |
|||
activeOption: { |
|||
active: { |
|||
text: "开" |
|||
}, |
|||
unActive: { |
|||
text: "关" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
methods:{ |
|||
submitForm(){ |
|||
if((this.controlObject==null||this.controlObject=='')||(this.openingPoint==null||this.openingPoint=='')){ |
|||
return null; |
|||
} |
|||
request({ |
|||
url: `/business/device/functions/${this.iotDeviceIdValue}/CSP`, |
|||
method: "post", |
|||
data: { |
|||
openingPoint:this.openingPoint, |
|||
controlObject:this.controlObject, |
|||
}, |
|||
}).then(result => { |
|||
if (result.code != 200) { |
|||
return Message.error("操作失败"); |
|||
} |
|||
Message.success("操作成功"); |
|||
}).catch(error => { |
|||
|
|||
Message.error("请求失败,请稍后再试"); |
|||
}); |
|||
}, |
|||
validateInput(value) { |
|||
const intValue = parseInt(value, 10); |
|||
const limits = this.rangeLimits[this.controlObject]; |
|||
if (isNaN(intValue) || intValue < limits.min || intValue > limits.max) { |
|||
this.errorMessage = `请输入 ${limits.min}-${limits.max} 之间的数字`; |
|||
if(this.controlObject=='000D'&&this.OOODValue!=''){ |
|||
this.errorMessage += ` 当前值为:`+this.OOODValue; |
|||
}else if(this.controlObject=='000E'&&this.OOOEValue!=''){ |
|||
this.errorMessage += ` 当前值为:`+this.OOOEValue; |
|||
}else if(this.controlObject=='000F'&&this.OOOFValue!=''){ |
|||
this.errorMessage += ` 当前值为:`+this.OOOFValue; |
|||
}else if(this.controlObject=='0010'&&this.OO1OValue!=''){ |
|||
this.errorMessage += ` 当前值为:`+this.OO1OValue; |
|||
} |
|||
} else { |
|||
this.errorMessage = ''; |
|||
} |
|||
}, |
|||
onControlObjectChange(value) { |
|||
console.log(value) |
|||
// 当选择变化时,检查当前输入值是否仍在新的范围内 |
|||
const inputValue = parseInt(this.openingPoint, 10); |
|||
const limits = this.rangeLimits[value]; |
|||
|
|||
if (isNaN(inputValue) || inputValue < limits.min || inputValue > limits.max) { |
|||
this.errorMessage = `请选择 ${limits.min}-${limits.max} 之间的数字`; |
|||
if(value=='000D'&&this.OOODValue!=''){ |
|||
this.errorMessage += ` 当前值为:`+this.OOODValue; |
|||
}else if(value=='000E'&&this.OOOEValue!=''){ |
|||
this.errorMessage += ` 当前值为:`+this.OOOEValue; |
|||
}else if(value=='000F'&&this.OOOFValue!=''){ |
|||
this.errorMessage += ` 当前值为:`+this.OOOFValue; |
|||
}else if(value=='0010'&&this.OO1OValue!=''){ |
|||
this.errorMessage += ` 当前值为:`+this.OO1OValue; |
|||
} |
|||
this.openingPoint = ''; // 清空超出范围的输入 |
|||
} else { |
|||
this.errorMessage = ''; |
|||
} |
|||
}, |
|||
AddMethods() { |
|||
this.devicesList = []; |
|||
let devs = []; |
|||
this.iotDeviceIdValue = this.dialogData.iotDeviceId.replace(/-502$/, '-5000'); |
|||
request({ |
|||
url: `/business/device/properties/latest/${this.iotDeviceIdValue}`, |
|||
method: "get", |
|||
}).then(result => { |
|||
if (result.code != 200) { |
|||
return Message.error("操作失败"); |
|||
} |
|||
result.data.forEach(item => { |
|||
if (item.property === "MonitorShutdown") { |
|||
devs.push({ |
|||
label: item.propertyName, |
|||
key: item.property, |
|||
formatValue: item.formatValue, |
|||
gridColumn: 3, |
|||
}); |
|||
this.devicesData[item.property] = item.formatValue; |
|||
if(item.value=='0'){ |
|||
this.swicthLight=true; |
|||
}else{ |
|||
this.swicthLight=false; |
|||
} |
|||
} |
|||
if(item.property=="CoolingStartTemperature"){ |
|||
this.OOODValue=item.value; |
|||
} |
|||
if(item.property=="CoolingStopTemperature"){ |
|||
this.OOOEValue=item.value; |
|||
} |
|||
if(item.property=="HeatingActivationTemperature"){ |
|||
this.OOOFValue=item.value; |
|||
} |
|||
if(item.property=="HeatingStopTemperature"){ |
|||
this.OO1OValue=item.value; |
|||
} |
|||
}); |
|||
this.devicesList = devs; |
|||
}).catch(error => { |
|||
|
|||
Message.error("请求失败,请稍后再试"); |
|||
}); |
|||
}, |
|||
|
|||
|
|||
switchTopState(e) { |
|||
let text = e ==true? "开启" : "关闭"; |
|||
console.log(e); |
|||
this.$modal.confirm('确认要"' + text + '"监控').then(() => { |
|||
return request({ |
|||
url: `/business/device/functions/${this.iotDeviceIdValue}/05`, |
|||
method: "post", |
|||
data: { |
|||
switch:e?1:0 |
|||
}, |
|||
}) |
|||
.then((result)=>{ |
|||
if (result.code != 200) { |
|||
Message.error("操作失败"); |
|||
this.swicthLight =!e |
|||
return; |
|||
} |
|||
this.$modal.msgSuccess(text + "成功"); |
|||
this.swicthLight=e |
|||
// setTimeout(() => { |
|||
// this.AddMethods(); |
|||
// }, 1500); |
|||
}).catch((error)=>{ |
|||
console.error('请求失败:', error); |
|||
this.swicthLight = !e; |
|||
}); |
|||
}).catch((error) => { |
|||
console.log(e) |
|||
this.swicthLight =!e |
|||
}); |
|||
}, |
|||
|
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.DeviceControlDialog { |
|||
width: 510px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 15px; |
|||
min-height: 360px; |
|||
|
|||
.tips { |
|||
font-size: 12px; |
|||
} |
|||
} |
|||
.contentBoard{ |
|||
flex:1; |
|||
background-color: #19425c; |
|||
color:#dfdfdf; |
|||
padding: 9px 0px; |
|||
text-align: center; |
|||
font-weight: bold; |
|||
} |
|||
.control-wrapper { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 10px; /* 调整开关与文本之间的间距 */ |
|||
} |
|||
|
|||
.control-wrapper span { |
|||
flex: 1; /* 使文本占据一定空间 */ |
|||
} |
|||
|
|||
.control-switch { |
|||
flex: 0 0 auto; /* 使开关根据其内容大小自动调整 */ |
|||
} |
|||
.DeviceControlDialog .control-unit { |
|||
line-height: 30px; |
|||
font-size: 16px; |
|||
display: flex; |
|||
align-items: center; /* 垂直居中 */ |
|||
width: calc(50% - 10px); /* 每个单元占据行宽度的一半减去间距 */ |
|||
box-sizing: border-box; /* 确保宽度和任何内边距/边框不会超出计算的宽度 */ |
|||
} |
|||
|
|||
.DeviceControlDialog .control-unit span { |
|||
font-size: 16px; |
|||
line-height: 30px; |
|||
flex-shrink: 0; /* 防止名字在容器宽度不足时缩小 */ |
|||
white-space: nowrap; /* 防止名字换行 */ |
|||
/* 减少名称和开关之间的空白,可以调整这个值 */ |
|||
margin-right: 10px; /* 之前是10px,现在改为5px */ |
|||
} |
|||
|
|||
</style> |
|||
|
@ -0,0 +1,139 @@ |
|||
<template> |
|||
<div class='DeviceParams'> |
|||
<div class="no-data" v-if="!devicesList.length" v-loading="secondLoading">暂无设备参数</div> |
|||
<Descriptions :list="devicesList" :data="devicesData" style="gap: 18px;" column="6"> |
|||
<template v-for="item in devicesList.slice(0, -1)" #[`content-${getSlotKey(item.key)}`]="{ data }"> |
|||
<span>{{ data.text }}</span> |
|||
|
|||
</template> |
|||
</Descriptions> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import Descriptions from '@screen/components/Descriptions.vue'; |
|||
import Switcher from '@screen/pages/service/PublishingChannelManagement/components/Switcher.vue'; |
|||
import request from "@/utils/request"; |
|||
import { Message } from 'element-ui'; |
|||
import { confirm } from "@screen/utils/common"; |
|||
|
|||
|
|||
export default { |
|||
name: 'DeviceParams', |
|||
components: { |
|||
Descriptions, |
|||
Switcher |
|||
}, |
|||
props: { |
|||
dialogData: { |
|||
type: Object, |
|||
default: () => ({}) |
|||
}, |
|||
disabled: Boolean |
|||
}, |
|||
data() { |
|||
return { |
|||
secondLoading: true, |
|||
devicesList: [], |
|||
devicesData: {}, |
|||
activeOption: { |
|||
active: { |
|||
text: "开" |
|||
}, |
|||
unActive: { |
|||
text: "关" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
async created() { |
|||
this.devicesList = []; |
|||
let devs = []; |
|||
// Promise.all([this.getAc('A1'), this.getAc('A2'), this.getAc('A3'), this.getAc('A4'), this.getAc('A5'), this.getAc('A6')]).then(res => { |
|||
|
|||
await request({ |
|||
url: `/business/device/batchFunctions`, |
|||
method: "post", |
|||
data: { |
|||
devices: [{ |
|||
iotDeviceId: this.dialogData.iotDeviceId, |
|||
id: this.dialogData.id, |
|||
deviceType: 17 |
|||
}], |
|||
functions: [ |
|||
{ |
|||
functionId: "03", |
|||
params: {} |
|||
}, { |
|||
functionId: "04", |
|||
params: {} |
|||
} |
|||
], |
|||
// parameter: {} |
|||
} |
|||
}).then(res => { |
|||
console.log('res', res) |
|||
if (res.msg == 500) { |
|||
this.getAc(); |
|||
} |
|||
}) |
|||
.catch((err) => { |
|||
console.log('err', err) |
|||
this.getAc(); |
|||
}) |
|||
request({ |
|||
url: `/business/device/properties/latest/${this.dialogData.iotDeviceId}`, |
|||
method: "get", |
|||
}).then(result => { |
|||
if (result.code != 200) return Message.error("操作失败"); |
|||
result.data.forEach(item => { |
|||
if (item.propertyName) { |
|||
devs.push({ |
|||
label: item.propertyName, |
|||
key: item.property, |
|||
gridColumn: 3, |
|||
}); |
|||
this.devicesData[item.property] = item.formatValue; |
|||
} |
|||
|
|||
}); |
|||
this.devicesList = devs; |
|||
}) |
|||
}, |
|||
methods: { |
|||
getAc() { |
|||
return request({ |
|||
url: `/business/device/batchFunctions`, |
|||
method: "post", |
|||
data: { |
|||
devices: [{ |
|||
iotDeviceId: this.dialogData.iotDeviceId, |
|||
id: this.dialogData.id, |
|||
deviceType: 17 |
|||
}], |
|||
functions: [ |
|||
{ |
|||
functionId: "03", |
|||
params: {} |
|||
}, { |
|||
functionId: "04", |
|||
params: {} |
|||
} |
|||
], |
|||
// parameter: {} |
|||
} |
|||
}) |
|||
}, |
|||
getSlotKey(key) { |
|||
return key.includes('electricity') || key.includes('fan') ? key : '' |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang='scss' scoped> |
|||
.DeviceParams { |
|||
height: 100%; |
|||
} |
|||
</style> |
|||
|
@ -0,0 +1,298 @@ |
|||
<template> |
|||
<Dialog v-model="modelVisible" title="设备操作" width="550px"> |
|||
<div class="DeviceControlDialog"> |
|||
<div class="row"> |
|||
<div class="control-unit"> |
|||
<span>频闪灯开关:</span> |
|||
<el-switch active-color="#13ce66" inactive-color="#ff4949" v-model="swicthLight" active-text="开启" inactive-text="关闭" @change="switchTopState"></el-switch> |
|||
</div> |
|||
<div class="control-unit"> |
|||
<span>雷电计数清零:</span> |
|||
<el-switch active-color="#13ce66" inactive-color="#ff4949" v-model="lightningReset" active-text="开启" inactive-text="关闭" @change="lightningResetZero"></el-switch> |
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="control-unit"> |
|||
<span>系统复位:</span> |
|||
<el-switch active-color="#13ce66" inactive-color="#ff4949" v-model="recloserReset" active-text="开启" inactive-text="关闭" @change="recloserResetSwitch"></el-switch> |
|||
</div> |
|||
<div class="control-unit"> |
|||
<span>令重合闸复位:</span> |
|||
<el-switch active-color="#13ce66" inactive-color="#ff4949" v-model="reclosing" active-text="开启" inactive-text="关闭" @change="reclosingSwitch"></el-switch> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</Dialog> |
|||
</template> |
|||
|
|||
<script> |
|||
import Switcher from '@screen/pages/service/PublishingChannelManagement/components/Switcher.vue'; |
|||
import Dialog from "@screen/components/Dialog/index.vue"; |
|||
import DeviceParams from "./DeviceParams.vue"; |
|||
import request from "@/utils/request"; |
|||
export default { |
|||
name: "DeviceControlDialog", |
|||
components: { |
|||
Dialog, |
|||
DeviceParams, |
|||
Switcher, |
|||
}, |
|||
model: { |
|||
prop: "visible", |
|||
event: "update:value", |
|||
}, |
|||
props: { |
|||
visible: Boolean, |
|||
dialogData: { |
|||
type: Object, |
|||
default: () => ({}), |
|||
}, |
|||
}, |
|||
computed: { |
|||
modelVisible: { |
|||
get() { |
|||
if(this.visible==true){ |
|||
this.AddMethods(); |
|||
} |
|||
return this.visible; |
|||
}, |
|||
set(val) { |
|||
this.$emit("update:value", val); |
|||
}, |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
getSwitch: 0, |
|||
swicthLight:false, |
|||
secondLoading: true, |
|||
lightningReset:false, |
|||
recloserReset:false, |
|||
reclosing:false, |
|||
devicesList: [], |
|||
devicesData: {}, |
|||
activeOption: { |
|||
active: { |
|||
text: "开" |
|||
}, |
|||
unActive: { |
|||
text: "关" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
methods:{ |
|||
AddMethods() { |
|||
this.devicesList = []; |
|||
let devs = []; |
|||
request({ |
|||
url: `/business/device/properties/latest/${this.dialogData.iotDeviceId}`, |
|||
method: "get", |
|||
}).then(result => { |
|||
if (result.code != 200) { |
|||
return Message.error("操作失败"); |
|||
} |
|||
result.data.forEach(item => { |
|||
if (item.property === "StrobeLightSwitch") { |
|||
devs.push({ |
|||
label: item.propertyName, |
|||
key: item.property, |
|||
formatValue: item.formatValue, |
|||
gridColumn: 3, |
|||
}); |
|||
this.devicesData[item.property] = item.formatValue; |
|||
if(item.value=='0'){ |
|||
this.getSwitch=0; |
|||
this.swicthLight=false; |
|||
}else{ |
|||
this.getSwitch=1; |
|||
this.swicthLight=true; |
|||
} |
|||
} |
|||
}); |
|||
this.devicesList = devs; |
|||
}).catch(error => { |
|||
|
|||
Message.error("请求失败,请稍后再试"); |
|||
}); |
|||
}, |
|||
|
|||
|
|||
switchTopState(e) { |
|||
console.log(e) |
|||
let text = e ==true? "开启" : "关闭"; |
|||
this.$modal.confirm('确认要"' + text + '"频闪灯').then(() => { |
|||
return request({ |
|||
url: `/business/device/functions/${this.dialogData.iotDeviceId}/SL`, |
|||
method: "post", |
|||
data: { |
|||
switch:e?1:0 |
|||
}, |
|||
}) |
|||
.then((result)=>{ |
|||
if (result.code != 200) { |
|||
Message.error("操作失败"); |
|||
this.swicthLight =!e |
|||
console.log(this.swicthLight) |
|||
return; |
|||
} |
|||
this.$modal.msgSuccess(text + "成功"); |
|||
this.swicthLight=e |
|||
setTimeout(() => { |
|||
this.AddMethods(); |
|||
}, 1000); |
|||
}).catch((error)=>{ |
|||
console.error('请求失败:', error); |
|||
this.swicthLight = !e; |
|||
}); |
|||
}).catch((error) => { |
|||
console.log(e) |
|||
this.swicthLight =!e |
|||
console.log(this.swicthLight) |
|||
}); |
|||
}, |
|||
|
|||
lightningResetZero(e){ |
|||
if(e==false){ |
|||
return this.lightningReset =e |
|||
} |
|||
let text = e ==true? "开启一次" : "关闭"; |
|||
console.log(e); |
|||
this.$modal.confirm('确认要"' + text + '"雷电计数清零?该操作会导致设备重启,请谨慎操作').then(() => { |
|||
if(e==false){ |
|||
return this.lightningReset =e |
|||
} |
|||
return request({ |
|||
url: `/business/device/functions/${this.dialogData.iotDeviceId}/TL`, |
|||
method: "post", |
|||
data: {}, |
|||
}) |
|||
.then((result)=>{ |
|||
if (result.code != 200) { |
|||
Message.error("操作失败"); |
|||
this.lightningReset =!e |
|||
return; |
|||
} |
|||
this.$modal.msgSuccess(text + "成功,请重新打开设备弹窗"); |
|||
this.lightningReset=e |
|||
}).catch((error)=>{ |
|||
console.error('请求失败:', error); |
|||
this.lightningReset = !e; |
|||
}); |
|||
}).catch((error) => { |
|||
console.log(e) |
|||
this.lightningReset =!e |
|||
}); |
|||
}, |
|||
|
|||
recloserResetSwitch(e){ |
|||
if(e==false){ |
|||
return this.recloserReset =e |
|||
} |
|||
let text = e ==true? "开启一次" : "关闭"; |
|||
console.log(e); |
|||
this.$modal.confirm('确认要"' + text + '"系统复位?该操作会导致设备重启,请谨慎操作').then(() => { |
|||
if(e==false){ |
|||
return this.recloserReset =e |
|||
} |
|||
return request({ |
|||
url: `/business/device/functions/${this.dialogData.iotDeviceId}/SR`, |
|||
method: "post", |
|||
data: {}, |
|||
}) |
|||
.then((result)=>{ |
|||
if (result.code != 200) { |
|||
Message.error("操作失败"); |
|||
this.recloserReset =!e |
|||
return; |
|||
} |
|||
this.$modal.msgSuccess(text + "系统复位成功,请重新打开设备弹窗"); |
|||
this.recloserReset=e |
|||
this.visible=false; |
|||
}).catch((error)=>{ |
|||
console.error('请求失败:', error); |
|||
this.recloserReset = !e; |
|||
}); |
|||
}).catch((error) => { |
|||
console.log(e) |
|||
this.recloserReset =!e |
|||
}); |
|||
}, |
|||
|
|||
reclosingSwitch(e){ |
|||
if(e==false){ |
|||
return this.reclosing =e |
|||
} |
|||
let text = e ==true? "开启一次" : "关闭"; |
|||
this.$modal.confirm('确认要"' + text + '"令重合闸复位?该操作会导致设备重启,请谨慎操作').then(() => { |
|||
if(e==false){ |
|||
return this.reclosing =e |
|||
} |
|||
return request({ |
|||
url: `/business/device/functions/${this.dialogData.iotDeviceId}/RS`, |
|||
method: "post", |
|||
data: {}, |
|||
}) |
|||
.then((result)=>{ |
|||
if (result.code != 200) { |
|||
Message.error("操作失败"); |
|||
this.reclosing =!e |
|||
return; |
|||
} |
|||
this.$modal.msgSuccess(text + "系统复位成功,请重新打开设备弹窗"); |
|||
this.reclosing=e |
|||
this.visible=false; |
|||
}).catch((error)=>{ |
|||
console.error('请求失败:', error); |
|||
this.reclosing = !e; |
|||
}); |
|||
}).catch((error) => { |
|||
this.reclosing =!e |
|||
}); |
|||
} |
|||
|
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.DeviceControlDialog { |
|||
width: 510px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 15px; |
|||
min-height: 360px; |
|||
|
|||
.tips { |
|||
font-size: 12px; |
|||
} |
|||
} |
|||
.DeviceControlDialog .row { |
|||
display: flex; |
|||
gap: 10px; /* 控制每个单元(名称+开关)之间的间距 */ |
|||
width: 100%; /* 行宽度占满容器 */ |
|||
box-sizing: border-box; /* 确保宽度和任何内边距/边框不会超出计算的宽度 */ |
|||
} |
|||
|
|||
.DeviceControlDialog .control-unit { |
|||
font-size: 16px; |
|||
display: flex; |
|||
align-items: center; /* 垂直居中 */ |
|||
width: calc(50% - 10px); /* 每个单元占据行宽度的一半减去间距 */ |
|||
box-sizing: border-box; /* 确保宽度和任何内边距/边框不会超出计算的宽度 */ |
|||
} |
|||
|
|||
.DeviceControlDialog .control-unit span { |
|||
flex-shrink: 0; /* 防止名字在容器宽度不足时缩小 */ |
|||
white-space: nowrap; /* 防止名字换行 */ |
|||
/* 减少名称和开关之间的空白,可以调整这个值 */ |
|||
margin-right: 5px; /* 之前是10px,现在改为5px */ |
|||
} |
|||
|
|||
.el-switch { |
|||
/* 这里的样式可以根据您的需求进行调整,例如大小、颜色等 */ |
|||
flex-shrink: 0; /* 通常不是必需的,因为开关组件本身有固定大小,但加上也无妨 */ |
|||
} |
|||
</style> |
|||
|
@ -0,0 +1,148 @@ |
|||
<template> |
|||
<div class="DevicePacks"> |
|||
<div class="no-data" v-if="!devicesList.length" v-loading="secondLoading"> |
|||
暂无设备参数 |
|||
</div> |
|||
<Descriptions :list="devicesList" :data="devicesData" style="gap: 18px" column="6" > |
|||
<template v-for="item in devicesList.slice(0, -1)" #[`content-${getSlotKey(item.key)}`]="{ data }" > |
|||
<span>{{ data.text }}</span> |
|||
</template> |
|||
</Descriptions> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import Descriptions from "@screen/components/Descriptions.vue"; |
|||
import Switcher from "@screen/pages/service/PublishingChannelManagement/components/Switcher.vue"; |
|||
import request from "@/utils/request"; |
|||
import { Message } from "element-ui"; |
|||
import { confirm } from "@screen/utils/common"; |
|||
|
|||
export default { |
|||
name: "DevicePacks", |
|||
components: { |
|||
Descriptions, |
|||
Switcher, |
|||
}, |
|||
props: { |
|||
dialogData: { |
|||
type: Object, |
|||
default: () => ({}), |
|||
}, |
|||
disabled: Boolean, |
|||
}, |
|||
data() { |
|||
return { |
|||
airStatus:"", |
|||
iotDeviceIdValue:"", |
|||
secondLoading: true, |
|||
devicesList: [], |
|||
devicesData: {}, |
|||
activeOption: { |
|||
active: { |
|||
text: "开", |
|||
}, |
|||
unActive: { |
|||
text: "关", |
|||
}, |
|||
}, |
|||
}; |
|||
}, |
|||
async created() { |
|||
this.devicesList = []; |
|||
let devs = []; |
|||
const iotDeviceId = this.dialogData.iotDeviceId.replace(/-502$/, '-5000'); |
|||
const functionId = "01"; |
|||
const functionId03 = "03"; |
|||
|
|||
request({ |
|||
url: `/business/device/getDeviceById`, |
|||
method: "post", |
|||
data: { iotDeviceId: iotDeviceId }, |
|||
}).then((res) => { |
|||
if (res.code !== 200) { |
|||
console.log('err', res.msg); |
|||
return; // 提前返回,避免后续代码执行 |
|||
} |
|||
this.airStatus = res.data.deviceState; |
|||
|
|||
if (this.airStatus !== '0') { |
|||
request({ |
|||
url: `/business/device/functions/${iotDeviceId}/${functionId}`, |
|||
method: "post", |
|||
data: {}, |
|||
}).then((res) => { |
|||
console.log("res", res); |
|||
if (res.msg === 500) { |
|||
// 可以处理错误或调用其他函数,如 this.getAc(); |
|||
} else { |
|||
// 只有当第一个请求成功时,才执行第二个请求 |
|||
request({ |
|||
url: `/business/device/functions/${iotDeviceId}/${functionId03}`, |
|||
method: "post", |
|||
data: {}, |
|||
}).then((res03) => { |
|||
console.log("res03", res03); |
|||
if (res03.msg === 500) { |
|||
// 可以处理错误或调用其他函数,如 this.getAc(); |
|||
} |
|||
}).catch((err03) => { |
|||
console.log("err03", err03); |
|||
// 可以处理错误或调用其他函数,如 this.getAc(); |
|||
}); |
|||
} |
|||
}).catch((err) => { |
|||
console.log("err", err); |
|||
// 可以处理错误或调用其他函数,如 this.getAc(); |
|||
}); |
|||
} |
|||
}).catch((err) => { |
|||
console.log('err', err); |
|||
}); |
|||
|
|||
request({ |
|||
url: `/business/device/properties/latest/${iotDeviceId}`, |
|||
method: "get", |
|||
}).then((result) => { |
|||
if (result.code !== 200) { |
|||
return Message.error("操作失败"); |
|||
} |
|||
result.data.forEach((item) => { |
|||
if (item.propertyName) { |
|||
devs.push({ |
|||
label: item.propertyName, |
|||
key: item.property, |
|||
gridColumn: 3, |
|||
}); |
|||
this.devicesData[item.property] = item.formatValue; |
|||
} |
|||
}); |
|||
this.devicesList = devs; |
|||
}).catch((err) => { |
|||
console.log('err fetching properties', err); |
|||
}); |
|||
}, |
|||
methods: { |
|||
getAc() { |
|||
const iotDeviceId = this.dialogData.iotDeviceId.replace(/-502$/, '-5000');; |
|||
const functionId = "01"; |
|||
return request({ |
|||
url: `/business/device/functions/${iotDeviceId}/${functionId}`, |
|||
method: "post", |
|||
data: {}, |
|||
}); |
|||
}, |
|||
|
|||
getSlotKey(key) { |
|||
return key.includes("electricity") || key.includes("fan") ? key : ""; |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang='scss' scoped> |
|||
.DevicePacks { |
|||
height: 100%; |
|||
} |
|||
</style> |
|||
|
@ -0,0 +1,184 @@ |
|||
<template> |
|||
<div class='DeviceParams'> |
|||
<div class="no-data" v-if="!devicesList.length" v-loading="secondLoading">暂无设备参数</div> |
|||
<Descriptions :list="devicesList" :data="devicesData" style="gap: 18px;" column="6"> |
|||
<template v-for="item in devicesList.slice(0, -1)" #[`content-${getSlotKey(item.key)}`]="{ data }"> |
|||
<span>{{ data.text }}</span> |
|||
<!-- <Switcher v-if="!disabled" class="switcher" :activeOption="activeOption" :value="data.state" |
|||
@change="(value) => handleSwitcherChange(value, data)" /> --> |
|||
<!-- <ElTag style="margin-left: 20px;" v-else effect="dark" :type="data.state ? '' : 'info'">{{ data.state ? '开' : |
|||
'关' }} |
|||
</ElTag> --> |
|||
</template> |
|||
</Descriptions> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import Descriptions from '@screen/components/Descriptions.vue'; |
|||
import Switcher from '@screen/pages/service/PublishingChannelManagement/components/Switcher.vue'; |
|||
import request from "@/utils/request"; |
|||
import { Message } from 'element-ui'; |
|||
import { confirm } from "@screen/utils/common"; |
|||
|
|||
|
|||
export default { |
|||
name: 'DeviceParams', |
|||
components: { |
|||
Descriptions, |
|||
Switcher |
|||
}, |
|||
props: { |
|||
dialogData: { |
|||
type: Object, |
|||
default: () => ({}) |
|||
}, |
|||
disabled: Boolean |
|||
}, |
|||
data() { |
|||
return { |
|||
secondLoading: true, |
|||
devicesList: [], |
|||
devicesData: {}, |
|||
activeOption: { |
|||
active: { |
|||
text: "开" |
|||
}, |
|||
unActive: { |
|||
text: "关" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
async created() { |
|||
this.devicesList = []; |
|||
let devs = []; |
|||
// Promise.all([this.getAc('A1'), this.getAc('A2'), this.getAc('A3'), this.getAc('A4'), this.getAc('A5'), this.getAc('A6')]).then(res => { |
|||
|
|||
await request({ |
|||
url: `/business/device/batchFunctions`, |
|||
method: "post", |
|||
data: { |
|||
devices: [{ |
|||
iotDeviceId: this.dialogData.iotDeviceId, |
|||
id: this.dialogData.id, |
|||
deviceType: 17 |
|||
}], |
|||
functions: [ |
|||
{ |
|||
functionId: "03", |
|||
params: {} |
|||
}, { |
|||
functionId: "04", |
|||
params: {} |
|||
} |
|||
], |
|||
// parameter: {} |
|||
} |
|||
}).then(res => { |
|||
console.log('res', res) |
|||
if (res.msg == 500) { |
|||
this.getAc(); |
|||
} |
|||
}) |
|||
.catch((err) => { |
|||
console.log('err', err) |
|||
this.getAc(); |
|||
}) |
|||
request({ |
|||
url: `/business/device/properties/latest/${this.dialogData.iotDeviceId}`, |
|||
method: "get", |
|||
}).then(result => { |
|||
if (result.code != 200) return Message.error("操作失败"); |
|||
result.data.forEach(item => { |
|||
if (item.propertyName) { |
|||
devs.push({ |
|||
label: item.propertyName, |
|||
key: item.property, |
|||
gridColumn: 3, |
|||
}); |
|||
this.devicesData[item.property] = item.formatValue; |
|||
} |
|||
}); |
|||
this.devicesList = devs; |
|||
}) |
|||
}, |
|||
methods: { |
|||
getAc() { |
|||
return request({ |
|||
url: `/business/device/batchFunctions`, |
|||
method: "post", |
|||
data: { |
|||
devices: [{ |
|||
iotDeviceId: this.dialogData.iotDeviceId, |
|||
id: this.dialogData.id, |
|||
deviceType: 17 |
|||
}], |
|||
functions: [ |
|||
{ |
|||
functionId: "03", |
|||
params: {} |
|||
}, { |
|||
functionId: "04", |
|||
params: {} |
|||
} |
|||
], |
|||
// parameter: {} |
|||
} |
|||
}) |
|||
}, |
|||
async handleSwitcherChange(value, data) { |
|||
let str = data.state ? "关闭" : "开启"; |
|||
let deviceName = ""; |
|||
if (data.key.includes("fan")) { |
|||
str += "风扇?"; |
|||
deviceName = "fan_out_en"; |
|||
} else { |
|||
str += "该支路?" |
|||
deviceName = data.key.match(/^[a-z]+_out|[0-9]+/g).join("_") + "_en"; //dc_out_2_en ac_out_2_en; |
|||
} |
|||
data.state = value; |
|||
const isContinue = await confirm({ message: `${str}` }) |
|||
.catch(() => { |
|||
console.log(data.state, value, 333) |
|||
data.state = !value; |
|||
}); |
|||
|
|||
if (!isContinue) return; |
|||
|
|||
// https://www.yuque.com/dayuanzhong-ovjwn/gkht0m/ww776d5kzs72ilzh?singleDoc= |
|||
request({ |
|||
url: `/business/device/functions/${this.dialogData.iotDeviceId}/${102}`, |
|||
method: "POST", |
|||
data: { |
|||
deviceName, |
|||
// 开关:1=打开,0=关闭 |
|||
value: value ? 1 : 0 |
|||
} |
|||
}) |
|||
.then(result => { |
|||
if (result.code != 200) { |
|||
Message.error("操作失败"); |
|||
data.state = !value; |
|||
return; |
|||
}; |
|||
Message.success("操作成功"); |
|||
}) |
|||
.catch(() => { |
|||
data.state = !value; |
|||
Message.error("操作失败"); |
|||
}) |
|||
}, |
|||
getSlotKey(key) { |
|||
return key.includes('electricity') || key.includes('fan') ? key : '' |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang='scss' scoped> |
|||
.DeviceParams { |
|||
height: 100%; |
|||
} |
|||
</style> |
|||
|
@ -0,0 +1,231 @@ |
|||
<template> |
|||
<Dialog v-model="obverseVisible" title="一体机柜" width="550px"> |
|||
<Video class="video-stream" :camId="camId" img="一体机柜" /> |
|||
|
|||
<div class="IntegratedCabinet"> |
|||
<ElTabs v-model="activeName" class="tabs"> |
|||
<ElTabPane label="基本信息" name="first"> |
|||
<!-- {{ dialogData }} --> |
|||
<Descriptions :list="list" :data="data" style="gap: 18px" /> |
|||
</ElTabPane> |
|||
<ElTabPane label="设备参数" name="second"> |
|||
<DeviceParams disabled :dialogData="dialogData" style="height: 180px" /> |
|||
</ElTabPane> |
|||
<ElTabPane label="空调参数" name="second2"> |
|||
<DevicePacks disabled :dialogData="dialogData" style="height: 180px" /> |
|||
</ElTabPane> |
|||
<ElTabPane label="在线率统计" name="third"> |
|||
<LineChart v-if="activeName === 'third'" :productId="dialogData.id" style="height: 180px" /> |
|||
</ElTabPane> |
|||
</ElTabs> |
|||
</div> |
|||
<template #footer> |
|||
<Button v-if="activeName === 'second' && data.deviceState == '1'" @click.native="deviceControlVisible = true"> |
|||
设备操作 |
|||
</Button> |
|||
<Button v-else-if="activeName === 'second2' && airStatus == '1'" @click.native="airConditioningVisible = true"> |
|||
设备操作 |
|||
</Button> |
|||
<Button v-else-if="activeName != 'first'" style="background-color: #bbb"> |
|||
设备离线 |
|||
</Button> |
|||
</template> |
|||
|
|||
<DeviceControlDialog v-model="deviceControlVisible" :dialogData="dialogData" /> |
|||
<AirConditioning v-model="airConditioningVisible" :dialogData="dialogData" /> |
|||
</Dialog> |
|||
</template> |
|||
|
|||
<script> |
|||
import Dialog from "@screen/components/Dialog/index.vue"; |
|||
import Button from "@screen/components/Buttons/Button.vue"; |
|||
import Descriptions from "@screen/components/Descriptions.vue"; |
|||
import Video from "@screen/components/Video"; |
|||
import LineChart from "../../LineChart/index.vue"; |
|||
import DeviceParams from "./components/DeviceParams.vue"; |
|||
import DeviceControlDialog from "./components/DeviceControlDialog.vue"; |
|||
import AirConditioning from "./components/AirConditioning.vue"; |
|||
import request from "@/utils/request"; |
|||
import DevicePacks from "./components/DevicePacks.vue"; |
|||
import { |
|||
getRoadInfoByStakeMark, |
|||
getProduct, |
|||
} from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js"; |
|||
import { dialogDelayVisible } from "./../mixin"; |
|||
import { resolve } from "@antv/x6/lib/registry/node-anchor/util"; |
|||
|
|||
// 一体机柜 |
|||
export default { |
|||
name: "IntegratedCabinet", |
|||
mixins: [dialogDelayVisible], |
|||
components: { |
|||
Dialog, |
|||
Descriptions, |
|||
LineChart, |
|||
Video, |
|||
Button, |
|||
DeviceParams, |
|||
DevicePacks, |
|||
DeviceControlDialog, |
|||
AirConditioning, |
|||
}, |
|||
data() { |
|||
return { |
|||
airStatus:"", |
|||
activeName: "first", |
|||
releaseVisible: false, |
|||
deviceControlVisible: false, |
|||
airConditioningVisible:false, |
|||
data: { |
|||
deviceName: "LH24", |
|||
roadName: "济菏高速", |
|||
stakeMark: "k094+079", |
|||
direction: "1", |
|||
organizationName: "山东高速济南发展公司", |
|||
brand: "XXX厂家", |
|||
deviceState: "0", |
|||
}, |
|||
list: [ |
|||
{ |
|||
label: "设备名称", |
|||
key: "deviceName", |
|||
}, |
|||
{ |
|||
label: "设备桩号", |
|||
key: "stakeMark", |
|||
}, |
|||
{ |
|||
label: "道路名称", |
|||
key: "roadName", |
|||
}, |
|||
{ |
|||
label: "设备方向", |
|||
key: "direction", |
|||
enum: "CameraDirectionEnum", |
|||
}, |
|||
{ |
|||
label: "设备状态", |
|||
key: "deviceState", |
|||
enum: "DeviceTypeEnum", |
|||
// visible: false, |
|||
}, |
|||
// { |
|||
// label: "设备状态", |
|||
// key: "deviceStateLiteral", |
|||
// }, |
|||
{ |
|||
label: "设备厂商", |
|||
key: "manufacturer", |
|||
}, |
|||
], |
|||
camId:null |
|||
}; |
|||
}, |
|||
async created() { |
|||
// if (!this.dialogData.iotDeviceId) this.dialogData.iotDeviceId = '10.0.36.146-1883'; |
|||
|
|||
// let deviceInfo = await this.getDeviceInfo(); |
|||
// 修改camid |
|||
if(typeof this.dialogData.otherConfig === 'string'){ |
|||
const oConfig = JSON.parse(this.dialogData.otherConfig) |
|||
if(oConfig && oConfig.camId){ |
|||
this.camId = oConfig.camId |
|||
} |
|||
} |
|||
this.data = { |
|||
...this.dialogData, |
|||
roadName: '济菏高速', |
|||
// deviceStateLiteral: deviceInfo.data.formatValue.deviceState, |
|||
}; |
|||
|
|||
//厂商 |
|||
getProduct(this.dialogData.productId).then((data) => { |
|||
this.dialogData.brand = data.brand; |
|||
}); |
|||
this.getSattue(); |
|||
// const roadInfo = await getRoadInfoByStakeMark(this.dialogData.stakeMark); |
|||
// if (roadInfo) this.data.roadName = roadInfo.roadName; |
|||
}, |
|||
methods: { |
|||
async getDeviceInfo() { |
|||
return request({ |
|||
url: `/business/device/properties/latest/${this.dialogData.iotDeviceId || "10.0.36.143-1883" }/3`, |
|||
method: "get", |
|||
params: {}, |
|||
}); |
|||
}, |
|||
async getSattue(){ |
|||
const iotDeviceId = this.dialogData.iotDeviceId.replace(/-502$/, '-5000'); |
|||
return request({ |
|||
url: `/business/device/getDeviceById`, |
|||
method: "post", |
|||
data: { iotDeviceId:iotDeviceId }, |
|||
}).then((res) => { |
|||
if(res.code!=200){ |
|||
console.log('err', res.msg) |
|||
} |
|||
console.log(res.data.deviceState) |
|||
this.airStatus=res.data.deviceState; |
|||
}).catch((err) => { |
|||
console.log('err', err) |
|||
}); |
|||
} |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
div.switcher { |
|||
font-size: 12px; |
|||
padding: 2px; |
|||
} |
|||
</style> |
|||
<style lang="scss" scoped> |
|||
.IntegratedCabinet { |
|||
width: 508px; |
|||
color: #fff; |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 250px; |
|||
::v-deep { |
|||
.el-tabs__content { |
|||
overflow-y: auto; |
|||
max-height: 220px; |
|||
} |
|||
} |
|||
|
|||
.camera-video { |
|||
flex: 1.5; |
|||
} |
|||
|
|||
.tabs { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
|
|||
::v-deep { |
|||
.el-tabs__content { |
|||
flex: 1; |
|||
|
|||
.el-tab-pane { |
|||
height: 100%; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.bottom { |
|||
margin-top: 12px; |
|||
display: flex; |
|||
gap: 9px; |
|||
align-items: center; |
|||
justify-content: end; |
|||
|
|||
>div { |
|||
font-size: 16px; |
|||
padding: 6px 12px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
|
Loading…
Reference in new issue