删除过滤

master
lion 3 months ago
parent 062fd5d9a2
commit 4e0d99a2b7

@ -68,13 +68,7 @@ class ChannelEntryController extends Controller
}
$user->fill($userPayload)->save();
$application = Application::query()->firstOrCreate(
[
'user_id' => $user->id,
'competition_id' => $competition->id,
],
['status' => 'draft']
);
$application = Application::firstOrCreateDraft($user->id, $competition->id);
$application->fill([
'signup_channel_id' => $channel->id,
'signup_channel_code' => $channel->channel_code,

@ -3,6 +3,7 @@
namespace App\Models;
use App\Support\ProjectCode;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
@ -11,6 +12,8 @@ use Illuminate\Validation\ValidationException;
class Application extends Model
{
public const EXCLUDE_SOFT_DELETED_SCOPE = 'excludeSoftDeleted';
protected $fillable = [
'project_code',
'user_id',
@ -44,10 +47,24 @@ class Application extends Model
'promise_signed_at' => 'datetime',
'submitted_at' => 'datetime',
'signup_channel_entered_at' => 'datetime',
'deleted_at' => 'datetime',
];
public static function hasDeletedAtColumn(): bool
{
return Schema::hasColumn((new static)->getTable(), 'deleted_at');
}
protected static function booted(): void
{
static::addGlobalScope(self::EXCLUDE_SOFT_DELETED_SCOPE, function (Builder $builder): void {
if (! static::hasDeletedAtColumn()) {
return;
}
$builder->whereNull($builder->getModel()->qualifyColumn('deleted_at'));
});
static::created(function (Application $application): void {
if (! Schema::hasColumn($application->getTable(), 'project_code')) {
return;
@ -63,6 +80,23 @@ class Application extends Model
public static function firstOrCreateDraft(int $userId, int $competitionId): self
{
if (static::hasDeletedAtColumn()) {
$trashed = static::withoutGlobalScope(self::EXCLUDE_SOFT_DELETED_SCOPE)
->where('user_id', $userId)
->where('competition_id', $competitionId)
->whereNotNull('deleted_at')
->first();
if ($trashed !== null) {
$trashed->forceFill([
'deleted_at' => null,
'status' => 'draft',
])->save();
return $trashed->fresh();
}
}
return static::query()->firstOrCreate(
[
'user_id' => $userId,

@ -0,0 +1,55 @@
<?php
namespace Tests\Feature;
use App\Models\AdminUser;
use App\Models\Application;
use App\Models\Competition;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;
class AdminApplicationListTest extends TestCase
{
use RefreshDatabase;
public function test_admin_application_list_excludes_soft_deleted_records(): void
{
Sanctum::actingAs(AdminUser::query()->create([
'username' => 'admin_list',
'password_hash' => 'unused',
'name' => '管理员',
'status' => 'active',
]));
$competition = Competition::query()->create([
'slug' => 'xxf',
'name' => '测试赛',
'published' => true,
]);
$active = Application::query()->create([
'user_id' => User::query()->create(['mobile' => '13800138001'])->id,
'competition_id' => $competition->id,
'status' => 'submitted',
'project_name' => '有效项目',
]);
$deleted = Application::query()->create([
'user_id' => User::query()->create(['mobile' => '13800138002'])->id,
'competition_id' => $competition->id,
'status' => 'submitted',
'project_name' => '已删除项目',
]);
$deleted->forceFill(['deleted_at' => now()])->save();
$response = $this->getJson("/api/v1/admin/competitions/{$competition->id}/applications?status=submitted")
->assertOk();
$ids = collect($response->json('data'))->pluck('id')->all();
$this->assertContains($active->id, $ids);
$this->assertNotContains($deleted->id, $ids);
}
}
Loading…
Cancel
Save