feat: 新增永久删除文件接口和前端删除按钮

后端新增 POST api/files/delete 接口,同时删除物理文件、缩略图和数据库记录。
前端在 FileCard 和 FileListItem 中增加 hover 可见的删除按钮,点击后弹出确认提示。
This commit is contained in:
2026-07-09 17:42:27 +08:00
parent 8c92d2fbac
commit 60878f9b6e
11 changed files with 587 additions and 3 deletions
@@ -272,6 +272,24 @@ function exitSearch() {
searchTotalPages.value = 0
}
async function deleteFile(file: FileRecordDto) {
if (!window.confirm(`确定要永久删除 "${file.fileName}" 吗?\n\n删除后无法恢复!`)) {
return
}
try {
await api.deleteFile(file.id)
await browseDirectory()
if (isSearching.value) {
await doSearch(searchPage.value)
}
if (selectedFile.value?.id === file.id) {
selectedFile.value = null
}
} catch (error) {
setError(error)
}
}
function updatePlaybackPosition(id: number, position: number) {
if (selectedFile.value?.id === id) {
selectedFile.value.playbackPosition = position
@@ -463,7 +481,7 @@ onBeforeUnmount(() => {
<p v-else-if="searchResults.length === 0" class="empty-state">无匹配文件</p>
<div v-else-if="viewMode === 'grid'" class="file-grid">
<template v-for="file in searchResults" :key="file.id">
<FileCard :file="file" show-created-time @select="selectSearchFile" />
<FileCard :file="file" show-created-time @select="selectSearchFile" @delete="deleteFile" />
<SelectedMediaPlayerHost
v-if="selectedFile?.id === file.id"
:ref="setMediaPlayer"
@@ -488,7 +506,7 @@ onBeforeUnmount(() => {
</div>
<div v-else class="file-list">
<template v-for="file in searchResults" :key="file.id">
<FileListItem :file="file" show-created-time @select="selectSearchFile" />
<FileListItem :file="file" show-created-time @select="selectSearchFile" @delete="deleteFile" />
<SelectedMediaPlayerHost
v-if="selectedFile?.id === file.id"
:ref="setMediaPlayer"
@@ -531,7 +549,7 @@ onBeforeUnmount(() => {
</p>
<div v-else-if="viewMode === 'grid'" class="file-grid">
<template v-for="file in recentFiles" :key="file.id">
<FileCard :file="file" :selected="selectedFile?.id === file.id" @select="selectFile" />
<FileCard :file="file" :selected="selectedFile?.id === file.id" @select="selectFile" @delete="deleteFile" />
<SelectedMediaPlayerHost
v-if="selectedFile?.id === file.id"
:ref="setMediaPlayer"
@@ -561,6 +579,7 @@ onBeforeUnmount(() => {
:selected="selectedFile?.id === file.id"
:show-last-played="activeTab === 'recent-played'"
@select="selectFile"
@delete="deleteFile"
/>
<SelectedMediaPlayerHost
v-if="selectedFile?.id === file.id"
@@ -630,6 +649,7 @@ onBeforeUnmount(() => {
:selected="selectedFile?.id === file.id"
show-created-time
@select="selectFile"
@delete="deleteFile"
/>
<SelectedMediaPlayerHost
v-if="selectedFile?.id === file.id"
@@ -661,6 +681,7 @@ onBeforeUnmount(() => {
:selected="selectedFile?.id === file.id"
show-created-time
@select="selectFile"
@delete="deleteFile"
/>
<SelectedMediaPlayerHost
v-if="selectedFile?.id === file.id"