fix: issues

This commit is contained in:
yanghao05
2025-04-08 17:32:04 +08:00
parent cf8bb5f192
commit 45ed2f508b

View File

@@ -34,11 +34,11 @@ const closeUploadDialog = () => {
// Media types for filtering // Media types for filtering
const mediaTypes = ref([ const mediaTypes = ref([
{ name: 'All media', value: null }, { name: '所有媒体', value: null },
{ name: 'Images', value: 'Image' }, { name: '图片', value: 'Image' },
{ name: 'Videos', value: 'Video' }, { name: '视频', value: 'Video' },
{ name: 'Documents', value: 'Document' }, { name: '文档', value: 'Document' },
{ name: 'Audio', value: 'Audio' }, { name: '音频', value: 'Audio' },
{ name: 'PDF', value: 'PDF' } { name: 'PDF', value: 'PDF' }
]); ]);
@@ -65,7 +65,7 @@ const mediaFiles = ref([]);
// File upload handling // File upload handling
const onUpload = (event) => { const onUpload = (event) => {
toast.add({ severity: 'success', summary: 'Success', detail: 'Files uploaded successfully', life: 3000 }); toast.add({ severity: 'success', summary: '成功', detail: '文件上传成功', life: 3000 });
// In a real app, you would process the files from event.files and update the mediaFiles list // In a real app, you would process the files from event.files and update the mediaFiles list
// Here we're just showing a success message // Here we're just showing a success message
@@ -78,25 +78,25 @@ const onUpload = (event) => {
// Preview file // Preview file
const previewFile = (file) => { const previewFile = (file) => {
toast.add({ severity: 'info', summary: 'Preview', detail: `Previewing ${file.name}`, life: 3000 }); toast.add({ severity: 'info', summary: '预览', detail: `预览 ${file.name}`, life: 3000 });
}; };
// Download file // Download file
const downloadFile = (file) => { const downloadFile = (file) => {
toast.add({ severity: 'info', summary: 'Download', detail: `Downloading ${file.name}`, life: 3000 }); toast.add({ severity: 'info', summary: '下载', detail: `下载 ${file.name}`, life: 3000 });
}; };
// Delete file // Delete file
const confirmDelete = (file) => { const confirmDelete = (file) => {
confirm.require({ confirm.require({
message: `Are you sure you want to delete ${file.name}?`, message: `您确定要删除 ${file.name} 吗?`,
header: 'Confirmation', header: '确认删除',
icon: 'pi pi-exclamation-triangle', icon: 'pi pi-exclamation-triangle',
acceptClass: 'p-button-danger', acceptClass: 'p-button-danger',
accept: () => { accept: () => {
// In a real app, you would call an API to delete the file // In a real app, you would call an API to delete the file
mediaFiles.value = mediaFiles.value.filter(f => f.id !== file.id); mediaFiles.value = mediaFiles.value.filter(f => f.id !== file.id);
toast.add({ severity: 'success', summary: 'Success', detail: 'File deleted', life: 3000 }); toast.add({ severity: 'success', summary: '成功', detail: '文件已删除', life: 3000 });
} }
}); });
}; };
@@ -113,7 +113,7 @@ const fetchMediaFiles = async () => {
totalRecords.value = response.total; totalRecords.value = response.total;
console.log(totalRecords.value); console.log(totalRecords.value);
} catch (error) { } catch (error) {
toast.add({ severity: 'error', summary: 'Error', detail: 'Failed to load media files', life: 3000 }); toast.add({ severity: 'error', summary: '错误', detail: '加载媒体文件失败', life: 3000 });
} finally { } finally {
loading.value = false; loading.value = false;
} }
@@ -155,7 +155,7 @@ const getFileIcon = (file) => {
const formatFileSize = (bytes) => { const formatFileSize = (bytes) => {
if (bytes === 0) return '0 B'; if (bytes === 0) return '0 B';
const k = BigInt(1024); const k = BigInt(1024);
const sizes = ['B', 'KB', 'MB', 'GB']; const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
// Convert input to BigInt // Convert input to BigInt
const bytesValue = BigInt(bytes); const bytesValue = BigInt(bytes);
@@ -179,7 +179,7 @@ const formatFileSize = (bytes) => {
<div class="w-full"> <div class="w-full">
<div class="flex justify-between items-center mb-6 gap-4"> <div class="flex justify-between items-center mb-6 gap-4">
<h1 class="text-2xl font-semibold text-gray-800 text-nowrap">Media Library</h1> <h1 class="text-2xl font-semibold text-gray-800 text-nowrap">媒体库</h1>
<Button class="text-nowrap !px-8" icon="pi pi-upload" label="上传" severity="primary" <Button class="text-nowrap !px-8" icon="pi pi-upload" label="上传" severity="primary"
@click="openUploadDialog" /> @click="openUploadDialog" />
@@ -188,36 +188,36 @@ const formatFileSize = (bytes) => {
<!-- Media Table --> <!-- Media Table -->
<div class="card mt-10"> <div class="card mt-10">
<div class="pb-10 flex"> <div class="pb-10 flex">
<InputText v-model="globalFilterValue" placeholder="Search media..." class="flex-1" /> <InputText v-model="globalFilterValue" placeholder="搜索媒体..." class="flex-1" />
</div> </div>
<DataTable v-model:filters="filters" :value="mediaFiles" :paginator="true" v-model:first="first" <DataTable v-model:filters="filters" :value="mediaFiles" :paginator="true" v-model:first="first"
v-model:rows="rows" :totalRecords="totalRecords" @page="onPage" v-model:rows="rows" :totalRecords="totalRecords" @page="onPage"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
:rows-per-page-options="[10, 25, 50]" :rows-per-page-options="[10, 25, 50]"
current-page-report-template="Showing {first} to {last} of {totalRecords} entries" :lazy="true" current-page-report-template=" {first} {last} {totalRecords} " :lazy="true"
:show-current-page-report="true"> :show-current-page-report="true">
<template #paginatorLeft> <template #paginatorLeft>
<div class="flex items-center"> <div class="flex items-center">
Per Page: {{ rows }} 每页: {{ rows }}
</div> </div>
</template> </template>
<template #paginatorRight> <template #paginatorRight>
<div class="flex items-center"> <div class="flex items-center">
Page {{ currentPage }} of {{ totalPages }} {{ currentPage }} {{ totalPages }}
</div> </div>
</template> </template>
<template #empty> <template #empty>
<div class="text-center p-4">No media files found.</div> <div class="text-center p-4">未找到媒体文件</div>
</template> </template>
<template #loading> <template #loading>
<div class="flex flex-col items-center justify-center p-4"> <div class="flex flex-col items-center justify-center p-4">
<ProgressSpinner style="width:50px;height:50px" /> <ProgressSpinner style="width:50px;height:50px" />
<span class="mt-2">Loading media data...</span> <span class="mt-2">加载中...</span>
</div> </div>
</template> </template>
<Column field="name" header="File Name" sortable> <Column field="name" header="文件名" sortable>
<template #body="{ data }"> <template #body="{ data }">
<div class="flex items-center"> <div class="flex items-center">
<div v-if="data.thumbnail_url" class="flex-shrink-0 h-10 w-10 mr-3"> <div v-if="data.thumbnail_url" class="flex-shrink-0 h-10 w-10 mr-3">
@@ -232,26 +232,25 @@ const formatFileSize = (bytes) => {
</template> </template>
</Column> </Column>
<Column field="upload_time" header="Upload Time" sortable></Column> <Column field="upload_time" header="上传时间" sortable></Column>
<Column field="file_size" header="File Size" sortable> <Column field="file_size" header="文件大小" sortable>
<template #body="{ data }"> <template #body="{ data }">
{{ formatFileSize(data.file_size) }} {{ formatFileSize(data.file_size) }}
</template> </template>
</Column> </Column>
<Column field="media_type" header="File Type" sortable> <Column field="media_type" header="文件类型" sortable>
<template #body="{ data }"> <template #body="{ data }">
<Badge :value="data.file_type" :severity="getBadgeSeverity(data.file_type)" /> <Badge :value="data.file_type" :severity="getBadgeSeverity(data.file_type)" />
</template> </template>
<template #filter="{ filterModel, filterCallback }"> <template #filter="{ filterModel, filterCallback }">
<Dropdown v-model="filterModel.value" @change="filterCallback()" :options="mediaTypes" <Dropdown v-model="filterModel.value" @change="filterCallback()" :options="mediaTypes"
optionLabel="name" optionValue="value" placeholder="Any" class="p-column-filter" optionLabel="name" optionValue="value" placeholder="全部" class="p-column-filter" showClear />
showClear />
</template> </template>
</Column> </Column>
<Column header="Actions" :exportable="false" style="min-width:8rem"> <Column header="" :exportable="false" style="min-width:8rem">
<template #body="{ data }"> <template #body="{ data }">
<div class="flex justify-center space-x-2"> <div class="flex justify-center space-x-2">
<Button icon="pi pi-eye" rounded text severity="info" @click="previewFile(data)" <Button icon="pi pi-eye" rounded text severity="info" @click="previewFile(data)"
@@ -268,21 +267,21 @@ const formatFileSize = (bytes) => {
</div> </div>
<!-- Upload Dialog --> <!-- Upload Dialog -->
<Dialog v-model:visible="uploadDialogVisible" header="Upload Media Files" :modal="true" :dismissableMask="true" <Dialog v-model:visible="uploadDialogVisible" header="上传媒体文件" :modal="true" :dismissableMask="true" :closable="true"
:closable="true" :style="{ width: '50vw' }" :breakpoints="{ '960px': '75vw', '640px': '90vw' }"> :style="{ width: '50vw' }" :breakpoints="{ '960px': '75vw', '640px': '90vw' }">
<FileUpload name="media[]" url="/api/upload" @upload="onUpload" :multiple="true" <FileUpload name="media[]" url="/api/upload" @upload="onUpload" :multiple="true"
accept="image/*,video/*,audio/*,.pdf,.doc,.docx" :maxFileSize="50000000" class="w-full"> accept="image/*,video/*,audio/*,.pdf,.doc,.docx" :maxFileSize="50000000" class="w-full">
<template #empty> <template #empty>
<div class="flex flex-col items-center justify-center p-8"> <div class="flex flex-col items-center justify-center p-8">
<i class="pi pi-cloud-upload text-5xl text-blue-500 mb-4"></i> <i class="pi pi-cloud-upload text-5xl text-blue-500 mb-4"></i>
<p class="text-gray-600 text-center mb-2">Drag and drop files here or click to browse</p> <p class="text-gray-600 text-center mb-2">拖拽文件到此处或点击上传</p>
<p class="text-gray-400 text-sm text-center">Supports: JPG, PNG, GIF, MP4, PDF, DOC</p> <p class="text-gray-400 text-sm text-center">支持: MP4, JPG, PNG, GIF, MP4, PDF, DOC</p>
</div> </div>
</template> </template>
</FileUpload> </FileUpload>
<template #footer> <template #footer>
<Button label="Cancel" icon="pi pi-times" @click="closeUploadDialog" text severity="secondary" /> <Button label="取消" icon="pi pi-times" @click="closeUploadDialog" text severity="secondary" />
</template> </template>
</Dialog> </Dialog>
</template> </template>