DeviceDetailsHeader.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <template>
  2. <div>
  3. <div class="flex items-start justify-between">
  4. <div>
  5. <el-col>
  6. <el-row>
  7. <span class="text-xl font-bold">{{ device.deviceName }}</span>
  8. </el-row>
  9. </el-col>
  10. </div>
  11. <div>
  12. <!-- 右上:按钮 -->
  13. <el-button
  14. @click="openForm('update', device.id)"
  15. v-hasPermi="['iot:device:update']"
  16. v-if="product.status === 0"
  17. >
  18. 编辑
  19. </el-button>
  20. </div>
  21. </div>
  22. </div>
  23. <ContentWrap class="mt-10px">
  24. <el-descriptions :column="5" direction="horizontal">
  25. <el-descriptions-item label="产品">
  26. <el-link @click="goToProductDetail(product.id)">{{ product.name }}</el-link>
  27. </el-descriptions-item>
  28. <el-descriptions-item label="ProductKey">
  29. {{ product.productKey }}
  30. <el-button @click="copyToClipboard(product.productKey)">复制</el-button>
  31. </el-descriptions-item>
  32. </el-descriptions>
  33. </ContentWrap>
  34. <!-- 表单弹窗:添加/修改 -->
  35. <DeviceForm ref="formRef" @success="emit('refresh')" />
  36. </template>
  37. <script setup lang="ts">
  38. import { ref } from 'vue'
  39. import DeviceForm from '@/views/iot/device/DeviceForm.vue'
  40. import { ProductVO } from '@/api/iot/product'
  41. import { DeviceVO } from '@/api/iot/device'
  42. import { useRouter } from 'vue-router'
  43. const message = useMessage()
  44. const router = useRouter()
  45. // 操作修改
  46. const formRef = ref()
  47. const openForm = (type: string, id?: number) => {
  48. formRef.value.open(type, id)
  49. }
  50. const { product, device } = defineProps<{ product: ProductVO; device: DeviceVO }>()
  51. const emit = defineEmits(['refresh'])
  52. /**
  53. * 将文本复制到剪贴板
  54. *
  55. * @param text 需要复制的文本
  56. */
  57. const copyToClipboard = async (text: string) => {
  58. if (!navigator.clipboard) {
  59. // 浏览器不支持 Clipboard API,使用回退方法
  60. const textarea = document.createElement('textarea')
  61. textarea.value = text
  62. // 防止页面滚动
  63. textarea.style.position = 'fixed'
  64. textarea.style.top = '0'
  65. textarea.style.left = '0'
  66. textarea.style.width = '2em'
  67. textarea.style.height = '2em'
  68. textarea.style.padding = '0'
  69. textarea.style.border = 'none'
  70. textarea.style.outline = 'none'
  71. textarea.style.boxShadow = 'none'
  72. textarea.style.background = 'transparent'
  73. document.body.appendChild(textarea)
  74. textarea.focus()
  75. textarea.select()
  76. try {
  77. const successful = document.execCommand('copy')
  78. if (successful) {
  79. message.success('复制成功!')
  80. } else {
  81. message.error('复制失败,请手动复制')
  82. }
  83. } catch (err) {
  84. console.error('Fallback: Oops, unable to copy', err)
  85. message.error('复制失败,请手动复制')
  86. }
  87. document.body.removeChild(textarea)
  88. return
  89. }
  90. try {
  91. await navigator.clipboard.writeText(text)
  92. message.success('复制成功!')
  93. } catch (err) {
  94. console.error('Async: Could not copy text: ', err)
  95. message.error('复制失败,请手动复制')
  96. }
  97. }
  98. /**
  99. * 跳转到产品详情页面
  100. *
  101. * @param productId 产品 ID
  102. */
  103. const goToProductDetail = (productId: number) => {
  104. router.push({ name: 'IoTProductDetail', params: { id: productId } })
  105. }
  106. </script>