Files
SaaS-lib/hx-ai-intelligent/src/view/equipmentControl/airConditionControlSystem/tabs1.vue

755 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<a-spin :spinning="isLoading">
<!-- 照明区域 -->
<div>
<div class="light-area">
<div class="light-area-tab"></div>
<span class="light-area-text">空调区域</span>
</div>
<!-- 照明区域按钮部分 -->
<div class="area">
<template v-if="!showAllButtonsArea">
<button
v-for="(button, index) in limitedButtons1"
:key="index"
:class="{ btn: true, selected: button.selected }"
@click="changeArea(button)">
{{ button.name }}
</button>
<div style="margin-top: 10px">
<span @click="showAllButtonsArea = true" class="openzm"><down-outlined /> 展开</span>
</div>
</template>
<template v-else>
<button
v-for="(button, index) in props.treeData"
:key="index"
:class="{ btn: true, selected: button.selected }"
@click="changeArea(button)">
{{ button.name }}
</button>
<div style="margin-top: 10px">
<span @click="showAllButtonsArea = false" class="openzm"><up-outlined /> 回缩</span>
</div>
</template>
</div>
</div>
<!-- 照明回路部分 -->
<div>
<div class="circuit-area">
<div class="circuit-tab"></div>
<span class="circuit-text">空调分组</span>
<div class="btn2">
<button
class="openPlan"
:class="{ enabled2: isPlanEnabled2, disabled2: !isPlanEnabled2 }"
@click="togglePlan2">
{{ isPlanEnabled2 ? '启用开关' : '禁用开关' }}
</button>
<a-switch
v-model:checked="selectAllCheckbox"
:disabled="singleSelection"
:class="{
'blue-background': selectAllCheckbox,
'grey-background': !selectAllCheckbox,
}"
@change="toggleAllSelection" />
<button class="allBtn">全选</button>
<button class="both" @click="selectAll">
{{ singleSelection ? '多选' : '单选' }}
</button>
</div>
</div>
<div class="btnArea">
<template v-if="!showAllButtons">
<button
v-for="(button, index) in limitedButtons2"
:key="index"
:class="{ btn: true, selected: button.selected }"
class="zmhlbtn"
@click="changeLine(button)">
<stop-outlined v-if="button.ctrlStatus" />
{{ button.name }}
</button>
<div style="margin-top: 10px">
<span @click="showAllButtons = true" class="openzm"><down-outlined /> 展开</span>
</div>
</template>
<template v-else>
<button
v-for="(button, index) in buttons2"
:key="index"
:class="{ btn: true, selected: button.selected }"
class="zmhlbtn"
@click="changeLine(button)">
<stop-outlined v-if="button.ctrlStatus" />
{{ button.name }}
</button>
<div style="margin-top: 10px">
<span @click="showAllButtons = false" class="openzm"><up-outlined /> 回缩</span>
</div>
</template>
</div>
</div>
<!-- 控制模式部分 -->
<div v-show="thisButton2.dataCode">
<div class="control-area">
<div class="control-tab"></div>
<span class="control-text">控制模式</span>
</div>
<!-- 控制模式按钮部分 -->
<div class="control-mode-btn-area">
<button
v-for="(button3, index) in thisButton2.childList"
:key="index"
class="btn"
:class="{ selected: button3.selectAble }"
@click="selectButton3(button3)">
{{ button3.name }}
</button>
</div>
</div>
<!-- 控制场景部分 -->
<div v-show="thisButton2.dataCode">
<div class="control-scene-area">
<div class="control-scene-tab"></div>
<span class="control-scene-text">启动模式</span>
<div v-if="!singleSelection" style="flex: 1; color: red; text-align: right"
>多选模式下会修改当前选中的所有回路</div
>
</div>
<!-- 控制场景按钮部分 -->
<div class="control-scene-btn-area">
<button
v-for="(button4, index) in thisButton3.childList"
:key="index"
:class="{ btn: true, selected: button4.executeStatus.value != 0 }"
@click="selectButton4(button4)">
{{ button4.name }}
</button>
</div>
</div>
<!-- 底部按钮区 -->
<div class="bottom">
<a-badge :offset="[-10, 2]" :count="changeList.length">
<a-popconfirm
title="刷新将会取消已作出的修改"
ok-text="确定"
cancel-text="取消"
@confirm="refresh"
@cancel="changeCancel">
<button class="flushed">刷新</button>
</a-popconfirm>
</a-badge>
<a-spin :spinning="buttonLoading">
<button class="execute" @click="showModal">执行</button>
</a-spin>
</div>
<!-- 点击执行时的弹出框 -->
<div class="out-dialog" v-if="executeVisible">
<div class="content">
<div>
<div class="div-operation"></div>
<span class="text-operation">变更内容 </span>
</div>
<div class="j-box" v-for="item in diffList" :key="item.id">
<div class="journal" style="margin-top: 20px">
<div class="imgText">
<div class="zjzm">
<img class="title-img" src="/asset/image//bulbLogo/21961.png" alt="" />&nbsp;
<span
class="title-text"
style="font-size: 20px; font-weight: 500; color: rgba(255, 255, 255, 1)"
>{{ item.regionName + ' > ' + item.deviceGroupName }}</span
>
</div>
<a-popconfirm
title="此操作将会撤销修改"
ok-text="确定"
cancel-text="取消"
@confirm="delBtn(item)"
@cancel="changeCancel">
<button class="cxbtn">撤销</button>
</a-popconfirm>
</div>
<div class="btn-box">
<div class="btn-item">
<div class="left">控制模式</div>
<div class="right">
<span>手动</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>自动</span>
</div>
</div>
<div class="btn-item">
<div class="left"> 亮度 </div>
<div class="right">
<!-- 由于数字0也会被判为false故只判断undefined null -->
<span>{{
item?.stateBefore?.brightness != undefined ? item.stateBefore.brightness : '--'
}}</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>{{
item?.stateAfter?.brightness != undefined ? item.stateAfter.brightness : '--'
}}</span>
</div>
</div>
<div class="btn-item">
<div class="left"> 控制场景 </div>
<div class="right">
<span>{{
item?.stateBefore?.scene?.label ? item.stateBefore.scene.label : '--'
}}</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>{{
item?.stateAfter?.scene?.label ? item.stateAfter.scene.label : '--'
}}</span>
</div>
</div>
<div class="btn-item">
<div class="left"> 色温 </div>
<div class="right">
<span>{{
item?.stateBefore?.color != undefined ? item.stateBefore.color : '--'
}}</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>
{{ item?.stateAfter?.color != undefined ? item.stateAfter.color : '--' }}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div style="width: 100%; height: 60px"></div>
<div class="button-box">
<button class="cancel" @click="executeVisible = false">取消</button>
<a-popconfirm
title="此操作将提交以上修改内容"
ok-text="确定"
cancel-text="取消"
@click="submitChangeList"
@cancel="changeCancel">
<button class="execute">执行</button>
</a-popconfirm>
</div>
</div>
</a-spin>
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { DownOutlined, UpOutlined, StopOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
// 请求
import { http } from '/nerv-lib/util/http';
import { lightingManage } from '/@/api/IlluminationInfo';
import { airConditionControl } from '/@/api/airConditionControlSystem';
// 全局变量
import { items } from '/@/store/item';
// 初始化 =========================================================================
onMounted(() => {
// 分区初始化
setArea();
});
// 分区初始化,以 1-1 作为默认回路
const setArea = () => {
const data = props.treeData[0];
buttons2.value = data.childList;
};
// 全局变量
const state = items();
// 与父组件的交互 ===================================================================
const props = defineProps({
// 分区结构(照明区域 > 照明回路)
treeData: {
type: Array,
default: () => {
[];
},
},
});
/** 向上传递方法
* @method changeArea 用于控制俯视图的选中状态
* @method reset 用于重置按钮区
* @method reload 用于刷新一次页面
*/
const emit = defineEmits(['changeArea', 'reset', 'reload']);
// 照明区域业务 =======================================================================
// 按钮区展开与收起状态
const showAllButtonsArea = ref(false);
// 被选中的分区 默认为1 用于选中样式渲染
const selectedButton = ref<string | undefined>('1');
// 分区切换
const changeArea = (button: any) => {
// 当前选中按钮
selectedButton.value = button.id;
// 设置当前选中的回路
buttons2.value = button.childList;
// 重置按钮状态
emit('reset');
// 设置选中按钮状态
button.selected = true;
// 改变俯视图样式
emit('changeArea', button.id);
// 当前选中回路 - 置空
resetMode();
// 最近交互过的按钮 - 置空
handleButton.value = '';
};
// 默认最多展示8个按钮
const limitedButtons1 = computed(() => props.treeData.slice(0, 8));
// 照明回路业务 ======================================================================
// 最近交互过的按钮id用于禁用和启用
const handleButton = ref('');
// 开关启用/禁用状态
const isPlanEnabled2 = ref(true);
// 开关启用/禁用切换事件
const togglePlan2 = () => {
// 如果未交互任何按钮
if (handleButton.value == '') {
return message.info('请选择照明回路');
}
// 获取最近交互过的按钮
const btn: any = buttons2.value.find((button: any) => button.id === handleButton.value);
let panel = +!btn.ctrlStatus;
isLoading.value = true;
http
.get(lightingManage.setDisable, {
deviceGroup: btn.dataCode,
panel,
projectId: state.projectId,
siteId: state.siteId,
})
.then((res) => {
if (res.msg === 'success') {
// 确认成功后 - 按钮文本取反 - 按钮布尔值修改 - 关闭loading
isPlanEnabled2.value = !isPlanEnabled2.value;
btn.ctrlStatus = panel;
isLoading.value = false;
} else {
isLoading.value = false;
}
})
.catch(() => {
isLoading.value = false;
});
};
// 是否单选,状态
let singleSelection = ref(true);
// 多选与单选切换事件
const selectAll = () => {
selectAllCheckbox.value = false;
// 切换时清空当前所有选项
buttons2.value.forEach((button: any) => {
button.selected = false;
});
singleSelection.value = !singleSelection.value;
// 当前选中回路 - 置空
resetMode();
// 改变俯视图样式
emit('changeArea', [selectedButton.value]);
};
// 全选状态
const selectAllCheckbox = ref(false);
// 全选切换事件switch
const toggleAllSelection = () => {
let arr = [selectedButton.value];
// 全选
if (selectAllCheckbox.value) {
buttons2.value.forEach((item: any, index: number) => {
// 全选时,默认展示第一条回路的模式-场景按钮
if (index == 0) {
thisButton2.value = item;
}
item.selected = true;
arr.push(item.id);
});
// 全不选
} else {
buttons2.value.forEach((item: any) => {
item.selected = false;
});
// 全不选时,隐藏 模式 与 场景 按钮
resetMode();
}
emit('changeArea', arr);
};
// 储存当前选中的回路
const thisButton2 = ref({
dataCode: '',
name: '',
treePid: '',
childList: [],
});
// 照明回路的按钮切换
const changeLine = (button: any) => {
console.log(button, 'button2mmmm');
// 存储一次按钮ID用于禁用/启用交互
handleButton.value = button.id;
// 根据按钮状态,展示禁用/启用按钮文本
if (button.ctrlStatus) {
isPlanEnabled2.value = true;
} else {
isPlanEnabled2.value = false;
}
// 选择时反控俯视图
let level1 = selectedButton.value;
let level2 = button.id;
// 单选模式需将所有其他回路设为false
if (singleSelection.value) {
buttons2.value.forEach((item: any) => {
item.selected = false;
});
button.selected = !button.selected;
emit('changeArea', [level1, level2]);
} else {
// 多选模式传值
button.selected = !button.selected;
const arr = [level1];
buttons2.value.forEach((item: any) => {
if (item.selected) {
arr.push(item.id);
}
});
emit('changeArea', arr);
}
// 用于展示控制模式
if (button.selected) {
// 发生了选中事件
thisButton2.value = button;
// 获得启动模式
if (button.childList) {
thisButton3.value = button.childList.find((item: any) => {
if (item.selectAble) {
return item.childList ? item.childList : [];
}
});
} else {
thisButton3.value = { childList: [] };
}
} else {
// 未发生选中 或 多选的其中一个按钮被取消
resetMode();
}
console.log(thisButton2, 'button');
};
// 照明回路所有按钮
const buttons2 = ref([]);
// 按钮区展开与收起状态
const showAllButtons = ref(false);
// 默认最多展示8个按钮
const limitedButtons2 = computed(() => buttons2.value.slice(0, 8));
// 控制模式业务 ====================================================================
const thisButton3 = ref({
childList: [],
});
// 控制模式 - 按钮切换
const selectButton3 = (button3: any) => {
console.log(button3);
if (!button3.selectAble) {
return message.warning(`${button3.name} 暂不支持`);
}
thisButton3.value = button3;
};
// 控制场景业务 =====================================================================
// 控制场景 - 按钮切换
const selectButton4 = (button4: any) => {
const after = button4.dataCode;
let before = '';
// 如果是多选模式
if (!singleSelection.value) {
// 操作线路总数
let sum = 0;
// 没有这个选项的线路
let nofind = 0;
// 修改无效的数量
let checked = 0;
// 可修改的数量
let changed = 0;
buttons2.value.forEach((item: any) => {
// 取出当前选中的值 before
if (item.childList) {
let mode = item.childList.find((lv3: any) => {
return lv3.selectAble;
});
if (mode.childList) {
mode.childList.forEach((mode: any) => {
// 取出当前选中的模式
if (mode.executeStatus.value == 1) {
before = mode.dataCode;
}
});
}
}
// 查看当前回路,哪些被选中
if (item.selected) {
item.childList.forEach((v: any) => {
if (v.childList) {
v.childList.forEach((v1: any) => {
// 查看是否包含当前要修改的值
if (v1.dataCode == after) {
sum += 1;
// 已经被选中,无需修改的内容
if (before == after) {
return (checked += 1);
// 修改
} else {
alert(v.treePid + '---' + before + '---' + after);
changed += 1;
resetScene(item.childList);
changeScene(v1, before, after);
v1.executeStatus.value = 1;
}
}
});
}
});
}
});
alert(`共修改${sum}条,${checked}条无需修改,${nofind}条不具有该选项,${changed}条生效`);
// 如果是单选模式
} else {
// 如果按钮已经被选择
if (button4.executeStatus.value == 1) {
return message.info('未产生实际修改');
} else {
// 获得线路当前的场景
let before;
thisButton2.value.childList.find((item: any) => {
if (item.childList) {
item.childList.forEach((i: any) => {
if (i.executeStatus.value == 1) {
return (before = i.dataCode);
}
});
}
});
// 移除选中场景
resetScene(thisButton2.value.childList);
changeScene(button4, before, after);
}
}
};
// 切换场景前,需要把其他场景移除
const resetScene = (list: any) => {
list.forEach((item: any) => {
if (item.childList) {
item.childList.forEach((i: any) => {
i.executeStatus.value = 0;
});
}
});
};
/** 控制场景 - 按钮切换通用方法(单选 & 多选)
* @param button 当前被选中的场景(单选 & 多选)
* @param before 当前回路场景的初始值(撤回时需使用)
*/
const changeScene = (button: any, before: string | undefined, after: string) => {
console.log(changeList.value, 'vvvvvvvvvvvvvv-----', button, 'bbbbbbbb---------');
// 通过分组ID查询之前是否修改过
const result = changeList.value.find((item: any, index: number) => {
item.index = index;
return item.deviceGroup == button.treePid.split('_')[0];
});
console.log(result, 'rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr');
// 如果已产生过修改
if (result) {
// 改回了原有的值,则从数组中移除
if (after == result.before) {
changeList.value.splice(result.index, 1);
// 修改为新值,则只修改场景
} else {
result.scene = after;
// 临时flag用后移除
delete result.index;
}
// 如果未产生过修改
} else {
changeList.value.push({
// 回路
deviceGroup: thisButton2.value.dataCode,
deviceGroupName: thisButton2.value.name,
// 分区
region: thisButton2.value.treePid,
regionName: '',
// 修改前
before,
scene: after,
});
}
button.executeStatus.value = 1;
};
// 底部按钮区 ======================================================================
const isLoading = ref(false);
// 执行按钮loading
const buttonLoading = ref(false);
// 刷新
const refresh = () => {
// 关闭执行弹窗
executeVisible.value = false;
// 设置当前选中的序列
selectedButton.value = '1';
// 重置选中样式 和 按钮选中状态
emit('changeArea', ['1']);
emit('reset');
// 将所有修改改回
changeList.value.forEach((item: any) => {
resetChangeList(item);
});
changeList.value = [];
// 默认选择第一个楼层
let data = props.treeData[0];
// 默认选中
data.selected = true;
// 默认选中 1-1 分区 回路
buttons2.value = data.childList;
// 将选中线路重置
resetMode();
};
// 刷新时,将已修改的值改回
const resetChangeList = (item: any) => {
props.treeData.find((v: any) => {
if (item.region == v.dataCode) {
v.childList.find((v1: any) => {
// 找到被修改过的线路
if (item.deviceGroup == v1.dataCode) {
v1.childList.forEach((v2: any) => {
if (v2.childList) {
v2.childList.forEach((v3: any) => {
// 将新值移除
if (item.scene == v3.dataCode) {
v3.executeStatus.value = 0;
}
// 旧值选中
if (item.before == v3.dataCode) {
v3.executeStatus.value = 1;
}
});
}
});
}
});
}
});
};
// 右下角的执行事件
const showModal = () => {
if (!changeList.value.length) {
return message.info('未产生任何修改');
}
buttonLoading.value = true;
http
.post(airConditionControl.getChangeList, {
sceneList: changeList.value,
lockList: [],
projectId: state.projectId,
siteId: state.siteId,
})
.then((res) => {
if (res.msg === 'success') {
diffList.value = res.data;
executeVisible.value = true;
} else {
message.warning('获取修改内容失败');
}
buttonLoading.value = false;
})
.catch(() => {
buttonLoading.value = false;
});
};
// 通用取消
const changeCancel = () => {};
// 内侧弹窗 ========================================================================
// 内侧弹窗显隐
const executeVisible = ref<boolean>(false);
// 修改模式 需要向后端提交的内容
const changeList: any = ref([]);
// 展示修改前后差异的内容
const diffList = ref([]);
//撤销
const delBtn = (obj: any) => {
// 将treeData对应回路的数据改回数据以后端为准
obj.scene = obj.stateAfter.scene.value;
obj.before = obj.stateBefore.scene.value;
resetChangeList(obj);
// 将 changeList 与 diffList 中记录的修改移除 (排除极端情况)
changeList.value = changeList.value.filter((item: any) => {
return item.deviceGroup !== obj.deviceGroup;
});
diffList.value = diffList.value.filter((item: any) => {
return item.deviceGroup !== obj.deviceGroup;
});
console.log(changeList, 'changeList');
console.log(diffList, 'diffList');
// 如果移除后不再有修改内容,则隐藏弹出框
if (changeList.value.length == 0) {
executeVisible.value = false;
}
};
// 提交本次修改
const submitChangeList = () => {
http
.post(airConditionControl.submitChangeList, {
sceneList: changeList.value,
lockList: [],
projectId: state.projectId,
siteId: state.siteId,
})
.then((res) => {
emit('reload');
refresh();
});
};
// 其他业务 ========================================================================
// 将当前选择的回路置空
const resetMode = () => {
thisButton2.value = {
dataCode: '',
name: '',
treePid: '',
childList: [],
};
};
// 向外暴露方法
defineExpose({
// 分区切换
changeArea,
// 回路切换
changeLine,
});
</script>
<style lang="less" scoped>
@import './dialogStyle.less';
@import './tabs1.less';
</style>