diff --git a/src/api/iot/device/index.ts b/src/api/iot/device/index.ts index 2a1951de..24d48789 100644 --- a/src/api/iot/device/index.ts +++ b/src/api/iot/device/index.ts @@ -67,8 +67,8 @@ export const DeviceApi = { return await request.delete({ url: `/iot/device/delete?id=` + id }) }, - // 导出设备 Excel - exportDevice: async (params) => { - return await request.download({ url: `/iot/device/export-excel`, params }) + // 获取设备数量 + getDeviceCount: async (productId: number) => { + return await request.get({ url: `/iot/device/count?productId=` + productId }) } } diff --git a/src/api/iot/product/index.ts b/src/api/iot/product/index.ts index d4de1e5b..2a8d430f 100644 --- a/src/api/iot/product/index.ts +++ b/src/api/iot/product/index.ts @@ -14,6 +14,7 @@ export interface ProductVO { netType: number // 联网方式, 0: Wi-Fi, 1: Cellular, 2: Ethernet, 3: 其他 protocolType: number // 接入网关协议, 0: modbus, 1: opc-ua, 2: customize, 3: ble, 4: zigbee dataFormat: number // 数据格式, 0: 透传模式, 1: Alink JSON + deviceCount: number // 设备数量 } // iot 产品 API diff --git a/src/views/iot/device/detail/DeviceDetailsHeader.vue b/src/views/iot/device/detail/DeviceDetailsHeader.vue index cc585f4a..4360cab1 100644 --- a/src/views/iot/device/detail/DeviceDetailsHeader.vue +++ b/src/views/iot/device/detail/DeviceDetailsHeader.vue @@ -58,49 +58,10 @@ const emit = defineEmits(['refresh']) * * @param text 需要复制的文本 */ -const copyToClipboard = async (text: string) => { - if (!navigator.clipboard) { - // 浏览器不支持 Clipboard API,使用回退方法 - const textarea = document.createElement('textarea') - textarea.value = text - // 防止页面滚动 - textarea.style.position = 'fixed' - textarea.style.top = '0' - textarea.style.left = '0' - textarea.style.width = '2em' - textarea.style.height = '2em' - textarea.style.padding = '0' - textarea.style.border = 'none' - textarea.style.outline = 'none' - textarea.style.boxShadow = 'none' - textarea.style.background = 'transparent' - document.body.appendChild(textarea) - textarea.focus() - textarea.select() - - try { - const successful = document.execCommand('copy') - if (successful) { - message.success('复制成功!') - } else { - message.error('复制失败,请手动复制') - } - } catch (err) { - console.error('Fallback: Oops, unable to copy', err) - message.error('复制失败,请手动复制') - } - - document.body.removeChild(textarea) - return - } - - try { - await navigator.clipboard.writeText(text) - message.success('复制成功!') - } catch (err) { - console.error('Async: Could not copy text: ', err) - message.error('复制失败,请手动复制') - } +const copyToClipboard = (text: string) => { + navigator.clipboard.writeText(text).then(() => { + message.success('复制成功') + }) } /** diff --git a/src/views/iot/device/detail/DeviceDetailsInfo.vue b/src/views/iot/device/detail/DeviceDetailsInfo.vue index 2acbaabb..77084625 100644 --- a/src/views/iot/device/detail/DeviceDetailsInfo.vue +++ b/src/views/iot/device/detail/DeviceDetailsInfo.vue @@ -103,49 +103,10 @@ const emit = defineEmits(['refresh']) const activeNames = ref(['basicInfo']) // 复制到剪贴板方法 -const copyToClipboard = async (text: string) => { - if (!navigator.clipboard) { - // 浏览器不支持 Clipboard API,使用回退方法 - const textarea = document.createElement('textarea') - textarea.value = text - // 防止页面滚动 - textarea.style.position = 'fixed' - textarea.style.top = '0' - textarea.style.left = '0' - textarea.style.width = '2em' - textarea.style.height = '2em' - textarea.style.padding = '0' - textarea.style.border = 'none' - textarea.style.outline = 'none' - textarea.style.boxShadow = 'none' - textarea.style.background = 'transparent' - document.body.appendChild(textarea) - textarea.focus() - textarea.select() - - try { - const successful = document.execCommand('copy') - if (successful) { - message.success('复制成功!') - } else { - message.error('复制失败,请手动复制') - } - } catch (err) { - console.error('Fallback: Oops, unable to copy', err) - message.error('复制失败,请手动复制') - } - - document.body.removeChild(textarea) - return - } - - try { - await navigator.clipboard.writeText(text) - message.success('复制成功!') - } catch (err) { - console.error('Async: Could not copy text: ', err) - message.error('复制失败,请手动复制') - } +const copyToClipboard = (text: string) => { + navigator.clipboard.writeText(text).then(() => { + message.success('复制成功') + }) } // 定义 MQTT 弹框的可见性 diff --git a/src/views/iot/product/detail/ProductDetailsHeader.vue b/src/views/iot/product/detail/ProductDetailsHeader.vue index b50001e8..db0849ed 100644 --- a/src/views/iot/product/detail/ProductDetailsHeader.vue +++ b/src/views/iot/product/detail/ProductDetailsHeader.vue @@ -45,8 +45,8 @@ - 0 - 前往管理 + {{ product.deviceCount }} + 前往管理 @@ -63,8 +63,11 @@ const copyToClipboard = (text: string) => { message.success('复制成功') }) } -const goToManagement = (productKey: string) => { - message.warning('暂未开放') + +// 路由跳转到设备管理 +const { currentRoute, push } = useRouter() +const goToManagement = (productId: string) => { + push({ name: 'IoTDevice', query: { productId } }) } // 操作修改 @@ -93,6 +96,9 @@ const confirmUnpublish = async (id: number) => { } } +// 定义 Props const { product } = defineProps<{ product: ProductVO }>() + +// 定义 Emits const emit = defineEmits(['refresh']) diff --git a/src/views/iot/product/detail/ProductTopic.vue b/src/views/iot/product/detail/ProductTopic.vue new file mode 100644 index 00000000..071a5236 --- /dev/null +++ b/src/views/iot/product/detail/ProductTopic.vue @@ -0,0 +1,229 @@ + + diff --git a/src/views/iot/product/detail/index.vue b/src/views/iot/product/detail/index.vue index c77fe176..6510ff3f 100644 --- a/src/views/iot/product/detail/index.vue +++ b/src/views/iot/product/detail/index.vue @@ -1,11 +1,13 @@