You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

291 lines
7.9 KiB

<template>
<div class="deviceItem" :style="info.styleObject">
<!-- 点击编辑弹出框 -->
<a-popover
color="rgba(0, 0, 0, 0.8)"
placement="right"
v-model:visible="visible"
trigger="click">
<template #content>
<div class="item-box">
<div class="item-box-title">
<img v-if="info.type == 2" src="./images/device1.png" alt="" />
<img v-if="info.type == 4" src="./images/device2.png" alt="" />
<span>{{ info.name }}</span>
</div>
<!-- 开关 -->
<div v-if="info.type == 4" class="item-box-switch">
<div>开关</div>
<a-switch style="margin-top: 3px" size="small" v-model:checked="info.open" />
</div>
<div v-if="info.type == 2" class="item-box-range">
<div>开度</div>
<!-- <a-slider v-model:value="info.value" :tooltip-visible="true" :marks="range" :step="1"> -->
<a-slider v-model:value="info.value" :marks="range" :step="1">
<template #mark="{ label, point }">
<template v-if="point === 100">
<strong>{{ label }}</strong>
</template>
<template v-else>{{ label }}</template>
</template>
</a-slider>
</div>
<div v-if="info.type == 4" class="item-box-range">
<div>频率</div>
<a-slider v-model:value="info.value" :marks="range" :step="1">
<template #mark="{ label, point }">
<template v-if="point === 100">
<strong>{{ label }}</strong>
</template>
<template v-else>{{ label }}</template>
</template>
</a-slider>
</div>
<div class="item-box-button">
<a-button class="item-btn" @click="refresh">刷新</a-button>
<a-popconfirm
title="此操作只保存修改,需右下角按钮提交"
ok-text="确定"
cancel-text="取消"
@confirm="editDevice">
<a-button class="item-btn" type="primary">执行</a-button>
</a-popconfirm>
</div>
</div>
</template>
<div v-if="!info.edited && info.control" class="device-button-back">
<img src="./images/edit.png" alt="" />
编辑</div
>
</a-popover>
<a-popconfirm
title="撤销将移除已保存的修改"
ok-text="确定"
cancel-text="取消"
@confirm="backConfirm">
<div v-if="info.edited && info.control" class="device-button">
<img src="./images/back.png" alt="" />
撤销</div
>
</a-popconfirm>
<!-- 设备图标 - 当前共5种单位 -->
<img v-if="info.icon == 1" src="./images/pond1.png" alt="" />
<img v-if="info.icon == 2" src="./images/pond2.png" alt="" />
<img v-if="info.icon == 3" src="./images/valve1.png" alt="" />
<img v-if="info.icon == 4" src="./images/valve2.png" alt="" />
<img v-if="info.icon == 5" style="width: 70px; height: 70px" src="./images/pump.png" alt="" />
<div class="info-name">
<span>{{ info.name }}</span>
<div class="img-box">
<img
v-if="(info.type == 2 || info.type == 4) && info.state == 0"
src="./images/alarm1.png"
alt="" />
<img
v-if="(info.type == 2 || info.type == 4) && info.state > 0"
src="./images/alarm2.png"
alt="" />
</div>
</div>
<!-- 只有水池会显示容量 -->
<div class="info-value" v-if="info.type == 1 || info.type == 3">
容量 : {{ info.value + info.unit }}</div
>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import { message } from 'ant-design-vue';
// 图像资源引入
// 初始化 ===============================================================
//页面 创建
onMounted(() => {});
// 传入的值
const props = defineProps({
// 设备类型
info: {
type: Object,
default: () => {},
},
});
// 父组件传递的数据
const info = computed(() => props.info);
// 组件交互 =============================================================
// 用于控制弹窗的显示状态
const visible = ref(false);
// 滑动条显示规则
const range = ref({
0: {
style: {
color: '#0DFFFF',
},
label: 'min',
},
100: {
style: {
color: '#0DFFFF',
},
label: 'max',
},
});
// 刷新事件
const refresh = () => {
info.value.value = info.value.oldVal;
};
// 撤销事件
const backConfirm = () => {
info.value.value = info.value.oldVal;
info.value.edited = false;
// 如果为水泵
if (info.value.type == 4) {
console.log(info.value);
info.value.open = info.value.opened;
}
};
// 编辑-执行事件
const editDevice = () => {
// 未产生修改
if (info.value.value == info.value.oldVal && info.value.open === info.value.opened) {
return message.info('未产生任何修改');
}
// 产生修改
visible.value = false;
info.value.edited = true;
message.success('保存成功');
};
</script>
<style lang="less" scoped>
// 设备的图像
.deviceItem {
--size: 90px;
width: var(--size);
height: var(--size);
position: absolute;
top: 20%;
text-align: center;
// 默认使用3
z-index: 3;
> img {
user-select: none;
}
// 设备名
.info-name {
color: white;
font-size: 15px;
text-align: center;
position: relative;
> span {
vertical-align: middle;
}
.img-box {
display: inline-block;
position: absolute;
margin-left: 8px;
width: 22px;
> img {
width: 22px;
}
}
}
// 设备容量(仅水池)
.info-value {
text-align: center;
color: #23fdab;
font-size: 13px;
}
// 撤销按钮
.device-button {
position: absolute;
top: -35px;
left: 0;
right: 0;
margin: auto;
width: 5em;
padding: 5px 0;
text-align: center;
border-radius: 4px;
font-weight: 700;
cursor: pointer;
background: linear-gradient(#ffd700, #ffa403);
color: #674330;
user-select: none;
> img {
width: 13px;
}
}
// 编辑按钮
.device-button-back {
position: absolute;
top: -35px;
left: 0;
right: 0;
margin: auto;
width: 5em;
padding: 5px 0;
text-align: center;
border-radius: 4px;
font-weight: 700;
cursor: pointer;
background: linear-gradient(#00f92c, #00fe9f);
color: #003d5a;
user-select: none;
> img {
width: 13px;
}
}
> img {
width: 100%;
height: 100%;
}
}
// 弹出框样式
.ant-popover-inner {
// 弹出框内部容器
.item-box {
width: 250px;
display: flex;
flex-direction: column;
gap: 15px;
color: white;
img {
width: 20px;
margin-right: 10px;
vertical-align: middle;
}
}
// 开关控件
.item-box-switch {
padding: 10px 15px;
display: flex;
justify-content: space-between;
border-radius: 4px;
background: rgba(67, 136, 251, 0.3);
.ant-switch-checked {
background: linear-gradient(180deg, rgba(1, 206, 255, 1) 0%, rgba(0, 150, 229, 1) 100%);
}
}
// 滑动条控件
.item-box-range {
padding: 10px 15px 10px 15px;
box-sizing: border-box;
border-radius: 4px;
background: rgba(67, 136, 251, 0.3);
.ant-slider-handle {
border: 2px solid red !important;
}
}
// 底部按钮区
.item-box-button {
text-align: right;
.item-btn {
text-align: center;
margin-left: 10px;
}
}
}
</style>