zhaohy
3 months ago
14 changed files with 2263 additions and 21 deletions
@ -0,0 +1,429 @@ |
|||||
|
<template> |
||||
|
<table class="custom-table table1"> |
||||
|
<thead> |
||||
|
<tr :style="{ background: 'rgba(35,45,69)' }"> |
||||
|
<th>序号</th> |
||||
|
<th>执行时间</th> |
||||
|
<th>操作内容</th> |
||||
|
<th>操作人</th> |
||||
|
<th>状态</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
<tr |
||||
|
:style="{ color: row.ctrlResult == 1 ? 'red' : 'white' }" |
||||
|
v-for="(row, index) in dataSource" |
||||
|
:key="index" |
||||
|
@click="handleRowClick(row.id, index)" |
||||
|
:class="index === trIndex ? 'isTrIndex' : ''"> |
||||
|
<td>{{ index + 1 }}</td> |
||||
|
<td>{{ row.startTime }}</td> |
||||
|
<td>{{ row.operationContent }}</td> |
||||
|
<td>{{ row.createUser }}</td> |
||||
|
<td>{{ row.ctrlResult ? '失败' : '成功' }}</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
<a-pagination |
||||
|
style="margin-top: 10px; text-align: right" |
||||
|
v-model:current="pagination.pageNum" |
||||
|
v-model:pageSize="pagination.pageSize" |
||||
|
show-size-changer |
||||
|
:total="pagination.total" |
||||
|
@change="getTable(true)" /> |
||||
|
<div style="width: 100%; height: 40px"></div> |
||||
|
|
||||
|
<div class="out-dialog" :class="{ showDialog: logModalVisible }" v-if="logModalVisible"> |
||||
|
<div class="content"> |
||||
|
<div> |
||||
|
<div class="div-operation"></div> |
||||
|
<span class="text-operation">变更内容 </span> |
||||
|
</div> |
||||
|
<div> |
||||
|
<button :class="{ btn: true, selected: activeButton == 1 }" @click="changeBtn(1)" |
||||
|
>阀门</button |
||||
|
> |
||||
|
<button :class="{ btn: true, selected: activeButton == 2 }" @click="changeBtn(2)" |
||||
|
>水泵</button |
||||
|
> |
||||
|
</div> |
||||
|
<div class="device-list" v-if="activeButton == 1"> |
||||
|
<div class="device-list-item" v-for="(item, index) in valveLogList" :key="index"> |
||||
|
<div class="list-item-title"> |
||||
|
<div class="item-title"> |
||||
|
<img src="../images/device1.png" alt="" /> |
||||
|
<span>{{ item.deviceGroupName }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="list-item-main"> |
||||
|
<div> |
||||
|
<div class="info">开度</div> |
||||
|
<div class="text"> |
||||
|
<span>{{ item.openPercentBefore + '%' }}</span> |
||||
|
<img src="/asset/image/bulbLogo/22406.png" alt="" /> |
||||
|
<span>{{ item.openPercentAfter + '%' }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<a-empty style="margin-top: 100px" v-if="valveLogList.length == 0"> |
||||
|
<template #description> <span style="color: white">暂无数据</span></template> |
||||
|
</a-empty> |
||||
|
</div> |
||||
|
<div class="device-list" v-if="activeButton == 2"> |
||||
|
<div class="device-list-item" v-for="(item, index) in pumpLogList" :key="index"> |
||||
|
<div class="list-item-title"> |
||||
|
<div class="item-title"> |
||||
|
<img src="../images/device2.png" alt="" /> |
||||
|
<span>{{ item.deviceGroupName }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="list-item-main"> |
||||
|
<div> |
||||
|
<div class="info">频率</div> |
||||
|
<div class="text"> |
||||
|
<span>{{ item.frequencyBefore + 'MHz' }}</span> |
||||
|
<img src="/asset/image/bulbLogo/22406.png" alt="" /> |
||||
|
<span>{{ item.frequencyAfter + 'MHz' }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div> |
||||
|
<div class="info">开关</div> |
||||
|
<div class="text"> |
||||
|
<span>{{ item.switchStatusBefore.label }}</span> |
||||
|
<img src="/asset/image/bulbLogo/22406.png" alt="" /> |
||||
|
<span>{{ item.switchStatusAfter.label }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<a-empty style="margin-top: 100px" v-if="pumpLogList.length == 0"> |
||||
|
<template #description> <span style="color: white">暂无数据</span></template> |
||||
|
</a-empty> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="width: 100%; height: 160px"></div> |
||||
|
<div class="button-box"> |
||||
|
<button class="cancel" @click="logModalVisible = false">关闭</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="div-add"> |
||||
|
<button class="add" @click="reset">刷新</button> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { ref, onMounted } from 'vue'; |
||||
|
import { message } from 'ant-design-vue'; |
||||
|
import { Pagination } from 'ant-design-vue'; |
||||
|
import { http } from '/nerv-lib/util/http'; |
||||
|
import { waterSys } from '/@/api/waterSystem'; |
||||
|
// 全局变量 |
||||
|
import { items } from '/@/store/item'; |
||||
|
|
||||
|
// 初始化 ======================================================= |
||||
|
|
||||
|
// 组件 |
||||
|
defineOptions({ |
||||
|
components: { |
||||
|
'a-pagination': Pagination, |
||||
|
}, |
||||
|
}); |
||||
|
// 初始化 |
||||
|
onMounted(() => { |
||||
|
getTable(); |
||||
|
}); |
||||
|
|
||||
|
// 全局变量 |
||||
|
const state = items(); |
||||
|
|
||||
|
// 日志业务 ====================================================== |
||||
|
|
||||
|
// 分页设置 |
||||
|
const pagination = ref({ |
||||
|
pageSize: 10, |
||||
|
pageNum: 1, |
||||
|
total: 0, |
||||
|
}); |
||||
|
// 表格数据 |
||||
|
const dataSource = ref([]); |
||||
|
// 当前选中表格行 |
||||
|
let trIndex = ref(-1); |
||||
|
// 获得表格数据 |
||||
|
const getTable = (changePage = false) => { |
||||
|
state.setLoading(true); |
||||
|
// 如果是切换页面,则清除当前序列、关闭弹窗 |
||||
|
if (changePage) { |
||||
|
trIndex.value = -1; |
||||
|
logModalVisible.value = false; |
||||
|
pumpLogList.value.length = 0; |
||||
|
valveLogList.value.length = 0; |
||||
|
} |
||||
|
http |
||||
|
.get(waterSys.getLog, { |
||||
|
pageSize: pagination.value.pageSize, |
||||
|
pageNum: pagination.value.pageNum, |
||||
|
}) |
||||
|
.then((res) => { |
||||
|
state.setLoading(false); |
||||
|
let data = res.data; |
||||
|
dataSource.value = data.records; |
||||
|
pagination.value.total = data.total; |
||||
|
}) |
||||
|
.catch(() => { |
||||
|
state.setLoading(false); |
||||
|
}); |
||||
|
}; |
||||
|
// 刷新功能(右下角) |
||||
|
const reset = () => { |
||||
|
trIndex.value = -1; |
||||
|
logModalVisible.value = false; |
||||
|
pagination.value = { |
||||
|
pageSize: 10, |
||||
|
pageNum: 1, |
||||
|
total: 0, |
||||
|
}; |
||||
|
getTable(); |
||||
|
}; |
||||
|
// 点击日志行事件 |
||||
|
const handleRowClick = (id: any, index: any) => { |
||||
|
trIndex.value = index; |
||||
|
getLogDetail(id); |
||||
|
}; |
||||
|
|
||||
|
// 日志详情业务 ================================================== |
||||
|
|
||||
|
// 日志详情显隐 |
||||
|
const logModalVisible = ref(false); |
||||
|
const getLogDetail = (id: any) => { |
||||
|
state.setLoading(true); |
||||
|
http |
||||
|
.get(waterSys.getLogDetail, { logId: id }) |
||||
|
.then((res) => { |
||||
|
state.setLoading(false); |
||||
|
const data = res.data; |
||||
|
if (data.pumpLogList.length || data.valveLogList.length) { |
||||
|
// 显示模态框 |
||||
|
logModalVisible.value = true; |
||||
|
pumpLogList.value = data.pumpLogList; |
||||
|
valveLogList.value = data.valveLogList; |
||||
|
} else { |
||||
|
return message.info('返回值无效'); |
||||
|
} |
||||
|
}) |
||||
|
.catch(() => { |
||||
|
state.setLoading(false); |
||||
|
}); |
||||
|
}; |
||||
|
// 当前选中的设备类型 阀门=1/水泵=2 |
||||
|
const activeButton = ref(1); |
||||
|
// 切换设备类型 |
||||
|
const changeBtn = (key: number) => { |
||||
|
activeButton.value = key; |
||||
|
}; |
||||
|
// 水泵数据 |
||||
|
const pumpLogList = ref<any>([]); |
||||
|
// 水阀数据 |
||||
|
const valveLogList = ref<any>([]); |
||||
|
|
||||
|
// 向外暴露方法 |
||||
|
defineExpose({ |
||||
|
reset, |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="less" scoped> |
||||
|
@import '../../style/dialogStyle.less'; |
||||
|
|
||||
|
// 右下角添加按钮 |
||||
|
.div-add { |
||||
|
height: 64px; |
||||
|
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
align-items: center; |
||||
|
position: fixed; |
||||
|
bottom: 0; |
||||
|
right: 0; |
||||
|
margin-right: 20px; |
||||
|
.add { |
||||
|
width: 74px; |
||||
|
height: 40px; |
||||
|
opacity: 1; |
||||
|
border-radius: 4px; |
||||
|
background: rgba(67, 136, 251, 1); |
||||
|
border: rgba(67, 136, 251, 1); |
||||
|
font-size: 14px; |
||||
|
font-weight: 400; |
||||
|
color: rgba(255, 255, 255, 1); |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 表格 |
||||
|
.custom-table { |
||||
|
border-collapse: collapse; |
||||
|
width: 416px; |
||||
|
min-height: 60px; |
||||
|
max-height: 500px; |
||||
|
overflow-y: auto; |
||||
|
cursor: pointer; |
||||
|
color: rgba(255, 255, 255, 1); |
||||
|
} |
||||
|
|
||||
|
.custom-table th, |
||||
|
.custom-table td { |
||||
|
border: 1px solid rgba(163, 192, 243, 1); |
||||
|
text-align: left; |
||||
|
padding: 8px; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.table1 { |
||||
|
margin-top: 20px; |
||||
|
width: 100%; |
||||
|
border: 1px solid rgba(255, 255, 255); |
||||
|
border-radius: 5px; |
||||
|
background: rgba(255, 255, 255, 0.1); |
||||
|
|
||||
|
.tabReboot, |
||||
|
.tabDelete { |
||||
|
border: none; |
||||
|
background-color: rgba(0, 0, 0, 0); |
||||
|
font-size: 14px; |
||||
|
font-weight: 400; |
||||
|
letter-spacing: 0; |
||||
|
line-height: 20px; |
||||
|
color: rgba(67, 136, 251, 1); |
||||
|
} |
||||
|
|
||||
|
.tabReboot { |
||||
|
margin-right: 8px; |
||||
|
} |
||||
|
|
||||
|
.isTrIndex { |
||||
|
background: rgba(67, 136, 251, 1); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
::v-deep(.ant-transfer) { |
||||
|
// 屏蔽自带的hover效果 |
||||
|
.ant-transfer-list-content-item:hover { |
||||
|
background: black; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.btn { |
||||
|
width: 92px; |
||||
|
height: 40px; |
||||
|
border-radius: 4px; |
||||
|
opacity: 1; |
||||
|
margin-top: 10px; |
||||
|
margin-left: 15px; |
||||
|
font-size: 14px; |
||||
|
font-weight: 400; |
||||
|
opacity: 1; |
||||
|
border: 1px solid rgba(207, 212, 219, 1); |
||||
|
line-height: 20.27px; |
||||
|
color: white; |
||||
|
text-align: center; |
||||
|
vertical-align: top; |
||||
|
background-color: rgba(255, 255, 255, 0.1); |
||||
|
} |
||||
|
|
||||
|
.selected { |
||||
|
background: linear-gradient(180deg, rgba(201, 245, 255, 1) 0%, rgba(138, 215, 255, 1) 100%); |
||||
|
color: rgba(0, 61, 90, 1); |
||||
|
border: 1px solid white; |
||||
|
} |
||||
|
|
||||
|
.btn:hover { |
||||
|
background-color: rgba(207, 212, 219, 1); |
||||
|
} |
||||
|
|
||||
|
.btn:active { |
||||
|
background-color: rgba(102, 102, 102, 1); |
||||
|
color: white; |
||||
|
} |
||||
|
.device-list { |
||||
|
margin-left: 15px; |
||||
|
margin-top: 15px; |
||||
|
width: calc(100% - 15px); |
||||
|
font-size: 13px; |
||||
|
height: auto; |
||||
|
display: flex; |
||||
|
gap: 15px; |
||||
|
flex-direction: column; |
||||
|
.device-list-item { |
||||
|
width: calc(100% - 15px); |
||||
|
box-sizing: border-box; |
||||
|
padding: 10px; |
||||
|
border: 2px solid #03407e; |
||||
|
border-radius: 4px; |
||||
|
background: rgba(0, 177, 255, 0.2); |
||||
|
display: flex; |
||||
|
gap: 10px; |
||||
|
flex-direction: column; |
||||
|
.list-item-title { |
||||
|
color: white; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
.item-title { |
||||
|
img { |
||||
|
width: 25px; |
||||
|
} |
||||
|
span { |
||||
|
margin-left: 10px; |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
} |
||||
|
.revoke { |
||||
|
text-align: center; |
||||
|
border: none; |
||||
|
border-radius: 4px; |
||||
|
padding: 5px 15px; |
||||
|
background: linear-gradient( |
||||
|
180deg, |
||||
|
rgba(255, 187, 0, 1) 0%, |
||||
|
rgba(255, 112, 3, 1) 91.21%, |
||||
|
rgba(255, 129, 3, 1) 100% |
||||
|
); |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
} |
||||
|
.list-item-main { |
||||
|
display: flex; |
||||
|
> div { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
gap: 8px; |
||||
|
> .info { |
||||
|
text-align: center; |
||||
|
width: 6em; |
||||
|
height: 2.5em; |
||||
|
line-height: 2.5em; |
||||
|
border-radius: 4px; |
||||
|
color: white; |
||||
|
background: linear-gradient( |
||||
|
180deg, |
||||
|
rgba(86, 221, 253, 1) 0%, |
||||
|
rgba(25, 176, 255, 1) 100% |
||||
|
); |
||||
|
} |
||||
|
> .text { |
||||
|
:first-child { |
||||
|
color: white; |
||||
|
line-height: 2.5em; |
||||
|
} |
||||
|
img { |
||||
|
padding: 0 5px; |
||||
|
} |
||||
|
:last-child { |
||||
|
line-height: 2.5em; |
||||
|
color: red; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,381 @@ |
|||||
|
<template> |
||||
|
<div class="div-add"> |
||||
|
<button class="add" @click="addModal">添加</button> |
||||
|
<a-popconfirm |
||||
|
title="是否提交以上修改?" |
||||
|
placement="bottomLeft" |
||||
|
ok-text="确定" |
||||
|
cancel-text="取消" |
||||
|
@confirm="sendTable"> |
||||
|
<button class="add" style="margin-left: 20px">执行</button> |
||||
|
</a-popconfirm> |
||||
|
</div> |
||||
|
<div class="buttons"> |
||||
|
<span style="color: red; padding-top: 20px">*以下修改需执行后生效</span> |
||||
|
<div class="plans"> |
||||
|
<button class="plan enabled" style="margin-right: 10px" @click="togglePlan(1)"> |
||||
|
计划启用 |
||||
|
</button> |
||||
|
<button class="plan disabled" @click="togglePlan(3)"> 计划禁用 </button> |
||||
|
</div> |
||||
|
</div> |
||||
|
<table class="custom-table table1"> |
||||
|
<thead> |
||||
|
<tr :style="{ background: 'rgba(35,45,69)' }"> |
||||
|
<th>序号</th> |
||||
|
<th>执行时间</th> |
||||
|
<th>计划名称</th> |
||||
|
<th>状态</th> |
||||
|
<th>操作</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
<tr v-for="(row, index) in dataSource" v-show="row.executeStatus.value != 0" :key="index"> |
||||
|
<td>{{ index + 1 }}</td> |
||||
|
<td>{{ row.startTime }}</td> |
||||
|
<td>{{ row.planName }}</td> |
||||
|
<td> |
||||
|
<button |
||||
|
:style="{ |
||||
|
'font-size': '12px', |
||||
|
width: '5em', |
||||
|
background: 'rgb(47, 47, 47)', |
||||
|
color: setStateColor(row.executeStatus.value), |
||||
|
border: '1px solid', |
||||
|
}"> |
||||
|
{{ setStateText(row.executeStatus.value) }} |
||||
|
</button> |
||||
|
</td> |
||||
|
<td> |
||||
|
<div class="tabReboot" @click="startPlan(row)">启用</div> |
||||
|
<a-popconfirm |
||||
|
title="此操作将移除该数据" |
||||
|
ok-text="确定" |
||||
|
cancel-text="取消" |
||||
|
placement="topRight" |
||||
|
@confirm="deletePlan(row)"> |
||||
|
<div class="tabDelete">删除</div> |
||||
|
</a-popconfirm> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
<div class="out-dialog" v-if="addVisible"> |
||||
|
<div class="content"> |
||||
|
<div class="div-operation"></div> |
||||
|
<span class="text-operation">计划库</span> |
||||
|
</div> |
||||
|
<div style="margin-top: 20px"> |
||||
|
<a-transfer |
||||
|
v-model:target-keys="targetKeys" |
||||
|
:data-source="transferData" |
||||
|
show-search |
||||
|
:filter-option="filterOption" |
||||
|
:render="(item: any) => item.title" |
||||
|
@change="handleChange" |
||||
|
:style="{ color: 'rgba(255,255,255,1)' }" |
||||
|
@search="handleSearch" |
||||
|
:listStyle="{ border: '2px solid rgba(25,74,125,1)', height: 'calc(100vh - 200px)' }" /> |
||||
|
</div> |
||||
|
<div style="width: 100%; height: 60px"></div> |
||||
|
<div class="button-box"> |
||||
|
<button class="cancel" @click="addVisible = false">取消</button> |
||||
|
<button class="execute" @click="sendPlan">确定</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { ref, onMounted } from 'vue'; |
||||
|
// 请求 |
||||
|
import { http } from '/nerv-lib/util/http'; |
||||
|
import { planManage } from '/@/api/planManage'; |
||||
|
import { waterSys } from '/@/api/waterSystem'; |
||||
|
import { message } from 'ant-design-vue'; |
||||
|
import { getEnum } from '/@/api'; |
||||
|
// 全局变量 |
||||
|
import { items } from '/@/store/item'; |
||||
|
|
||||
|
// 初始化 =========================================================== |
||||
|
|
||||
|
onMounted(() => { |
||||
|
// 获得枚举 |
||||
|
getStateEnum(); |
||||
|
// 获得穿梭框 与 表格数据 |
||||
|
reset(); |
||||
|
}); |
||||
|
// 全局变量 |
||||
|
const state = items(); |
||||
|
// 获得任务状态枚举 |
||||
|
const getStateEnum = async () => { |
||||
|
let enumData = await getEnum({ params: { enumType: 'PlanExecuteStatus' } }); |
||||
|
stateList.value = enumData.data; |
||||
|
}; |
||||
|
/** |
||||
|
* @method resetAll 刷新3个tab中的全部数据(修改计划,会影响tab1数据信息,生成tab3日志) |
||||
|
*/ |
||||
|
const emit = defineEmits(['resetAll']); |
||||
|
|
||||
|
// tab页部分 ======================================================== |
||||
|
|
||||
|
// 状态枚举 |
||||
|
const stateList = ref([]); |
||||
|
// 设置枚举的颜色 与 文本 |
||||
|
const setStateColor = (state: number) => { |
||||
|
if (state == 0) { |
||||
|
return '#ccc'; |
||||
|
} else if (state == 1) { |
||||
|
return 'orange'; |
||||
|
} else if (state == 2) { |
||||
|
return 'rgb(57, 215, 187)'; |
||||
|
} else if (state == 3) { |
||||
|
return 'rgb(255, 0, 0)'; |
||||
|
} |
||||
|
}; |
||||
|
// 设置枚举的文本 |
||||
|
const setStateText = (state: number) => { |
||||
|
const res = stateList.value.find((item) => { |
||||
|
return item.value == state; |
||||
|
}); |
||||
|
return res.label; |
||||
|
}; |
||||
|
// 计划启用/禁用事件 |
||||
|
const togglePlan = (state: number) => { |
||||
|
dataSource.value.forEach((item: any) => { |
||||
|
// 执行中 无法修改为待执行 |
||||
|
if (state == 1) { |
||||
|
if (item.executeStatus.value != 2) { |
||||
|
item.executeStatus.value = state; |
||||
|
} |
||||
|
// 任何状态都可以修改为 暂停 |
||||
|
} else { |
||||
|
item.executeStatus.value = state; |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
// 表格数据 |
||||
|
const dataSource = ref([]); |
||||
|
// 获得表格数据 |
||||
|
const getTable = () => { |
||||
|
http |
||||
|
.get(planManage.getTableData, { |
||||
|
projectId: state.projectId, |
||||
|
siteId: state.siteId, |
||||
|
// 设备类型(1照明,2空调,3排风扇,4风幕机,5电动窗,6给排水) |
||||
|
ctrlType: 6, |
||||
|
}) |
||||
|
.then((res) => { |
||||
|
dataSource.value = res.data; |
||||
|
}); |
||||
|
}; |
||||
|
// 删除表格中的计划(将当前任意状态,修改为未启用 =0) |
||||
|
const deletePlan = (row: any) => { |
||||
|
row.executeStatus.value = 0; |
||||
|
}; |
||||
|
// 重启表格中的计划(将当前任意状态,修改为待执行 = 1) |
||||
|
const startPlan = (row: any) => { |
||||
|
if (row.executeStatus.value == 1) { |
||||
|
return message.info('该数据已是待执行状态,无需再次修改'); |
||||
|
} |
||||
|
if (row.executeStatus.value == 2) { |
||||
|
return message.info('执行中的状态已被启用,无需修改'); |
||||
|
} |
||||
|
row.executeStatus.value = 1; |
||||
|
}; |
||||
|
// 将对表格的修改统一发送 |
||||
|
const sendTable = () => { |
||||
|
if (!dataSource.value.length) { |
||||
|
return message.info('没有任何数据可以提交'); |
||||
|
} |
||||
|
state.setLoading(true); |
||||
|
http |
||||
|
.post( |
||||
|
waterSys.submitTableData + |
||||
|
`?projectId=${state.projectId}${state.siteId ? `&siteId=${state.siteId}` : ''}`, |
||||
|
dataSource.value, |
||||
|
) |
||||
|
.then((res) => { |
||||
|
state.setLoading(false); |
||||
|
if (res.retcode == 0) { |
||||
|
message.success('操作成功'); |
||||
|
// 刷新数据 |
||||
|
emit('resetAll'); |
||||
|
} else { |
||||
|
message.info(res.msg); |
||||
|
} |
||||
|
}) |
||||
|
.catch(() => { |
||||
|
state.setLoading(false); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const reset = () => { |
||||
|
// 计划表格 |
||||
|
getTable(); |
||||
|
// 穿梭框原始数据 |
||||
|
getLeftPlan(); |
||||
|
}; |
||||
|
|
||||
|
// tab页弹窗部分 ==================================================== |
||||
|
|
||||
|
// 添加弹窗控制变量 |
||||
|
const addVisible = ref(false); |
||||
|
// 打开弹窗 |
||||
|
const addModal = () => { |
||||
|
addVisible.value = true; |
||||
|
}; |
||||
|
|
||||
|
// 穿梭框部分 ======================================================= |
||||
|
|
||||
|
// 穿梭框数据 |
||||
|
const transferData = ref([]) as any; |
||||
|
// 获得穿梭框原始数据 |
||||
|
const getLeftPlan = () => { |
||||
|
http |
||||
|
.get(planManage.getTransData, { |
||||
|
projectId: state.projectId, |
||||
|
siteId: state.siteId, |
||||
|
// 设备类型(1照明,2空调,3排风扇,4风幕机,5电动窗,6给排水) |
||||
|
ctrlType: 6, |
||||
|
}) |
||||
|
.then((res) => { |
||||
|
let arr: Array<Object> = []; |
||||
|
res.data.forEach((item: any) => { |
||||
|
arr.push({ |
||||
|
key: item.id, |
||||
|
title: item.planName, |
||||
|
}); |
||||
|
}); |
||||
|
transferData.value = arr; |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const handleChange = (keys: string[], direction: string, moveKeys: string[]) => { |
||||
|
console.log(keys, direction, moveKeys); |
||||
|
}; |
||||
|
const handleSearch = (dir: string, value: string) => { |
||||
|
console.log('search:', dir, value); |
||||
|
}; |
||||
|
// 穿梭框选中数据 |
||||
|
const targetKeys = ref<string[]>([]); |
||||
|
// 将穿梭框选中的计划提交 |
||||
|
const sendPlan = () => { |
||||
|
if (targetKeys.value.length < 1) { |
||||
|
return message.info('没有选择任何计划'); |
||||
|
} |
||||
|
http.post(planManage.submitTransData, targetKeys.value).then(() => { |
||||
|
message.success('添加成功'); |
||||
|
// 如果发送成功,则刷新表格 |
||||
|
reset(); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const filterOption = (inputValue: string, option: any) => { |
||||
|
return option.description.indexOf(inputValue) > -1; |
||||
|
}; |
||||
|
|
||||
|
// 向外暴露方法 |
||||
|
defineExpose({ |
||||
|
reset, |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="less" scoped> |
||||
|
@import '../../style/dialogStyle.less'; |
||||
|
.buttons { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
.plan { |
||||
|
border: none; |
||||
|
font-size: 14px; |
||||
|
font-weight: 400; |
||||
|
border-radius: 5px; |
||||
|
width: 88px; |
||||
|
height: 32px; |
||||
|
color: white; |
||||
|
cursor: pointer; |
||||
|
margin: 15px 0; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
.plan.enabled { |
||||
|
background: linear-gradient(180deg, rgba(103, 222, 0, 1) 0%, rgba(0, 181, 6, 1) 100%); |
||||
|
} |
||||
|
.plan.disabled { |
||||
|
background-color: red; |
||||
|
} |
||||
|
.plan:disabled { |
||||
|
cursor: not-allowed; |
||||
|
} |
||||
|
} |
||||
|
// 右下角添加按钮 |
||||
|
.div-add { |
||||
|
height: 64px; |
||||
|
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
align-items: center; |
||||
|
position: fixed; |
||||
|
bottom: 0; |
||||
|
right: 0; |
||||
|
margin-right: 10px; |
||||
|
.add { |
||||
|
width: 74px; |
||||
|
height: 40px; |
||||
|
opacity: 1; |
||||
|
border-radius: 4px; |
||||
|
background: rgba(67, 136, 251, 1); |
||||
|
border: rgba(67, 136, 251, 1); |
||||
|
font-size: 14px; |
||||
|
font-weight: 400; |
||||
|
color: rgba(255, 255, 255, 1); |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
} |
||||
|
// 表格 |
||||
|
.custom-table { |
||||
|
border-collapse: collapse; |
||||
|
width: 416px; |
||||
|
height: 40px; |
||||
|
color: rgba(255, 255, 255, 1); |
||||
|
} |
||||
|
.custom-table th, |
||||
|
.custom-table td { |
||||
|
border: 1px solid rgba(163, 192, 243, 1); |
||||
|
text-align: left; |
||||
|
padding: 8px; |
||||
|
text-align: center; |
||||
|
} |
||||
|
.table1 { |
||||
|
width: 100%; |
||||
|
border: 1px solid rgba(255, 255, 255); |
||||
|
border-radius: 5px; |
||||
|
background: rgba(255, 255, 255, 0.1); |
||||
|
// 表格中的操作按钮 |
||||
|
.tabReboot, |
||||
|
.tabDelete { |
||||
|
border: none; |
||||
|
display: inline-block; |
||||
|
background-color: rgba(0, 0, 0, 0); |
||||
|
font-size: 14px; |
||||
|
font-weight: 400; |
||||
|
letter-spacing: 0; |
||||
|
line-height: 20px; |
||||
|
color: rgba(67, 136, 251, 1); |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.tabReboot { |
||||
|
margin-right: 8px; |
||||
|
} |
||||
|
.tabReboot::active { |
||||
|
color: white !important; |
||||
|
} |
||||
|
.tabDelete::active { |
||||
|
color: white; |
||||
|
} |
||||
|
} |
||||
|
::v-deep(.ant-transfer) { |
||||
|
// 屏蔽自带的hover效果 |
||||
|
.ant-transfer-list-content-item:hover { |
||||
|
background: black; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,282 @@ |
|||||
|
import { ref } from 'vue'; |
||||
|
// 流动线条样式与定位
|
||||
|
export const linePosition = [ |
||||
|
// 雨水池 - 控制阀
|
||||
|
{ |
||||
|
left: '4%', |
||||
|
top: '44%', |
||||
|
transform: 'rotateZ(-30deg)', |
||||
|
transformOrigin: 'left', |
||||
|
zIndex: '6', |
||||
|
width: '6%', |
||||
|
}, |
||||
|
{ |
||||
|
left: '4%', |
||||
|
top: '84%', |
||||
|
transform: 'rotateZ(-30deg)', |
||||
|
transformOrigin: 'left', |
||||
|
zIndex: '6', |
||||
|
width: '6%', |
||||
|
}, |
||||
|
// 控制阀 - 进水阀
|
||||
|
{ left: '12%', top: '34%', width: '10%' }, |
||||
|
{ left: '12%', top: '74%', width: '10%' }, |
||||
|
// 进水阀 - 集水池
|
||||
|
{ left: '23%', top: '34%', width: '8%' }, |
||||
|
{ left: '23%', top: '74%', width: '8%' }, |
||||
|
// 集水池 - 排水泵 - 横线
|
||||
|
{ left: '35%', top: '34%', width: '4%' }, |
||||
|
{ left: '35%', top: '74%', width: '4%' }, |
||||
|
// 上半集水池右侧分线
|
||||
|
{ left: '39%', top: '34%', transform: 'rotateZ(90deg)', transformOrigin: 'left', width: '4%' }, |
||||
|
{ left: '39%', top: '34%', transform: 'rotateZ(-90deg)', transformOrigin: 'left', width: '4%' }, |
||||
|
// 下半集水池右侧分线
|
||||
|
{ left: '39%', top: '74%', transform: 'rotateZ(90deg)', transformOrigin: 'left', width: '4%' }, |
||||
|
{ left: '39%', top: '74%', transform: 'rotateZ(-90deg)', transformOrigin: 'left', width: '4%' }, |
||||
|
// 上半-左侧水泵分线
|
||||
|
{ left: '39%', top: '25%', width: '8%' }, |
||||
|
{ left: '39%', top: '43%', width: '8%' }, |
||||
|
// 下半-左侧水泵分线
|
||||
|
{ left: '39%', top: '65%', width: '8%' }, |
||||
|
{ left: '39%', top: '83%', width: '8%' }, |
||||
|
// 水泵右侧合线 下半
|
||||
|
{ left: '47%', top: '83%', transform: 'rotateZ(-90deg)', transformOrigin: 'left', width: '14%' }, |
||||
|
// 水泵右侧合线 上半
|
||||
|
{ left: '47%', top: '25%', transform: 'rotateZ(90deg)', transformOrigin: 'left', width: '12%' }, |
||||
|
// 汇入总闸连线
|
||||
|
{ left: '47%', top: '52%', width: '4%' }, |
||||
|
// 汇入总集水池
|
||||
|
{ left: '51%', top: '52%', transform: 'rotateZ(-25deg)', transformOrigin: 'left', width: '7%' }, |
||||
|
// 汇入总排水闸
|
||||
|
{ left: '58%', top: '45%', width: '9%' }, |
||||
|
// 汇入市政管道 - 途径水泵2
|
||||
|
{ left: '68%', top: '45%', width: '28%' }, |
||||
|
// 总排水闸 - 总排水泵1 上半
|
||||
|
{ left: '75%', top: '45%', transform: 'rotateZ(-90deg)', transformOrigin: 'left', width: '10%' }, |
||||
|
{ left: '75%', top: '23%', width: '11%' }, |
||||
|
{ left: '86%', top: '22.5%', transform: 'rotateZ(90deg)', transformOrigin: 'left', width: '10%' }, |
||||
|
// 总排水闸 - 总排水泵3 下半
|
||||
|
{ left: '75%', top: '45%', transform: 'rotateZ(90deg)', transformOrigin: 'left', width: '9%' }, |
||||
|
{ left: '75%', top: '65%', width: '11%' }, |
||||
|
{ |
||||
|
left: '86%', |
||||
|
top: '65%', |
||||
|
transform: 'rotateZ(-90deg)', |
||||
|
transformOrigin: 'left', |
||||
|
width: '9%', |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
/** |
||||
|
* 1. 设备数量是固定的 |
||||
|
* 2. 设备顺序是固定的 |
||||
|
* 3. 此处数据用于渲染设备图标,后端返回数据后,将依次插入 |
||||
|
* @param icon 决定调用的设备图标:污水池=1/集水池=2/控制阀=3//进水阀=4//排水泵=5
|
||||
|
* @param type 设备类型:污水池=1/阀门=2/集水池=3/水泵=4 |
||||
|
* @param open 水泵的开关状态 开=true/关=false |
||||
|
* @param control 是否可以被操作(是否显示顶部按钮,水池为false) |
||||
|
* @param edited 是否已经被编辑(决定显示编辑 或 撤销) |
||||
|
*/ |
||||
|
// 污水池
|
||||
|
export const device1 = ref([ |
||||
|
{ |
||||
|
control: false, |
||||
|
type: 1, |
||||
|
icon: 1, |
||||
|
styleObject: { |
||||
|
left: '1%', |
||||
|
top: '40%', |
||||
|
zIndex: '9', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: false, |
||||
|
type: 1, |
||||
|
icon: 1, |
||||
|
styleObject: { |
||||
|
left: '1%', |
||||
|
top: '80%', |
||||
|
zIndex: '9', |
||||
|
}, |
||||
|
}, |
||||
|
]); |
||||
|
// 阀门
|
||||
|
export const device2 = ref([ |
||||
|
{ |
||||
|
control: true, |
||||
|
open: true, |
||||
|
type: 2, |
||||
|
icon: 3, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '8%', |
||||
|
top: '28%', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: true, |
||||
|
open: false, |
||||
|
type: 2, |
||||
|
icon: 3, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '8%', |
||||
|
top: '68%', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: true, |
||||
|
open: true, |
||||
|
type: 2, |
||||
|
icon: 4, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '20%', |
||||
|
top: '28%', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: true, |
||||
|
open: true, |
||||
|
type: 2, |
||||
|
icon: 4, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '20%', |
||||
|
top: '68%', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: true, |
||||
|
open: true, |
||||
|
type: 2, |
||||
|
icon: 3, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '48%', |
||||
|
top: '46%', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: true, |
||||
|
open: true, |
||||
|
type: 2, |
||||
|
icon: 3, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '65%', |
||||
|
top: '38%', |
||||
|
}, |
||||
|
}, |
||||
|
]); |
||||
|
// 集水池
|
||||
|
export const device3 = ref([ |
||||
|
{ |
||||
|
control: false, |
||||
|
type: 3, |
||||
|
icon: 2, |
||||
|
styleObject: { |
||||
|
left: '30%', |
||||
|
top: '68%', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: false, |
||||
|
type: 3, |
||||
|
icon: 2, |
||||
|
styleObject: { |
||||
|
left: '30%', |
||||
|
top: '28%', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: false, |
||||
|
type: 3, |
||||
|
icon: 2, |
||||
|
styleObject: { |
||||
|
left: '56%', |
||||
|
top: '40%', |
||||
|
}, |
||||
|
}, |
||||
|
]); |
||||
|
// 水泵
|
||||
|
export const device4 = ref([ |
||||
|
{ |
||||
|
control: true, |
||||
|
open: false, |
||||
|
type: 4, |
||||
|
icon: 5, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '40%', |
||||
|
top: '20%', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: true, |
||||
|
open: true, |
||||
|
type: 4, |
||||
|
icon: 5, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '40%', |
||||
|
top: '40%', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: true, |
||||
|
open: true, |
||||
|
type: 4, |
||||
|
icon: 5, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '40%', |
||||
|
top: '60%', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: true, |
||||
|
open: true, |
||||
|
type: 4, |
||||
|
icon: 5, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '40%', |
||||
|
top: '80%', |
||||
|
}, |
||||
|
}, |
||||
|
// 右上3水泵
|
||||
|
{ |
||||
|
control: true, |
||||
|
open: true, |
||||
|
type: 4, |
||||
|
icon: 5, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '78%', |
||||
|
top: '20%', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: true, |
||||
|
open: true, |
||||
|
type: 4, |
||||
|
icon: 5, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '78%', |
||||
|
top: '40%', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
control: true, |
||||
|
open: true, |
||||
|
type: 4, |
||||
|
icon: 5, |
||||
|
edited: false, |
||||
|
styleObject: { |
||||
|
left: '78%', |
||||
|
top: '60%', |
||||
|
}, |
||||
|
}, |
||||
|
]); |
@ -0,0 +1,150 @@ |
|||||
|
<template> |
||||
|
<div class="left-top"> |
||||
|
<div class="info"> |
||||
|
<div class="title-item"> |
||||
|
<div class="title-back">设备状态</div> |
||||
|
</div> |
||||
|
<div class="info-item"> |
||||
|
<div v-for="(item, index) in deviceState" :key="index"> |
||||
|
<img v-if="item.type == props.state" :src="item.icon" alt="" /> |
||||
|
<img v-else :src="item.default" alt="" /> |
||||
|
<div class="mode-item-text">{{ item.name }}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="mode"> |
||||
|
<div class="title-item"> |
||||
|
<div class="title-back">控制模式</div> |
||||
|
<div class="title-button">计划启用</div> |
||||
|
</div> |
||||
|
<div class="mode-item"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref, onMounted } from 'vue'; |
||||
|
// 全局变量 |
||||
|
import { items } from '/@/store/item'; |
||||
|
// 图像资源引入 |
||||
|
import type1 from './images/type1.png'; |
||||
|
import type2 from './images/type2.png'; |
||||
|
import type3 from './images/type3.png'; |
||||
|
import type1off from './images/type1off.png'; |
||||
|
import type2off from './images/type2off.png'; |
||||
|
import type3off from './images/type3off.png'; |
||||
|
// 传入的值 |
||||
|
const props = defineProps({ |
||||
|
// 设备状态 |
||||
|
state: { |
||||
|
type: Number, |
||||
|
}, |
||||
|
}); |
||||
|
const deviceState = [ |
||||
|
{ |
||||
|
icon: type1, |
||||
|
default: type1off, |
||||
|
name: '运行', |
||||
|
type: 1, |
||||
|
}, |
||||
|
{ |
||||
|
icon: type2, |
||||
|
default: type2off, |
||||
|
name: '故障', |
||||
|
type: 2, |
||||
|
}, |
||||
|
{ |
||||
|
icon: type3, |
||||
|
default: type3off, |
||||
|
name: '强排', |
||||
|
type: 3, |
||||
|
}, |
||||
|
]; |
||||
|
//页面 创建 |
||||
|
onMounted(() => {}); |
||||
|
</script> |
||||
|
<style lang="less" scoped> |
||||
|
.left-top { |
||||
|
--pad: 12px; |
||||
|
position: absolute; |
||||
|
left: var(--pad); |
||||
|
top: var(--pad); |
||||
|
width: auto; |
||||
|
height: 110px; |
||||
|
display: flex; |
||||
|
z-index: 99; |
||||
|
gap: var(--pad); |
||||
|
> div { |
||||
|
background: black; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 3px; |
||||
|
box-sizing: border-box; |
||||
|
padding: 10px; |
||||
|
border-radius: 4px; |
||||
|
.title-item { |
||||
|
padding: 5px; |
||||
|
position: relative; |
||||
|
.title-back { |
||||
|
margin-left: 10px; |
||||
|
padding-left: 5px; |
||||
|
background: linear-gradient(to right, #1aaefb, transparent); |
||||
|
width: 7em; |
||||
|
color: white; |
||||
|
position: relative; |
||||
|
font-size: 14px; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
.title-back::before { |
||||
|
position: absolute; |
||||
|
content: ''; |
||||
|
display: block; |
||||
|
width: 5px; |
||||
|
height: 100%; |
||||
|
left: -12px; |
||||
|
background: #1aaefb; |
||||
|
} |
||||
|
.title-button { |
||||
|
position: absolute; |
||||
|
right: 2px; |
||||
|
top: 2px; |
||||
|
padding: 3px 8px; |
||||
|
color: white; |
||||
|
border-radius: 4px; |
||||
|
user-select: none; |
||||
|
cursor: pointer; |
||||
|
background: linear-gradient(180deg, rgba(103, 222, 0, 1) 0%, rgba(0, 181, 6, 1) 100%); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
// 设备状态 |
||||
|
.info { |
||||
|
width: 230px; |
||||
|
.info-item { |
||||
|
display: flex; |
||||
|
padding-top: 3px; |
||||
|
div { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 5px; |
||||
|
align-items: center; |
||||
|
.mode-item-text { |
||||
|
color: white; |
||||
|
user-select: none; |
||||
|
} |
||||
|
img { |
||||
|
width: 23px; |
||||
|
display: block; |
||||
|
user-select: none; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
// 控制模式 |
||||
|
.mode { |
||||
|
width: 200px; |
||||
|
.mode-item { |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,291 @@ |
|||||
|
<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> |
@ -0,0 +1,30 @@ |
|||||
|
<template> |
||||
|
<div class="line-item" :style="position"></div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { computed } from 'vue'; |
||||
|
|
||||
|
// 传入的值 |
||||
|
const props = defineProps({ |
||||
|
// 线条 |
||||
|
position: { |
||||
|
type: Object, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
}); |
||||
|
const position = computed(() => { |
||||
|
return props.position; |
||||
|
}); |
||||
|
</script> |
||||
|
<style lang="less" scoped> |
||||
|
.line-item { |
||||
|
position: absolute; |
||||
|
height: 10px; |
||||
|
width: 250px; |
||||
|
z-index: 1; |
||||
|
background-image: url(./images/back.gif); |
||||
|
background-color: rgba(13, 255, 164, 0.3); |
||||
|
background-size: 200px 10px; |
||||
|
border-radius: 5px; |
||||
|
} |
||||
|
</style> |
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1,663 @@ |
|||||
|
<template> |
||||
|
<div class="main"> |
||||
|
<!-- 左上角设备信息面板 --> |
||||
|
<deviceInfo :state="deviceState" /> |
||||
|
<!-- 示意图 --> |
||||
|
<div class="map"> |
||||
|
<!-- 污水池图标 --> |
||||
|
<deviceItem v-for="(item, index) in device1" :key="index" :info="item" /> |
||||
|
<!-- 阀门图标 --> |
||||
|
<deviceItem v-for="(item, index) in device2" :key="index" :info="item" /> |
||||
|
<!-- 集水池图标 --> |
||||
|
<deviceItem v-for="(item, index) in device3" :key="index" :info="item" /> |
||||
|
<!-- 排水泵图标 --> |
||||
|
<deviceItem v-for="(item, index) in device4" :key="index" :info="item" /> |
||||
|
<!-- 市政管道图标 --> |
||||
|
<div class="pipe"> |
||||
|
<div>市政管道</div> |
||||
|
<img src="./images/pipe.png" alt="" /> |
||||
|
</div> |
||||
|
<!-- 设备图标底部连线 --> |
||||
|
<deviceLine v-for="(item, index) in linePosition" :key="index" :position="item" /> |
||||
|
</div> |
||||
|
<!-- 右下角按钮 --> |
||||
|
<div class="buttons"> |
||||
|
<a-button type="primary" @click="openDrawer1">执行</a-button> |
||||
|
<a-button type="primary" @click="resetAll">全部撤销</a-button> |
||||
|
</div> |
||||
|
<!-- 页面右侧抽屉开关 --> |
||||
|
<div class="right-button"> |
||||
|
<div>计划与日志</div> |
||||
|
<img @click="visible = true" src="./images/open.png" alt="" /> |
||||
|
</div> |
||||
|
<!-- 右侧 计划日志抽屉 --> |
||||
|
<a-drawer |
||||
|
v-model:visible="visible" |
||||
|
class="drawer-item" |
||||
|
width="496" |
||||
|
placement="right" |
||||
|
:body-style="{ background: 'rgba(0, 0, 0)', opacity: 0.8 }" |
||||
|
:closable="false" |
||||
|
id="drawer" |
||||
|
:maskStyle="{ 'background-color': 'rgba(0, 0, 0, 0)' }"> |
||||
|
<a-tabs v-model:activeKey="activeKey"> |
||||
|
<a-tab-pane key="1" tab="计划列表" force-render> |
||||
|
<planTab ref="tabs1Ref" @reset-all="resetDrawer" /> |
||||
|
</a-tab-pane> |
||||
|
<a-tab-pane key="2" tab="日志"> |
||||
|
<logTab ref="tabs2Ref" @reset-all="resetDrawer" /> |
||||
|
</a-tab-pane> |
||||
|
</a-tabs> |
||||
|
</a-drawer> |
||||
|
<!-- 右侧 操作队列 --> |
||||
|
<a-drawer |
||||
|
v-model:visible="visible1" |
||||
|
class="drawer-item" |
||||
|
width="496" |
||||
|
placement="right" |
||||
|
:body-style="{ background: 'rgba(0, 0, 0)', opacity: 0.8 }" |
||||
|
:closable="false" |
||||
|
id="drawer" |
||||
|
:maskStyle="{ 'background-color': 'rgba(0, 0, 0, 0)' }"> |
||||
|
<a-tabs v-model:activeKey="activeKey1"> |
||||
|
<a-tab-pane key="1" tab="操作队列" force-render> |
||||
|
<div> |
||||
|
<a-badge :offset="[-5, 12]" :count="valveList.length"> |
||||
|
<button :class="{ btn: true, selected: activeButton == 1 }" @click="changeBtn(1)" |
||||
|
>阀门</button |
||||
|
> |
||||
|
</a-badge> |
||||
|
<a-badge :offset="[-5, 12]" :count="pumpList.length"> |
||||
|
<button :class="{ btn: true, selected: activeButton == 2 }" @click="changeBtn(2)" |
||||
|
>水泵</button |
||||
|
> |
||||
|
</a-badge> |
||||
|
</div> |
||||
|
<div class="device-list" v-if="activeButton == 1"> |
||||
|
<div class="device-list-item" v-for="(item, index) in valveList" :key="index"> |
||||
|
<div class="list-item-title"> |
||||
|
<div class="item-title"> |
||||
|
<img src="./images/device1.png" alt="" /> |
||||
|
<span>{{ item.name }}</span> |
||||
|
</div> |
||||
|
<div class="revoke" @click="revoke(item.id, index, 1)">撤销</div> |
||||
|
</div> |
||||
|
<div class="list-item-main"> |
||||
|
<div> |
||||
|
<div class="info">开度</div> |
||||
|
<div class="text"> |
||||
|
<span>{{ item.oldVal + item.unit }}</span> |
||||
|
<img src="/asset/image/bulbLogo/22406.png" alt="" /> |
||||
|
<span>{{ item.value + item.unit }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<a-empty style="margin-top: 100px" v-if="valveList.length == 0"> |
||||
|
<template #description> <span style="color: white">暂无数据</span></template> |
||||
|
</a-empty> |
||||
|
</div> |
||||
|
<div class="device-list" v-if="activeButton == 2"> |
||||
|
<div class="device-list-item" v-for="(item, index) in pumpList" :key="index"> |
||||
|
<div class="list-item-title"> |
||||
|
<div class="item-title"> |
||||
|
<img src="./images/device2.png" alt="" /> |
||||
|
<span>{{ item.name }}</span> |
||||
|
</div> |
||||
|
<div class="revoke" @click="revoke(item.id, index, 2)">撤销</div> |
||||
|
</div> |
||||
|
<div class="list-item-main"> |
||||
|
<div> |
||||
|
<div class="info">频率</div> |
||||
|
<div class="text"> |
||||
|
<span>{{ item.oldVal + item.unit }}</span> |
||||
|
<img src="/asset/image/bulbLogo/22406.png" alt="" /> |
||||
|
<span>{{ item.value + item.unit }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div> |
||||
|
<div class="info">开关</div> |
||||
|
<div class="text"> |
||||
|
<span>{{ item.opened ? '开' : '关' }}</span> |
||||
|
<img src="/asset/image/bulbLogo/22406.png" alt="" /> |
||||
|
<span>{{ item.open == 1 ? '开' : '关' }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<a-empty style="margin-top: 100px" v-if="pumpList.length == 0"> |
||||
|
<template #description> <span style="color: white">暂无数据</span></template> |
||||
|
</a-empty> |
||||
|
</div> |
||||
|
<div style="width: 100%; height: 100px"></div> |
||||
|
<div class="button-box"> |
||||
|
<button class="cancel" @click="visible1 = false">取消</button> |
||||
|
<a-popconfirm |
||||
|
title="此操作将提交以上修改内容" |
||||
|
ok-text="确定" |
||||
|
cancel-text="取消" |
||||
|
placement="bottomRight" |
||||
|
@confirm="submitChange"> |
||||
|
<button class="execute">执行</button> |
||||
|
</a-popconfirm> |
||||
|
</div> |
||||
|
</a-tab-pane> |
||||
|
</a-tabs> |
||||
|
</a-drawer> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref, onMounted } from 'vue'; |
||||
|
import { Modal, message } from 'ant-design-vue'; |
||||
|
|
||||
|
import deviceInfo from './deviceInfo.vue'; |
||||
|
import deviceLine from './deviceLine.vue'; |
||||
|
import deviceItem from './deviceItem.vue'; |
||||
|
import planTab from './component/planTab.vue'; |
||||
|
import logTab from './component/logTab.vue'; |
||||
|
import { linePosition, device1, device2, device3, device4 } from './device'; |
||||
|
// 网络请求 |
||||
|
import { http } from '/nerv-lib/util/http'; |
||||
|
import { waterSys } from '/@/api/waterSystem'; |
||||
|
// 全局变量 |
||||
|
import { items } from '/@/store/item'; |
||||
|
|
||||
|
// 初始化 =========================================================================================== |
||||
|
|
||||
|
const state = items(); |
||||
|
onMounted(() => { |
||||
|
// 获得所有设备状态 |
||||
|
getAllDevice(); |
||||
|
}); |
||||
|
const deviceState = 1; |
||||
|
|
||||
|
// 计划与日志 抽屉业务 ========================================================================================= |
||||
|
|
||||
|
// 计划与日志 |
||||
|
const visible = ref(false); |
||||
|
// 当前选中的tab |
||||
|
const activeKey = ref('1'); |
||||
|
|
||||
|
// 执行 抽屉业务 ========================================================================================= |
||||
|
|
||||
|
// 执行 |
||||
|
const visible1 = ref(false); |
||||
|
// 当前选中的tab |
||||
|
const activeKey1 = '1'; |
||||
|
// 当前选中的设备类型 阀门=1/水泵=2 |
||||
|
const activeButton = ref(1); |
||||
|
// 切换设备类型 |
||||
|
const changeBtn = (key: number) => { |
||||
|
activeButton.value = key; |
||||
|
}; |
||||
|
// 当前修改的水泵数据 |
||||
|
const pumpList = ref<any>([]); |
||||
|
// 当前修改的水阀数据 |
||||
|
const valveList = ref<any>([]); |
||||
|
|
||||
|
// 打开右侧抽屉 |
||||
|
const openDrawer1 = () => { |
||||
|
valveList.value = device2.value.filter((item: any) => { |
||||
|
return item.edited; |
||||
|
}); |
||||
|
pumpList.value = device4.value.filter((item: any) => { |
||||
|
return item.edited; |
||||
|
}); |
||||
|
if (valveList.value.length || pumpList.value.length) { |
||||
|
visible1.value = true; |
||||
|
} else { |
||||
|
message.info('未产生任何修改'); |
||||
|
} |
||||
|
}; |
||||
|
// 右侧抽屉 - 撤回 |
||||
|
const revoke = (id: any, index: number, type: number) => { |
||||
|
if (type == 1) { |
||||
|
valveList.value.splice(index, 1); |
||||
|
device2.value.forEach((item: any) => { |
||||
|
if (item.id == id) { |
||||
|
item.value = item.oldVal; |
||||
|
item.edited = false; |
||||
|
} |
||||
|
}); |
||||
|
} else if (type == 2) { |
||||
|
pumpList.value.splice(index, 1); |
||||
|
device4.value.forEach((item: any) => { |
||||
|
if (item.id == id) { |
||||
|
item.value = item.oldVal; |
||||
|
item.open = item.opened; |
||||
|
item.edited = false; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}; |
||||
|
const submitChange = () => { |
||||
|
let valveList = []; |
||||
|
device2.value.forEach((item: any) => { |
||||
|
if (item.edited) { |
||||
|
valveList.push({ |
||||
|
deviceGroup: item.id, |
||||
|
openPercent: item.value, |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
let pumpList = []; |
||||
|
device4.value.forEach((item: any) => { |
||||
|
if (item.edited) { |
||||
|
pumpList.push({ |
||||
|
deviceGroup: item.id, |
||||
|
frequency: item.value, |
||||
|
switchStatus: +item.open, |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
state.setLoading(true); |
||||
|
http |
||||
|
.post(waterSys.submitList, { |
||||
|
projectId: state.projectId, |
||||
|
siteId: state.siteId, |
||||
|
valveList, |
||||
|
pumpList, |
||||
|
}) |
||||
|
.then((res) => { |
||||
|
let data = res.data; |
||||
|
state.setLoading(false); |
||||
|
// 修改请求发送了,但操作时产生了失败结果 |
||||
|
if (res.retcode != 0) { |
||||
|
// 直接提示并跳出 |
||||
|
return message.warning(res.msg); |
||||
|
} |
||||
|
// 所有修改均生效 |
||||
|
if (data.allSucceed) { |
||||
|
message.success('修改完成'); |
||||
|
// allSucceed不为true,则至少有一条数据修改失败 |
||||
|
} else { |
||||
|
message.info(`${data.successList.length}条修改成功,${data.failList.length}条修改失败`); |
||||
|
} |
||||
|
// 将所有已修改状态的数据还原 |
||||
|
resetEdit(); |
||||
|
visible1.value = false; |
||||
|
getAllDevice(); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const resetEdit = () => { |
||||
|
device2.value.forEach((item) => { |
||||
|
item.edited = false; |
||||
|
}); |
||||
|
device4.value.forEach((item) => { |
||||
|
item.edited = false; |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
// 设备数据业务 ========================================================================================== |
||||
|
|
||||
|
// 当其中一个tab产生了数据修改,可以调用该方法重置所有tab |
||||
|
const resetDrawer = () => { |
||||
|
try { |
||||
|
// tab1重置 |
||||
|
tabs1Ref.value.reset(); |
||||
|
} catch {} |
||||
|
try { |
||||
|
// tab2重置 |
||||
|
tabs2Ref.value.reset(); |
||||
|
} catch {} |
||||
|
}; |
||||
|
// 抽屉tab1组件的引用 |
||||
|
const tabs1Ref = ref(); |
||||
|
// 抽屉tab2组件的引用 |
||||
|
const tabs2Ref = ref(); |
||||
|
// 撤销所有修改 |
||||
|
const resetAll = () => { |
||||
|
Modal.confirm({ |
||||
|
title: '提示信息', |
||||
|
content: '该操作将还原已编辑内容', |
||||
|
onOk() { |
||||
|
// 水阀 |
||||
|
device2.value.forEach((item: any) => { |
||||
|
if (item.edited) { |
||||
|
item.value = item.oldVal; |
||||
|
item.edited = false; |
||||
|
} |
||||
|
}); |
||||
|
// 水泵 水泵包含 |
||||
|
device4.value.forEach((item: any) => { |
||||
|
if (item.edited) { |
||||
|
item.value = item.oldVal; |
||||
|
item.open = item.opened; |
||||
|
item.edited = false; |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
onCancel() {}, |
||||
|
}); |
||||
|
}; |
||||
|
// 获得所有设备状态 |
||||
|
const getAllDevice = () => { |
||||
|
getDevice(1); |
||||
|
getDevice(2); |
||||
|
getDevice(3); |
||||
|
getDevice(4); |
||||
|
}; |
||||
|
/** |
||||
|
* 获取一个设备类型的数据 |
||||
|
* @param type 污水池=1/阀门=2/集水池=3/水泵=4 |
||||
|
*/ |
||||
|
const getDevice = (type: number) => { |
||||
|
// 请求地址 |
||||
|
let url = ''; |
||||
|
if (type == 1) { |
||||
|
url = waterSys.getPool1; |
||||
|
} else if (type == 2) { |
||||
|
url = waterSys.getValve; |
||||
|
} else if (type == 3) { |
||||
|
url = waterSys.getPool2; |
||||
|
} else if (type == 4) { |
||||
|
url = waterSys.getPump; |
||||
|
} |
||||
|
http |
||||
|
.get(url, { |
||||
|
projectId: state.projectId, |
||||
|
siteId: state.siteId, |
||||
|
}) |
||||
|
.then((res) => { |
||||
|
let data = res.data; |
||||
|
// 污水池数据 |
||||
|
if (type == 1) { |
||||
|
device1.value.forEach((item: any, index: number) => { |
||||
|
let result = data[index]; |
||||
|
// 污水池名称 |
||||
|
item.name = result.deviceInfoName; |
||||
|
// 污水池容量 |
||||
|
item.value = result.record.capacity ? result.record.capacity : '--'; |
||||
|
// 单位 |
||||
|
item.unit = result.record.capacityUnit ? result.record.capacityUnit : ''; |
||||
|
}); |
||||
|
} |
||||
|
// 阀门数据 |
||||
|
if (type == 2) { |
||||
|
device2.value.forEach((item: any, index: number) => { |
||||
|
let result = data[index]; |
||||
|
// 阀门名称 |
||||
|
item.name = result.deviceGroupName; |
||||
|
// 阀门ID |
||||
|
item.id = result.deviceGroup; |
||||
|
// 编辑状态重置 |
||||
|
item.edited = false; |
||||
|
// 设备状态(是否正常) |
||||
|
item.state = result.record.runStatus.value != null ? result.record.runStatus.value : -1; |
||||
|
// 开度-新值 |
||||
|
item.value = result.record.openPercent ? result.record.openPercent : 0; |
||||
|
// 开度-旧值(用于判断旧值是否被修改) |
||||
|
item.oldVal = result.record.openPercent ? result.record.openPercent : null; |
||||
|
// 单位 |
||||
|
item.unit = result.record.openPercentUnit ? result.record.openPercentUnit : ''; |
||||
|
}); |
||||
|
} |
||||
|
// 集水池数据 |
||||
|
if (type == 3) { |
||||
|
device3.value.forEach((item: any, index: number) => { |
||||
|
let result = data[index]; |
||||
|
// 集水池名称 |
||||
|
item.name = result.deviceInfoName; |
||||
|
// 集水池容量 |
||||
|
item.value = result.record.capacity ? result.record.capacity : '--'; |
||||
|
// 单位 |
||||
|
item.unit = result.record.capacityUnit ? result.record.capacityUnit : ''; |
||||
|
}); |
||||
|
} |
||||
|
// 水泵数据 |
||||
|
if (type == 4) { |
||||
|
device4.value.forEach((item: any, index: number) => { |
||||
|
let result = data[index]; |
||||
|
// 水泵名称 |
||||
|
item.name = result.deviceGroupName; |
||||
|
// 水泵ID |
||||
|
item.id = result.deviceGroup; |
||||
|
// 编辑状态重置 |
||||
|
item.edited = false; |
||||
|
// 水泵的开启状态-新值 |
||||
|
item.open = result.record.switchStatus.value == 1 ? true : false; |
||||
|
// 水泵的开启状态-旧值(用于判断是否被修改) |
||||
|
item.opened = result.record.switchStatus.value == 1 ? true : false; |
||||
|
// 设备状态(是否正常) |
||||
|
item.state = result.record.runStatus.value != null ? result.record.runStatus.value : -1; |
||||
|
// 频率-新值 |
||||
|
item.value = result.record.frequency ? result.record.frequency : 0; |
||||
|
// 频率-旧值(用于判断是否被修改) |
||||
|
item.oldVal = result.record.frequency ? result.record.frequency : null; |
||||
|
// 单位 |
||||
|
item.unit = result.record.frequencyUnit ? result.record.frequencyUnit : ''; |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="less" scoped> |
||||
|
.main { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
position: relative; |
||||
|
background: linear-gradient(to bottom, rgb(35, 102, 165), rgb(1, 19, 81)); |
||||
|
// 图例区域 |
||||
|
.map { |
||||
|
width: 85vw; |
||||
|
height: 38vw; |
||||
|
position: relative; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
top: 0; |
||||
|
bottom: 0; |
||||
|
margin: auto; |
||||
|
// 右侧 市政管道 |
||||
|
.pipe { |
||||
|
width: 120px; |
||||
|
height: 120px; |
||||
|
position: absolute; |
||||
|
text-align: center; |
||||
|
left: 92%; |
||||
|
top: 40%; |
||||
|
z-index: 3; |
||||
|
transform: translateY(-60px); |
||||
|
img { |
||||
|
height: 100%; |
||||
|
} |
||||
|
div { |
||||
|
width: inherit; |
||||
|
color: white; |
||||
|
position: absolute; |
||||
|
top: -1.5em; |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
// 右下角按钮 |
||||
|
.buttons { |
||||
|
position: absolute; |
||||
|
right: 15px; |
||||
|
bottom: 15px; |
||||
|
display: flex; |
||||
|
gap: 15px; |
||||
|
height: 40px; |
||||
|
> button { |
||||
|
height: 40px; |
||||
|
} |
||||
|
} |
||||
|
.right-button { |
||||
|
height: 25px; |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
bottom: 0; |
||||
|
right: 10px; |
||||
|
margin: auto; |
||||
|
display: flex; |
||||
|
z-index: 99; |
||||
|
gap: 10px; |
||||
|
color: #0dffff; |
||||
|
> img { |
||||
|
width: 25px; |
||||
|
height: 25px; |
||||
|
border-radius: 2px; |
||||
|
vertical-align: middle; |
||||
|
cursor: pointer; |
||||
|
user-select: none; |
||||
|
} |
||||
|
} |
||||
|
.drawer-item { |
||||
|
width: 100px; |
||||
|
height: 100px; |
||||
|
border: 2px solid red; |
||||
|
} |
||||
|
} |
||||
|
// 抽屉顶部tab按钮样式 |
||||
|
:deep(.ant-tabs-tab-btn) { |
||||
|
color: white; |
||||
|
} |
||||
|
.btn { |
||||
|
width: 92px; |
||||
|
height: 40px; |
||||
|
border-radius: 4px; |
||||
|
opacity: 1; |
||||
|
margin-top: 10px; |
||||
|
margin-left: 15px; |
||||
|
font-size: 14px; |
||||
|
font-weight: 400; |
||||
|
opacity: 1; |
||||
|
border: 1px solid rgba(207, 212, 219, 1); |
||||
|
line-height: 20.27px; |
||||
|
color: white; |
||||
|
text-align: center; |
||||
|
vertical-align: top; |
||||
|
background-color: rgba(255, 255, 255, 0.1); |
||||
|
} |
||||
|
|
||||
|
.selected { |
||||
|
background: linear-gradient(180deg, rgba(201, 245, 255, 1) 0%, rgba(138, 215, 255, 1) 100%); |
||||
|
color: rgba(0, 61, 90, 1); |
||||
|
border: 1px solid white; |
||||
|
} |
||||
|
|
||||
|
.btn:hover { |
||||
|
background-color: rgba(207, 212, 219, 1); |
||||
|
} |
||||
|
|
||||
|
.btn:active { |
||||
|
background-color: rgba(102, 102, 102, 1); |
||||
|
color: white; |
||||
|
} |
||||
|
.device-list { |
||||
|
margin-left: 15px; |
||||
|
margin-top: 15px; |
||||
|
width: 100%; |
||||
|
height: auto; |
||||
|
display: flex; |
||||
|
gap: 15px; |
||||
|
flex-direction: column; |
||||
|
.device-list-item { |
||||
|
width: calc(100% - 15px); |
||||
|
box-sizing: border-box; |
||||
|
padding: 10px; |
||||
|
border: 2px solid #03407e; |
||||
|
border-radius: 4px; |
||||
|
background: rgba(0, 177, 255, 0.2); |
||||
|
display: flex; |
||||
|
gap: 10px; |
||||
|
flex-direction: column; |
||||
|
.list-item-title { |
||||
|
color: white; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
.item-title { |
||||
|
img { |
||||
|
width: 25px; |
||||
|
} |
||||
|
span { |
||||
|
margin-left: 10px; |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
} |
||||
|
.revoke { |
||||
|
text-align: center; |
||||
|
border: none; |
||||
|
border-radius: 4px; |
||||
|
padding: 5px 15px; |
||||
|
background: linear-gradient( |
||||
|
180deg, |
||||
|
rgba(255, 187, 0, 1) 0%, |
||||
|
rgba(255, 112, 3, 1) 91.21%, |
||||
|
rgba(255, 129, 3, 1) 100% |
||||
|
); |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
} |
||||
|
.list-item-main { |
||||
|
display: flex; |
||||
|
font-size: 13px; |
||||
|
> div { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
gap: 8px; |
||||
|
> .info { |
||||
|
text-align: center; |
||||
|
width: 6em; |
||||
|
height: 2.5em; |
||||
|
line-height: 2.5em; |
||||
|
border-radius: 4px; |
||||
|
color: white; |
||||
|
background: linear-gradient( |
||||
|
180deg, |
||||
|
rgba(86, 221, 253, 1) 0%, |
||||
|
rgba(25, 176, 255, 1) 100% |
||||
|
); |
||||
|
} |
||||
|
> .text { |
||||
|
:first-child { |
||||
|
color: white; |
||||
|
line-height: 2.5em; |
||||
|
} |
||||
|
img { |
||||
|
padding: 0 5px; |
||||
|
} |
||||
|
:last-child { |
||||
|
line-height: 2.5em; |
||||
|
color: red; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.button-box { |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
padding: 10px; |
||||
|
height: 60px; |
||||
|
position: absolute; |
||||
|
background-color: transparent; |
||||
|
text-align: right; |
||||
|
bottom: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
.execute, |
||||
|
.cancel { |
||||
|
margin-right: 10px; |
||||
|
width: 74px; |
||||
|
height: 40px; |
||||
|
opacity: 1; |
||||
|
cursor: pointer; |
||||
|
border-radius: 4px; |
||||
|
font-size: 14px; |
||||
|
font-weight: 400; |
||||
|
border: 0; |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
.execute { |
||||
|
background: rgb(67, 136, 251); |
||||
|
color: white; |
||||
|
} |
||||
|
.cancel { |
||||
|
background: white; |
||||
|
color: black; |
||||
|
} |
||||
|
} |
||||
|
</style> |
Loading…
Reference in new issue