gaoluyang
2 天以前 b64a0deae5b5d33f9e20671a68936b27f0b9b00b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<script setup lang="ts">
import { computed } from 'vue';
 
import { IconifyIcon } from '@vben/icons';
import { getFileIcon, getFileNameFromUrl, getFileTypeClass, isImage } from '@vben/utils';
 
import { FilePreviewModal, useFilePreview } from '#/components/file-preview';
 
const props = defineProps<{
  attachmentUrls?: string[];
}>();
 
const { openPreview, previewState } = useFilePreview();
 
/** 过滤掉空值的附件列表 */
const validAttachmentUrls = computed(() => {
  return (props.attachmentUrls || []).filter((url) => url && url.trim());
});
 
/** 点击文件 */
function handleFileClick(url: string) {
  if (isImage(url)) {
    window.open(url, '_blank');
  } else {
    openPreview(url);
  }
}
</script>
 
<template>
  <div v-if="validAttachmentUrls.length > 0" class="mt-2">
    <div class="flex flex-wrap gap-2">
      <div
        v-for="(url, index) in validAttachmentUrls"
        :key="index"
        class="max-w-70 flex min-w-40 cursor-pointer items-center rounded-lg border border-transparent bg-gray-100 p-3 transition-all duration-200 hover:-translate-y-1 hover:bg-gray-200 hover:shadow-lg"
        @click="handleFileClick(url)"
      >
        <div class="mr-3 flex-shrink-0">
          <div
            class="flex h-8 w-8 items-center justify-center rounded-md bg-gradient-to-br font-bold text-white"
            :class="getFileTypeClass(getFileNameFromUrl(url))"
          >
            <IconifyIcon
              :icon="getFileIcon(getFileNameFromUrl(url))"
              :size="20"
            />
          </div>
        </div>
        <div class="min-w-0 flex-1">
          <div
            class="mb-1 overflow-hidden text-ellipsis whitespace-nowrap text-sm font-medium leading-tight text-gray-800"
            :title="getFileNameFromUrl(url)"
          >
            {{ getFileNameFromUrl(url) }}
          </div>
        </div>
      </div>
    </div>
  </div>
  <FilePreviewModal
    v-model:visible="previewState.visible.value"
    :file-url="previewState.fileUrl.value"
    :file-name="previewState.fileName.value"
  />
</template>