feat(area-edit): 将门区域设备ID输入框改为下拉选择,通过查询设备映射列表实现设备绑定以提升用户体验
This commit is contained in:
parent
db5b2275f7
commit
22cf89f7e9
@ -4,5 +4,5 @@ ENV_WEBSOCKET_BASE=/ws
|
|||||||
ENV_STORAGE_WEBSOCKET_BASE=/vwedWs
|
ENV_STORAGE_WEBSOCKET_BASE=/vwedWs
|
||||||
|
|
||||||
# 开发环境token配置 - 可以手动设置或从另一个项目获取后填入
|
# 开发环境token配置 - 可以手动设置或从另一个项目获取后填入
|
||||||
ENV_DEV_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3NjQxNjM2MzIsInVzZXJuYW1lIjoiYWRtaW4ifQ.IC24_YwD10DPM6PYyB-aBHoN4BMmDnQYe_8ZGI-Cyzg
|
ENV_DEV_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3NjQ3MDExNDcsInVzZXJuYW1lIjoiYWRtaW4ifQ.NHLOjXm9JblCXXaDmc8PRvqB-uIpjwltrFh2EH4usIc
|
||||||
ENV_DEV_TENANT_ID=1000
|
ENV_DEV_TENANT_ID=1000
|
||||||
|
|||||||
48
src/apis/device/api.ts
Normal file
48
src/apis/device/api.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import http from '@core/http';
|
||||||
|
|
||||||
|
const enum API {
|
||||||
|
根据设备类型查询 = '/device/mapping/queryByType',
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备映射数据传输对象
|
||||||
|
*/
|
||||||
|
export interface DeviceMappingDTO {
|
||||||
|
id: string;
|
||||||
|
deviceUniqueName: string;
|
||||||
|
protocolType: string;
|
||||||
|
mappingType: string;
|
||||||
|
brandName: string | null;
|
||||||
|
ipAddress: string | null;
|
||||||
|
port: number;
|
||||||
|
slaveId: number;
|
||||||
|
enabled: number;
|
||||||
|
sceneId: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备类型映射
|
||||||
|
*/
|
||||||
|
export const DeviceTypeMapping = {
|
||||||
|
'0': '非保持呼叫器',
|
||||||
|
'4': '保持呼叫器',
|
||||||
|
'1': '门',
|
||||||
|
'2': '电梯',
|
||||||
|
'3': '光电传感器'
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据设备类型查询所有映射关系
|
||||||
|
* @param type 设备类型(必填)
|
||||||
|
* @returns DeviceMappingDTO[] 设备映射列表
|
||||||
|
*/
|
||||||
|
export async function queryDeviceMappingByType(type: string): Promise<DeviceMappingDTO[]> {
|
||||||
|
type ResponseType = DeviceMappingDTO[];
|
||||||
|
try {
|
||||||
|
const response = await http.get<ResponseType>(`${API.根据设备类型查询}?type=${type}`);
|
||||||
|
return response || [];
|
||||||
|
} catch (error) {
|
||||||
|
console.error('根据设备类型查询映射关系失败:', error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/apis/device/index.ts
Normal file
1
src/apis/device/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './api';
|
||||||
@ -1,10 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { type DeviceMappingDTO,queryDeviceMappingByType } from '@api/device';
|
||||||
import { type MapAreaInfo, MapAreaType, type MapPen, MapPointType } from '@api/map';
|
import { type MapAreaInfo, MapAreaType, type MapPen, MapPointType } from '@api/map';
|
||||||
import { DOOR_AREA_TYPE } from '@api/map/door-area';
|
import { DOOR_AREA_TYPE } from '@api/map/door-area';
|
||||||
import type { PointBindModalRef } from '@common/modal/point-bind-modal.vue';
|
import type { PointBindModalRef } from '@common/modal/point-bind-modal.vue';
|
||||||
import type { EditorService } from '@core/editor.service';
|
import type { EditorService } from '@core/editor.service';
|
||||||
import sTheme from '@core/theme.service';
|
import sTheme from '@core/theme.service';
|
||||||
import { ref, shallowRef } from 'vue';
|
import { ref, shallowRef, watch } from 'vue';
|
||||||
import { computed, inject, type InjectionKey, type ShallowRef } from 'vue';
|
import { computed, inject, type InjectionKey, type ShallowRef } from 'vue';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -54,6 +55,60 @@ const points = computed<MapPen[]>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const actions = computed<MapPen[]>(() => points.value?.filter(({ point }) => point?.type === MapPointType.动作点));
|
const actions = computed<MapPen[]>(() => points.value?.filter(({ point }) => point?.type === MapPointType.动作点));
|
||||||
|
|
||||||
|
// 设备映射相关状态
|
||||||
|
const deviceMappings = ref<DeviceMappingDTO[]>([]);
|
||||||
|
const selectedDeviceId = ref<string>('');
|
||||||
|
const loading = ref<boolean>(false);
|
||||||
|
|
||||||
|
// 根据门类型获取设备映射
|
||||||
|
const fetchDeviceMappings = async () => {
|
||||||
|
if (!area.value || (area.value?.type as any) !== DOOR_AREA_TYPE) return;
|
||||||
|
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
// 根据门类型获取对应的设备映射
|
||||||
|
const deviceType = '1'; // 门的类型是"1"
|
||||||
|
deviceMappings.value = await queryDeviceMappingByType(deviceType);
|
||||||
|
|
||||||
|
// 如果当前有绑定的设备ID,设置选中值
|
||||||
|
if (area.value.doorDeviceId) {
|
||||||
|
selectedDeviceId.value = area.value.doorDeviceId;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取设备映射失败:', error);
|
||||||
|
deviceMappings.value = [];
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听区域变化,获取设备映射
|
||||||
|
watch(area, (newArea) => {
|
||||||
|
if (newArea && (newArea.type as any) === DOOR_AREA_TYPE) {
|
||||||
|
fetchDeviceMappings();
|
||||||
|
}
|
||||||
|
}, { immediate: true });
|
||||||
|
|
||||||
|
// 设备选择变化处理函数
|
||||||
|
const handleDeviceChange = (deviceId: string) => {
|
||||||
|
if (!props.id) return;
|
||||||
|
|
||||||
|
selectedDeviceId.value = deviceId;
|
||||||
|
|
||||||
|
// 更新区域信息,保存设备ID
|
||||||
|
editor.value.updateArea(props.id, { doorDeviceId: deviceId });
|
||||||
|
|
||||||
|
// 同时更新关联路段的设备ID
|
||||||
|
if (area.value?.routes) {
|
||||||
|
area.value.routes.forEach((rid: string) => {
|
||||||
|
const rpen = editor.value.getPenById(rid) as any;
|
||||||
|
const merged = { ...(rpen?.route || {}), deviceId };
|
||||||
|
editor.value.updatePen(rid, { route: merged }, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -196,21 +251,22 @@ const actions = computed<MapPen[]>(() => points.value?.filter(({ point }) => poi
|
|||||||
<a-typography-text>{{ $t('设备ID') }}:</a-typography-text>
|
<a-typography-text>{{ $t('设备ID') }}:</a-typography-text>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-input
|
<a-select
|
||||||
:placeholder="$t('请输入设备ID')"
|
v-model:value="selectedDeviceId"
|
||||||
:value="area.doorDeviceId"
|
:placeholder="$t('请选择设备')"
|
||||||
@change="
|
:loading="loading"
|
||||||
(e: any) => {
|
allow-clear
|
||||||
const v = e?.target?.value;
|
@change="handleDeviceChange"
|
||||||
editor.updateArea(id, { doorDeviceId: v });
|
>
|
||||||
(area.routes || []).forEach((rid: string) => {
|
<a-select-option
|
||||||
const rpen = editor.getPenById(rid) as any;
|
v-for="device in deviceMappings"
|
||||||
const merged = { ...(rpen?.route || {}), deviceId: v };
|
:key="device.id"
|
||||||
editor.updatePen(rid, { route: merged }, true);
|
:value="device.id"
|
||||||
});
|
:label="device.deviceUniqueName"
|
||||||
}
|
>
|
||||||
"
|
{{ device.deviceUniqueName }}
|
||||||
/>
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user