|
@@ -1,17 +1,59 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { computed, ref } from 'vue';
|
|
|
-import { message, Modal } from 'ant-design-vue';
|
|
|
+import { computed, onUnmounted, ref, watch } from 'vue';
|
|
|
+import { Modal } from 'ant-design-vue';
|
|
|
|
|
|
import SvgIcon from '@/components/SvgIcon.vue';
|
|
|
+import { useRequest } from '@/hooks/request';
|
|
|
import { useViewVisible } from '@/hooks/view-visible';
|
|
|
import { t } from '@/i18n';
|
|
|
+import { getGroupModuleDevStatus, updateGroupModuleDevData } from '@/api';
|
|
|
|
|
|
import { DeviceType } from '../device-work-status/device-card';
|
|
|
|
|
|
+import StartStopTip from './StartStopTip.vue';
|
|
|
+
|
|
|
import type { SegmentedBaseOption } from 'ant-design-vue/es/segmented/src/segmented';
|
|
|
-import type { IconObject } from '@/types';
|
|
|
+import type { GroupBatchDeviceItem, IconObject } from '@/types';
|
|
|
+
|
|
|
+interface Props {
|
|
|
+ groupId: number;
|
|
|
+}
|
|
|
+
|
|
|
+const props = defineProps<Props>();
|
|
|
|
|
|
const { visible, showView, hideView } = useViewVisible();
|
|
|
+const { isLoading, handleRequest } = useRequest();
|
|
|
+const devicesStatus = ref<Record<number, GroupBatchDeviceItem[] | undefined>>({});
|
|
|
+let devicesStatusTimer: number | undefined;
|
|
|
+
|
|
|
+watch(visible, () => {
|
|
|
+ if (visible.value) {
|
|
|
+ getAllDeviceStatus();
|
|
|
+ } else {
|
|
|
+ devicesStatus.value = {};
|
|
|
+ clearTimeout(devicesStatusTimer);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+onUnmounted(() => {
|
|
|
+ devicesStatus.value = {};
|
|
|
+ clearTimeout(devicesStatusTimer);
|
|
|
+});
|
|
|
+
|
|
|
+const getAllDeviceStatus = () => {
|
|
|
+ clearTimeout(devicesStatusTimer);
|
|
|
+
|
|
|
+ handleRequest(async () => {
|
|
|
+ const data = await getGroupModuleDevStatus(props.groupId);
|
|
|
+
|
|
|
+ data.forEach((item) => {
|
|
|
+ devicesStatus.value[item.deviceType] = item.deviceDataList;
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ devicesStatusTimer = window.setTimeout(getAllDeviceStatus, 3000);
|
|
|
+};
|
|
|
+
|
|
|
const activeKey = ref('manualStartStop');
|
|
|
const activeType = ref([DeviceType.冷水主机, DeviceType.冷却塔, DeviceType.冷冻泵, DeviceType.冷却泵]);
|
|
|
|
|
@@ -19,20 +61,11 @@ const isStartStop = computed(() => {
|
|
|
return activeKey.value === 'manualStartStop';
|
|
|
});
|
|
|
|
|
|
-interface DeviceItem {
|
|
|
- id: number;
|
|
|
- name: string;
|
|
|
- type: DeviceType.冷水主机 | DeviceType.冷却塔 | DeviceType.冷冻泵 | DeviceType.冷却泵;
|
|
|
- status: 'on' | 'off';
|
|
|
- enable: boolean;
|
|
|
- auto: boolean;
|
|
|
-}
|
|
|
-
|
|
|
interface DeviceTypeGroupItem {
|
|
|
name: string;
|
|
|
icon: IconObject;
|
|
|
type: DeviceType.冷水主机 | DeviceType.冷却塔 | DeviceType.冷冻泵 | DeviceType.冷却泵;
|
|
|
- list: DeviceItem[];
|
|
|
+ list: GroupBatchDeviceItem[];
|
|
|
}
|
|
|
|
|
|
const deviceTypeGroups = computed<DeviceTypeGroupItem[]>(() => {
|
|
@@ -44,11 +77,7 @@ const deviceTypeGroups = computed<DeviceTypeGroupItem[]>(() => {
|
|
|
size: 21,
|
|
|
},
|
|
|
type: DeviceType.冷水主机,
|
|
|
- list: [
|
|
|
- { id: 1, name: '五期-1#冷水主机', type: DeviceType.冷水主机, status: 'off', enable: true, auto: true },
|
|
|
- { id: 2, name: '五期-2#冷水主机', type: DeviceType.冷水主机, status: 'on', enable: false, auto: false },
|
|
|
- { id: 3, name: '五期-3#冷水主机', type: DeviceType.冷水主机, status: 'off', enable: true, auto: true },
|
|
|
- ],
|
|
|
+ list: devicesStatus.value[DeviceType.冷水主机] || [],
|
|
|
},
|
|
|
{
|
|
|
name: t('common.coolingTower'),
|
|
@@ -57,11 +86,7 @@ const deviceTypeGroups = computed<DeviceTypeGroupItem[]>(() => {
|
|
|
size: 23,
|
|
|
},
|
|
|
type: DeviceType.冷却塔,
|
|
|
- list: [
|
|
|
- { id: 4, name: '五期-1#冷却塔', type: DeviceType.冷却塔, status: 'off', enable: true, auto: true },
|
|
|
- { id: 5, name: '五期-2#冷却塔', type: DeviceType.冷却塔, status: 'off', enable: true, auto: true },
|
|
|
- { id: 6, name: '五期-3#冷却塔', type: DeviceType.冷却塔, status: 'off', enable: true, auto: true },
|
|
|
- ],
|
|
|
+ list: devicesStatus.value[DeviceType.冷却塔] || [],
|
|
|
},
|
|
|
{
|
|
|
name: t('common.chilledWaterPump'),
|
|
@@ -70,11 +95,7 @@ const deviceTypeGroups = computed<DeviceTypeGroupItem[]>(() => {
|
|
|
size: 20,
|
|
|
},
|
|
|
type: DeviceType.冷冻泵,
|
|
|
- list: [
|
|
|
- { id: 7, name: '五期-1#冷冻泵', type: DeviceType.冷冻泵, status: 'off', enable: true, auto: true },
|
|
|
- { id: 8, name: '五期-2#冷冻泵', type: DeviceType.冷冻泵, status: 'off', enable: true, auto: true },
|
|
|
- { id: 9, name: '五期-3#冷冻泵', type: DeviceType.冷冻泵, status: 'off', enable: true, auto: true },
|
|
|
- ],
|
|
|
+ list: devicesStatus.value[DeviceType.冷冻泵] || [],
|
|
|
},
|
|
|
{
|
|
|
name: t('common.coolingPump'),
|
|
@@ -83,36 +104,30 @@ const deviceTypeGroups = computed<DeviceTypeGroupItem[]>(() => {
|
|
|
size: 20,
|
|
|
},
|
|
|
type: DeviceType.冷却泵,
|
|
|
- list: [
|
|
|
- { id: 10, name: '五期-1#冷却泵', type: DeviceType.冷却泵, status: 'off', enable: true, auto: true },
|
|
|
- { id: 11, name: '五期-2#冷却泵', type: DeviceType.冷却泵, status: 'off', enable: true, auto: true },
|
|
|
- { id: 12, name: '五期-3#冷却泵', type: DeviceType.冷却泵, status: 'off', enable: true, auto: true },
|
|
|
- ],
|
|
|
+ list: devicesStatus.value[DeviceType.冷却泵] || [],
|
|
|
},
|
|
|
];
|
|
|
});
|
|
|
|
|
|
-type StartStopValue = 'true' | 'false';
|
|
|
-
|
|
|
-interface StartStopTypeItem extends SegmentedBaseOption {
|
|
|
- value: StartStopValue;
|
|
|
+interface ManualAutoTypeItem extends SegmentedBaseOption {
|
|
|
+ value: GroupBatchDeviceItem['manualAutoStatus'];
|
|
|
payload: {
|
|
|
title: string;
|
|
|
confirmTip: string;
|
|
|
};
|
|
|
}
|
|
|
|
|
|
-const startStopTypes = computed<StartStopTypeItem[]>(() => {
|
|
|
+const manualAutoTypes = computed<ManualAutoTypeItem[]>(() => {
|
|
|
return [
|
|
|
{
|
|
|
- value: 'true',
|
|
|
+ value: 1,
|
|
|
payload: {
|
|
|
title: t('common.automatic'),
|
|
|
confirmTip: t('realTimeMonitor.confirmSwitchToAutoTip'),
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
- value: 'false',
|
|
|
+ value: 0,
|
|
|
payload: {
|
|
|
title: t('common.manual'),
|
|
|
confirmTip: t('realTimeMonitor.confirmSwitchToManualTip'),
|
|
@@ -121,29 +136,63 @@ const startStopTypes = computed<StartStopTypeItem[]>(() => {
|
|
|
];
|
|
|
});
|
|
|
|
|
|
-const handleStartStopClick = (option: StartStopTypeItem, device: DeviceItem) => {
|
|
|
- if (option.disabled || option.value === String(device.auto)) {
|
|
|
+const handleManualAutoClick = (option: ManualAutoTypeItem, device: GroupBatchDeviceItem) => {
|
|
|
+ if (option.disabled || option.value === device.manualAutoStatus) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
Modal.confirm({
|
|
|
title: t('realTimeMonitor.confirmSwitchStartStop', {
|
|
|
- name: device.name,
|
|
|
+ name: device.deviceName,
|
|
|
status: option.payload.title,
|
|
|
}),
|
|
|
content: option.payload.confirmTip,
|
|
|
closable: true,
|
|
|
- async onOk() {
|
|
|
- try {
|
|
|
- device.auto = option.value === 'true';
|
|
|
- } catch (err) {
|
|
|
- message.error((err as Error).message);
|
|
|
- console.error(err);
|
|
|
- }
|
|
|
+ centered: true,
|
|
|
+ onOk() {
|
|
|
+ updateDeviceData(device.deviceId, 'manualAutoStatus', option.value);
|
|
|
},
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+const handleDisableEnableSwitch = (device: GroupBatchDeviceItem) => {
|
|
|
+ const content = device.disableEnableStatus
|
|
|
+ ? t('realTimeMonitor.confirmDeviceDisable')
|
|
|
+ : t('realTimeMonitor.confirmDeviceEnable');
|
|
|
+ const value = device.disableEnableStatus ? 0 : 1;
|
|
|
+
|
|
|
+ Modal.confirm({
|
|
|
+ title: t('realTimeMonitor.deviceStartStop'),
|
|
|
+ content,
|
|
|
+ closable: true,
|
|
|
+ centered: true,
|
|
|
+ onOk() {
|
|
|
+ updateDeviceData(device.deviceId, 'disableEnableStatus', value);
|
|
|
+ },
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const handleStartStopSwitch = (device: GroupBatchDeviceItem) => {
|
|
|
+ const content = device.startStopOrder ? t('common.confirmClose') : t('common.confirmOpen');
|
|
|
+ const value = device.startStopOrder ? 0 : 1;
|
|
|
+
|
|
|
+ Modal.confirm({
|
|
|
+ title: t('realTimeMonitor.manualStartStop'),
|
|
|
+ content: content + device.deviceName,
|
|
|
+ closable: true,
|
|
|
+ centered: true,
|
|
|
+ onOk() {
|
|
|
+ updateDeviceData(device.deviceId, 'startStopOrder', value);
|
|
|
+ },
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const updateDeviceData = (deviceId: number, paramCode: string, value: number) => {
|
|
|
+ handleRequest(async () => {
|
|
|
+ await updateGroupModuleDevData(deviceId, paramCode, value);
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
defineExpose({
|
|
|
showView,
|
|
|
hideView,
|
|
@@ -178,27 +227,41 @@ defineExpose({
|
|
|
<span>{{ item.name }}</span>
|
|
|
</span>
|
|
|
</template>
|
|
|
- <div class="device-batch-list-item" v-for="device in item.list" :key="device.id">
|
|
|
+ <div class="device-batch-list-item" v-for="device in item.list" :key="device.deviceId">
|
|
|
<span
|
|
|
v-show="isStartStop"
|
|
|
:class="[
|
|
|
'status-dot',
|
|
|
'device-batch-list-status',
|
|
|
{
|
|
|
- 'device-batch-status-offline': device.status === 'off',
|
|
|
+ 'device-batch-status-offline': device.runningStatus === 0,
|
|
|
},
|
|
|
]"
|
|
|
></span>
|
|
|
- <div class="device-batch-list-name">{{ device.name }}</div>
|
|
|
- <ASwitch v-show="!isStartStop" v-model:checked="device.enable" />
|
|
|
- <ASegmented v-show="isStartStop" :value="String(device.auto)" :options="startStopTypes">
|
|
|
+ <div :class="['device-batch-list-name', { 'flex-1': !isStartStop || device.manualAutoStatus }]">
|
|
|
+ {{ device.deviceName }}
|
|
|
+ </div>
|
|
|
+ <div v-show="isStartStop && !device.manualAutoStatus" class="device-batch-start-stop flex-1">
|
|
|
+ <StartStopTip :device-data="device" @click="handleStartStopSwitch(device)" />
|
|
|
+ </div>
|
|
|
+ <ASwitch
|
|
|
+ v-show="!isStartStop"
|
|
|
+ :checked="device.disableEnableStatus"
|
|
|
+ :checked-value="1"
|
|
|
+ :un-checked-value="0"
|
|
|
+ @click="handleDisableEnableSwitch(device)"
|
|
|
+ />
|
|
|
+ <ASegmented v-show="isStartStop" :value="device.manualAutoStatus" :options="manualAutoTypes">
|
|
|
<template #label="option">
|
|
|
- <span @click="handleStartStopClick(option as StartStopTypeItem, device)">{{ option.payload.title }}</span>
|
|
|
+ <span @click="handleManualAutoClick(option as ManualAutoTypeItem, device)">
|
|
|
+ {{ option.payload.title }}
|
|
|
+ </span>
|
|
|
</template>
|
|
|
</ASegmented>
|
|
|
</div>
|
|
|
</ACollapsePanel>
|
|
|
</ACollapse>
|
|
|
+ <ASpin v-if="isLoading" class="center-loading" :spinning="true" />
|
|
|
</AModal>
|
|
|
</template>
|
|
|
|
|
@@ -331,8 +394,14 @@ defineExpose({
|
|
|
}
|
|
|
|
|
|
.device-batch-list-name {
|
|
|
- flex: 1;
|
|
|
line-height: 24px;
|
|
|
color: var(--antd-color-text-secondary);
|
|
|
}
|
|
|
+
|
|
|
+.device-batch-start-stop {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-right: 24px;
|
|
|
+ margin-left: 16px;
|
|
|
+}
|
|
|
</style>
|