|
@@ -247,9 +247,51 @@
|
|
name="region"
|
|
name="region"
|
|
style="user-select: none"
|
|
style="user-select: none"
|
|
>
|
|
>
|
|
- <span style="user-select: none">框选区域 {{ formState.region }}</span>
|
|
|
|
|
|
+ <div>雷达检测区域:{{ props.area!.ranges }}</div>
|
|
|
|
+ <div style="user-select: none">
|
|
|
|
+ <span>告警框选区域: {{ formState.region }}</span>
|
|
|
|
+ <a-button type="link" style="margin-left: 16px" @click="resetBlocks"> 重置 </a-button>
|
|
|
|
+ </div>
|
|
<a-form-item-rest>
|
|
<a-form-item-rest>
|
|
- <div class="viewer">
|
|
|
|
|
|
+ <baseAreaViewer
|
|
|
|
+ :width="areaWidth"
|
|
|
|
+ :length="areaHeight"
|
|
|
|
+ :furnitureItems="furnitureItems"
|
|
|
|
+ :ranges="props?.area?.ranges ?? []"
|
|
|
|
+ class="blockArea"
|
|
|
|
+ >
|
|
|
|
+ <div
|
|
|
|
+ v-for="(block, blockIndex) in blocks"
|
|
|
|
+ :key="blockIndex"
|
|
|
|
+ class="block-item"
|
|
|
|
+ :style="{
|
|
|
|
+ left: `${block.x}px`,
|
|
|
|
+ top: `${block.y}px`,
|
|
|
|
+ width: `${block.width}px`,
|
|
|
|
+ height: `${block.height}px`,
|
|
|
|
+ border: `2px solid #1890ff`,
|
|
|
|
+ position: 'absolute',
|
|
|
|
+ cursor: 'move',
|
|
|
|
+ backgroundColor: 'rgba(24, 144, 255, 0.1)',
|
|
|
|
+ }"
|
|
|
|
+ @mousedown="startDrag(block, $event)"
|
|
|
|
+ >
|
|
|
|
+ <div
|
|
|
|
+ class="resize-handle"
|
|
|
|
+ :style="{
|
|
|
|
+ backgroundColor: '#1890ff',
|
|
|
|
+ }"
|
|
|
|
+ @mousedown.stop="startResize(block, $event)"
|
|
|
|
+ >
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </baseAreaViewer>
|
|
|
|
+
|
|
|
|
+ {{ blocks[0] }}
|
|
|
|
+
|
|
|
|
+ {{ getOriginPosition(props.area!.ranges, [0, 0]) }}
|
|
|
|
+
|
|
|
|
+ <!-- <div class="viewer">
|
|
<div class="viewer-content">
|
|
<div class="viewer-content">
|
|
<div
|
|
<div
|
|
class="mapBox blockArea"
|
|
class="mapBox blockArea"
|
|
@@ -259,7 +301,6 @@
|
|
cursor: 'default',
|
|
cursor: 'default',
|
|
}"
|
|
}"
|
|
>
|
|
>
|
|
- <!-- 已创建区块 -->
|
|
|
|
<div
|
|
<div
|
|
v-for="(block, blockIndex) in blocks"
|
|
v-for="(block, blockIndex) in blocks"
|
|
:key="blockIndex"
|
|
:key="blockIndex"
|
|
@@ -289,7 +330,7 @@
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
|
|
+ </div> -->
|
|
</a-form-item-rest>
|
|
</a-form-item-rest>
|
|
</a-form-item>
|
|
</a-form-item>
|
|
|
|
|
|
@@ -315,13 +356,15 @@
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
-import { ref, reactive, watch, computed } from 'vue'
|
|
|
|
|
|
+import { ref, reactive, watch, computed, nextTick } from 'vue'
|
|
import { message, type FormInstance, type SelectProps } from 'ant-design-vue'
|
|
import { message, type FormInstance, type SelectProps } from 'ant-design-vue'
|
|
import * as alarmApi from '@/api/alarm'
|
|
import * as alarmApi from '@/api/alarm'
|
|
import { getOriginPosition } from '@/utils/index'
|
|
import { getOriginPosition } from '@/utils/index'
|
|
import type { AlarmPlanParams } from '@/api/alarm/types'
|
|
import type { AlarmPlanParams } from '@/api/alarm/types'
|
|
import dayjs from 'dayjs'
|
|
import dayjs from 'dayjs'
|
|
import { debounce } from 'lodash-es'
|
|
import { debounce } from 'lodash-es'
|
|
|
|
+import * as roomApi from '@/api/room'
|
|
|
|
+import type { Furniture } from '@/api/room/types'
|
|
|
|
|
|
defineOptions({
|
|
defineOptions({
|
|
name: 'AlarmPlanModal',
|
|
name: 'AlarmPlanModal',
|
|
@@ -369,9 +412,10 @@ type Props = {
|
|
data?: AlarmPlan // 编辑数据
|
|
data?: AlarmPlan // 编辑数据
|
|
area?: {
|
|
area?: {
|
|
width: number
|
|
width: number
|
|
- height: number
|
|
|
|
|
|
+ length: number
|
|
ranges: number[]
|
|
ranges: number[]
|
|
}
|
|
}
|
|
|
|
+ devId?: string // 设备ID
|
|
}
|
|
}
|
|
const emit = defineEmits<{
|
|
const emit = defineEmits<{
|
|
(e: 'update:open', value: boolean): void
|
|
(e: 'update:open', value: boolean): void
|
|
@@ -387,21 +431,17 @@ const props = withDefaults(defineProps<Props>(), {
|
|
data: undefined,
|
|
data: undefined,
|
|
})
|
|
})
|
|
|
|
|
|
-// const modelTitle = computed(() => {
|
|
|
|
-// return props.alarmPlanId ? '编辑告警计划' : '新增告警计划'
|
|
|
|
-// })
|
|
|
|
-
|
|
|
|
// 检测区域宽度
|
|
// 检测区域宽度
|
|
const areaWidth = computed(() => {
|
|
const areaWidth = computed(() => {
|
|
- return Math.abs(props.area?.width || 0)
|
|
|
|
|
|
+ return Math.abs(props.area?.length || 0)
|
|
})
|
|
})
|
|
// 检测区域高度
|
|
// 检测区域高度
|
|
const areaHeight = computed(() => {
|
|
const areaHeight = computed(() => {
|
|
- return Math.abs(props.area?.height || 0)
|
|
|
|
|
|
+ return Math.abs(props.area?.width || 0)
|
|
})
|
|
})
|
|
|
|
|
|
// 获取原点坐标
|
|
// 获取原点坐标
|
|
-const { originX, originY } = getOriginPosition(props.area!.ranges, [0, 0])
|
|
|
|
|
|
+const { originOffsetX, originOffsetY } = getOriginPosition(props.area!.ranges, [0, 0])
|
|
|
|
|
|
interface BlockItem {
|
|
interface BlockItem {
|
|
// 本地用
|
|
// 本地用
|
|
@@ -417,7 +457,8 @@ const blocks = ref<BlockItem[]>([])
|
|
|
|
|
|
// 区块拖动
|
|
// 区块拖动
|
|
const startDrag = (block: BlockItem, e: MouseEvent) => {
|
|
const startDrag = (block: BlockItem, e: MouseEvent) => {
|
|
- console.log('startDrag', block)
|
|
|
|
|
|
+ const { originX, originY } = getOriginPosition(props.area!.ranges, [0, 0])
|
|
|
|
+
|
|
e.stopPropagation()
|
|
e.stopPropagation()
|
|
const container = document.querySelector('.blockArea') as HTMLElement
|
|
const container = document.querySelector('.blockArea') as HTMLElement
|
|
const rect = container.getBoundingClientRect()
|
|
const rect = container.getBoundingClientRect()
|
|
@@ -434,6 +475,9 @@ const startDrag = (block: BlockItem, e: MouseEvent) => {
|
|
block.y = Math.max(0, Math.min(newY, containerHeight - block.height))
|
|
block.y = Math.max(0, Math.min(newY, containerHeight - block.height))
|
|
block.ox = block.x - originX
|
|
block.ox = block.x - originX
|
|
block.oy = originY - block.y
|
|
block.oy = originY - block.y
|
|
|
|
+ // block.ox = block.x - originOffsetX
|
|
|
|
+ // block.oy = originOffsetY - block.y
|
|
|
|
+ formState.region = [block.ox, block.oy, block.width, block.height]
|
|
}
|
|
}
|
|
|
|
|
|
const upHandler = () => {
|
|
const upHandler = () => {
|
|
@@ -445,13 +489,13 @@ const startDrag = (block: BlockItem, e: MouseEvent) => {
|
|
document.addEventListener('mouseup', upHandler)
|
|
document.addEventListener('mouseup', upHandler)
|
|
}
|
|
}
|
|
|
|
|
|
-const drag = (block: BlockItem) => {
|
|
|
|
- formState.region = [block.ox, block.oy, block.width, block.height]
|
|
|
|
-}
|
|
|
|
|
|
+// const drag = (block: BlockItem) => {
|
|
|
|
+// formState.region = [block.ox, block.oy, block.width, block.height]
|
|
|
|
+// }
|
|
|
|
|
|
-const endDrag = (block: BlockItem) => {
|
|
|
|
- formState.region = [block.ox, block.oy, block.width, block.height]
|
|
|
|
-}
|
|
|
|
|
|
+// const endDrag = (block: BlockItem) => {
|
|
|
|
+// formState.region = [block.ox, block.oy, block.width, block.height]
|
|
|
|
+// }
|
|
|
|
|
|
// 获取容器边界
|
|
// 获取容器边界
|
|
const getContainerRect = () => {
|
|
const getContainerRect = () => {
|
|
@@ -472,6 +516,7 @@ const startResize = (block: BlockItem, e: MouseEvent) => {
|
|
// 限制最小尺寸和容器边界
|
|
// 限制最小尺寸和容器边界
|
|
block.width = Math.max(0, Math.min(initialWidth + deltaX, rect.width - block.x))
|
|
block.width = Math.max(0, Math.min(initialWidth + deltaX, rect.width - block.x))
|
|
block.height = Math.max(0, Math.min(initialHeight + deltaY, rect.height - block.y))
|
|
block.height = Math.max(0, Math.min(initialHeight + deltaY, rect.height - block.y))
|
|
|
|
+ formState.region = [block.ox, block.oy, block.width, block.height]
|
|
}
|
|
}
|
|
|
|
|
|
const upHandler = () => {
|
|
const upHandler = () => {
|
|
@@ -510,7 +555,7 @@ type FormState = {
|
|
|
|
|
|
const formState = reactive<FormState>({
|
|
const formState = reactive<FormState>({
|
|
planName: '',
|
|
planName: '',
|
|
- region: [0, 0, 50, 50],
|
|
|
|
|
|
+ region: [originOffsetX, originOffsetY, 50, 50],
|
|
eventType: null,
|
|
eventType: null,
|
|
thresholdTime: 300,
|
|
thresholdTime: 300,
|
|
mergeTime: 30,
|
|
mergeTime: 30,
|
|
@@ -596,11 +641,18 @@ const handleSearch = (val: string) => {
|
|
fetchTemplateList(val)
|
|
fetchTemplateList(val)
|
|
}
|
|
}
|
|
|
|
|
|
-const initBlocks = () => {
|
|
|
|
|
|
+const initBlocks = async () => {
|
|
|
|
+ const { originX, originY, originOffsetX, originOffsetY } = getOriginPosition(
|
|
|
|
+ props.area!.ranges,
|
|
|
|
+ [0, 0]
|
|
|
|
+ )
|
|
|
|
+ console.log('🚀🚀🚀🚀initBlocks', originX, originY, originOffsetX, originOffsetY)
|
|
|
|
+ await nextTick()
|
|
|
|
+ formState.region = [0, 0, 50, 50]
|
|
blocks.value = [
|
|
blocks.value = [
|
|
{
|
|
{
|
|
- x: 0,
|
|
|
|
- y: 0,
|
|
|
|
|
|
+ x: originX,
|
|
|
|
+ y: originY,
|
|
ox: formState.region[0],
|
|
ox: formState.region[0],
|
|
oy: formState.region[1],
|
|
oy: formState.region[1],
|
|
width: formState.region[2],
|
|
width: formState.region[2],
|
|
@@ -608,7 +660,10 @@ const initBlocks = () => {
|
|
},
|
|
},
|
|
]
|
|
]
|
|
}
|
|
}
|
|
-initBlocks()
|
|
|
|
|
|
+
|
|
|
|
+const resetBlocks = () => {
|
|
|
|
+ initBlocks()
|
|
|
|
+}
|
|
|
|
|
|
const thresholdTimeFormat = ref<'s' | 'min' | 'hour' | 'day'>('s') // 触发阈值 额外选择器
|
|
const thresholdTimeFormat = ref<'s' | 'min' | 'hour' | 'day'>('s') // 触发阈值 额外选择器
|
|
const timeThresholdFormat = ref<'s' | 'min' | 'hour' | 'day'>('s') // 异常消失时间阈值 额外选择器
|
|
const timeThresholdFormat = ref<'s' | 'min' | 'hour' | 'day'>('s') // 异常消失时间阈值 额外选择器
|
|
@@ -790,7 +845,18 @@ watch(
|
|
formState.region = echoFormState(val).region
|
|
formState.region = echoFormState(val).region
|
|
formState.enable = echoFormState(val).enable
|
|
formState.enable = echoFormState(val).enable
|
|
formState.linkagePushWechatService = echoFormState(val).linkagePushWechatService
|
|
formState.linkagePushWechatService = echoFormState(val).linkagePushWechatService
|
|
- initBlocks()
|
|
|
|
|
|
+ const { originOffsetX, originOffsetY } = getOriginPosition(props.area!.ranges, [0, 0])
|
|
|
|
+ blocks.value = [
|
|
|
|
+ {
|
|
|
|
+ x: formState.region[0] - originOffsetX,
|
|
|
|
+ y: originOffsetY - formState.region[1],
|
|
|
|
+ ox: formState.region[0],
|
|
|
|
+ oy: formState.region[1],
|
|
|
|
+ width: formState.region[2],
|
|
|
|
+ height: formState.region[3],
|
|
|
|
+ },
|
|
|
|
+ ]
|
|
|
|
+ console.log('🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥')
|
|
}
|
|
}
|
|
if (value && props.type === 'plan') {
|
|
if (value && props.type === 'plan') {
|
|
fetchTemplateList()
|
|
fetchTemplateList()
|
|
@@ -843,7 +909,7 @@ const cancel = () => {
|
|
emit('update:open', false)
|
|
emit('update:open', false)
|
|
// 重置表单
|
|
// 重置表单
|
|
formState.planName = ''
|
|
formState.planName = ''
|
|
- formState.region = [0, 0, 50, 50]
|
|
|
|
|
|
+ formState.region = [originOffsetX, originOffsetY, 50, 50]
|
|
formState.eventType = null
|
|
formState.eventType = null
|
|
formState.thresholdTime = 300
|
|
formState.thresholdTime = 300
|
|
formState.mergeTime = 30
|
|
formState.mergeTime = 30
|
|
@@ -860,6 +926,7 @@ const cancel = () => {
|
|
formState.timeThreshold = 300
|
|
formState.timeThreshold = 300
|
|
formState.remark = ''
|
|
formState.remark = ''
|
|
planTemplateId.value = null
|
|
planTemplateId.value = null
|
|
|
|
+ initBlocks()
|
|
}
|
|
}
|
|
|
|
|
|
const eventTypeList = ref<{ label: string; value: string }[]>([])
|
|
const eventTypeList = ref<{ label: string; value: string }[]>([])
|
|
@@ -1060,6 +1127,45 @@ const saveTemplate = async (params: AlarmPlanParams) => {
|
|
message.error('添加失败')
|
|
message.error('添加失败')
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+const furnitureItems = ref<Furniture[]>([])
|
|
|
|
+const devId = ref<string | undefined>(props.devId)
|
|
|
|
+/**
|
|
|
|
+ * 获取房间布局
|
|
|
|
+ */
|
|
|
|
+const fetchRoomLayout = async () => {
|
|
|
|
+ console.log('fetchRoomLayout', devId.value)
|
|
|
|
+ if (!devId.value) {
|
|
|
|
+ furnitureItems.value = []
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ const res = await roomApi.queryRoomInfo({
|
|
|
|
+ devId: devId.value,
|
|
|
|
+ })
|
|
|
|
+ console.log('✅获取到房间布局信息', res)
|
|
|
|
+ if (!res) return
|
|
|
|
+ const { furnitures } = res.data
|
|
|
|
+ if (furnitures) {
|
|
|
|
+ // 添加接口返回的家具数据
|
|
|
|
+ furnitures!.forEach((item) => {
|
|
|
|
+ furnitureItems.value.push({
|
|
|
|
+ ...item,
|
|
|
|
+ width: item.width || 45,
|
|
|
|
+ length: item.length || 45,
|
|
|
|
+ top: item.top || 0,
|
|
|
|
+ left: item.left || 0,
|
|
|
|
+ rotate: item.rotate || 0,
|
|
|
|
+ x: item.x || 0,
|
|
|
|
+ y: item.y || 0,
|
|
|
|
+ })
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('❌获取房间布局信息失败', error)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+fetchRoomLayout()
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style scoped lang="less">
|
|
<style scoped lang="less">
|