From 275661e025e95ec415e20c62d195ee227bdea6f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E4=B8=91=E8=B7=AF=E4=BA=BA?= <2278757482@qq.com> Date: Thu, 2 Dec 2021 10:36:00 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=AE=9A=E4=B9=89=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E7=9A=84=E5=81=87=E5=88=A0=E9=99=A4trait=E7=B1=BB=E4=B8=8E?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=8C=83=E5=9B=B4=EF=BC=9B=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E6=A8=A1=E5=9E=8B=E7=9A=84=E5=81=87=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8Cbaseservice=E6=97=A0=E9=9C=80?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E6=A8=A1=E5=9E=8B=E6=98=AF=E5=90=A6=E5=81=87?= =?UTF-8?q?=E5=88=A0=E9=99=A4=EF=BC=8C=E7=9B=B4=E6=8E=A5=E8=B0=83=E7=94=A8?= =?UTF-8?q?delete=E5=8D=B3=E5=8F=AF=E5=AE=9E=E7=8E=B0=E5=81=87=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E7=9A=84=E5=8A=9F=E8=83=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Models/Model.php | 31 +--- app/Models/SoftDelete/DeleteScope.php | 143 +++++++++++++++ app/Models/SoftDelete/SoftDelete.php | 194 +++++++++++++++++++++ app/Modules/Admin/Services/BaseService.php | 6 +- app/Scopes/DeleteScope.php | 31 ---- 5 files changed, 340 insertions(+), 65 deletions(-) create mode 100644 app/Models/SoftDelete/DeleteScope.php create mode 100644 app/Models/SoftDelete/SoftDelete.php delete mode 100644 app/Scopes/DeleteScope.php diff --git a/app/Models/Model.php b/app/Models/Model.php index ccdea0b..8a5d52f 100644 --- a/app/Models/Model.php +++ b/app/Models/Model.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Models\SoftDelete\SoftDelete; use App\Scopes\DeleteScope; use App\Traits\Instance; use App\Traits\MysqlTable; @@ -10,6 +11,7 @@ use Illuminate\Database\Eloquent\Model as EloquentModel; class Model extends EloquentModel { + use SoftDelete; use MysqlTable; use Instance; use HasFactory; @@ -48,22 +50,6 @@ class Model extends EloquentModel return $this->attributes[self::UPDATED_AT]; } - /** - * 自定义的软删除 - */ - protected $is_delete = 1; //是否开启删除(1.开启删除,就是直接删除;0.假删除) - protected $delete_field = 'is_delete'; //删除字段 - - public function getIsDelete() - { - return $this->is_delete; - } - - public function getDeleteField() - { - return $this->delete_field; - } - /** * 不可批量赋值的属性 * @@ -71,19 +57,6 @@ class Model extends EloquentModel */ protected $guarded = []; - /** - * 模型的 "booted" 方法 - * - * 应用全局作用域 - * - * @return void - */ - protected static function booted() - { - // 假删除的作用域 - static::addGlobalScope(new DeleteScope(new static)); - } - public static function firstByWhere($where) { return self::where($where)->first(); diff --git a/app/Models/SoftDelete/DeleteScope.php b/app/Models/SoftDelete/DeleteScope.php new file mode 100644 index 0000000..ff1a32b --- /dev/null +++ b/app/Models/SoftDelete/DeleteScope.php @@ -0,0 +1,143 @@ +getIsDelete() == 0) $builder->where($model->getQualifiedDeletedAtColumn(), $model->getIsDelete()); + } + + /** + * Extend the query builder with the needed functions. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + public function extend(Builder $builder) + { + // 假删除时,才需要调用扩展方法与更新字段状态 + if ($builder->getModel()->getIsDelete() == 0){ + foreach ($this->extensions as $extension) { + $this->{"add{$extension}"}($builder); + } + + $builder->onDelete(function (Builder $builder) { + $column = $this->getDeletedAtColumn($builder); + + return $builder->update([ + $column => 1, + ]); + }); + } + } + + /** + * Get the "deleted at" column for the builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return string + */ + protected function getDeletedAtColumn(Builder $builder) + { + if (count((array) $builder->getQuery()->joins) > 0) { + return $builder->getModel()->getQualifiedDeletedAtColumn(); + } + + return $builder->getModel()->getDeletedAtColumn(); + } + + /** + * Add the restore extension to the builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + protected function addRestore(Builder $builder) + { + $builder->macro('restore', function (Builder $builder) { + $builder->withTrashed(); + + return $builder->update([$builder->getModel()->getDeletedAtColumn() => 0]); + }); + } + + /** + * Add the with-trashed extension to the builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + protected function addWithTrashed(Builder $builder) + { + $builder->macro('withTrashed', function (Builder $builder, $withTrashed = true) { + if (! $withTrashed) { + return $builder->withoutTrashed(); + } + + return $builder->withoutGlobalScope($this); + }); + } + + /** + * Add the without-trashed extension to the builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + protected function addWithoutTrashed(Builder $builder) + { + $builder->macro('withoutTrashed', function (Builder $builder) { + $model = $builder->getModel(); + + $builder->withoutGlobalScope($this)->where($model->getQualifiedDeletedAtColumn(), 0); + + return $builder; + }); + } + + /** + * Add the only-trashed extension to the builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + protected function addOnlyTrashed(Builder $builder) + { + $builder->macro('onlyTrashed', function (Builder $builder) { + $model = $builder->getModel(); + + $builder->withoutGlobalScope($this)->where($model->getQualifiedDeletedAtColumn(), 0); + + return $builder; + }); + } +} diff --git a/app/Models/SoftDelete/SoftDelete.php b/app/Models/SoftDelete/SoftDelete.php new file mode 100644 index 0000000..09807b7 --- /dev/null +++ b/app/Models/SoftDelete/SoftDelete.php @@ -0,0 +1,194 @@ +is_delete; + } + + public function getDeleteField() + { + return static::DELETE_FIELD; + } + + /** + * Boot the soft deleting trait for a model. + * + * @return void + */ + public static function bootSoftDelete() + { + static::addGlobalScope(new DeleteScope()); + } + + /** + * Force a hard delete on a soft deleted model. + * + * @return bool|null + */ + public function forceDelete() + { + $this->is_delete = 1; + + return tap($this->delete(), function ($deleted) { + $this->is_delete = 0; + + if ($deleted) { + $this->fireModelEvent('forceDeleted', false); + } + }); + } + + /** + * Perform the actual delete query on this model instance. + * + * @return mixed + */ + protected function performDeleteOnModel() + { + if ($this->is_delete) { + $this->exists = false; + + return $this->setKeysForSaveQuery($this->newModelQuery())->forceDelete(); + } + + return $this->runSoftDelete(); + } + + /** + * Perform the actual delete query on this model instance. + * + * @return void + */ + protected function runSoftDelete() + { + $query = $this->setKeysForSaveQuery($this->newModelQuery()); + + $time = $this->freshTimestamp(); + + $columns = [$this->getDeletedAtColumn() => 1]; + + $this->{$this->getDeletedAtColumn()} = $time; + + if ($this->timestamps && ! is_null($this->getUpdatedAtColumn())) { + $this->{$this->getUpdatedAtColumn()} = $time; + + $columns[$this->getUpdatedAtColumn()] = $this->fromDateTime($time); + } + + $query->update($columns); + + $this->syncOriginalAttributes(array_keys($columns)); + + $this->fireModelEvent('trashed', false); + } + + /** + * Restore a soft-deleted model instance. + * + * @return bool|null + */ + public function restore() + { + // If the restoring event does not return false, we will proceed with this + // restore operation. Otherwise, we bail out so the developer will stop + // the restore totally. We will clear the deleted timestamp and save. + if ($this->fireModelEvent('restoring') === false) { + return false; + } + + $this->{$this->getDeletedAtColumn()} = null; + + // Once we have saved the model, we will fire the "restored" event so this + // developer will do anything they need to after a restore operation is + // totally finished. Then we will return the result of the save call. + $this->exists = true; + + $result = $this->save(); + + $this->fireModelEvent('restored', false); + + return $result; + } + + /** + * Determine if the model instance has been soft-deleted. + * + * @return bool + */ + public function trashed() + { + return ! is_null($this->{$this->getDeletedAtColumn()}); + } + + /** + * Register a "softDeleted" model event callback with the dispatcher. + * + * @param \Closure|string $callback + * @return void + */ + public static function softDeleted($callback) + { + static::registerModelEvent('trashed', $callback); + } + + /** + * Register a "restoring" model event callback with the dispatcher. + * + * @param \Closure|string $callback + * @return void + */ + public static function restoring($callback) + { + static::registerModelEvent('restoring', $callback); + } + + /** + * Register a "restored" model event callback with the dispatcher. + * + * @param \Closure|string $callback + * @return void + */ + public static function restored($callback) + { + static::registerModelEvent('restored', $callback); + } + + /** + * Register a "forceDeleted" model event callback with the dispatcher. + * + * @param \Closure|string $callback + * @return void + */ + public static function forceDeleted($callback) + { + static::registerModelEvent('forceDeleted', $callback); + } + + /** + * Get the name of the "deleted at" column. + * + * @return string + */ + public function getDeletedAtColumn() + { + return defined('static::DELETED_AT') ? static::DELETED_FIELD : 'is_delete'; + } + + /** + * Get the fully qualified "deleted at" column. + * + * @return string + */ + public function getQualifiedDeletedAtColumn() + { + return $this->qualifyColumn($this->getDeletedAtColumn()); + } +} diff --git a/app/Modules/Admin/Services/BaseService.php b/app/Modules/Admin/Services/BaseService.php index 891528e..c3de2ca 100644 --- a/app/Modules/Admin/Services/BaseService.php +++ b/app/Modules/Admin/Services/BaseService.php @@ -110,11 +110,7 @@ class BaseService extends Service if ($this->model instanceof MonthModel && isset($params['month'])){ $this->model = $this->model->setMonthTable($params['month']); } - if ($this->model->getIsDelete() == 0){ - return $this->model->whereIn($primaryKey, $ids)->update([$this->model->getDeleteField() => 1]); - }else{ - return $this->model->whereIn($primaryKey, $ids)->delete(); - } + return $this->model->whereIn($primaryKey, $ids)->delete(); } /** diff --git a/app/Scopes/DeleteScope.php b/app/Scopes/DeleteScope.php deleted file mode 100644 index 6fe95f3..0000000 --- a/app/Scopes/DeleteScope.php +++ /dev/null @@ -1,31 +0,0 @@ -is_delete = $model->getIsDelete(); - $this->delete_field = $model->getDeleteField(); - } - - /** - * 把约束加到 Eloquent 查询构造中 - * - * @param \Illuminate\Database\Eloquent\Builder $builder - * @param \Illuminate\Database\Eloquent\Model $model - * @return void - */ - public function apply(Builder $builder, Model $model) - { - if ($this->is_delete == 0) $builder->where($this->delete_field, $this->is_delete); - } -} -- Gitee From 0a6bae2a40e3c7567033dc89fcb8123165be069b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E4=B8=91=E8=B7=AF=E4=BA=BA?= <2278757482@qq.com> Date: Tue, 19 Apr 2022 21:50:04 +0800 Subject: [PATCH 2/2] optimize --- app/Modules/Bbs/Resources/views/layouts/master.blade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Modules/Bbs/Resources/views/layouts/master.blade.php b/app/Modules/Bbs/Resources/views/layouts/master.blade.php index b3b5e5c..e3fb12d 100644 --- a/app/Modules/Bbs/Resources/views/layouts/master.blade.php +++ b/app/Modules/Bbs/Resources/views/layouts/master.blade.php @@ -8,8 +8,8 @@