diff --git a/app/Http/Controllers/User/ImageController.php b/app/Http/Controllers/User/ImageController.php index fe941e28..9c78c000 100644 --- a/app/Http/Controllers/User/ImageController.php +++ b/app/Http/Controllers/User/ImageController.php @@ -79,4 +79,15 @@ class ImageController extends Controller }); return $this->success('移动成功'); } + + public function delete(Request $request): Response + { + /** @var User $user */ + $user = Auth::user(); + /** @var Image $image */ + foreach ($user->images()->with('strategy')->whereIn('id', $request->all() ?: [])->cursor() as $image) { + $image->delete(); + } + return $this->success('删除成功'); + } } diff --git a/app/Models/Image.php b/app/Models/Image.php index c77ed6bb..dea9a952 100644 --- a/app/Models/Image.php +++ b/app/Models/Image.php @@ -3,12 +3,14 @@ namespace App\Models; use App\Enums\StrategyKey; +use App\Service\UploadService; use Carbon\Carbon; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Storage; +use League\Flysystem\Filesystem; /** * @property int $id @@ -74,6 +76,15 @@ class Image extends Model 'is_unhealthy' => 'bool', ]; + protected static function booted() + { + static::deleting(function (self $image) { + // TODO 检测是否启用了队列,放置队列中异步删除 + $adapter = (new UploadService())->getAdapter($image->strategy->key, $image->strategy->configs); + (new Filesystem($adapter))->delete($image->pathname); + }); + } + public function getFilenameAttribute(): string { return $this->alias_name ?: $this->origin_name; diff --git a/app/Service/UploadService.php b/app/Service/UploadService.php index ea3fa014..ea8b7070 100644 --- a/app/Service/UploadService.php +++ b/app/Service/UploadService.php @@ -170,7 +170,7 @@ class UploadService return $image; } - protected function getAdapter(int $disk, Collection $configs): AdapterInterface + public function getAdapter(int $disk, Collection $configs): AdapterInterface { return match ($disk) { StrategyKey::Local => new Local($configs->get('root') ?: config('filesystems.disks.uploads.root')), diff --git a/public/css/app.css b/public/css/app.css index 533399dd..f5d6beec 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -1255,14 +1255,14 @@ select { padding-left: 0.75rem; padding-right: 0.75rem; } -.px-2\.5 { - padding-left: 0.625rem; - padding-right: 0.625rem; -} .py-1\.5 { padding-top: 0.375rem; padding-bottom: 0.375rem; } +.px-2\.5 { + padding-left: 0.625rem; + padding-right: 0.625rem; +} .py-10 { padding-top: 2.5rem; padding-bottom: 2.5rem; diff --git a/public/css/justified-gallery/justifiedGallery.min.css b/public/css/justified-gallery/justifiedGallery.min.css old mode 100644 new mode 100755 diff --git a/public/css/viewer-js/viewer.min.css b/public/css/viewer-js/viewer.min.css old mode 100644 new mode 100755 diff --git a/public/js/app.js b/public/js/app.js index 8cb53a38..309583d0 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -5586,7 +5586,14 @@ window.utils = { window._ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"); window.$ = window.jQuery = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); window.toastr = __webpack_require__(/*! toastr */ "./node_modules/toastr/toastr.js"); -window.swal = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js"); +window.Swal = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js"); +window.Swal.mixin({ + customClass: { + confirmButton: 'btn btn-success', + cancelButton: 'btn btn-danger' + }, + buttonsStyling: false +}); toastr.options = { "closeButton": true, "debug": false, diff --git a/public/js/blueimp-file-upload/jquery.fileupload.js b/public/js/blueimp-file-upload/jquery.fileupload.js old mode 100644 new mode 100755 diff --git a/public/js/blueimp-file-upload/jquery.iframe-transport.js b/public/js/blueimp-file-upload/jquery.iframe-transport.js old mode 100644 new mode 100755 diff --git a/public/js/blueimp-file-upload/jquery.ui.widget.js b/public/js/blueimp-file-upload/jquery.ui.widget.js old mode 100644 new mode 100755 diff --git a/public/js/blueimp-load-image/load-image.all.min.js b/public/js/blueimp-load-image/load-image.all.min.js old mode 100644 new mode 100755 diff --git a/public/js/clipboard/clipboard.min.js b/public/js/clipboard/clipboard.min.js old mode 100644 new mode 100755 diff --git a/public/js/clipboard/index.browser.js b/public/js/clipboard/index.browser.js old mode 100644 new mode 100755 diff --git a/public/js/dragselect/ds.min.js b/public/js/dragselect/ds.min.js old mode 100644 new mode 100755 diff --git a/public/js/justified-gallery/jquery.justifiedGallery.min.js b/public/js/justified-gallery/jquery.justifiedGallery.min.js old mode 100644 new mode 100755 diff --git a/public/js/viewer-js/viewer.min.js b/public/js/viewer-js/viewer.min.js old mode 100644 new mode 100755 diff --git a/resources/js/bootstrap.js b/resources/js/bootstrap.js index b3af2186..e502710a 100644 --- a/resources/js/bootstrap.js +++ b/resources/js/bootstrap.js @@ -1,7 +1,15 @@ window._ = require('lodash'); window.$ = window.jQuery = require('jquery'); window.toastr = require('toastr'); -window.swal = require('sweetalert2') +window.Swal = require('sweetalert2') +window.Swal.mixin({ + customClass: { + confirmButton: 'btn btn-success', + cancelButton: 'btn btn-danger' + }, + buttonsStyling: false +}) + toastr.options = { "closeButton": true, diff --git a/resources/views/images.blade.php b/resources/views/images.blade.php index 47490783..34a49670 100644 --- a/resources/views/images.blade.php +++ b/resources/views/images.blade.php @@ -542,7 +542,33 @@ visible: _ => selectedAlbum.id !== undefined, }, detail: {text: '详细信息', action: e => {}}, - delete: {text: '删除', action: e => {}}, + delete: { + text: '删除', + action: e => { + Swal.fire({ + title: '确认要删除选中的图片?', + text: "删除后不可恢复,记录和文件同时删除", + icon: 'warning', + showCancelButton: true, + confirmButtonText: '确认删除', + cancelButtonText: '取消', + }).then((result) => { + if (result.isConfirmed) { + let selected = ds.getSelection().map(item => $(item).data('id')); + axios.delete('{{ route('user.images.delete') }}', { + data: selected, + }).then(response => { + if (response.data.status) { + resetImages(); + toastr.success(response.data.message); + } else { + toastr.warning(response.data.message); + } + }); + } + }) + }, + }, visibility: { text: '设置可见性', action: e => {}, diff --git a/routes/web.php b/routes/web.php index c9ada61d..20e544d8 100644 --- a/routes/web.php +++ b/routes/web.php @@ -25,6 +25,7 @@ Route::group(['middleware' => ['auth']], function () { Route::get('/images', [ImageController::class, 'index'])->name('images'); Route::group(['prefix' => 'user'], function () { Route::get('images', [ImageController::class, 'images'])->name('user.images'); + Route::delete('images', [ImageController::class, 'delete'])->name('user.images.delete'); Route::put('images/movement', [ImageController::class, 'movement'])->name('user.images.movement'); Route::get('albums', [AlbumController::class, 'albums'])->name('user.albums'); Route::post('albums', [AlbumController::class, 'create'])->name('user.album.create');