mcwl-pc/app/components/DownPlanetFile.vue

150 lines
3.4 KiB
Vue

# 创建新文件
<script setup lang="ts">
import { Download } from 'lucide-vue-next'
import { useMessage } from 'naive-ui'
import { onMounted, ref, watch } from 'vue'
interface Props {
communityId: number | string
tenantId: number | string
show?: boolean
}
interface FileItem {
fileName: string
fileSize: string
uploadTime: string
uploadBy: string
url: string
}
const props = defineProps<Props>()
const emit = defineEmits<{
'update:show': [value: boolean]
}>()
const message = useMessage()
const loading = ref(false)
const fileList = ref<FileItem[]>([])
const currentFile = ref<FileItem | null>(null)
// 获取文件列表
async function getFileList() {
try {
const res = await request.post('/communityFile/list', {
tenantId: props.tenantId,
communityId: props.communityId,
})
if (res.code === 200) {
fileList.value = res.rows
}
}
catch (error) {
message.error('获取文件列表失败')
}
}
// 处理文件下载
async function handleDownload(file: FileItem) {
if (!file.url) {
message.error('文件链接不存在')
return
}
currentFile.value = file
loading.value = true
try {
const link = document.createElement('a')
link.href = file.url
link.download = file.fileName
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
message.success('下载成功')
}
catch (error) {
message.error('下载失败')
}
finally {
loading.value = false
currentFile.value = null
}
}
// 组件挂载时获取文件列表
onMounted(() => {
if (props.show) {
getFileList()
}
})
// 监听 show 变化,当显示弹框时获取文件列表
watch(() => props.show, (newVal) => {
if (newVal) {
getFileList()
}
})
</script>
<template>
<n-modal
:show="props.show"
:mask-closable="true"
preset="dialog"
class="w-[600px]"
:show-icon="false"
title="文件下载"
@update:show="emit('update:show', $event)"
>
<div class="py-4">
<div v-if="fileList.length > 0" class="space-y-3">
<div
v-for="file in fileList"
:key="file.fileName"
class="flex items-center justify-between p-4 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors"
>
<div class="flex-1 min-w-0">
<div class="text-base font-medium mb-1 truncate">
{{ file.fileName }}
</div>
<div class="text-gray-500 text-sm">
{{ file.fileSize }} · {{ file.uploadBy }} · {{ file.uploadTime }}
</div>
</div>
<n-button
type="primary"
class="ml-4 !px-6"
:loading="currentFile?.fileName === file.fileName && loading"
:theme-overrides="{
common: {
primaryColor: '#3f7ef7',
primaryColorHover: '#3f7ef7',
},
}"
@click="handleDownload(file)"
>
<template #icon>
<Download class="w-4 h-4 mr-1" />
</template>
下载
</n-button>
</div>
</div>
<div v-else class="text-center text-gray-500 py-8">
暂无文件
</div>
</div>
<template #action>
<div class="flex justify-end">
<n-button
size="large"
class="!px-8"
@click="emit('update:show', false)"
>
关闭
</n-button>
</div>
</template>
</n-modal>
</template>