From 0e03c578f4bd8cb77bf8368905dba1d293cc0755 Mon Sep 17 00:00:00 2001 From: lion <120344285@qq.com> Date: Tue, 21 Apr 2026 11:39:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/UploadController.php | 30 +++++++++++++++++++ routes/api.php | 1 + 2 files changed, 31 insertions(+) diff --git a/app/Http/Controllers/Api/UploadController.php b/app/Http/Controllers/Api/UploadController.php index 163e56e..777c92b 100644 --- a/app/Http/Controllers/Api/UploadController.php +++ b/app/Http/Controllers/Api/UploadController.php @@ -8,6 +8,7 @@ use App\Http\Controllers\Controller; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Storage; use Throwable; class UploadController extends Controller @@ -89,4 +90,33 @@ class UploadController extends Controller return $clean !== false ? $clean : 'application/octet-stream'; } + + /** + * 删除 public 磁盘下已上传文件(仅 uploads/ 根目录内扁平文件)。仅超级管理员。 + */ + public function remove(Request $request): JsonResponse + { + abort_unless($request->user()?->isSuperAdmin(), 403, '仅超级管理员可删除上传文件'); + + $data = $request->validate([ + 'path' => ['required', 'string', 'max:500'], + ]); + + $path = str_replace('\\', '/', trim($data['path'])); + if (str_contains($path, '..') || ! str_starts_with($path, 'uploads/')) { + return response()->json(['message' => '无效路径'], 422); + } + + if (! preg_match('#^uploads/[a-zA-Z0-9][a-zA-Z0-9._-]*$#', $path)) { + return response()->json(['message' => '无效路径'], 422); + } + + if (! Storage::disk('public')->exists($path)) { + return response()->json(['message' => '文件不存在'], 404); + } + + Storage::disk('public')->delete($path); + + return response()->json(['message' => '已删除']); + } } diff --git a/routes/api.php b/routes/api.php index bca7edd..7c247ba 100644 --- a/routes/api.php +++ b/routes/api.php @@ -85,6 +85,7 @@ Route::middleware(['auth:sanctum', 'audit.log'])->group(function () { Route::put('/dict-items/{dictItem}', [DictItemController::class, 'update']); Route::delete('/dict-items/{dictItem}', [DictItemController::class, 'destroy']); Route::post('/upload', [UploadController::class, 'store']); + Route::post('/upload/delete', [UploadController::class, 'remove']); Route::get('/map/search', [MapController::class, 'search']); Route::get('/map/reverse-geocode', [MapController::class, 'reverseGeocode']); Route::get('/study-tours', [StudyTourController::class, 'index']);