| src/api/device-setting/index.js | ●●●●● patch | view | raw | blame | history | |
| src/types/device-setting.js | ●●●●● patch | view | raw | blame | history | |
| src/utils/device-setting.js | ●●●●● patch | view | raw | blame | history | |
| src/views/device/components/DeviceSettingBox.vue | ●●●●● patch | view | raw | blame | history | |
| src/views/device/components/DeviceSettingPopover.vue | ●●●●● patch | view | raw | blame | history | |
| src/views/device/components/use-device-setting.js | ●●●●● patch | view | raw | blame | history |
src/api/device-setting/index.js
New file @@ -0,0 +1,23 @@ /* * @Author: shuishen 1109946754@qq.com * @Date: 2024-09-13 20:01:59 * @LastEditors: shuishen 1109946754@qq.com * @LastEditTime: 2024-09-13 20:08:09 * @FilePath: \drone-web-manage\src\api\device-setting\index.js * @Description: * * Copyright (c) 2024 by shuishen, All Rights Reserved. */ import request from '@/axios'; import { ELocalStorageKey } from '@/types'; const workspaceId = localStorage.getItem(ELocalStorageKey.WorkspaceId) || ''; export const putDeviceProps = (deviceSn, body) => { return request({ url: `/drone-yw/manage/api/v1/devices/${workspaceId}/devices/${deviceSn}/property`, method: 'put', body, }); }; src/types/device-setting.js
New file @@ -0,0 +1,141 @@ // 夜航灯开关 export let NightLightsStateEnum ;(function(NightLightsStateEnum) { NightLightsStateEnum[(NightLightsStateEnum["CLOSE"] = 0)] = "CLOSE" NightLightsStateEnum[(NightLightsStateEnum["OPEN"] = 1)] = "OPEN" })(NightLightsStateEnum || (NightLightsStateEnum = {})) // 限远开关 export let DistanceLimitStatusEnum ;(function(DistanceLimitStatusEnum) { DistanceLimitStatusEnum[(DistanceLimitStatusEnum["UNSET"] = 0)] = "UNSET" DistanceLimitStatusEnum[(DistanceLimitStatusEnum["SET"] = 1)] = "SET" })(DistanceLimitStatusEnum || (DistanceLimitStatusEnum = {})) // 避障 export let ObstacleAvoidanceStatusEnum ;(function(ObstacleAvoidanceStatusEnum) { ObstacleAvoidanceStatusEnum[(ObstacleAvoidanceStatusEnum["CLOSE"] = 0)] = "CLOSE" ObstacleAvoidanceStatusEnum[(ObstacleAvoidanceStatusEnum["OPEN"] = 1)] = "OPEN" })(ObstacleAvoidanceStatusEnum || (ObstacleAvoidanceStatusEnum = {})) // 设备管理设置key export let DeviceSettingKeyEnum ;(function(DeviceSettingKeyEnum) { DeviceSettingKeyEnum["NIGHT_LIGHTS_MODE_SET"] = "night_lights_state" DeviceSettingKeyEnum["HEIGHT_LIMIT_SET"] = "height_limit" DeviceSettingKeyEnum["DISTANCE_LIMIT_SET"] = "distance_limit_status" DeviceSettingKeyEnum["OBSTACLE_AVOIDANCE_HORIZON"] = "obstacle_avoidance_horizon" DeviceSettingKeyEnum["OBSTACLE_AVOIDANCE_UPSIDE"] = "obstacle_avoidance_upside" DeviceSettingKeyEnum["OBSTACLE_AVOIDANCE_DOWNSIDE"] = "obstacle_avoidance_downside" })(DeviceSettingKeyEnum || (DeviceSettingKeyEnum = {})) export const initDeviceSetting = { [DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET]: { label: "飞行器夜航灯", value: "", trueValue: NightLightsStateEnum.CLOSE, editable: false, popConfirm: { visible: false, loading: false, // content: '为保证飞行器的作业安全,建议打开夜航灯', label: "飞行器夜航灯" }, settingKey: DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET }, [DeviceSettingKeyEnum.HEIGHT_LIMIT_SET]: { label: "限高", value: "", trueValue: 120, editable: false, popConfirm: { visible: false, loading: false, // content: '限高:20 - 1500m', // info: '修改限高会影响当前机场的所有作业任务,建议确认作业情况后再进行修改', label: "限高" }, settingKey: DeviceSettingKeyEnum.HEIGHT_LIMIT_SET }, [DeviceSettingKeyEnum.DISTANCE_LIMIT_SET]: { label: "限远", value: "", trueValue: DistanceLimitStatusEnum.UNSET, // info: '限远(15 - 8000m)是约束飞行器相对机场的最大作业距离', editable: false, popConfirm: { visible: false, loading: false, // content: '限远 (15- 8000m) 是约束飞行器相对机场的最大作业距离', // info: '修改限远会影响当前机场的所有作业任务,建议确认作业情况后再进行修改', label: "限远" }, settingKey: DeviceSettingKeyEnum.DISTANCE_LIMIT_SET }, [DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON]: { label: "水平避障", value: "", trueValue: ObstacleAvoidanceStatusEnum.CLOSE, // info: '飞行器的避障工作状态显示,可以快速开启/关闭飞行器避障,如需进一步设置请在设备运维页面设置', editable: false, popConfirm: { visible: false, loading: false, // content: '飞行器避障是保障飞行作业安全的基础功能,建议保持飞行器避障开启', label: "水平避障" }, settingKey: DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON }, [DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE]: { label: "上视避障", value: "", trueValue: ObstacleAvoidanceStatusEnum.CLOSE, // info: '飞行器的避障工作状态显示,可以快速开启/关闭飞行器避障,如需进一步设置请在设备运维页面设置', editable: false, popConfirm: { visible: false, loading: false, // content: '飞行器避障是保障飞行作业安全的基础功能,建议保持飞行器避障开启', label: "上视避障" }, settingKey: DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE }, [DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE]: { label: "下视避障", value: "", trueValue: ObstacleAvoidanceStatusEnum.CLOSE, // info: '飞行器的避障工作状态显示,可以快速开启/关闭飞行器避障,如需进一步设置请在设备运维页面设置', editable: false, popConfirm: { visible: false, loading: false, // content: '飞行器避障是保障飞行作业安全的基础功能,建议保持飞行器避障开启', label: "下视避障" }, settingKey: DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE } } export const initDeviceSettingFormModel = { nightLightsState: false, // 夜航灯开关 heightLimit: 20, // 限高设置 distanceLimitStatus: { state: false, distanceLimit: 15 }, // 限远开关 obstacleAvoidanceHorizon: false, // 飞行器避障-水平开关设置 obstacleAvoidanceUpside: false, // 飞行器避障-上视开关设置 obstacleAvoidanceDownside: false // 飞行器避障-下视开关设置 } src/utils/device-setting.js
New file @@ -0,0 +1,283 @@ import { DeviceSettingKeyEnum, DistanceLimitStatusEnum, ObstacleAvoidanceStatusEnum, NightLightsStateEnum } from "@/types/device-setting" import { DEFAULT_PLACEHOLDER } from "./constants" import { isNil } from "lodash" const Unit_M = " m" /** * 根据osd 更新信息 * @param deviceSetting * @param deviceInfo * @returns */ export function updateDeviceSettingInfoByOsd(deviceSetting, deviceInfo) { const { device, dock, gateway } = deviceInfo || {} if (!deviceSetting) { return } // 夜航灯 let nightLightsState = "" if (isNil(device?.night_lights_state)) { deviceSetting[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].editable = false deviceSetting[ DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET ].value = DEFAULT_PLACEHOLDER nightLightsState = DEFAULT_PLACEHOLDER } else { deviceSetting[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].editable = true nightLightsState = device?.night_lights_state if (nightLightsState === NightLightsStateEnum.CLOSE) { deviceSetting[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].value = "关闭" } else if (nightLightsState === NightLightsStateEnum.OPEN) { deviceSetting[DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET].value = "开启" } else { deviceSetting[ DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET ].value = DEFAULT_PLACEHOLDER } } deviceSetting[ DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET ].trueValue = nightLightsState // 限高 let heightLimit = device?.height_limit if (isNil(heightLimit) || heightLimit === 0) { heightLimit = DEFAULT_PLACEHOLDER deviceSetting[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].editable = false } else { deviceSetting[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].editable = true } deviceSetting[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].trueValue = heightLimit deviceSetting[DeviceSettingKeyEnum.HEIGHT_LIMIT_SET].value = heightLimit + Unit_M // 限远 let distanceLimitStatus = "" if (isNil(device?.distance_limit_status?.state)) { distanceLimitStatus = DEFAULT_PLACEHOLDER deviceSetting[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].editable = false deviceSetting[ DeviceSettingKeyEnum.DISTANCE_LIMIT_SET ].value = DEFAULT_PLACEHOLDER } else { deviceSetting[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].editable = true distanceLimitStatus = device?.distance_limit_status?.state if (distanceLimitStatus === DistanceLimitStatusEnum.UNSET) { deviceSetting[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].value = "关闭" } else if (distanceLimitStatus === DistanceLimitStatusEnum.SET) { const distanceLimit = device?.distance_limit_status?.distance_limit if (distanceLimit) { deviceSetting[DeviceSettingKeyEnum.DISTANCE_LIMIT_SET].value = distanceLimit + Unit_M } else { deviceSetting[ DeviceSettingKeyEnum.DISTANCE_LIMIT_SET ].value = DEFAULT_PLACEHOLDER } } else { deviceSetting[ DeviceSettingKeyEnum.DISTANCE_LIMIT_SET ].value = DEFAULT_PLACEHOLDER } } deviceSetting[ DeviceSettingKeyEnum.DISTANCE_LIMIT_SET ].trueValue = distanceLimitStatus // 避障 if (isNil(device?.obstacle_avoidance)) { deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON ].editable = false deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON ].value = DEFAULT_PLACEHOLDER deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON ].trueValue = DEFAULT_PLACEHOLDER deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE ].editable = false deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE ].value = DEFAULT_PLACEHOLDER deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE ].trueValue = DEFAULT_PLACEHOLDER deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE ].editable = false deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE ].value = DEFAULT_PLACEHOLDER deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE ].trueValue = DEFAULT_PLACEHOLDER } else { const { horizon, upside, downside } = device.obstacle_avoidance || {} if (isNil(horizon)) { deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON ].editable = false deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON ].value = DEFAULT_PLACEHOLDER deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON ].trueValue = DEFAULT_PLACEHOLDER } else { deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON ].editable = false if (horizon === ObstacleAvoidanceStatusEnum.CLOSE) { deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON].value = "关闭" } else if (horizon === ObstacleAvoidanceStatusEnum.OPEN) { deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON].value = "开启" } else { deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON ].value = DEFAULT_PLACEHOLDER } deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON ].trueValue = horizon } if (isNil(upside)) { deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE ].editable = false deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE ].value = DEFAULT_PLACEHOLDER deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE ].trueValue = DEFAULT_PLACEHOLDER } else { deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE ].editable = false if (upside === ObstacleAvoidanceStatusEnum.CLOSE) { deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE].value = "关闭" } else if (upside === ObstacleAvoidanceStatusEnum.OPEN) { deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE].value = "开启" } else { deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE ].value = DEFAULT_PLACEHOLDER } deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE ].trueValue = upside } if (isNil(downside)) { deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE ].editable = false deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE ].value = DEFAULT_PLACEHOLDER deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE ].trueValue = DEFAULT_PLACEHOLDER } else { deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE ].editable = false if (downside === ObstacleAvoidanceStatusEnum.CLOSE) { deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE].value = "关闭" } else if (downside === ObstacleAvoidanceStatusEnum.OPEN) { deviceSetting[DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE].value = "开启" } else { deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE ].value = DEFAULT_PLACEHOLDER } deviceSetting[ DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE ].trueValue = downside } } return deviceSetting } // 更新formModel export function updateDeviceSettingFormModelByOsd( deviceSettingFormModelFromOsd, deviceInfo ) { const { device, dock, gateway } = deviceInfo || {} if (!deviceSettingFormModelFromOsd) { return } // 夜航灯 const nightLightsState = device?.night_lights_state if ( !isNil(nightLightsState) && nightLightsState === NightLightsStateEnum.OPEN ) { deviceSettingFormModelFromOsd.nightLightsState = true } else { deviceSettingFormModelFromOsd.nightLightsState = false } // 限高 const heightLimit = device?.height_limit if (isNil(heightLimit) || heightLimit === 0) { deviceSettingFormModelFromOsd.heightLimit = 20 } else { deviceSettingFormModelFromOsd.heightLimit = heightLimit } // 限远 const distanceLimitStatus = device?.distance_limit_status?.state if ( !isNil(distanceLimitStatus) && distanceLimitStatus === DistanceLimitStatusEnum.SET ) { deviceSettingFormModelFromOsd.distanceLimitStatus.state = true deviceSettingFormModelFromOsd.distanceLimitStatus.distanceLimit = device?.distance_limit_status?.distance_limit || 15 } else { deviceSettingFormModelFromOsd.distanceLimitStatus.state = false deviceSettingFormModelFromOsd.distanceLimitStatus.distanceLimit = 15 } // 避障 if (isNil(device?.obstacle_avoidance)) { deviceSettingFormModelFromOsd.obstacleAvoidanceHorizon = false deviceSettingFormModelFromOsd.obstacleAvoidanceUpside = false deviceSettingFormModelFromOsd.obstacleAvoidanceDownside = false } else { const { horizon, upside, downside } = device.obstacle_avoidance || {} if (!isNil(horizon) && horizon === ObstacleAvoidanceStatusEnum.OPEN) { deviceSettingFormModelFromOsd.obstacleAvoidanceHorizon = true } else { deviceSettingFormModelFromOsd.obstacleAvoidanceHorizon = false } if (!isNil(upside) && upside === ObstacleAvoidanceStatusEnum.OPEN) { deviceSettingFormModelFromOsd.obstacleAvoidanceUpside = true } else { deviceSettingFormModelFromOsd.obstacleAvoidanceUpside = false } if (!isNil(downside) && downside === ObstacleAvoidanceStatusEnum.OPEN) { deviceSettingFormModelFromOsd.obstacleAvoidanceDownside = true } else { deviceSettingFormModelFromOsd.obstacleAvoidanceDownside = false } } return deviceSettingFormModelFromOsd } src/views/device/components/DeviceSettingBox.vue
@@ -309,29 +309,18 @@ </div> </template> <script setup lang="ts"> <script setup> import { defineProps, ref, watch } from 'vue'; import { DeviceInfoType } from '@/types/device'; import { useMyStore } from '@/store'; import { cloneDeep } from 'lodash'; import { initDeviceSetting, initDeviceSettingFormModel, DeviceSettingKeyEnum, } from '@/types/device-setting'; import { initDeviceSetting, initDeviceSettingFormModel } from '@/types/device-setting'; import { updateDeviceSettingInfoByOsd, updateDeviceSettingFormModelByOsd, } from '@/utils/device-setting'; import { useDeviceSetting } from './use-device-setting'; import DeviceSettingPopover from './DeviceSettingPopover.vue'; const props = defineProps<{ sn: string; deviceInfo: DeviceInfoType; }>(); const props = defineProps(); const store = useMyStore(); const deviceSetting = ref(cloneDeep(initDeviceSetting)); const deviceSettingFormModelFromOsd = ref(cloneDeep(initDeviceSettingFormModel)); const deviceSettingFormModel = ref(cloneDeep(initDeviceSettingFormModel)); // 真实使用的formModel @@ -350,16 +339,16 @@ } ); function onShowPopConfirm(settingKey: DeviceSettingKeyEnum) { function onShowPopConfirm(settingKey) { deviceSetting.value[settingKey].popConfirm.visible = true; deviceSettingFormModel.value = cloneDeep(deviceSettingFormModelFromOsd.value); } function onCancel(settingKey: DeviceSettingKeyEnum) { function onCancel(settingKey) { deviceSetting.value[settingKey].popConfirm.visible = false; } async function onConfirm(settingKey: DeviceSettingKeyEnum) { async function onConfirm(settingKey) { deviceSetting.value[settingKey].popConfirm.loading = true; const body = genDevicePropsBySettingKey(settingKey, deviceSettingFormModel.value); await setDeviceProps(props.sn, body); src/views/device/components/DeviceSettingPopover.vue
@@ -32,18 +32,10 @@ </a-popover> </template> <script lang="ts" setup> <script setup> import { defineProps, defineEmits, reactive, watch, computed } from 'vue'; const props = defineProps<{ visible?: boolean; loading?: Boolean; disabled?: Boolean; title?: String; okText?: String; cancelText?: String; width?: Number; }>(); const props = defineProps(); const emit = defineEmits(['cancel', 'confirm']); @@ -71,14 +63,14 @@ return classList.join(' '); }); function onConfirm(e: Event) { function onConfirm(e) { if (props.disabled) { return; } emit('confirm', e); } function onCancel(e: Event) { function onCancel(e) { state.sVisible = false; emit('cancel', e); } src/views/device/components/use-device-setting.js
New file @@ -0,0 +1,72 @@ import { ElMessage } from 'element-plus'; import { putDeviceProps } from '@/api/device-setting'; import { DeviceSettingKeyEnum, ObstacleAvoidanceStatusEnum, NightLightsStateEnum, DistanceLimitStatusEnum, } from '@/types/device-setting'; export function useDeviceSetting() { // 生成参数 function genDevicePropsBySettingKey(key, fromModel) { const body = {}; if (key === DeviceSettingKeyEnum.NIGHT_LIGHTS_MODE_SET) { body.night_lights_state = fromModel.nightLightsState ? NightLightsStateEnum.OPEN : NightLightsStateEnum.CLOSE; } else if (key === DeviceSettingKeyEnum.HEIGHT_LIMIT_SET) { body.height_limit = fromModel.heightLimit; } else if (key === DeviceSettingKeyEnum.DISTANCE_LIMIT_SET) { body.distance_limit_status = {}; if (fromModel.distanceLimitStatus.state) { body.distance_limit_status.state = DistanceLimitStatusEnum.SET; body.distance_limit_status.distance_limit = fromModel.distanceLimitStatus.distanceLimit; } else { body.distance_limit_status.state = DistanceLimitStatusEnum.UNSET; } } else if (key === DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_HORIZON) { body.obstacle_avoidance = { horizon: fromModel.obstacleAvoidanceHorizon ? ObstacleAvoidanceStatusEnum.OPEN : ObstacleAvoidanceStatusEnum.CLOSE, }; } else if (key === DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_UPSIDE) { body.obstacle_avoidance = { upside: fromModel.obstacleAvoidanceUpside ? ObstacleAvoidanceStatusEnum.OPEN : ObstacleAvoidanceStatusEnum.CLOSE, }; } else if (key === DeviceSettingKeyEnum.OBSTACLE_AVOIDANCE_DOWNSIDE) { body.obstacle_avoidance = { downside: fromModel.obstacleAvoidanceDownside ? ObstacleAvoidanceStatusEnum.OPEN : ObstacleAvoidanceStatusEnum.CLOSE, }; } return body; } // 设置设备属性 async function setDeviceProps(sn, body) { try { const { code, message: msg } = await putDeviceProps(sn, body); if (code === 0) { return true; } throw msg; } catch (e) { ElMessage({ message: '设备属性设置失败', type: 'error', }); return false; } } return { genDevicePropsBySettingKey, setDeviceProps, }; }