Files
novalon-manage-system/novalon-manage-web/src/views/file/FileManagement.vue
T
张翔 af44c23f21 refactor(security): 重构安全配置并优化测试环境
- 移除旧的测试套件和UAT测试文件
- 更新密码编码器配置使用BCrypt strength=12
- 添加用户角色关联表和相关服务
- 优化前端日期显示格式
- 清理无用资源和配置文件
- 增强测试数据管理和清理功能
2026-03-27 13:00:22 +08:00

197 lines
5.1 KiB
Vue

<template>
<div class="file-management">
<el-card>
<template #header>
<div class="card-title">
<span>文件管理</span>
<el-upload
:before-upload="handleUpload"
:show-file-list="false"
>
<el-button type="primary">
<el-icon><Upload /></el-icon> 上传文件
</el-button>
</el-upload>
</div>
</template>
<div class="search-bar">
<el-input
v-model="searchKeyword"
placeholder="搜索文件名"
clearable
style="width: 300px"
@input="handleSearch"
>
<template #prefix>
<el-icon><Search /></el-icon>
</template>
</el-input>
</div>
<el-table
v-loading="loading"
:data="filteredDataSource"
style="width: 100%"
>
<el-table-column
prop="id"
label="ID"
/>
<el-table-column
prop="fileName"
label="文件名"
/>
<el-table-column
prop="fileSize"
label="文件大小"
/>
<el-table-column label="文件类型">
<template #default="{ row }">
<el-tag :type="getFileTypeTag(row.fileType)">
{{ getFileTypeName(row.fileType) }}
</el-tag>
</template>
</el-table-column>
<el-table-column
prop="storageType"
label="存储方式"
/>
<el-table-column
prop="createdAt"
label="上传时间"
>
<template #default="{ row }">
{{ formatDateTime(row.createdAt) }}
</template>
</el-table-column>
<el-table-column
prop="createBy"
label="上传人"
/>
<el-table-column
label="操作"
width="150"
>
<template #default="{ row }">
<el-button
type="primary"
link
size="small"
@click="handleDownload(row)"
>
下载
</el-button>
<el-button
type="danger"
link
size="small"
@click="handleDelete(row)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Upload, Search } from '@element-plus/icons-vue'
import request from '@/utils/request'
import { formatDateTime } from '@/utils/dateFormat'
const loading = ref(false)
const dataSource = ref([])
const searchKeyword = ref('')
const filteredDataSource = computed(() => {
if (!searchKeyword.value) {
return dataSource.value
}
return dataSource.value.filter((item: any) =>
item.fileName.toLowerCase().includes(searchKeyword.value.toLowerCase())
)
})
const handleSearch = () => {
}
const fetchData = async () => {
loading.value = true
try {
const res: any = await request.get('/files')
dataSource.value = res
} finally {
loading.value = false
}
}
const handleUpload = async (file: File) => {
const formData = new FormData()
formData.append('file', file)
try {
await request.post('/files/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
})
ElMessage.success('上传成功')
fetchData()
} catch {
ElMessage.error('上传失败')
}
return false
}
const handleDownload = (row: any) => {
window.open(row.filePath)
}
const handleDelete = async (row: any) => {
try {
await ElMessageBox.confirm('确定要删除该文件吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
await request.delete(`/files/${row.id}`)
ElMessage.success('删除成功')
fetchData()
} catch (error) {
console.error('删除文件失败:', error)
}
}
const getFileTypeName = (fileType: string) => {
if (!fileType) return '未知'
if (fileType.startsWith('image/')) return '图片'
if (fileType.startsWith('video/')) return '视频'
if (fileType.startsWith('audio/')) return '音频'
if (fileType.includes('pdf')) return 'PDF'
if (fileType.includes('word') || fileType.includes('document')) return 'Word'
if (fileType.includes('excel') || fileType.includes('spreadsheet')) return 'Excel'
return '其他'
}
const getFileTypeTag = (fileType: string): '' | 'success' | 'warning' | 'danger' | 'info' => {
if (!fileType) return 'info'
if (fileType.startsWith('image/')) return 'success'
if (fileType.startsWith('video/')) return 'danger'
if (fileType.startsWith('audio/')) return 'warning'
if (fileType.includes('pdf')) return 'danger'
if (fileType.includes('word')) return ''
if (fileType.includes('excel')) return 'success'
return 'info'
}
onMounted(() => fetchData())
</script>
<style scoped lang="css">
.file-management .card-title {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>