From a80242c53cf87ff223c6c4b8240172bb230e6d5d Mon Sep 17 00:00:00 2001 From: K <1175047471@qq.com> Date: Wed, 6 Mar 2024 14:15:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=AE=BE=E5=A4=87=E8=AF=A6=E6=83=85=20?= =?UTF-8?q?-=20=E6=9C=80=E6=96=B0=E4=B8=8A=E6=8A=A5=E6=95=B0=E6=8D=AE=20/?= =?UTF-8?q?=20=E5=B7=B2=E8=AE=A2=E9=98=85=20Topic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/device-manage/device/index.ts | 31 +++++- src/api/device-manage/device/types.ts | 8 ++ .../device/components/DeviceInfo.vue | 103 ++++++++++++++++++ .../device/components/TopicList.vue | 53 +++++++++ .../components/composables/useDeviceInfo.ts | 90 +++++++++++++++ .../composables/useDeviceProperties.ts | 27 +++++ .../device-manage/device/components/index.ts | 2 + src/views/device-manage/device/detail.vue | 29 ++++- .../components/composables/useModelService.ts | 19 +++- 9 files changed, 354 insertions(+), 8 deletions(-) create mode 100644 src/views/device-manage/device/components/DeviceInfo.vue create mode 100644 src/views/device-manage/device/components/TopicList.vue create mode 100644 src/views/device-manage/device/components/composables/useDeviceInfo.ts create mode 100644 src/views/device-manage/device/components/composables/useDeviceProperties.ts create mode 100644 src/views/device-manage/device/components/index.ts diff --git a/src/api/device-manage/device/index.ts b/src/api/device-manage/device/index.ts index 604e8783..94e5f48a 100644 --- a/src/api/device-manage/device/index.ts +++ b/src/api/device-manage/device/index.ts @@ -1,4 +1,4 @@ -import type { Device, GetDeviceListParams } from './types' +import type { Device, DevicePropertie, GetDeviceListParams } from './types' import { defHttp } from '@/utils/http/axios' export function getDeviceList(params: GetDeviceListParams) { @@ -27,3 +27,32 @@ export function deleteDevice(id: string) { url: `/device/remove?id=${id}`, }) } + +export function getDeviceDetail(id: string) { + return defHttp.get({ + url: '/device/detail', + params: { + id, + }, + }) +} + +export function getDeviceProperties(modelId: string, deviceSn: string) { + return defHttp.get<{ + properties?: DevicePropertie[] + updateTime?: string + }>({ + url: '/device/properties', + params: { + deviceSn, + modelId, + }, + }) +} + +export function getDeviceTopicList(params: PageParam & { deviceId: string }) { + return defHttp.get({ + url: '/device/topic/page', + params, + }) +} diff --git a/src/api/device-manage/device/types.ts b/src/api/device-manage/device/types.ts index 6cf9333c..4c76ccd6 100644 --- a/src/api/device-manage/device/types.ts +++ b/src/api/device-manage/device/types.ts @@ -13,3 +13,11 @@ export interface Device { deviceDesc: string isOnline: BooleanFlag } + +export interface DevicePropertie { + identifier: string + name: string + unit: string + value: string + sort: number +} diff --git a/src/views/device-manage/device/components/DeviceInfo.vue b/src/views/device-manage/device/components/DeviceInfo.vue new file mode 100644 index 00000000..4d315fd7 --- /dev/null +++ b/src/views/device-manage/device/components/DeviceInfo.vue @@ -0,0 +1,103 @@ + + + diff --git a/src/views/device-manage/device/components/TopicList.vue b/src/views/device-manage/device/components/TopicList.vue new file mode 100644 index 00000000..745fed33 --- /dev/null +++ b/src/views/device-manage/device/components/TopicList.vue @@ -0,0 +1,53 @@ + + + diff --git a/src/views/device-manage/device/components/composables/useDeviceInfo.ts b/src/views/device-manage/device/components/composables/useDeviceInfo.ts new file mode 100644 index 00000000..4b917f97 --- /dev/null +++ b/src/views/device-manage/device/components/composables/useDeviceInfo.ts @@ -0,0 +1,90 @@ +import { h } from 'vue' +import { Button, Tag } from 'ant-design-vue' +import { EyeOutlined } from '@ant-design/icons-vue' +import { useRoute } from 'vue-router' +import { useAsyncState } from '@vueuse/core' +import type { DescItem } from '@/components/Description' +import { getDeviceDetail } from '@/api/device-manage/device' + +export function useDeviceInfo() { + const scheam: DescItem[] = [ + { + field: 'productName', + label: '所属产品', + }, + { + field: 'deviceName', + label: '设备名称', + }, + { + field: 'deviceSn', + label: '设备序列号', + }, + { + field: 'deviceSecret', + label: '设备密钥', + }, + { + field: 'isActive', + label: '设备状态', + render(value) { + return h(Tag, { color: value ? 'green' : 'default' }, () => value ? '已激活' : '未激活') + }, + }, + { + field: 'isOnline', + label: '在线状态', + render(value) { + return h(Tag, { color: value ? 'green' : 'default' }, () => value ? '在线' : '离线') + }, + }, + { + field: 'createTime', + label: '创建时间', + }, + { + field: 'activeTime', + label: '激活时间', + }, + { + field: 'lastOnlineTime', + label: '最后上线时间', + }, + { + field: 'lastOfflineTime', + label: '最后离线时间', + }, + { + field: 'mqtt', + label: 'MQTT连接参数', + render: () => h(Button, { + size: 'small', + onClick: openMqttParamsModal, + }, () => [h(EyeOutlined), '查看参数']), + }, + { + field: 'report', + label: '上报示例', + render: () => h(Button, { + size: 'small', + onClick: openReportExampleModal, + }, () => [h(EyeOutlined), '查看示例']), + }, + { + field: 'deviceDesc', + label: '设备描述', + }, + ] + + const route = useRoute() + const { state: data } = useAsyncState(() => getDeviceDetail(route.params.id as string), undefined) + + function openMqttParamsModal() {} + + function openReportExampleModal() {} + + return { + data, + scheam, + } +} diff --git a/src/views/device-manage/device/components/composables/useDeviceProperties.ts b/src/views/device-manage/device/components/composables/useDeviceProperties.ts new file mode 100644 index 00000000..e19c55b9 --- /dev/null +++ b/src/views/device-manage/device/components/composables/useDeviceProperties.ts @@ -0,0 +1,27 @@ +import { useAsyncState } from '@vueuse/core' +import { type MaybeRefOrGetter, toValue, watchEffect } from 'vue' +import { getDeviceProperties } from '@/api/device-manage/device' + +export function useDeviceProperties(modelId: MaybeRefOrGetter, deviceSn: MaybeRefOrGetter) { + const { state, execute, isLoading } = useAsyncState( + () => getDeviceProperties(toValue(modelId)!, toValue(deviceSn)!), + undefined, + { + immediate: false, + resetOnExecute: false, + }, + ) + + watchEffect(() => { + if (!toValue(modelId) || !toValue(deviceSn)) + return + + execute() + }) + + return { + isLoading, + deviceProperties: state, + reloadReviceProperties: execute, + } +} diff --git a/src/views/device-manage/device/components/index.ts b/src/views/device-manage/device/components/index.ts new file mode 100644 index 00000000..a8661495 --- /dev/null +++ b/src/views/device-manage/device/components/index.ts @@ -0,0 +1,2 @@ +export { default as DeviceInfo } from './DeviceInfo.vue' +export { default as TopicList } from './TopicList.vue' diff --git a/src/views/device-manage/device/detail.vue b/src/views/device-manage/device/detail.vue index 72480a97..173de078 100644 --- a/src/views/device-manage/device/detail.vue +++ b/src/views/device-manage/device/detail.vue @@ -1,5 +1,30 @@ + + + + diff --git a/src/views/product/components/composables/useModelService.ts b/src/views/product/components/composables/useModelService.ts index a3692d84..027fcf76 100644 --- a/src/views/product/components/composables/useModelService.ts +++ b/src/views/product/components/composables/useModelService.ts @@ -1,15 +1,24 @@ -import { useAsyncState, watchOnce } from '@vueuse/core' -import type { MaybeRef } from 'vue' -import { ref, unref } from 'vue' +import { toValue, useAsyncState, watchOnce } from '@vueuse/core' +import type { MaybeRefOrGetter } from 'vue' +import { ref, watch } from 'vue' import { deleteModelService, getAllModelServices } from '@/api/product/model' import { useMessage } from '@/hooks/web/useMessage' import { useModal } from '@/components/Modal' import type { ModelService } from '@/api/product/types' -export function useModelService(productId: MaybeRef) { +export function useModelService(productId: MaybeRefOrGetter) { const selectedModelId = ref() - const { state, execute } = useAsyncState(() => getAllModelServices(unref(productId)), [], { resetOnExecute: false }) + const { state, execute } = useAsyncState( + () => getAllModelServices(toValue(productId) as string), + [], + { + resetOnExecute: false, + immediate: toValue(productId) !== undefined, + }, + ) + + watch(() => toValue(productId), () => execute()) watchOnce(state, () => { if (state.value.length > 0)