af44c23f21
- 移除旧的测试套件和UAT测试文件 - 更新密码编码器配置使用BCrypt strength=12 - 添加用户角色关联表和相关服务 - 优化前端日期显示格式 - 清理无用资源和配置文件 - 增强测试数据管理和清理功能
197 lines
5.1 KiB
Vue
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>
|