import { useEffect, useState } from 'react' import { Link } from 'react-router-dom' import toast from 'react-hot-toast' import { Home, RotateCcw, Square, CheckSquare, Trash2 } from 'lucide-react' import { recycleAPI } from '../api/recycle' import { confirmAction } from '../components/confirmAction' import type { Media } from '../types' export function RecycleBinPage() { const [items, setItems] = useState([]) const [loading, setLoading] = useState(true) const [selectedIds, setSelectedIds] = useState([]) const [batchBusy, setBatchBusy] = useState('') const refresh = () => recycleAPI .list() .then((rows) => { setItems(rows) setSelectedIds((current) => current.filter((id) => rows.some((item) => item.id === id))) }) .finally(() => setLoading(false)) useEffect(() => { refresh().catch(() => undefined) }, []) const allSelected = items.length > 0 && selectedIds.length === items.length const toggleAll = () => { setSelectedIds(allSelected ? [] : items.map((item) => item.id)) } const toggleOne = (id: string) => { setSelectedIds((current) => current.includes(id) ? current.filter((item) => item !== id) : [...current, id]) } const runBatch = async (mode: 'restore' | 'purge') => { if (selectedIds.length === 0) return if (mode === 'purge' && !(await confirmAction({ title: '批量彻底删除记录', message: `彻底删除选中的 ${selectedIds.length} 条记录? (磁盘文件保留)`, confirmText: '彻底删除', }))) return setBatchBusy(mode) try { const result = await runRecycleBatchRequest(mode, selectedIds) toast.success(`${mode === 'restore' ? '恢复' : '彻底删除'}完成:${result.applied} 条`) setSelectedIds([]) await refresh() } catch (err: unknown) { const response = (err as { response?: { status?: number; data?: { error?: string } }; message?: string })?.response const msg = response?.data?.error || (response?.status ? `批量操作失败 (${response.status})` : (err as { message?: string })?.message || '批量操作失败') toast.error(msg) } finally { setBatchBusy('') } } const runRecycleBatchRequest = async (mode: 'restore' | 'purge', ids: string[]) => { try { return mode === 'restore' ? await recycleAPI.restoreMany(ids) : await recycleAPI.purgeMany(ids) } catch (err: unknown) { const status = (err as { response?: { status?: number } })?.response?.status if (status !== 404 && status !== 405) throw err let applied = 0 for (const id of ids) { if (mode === 'restore') { await recycleAPI.restore(id) } else { await recycleAPI.purge(id) } applied += 1 } return { applied, errors: [] as string[] } } } return (

回收站

软删除的媒体保留在数据库中,可以恢复。彻底删除不会移除磁盘上的文件,只会从数据库清除条目。

系统最多保留最新 200 条回收站记录,超过后会自动清理旧记录。

返回系统首页
{loading &&

加载中…

} {!loading && items.length === 0 &&

回收站为空。

} {items.length > 0 && (
已选择 {selectedIds.length} / {items.length} 条
{items.map((m) => ( ))}
标题 路径 操作
{m.title} {m.path}
)}
) }