153 lines
3.1 KiB
Vue
153 lines
3.1 KiB
Vue
<template>
|
|
<div class="result-item">
|
|
<div class="result-icon">
|
|
<img :src="getFileTypeIcon(item.fileType)" :alt="item.fileType" />
|
|
</div>
|
|
<div class="result-content">
|
|
<h3 class="result-title">{{ item.title }}</h3>
|
|
<div class="result-details">
|
|
<div v-if="item.fileList && item.fileList.length" class="file-list">
|
|
<div v-for="(file, index) in visibleFiles" :key="index" class="file-item">
|
|
<span>├ {{ file.name }} - {{ formatSize(file.size) }}</span>
|
|
</div>
|
|
<div v-if="item.fileList.length > maxVisibleFiles" class="more-files">
|
|
...还有{{ item.fileList.length - maxVisibleFiles }}个文件
|
|
</div>
|
|
</div>
|
|
<div class="result-meta">
|
|
<span class="size">文件大小: {{ formatSize(item.size) }}</span>
|
|
<span class="date">更新时间: {{ item.updateTime }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="result-actions">
|
|
<button class="get-link-button" @click="$emit('get-link', item)">
|
|
获取链接
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
|
|
interface File {
|
|
name: string;
|
|
size: number;
|
|
}
|
|
|
|
interface SearchResult {
|
|
id: string;
|
|
title: string;
|
|
fileType: string;
|
|
size: number;
|
|
updateTime: string;
|
|
cloudType: string;
|
|
fileList?: File[];
|
|
}
|
|
|
|
const props = defineProps<{ item: SearchResult }>()
|
|
const emit = defineEmits<{ (e: 'get-link', item: SearchResult): void }>()
|
|
|
|
const maxVisibleFiles = 5
|
|
|
|
const visibleFiles = computed(() => {
|
|
if (!props.item.fileList) return []
|
|
return props.item.fileList.slice(0, maxVisibleFiles)
|
|
})
|
|
|
|
function formatSize(bytes: number) {
|
|
if (bytes === 0) return '0 B'
|
|
|
|
const units = ['B', 'KB', 'MB', 'GB', 'TB']
|
|
const i = Math.floor(Math.log(bytes) / Math.log(1024))
|
|
|
|
return (bytes / Math.pow(1024, i)).toFixed(2) + ' ' + units[i]
|
|
}
|
|
|
|
function getFileTypeIcon(fileType: string) {
|
|
const icons: Record<string, string> = {
|
|
folder: '/icons/folder.png',
|
|
document: '/icons/document.png',
|
|
video: '/icons/video.png',
|
|
audio: '/icons/audio.png',
|
|
image: '/icons/image.png',
|
|
}
|
|
|
|
return icons[fileType] || '/icons/file.png'
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.result-item {
|
|
display: flex;
|
|
padding: 16px 0;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
}
|
|
|
|
.result-icon {
|
|
margin-right: 16px;
|
|
}
|
|
|
|
.result-icon img {
|
|
width: 40px;
|
|
height: 40px;
|
|
}
|
|
|
|
.result-content {
|
|
flex: 1;
|
|
}
|
|
|
|
.result-title {
|
|
font-size: 16px;
|
|
font-weight: 500;
|
|
margin-bottom: 8px;
|
|
color: #333;
|
|
}
|
|
|
|
.file-list {
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.file-item {
|
|
margin-bottom: 4px;
|
|
color: #666;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.more-files {
|
|
color: #999;
|
|
font-style: italic;
|
|
font-size: 13px;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.result-meta {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 16px;
|
|
color: #666;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.result-actions {
|
|
margin-left: 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.get-link-button {
|
|
background-color: #ff9500;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 4px;
|
|
padding: 8px 16px;
|
|
cursor: pointer;
|
|
font-weight: 500;
|
|
transition: background-color 0.2s;
|
|
}
|
|
|
|
.get-link-button:hover {
|
|
background-color: #e68600;
|
|
}
|
|
</style> |