yanghao há 9 horas atrás
pai
commit
e6bc69c81b

+ 3 - 1
src/components/ImageViewer/index.ts

@@ -14,7 +14,8 @@ export function createImageViewer(options: ImageViewerProps) {
     hideOnClickModal = false,
     teleported = false,
     zIndex = 2000,
-    show = true
+    show = true,
+    headers = {}
   } = options
 
   const propsData: Partial<ImageViewerProps> = {}
@@ -26,6 +27,7 @@ export function createImageViewer(options: ImageViewerProps) {
   propsData.teleported = teleported
   propsData.zIndex = zIndex
   propsData.show = show
+  propsData.headers = headers
 
   document.body.appendChild(container)
   instance = createVNode(ImageViewer, propsData)

+ 43 - 2
src/components/ImageViewer/src/ImageViewer.vue

@@ -1,6 +1,7 @@
 <script lang="ts" setup>
 import { PropType } from 'vue'
 import { propTypes } from '@/utils/propTypes'
+import axios from 'axios'
 
 defineOptions({ name: 'ImageViewer' })
 
@@ -14,22 +15,62 @@ const props = defineProps({
   infinite: propTypes.bool.def(true),
   hideOnClickModal: propTypes.bool.def(false),
   teleported: propTypes.bool.def(false),
-  show: propTypes.bool.def(false)
+  show: propTypes.bool.def(false),
+  headers: {
+    type: Object as PropType<Record<string, any>>,
+    default: () => ({})
+  }
 })
 
+const imageUrls = ref<string[]>([])
+
+// 加载图片,如果需要 headers,则通过 axios 获取 blob
+const loadImages = async () => {
+  if (props.headers && Object.keys(props.headers).length > 0) {
+    // 如果有 headers,使用 axios 下载图片
+    const promises = props.urlList.map(async (url) => {
+      try {
+        const response = await axios.get(url, {
+          headers: props.headers,
+          responseType: 'blob'
+        })
+        // 创建 blob URL
+        return URL.createObjectURL(response.data)
+      } catch (error) {
+        console.error('图片加载失败:', url, error)
+        return url // 失败时返回原 URL
+      }
+    })
+    imageUrls.value = await Promise.all(promises)
+  } else {
+    // 如果没有 headers,直接使用原 URL
+    imageUrls.value = [...props.urlList]
+  }
+}
+
 const getBindValue = computed(() => {
   const propsData: Recordable = { ...props }
   delete propsData.show
+  delete propsData.headers
   return propsData
 })
 
 const show = ref(props.show)
 
 const close = () => {
+  // 清理 blob URLs
+  imageUrls.value.forEach((url) => {
+    if (url.startsWith('blob:')) {
+      URL.revokeObjectURL(url)
+    }
+  })
   show.value = false
 }
+
+// 初始化加载图片
+loadImages()
 </script>
 
 <template>
-  <ElImageViewer v-if="show" v-bind="getBindValue" @close="close" />
+  <ElImageViewer v-if="show" v-bind="{ ...getBindValue, urlList: imageUrls }" @close="close" />
 </template>

+ 1 - 0
src/components/ImageViewer/src/types.ts

@@ -6,4 +6,5 @@ export interface ImageViewerProps {
   hideOnClickModal?: boolean
   teleported?: boolean
   show?: boolean
+  headers?: Record<string, any> // 新增:支持自定义请求头
 }

+ 6 - 1
src/views/pms/device/DeviceInfo.vue

@@ -259,6 +259,7 @@ import RecordList from '@/views/pms/device/record/RecordList.vue'
 import AssociationDevices from '@/views/pms/device/completeSet/AssociationDevices.vue'
 import { createImageViewer } from '@/components/ImageViewer'
 import { ref, onMounted } from 'vue'
+import { getAccessToken } from '@/utils/auth'
 
 const defaultPicUrl = ref(
   import.meta.env.VITE_BASE_URL + '/admin-api/infra/file/29/get/IntegratedSolution.png'
@@ -322,8 +323,12 @@ const getDetail = async () => {
 }
 
 const imagePreview = (imgUrl: string) => {
+  const token = getAccessToken()
   createImageViewer({
-    urlList: [imgUrl]
+    urlList: [imgUrl],
+    headers: {
+      Authorization: `Bearer ${token}`
+    }
   })
 }