Explorar o código

refactor(device): 提取坐标计算逻辑到工具函数并优化家具处理

将重复的坐标计算逻辑提取到工具函数getOriginPosition中,优化家具数据处理流程
移除重复代码,统一坐标计算方式,提高代码复用性和可维护性
liujia hai 1 mes
pai
achega
654cd3a69c

+ 62 - 0
src/utils/index.ts

@@ -1,3 +1,5 @@
+import { furnitureIconSizeMap } from '@/const/furniture'
+
 /**
  * 格式化秒数为年、月、日、时、分、秒的字符串表示
  * @param {number} seconds - 秒数
@@ -52,3 +54,63 @@ export function formatDateTime(d: Date) {
   const pad = (n: number) => String(n).padStart(2, '0')
   return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
 }
+
+/**
+ * 获取坐标位置
+ */
+/**
+ * 获取坐标位置
+ * @note 雷达的检测范围
+ * @param xstart x 开始坐标
+ * @param xend x 结束坐标
+ * @param ystart y 开始坐标
+ * @param yend y 结束坐标
+ * @note 配置家具时,点击的家具元素的坐标
+ * @param offsetLeft 元素基于父容器的X坐标
+ * @param offsetTop 元素基于父容器的Y坐标
+ */
+export const getOriginPosition = (
+  [xstart, xend, ystart, yend]: number[],
+  [offsetLeft, offsetTop]: number[]
+) => {
+  // 容器宽高
+  const containerWidth = Math.abs(xstart) + Math.abs(xend)
+  const containerHeight = Math.abs(ystart) + Math.abs(yend)
+
+  // 原点在容器中的坐标
+  const originX = Math.abs(xstart)
+  const originY = Math.abs(yend)
+
+  // 元素基于父容器的偏移量
+  const offsetX = offsetLeft ?? 0
+  const offsetY = offsetTop ?? 0
+
+  // 元素基于原点的偏移量
+  const originOffsetX = offsetX - originX
+  const originOffsetY = originY - offsetY
+
+  // 雷达尺寸
+  const radarWidth = furnitureIconSizeMap['radar']?.width ?? 0
+  const radarHeight = furnitureIconSizeMap['radar']?.height ?? 0
+
+  // 雷达基于原点的偏移量
+  const radarX = Math.round(originX - radarWidth / 2)
+  const radarY = Math.round(originY - radarHeight / 2)
+
+  const data = {
+    width: containerWidth, // 容器宽度
+    height: containerHeight, // 容器高度
+    originX: Math.round(originX), // 原点X坐标
+    originY: Math.round(originY), // 原点Y坐标
+    offsetX: Math.round(offsetX), // 元素基于父容器的偏移量 X坐标
+    offsetY: Math.round(offsetY), // 元素基于父容器的偏移量 Y坐标
+    originOffsetX: Math.round(originOffsetX), // 元素基于原点的偏移量 X坐标
+    originOffsetY: Math.round(originOffsetY), // 元素基于原点的偏移量 Y坐标
+    radarX, // 雷达X坐标
+    radarY, // 雷达Y坐标
+    radarWidth, // 雷达宽度
+    radarHeight, // 雷达高度
+  }
+
+  return data
+}

+ 6 - 53
src/views/device/detail/components/alarmPlanModal/index.vue

@@ -287,7 +287,7 @@
 import { ref, reactive, watch, computed } from 'vue'
 import { message, type FormInstance } from 'ant-design-vue'
 import * as alarmApi from '@/api/alarm'
