user medal add more bulk actions

This commit is contained in:
xiaomlove
2025-07-15 01:33:59 +07:00
parent 3ffdec1f4a
commit d64243fe6a
9 changed files with 239 additions and 3 deletions
@@ -2,11 +2,14 @@
namespace App\Filament\Resources\User;
use App\Filament\OptionsTrait;
use App\Filament\Resources\User\UserMedalResource\Pages;
use App\Filament\Resources\User\UserMedalResource\RelationManagers;
use App\Models\Medal;
use App\Models\NexusModel;
use App\Models\UserMedal;
use App\Repositories\MedalRepository;
use Carbon\Carbon;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
@@ -14,10 +17,13 @@ use Filament\Tables\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Collection;
use Illuminate\Support\HtmlString;
class UserMedalResource extends Resource
{
use OptionsTrait;
protected static ?string $model = UserMedal::class;
protected static ?string $navigationIcon = 'heroicon-o-flag';
@@ -57,8 +63,10 @@ class UserMedalResource extends Resource
,
Tables\Columns\TextColumn::make('medal.name')->label(__('label.medal.label'))->searchable(),
Tables\Columns\ImageColumn::make('medal.image_large')->label(__('label.image')),
Tables\Columns\TextColumn::make('expire_at')->label(__('label.expire_at'))->dateTime(),
Tables\Columns\TextColumn::make('expire_at')->label(__('label.expire_at')),
Tables\Columns\TextColumn::make('bonus_addition_expire_at')->label(__('medal.bonus_addition_expire_at')),
Tables\Columns\TextColumn::make('wearingStatusText')->label(__('label.status')),
Tables\Columns\TextColumn::make('created_at')->label(__('label.created_at')),
])
->defaultSort('id', 'desc')
->filters([
@@ -76,6 +84,42 @@ class UserMedalResource extends Resource
->options(Medal::query()->pluck('name', 'id')->toArray())
->label(__('medal.label'))
,
Tables\Filters\SelectFilter::make('is_expired')
->options(self::getYesNoOptions())
->label(__('medal.is_expired'))
->query(function (Builder $query, array $data) {
if (isset($data['value']) && $data['value'] === "0") {
//未过期,为 null 或大于当前时间
$query->where(function ($query) {
$query->whereNull('expire_at')->orWhere('expire_at', '>', now());
});
}
if (isset($data['value']) && $data['value'] === "1") {
//已过期, 不为 null 且小于当前时间
$query->whereNotNull('expire_at')->where("expire_at", "<", now());
}
})
,
Tables\Filters\SelectFilter::make('is_bonus_addition_expired')
->options(self::getYesNoOptions())
->label(__('medal.is_bonus_addition_expired'))
->query(function (Builder $query, array $data) {
if (isset($data['value']) && $data['value'] === "0") {
//未过期,为 null 或大于当前时间
$query->where(function ($query) {
$query->whereNull('bonus_addition_expire_at')->orWhere('bonus_addition_expire_at', '>', now());
});
}
if (isset($data['value']) && $data['value'] === "1") {
//已过期, 不为 null 且小于当前时间
$query->whereNotNull('bonus_addition_expire_at')->where("bonus_addition_expire_at", "<", now());
}
})
,
Tables\Filters\SelectFilter::make('status')
->options(UserMedal::listWearingStatusLabels())
->label(__('label.status'))
,
])
->actions([
Tables\Actions\DeleteAction::make()->using(function (NexusModel $record) {
@@ -84,8 +128,89 @@ class UserMedalResource extends Resource
})
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
self::buildBulkActionIncreaseExpireAt('expire_at'),
self::buildBulkActionUpdateExpireAt('expire_at'),
self::buildBulkActionCancelExpireAt('expire_at'),
])->label(sprintf("%s-%s", __('label.bulk'), __('label.expire_at'))),
Tables\Actions\BulkActionGroup::make([
self::buildBulkActionIncreaseExpireAt('bonus_addition_expire_at'),
self::buildBulkActionUpdateExpireAt('bonus_addition_expire_at'),
self::buildBulkActionCancelExpireAt('bonus_addition_expire_at'),
])->label(sprintf("%s-%s", __('label.bulk'), __('medal.bonus_addition_expire_at'))),
Tables\Actions\DeleteBulkAction::make(),
])
->selectCurrentPageOnly()
;
}
]);
private static function buildBulkActionIncreaseExpireAt(string $filed): Tables\Actions\BulkAction
{
return Tables\Actions\BulkAction::make("bulkActionIncrease$filed")
->label(__('medal.bulk_action_increase'))
->modalHeading(__('medal.bulk_action_increase_' . $filed))
->form([
Forms\Components\TextInput::make('increase_duration')
->label(__('medal.increase_duration'))
->helperText(__('medal.increase_duration_help'))
->integer()
->required(),
])
->action(function (Collection $collection, array $data) use ($filed) {
try {
$rep = new MedalRepository();
$rep->increaseExpireAt($collection, $filed, $data['increase_duration']);
send_admin_success_notification();
} catch (\Exception $e) {
send_admin_fail_notification($e->getMessage());
}
})
->deselectRecordsAfterCompletion()
;
}
private static function buildBulkActionUpdateExpireAt(string $filed): Tables\Actions\BulkAction
{
return Tables\Actions\BulkAction::make("bulkActionUpdate$filed")
->label(__('medal.bulk_action_update'))
->modalHeading(__('medal.bulk_action_update_' . $filed))
->form([
Forms\Components\DateTimePicker::make('update_expire_at')
->label(__('medal.update_expire_at'))
->helperText(__('medal.update_expire_at_help'))
->required(),
])
->action(function (Collection $collection, array $data) use ($filed) {
try {
$expireAt = Carbon::parse($data['update_expire_at']);
$rep = new MedalRepository();
$rep->updateExpireAt($collection, $filed, $expireAt);
send_admin_success_notification();
} catch (\Exception $e) {
send_admin_fail_notification($e->getMessage());
}
})
->deselectRecordsAfterCompletion()
;
}
private static function buildBulkActionCancelExpireAt(string $filed): Tables\Actions\BulkAction
{
return Tables\Actions\BulkAction::make("bulkActionCancel$filed")
->label(__('medal.bulk_action_cancel'))
->modalHeading(__('medal.bulk_action_cancel_' . $filed))
->requiresConfirmation()
->action(function (Collection $collection) use ($filed) {
try {
$rep = new MedalRepository();
$rep->cancelExpireAt($collection, $filed);
send_admin_success_notification();
} catch (\Exception $e) {
send_admin_fail_notification($e->getMessage());
}
})
->deselectRecordsAfterCompletion()
;
}
public static function getEloquentQuery(): Builder
+9 -1
View File
@@ -9,11 +9,19 @@ class UserMedal extends NexusModel
const STATUS_NOT_WEARING = 0;
const STATUS_WEARING = 1;
public function getWearingStatusTextAttribute()
public function getWearingStatusTextAttribute(): string
{
return nexus_trans("medal.wearing_status_text." . $this->status);
}
public static function listWearingStatusLabels(): array
{
return [
self::STATUS_WEARING => nexus_trans("medal.wearing_status_text." . self::STATUS_WEARING),
self::STATUS_NOT_WEARING => nexus_trans("medal.wearing_status_text." . self::STATUS_NOT_WEARING),
];
}
public function medal()
{
return $this->belongsTo(Medal::class, 'medal_id');
+48
View File
@@ -7,6 +7,7 @@ use App\Models\Setting;
use App\Models\User;
use App\Models\UserMedal;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Nexus\Database\NexusDB;
@@ -148,4 +149,51 @@ class MedalRepository extends BaseRepository
return NexusDB::statement($sql);
}
public function increaseExpireAt(Collection $collection, string $field, int $duration): void
{
$this->checkExpireField($field);
$idArr = $collection->pluck('id')->toArray();
$result = NexusDB::table("user_medals")
->whereIn('id', $idArr)
->whereNotNull($field)
->update([$field => NexusDB::raw("`$field` + INTERVAL $duration DAY")]);
do_log(sprintf(
"operator: %s, increase records: %s $field + $duration day, result: %s",
get_pure_username(), implode(', ', $idArr), $result
));
}
public function updateExpireAt(Collection $collection, string $field, Carbon $expireAt): void
{
$this->checkExpireField($field);
$idArr = $collection->pluck('id')->toArray();
$result = NexusDB::table("user_medals")
->whereIn('id', $idArr)
->update([$field => $expireAt]);
do_log(sprintf(
"operator: %s, update records: %s $field $expireAt, result: %s",
get_pure_username(), implode(', ', $idArr), $result
));
}
public function cancelExpireAt(Collection $collection, string $field): void
{
$this->checkExpireField($field);
$idArr = $collection->pluck('id')->toArray();
$result = NexusDB::table("user_medals")
->whereIn('id', $idArr)
->update([$field => NexusDB::raw("null")]);
do_log(sprintf(
"operator: %s, update records: %s $field null, result: %s",
get_pure_username(), implode(', ', $idArr), $result
));
}
private function checkExpireField(string $field): void
{
if (!in_array($field, ['expire_at', 'bonus_addition_expire_at'])) {
throw new \InvalidArgumentException("invalid field: $field");
}
}
}