mirror of
https://gitee.com/myxzgzs/boyue-ui-admin-vue3
synced 2025-08-08 16:32:43 +08:00
【功能完善】IoT:增加 device config 配置
This commit is contained in:
parent
6636068bd5
commit
3685e438fa
@ -27,6 +27,7 @@ export interface DeviceVO {
|
||||
areaId: number // 地区编码
|
||||
address: string // 设备详细地址
|
||||
serialNumber: string // 设备序列号
|
||||
config: string // 设备配置
|
||||
groupIds?: number[] // 添加分组 ID
|
||||
}
|
||||
|
||||
@ -72,7 +73,7 @@ export interface IotDeviceDownstreamReqVO {
|
||||
data: any // 请求参数
|
||||
}
|
||||
|
||||
// MQTT连接参数 VO
|
||||
// MQTT 连接参数 VO
|
||||
export interface MqttConnectionParamsVO {
|
||||
mqttClientId: string // MQTT 客户端 ID
|
||||
mqttUsername: string // MQTT 用户名
|
||||
|
@ -11,9 +11,8 @@
|
||||
|
||||
<!-- JSON 编辑器:读模式 -->
|
||||
<Vue3Jsoneditor
|
||||
ref="editor"
|
||||
v-if="isEditing"
|
||||
v-model="deviceConfigState"
|
||||
v-model="config"
|
||||
:options="editorOptions"
|
||||
height="500px"
|
||||
currentMode="code"
|
||||
@ -21,62 +20,48 @@
|
||||
/>
|
||||
<!-- JSON 编辑器:写模式 -->
|
||||
<Vue3Jsoneditor
|
||||
ref="editor"
|
||||
v-else
|
||||
v-model="deviceConfigState"
|
||||
v-model="config"
|
||||
:options="editorOptions"
|
||||
height="500px"
|
||||
currentMode="view"
|
||||
v-loading.fullscreen.lock="loading"
|
||||
@error="onError"
|
||||
/>
|
||||
<div class="flex justify-center mt-24">
|
||||
<div class="mt-5 text-center">
|
||||
<el-button v-if="isEditing" @click="cancelEdit">取消</el-button>
|
||||
<el-button v-if="isEditing" type="primary" @click="saveConfig">保存</el-button>
|
||||
<el-button v-if="isEditing" type="primary" @click="saveConfig" :disabled="hasJsonError"
|
||||
>保存</el-button
|
||||
>
|
||||
<el-button v-else @click="enableEdit">编辑</el-button>
|
||||
<!-- TODO @芋艿:缺一个下发按钮 -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import Vue3Jsoneditor from 'v3-jsoneditor/src/Vue3Jsoneditor.vue'
|
||||
import { DeviceApi } from '@/api/iot/device/device/index'
|
||||
import { useTagsViewStore } from '@/store/modules/tagsView'
|
||||
import { DeviceVO } from '../../../../../api/iot/device/device/index';
|
||||
import { DeviceApi, DeviceVO } from '@/api/iot/device/device'
|
||||
import { jsonParse } from '@/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
device: DeviceVO
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'success'): void // 定义 success 事件,不需要参数
|
||||
}>()
|
||||
|
||||
const route = useRoute()
|
||||
const message = useMessage()
|
||||
const { delView } = useTagsViewStore() // 视图操作
|
||||
const { currentRoute } = useRouter() // 路由
|
||||
const id = Number(route.params.id) // 将字符串转换为数字
|
||||
const loading = ref(true) // 加载中
|
||||
const deviceConfigState = ref({}) // 设置配置
|
||||
const loading = ref(false) // 加载中
|
||||
const config = ref<any>({}) // 只存储 config 字段
|
||||
const hasJsonError = ref(false) // 是否有 JSON 格式错误
|
||||
|
||||
|
||||
// 获取设备配置
|
||||
const getDeviceConfig = async (id: number) => {
|
||||
try {
|
||||
loading.value = true
|
||||
const res = await DeviceApi.getDevice(id)
|
||||
deviceConfigState.value = res
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (!id) {
|
||||
message.warning('参数错误,产品不能为空!')
|
||||
delView(unref(currentRoute))
|
||||
return
|
||||
}
|
||||
await getDeviceConfig(id)
|
||||
/** 监听 props.device 的变化,只更新 config 字段 */
|
||||
watchEffect(() => {
|
||||
config.value = jsonParse(props.device.config)
|
||||
})
|
||||
|
||||
|
||||
const isEditing = ref(false) // 编辑状态
|
||||
const editorOptions = computed(() => ({
|
||||
mainMenuBar: false,
|
||||
@ -87,40 +72,48 @@ const editorOptions = computed(() => ({
|
||||
/** 启用编辑模式的函数 */
|
||||
const enableEdit = () => {
|
||||
isEditing.value = true
|
||||
hasJsonError.value = false // 重置错误状态
|
||||
}
|
||||
|
||||
/** 取消编辑的函数 */
|
||||
const cancelEdit = () => {
|
||||
config.value = jsonParse(props.device.config)
|
||||
isEditing.value = false
|
||||
// 逻辑代码
|
||||
console.log('取消编辑')
|
||||
hasJsonError.value = false // 重置错误状态
|
||||
}
|
||||
|
||||
/** 保存配置的函数 */
|
||||
const saveConfig = async () => {
|
||||
const params = {
|
||||
...deviceConfigState.value
|
||||
} as DeviceVO
|
||||
await updateDeviceConfig(params)
|
||||
if (hasJsonError.value) {
|
||||
message.error('JSON格式错误,请修正后再提交!')
|
||||
return
|
||||
}
|
||||
await updateDeviceConfig()
|
||||
isEditing.value = false
|
||||
}
|
||||
|
||||
/** 处理 JSON 编辑器错误的函数 */
|
||||
const onError = (e: any) => {
|
||||
console.log('onError', e)
|
||||
}
|
||||
|
||||
// 更新设备配置
|
||||
const updateDeviceConfig = async (params: DeviceVO) => {
|
||||
/** 更新设备配置 */
|
||||
const updateDeviceConfig = async () => {
|
||||
try {
|
||||
// 提交请求
|
||||
loading.value = true
|
||||
await DeviceApi.updateDevice(params)
|
||||
await getDeviceConfig(id)
|
||||
await DeviceApi.updateDevice({
|
||||
id: props.device.id,
|
||||
config: JSON.stringify(config.value)
|
||||
} as DeviceVO)
|
||||
message.success('更新成功!')
|
||||
// 触发 success 事件
|
||||
emit('success')
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 处理 JSON 编辑器错误的函数 */
|
||||
const onError = (e: any) => {
|
||||
console.log('onError', e)
|
||||
hasJsonError.value = true
|
||||
}
|
||||
</script>
|
||||
|
@ -63,7 +63,11 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="passwd">
|
||||
<el-input v-model="mqttParams.mqttPassword" readonly :type="passwordVisible ? 'text' : 'password'">
|
||||
<el-input
|
||||
v-model="mqttParams.mqttPassword"
|
||||
readonly
|
||||
:type="passwordVisible ? 'text' : 'password'"
|
||||
>
|
||||
<template #append>
|
||||
<el-button @click="passwordVisible = !passwordVisible" type="primary">
|
||||
<Icon :icon="passwordVisible ? 'ph:eye-slash' : 'ph:eye'" />
|
||||
@ -117,13 +121,14 @@ const copyToClipboard = async (text: string) => {
|
||||
const openMqttParams = async () => {
|
||||
try {
|
||||
const res = await DeviceApi.getMqttConnectionParams(device.id)
|
||||
|
||||
// 根据API响应结构正确获取数据
|
||||
// 根据 API 响应结构正确获取数据
|
||||
mqttParams.value = {
|
||||
mqttClientId: res.mqttClientId || 'N/A',
|
||||
mqttUsername: res.mqttUsername || 'N/A',
|
||||
mqttPassword: res.mqttPassword || 'N/A'
|
||||
}
|
||||
|
||||
// 显示 MQTT 弹框
|
||||
mqttDialogVisible.value = true
|
||||
} catch (error) {
|
||||
console.error('获取MQTT连接参数出错:', error)
|
||||
|
@ -27,7 +27,11 @@
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="设备配置" name="config">
|
||||
<DeviceDetailConfig />
|
||||
<DeviceDetailConfig
|
||||
v-if="activeTab === 'config'"
|
||||
:device="device"
|
||||
@success="getDeviceData"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-col>
|
||||
@ -41,7 +45,7 @@ import DeviceDetailsInfo from './DeviceDetailsInfo.vue'
|
||||
import DeviceDetailsModel from './DeviceDetailsModel.vue'
|
||||
import DeviceDetailsLog from './DeviceDetailsLog.vue'
|
||||
import DeviceDetailsSimulator from './DeviceDetailsSimulator.vue'
|
||||
import DeviceDetailConfig from './DeviceDetailConfig.vue';
|
||||
import DeviceDetailConfig from './DeviceDetailConfig.vue'
|
||||
|
||||
defineOptions({ name: 'IoTDeviceDetail' })
|
||||
|
||||
@ -54,7 +58,7 @@ const device = ref<DeviceVO>({} as DeviceVO) // 设备详情
|
||||
const activeTab = ref('info') // 默认激活的标签页
|
||||
|
||||
/** 获取设备详情 */
|
||||
const getDeviceData = async (id: number) => {
|
||||
const getDeviceData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
device.value = await DeviceApi.getDevice(id)
|
||||
@ -78,7 +82,7 @@ onMounted(async () => {
|
||||
delView(unref(currentRoute))
|
||||
return
|
||||
}
|
||||
await getDeviceData(id)
|
||||
await getDeviceData()
|
||||
activeTab.value = (route.query.tab as string) || 'info'
|
||||
})
|
||||
</script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user