add:新增给排水页面/接口及功能

This commit is contained in:
chenpingsen
2024-08-29 16:05:58 +08:00
parent ffd7be94f6
commit 3cf535351e
9 changed files with 2258 additions and 19 deletions

View File

@@ -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>

View File

@@ -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>