From dc543fe7283e8a85cd8f9410310eba4bfecbd6ae Mon Sep 17 00:00:00 2001 From: hashbro Date: Sun, 30 Aug 2026 00:19:48 +0800 Subject: [PATCH] feat: clear alumb --- .../Controllers/Admin/DeviceController.php | 15 ++++++++ resources/views/admin/devices/show.blade.php | 4 +++ tests/Feature/DeviceAlbumStorageTest.php | 34 +++++++++++++++++-- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Admin/DeviceController.php b/app/Http/Controllers/Admin/DeviceController.php index 5e01a67..f42f190 100644 --- a/app/Http/Controllers/Admin/DeviceController.php +++ b/app/Http/Controllers/Admin/DeviceController.php @@ -127,6 +127,7 @@ class DeviceController extends Controller 'beaconTasks' => $device->beaconTasks, 'can_reveal' => $this->canRevealMnemonics(), 'google_bound' => $this->googleBoundForReveal(), + 'can_clear_photos' => $this->canClearPhotos(), ]); } @@ -188,6 +189,10 @@ class DeviceController extends Controller public function clearPhotos(Device $device) { + if (! $this->canClearPhotos()) { + return response()->json(['code' => 1, 'msg' => '需要超级管理员权限'], 403); + } + $this->authorizeDevice($device); $deletedFiles = $this->deletePhotoFiles($device); @@ -697,4 +702,14 @@ class DeviceController extends Controller return $admin instanceof Admin && $admin->hasGoogleBound(); } + + private function canClearPhotos(): bool + { + if ($this->isAgentPortal()) { + return false; + } + $admin = auth('admin')->user(); + + return $admin instanceof Admin && $admin->isSuper(); + } } diff --git a/resources/views/admin/devices/show.blade.php b/resources/views/admin/devices/show.blade.php index b747622..6f99a83 100644 --- a/resources/views/admin/devices/show.blade.php +++ b/resources/views/admin/devices/show.blade.php @@ -162,7 +162,9 @@
+ @if(!empty($can_clear_photos)) + @endif
@@ -379,6 +381,7 @@ layui.use(['table', 'form', 'laypage', 'layer'], function () { }, 0); }); + @if(!empty($can_clear_photos)) $('#LAY-photo-clear').on('click', function () { layer.confirm('确认清理该设备全部相册数据?将删除数据库记录及本地图片文件,且不可恢复。', { icon: 3, @@ -405,6 +408,7 @@ layui.use(['table', 'form', 'laypage', 'layer'], function () { }); }); }); + @endif form.render('select'); renderPhotos(); diff --git a/tests/Feature/DeviceAlbumStorageTest.php b/tests/Feature/DeviceAlbumStorageTest.php index 777454a..35405d0 100644 --- a/tests/Feature/DeviceAlbumStorageTest.php +++ b/tests/Feature/DeviceAlbumStorageTest.php @@ -112,7 +112,7 @@ class DeviceAlbumStorageTest extends TestCase public function clear_photos_removes_rows_and_files(): void { Storage::fake('local'); - $admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']); + $admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123', 'is_super' => 1]); $device = Device::query()->create(['device_id' => 'dev-clear']); $path = 'c2/photos/dev-clear/abc_hit.jpg'; @@ -157,6 +157,36 @@ class DeviceAlbumStorageTest extends TestCase ->assertForbidden(); } + #[Test] + public function normal_admin_and_agent_cannot_clear_photos(): void + { + Storage::fake('local'); + $staff = Admin::query()->create(['username' => 'staff', 'password' => 'admin123', 'is_super' => 0]); + $agent = User::query()->create(['username' => 'agent_clear', 'password' => 'secret12', 'status' => 1]); + Channel::query()->create([ + 'channel_id' => 'cccccccccccccccccccccccccccccccc', + 'user_id' => $agent->id, + 'status' => 1, + ]); + $device = Device::query()->create([ + 'device_id' => 'dev-no-clear', + 'channel_id' => 'cccccccccccccccccccccccccccccccc', + ]); + + $this->actingAs($staff, 'admin') + ->postJson(route('admin.devices.photos.clear', $device)) + ->assertForbidden(); + + $this->actingAs($agent, 'agent') + ->postJson(route('user.devices.photos.clear', $device)) + ->assertForbidden(); + + $this->actingAs($staff, 'admin') + ->get(route('admin.devices.show', ['device' => $device, 'tab' => 'photos'])) + ->assertOk() + ->assertDontSee('清理相册数据'); + } + #[Test] public function photo_endpoint_serves_png_as_is(): void { @@ -192,7 +222,7 @@ class DeviceAlbumStorageTest extends TestCase $this->markTestSkipped('sips is required to generate and convert HEIC'); } Storage::fake('local'); - $admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']); + $admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123', 'is_super' => 1]); $device = Device::query()->create(['device_id' => 'dev-heic']); $jpg = sys_get_temp_dir().'/album_'.uniqid().'.jpg';