|
@@ -1,15 +1,18 @@
|
|
|
<template>
|
|
|
<a-spin :spinning="spinning">
|
|
|
<div class="deviceDetail">
|
|
|
- <info-card title="点位图">
|
|
|
+ <info-card title="实时点位图">
|
|
|
<template #extra>
|
|
|
- <a-button type="primary" size="small" @click="roomConfigHandler('area')">
|
|
|
- 区域配置
|
|
|
- </a-button>
|
|
|
+ <a-space>
|
|
|
+ <a-button type="primary" size="small" @click="roomConfigHandler('area')">
|
|
|
+ 区域配置
|
|
|
+ </a-button>
|
|
|
+ <div class="areaZoom"> <FullscreenOutlined @click="openFullView = true" /> </div>
|
|
|
+ </a-space>
|
|
|
</template>
|
|
|
<a-alert
|
|
|
v-if="areaAvailable"
|
|
|
- message="检测区域范围未配置或数值较小,建议通过设备配置调整参数!"
|
|
|
+ message="检测区域范围未配置或数值较小,请在设备配置调整参数!"
|
|
|
banner
|
|
|
style="margin-bottom: 10px"
|
|
|
/>
|
|
@@ -83,6 +86,78 @@
|
|
|
</div>
|
|
|
</info-card>
|
|
|
|
|
|
+ <FullViewModal v-model:open="openFullView" :title="detailState.devName">
|
|
|
+ <div class="fullView">
|
|
|
+ <div class="pointTitle">实时点位图</div>
|
|
|
+ <div
|
|
|
+ class="radarBox"
|
|
|
+ :style="{
|
|
|
+ width: `${detailState?.length || 400}px`,
|
|
|
+ height: `${detailState?.width || 400}px`,
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <template v-if="targets && Object.keys(targets).length > 0">
|
|
|
+ <template v-for="t in targets" :key="t.id">
|
|
|
+ <div
|
|
|
+ class="target-dot"
|
|
|
+ :style="{
|
|
|
+ position: 'absolute',
|
|
|
+ width: '18px',
|
|
|
+ height: '18px',
|
|
|
+ background: t.id === 0 ? 'red' : t.id === 1 ? 'blue' : 'green',
|
|
|
+ borderRadius: '50%',
|
|
|
+ transform: `translate3d(${t.displayX + 200}px, ${-t.displayY + 200}px, 0) translate(-50%, -50%)`,
|
|
|
+ zIndex: 10,
|
|
|
+ transition: 'transform 1s linear',
|
|
|
+ willChange: 'transform',
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <span
|
|
|
+ style="
|
|
|
+ color: #fff;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 600;
|
|
|
+ position: absolute;
|
|
|
+ left: 50%;
|
|
|
+ top: 50%;
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+ pointer-events: none;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ {{ t.id + 1 }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ <div>
|
|
|
+ <furniture-icon
|
|
|
+ v-for="(item, index) in furnitureItems"
|
|
|
+ :key="index"
|
|
|
+ :icon="item.type"
|
|
|
+ :width="item.width"
|
|
|
+ :height="item.length"
|
|
|
+ :style="{
|
|
|
+ left: `${item.left}px`,
|
|
|
+ top: `${item.top}px`,
|
|
|
+ position: 'absolute',
|
|
|
+ rotate: `${item.rotate}deg`,
|
|
|
+ cursor: 'default',
|
|
|
+ pointerEvents: 'none',
|
|
|
+ }"
|
|
|
+ :draggable="false"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ v-if="furnitureItems && furnitureItems.some((item) => item.type === 'bed')"
|
|
|
+ class="breathLine"
|
|
|
+ >
|
|
|
+ <BreathLineChart :data="breathRpmList"></BreathLineChart>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </FullViewModal>
|
|
|
+
|
|
|
<info-card title="基本信息">
|
|
|
<template #extra>
|
|
|
<a-button type="primary" size="small" @click="roomConfigHandler('base')">
|
|
@@ -112,7 +187,14 @@
|
|
|
</info-item>
|
|
|
<info-item label="归属租户">{{ detailState.tenantName }}</info-item>
|
|
|
<info-item label="统计信息">
|
|
|
- <a-button type="link" size="small" @click="viewDeviceHistoryInfo"> 点击查看 </a-button>
|
|
|
+ <a-button
|
|
|
+ v-if="detailState.clientId"
|
|
|
+ type="link"
|
|
|
+ size="small"
|
|
|
+ @click="viewDeviceHistoryInfo"
|
|
|
+ >
|
|
|
+ 点击查看
|
|
|
+ </a-button>
|
|
|
</info-item>
|
|
|
</info-card>
|
|
|
|
|
@@ -176,6 +258,8 @@ import deviceConfigDrawer from './components/deviceConfig/index.vue'
|
|
|
import deviceStatsDrawer from './components/deviceStatsDrawer/index.vue'
|
|
|
import BreathLineChart from './components/breathLineChart/index.vue'
|
|
|
import { formatDateTime } from '@/utils'
|
|
|
+import { FullscreenOutlined } from '@ant-design/icons-vue'
|
|
|
+import FullViewModal from './components/fullViewModal/index.vue'
|
|
|
|
|
|
defineOptions({
|
|
|
name: 'DeviceDetail',
|
|
@@ -463,6 +547,8 @@ onUnmounted(() => {
|
|
|
if (mqttClient) mqttClient.end()
|
|
|
if (mqttTimeout) clearTimeout(mqttTimeout)
|
|
|
})
|
|
|
+
|
|
|
+const openFullView = ref(false)
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="less">
|
|
@@ -478,25 +564,48 @@ onUnmounted(() => {
|
|
|
border-radius: 10px;
|
|
|
display: flex;
|
|
|
flex-direction: row;
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- .radarBox {
|
|
|
- position: relative;
|
|
|
- background-image:
|
|
|
- linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),
|
|
|
- linear-gradient(to right, rgba(0, 0, 0, 0.1) 1px, transparent 1px);
|
|
|
- background-size: 20px 20px;
|
|
|
- border: 1px solid rgba(0, 0, 0, 0.8);
|
|
|
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
|
- overflow: hidden;
|
|
|
-
|
|
|
- .furniture-item {
|
|
|
- position: absolute;
|
|
|
- user-select: none;
|
|
|
- cursor: move;
|
|
|
- width: 30px;
|
|
|
- height: 30px;
|
|
|
- }
|
|
|
- }
|
|
|
+.radarBox {
|
|
|
+ position: relative;
|
|
|
+ background-image:
|
|
|
+ linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),
|
|
|
+ linear-gradient(to right, rgba(0, 0, 0, 0.1) 1px, transparent 1px);
|
|
|
+ background-size: 20px 20px;
|
|
|
+ border: 1px solid rgba(0, 0, 0, 0.8);
|
|
|
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .furniture-item {
|
|
|
+ position: absolute;
|
|
|
+ user-select: none;
|
|
|
+ cursor: move;
|
|
|
+ width: 30px;
|
|
|
+ height: 30px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.areaZoom {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+ cursor: pointer;
|
|
|
+ &:hover {
|
|
|
+ color: #1890ff;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.fullView {
|
|
|
+ margin-top: 50px;
|
|
|
+ .radarBox {
|
|
|
+ margin: auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .pointTitle {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ text-align: center;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -505,5 +614,6 @@ onUnmounted(() => {
|
|
|
flex-shrink: 0;
|
|
|
flex-grow: 1;
|
|
|
flex-basis: 350px;
|
|
|
+ position: relative;
|
|
|
}
|
|
|
</style>
|