|
@@ -1,20 +1,30 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { onMounted, ref } from 'vue';
|
|
|
+import { onMounted, ref, useTemplateRef } from 'vue';
|
|
|
|
|
|
+import SvgIcon from '@/components/SvgIcon.vue';
|
|
|
import { useRequest } from '@/hooks/request';
|
|
|
import { getDevWorkRealTimeData, getDevWorkTypeCount, queryDevicesList } from '@/api';
|
|
|
+import { DeviceRunningStatus, DeviceStatusQuery } from '@/constants';
|
|
|
|
|
|
import { deviceCardData, DeviceType } from './device-card';
|
|
|
+import DeviceWorkParams from './DeviceWorkParams.vue';
|
|
|
|
|
|
import type { DevicesListItem, DeviceTypeCount, PageParams } from '@/types';
|
|
|
|
|
|
const { handleRequest } = useRequest();
|
|
|
const deviceTypes = ref<DeviceTypeCount[]>([]);
|
|
|
const activeDeviceType = ref<DeviceType>(DeviceType.空);
|
|
|
+const activeDeviceStatus = ref<DeviceStatusQuery>(DeviceStatusQuery.All);
|
|
|
|
|
|
onMounted(() => {
|
|
|
handleRequest(async () => {
|
|
|
- deviceTypes.value = await getDevWorkTypeCount(7);
|
|
|
+ deviceTypes.value = await getDevWorkTypeCount(7, [
|
|
|
+ DeviceType.冷水主机,
|
|
|
+ DeviceType.控制柜,
|
|
|
+ DeviceType.冷却塔,
|
|
|
+ DeviceType.冷却泵,
|
|
|
+ DeviceType.冷冻泵,
|
|
|
+ ]);
|
|
|
|
|
|
if (deviceTypes.value.length) {
|
|
|
activeDeviceType.value = deviceTypes.value[0].deviceType;
|
|
@@ -27,7 +37,7 @@ const deviceList = ref<DevicesListItem[]>([]);
|
|
|
const deviceTotal = ref(0);
|
|
|
const pageParams = ref<PageParams>({
|
|
|
pageIndex: 1,
|
|
|
- pageSize: 10,
|
|
|
+ pageSize: 100,
|
|
|
pageSorts: [
|
|
|
{
|
|
|
column: 'id',
|
|
@@ -38,9 +48,18 @@ const pageParams = ref<PageParams>({
|
|
|
|
|
|
const getDeviceList = () => {
|
|
|
handleRequest(async () => {
|
|
|
+ let runningStatusList = null;
|
|
|
+
|
|
|
+ if (activeDeviceStatus.value === DeviceStatusQuery.Offline) {
|
|
|
+ runningStatusList = [DeviceRunningStatus.Offline];
|
|
|
+ } else if (activeDeviceStatus.value === DeviceStatusQuery.Online) {
|
|
|
+ runningStatusList = [DeviceRunningStatus.Stop, DeviceRunningStatus.Run];
|
|
|
+ }
|
|
|
+
|
|
|
const { records, total } = await queryDevicesList({
|
|
|
...pageParams.value,
|
|
|
deviceType: activeDeviceType.value,
|
|
|
+ runningStatusList,
|
|
|
});
|
|
|
|
|
|
const deviceIds = records.map((item) => item.id);
|
|
@@ -59,27 +78,87 @@ const handleTabClick = () => {
|
|
|
getDeviceList();
|
|
|
}, 0);
|
|
|
};
|
|
|
+
|
|
|
+const deviceWorkParamsRef = useTemplateRef('deviceWorkParams');
|
|
|
+
|
|
|
+const viewDevParam = () => {
|
|
|
+ deviceWorkParamsRef.value?.showView();
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
<div>
|
|
|
- <ATabs class="button-tabs-card" v-model:active-key="activeDeviceType" type="card" @tab-click="handleTabClick">
|
|
|
- <ATabPane v-for="item in deviceTypes" :key="item.deviceType" :tab="`${item.deviceTypeName}(${item.count})`" />
|
|
|
- </ATabs>
|
|
|
+ <div class="device-work-header">
|
|
|
+ <ATabs
|
|
|
+ class="button-tabs-card device-type-tab"
|
|
|
+ v-model:active-key="activeDeviceType"
|
|
|
+ type="card"
|
|
|
+ @tab-click="handleTabClick"
|
|
|
+ >
|
|
|
+ <ATabPane v-for="item in deviceTypes" :key="item.deviceType" :tab="`${item.deviceTypeName}(${item.count})`" />
|
|
|
+ </ATabs>
|
|
|
+ <ATabs class="device-status-tab" v-model:active-key="activeDeviceStatus" @tab-click="handleTabClick">
|
|
|
+ <ATabPane :key="DeviceStatusQuery.All" :tab="$t('common.entire')" />
|
|
|
+ <ATabPane :key="DeviceStatusQuery.Online" :tab="$t('common.online')" />
|
|
|
+ <ATabPane :key="DeviceStatusQuery.Offline" :tab="$t('common.offline')" />
|
|
|
+ </ATabs>
|
|
|
+ </div>
|
|
|
<ARow :gutter="[22, 24]">
|
|
|
<ACol v-for="item in deviceList" :key="item.id" :xs="24" :sm="24" :md="24" :lg="12" :xl="12" :xxl="8">
|
|
|
<div class="device-card-container">
|
|
|
<div class="device-card-header">
|
|
|
- <div class="device-card-header-title">{{ item.deviceName }}</div>
|
|
|
+ <span
|
|
|
+ :class="[
|
|
|
+ 'status-dot',
|
|
|
+ {
|
|
|
+ 'device-status-offline': item.runningStatus === DeviceRunningStatus.Offline,
|
|
|
+ },
|
|
|
+ ]"
|
|
|
+ ></span>
|
|
|
+ <div class="ellipsis-text device-card-header-title">{{ item.deviceName }}</div>
|
|
|
+ <div class="device-cop-value">5.17</div>
|
|
|
+ <div class="device-cop-level">中</div>
|
|
|
+ <span class="device-card-header-time">2025-3-21 09:40</span>
|
|
|
+ <SvgIcon class="device-card-header-button" name="adjustment" @click="viewDevParam" />
|
|
|
</div>
|
|
|
<component :is="deviceCardData[activeDeviceType]?.component" />
|
|
|
</div>
|
|
|
</ACol>
|
|
|
</ARow>
|
|
|
+ <DeviceWorkParams ref="deviceWorkParams" />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
+.device-work-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.device-type-tab {
|
|
|
+ width: calc(100% - 200px);
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.device-status-tab) {
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 22px;
|
|
|
+
|
|
|
+ &.ant-tabs-top > .ant-tabs-nav {
|
|
|
+ .ant-tabs-tab {
|
|
|
+ padding: 5px 0;
|
|
|
+
|
|
|
+ + .ant-tabs-tab {
|
|
|
+ margin-left: 24px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &::before {
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
.device-card-container {
|
|
|
height: 328px;
|
|
|
padding: 16px 24px;
|
|
@@ -90,14 +169,77 @@ const handleTabClick = () => {
|
|
|
.device-card-header {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
margin-bottom: 24px;
|
|
|
}
|
|
|
|
|
|
+.device-status-offline {
|
|
|
+ --status-dot-rgb: 191, 191, 191; // RGB 颜色分量 (灰色)
|
|
|
+}
|
|
|
+
|
|
|
.device-card-header-title {
|
|
|
+ max-width: 150px;
|
|
|
+ margin-right: 16px;
|
|
|
+ margin-left: 8px;
|
|
|
font-size: 16px;
|
|
|
font-weight: 600;
|
|
|
line-height: 28px;
|
|
|
color: var(--antd-color-text);
|
|
|
}
|
|
|
+
|
|
|
+.device-cop-value {
|
|
|
+ font-family: DINAlternate;
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: bold;
|
|
|
+ line-height: 32px;
|
|
|
+ color: #e6a23c;
|
|
|
+}
|
|
|
+
|
|
|
+.device-cop-level {
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ margin-left: 8px;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 600;
|
|
|
+ line-height: 16px;
|
|
|
+ color: #e6a23c;
|
|
|
+ text-align: center;
|
|
|
+ background: rgb(234 178 94 / 40%);
|
|
|
+ border-radius: 2px;
|
|
|
+}
|
|
|
+
|
|
|
+.device-card-header-time {
|
|
|
+ flex: 1;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 20px;
|
|
|
+ color: #999;
|
|
|
+ text-align: right;
|
|
|
+}
|
|
|
+
|
|
|
+.device-card-header-button {
|
|
|
+ padding: 4px;
|
|
|
+ margin-left: 16px;
|
|
|
+ font-size: 16px;
|
|
|
+ color: var(--antd-color-primary);
|
|
|
+ cursor: pointer;
|
|
|
+ background: var(--antd-color-primary-opacity-15);
|
|
|
+ border-radius: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.device-card-label) {
|
|
|
+ height: 20px;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 20px;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.device-card-value) {
|
|
|
+ height: 24px;
|
|
|
+ font-family: DINAlternate;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+ line-height: 24px;
|
|
|
+ color: #333;
|
|
|
+}
|
|
|
</style>
|