feat: 添加系统配置、审计中心、通知中心、文件管理模块

This commit is contained in:
张翔
2026-03-11 12:11:59 +08:00
commit 52c66444a5
264 changed files with 10109 additions and 0 deletions
@@ -0,0 +1,118 @@
<template>
<div class="file-management">
<a-card>
<template #title>
<div class="card-title">
<span>文件管理</span>
<a-upload :before-upload="handleUpload" :show-upload-list="false">
<a-button type="primary">
<upload-outlined /> 上传文件
</a-button>
</a-upload>
</div>
</template>
<a-table :columns="columns" :data-source="dataSource" :loading="loading">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'fileType'">
<a-tag :color="getFileTypeColor(record.fileType)">
{{ getFileTypeName(record.fileType) }}
</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a-button type="link" size="small" @click="handleDownload(record)">下载</a-button>
<a-button type="link" size="small" danger @click="handleDelete(record)">删除</a-button>
</a-space>
</template>
</template>
</a-table>
</a-card>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { UploadOutlined } from '@ant-design/icons-vue'
import request from '@/utils/request'
const columns = [
{ title: 'ID', dataIndex: 'id', key: 'id' },
{ title: '文件名', dataIndex: 'fileName', key: 'fileName' },
{ title: '文件大小', dataIndex: 'fileSize', key: 'fileSize' },
{ title: '文件类型', key: 'fileType' },
{ title: '存储方式', dataIndex: 'storageType', key: 'storageType' },
{ title: '上传时间', dataIndex: 'createdAt', key: 'createdAt' },
{ title: '操作', key: 'action', width: 150 }
]
const loading = ref(false)
const dataSource = ref([])
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' }
})
message.success('上传成功')
fetchData()
} catch { message.error('上传失败') }
return false
}
const handleDownload = (record: any) => {
window.open(record.filePath)
}
const handleDelete = async (record: any) => {
try {
await request.delete(`/files/${record.id}`)
message.success('删除成功')
fetchData()
} catch { message.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 getFileTypeColor = (fileType: string) => {
if (!fileType) return 'default'
if (fileType.startsWith('image/')) return 'pink'
if (fileType.startsWith('video/')) return 'purple'
if (fileType.startsWith('audio/')) return 'cyan'
if (fileType.includes('pdf')) return 'red'
if (fileType.includes('word')) return 'blue'
if (fileType.includes('excel')) return 'green'
return 'orange'
}
onMounted(() => fetchData())
</script>
<style scoped lang="scss">
.file-management .card-title {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>