mirror of
https://github.com/lkddi/nexusphp.git
synced 2026-04-24 20:17:24 +08:00
user medal add more bulk actions
This commit is contained in:
@@ -2,11 +2,14 @@
|
|||||||
|
|
||||||
namespace App\Filament\Resources\User;
|
namespace App\Filament\Resources\User;
|
||||||
|
|
||||||
|
use App\Filament\OptionsTrait;
|
||||||
use App\Filament\Resources\User\UserMedalResource\Pages;
|
use App\Filament\Resources\User\UserMedalResource\Pages;
|
||||||
use App\Filament\Resources\User\UserMedalResource\RelationManagers;
|
use App\Filament\Resources\User\UserMedalResource\RelationManagers;
|
||||||
use App\Models\Medal;
|
use App\Models\Medal;
|
||||||
use App\Models\NexusModel;
|
use App\Models\NexusModel;
|
||||||
use App\Models\UserMedal;
|
use App\Models\UserMedal;
|
||||||
|
use App\Repositories\MedalRepository;
|
||||||
|
use Carbon\Carbon;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
@@ -14,10 +17,13 @@ use Filament\Tables\Table;
|
|||||||
use Filament\Tables;
|
use Filament\Tables;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\HtmlString;
|
use Illuminate\Support\HtmlString;
|
||||||
|
|
||||||
class UserMedalResource extends Resource
|
class UserMedalResource extends Resource
|
||||||
{
|
{
|
||||||
|
use OptionsTrait;
|
||||||
|
|
||||||
protected static ?string $model = UserMedal::class;
|
protected static ?string $model = UserMedal::class;
|
||||||
|
|
||||||
protected static ?string $navigationIcon = 'heroicon-o-flag';
|
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\TextColumn::make('medal.name')->label(__('label.medal.label'))->searchable(),
|
||||||
Tables\Columns\ImageColumn::make('medal.image_large')->label(__('label.image')),
|
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('wearingStatusText')->label(__('label.status')),
|
||||||
|
Tables\Columns\TextColumn::make('created_at')->label(__('label.created_at')),
|
||||||
])
|
])
|
||||||
->defaultSort('id', 'desc')
|
->defaultSort('id', 'desc')
|
||||||
->filters([
|
->filters([
|
||||||
@@ -76,6 +84,42 @@ class UserMedalResource extends Resource
|
|||||||
->options(Medal::query()->pluck('name', 'id')->toArray())
|
->options(Medal::query()->pluck('name', 'id')->toArray())
|
||||||
->label(__('medal.label'))
|
->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([
|
->actions([
|
||||||
Tables\Actions\DeleteAction::make()->using(function (NexusModel $record) {
|
Tables\Actions\DeleteAction::make()->using(function (NexusModel $record) {
|
||||||
@@ -84,8 +128,89 @@ class UserMedalResource extends Resource
|
|||||||
})
|
})
|
||||||
])
|
])
|
||||||
->bulkActions([
|
->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
|
public static function getEloquentQuery(): Builder
|
||||||
|
|||||||
@@ -9,11 +9,19 @@ class UserMedal extends NexusModel
|
|||||||
const STATUS_NOT_WEARING = 0;
|
const STATUS_NOT_WEARING = 0;
|
||||||
const STATUS_WEARING = 1;
|
const STATUS_WEARING = 1;
|
||||||
|
|
||||||
public function getWearingStatusTextAttribute()
|
public function getWearingStatusTextAttribute(): string
|
||||||
{
|
{
|
||||||
return nexus_trans("medal.wearing_status_text." . $this->status);
|
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()
|
public function medal()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Medal::class, 'medal_id');
|
return $this->belongsTo(Medal::class, 'medal_id');
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use App\Models\Setting;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\UserMedal;
|
use App\Models\UserMedal;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Nexus\Database\NexusDB;
|
use Nexus\Database\NexusDB;
|
||||||
|
|
||||||
@@ -148,4 +149,51 @@ class MedalRepository extends BaseRepository
|
|||||||
return NexusDB::statement($sql);
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ return [
|
|||||||
'language' => 'Language',
|
'language' => 'Language',
|
||||||
'content' => 'Content',
|
'content' => 'Content',
|
||||||
'is_default' => 'Is default',
|
'is_default' => 'Is default',
|
||||||
|
'bulk' => 'Bulk',
|
||||||
'setting' => [
|
'setting' => [
|
||||||
'nav_text' => 'Setting',
|
'nav_text' => 'Setting',
|
||||||
'backup' => [
|
'backup' => [
|
||||||
|
|||||||
@@ -50,4 +50,22 @@ return [
|
|||||||
0 => 'Wearing',
|
0 => 'Wearing',
|
||||||
1 => 'Not wearing'
|
1 => 'Not wearing'
|
||||||
],
|
],
|
||||||
|
'bonus_addition_expire_at' => 'Bonus addition Expiration Time',
|
||||||
|
'is_expired' => 'Is Expired',
|
||||||
|
'is_bonus_addition_expired' => 'Is Bonus addition expired',
|
||||||
|
'is_wearing' => 'Is Wearing',
|
||||||
|
'increase_duration' => 'Increase Duration',
|
||||||
|
'increase_duration_help' => 'Unit: days. Uniformly extend the expiration time from the original value',
|
||||||
|
'update_expire_at' => 'Set expiration time',
|
||||||
|
'update_expire_at_help' => 'Uniformly set the expiration time to a specified value',
|
||||||
|
'bulk_action_increase' => 'Increase',
|
||||||
|
'bulk_action_update' => 'Update',
|
||||||
|
'bulk_action_cancel' => 'Cancel',
|
||||||
|
'bulk_action_increase_expire_at' => 'Bulk increase expiration time',
|
||||||
|
'bulk_action_update_expire_at' => 'Bulk update expiration time',
|
||||||
|
'bulk_action_cancel_expire_at' => 'Bulk cancel expiration time',
|
||||||
|
'bulk_action_increase_bonus_addition_expire_at' => 'Bulk extend bonus addition expiration time',
|
||||||
|
'bulk_action_update_bonus_addition_expire_at' => 'Bulk update bonus expiration time',
|
||||||
|
'bulk_action_cancel_bonus_addition_expire_at' => 'Bulk cancel bonus expiration time',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ return [
|
|||||||
'language' => '语言',
|
'language' => '语言',
|
||||||
'content' => '内容',
|
'content' => '内容',
|
||||||
'is_default' => '是否默认',
|
'is_default' => '是否默认',
|
||||||
|
'bulk' => '批量',
|
||||||
'setting' => [
|
'setting' => [
|
||||||
'nav_text' => '设置',
|
'nav_text' => '设置',
|
||||||
'backup' => [
|
'backup' => [
|
||||||
|
|||||||
@@ -50,4 +50,21 @@ return [
|
|||||||
0 => '未佩戴',
|
0 => '未佩戴',
|
||||||
1 => '已佩戴'
|
1 => '已佩戴'
|
||||||
],
|
],
|
||||||
|
'bonus_addition_expire_at' => '魔力加成过期时间',
|
||||||
|
'is_expired' => '是否过期',
|
||||||
|
'is_bonus_addition_expired' => '是否魔力加成过期',
|
||||||
|
'is_wearing' => '是否佩戴',
|
||||||
|
'increase_duration' => '延长时长',
|
||||||
|
'increase_duration_help' => '单位:天。将过期时间在原基础上统一延长',
|
||||||
|
'update_expire_at' => '设置过期时间',
|
||||||
|
'update_expire_at_help' => '将过期时间统一设置为指定值',
|
||||||
|
'bulk_action_increase' => '延长',
|
||||||
|
'bulk_action_update' => '设置',
|
||||||
|
'bulk_action_cancel' => '取消',
|
||||||
|
'bulk_action_increase_expire_at' => '批量延长过期时间',
|
||||||
|
'bulk_action_update_expire_at' => '批量设置过期时间',
|
||||||
|
'bulk_action_cancel_expire_at' => '批量取消过期时间',
|
||||||
|
'bulk_action_increase_bonus_addition_expire_at' => '批量延长魔力加成过期时间',
|
||||||
|
'bulk_action_update_bonus_addition_expire_at' => '批量设置魔力加成过期时间',
|
||||||
|
'bulk_action_cancel_bonus_addition_expire_at' => '批量取消魔力加成过期时间',
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ return [
|
|||||||
'language' => '語言',
|
'language' => '語言',
|
||||||
'content' => '內容',
|
'content' => '內容',
|
||||||
'is_default' => '是否默認',
|
'is_default' => '是否默認',
|
||||||
|
'bulk' => '批量',
|
||||||
'setting' => [
|
'setting' => [
|
||||||
'nav_text' => '設置',
|
'nav_text' => '設置',
|
||||||
'backup' => [
|
'backup' => [
|
||||||
|
|||||||
@@ -50,4 +50,21 @@ return [
|
|||||||
0 => '未佩戴',
|
0 => '未佩戴',
|
||||||
1 => '已佩戴'
|
1 => '已佩戴'
|
||||||
],
|
],
|
||||||
|
'bonus_addition_expire_at' => '魔力加成過期時間',
|
||||||
|
'is_expired' => '是否過期',
|
||||||
|
'is_bonus_addition_expired' => '是否魔力加成過期',
|
||||||
|
'is_wearing' => '是否佩戴',
|
||||||
|
'increase_duration' => '延長時長',
|
||||||
|
'increase_duration_help' => '單位:天。將過期時間在原基礎上統一延長',
|
||||||
|
'update_expire_at' => '設置過期時間',
|
||||||
|
'update_expire_at_help' => '將過期時間統一設置爲指定值',
|
||||||
|
'bulk_action_increase' => '延長',
|
||||||
|
'bulk_action_update' => '設置',
|
||||||
|
'bulk_action_cancel' => '取消',
|
||||||
|
'bulk_action_increase_expire_at' => '批量延長過期時間',
|
||||||
|
'bulk_action_update_expire_at' => '批量設置過期時間',
|
||||||
|
'bulk_action_cancel_expire_at' => '批量取消過期時間',
|
||||||
|
'bulk_action_increase_bonus_addition_expire_at' => '批量延長魔力加成過期時間',
|
||||||
|
'bulk_action_update_bonus_addition_expire_at' => '批量設置魔力加成過期時間',
|
||||||
|
'bulk_action_cancel_bonus_addition_expire_at' => '批量取消魔力加成過期時間',
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user