Browse Source

feat: 设备详情 - 查看 mqtt 参数 / 上报示例

main
刘凯 1 year ago
parent
commit
c865d2f933
  1. 19
      src/api/device-manage/device/index.ts
  2. 77
      src/views/device-manage/device/components/MqttParamsModal.vue
  3. 57
      src/views/device-manage/device/components/ReportExampleModal.vue
  4. 22
      src/views/device-manage/device/components/composables/useDeviceInfo.ts

19
src/api/device-manage/device/index.ts

@ -56,3 +56,22 @@ export function getDeviceTopicList(params: PageParam & { deviceId: string }) {
params,
})
}
export function getMqttConnectParams(deviceId: string) {
return defHttp.get({
url: '/device/mqttLinkInfo',
params: {
deviceId,
},
})
}
export function getReportExample(productId: string, deviceSn: string) {
return defHttp.get({
url: '/device/messageExample',
params: {
productId,
deviceSn,
},
})
}

77
src/views/device-manage/device/components/MqttParamsModal.vue

@ -0,0 +1,77 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { Modal } from 'ant-design-vue'
import { EyeOutlined } from '@ant-design/icons-vue'
import { useAsyncState } from '@vueuse/core'
import { getMqttConnectParams } from '@/api/device-manage/device'
import type { DescItem } from '@/components/Description'
import { Description } from '@/components/Description'
import { noop } from '@/utils'
import { copyText } from '@/utils/copyTextToClipboard'
const props = defineProps<{ deviceId: string }>()
const { state, execute, isLoading } = useAsyncState(() => getMqttConnectParams(props.deviceId), undefined, { immediate: false })
const open = ref(false)
function handleOpen() {
if (state.value)
return open.value = true
execute()
.then(() => {
open.value = true
})
.catch(noop)
}
const schema: DescItem[] = [
{
label: '服务器地址 (hostUrl)',
field: 'hostUrl',
},
{
label: '端口 (port)',
field: 'port',
},
{
label: 'ClientID (clientId)',
field: 'clientId',
},
{
label: '用户名 (username)',
field: 'username',
},
{
label: '密码 (password)',
field: 'password',
},
]
function handleCopy() {
const data = schema.map((item) => {
return {
key: item.field,
keyName: item.label,
value: state.value[item.field],
}
})
copyText(JSON.stringify(data))
}
</script>
<template>
<a-button size="small" :loading="isLoading" @click="handleOpen">
<EyeOutlined />
查看参数
</a-button>
<Modal v-model:open="open" title="MQTT 连接参数" :footer="null">
<Description :data="state" :schema="schema" :column="1" />
<div text="center" mt="10px">
<a-button size="small" @click="handleCopy">
一键复制
</a-button>
</div>
</Modal>
</template>

57
src/views/device-manage/device/components/ReportExampleModal.vue

@ -0,0 +1,57 @@
<script lang="ts" setup>
import { h, ref } from 'vue'
import { Modal } from 'ant-design-vue'
import { EyeOutlined } from '@ant-design/icons-vue'
import { useAsyncState } from '@vueuse/core'
import { getReportExample } from '@/api/device-manage/device'
import type { DescItem } from '@/components/Description'
import { Description } from '@/components/Description'
import { JsonPreview } from '@/components/CodeEditor'
import { noop } from '@/utils'
const props = defineProps<{ productId: string, deviceSn: string }>()
const { state, execute, isLoading } = useAsyncState(() => getReportExample(props.productId, props.deviceSn), undefined, { immediate: false })
const open = ref(false)
function handleOpen() {
if (state.value)
return open.value = true
execute()
.then(() => open.value = true)
.catch(noop)
}
const schema: DescItem[] = [
{
label: 'Topic',
field: 'topic',
},
{
label: '上报示例',
field: 'message',
render(value) {
let content = value
try {
content = JSON.parse(value)
}
catch {}
return h(JsonPreview, {
data: content,
})
},
},
]
</script>
<template>
<a-button size="small" :loading="isLoading" @click="handleOpen">
<EyeOutlined />
查看参数
</a-button>
<Modal v-model:open="open" title="上报示例" :footer="null" width="50%">
<Description :data="state" :schema="schema" :column="1" />
</Modal>
</template>

22
src/views/device-manage/device/components/composables/useDeviceInfo.ts

@ -1,8 +1,9 @@
import { h } from 'vue'
import { Button, Tag } from 'ant-design-vue'
import { EyeOutlined } from '@ant-design/icons-vue'
import { Tag } from 'ant-design-vue'
import { useRoute } from 'vue-router'
import { useAsyncState } from '@vueuse/core'
import MqttParamsModal from '../MqttParamsModal.vue'
import ReportExampleModal from '../ReportExampleModal.vue'
import type { DescItem } from '@/components/Description'
import { getDeviceDetail } from '@/api/device-manage/device'
import { usePermission } from '@/hooks/web/usePermission'
@ -61,19 +62,16 @@ export function useDeviceInfo() {
field: 'mqtt',
label: 'MQTT连接参数',
show: () => hasPermission('device_mqtt_params'),
render: () => h(Button, {
size: 'small',
onClick: openMqttParamsModal,
}, () => [h(EyeOutlined), '查看参数']),
render: () => h(MqttParamsModal, { deviceId: data.value!.id }),
},
{
field: 'report',
label: '上报示例',
show: () => hasPermission('device_report_example'),
render: () => h(Button, {
size: 'small',
onClick: openReportExampleModal,
}, () => [h(EyeOutlined), '查看示例']),
render: () => h(ReportExampleModal, {
productId: data.value!.productId,
deviceSn: data.value!.deviceSn,
}),
},
{
field: 'deviceDesc',
@ -84,10 +82,6 @@ export function useDeviceInfo() {
const route = useRoute()
const { state: data } = useAsyncState(() => getDeviceDetail(route.params.id as string), undefined)
function openMqttParamsModal() {}
function openReportExampleModal() {}
return {
data,
scheam,

Loading…
Cancel
Save