Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
v-model:pageSize="pagination.pageSize"
|
||||
show-size-changer
|
||||
:total="pagination.total"
|
||||
show-less-items
|
||||
@change="getTable(true)" />
|
||||
<div style="width: 100%; height: 40px"></div>
|
||||
|
||||
|
@@ -30,6 +30,7 @@
|
||||
v-model:pageSize="pagination.pageSize"
|
||||
show-size-changer
|
||||
:total="pagination.total"
|
||||
show-less-items
|
||||
@change="getTable(true)" />
|
||||
<div style="width: 100%; height: 40px"></div>
|
||||
|
||||
|
@@ -85,9 +85,9 @@
|
||||
:class="{ btn: true, selected: button.selected }"
|
||||
class="zmhlbtn"
|
||||
@click="changeLine(button)">
|
||||
<div v-if="button.lockStatus" class="btn-back">
|
||||
<!-- <div v-if="button.lockStatus" class="btn-back">
|
||||
<stop-outlined />
|
||||
</div>
|
||||
</div> -->
|
||||
{{ button.name }}
|
||||
</button>
|
||||
<div style="margin-top: 10px">
|
||||
|
@@ -30,6 +30,7 @@
|
||||
v-model:pageSize="pagination.pageSize"
|
||||
show-size-changer
|
||||
:total="pagination.total"
|
||||
show-less-items
|
||||
@change="getTable(true)" />
|
||||
<div style="width: 100%; height: 40px"></div>
|
||||
|
||||
|
@@ -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>
|
Binary file not shown.
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>
|
Reference in New Issue
Block a user