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
|
||||
|
||||
# 开发环境token配置 - 可以手动设置或从另一个项目获取后填入
|
||||
ENV_DEV_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3NjQxNjM2MzIsInVzZXJuYW1lIjoiYWRtaW4ifQ.IC24_YwD10DPM6PYyB-aBHoN4BMmDnQYe_8ZGI-Cyzg
|
||||
ENV_DEV_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3NjQ3MDExNDcsInVzZXJuYW1lIjoiYWRtaW4ifQ.NHLOjXm9JblCXXaDmc8PRvqB-uIpjwltrFh2EH4usIc
|
||||
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">
|
||||
import { type DeviceMappingDTO,queryDeviceMappingByType } from '@api/device';
|
||||
import { type MapAreaInfo, MapAreaType, type MapPen, MapPointType } from '@api/map';
|
||||
import { DOOR_AREA_TYPE } from '@api/map/door-area';
|
||||
import type { PointBindModalRef } from '@common/modal/point-bind-modal.vue';
|
||||
import type { EditorService } from '@core/editor.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';
|
||||
|
||||
type Props = {
|
||||
@ -54,6 +55,60 @@ const points = computed<MapPen[]>(
|
||||
);
|
||||
|
||||
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>
|
||||
|
||||
<template>
|
||||
@ -196,21 +251,22 @@ const actions = computed<MapPen[]>(() => points.value?.filter(({ point }) => poi
|
||||
<a-typography-text>{{ $t('设备ID') }}:</a-typography-text>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-input
|
||||
:placeholder="$t('请输入设备ID')"
|
||||
:value="area.doorDeviceId"
|
||||
@change="
|
||||
(e: any) => {
|
||||
const v = e?.target?.value;
|
||||
editor.updateArea(id, { doorDeviceId: v });
|
||||
(area.routes || []).forEach((rid: string) => {
|
||||
const rpen = editor.getPenById(rid) as any;
|
||||
const merged = { ...(rpen?.route || {}), deviceId: v };
|
||||
editor.updatePen(rid, { route: merged }, true);
|
||||
});
|
||||
}
|
||||
"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="selectedDeviceId"
|
||||
:placeholder="$t('请选择设备')"
|
||||
:loading="loading"
|
||||
allow-clear
|
||||
@change="handleDeviceChange"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="device in deviceMappings"
|
||||
:key="device.id"
|
||||
:value="device.id"
|
||||
:label="device.deviceUniqueName"
|
||||
>
|
||||
{{ device.deviceUniqueName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user