admin-vue3/src/views/review/meeting/FileListDialog.vue

114 lines
3.6 KiB
Vue

<template>
<el-dialog v-model="visible" :title="`会议文件 - ${projectTitle}`" width="720px">
<!-- 上传区域 -->
<el-upload
:action="''"
:auto-upload="false"
:on-change="handleFileChange"
:show-file-list="false"
multiple
accept=".doc,.docx,.xls,.xlsx,.pdf,.ppt,.pptx"
>
<el-button type="primary" plain>上传文件</el-button>
<template #tip>
<div class="el-upload__tip">支持 doc、docx、xls、xlsx、pdf、ppt、pptx 格式,单文件不超过 50MB</div>
</template>
</el-upload>
<el-divider />
<!-- 文件列表 -->
<el-table :data="fileList" v-loading="loading" border size="small">
<el-table-column label="文件名" prop="fileName" show-overflow-tooltip min-width="200" />
<el-table-column label="大小" width="90" align="right">
<template #default="{ row }">{{ formatFileSize(row.fileSize) }}</template>
</el-table-column>
<el-table-column label="类型" prop="fileType" width="70" align="center" />
<el-table-column label="上传人" prop="creator" width="90" />
<el-table-column label="上传时间" prop="createTime" width="165" />
<el-table-column label="操作" width="120" align="center">
<template #default="{ row }">
<el-button type="primary" link @click="handleDownload(row)">下载</el-button>
<el-button type="danger" link @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, defineProps } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { UploadFile } from 'element-plus'
import {
getMeetingFileList,
uploadMeetingFile,
deleteMeetingFile,
type ReviewMeetingFileRespVO
} from '@/api/review/project'
defineOptions({ name: 'FileListDialog' })
const props = defineProps<{ reviewMeetingId: number }>()
const visible = ref(false)
const loading = ref(false)
const projectTitle = ref('')
const reviewMeetingProjectId = ref<number>()
const fileList = ref<ReviewMeetingFileRespVO[]>([])
const open = async (projectId: number, title: string) => {
reviewMeetingProjectId.value = projectId
projectTitle.value = title
visible.value = true
await loadFiles()
}
const loadFiles = async () => {
loading.value = true
try {
fileList.value = await getMeetingFileList(reviewMeetingProjectId.value!)
} finally {
loading.value = false
}
}
const handleFileChange = async (uploadFile: UploadFile) => {
if (!uploadFile.raw) return
if (uploadFile.raw.size > 50 * 1024 * 1024) {
ElMessage.error('文件大小不能超过 50MB')
return
}
loading.value = true
try {
await uploadMeetingFile(props.reviewMeetingId, reviewMeetingProjectId.value!, uploadFile.raw)
ElMessage.success('上传成功')
await loadFiles()
} catch (e) {
ElMessage.error('上传失败')
} finally {
loading.value = false
}
}
const handleDownload = (row: ReviewMeetingFileRespVO) => {
window.open(row.fileUrl, '_blank')
}
const handleDelete = async (row: ReviewMeetingFileRespVO) => {
await ElMessageBox.confirm(`确定要删除文件「${row.fileName}」吗?`, '提示', { type: 'warning' })
await deleteMeetingFile(row.id)
ElMessage.success('删除成功')
await loadFiles()
}
const formatFileSize = (bytes: number): string => {
if (!bytes) return '-'
if (bytes < 1024) return bytes + ' B'
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'
return (bytes / (1024 * 1024)).toFixed(1) + ' MB'
}
defineExpose({ open })
</script>