|
|
@@ -1,4 +1,5 @@
|
|
|
<template>
|
|
|
+ <!-- 场景选择下拉框 -->
|
|
|
<customHeader
|
|
|
:fieldNames="{ label: 'systemname', value: 'id', options: 'children' }"
|
|
|
:options="options"
|
|
|
@@ -7,10 +8,21 @@
|
|
|
>
|
|
|
{{ mainTitle }}
|
|
|
</customHeader>
|
|
|
+ <!-- 默认插槽,一般用来放模型 -->
|
|
|
<slot :monitor-data="monitorData"></slot>
|
|
|
<div class="scene-box">
|
|
|
<div class="center-container">
|
|
|
+ <!-- 监测模块 -->
|
|
|
<template v-if="activeKey == 'monitor'">
|
|
|
+ <slot name="opration">
|
|
|
+ <div class="button-wrapper">
|
|
|
+ <template v-for="item in mainConfig.operations" :key="item.key">
|
|
|
+ <template v-if="hasPermission(item.permission)">
|
|
|
+ <div :class="{ 'button-box': true, 'button-box-disable': item.disabled }" @click="handleOperate(item)">{{ item.label }} </div>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </slot>
|
|
|
<slot name="monitor">
|
|
|
<ModuleCommon
|
|
|
v-for="cfg in mainConfig.configs"
|
|
|
@@ -25,6 +37,7 @@
|
|
|
</slot>
|
|
|
</template>
|
|
|
<div v-else class="history-group">
|
|
|
+ <!-- 场景下关联的设备有很多,在这里选择 -->
|
|
|
<div v-if="showDeviceList && deviceList.length > 0" class="device-button-group">
|
|
|
<div
|
|
|
v-for="(device, index) in deviceList"
|
|
|
@@ -70,6 +83,12 @@
|
|
|
</div>
|
|
|
<BottomMenu @change="changeActive" />
|
|
|
</div>
|
|
|
+ <PasswordModal
|
|
|
+ :modal-is-show="passwordModalShown"
|
|
|
+ :modal-title="operatingTarget?.label"
|
|
|
+ @handle-ok="handlePasswordOK"
|
|
|
+ @handle-cancel="passwordModalShown = false"
|
|
|
+ />
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
@@ -83,15 +102,27 @@
|
|
|
import AlarmHistoryTable from '/@/views/vent/monitorManager/comment/AlarmHistoryTable.vue';
|
|
|
import { useRouter } from 'vue-router';
|
|
|
import { Config } from '/@/views/vent/deviceManager/configurationTable/types';
|
|
|
- import { message } from 'ant-design-vue';
|
|
|
+ import { message, Modal } from 'ant-design-vue';
|
|
|
import _ from 'lodash';
|
|
|
+ import PasswordModal from '/@/views/vent/monitorManager/comment/components/PasswordModal.vue';
|
|
|
+ import { usePermission } from '/@/hooks/web/usePermission';
|
|
|
+ import { deviceControlApi } from '/@/api/vent';
|
|
|
|
|
|
type DeviceType = { deviceType: string; deviceName: string; datalist: any[] };
|
|
|
+ type Operation = {
|
|
|
+ label: string;
|
|
|
+ key: string;
|
|
|
+ value: string;
|
|
|
+ disabled?: boolean;
|
|
|
+ showPassword?: boolean;
|
|
|
+ permission?: string;
|
|
|
+ onOk?: (key: string, value: string, pwd?: string) => Promise<void>;
|
|
|
+ };
|
|
|
|
|
|
const props = withDefaults(
|
|
|
defineProps<{
|
|
|
mainTitle: string;
|
|
|
- /** 是否显示历史数据上方的设备列表 */
|
|
|
+ /** 是否显示历史数据上方的设备类型选择器 */
|
|
|
showDeviceList?: boolean;
|
|
|
/** 请求场景数据传入的类型字符 */
|
|
|
strtype: string;
|
|
|
@@ -101,6 +132,7 @@
|
|
|
// deviceType: string;
|
|
|
/** 主要模块配置 */
|
|
|
mainConfig: {
|
|
|
+ operations: Operation[];
|
|
|
configs: Config[];
|
|
|
/** 获取该场景所含设备及其监测信息的API */
|
|
|
monitorApi?: (params: { deviceType: string; deviceId: number | string }) => Promise<any>;
|
|
|
@@ -141,6 +173,7 @@
|
|
|
}>(),
|
|
|
{
|
|
|
mainConfig: () => ({
|
|
|
+ operations: [],
|
|
|
configs: [],
|
|
|
}),
|
|
|
monitorHistoryConfig: () => ({}),
|
|
|
@@ -152,6 +185,7 @@
|
|
|
);
|
|
|
|
|
|
const { currentRoute } = useRouter();
|
|
|
+ const { hasPermission } = usePermission();
|
|
|
|
|
|
const activeKey = ref('monitor');
|
|
|
|
|
|
@@ -159,7 +193,9 @@
|
|
|
activeKey.value = activeValue;
|
|
|
}
|
|
|
|
|
|
+ /** 场景选项 */
|
|
|
const options = ref([]);
|
|
|
+ /** 已选择了的场景的id */
|
|
|
const optionValue = ref('');
|
|
|
|
|
|
/** 获取左上角场景选择框数据的方法,如果此时初始场景未赋值则选择首项做初始化 */
|
|
|
@@ -180,17 +216,18 @@
|
|
|
getDeviceList();
|
|
|
}
|
|
|
|
|
|
- //关联设备
|
|
|
+ /** 当前场景所关联设备 */
|
|
|
const deviceList = ref<DeviceType[]>([]);
|
|
|
const deviceActive = ref('');
|
|
|
const deviceType = ref('');
|
|
|
|
|
|
+ /** 选择设备 */
|
|
|
function deviceChange(index) {
|
|
|
deviceType.value = deviceList.value[index]?.deviceType || '';
|
|
|
deviceActive.value = deviceList.value[index]?.deviceType || '';
|
|
|
}
|
|
|
|
|
|
- // 查询关联设备列表
|
|
|
+ /** 查询当前场景所关联设备列表 */
|
|
|
async function getDeviceList() {
|
|
|
const { msgTxt = [] } = await getDevice({ devicetype: 'sys', systemID: optionValue.value }).catch(() => {
|
|
|
message.error('获取已绑定设备时发生了错误');
|
|
|
@@ -217,6 +254,7 @@
|
|
|
}
|
|
|
|
|
|
let timer: NodeJS.Timeout;
|
|
|
+ /** 场景的监测数据 */
|
|
|
const monitorData = ref<any>({});
|
|
|
/** 获取本场景下所绑定的设备,将监测数据赋值 */
|
|
|
async function getMonitor() {
|
|
|
@@ -241,6 +279,59 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /** 密码提示框是否显示 */
|
|
|
+ const passwordModalShown = ref(false);
|
|
|
+ /** 下发操作时的目标配置 */
|
|
|
+ const operatingTarget = ref<Operation>();
|
|
|
+
|
|
|
+ /** 操作按钮点击后根据配置弹出确认框,初始化数据 */
|
|
|
+ function handleOperate(item: Operation) {
|
|
|
+ if (item.disabled) return;
|
|
|
+ operatingTarget.value = item;
|
|
|
+
|
|
|
+ if (item.showPassword) {
|
|
|
+ passwordModalShown.value = true;
|
|
|
+ } else {
|
|
|
+ Modal.confirm({
|
|
|
+ title: '操作确认',
|
|
|
+ content: `确定要进行${operatingTarget.value.label}操作吗?`,
|
|
|
+ iconType: 'info',
|
|
|
+ onOk: () => handlePasswordOK(),
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 密码输入后确认的回调 */
|
|
|
+ function handlePasswordOK(pwd?: string) {
|
|
|
+ if (!operatingTarget.value) return message.error('操作目标不存在');
|
|
|
+ const { onOk = deviceControl, key, value } = operatingTarget.value;
|
|
|
+
|
|
|
+ return onOk(key, value, pwd)
|
|
|
+ .then(() => {
|
|
|
+ passwordModalShown.value = false;
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ operatingTarget.value = undefined;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function deviceControl(key: string, value: string, pwd?: string) {
|
|
|
+ return deviceControlApi({
|
|
|
+ deviceid: optionValue.value,
|
|
|
+ devicetype: deviceType.value,
|
|
|
+ password: pwd,
|
|
|
+ paramcode: key,
|
|
|
+ value: value,
|
|
|
+ })
|
|
|
+ .then((r) => {
|
|
|
+ if (!r.success) throw r.message || '操作失败';
|
|
|
+ message.success('指令下发成功');
|
|
|
+ })
|
|
|
+ .catch((e) => {
|
|
|
+ message.error(typeof e === 'string' ? e : '指令下发失败');
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
onMounted(async () => {
|
|
|
if (currentRoute.value && currentRoute.value['query'] && currentRoute.value['query']['id']) {
|
|
|
optionValue.value = currentRoute.value['query']['id'] as string;
|
|
|
@@ -262,7 +353,9 @@
|
|
|
<style lang="less" scoped>
|
|
|
@import '/@/design/vent/modal.less';
|
|
|
@ventSpace: zxm;
|
|
|
+
|
|
|
.scene-box {
|
|
|
+ --image-tab-group-bg: url('/@/assets/images/vent/tab-group-bg.png');
|
|
|
margin-top: 40px;
|
|
|
pointer-events: none;
|
|
|
.history-group {
|
|
|
@@ -342,9 +435,77 @@
|
|
|
}
|
|
|
|
|
|
.@{ventSpace}-input-number {
|
|
|
- border-color: #ffffff88 !important;
|
|
|
+ border-color: #ffffff88;
|
|
|
}
|
|
|
|
|
|
margin-right: 10px;
|
|
|
}
|
|
|
+
|
|
|
+ .button-wrapper {
|
|
|
+ position: relative;
|
|
|
+ top: 30px;
|
|
|
+ left: 500px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-start;
|
|
|
+ align-items: center;
|
|
|
+ margin-top: 10px;
|
|
|
+ width: 1165px !important;
|
|
|
+ height: 75px;
|
|
|
+ background: var(--image-tab-group-bg) no-repeat;
|
|
|
+ background-image: 100% 100%;
|
|
|
+ padding: 0 30px;
|
|
|
+ z-index: 10;
|
|
|
+
|
|
|
+ .button-box {
|
|
|
+ margin: 0 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .button-box {
|
|
|
+ position: relative;
|
|
|
+ padding: 5px;
|
|
|
+ border-radius: 5px;
|
|
|
+ width: auto;
|
|
|
+ height: 34px;
|
|
|
+ border: 1px solid var(--vent-base-border);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ color: var(--vent-font-color);
|
|
|
+ padding: 0 10px;
|
|
|
+ cursor: pointer;
|
|
|
+ pointer-events: all;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: var(--vent-device-manager-control-btn-hover);
|
|
|
+ }
|
|
|
+
|
|
|
+ &::before {
|
|
|
+ width: calc(100% - 6px);
|
|
|
+ height: 26px;
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ top: 3px;
|
|
|
+ right: 0;
|
|
|
+ left: 3px;
|
|
|
+ bottom: 0;
|
|
|
+ z-index: -1;
|
|
|
+ border-radius: inherit;
|
|
|
+ /*important*/
|
|
|
+ background: var(--vent-device-manager-control-btn);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .button-box-disable {
|
|
|
+ cursor: not-allowed;
|
|
|
+ border: 1px solid var(--vent-base-border);
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:before {
|
|
|
+ background: linear-gradient(#5897c299, #4a92a899);
|
|
|
+ }
|
|
|
+ }
|
|
|
</style>
|