-import { furnitureIconSizeMap } from '@/const/furniture'
+import { getOriginPosition } from '@/utils/index'
 
 defineOptions({
   name: 'AlarmPlanModal',
@@ -364,6 +364,9 @@ const areaHeight = computed(() => {
   return Math.abs(props.area?.height || 0)
 })
 
+// 获取原点坐标
+const { originX, originY } = getOriginPosition(props.area!.ranges, [0, 0])
+
 interface BlockItem {
   // 本地用
   x: number // 区块基于父元素的X偏移量,区块的左上角x坐标
@@ -376,56 +379,6 @@ interface BlockItem {
 
 const blocks = ref<BlockItem[]>([])
 
-/**
- * 获取坐标位置
- * @param offsetLeft 元素基于父容器的X坐标
- * @param offsetTop 元素基于父容器的Y坐标
- */
-const getOriginPosition = ([offsetLeft, offsetTop]: number[] = [0, 0]) => {
-  const [xstart, xend, ystart, yend] = props.area!.ranges
-
-  // 容器宽高
-  const containerWidth = Math.abs(xstart) + Math.abs(xend)
-  const containerHeight = Math.abs(ystart) + Math.abs(yend)
-
-  // 原点在容器中的坐标
-  const originX = Math.abs(xstart)
-  const originY = Math.abs(yend)
-
-  // 元素基于父容器的偏移量
-  const offsetX = offsetLeft ?? 0
-  const offsetY = offsetTop ?? 0
-
-  // 元素基于原点的偏移量
-  const originOffsetX = offsetX - originX
-  const originOffsetY = originY - offsetY
-
-  // 雷达尺寸
-  const radarWidth = furnitureIconSizeMap['radar']?.width ?? 0
-  const radarHeight = furnitureIconSizeMap['radar']?.height ?? 0
-
-  // 雷达基于原点的偏移量
-  const radarX = Math.round(originX - radarWidth / 2)
-  const radarY = Math.round(originY - radarHeight / 2)
-
-  const data = {
-    width: containerWidth, // 容器宽度
-    height: containerHeight, // 容器高度
-    originX: Math.round(originX), // 原点X坐标
-    originY: Math.round(originY), // 原点Y坐标
-    offsetX: Math.round(offsetX), // 元素基于父容器的偏移量 X坐标
-    offsetY: Math.round(offsetY), // 元素基于父容器的偏移量 Y坐标
-    originOffsetX: Math.round(originOffsetX), // 元素基于原点的偏移量 X坐标
-    originOffsetY: Math.round(originOffsetY), // 元素基于原点的偏移量 Y坐标
-    radarX, // 雷达X坐标
-    radarY, // 雷达Y坐标
-    radarWidth, // 雷达宽度
-    radarHeight, // 雷达高度
-  }
-
-  return data
-}
-
 // 区块拖动
 const startDrag = (block: BlockItem, e: MouseEvent) => {
   console.log('startDrag', block)
@@ -443,8 +396,8 @@ const startDrag = (block: BlockItem, e: MouseEvent) => {
 
     block.x = Math.max(0, Math.min(newX, containerWidth - block.width))
     block.y = Math.max(0, Math.min(newY, containerHeight - block.height))
-    block.ox = block.x - getOriginPosition().originX
-    block.oy = getOriginPosition().originY - block.y
+    block.ox = block.x - originX
+    block.oy = originY - block.y
   }
 
   const upHandler = () => {

+ 25 - 86
src/views/device/detail/components/deviceAreaConfig/index.vue

@@ -367,6 +367,7 @@ import {
   DeleteOutlined,
   QuestionCircleOutlined,
 } from '@ant-design/icons-vue'
+import { getOriginPosition } from '@/utils'
 
 defineOptions({
   name: 'deviceAreaConfig',
@@ -461,10 +462,10 @@ const fetchRoomLayout = async () => {
         blocks.value.push({
           // 本地需要使用的数据
           id: nanoid(),
-          x: item.startXx + getOriginPosition().originX,
-          y: getOriginPosition().originY - item.startYy,
-          ox: item.startXx + getOriginPosition().originX - getOriginPosition().originX,
-          oy: getOriginPosition().originY - item.startYy - getOriginPosition().originY,
+          x: item.startXx + originX,
+          y: originY - item.startYy,
+          ox: item.startXx + originX - originX,
+          oy: originY - item.startYy - originY,
           width: Math.abs(item.stopXx - item.startXx),
           height: Math.abs(item.stopYy - item.startYy),
           isDragging: false,
@@ -532,15 +533,6 @@ const addHnadler = (icon: FurnitureIconType) => {
     }
   }
 
-  const { originOffsetX, originOffsetY } = getOriginPosition()
-  console.log(
-    'originOffsetX',
-    originOffsetX,
-    'originOffsetY',
-    originOffsetY,
-    'data',
-    getOriginPosition()
-  )
   // 家具原始宽高
   const originWidth = furnitureIconSizeMap[icon].width || 30
   const originHeight = furnitureIconSizeMap[icon].height || 30
@@ -656,7 +648,6 @@ const onDragstartListItem = (event: DragEvent, item: CanvaseItem) => {
 // 家具列表元素结束拖拽
 const onDragendEndListItem = (event: DragEvent, item: CanvaseItem) => {
   item.isDragging = false
-  const { originOffsetX, originOffsetY } = getOriginPosition()
   if (currentDragItem.value) {
     currentDragItem.value.x = originOffsetX
     currentDragItem.value.y = originOffsetY
@@ -862,8 +853,8 @@ const handleMouseUp = () => {
       id: nanoid(),
       x: Math.round(Math.min(startX, currentX)),
       y: Math.round(Math.min(startY, currentY)),
-      ox: Math.round(Math.min(startX, currentX)) - getOriginPosition().originX,
-      oy: Math.round(Math.min(startY, currentY)) - getOriginPosition().originY,
+      ox: Math.round(Math.min(startX, currentX)) - originX,
+      oy: Math.round(Math.min(startY, currentY)) - originY,
       width,
       height,
       isDragging: false,
@@ -872,10 +863,10 @@ const handleMouseUp = () => {
       isTracking: false,
       isFalling: false,
       // 接口用
-      startXx: Math.round(Math.min(startX, currentX)) - getOriginPosition().originX,
-      stopXx: Math.round(Math.min(startX, currentX)) - getOriginPosition().originX + width,
-      startYy: Math.round(Math.min(startY, currentY)) - getOriginPosition().originY,
-      stopYy: Math.round(Math.min(startY, currentY)) - getOriginPosition().originY + height,
+      startXx: Math.round(Math.min(startX, currentX)) - originX,
+      stopXx: Math.round(Math.min(startX, currentX)) - originX + width,
+      startYy: Math.round(Math.min(startY, currentY)) - originY,
+      stopYy: Math.round(Math.min(startY, currentY)) - originY + height,
       startZz: 0,
       stopZz: 0,
       isLowSnr: 0,
@@ -913,8 +904,8 @@ const startDrag = (block: BlockItem, e: MouseEvent) => {
 
     block.x = Math.max(0, Math.min(newX, containerWidth - block.width))
     block.y = Math.max(0, Math.min(newY, containerHeight - block.height))
-    block.ox = block.x - getOriginPosition().originX
-    block.oy = getOriginPosition().originY - block.y
+    block.ox = block.x - originX
+    block.oy = originY - block.y
     block.startXx = block.ox
     block.stopXx = block.ox + block.width
     block.startYy = block.oy
@@ -974,66 +965,14 @@ const selectBlock = (block: BlockItem) => {
 //   }
 // }
 
-/**
- * 获取坐标位置
- * @param offsetLeft 元素基于父容器的X坐标
- * @param offsetTop 元素基于父容器的Y坐标
- */
-const getOriginPosition = (
-  [offsetLeft, offsetTop]: number[] = [
-    currentDragItem.value?.left as number,
-    currentDragItem.value?.top as number,
-  ]
-) => {
-  const [xstart, xend, ystart, yend] = props.ranges
-
-  // 容器宽高
-  const containerWidth = Math.abs(xstart) + Math.abs(xend)
-  const containerHeight = Math.abs(ystart) + Math.abs(yend)
-
-  // 原点在容器中的坐标
-  const originX = Math.abs(xstart)
-  const originY = Math.abs(yend)
-
-  // 元素基于父容器的偏移量
-  const offsetX = offsetLeft ?? 0
-  const offsetY = offsetTop ?? 0
-
-  // 元素基于原点的偏移量
-  const originOffsetX = offsetX - originX
-  const originOffsetY = originY - offsetY
-
-  // 雷达尺寸
-  const radarWidth = furnitureIconSizeMap['radar']?.width ?? 0
-  const radarHeight = furnitureIconSizeMap['radar']?.height ?? 0
-
-  // 雷达基于原点的偏移量
-  const radarX = Math.round(originX - radarWidth / 2)
-  const radarY = Math.round(originY - radarHeight / 2)
-
-  const data = {
-    width: containerWidth, // 容器宽度
-    height: containerHeight, // 容器高度
-    originX: Math.round(originX), // 原点X坐标
-    originY: Math.round(originY), // 原点Y坐标
-    offsetX: Math.round(offsetX), // 元素基于父容器的偏移量 X坐标
-    offsetY: Math.round(offsetY), // 元素基于父容器的偏移量 Y坐标
-    originOffsetX: Math.round(originOffsetX), // 元素基于原点的偏移量 X坐标
-    originOffsetY: Math.round(originOffsetY), // 元素基于原点的偏移量 Y坐标
-    radarX, // 雷达X坐标
-    radarY, // 雷达Y坐标
-    radarWidth, // 雷达宽度
-    radarHeight, // 雷达高度
-  }
-
-  return data
-}
+const { originX, originY, originOffsetX, originOffsetY, radarX, radarY } = getOriginPosition(
+  props.ranges,
+  [currentDragItem.value?.left as number, currentDragItem.value?.top as number]
+)
 
 // 初始化添加雷达图标
 const initRadarIcon = () => {
   console.log('initRadarIcon', mapCanvasList.value, furnitureItems.value)
-  const { radarX, radarY, originOffsetX, originOffsetY } = getOriginPosition()
-  console.log(11111111, getOriginPosition())
   // 在家具地图添加雷达图标
   mapCanvasList.value.push({
     name: '雷达',
@@ -1176,20 +1115,20 @@ const startResize = (block: BlockItem, e: MouseEvent) => {
 const blockInputPressEnter = (e: Event, el: BlockItem, attr: string) => {
   if (attr === 'startXx') {
     el.startXx = Number(el[attr as keyof BlockItem])
-    el.x = el.startXx + getOriginPosition().originX
+    el.x = el.startXx + originX
   }
   if (attr === 'stopXx') {
     el.stopXx = Number(el[attr as keyof BlockItem])
-    el.width = el.stopXx + getOriginPosition().originX - el.width
+    el.width = el.stopXx + originX - el.width
   }
 
   if (attr === 'startYy') {
     el.startYy = Number(el[attr as keyof BlockItem])
-    el.x = el.startYy + getOriginPosition().originY
+    el.x = el.startYy + originY
   }
   if (attr === 'stopYy') {
     el.stopYy = Number(el[attr as keyof BlockItem])
-    el.height = el.stopYy + getOriginPosition().originY - el.height
+    el.height = el.stopYy + originY - el.height
   }
 }
 
@@ -1197,20 +1136,20 @@ const blockInputBlur = (e: Event, el: BlockItem, attr: string) => {
   console.log('blockInputBlur', e, el, attr)
   if (attr === 'startXx') {
     el.startXx = Number(el[attr as keyof BlockItem])
-    el.x = el.startXx + getOriginPosition().originX
+    el.x = el.startXx + originX
   }
   if (attr === 'stopXx') {
     el.stopXx = Number(el[attr as keyof BlockItem])
-    el.width = el.stopXx + getOriginPosition().originX - el.width
+    el.width = el.stopXx + originX - el.width
   }
 
   if (attr === 'startYy') {
     el.startYy = Number(el[attr as keyof BlockItem])
-    el.x = el.startYy + getOriginPosition().originY
+    el.x = el.startYy + originY
   }
   if (attr === 'stopYy') {
     el.stopYy = Number(el[attr as keyof BlockItem])
-    el.height = el.stopYy + getOriginPosition().originY - el.height
+    el.height = el.stopYy + originY - el.height
   }
 }
 

+ 30 - 3
src/views/device/detail/index.vue

@@ -333,6 +333,7 @@ import { EditOutlined, DeleteOutlined } from '@ant-design/icons-vue'
 import * as alarmApi from '@/api/alarm'
 import { Empty } from 'ant-design-vue'
 const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE
+import { getOriginPosition } from '@/utils'
 
 defineOptions({
   name: 'DeviceDetail',
@@ -378,8 +379,9 @@ const fetchRoomLayout = async () => {
     if (!res) return
     const { furnitures, roomId, subRegions } = res.data
     if (furnitures) {
-      furnitureItems.value = furnitures!.map((item) => {
-        return {
+      // 添加接口返回的家具数据
+      furnitures!.forEach((item) => {
+        furnitureItems.value.push({
           ...item,
           width: item.width || 45,
           length: item.length || 45,
@@ -388,7 +390,7 @@ const fetchRoomLayout = async () => {
           rotate: item.rotate || 0,
           x: item.x || 0,
           y: item.y || 0,
-        }
+        })
       })
     }
     deviceRoomId.value = roomId || ''
@@ -453,6 +455,31 @@ const fetchDeviceDetail = async () => {
     console.log('✅获取到设备详情', res)
     detailState.value = res.data
     spinning.value = false
+
+    // 获取雷达图标尺寸
+    const { radarX, radarY, radarWidth, radarHeight, originOffsetX, originOffsetY } =
+      getOriginPosition(
+        [
+          res.data.xxStart as number,
+          res.data.xxEnd as number,
+          res.data.yyStart as number,
+          res.data.yyEnd as number,
+        ],
+        [0, 0]
+      )
+
+    // 添加雷达图标
+    furnitureItems.value.unshift({
+      name: '雷达',
+      type: 'radar',
+      width: radarWidth,
+      length: radarHeight,
+      top: radarY,
+      left: radarX,
+      x: originOffsetX,
+      y: originOffsetY,
+      rotate: 0,
+    })
   } catch (error) {
     console.error('❌获取设备详情失败', error)
     spinning.value = false