From 5191a1ba9a4d848ac732dcd070cd39db86e989ec Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 2 Jul 2022 15:08:23 +0800 Subject: [PATCH] admin add claim --- README-EN.md | 2 +- README.md | 2 +- app/Console/Commands/Test.php | 4 +- app/Filament/OptionsTrait.php | 8 + .../Resources/System/AgentAllowResource.php | 2 + .../Resources/System/AgentDenyResource.php | 2 + .../Resources/System/ExamResource.php | 56 ++-- .../System/ExamResource/Pages/CreateExam.php | 24 ++ .../System/ExamResource/Pages/EditExam.php | 14 + .../System/ExamResource/Pages/ListExams.php | 2 +- .../Resources/System/MedalResource.php | 2 + .../Resources/System/SettingResource.php | 2 +- .../Resources/Torrent/TagResource.php | 2 + app/Filament/Resources/User/ClaimResource.php | 86 ++++++ .../User/ClaimResource/Pages/CreateClaim.php | 12 + .../User/ClaimResource/Pages/EditClaim.php | 19 ++ .../User/ClaimResource/Pages/ListClaims.php | 20 ++ .../Resources/User/ExamUserResource.php | 9 +- .../ExamUserResource/Pages/ViewExamUser.php | 93 +++++++ .../Resources/User/HitAndRunResource.php | 28 +- .../HitAndRunResource/Pages/ViewHitAndRun.php | 88 ++++++- .../Resources/User/UserMedalResource.php | 4 +- app/Filament/Resources/User/UserResource.php | 2 + app/Models/Claim.php | 24 ++ app/Models/Exam.php | 33 ++- app/Models/ExamUser.php | 35 +++ app/Models/Snatch.php | 22 ++ app/Models/User.php | 2 +- app/Repositories/ClaimRepository.php | 8 +- app/Repositories/DashboardRepository.php | 4 +- app/Repositories/ExamRepository.php | 21 +- app/Repositories/HitAndRunRepository.php | 2 +- composer.lock | 248 +++++++++--------- include/constants.php | 2 +- include/functions.php | 4 +- public/modtask.php | 6 +- resources/lang/en/admin.php | 12 + resources/lang/en/exam.php | 5 + resources/lang/en/label.php | 49 ++++ resources/lang/zh_CN/admin.php | 13 +- resources/lang/zh_CN/exam.php | 5 + resources/lang/zh_CN/label.php | 28 +- resources/lang/zh_TW/admin.php | 13 +- resources/lang/zh_TW/exam.php | 5 + resources/lang/zh_TW/label.php | 27 ++ .../views/filament/detail-card.blade.php | 20 ++ .../exam-user-resource/pages/detail.blade.php | 40 +++ .../pages/user-profile.blade.php | 174 ++++++------ 48 files changed, 992 insertions(+), 293 deletions(-) create mode 100644 app/Filament/Resources/User/ClaimResource.php create mode 100644 app/Filament/Resources/User/ClaimResource/Pages/CreateClaim.php create mode 100644 app/Filament/Resources/User/ClaimResource/Pages/EditClaim.php create mode 100644 app/Filament/Resources/User/ClaimResource/Pages/ListClaims.php create mode 100644 app/Filament/Resources/User/ExamUserResource/Pages/ViewExamUser.php create mode 100644 resources/views/filament/detail-card.blade.php create mode 100644 resources/views/filament/resources/user/exam-user-resource/pages/detail.blade.php diff --git a/README-EN.md b/README-EN.md index 55b590d3..c45a14d9 100644 --- a/README-EN.md +++ b/README-EN.md @@ -1,6 +1,6 @@ English | [中文](/) -Complete PT website building solution. Based on NexusPHP + Laravel Framework + Element Plus. +Complete PT website building solution. Based on NexusPHP + Laravel Framework + Filament. ## Functional Features diff --git a/README.md b/README.md index 7ff59dab..bc272443 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ 中文 | [English](/README-EN.md) -完整的 PT 建站解决方案。基于 NexusPHP + Laravel Framework + Element Plus。 +完整的 PT 建站解决方案。基于 NexusPHP + Laravel Framework + Filament。 ## 功能特性 - 发种 diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php index 6b40bd93..aae1340b 100644 --- a/app/Console/Commands/Test.php +++ b/app/Console/Commands/Test.php @@ -78,8 +78,8 @@ class Test extends Command */ public function handle() { - $r = range(0, 23); - dd($r); + $r = User::query()->find(10003, ['id', 'added', 'donoruntil']); + dd($r->donoruntil->toDateTimeString() < '1978'); } diff --git a/app/Filament/OptionsTrait.php b/app/Filament/OptionsTrait.php index fb3e25c3..0da89a5f 100644 --- a/app/Filament/OptionsTrait.php +++ b/app/Filament/OptionsTrait.php @@ -7,4 +7,12 @@ trait OptionsTrait private static array $matchTypes = ['dec' => 'dec', 'hex' => 'hex']; private static array $yesOrNo = ['yes' => 'yes', 'no' => 'no']; + + private static function getEnableDisableOptions($enableValue = 0, $disableValue = 1): array + { + return [ + $enableValue => __('label.enabled'), + $disableValue => __('label.disabled'), + ]; + } } diff --git a/app/Filament/Resources/System/AgentAllowResource.php b/app/Filament/Resources/System/AgentAllowResource.php index 79a16f0f..db5bce75 100644 --- a/app/Filament/Resources/System/AgentAllowResource.php +++ b/app/Filament/Resources/System/AgentAllowResource.php @@ -24,6 +24,8 @@ class AgentAllowResource extends Resource protected static ?string $navigationGroup = 'System'; + protected static ?int $navigationSort = 3; + protected static function getNavigationLabel(): string { return __('admin.sidebar.agent_allows'); diff --git a/app/Filament/Resources/System/AgentDenyResource.php b/app/Filament/Resources/System/AgentDenyResource.php index efea3ab6..a5f102ad 100644 --- a/app/Filament/Resources/System/AgentDenyResource.php +++ b/app/Filament/Resources/System/AgentDenyResource.php @@ -21,6 +21,8 @@ class AgentDenyResource extends Resource protected static ?string $navigationGroup = 'System'; + protected static ?int $navigationSort = 4; + protected static function getNavigationLabel(): string { return __('admin.sidebar.agent_denies'); diff --git a/app/Filament/Resources/System/ExamResource.php b/app/Filament/Resources/System/ExamResource.php index 875c51bd..a6e8c021 100644 --- a/app/Filament/Resources/System/ExamResource.php +++ b/app/Filament/Resources/System/ExamResource.php @@ -14,6 +14,7 @@ use Filament\Resources\Table; use Filament\Tables; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; +use Illuminate\Validation\Rule; class ExamResource extends Resource { @@ -25,9 +26,9 @@ class ExamResource extends Resource protected static ?string $navigationGroup = 'System'; - const IS_DISCOVERED_OPTIONS = ['0' => 'No', '1' => 'Yes']; + protected static ?int $navigationSort = 1; - const STATUS_OPTIONS = ['0' => 'Enabled', '1' => 'Disabled']; + const IS_DISCOVERED_OPTIONS = ['0' => 'No', '1' => 'Yes']; protected static function getNavigationLabel(): string { @@ -44,46 +45,67 @@ class ExamResource extends Resource $userRep = new UserRepository(); return $form ->schema([ - Forms\Components\Section::make('Base info')->schema([ + Forms\Components\Section::make(__('label.exam.section_base_info'))->schema([ Forms\Components\TextInput::make('name')->required()->columnSpan(['sm' => 2])->label(__('label.name')), - Forms\Components\TextInput::make('priority') - ->columnSpan(['sm' => 2]) - ->label(__("label.priority")) - ->helperText('The higher the value, the higher the priority, and when multiple exam match the same user, the one with the highest priority is assigned.'), + Forms\Components\Repeater::make('indexes')->schema([ + Forms\Components\Select::make('index') + ->options(Exam::listIndex(true)) + ->label(__('label.exam.index_required_label')) + ->rules([Rule::in(array_keys(Exam::$indexes))]) + ->required(), + Forms\Components\TextInput::make('require_value') + ->label(__('label.exam.index_required_value')) + ->placeholder(__('label.exam.index_placeholder')) + ->integer() + ->required(), + Forms\Components\Hidden::make('checked')->default(true), + ]) + ->label(__('label.exam.index_formatted')) + ->required(), + Forms\Components\Radio::make('status') - ->options(self::STATUS_OPTIONS) + ->options(self::getEnableDisableOptions()) ->inline() + ->required() ->label(__('label.status')) ->columnSpan(['sm' => 2]), Forms\Components\Radio::make('is_discovered') ->options(self::IS_DISCOVERED_OPTIONS) ->label(__('label.exam.is_discovered')) ->inline() + ->required() ->columnSpan(['sm' => 2]), + Forms\Components\TextInput::make('priority') + ->columnSpan(['sm' => 2]) + ->integer() + ->label(__("label.priority")) + ->helperText(__('label.exam.priority_help')), ])->columns(2), - Forms\Components\Section::make('Time')->schema([ + Forms\Components\Section::make(__('label.exam.section_time'))->schema([ Forms\Components\DateTimePicker::make('begin')->label(__('label.begin')), Forms\Components\DateTimePicker::make('end')->label(__('label.begin')), Forms\Components\TextInput::make('duration') ->integer() ->columnSpan(['sm' => 2]) ->label(__('label.duration')) - ->helperText('Unit: days. When assign to user, begin and end are used if they are specified. Otherwise begin time is the time at assignment, and the end time is the time at assignment plus the duration.'), + ->helperText(__('label.exam.duration_help')), ])->columns(2), - Forms\Components\Section::make('Select user')->schema([ + Forms\Components\Section::make(__('label.exam.section_target_user'))->schema([ Forms\Components\CheckboxList::make('filters.classes') ->options($userRep->listClass())->columnSpan(['sm' => 2]) ->columns(4) ->label(__('label.user.class')), Forms\Components\DateTimePicker::make('filters.register_time_range.0')->label(__("label.exam.register_time_range.begin")), Forms\Components\DateTimePicker::make('filters.register_time_range.1')->label(__("label.exam.register_time_range.end")), - Forms\Components\Toggle::make('filters.donate_status')->label(__('label.exam.donated')), + Forms\Components\CheckboxList::make('filters.donate_status') + ->options(self::$yesOrNo) + ->label(__('label.exam.donated')), ])->columns(2), - Forms\Components\Textarea::make('description')->columnSpan(['sm' => 2]), + Forms\Components\Textarea::make('description')->columnSpan(['sm' => 2])->label(__('label.description')), ]); } @@ -104,10 +126,10 @@ class ExamResource extends Resource ]) ->filters([ Tables\Filters\SelectFilter::make('is_discovered')->options(self::IS_DISCOVERED_OPTIONS)->label(__("label.exam.is_discovered")), - Tables\Filters\SelectFilter::make('status')->options(self::STATUS_OPTIONS)->label(__("label.status")), + Tables\Filters\SelectFilter::make('status')->options(self::getEnableDisableOptions())->label(__("label.status")), ]) ->actions([ -// Tables\Actions\EditAction::make(), + Tables\Actions\EditAction::make(), ]) ->bulkActions([ Tables\Actions\DeleteBulkAction::make(), @@ -125,8 +147,8 @@ class ExamResource extends Resource { return [ 'index' => Pages\ListExams::route('/'), -// 'create' => Pages\CreateExam::route('/create'), -// 'edit' => Pages\EditExam::route('/{record}/edit'), + 'create' => Pages\CreateExam::route('/create'), + 'edit' => Pages\EditExam::route('/{record}/edit'), ]; } } diff --git a/app/Filament/Resources/System/ExamResource/Pages/CreateExam.php b/app/Filament/Resources/System/ExamResource/Pages/CreateExam.php index 62e47d91..675aaa7a 100644 --- a/app/Filament/Resources/System/ExamResource/Pages/CreateExam.php +++ b/app/Filament/Resources/System/ExamResource/Pages/CreateExam.php @@ -3,10 +3,34 @@ namespace App\Filament\Resources\System\ExamResource\Pages; use App\Filament\Resources\System\ExamResource; +use App\Repositories\ExamRepository; use Filament\Pages\Actions; use Filament\Resources\Pages\CreateRecord; class CreateExam extends CreateRecord { protected static string $resource = ExamResource::class; + + public function create(bool $another = false): void + { + $data = $this->form->getState(); +// dd($data); + $examRep = new ExamRepository(); + try { + $examRep->store($data); + $this->notify('success', $this->getCreatedNotificationMessage()); + if ($another) { + // Ensure that the form record is anonymized so that relationships aren't loaded. + $this->form->model($this->record::class); + $this->record = null; + + $this->fillForm(); + + return; + } + $this->redirect($this->getRedirectUrl()); + } catch (\Exception $exception) { + $this->notify('danger', $exception->getMessage()); + } + } } diff --git a/app/Filament/Resources/System/ExamResource/Pages/EditExam.php b/app/Filament/Resources/System/ExamResource/Pages/EditExam.php index 57c4c0ae..95d1fedc 100644 --- a/app/Filament/Resources/System/ExamResource/Pages/EditExam.php +++ b/app/Filament/Resources/System/ExamResource/Pages/EditExam.php @@ -3,6 +3,7 @@ namespace App\Filament\Resources\System\ExamResource\Pages; use App\Filament\Resources\System\ExamResource; +use App\Repositories\ExamRepository; use Filament\Pages\Actions; use Filament\Resources\Pages\EditRecord; @@ -16,4 +17,17 @@ class EditExam extends EditRecord Actions\DeleteAction::make(), ]; } + + public function save(bool $shouldRedirect = true): void + { + $data = $this->form->getState(); + $examRep = new ExamRepository(); + try { + $examRep->update($data, $this->record->id); + $this->notify('success', $this->getSavedNotificationMessage()); + $this->redirect($this->getResource()::getUrl('index')); + } catch (\Exception $exception) { + $this->notify('danger', $exception->getMessage()); + } + } } diff --git a/app/Filament/Resources/System/ExamResource/Pages/ListExams.php b/app/Filament/Resources/System/ExamResource/Pages/ListExams.php index 8cc2ccc0..93a2992e 100644 --- a/app/Filament/Resources/System/ExamResource/Pages/ListExams.php +++ b/app/Filament/Resources/System/ExamResource/Pages/ListExams.php @@ -14,7 +14,7 @@ class ListExams extends PageList protected function getActions(): array { return [ -// Actions\CreateAction::make(), + Actions\CreateAction::make(), ]; } } diff --git a/app/Filament/Resources/System/MedalResource.php b/app/Filament/Resources/System/MedalResource.php index 7690e389..3e12e885 100644 --- a/app/Filament/Resources/System/MedalResource.php +++ b/app/Filament/Resources/System/MedalResource.php @@ -21,6 +21,8 @@ class MedalResource extends Resource protected static ?string $navigationGroup = 'System'; + protected static ?int $navigationSort = 2; + protected static function getNavigationLabel(): string { return __('admin.sidebar.medals_list'); diff --git a/app/Filament/Resources/System/SettingResource.php b/app/Filament/Resources/System/SettingResource.php index f870208b..b73e1dc1 100644 --- a/app/Filament/Resources/System/SettingResource.php +++ b/app/Filament/Resources/System/SettingResource.php @@ -24,7 +24,7 @@ class SettingResource extends Resource protected static ?string $navigationGroup = 'System'; - protected static bool $shouldRegisterNavigation = true; + protected static ?int $navigationSort = 100; protected static function getNavigationLabel(): string { diff --git a/app/Filament/Resources/Torrent/TagResource.php b/app/Filament/Resources/Torrent/TagResource.php index 5218f009..e5aaa22d 100644 --- a/app/Filament/Resources/Torrent/TagResource.php +++ b/app/Filament/Resources/Torrent/TagResource.php @@ -21,6 +21,8 @@ class TagResource extends Resource protected static ?string $navigationGroup = 'Torrent'; + protected static ?int $navigationSort = 1; + protected static function getNavigationLabel(): string { return __('admin.sidebar.tags_list'); diff --git a/app/Filament/Resources/User/ClaimResource.php b/app/Filament/Resources/User/ClaimResource.php new file mode 100644 index 00000000..3d0f2898 --- /dev/null +++ b/app/Filament/Resources/User/ClaimResource.php @@ -0,0 +1,86 @@ +schema([ + // + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('id')->sortable(), + Tables\Columns\TextColumn::make('user.username')->label(__('label.user.label'))->searchable(), + Tables\Columns\TextColumn::make('torrent.name')->limit(50)->label(__('label.torrent.label'))->searchable(), + Tables\Columns\TextColumn::make('torrent.size')->label(__('label.torrent.size'))->formatStateUsing(fn ($record) => mksize($record->size)), + Tables\Columns\TextColumn::make('torrent.added')->label(__('label.torrent.ttl'))->formatStateUsing(fn ($record) => mkprettytime($record->added)), + Tables\Columns\TextColumn::make('created_at')->label(__('label.created_at'))->dateTime(), + Tables\Columns\TextColumn::make('last_settle_at')->label(__('label.claim.last_settle_at'))->dateTime(), + Tables\Columns\TextColumn::make('seedTimeThisMonth')->label(__('label.claim.seed_time_this_month')), + Tables\Columns\TextColumn::make('uploadedThisMonth')->label(__('label.claim.uploaded_this_month')), + Tables\Columns\BooleanColumn::make('isReachedThisMonth')->label(__('label.claim.is_reached_this_month')), + ]) + ->defaultSort('id', 'desc') + ->filters([ + // + ]) + ->actions([ +// Tables\Actions\EditAction::make(), + ]) + ->bulkActions([ +// Tables\Actions\DeleteBulkAction::make(), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListClaims::route('/'), + 'create' => Pages\CreateClaim::route('/create'), + 'edit' => Pages\EditClaim::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/User/ClaimResource/Pages/CreateClaim.php b/app/Filament/Resources/User/ClaimResource/Pages/CreateClaim.php new file mode 100644 index 00000000..6dcf5076 --- /dev/null +++ b/app/Filament/Resources/User/ClaimResource/Pages/CreateClaim.php @@ -0,0 +1,12 @@ +options(['0' => 'No', '1' => 'yes'])->label(__('label.exam.is_done')), ]) ->actions([ -// Tables\Actions\ViewAction::make(), + Tables\Actions\ViewAction::make(), ]) ->prependBulkActions([ Tables\Actions\BulkAction::make('Avoid')->action(function (Collection $records) { @@ -86,8 +88,9 @@ class ExamUserResource extends Resource { return [ 'index' => Pages\ListExamUsers::route('/'), - 'create' => Pages\CreateExamUser::route('/create'), - 'edit' => Pages\EditExamUser::route('/{record}/edit'), +// 'create' => Pages\CreateExamUser::route('/create'), +// 'edit' => Pages\EditExamUser::route('/{record}/edit'), + 'view' => Pages\ViewExamUser::route('/{record}'), ]; } } diff --git a/app/Filament/Resources/User/ExamUserResource/Pages/ViewExamUser.php b/app/Filament/Resources/User/ExamUserResource/Pages/ViewExamUser.php new file mode 100644 index 00000000..db1060e8 --- /dev/null +++ b/app/Filament/Resources/User/ExamUserResource/Pages/ViewExamUser.php @@ -0,0 +1,93 @@ +record->progressFormatted); + $data = []; + $record = $this->record; + $data[] = [ + 'label' => 'ID', + 'value' => $record->id, + ]; + $data[] = [ + 'label' => __('label.status'), + 'value' => $record->statusText, + ]; + $data[] = [ + 'label' => __('label.username'), + 'value' => $record->user->username, + ]; + $data[] = [ + 'label' => __('label.exam.label'), + 'value' => $record->exam->name, + ]; + $data[] = [ + 'label' => __('label.begin'), + 'value' => $record->begin, + ]; + $data[] = [ + 'label' => __('label.end'), + 'value' => $record->end, + ]; + $data[] = [ + 'label' => __('label.exam_user.is_done'), + 'value' => $record->isDoneText, + ]; + $data[] = [ + 'label' => __('label.created_at'), + 'value' => $record->created_at, + ]; + $data[] = [ + 'label' => __('label.updated_at'), + 'value' => $record->updated_at, + ]; + return $data; + } + + protected function getViewData(): array + { + return [ + 'cardData' => $this->getDetailCardData(), + ]; + } + + protected function getActions(): array + { + return [ + Actions\Action::make('Avoid') + ->requiresConfirmation() + ->action(function () { + $examRep = new ExamRepository(); + try { + $examRep->avoidExamUser($this->record->id); + $this->notify('success', 'Success !'); + $this->record = $this->resolveRecord($this->record->id); + } catch (\Exception $exception) { + $this->notify('danger', $exception->getMessage()); + } + }) + ->label(__('admin.resources.exam_user.action_avoid')), + + Actions\DeleteAction::make(), + ]; + } + + private function getProgress() + { + + } +} diff --git a/app/Filament/Resources/User/HitAndRunResource.php b/app/Filament/Resources/User/HitAndRunResource.php index e571ffa4..add429ef 100644 --- a/app/Filament/Resources/User/HitAndRunResource.php +++ b/app/Filament/Resources/User/HitAndRunResource.php @@ -24,6 +24,8 @@ class HitAndRunResource extends Resource protected static ?string $navigationGroup = 'User'; + protected static ?int $navigationSort = 3; + protected static function getNavigationLabel(): string { return __('admin.sidebar.hit_and_runs'); @@ -34,18 +36,18 @@ class HitAndRunResource extends Resource return self::getNavigationLabel(); } - public static function form(Form $form): Form - { - return $form - ->schema(Forms\Components\Card::make()->schema([ -// Forms\Components\Select::make('user')->relationship('user', 'username')->required(), -// Forms\Components\Select::make('torrent_id')->relationship('torrent', 'name')->required(), - Forms\Components\Radio::make('status')->options(HitAndRun::listStatus(true))->inline()->required(), -// Forms\Components\Select::make('snatch_id')->relationship('snatch', 'uploaded'), - Forms\Components\Textarea::make('comment'), - Forms\Components\DateTimePicker::make('created_at')->displayFormat('Y-m-d H:i:s'), - ])); - } +// public static function form(Form $form): Form +// { +// return $form +// ->schema(Forms\Components\Card::make()->schema([ +//// Forms\Components\Select::make('user')->relationship('user', 'username')->required(), +//// Forms\Components\Select::make('torrent_id')->relationship('torrent', 'name')->required(), +// Forms\Components\Radio::make('status')->options(HitAndRun::listStatus(true))->inline()->required(), +//// Forms\Components\Select::make('snatch_id')->relationship('snatch', 'uploaded'), +// Forms\Components\Textarea::make('comment'), +// Forms\Components\DateTimePicker::make('created_at')->displayFormat('Y-m-d H:i:s'), +// ])); +// } public static function table(Table $table): Table { @@ -74,6 +76,8 @@ class HitAndRunResource extends Resource $rep->bulkPardon(['id' => $idArr], Auth::user()); }) ->deselectRecordsAfterCompletion() + ->label(__('admin.resources.hit_and_run.bulk_action_pardon')) + ->icon('heroicon-o-x') ]); } diff --git a/app/Filament/Resources/User/HitAndRunResource/Pages/ViewHitAndRun.php b/app/Filament/Resources/User/HitAndRunResource/Pages/ViewHitAndRun.php index f96f1e5d..5aa26b40 100644 --- a/app/Filament/Resources/User/HitAndRunResource/Pages/ViewHitAndRun.php +++ b/app/Filament/Resources/User/HitAndRunResource/Pages/ViewHitAndRun.php @@ -4,22 +4,98 @@ namespace App\Filament\Resources\User\HitAndRunResource\Pages; use App\Filament\Resources\User\HitAndRunResource; use App\Models\HitAndRun; +use App\Repositories\HitAndRunRepository; use Filament\Pages\Actions; use Filament\Resources\Pages\ViewRecord; use Filament\Forms; +use Illuminate\Support\Facades\Auth; class ViewHitAndRun extends ViewRecord { protected static string $resource = HitAndRunResource::class; - protected function getFormSchema(): array + protected static string $view = 'filament.detail-card'; + + private function getDetailCardData(): array + { + $data = []; + $record = $this->record; + $data[] = [ + 'label' => 'ID', + 'value' => $record->id, + ]; + $data[] = [ + 'label' => __('label.status'), + 'value' => $record->statusText, + ]; + $data[] = [ + 'label' => __('label.username'), + 'value' => $record->user->username, + ]; + $data[] = [ + 'label' => __('label.torrent.label'), + 'value' => $record->torrent->name, + ]; + $data[] = [ + 'label' => __('label.uploaded'), + 'value' => $record->snatch->uploadedText, + ]; + $data[] = [ + 'label' => __('label.downloaded'), + 'value' => $record->snatch->downloadedText, + ]; + $data[] = [ + 'label' => __('label.ratio'), + 'value' => $record->snatch->shareRatio, + ]; + $data[] = [ + 'label' => __('label.seed_time_required'), + 'value' => $record->seedTimeRequired, + ]; + $data[] = [ + 'label' => __('label.inspect_time_left'), + 'value' => $record->inspectTimeLeft, + ]; + $data[] = [ + 'label' => __('label.comment'), + 'value' => nl2br($record->comment), + ]; + $data[] = [ + 'label' => __('label.created_at'), + 'value' => $record->created_at, + ]; + $data[] = [ + 'label' => __('label.updated_at'), + 'value' => $record->updated_at, + ]; + return $data; + } + + protected function getViewData(): array { return [ - Forms\Components\TextInput::make('id'), - Forms\Components\TextInput::make('uid'), - Forms\Components\Radio::make('status')->options(HitAndRun::listStatus(true))->inline(), - Forms\Components\Textarea::make('comment'), - Forms\Components\DateTimePicker::make('created_at'), + 'cardData' => $this->getDetailCardData(), + ]; + } + + protected function getActions(): array + { + return [ + Actions\Action::make('Pardon') + ->requiresConfirmation() + ->action(function () { + $hitAndRunRep = new HitAndRunRepository(); + try { + $hitAndRunRep->pardon($this->record->id, Auth::user()); + $this->notify('success', 'Success !'); + $this->record = $this->resolveRecord($this->record->id); + } catch (\Exception $exception) { + $this->notify('danger', $exception->getMessage()); + } + }) + ->label(__('admin.resources.hit_and_run.action_pardon')), + + Actions\DeleteAction::make(), ]; } diff --git a/app/Filament/Resources/User/UserMedalResource.php b/app/Filament/Resources/User/UserMedalResource.php index bea7de7f..80a28ef1 100644 --- a/app/Filament/Resources/User/UserMedalResource.php +++ b/app/Filament/Resources/User/UserMedalResource.php @@ -21,9 +21,11 @@ class UserMedalResource extends Resource protected static ?string $navigationGroup = 'User'; + protected static ?int $navigationSort = 5; + protected static function getNavigationLabel(): string { - return __('admin.sidebar.users_medal'); + return __('admin.sidebar.users_medals'); } public static function getBreadcrumb(): string diff --git a/app/Filament/Resources/User/UserResource.php b/app/Filament/Resources/User/UserResource.php index c790ca06..3a1b77ae 100644 --- a/app/Filament/Resources/User/UserResource.php +++ b/app/Filament/Resources/User/UserResource.php @@ -26,6 +26,8 @@ class UserResource extends Resource protected static ?string $navigationGroup = 'User'; + protected static ?int $navigationSort = 1; + protected static function getNavigationLabel(): string { return __('admin.sidebar.users_list'); diff --git a/app/Models/Claim.php b/app/Models/Claim.php index 3355a4ab..3aa02186 100644 --- a/app/Models/Claim.php +++ b/app/Models/Claim.php @@ -22,6 +22,30 @@ class Claim extends NexusModel 'last_settle_at' => 'datetime', ]; + public function getSeedTimeThisMonthAttribute() + { + return mkprettytime($this->snatch->seedtime - $this->seed_time_begin); + } + + public function getUploadedThisMonthAttribute() + { + return mksize($this->snatch->uploaded - $this->uploaded_begin); + } + + public function getIsReachedThisMonthAttribute(): bool + { + $seedTimeRequiredHours = self::getConfigStandardSeedTimeHours(); + $uploadedRequiredTimes = self::getConfigStandardUploadedTimes(); + if ( + bcsub($this->snatch->seedtime, $this->seed_time_begin) >= $seedTimeRequiredHours * 3600 + || bcsub($this->snatch->uploaded, $this->uploaded_begin) >= $uploadedRequiredTimes * $this->torrent->size + ) { + return true; + } else { + return false; + } + } + public function user() { return $this->belongsTo(User::class, 'uid'); diff --git a/app/Models/Exam.php b/app/Models/Exam.php index f5b78536..11fc524d 100644 --- a/app/Models/Exam.php +++ b/app/Models/Exam.php @@ -39,8 +39,8 @@ class Exam extends NexusModel public static $indexes = [ self::INDEX_UPLOADED => ['name' => 'Uploaded', 'unit' => 'GB', 'source_user_field' => 'uploaded'], - self::INDEX_SEED_TIME_AVERAGE => ['name' => 'Seed time average', 'unit' => 'Hour', 'source_user_field' => 'seedtime'], self::INDEX_DOWNLOADED => ['name' => 'Downloaded', 'unit' => 'GB', 'source_user_field' => 'downloaded'], + self::INDEX_SEED_TIME_AVERAGE => ['name' => 'Seed time average', 'unit' => 'Hour', 'source_user_field' => 'seedtime'], self::INDEX_SEED_BONUS => ['name' => 'Bonus', 'unit' => '', 'source_user_field' => 'seedbonus'], ]; @@ -61,9 +61,24 @@ class Exam extends NexusModel }); } + public static function listIndex($onlyKeyValue = false): array + { + $result = self::$indexes; + $keyValues = []; + foreach ($result as $key => &$value) { + $text = nexus_trans("exam.index_text_$key"); + $value['text'] = $text; + $keyValues[$key] = $text; + } + if ($onlyKeyValue) { + return $keyValues; + } + return $result; + } + public function getStatusTextAttribute(): string { - return self::$status[$this->status]['text'] ?? ''; + return $this->status == self::STATUS_ENABLED ? nexus_trans('label.enabled') : nexus_trans('label.disabled'); } public function getIsDiscoveredTextAttribute(): string @@ -87,7 +102,7 @@ class Exam extends NexusModel if (isset($index['checked']) && $index['checked']) { $arr[] = sprintf( '%s: %s %s', - self::$indexes[$index['index']]['name'] ?? '', + nexus_trans("exam.index_text_{$index['index']}"), $index['require_value'], self::$indexes[$index['index']]['unit'] ?? '' ); @@ -103,24 +118,24 @@ class Exam extends NexusModel $filter = self::FILTER_USER_CLASS; if (!empty($currentFilters->{$filter})) { $classes = collect(User::$classes)->only($currentFilters->{$filter}); - $arr[] = sprintf('%s: %s', self::$filters[$filter]['name'], $classes->pluck('text')->implode(', ')); + $arr[] = sprintf('%s: %s', nexus_trans("exam.filters.$filter"), $classes->pluck('text')->implode(', ')); } $filter = self::FILTER_USER_REGISTER_TIME_RANGE; if (!empty($currentFilters->{$filter})) { $range = $currentFilters->{$filter}; $arr[] = sprintf( - "%s: \n%s ~ %s", - self::$filters[$filter]['name'], - $range[0] ? Carbon::parse($range[0])->toDateTimeString() : '-', - $range[1] ? Carbon::parse($range[1])->toDateTimeString() : '-' + "%s:
%s ~ %s", + nexus_trans("exam.filters.$filter"), + $range[0] ? Carbon::parse($range[0])->toDateTimeString() : '--', + $range[1] ? Carbon::parse($range[1])->toDateTimeString() : '--' ); } $filter = self::FILTER_USER_DONATE; if (!empty($currentFilters->{$filter})) { $donateStatus = $classes = collect(User::$donateStatus)->only($currentFilters->{$filter}); - $arr[] = sprintf('%s: %s', self::$filters[$filter]['name'], $donateStatus->pluck('text')->implode(', ')); + $arr[] = sprintf('%s: %s', nexus_trans("exam.filters.$filter"), $donateStatus->pluck('text')->implode(', ')); } return implode("
", $arr); diff --git a/app/Models/ExamUser.php b/app/Models/ExamUser.php index 6f2cc10f..0dbcd3ae 100644 --- a/app/Models/ExamUser.php +++ b/app/Models/ExamUser.php @@ -41,6 +41,41 @@ class ExamUser extends NexusModel return self::$isDoneInfo[$this->is_done]['text'] ?? ''; } + public function getProgressFormattedAttribute(): array + { + $result = []; + $progress = $this->progress; + foreach ($this->exam->indexes as $key => $index) { + if (!isset($index['checked']) || !$index['checked']) { + continue; + } + $currentValue = $progress[$index['index']] ?? 0; + $requireValue = $index['require_value']; + switch ($index['index']) { + case Exam::INDEX_UPLOADED: + case Exam::INDEX_DOWNLOADED: + $currentValueFormatted = mksize($currentValue); + $requireValueAtomic = $requireValue * 1024 * 1024 * 1024; + break; + case Exam::INDEX_SEED_TIME_AVERAGE: + $currentValueFormatted = number_format($currentValue / 3600, 2) . " {$index['unit']}"; + $requireValueAtomic = $requireValue * 3600; + break; + default: + $currentValueFormatted = $currentValue; + $requireValueAtomic = $requireValue; + } + $index['name'] = Exam::$indexes[$index['index']]['name'] ?? ''; + $index['index_formatted'] = nexus_trans('exam.index_text_' . $index['index']); + $index['require_value_formatted'] = "$requireValue " . ($index['unit'] ?? ''); + $index['current_value'] = $currentValue; + $index['current_value_formatted'] = $currentValueFormatted; + $index['passed'] = $currentValue >= $requireValueAtomic; + $result[] = $index; + } + return $result; + } + public static function listStatus($onlyKeyValue = false): array { $result = self::$status; diff --git a/app/Models/Snatch.php b/app/Models/Snatch.php index d3d543ba..730b5630 100644 --- a/app/Models/Snatch.php +++ b/app/Models/Snatch.php @@ -35,6 +35,10 @@ class Snatch extends NexusModel const FINISHED_NO = 'no'; + /** + * @deprecated Use uploadedText instead + * @return Attribute + */ protected function uploadText(): Attribute { return new Attribute( @@ -42,6 +46,10 @@ class Snatch extends NexusModel ); } + /** + * @deprecated Use downloadedText instead + * @return Attribute + */ protected function downloadText(): Attribute { return new Attribute( @@ -49,6 +57,20 @@ class Snatch extends NexusModel ); } + protected function uploadedText(): Attribute + { + return new Attribute( + get: fn($value, $attributes) => sprintf('%s@%s', mksize($attributes['uploaded']), $this->getUploadSpeed()) + ); + } + + protected function downloadedText(): Attribute + { + return new Attribute( + get: fn($value, $attributes) => sprintf('%s@%s', mksize($attributes['downloaded']), $this->getDownloadSpeed()) + ); + } + protected function shareRatio(): Attribute { return new Attribute( diff --git a/app/Models/User.php b/app/Models/User.php index 28185cfc..0727ee13 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -105,7 +105,7 @@ class User extends Authenticatable implements FilamentUser, HasName public function canAccessFilament(): bool { - return $this->class >= self::CLASS_ADMINISTRATOR; + return $this->canAccessAdmin(); } public function getFilamentName(): string diff --git a/app/Repositories/ClaimRepository.php b/app/Repositories/ClaimRepository.php index b19aaf43..0bd31605 100644 --- a/app/Repositories/ClaimRepository.php +++ b/app/Repositories/ClaimRepository.php @@ -185,7 +185,7 @@ class ClaimRepository extends BaseRepository if ($startOfThisMonth->diffInMonths($targetStartOfMonth) > 1) { do_log("[UNREACHED_REMOVE], uid: $uid, torrent: " . $row->torrent_id); $unReachedIdArr[] = $row->id; - $unReachedTorrentIdArr = $row->torrent_id; + $unReachedTorrentIdArr[] = $row->torrent_id; } else { do_log("[UNREACHED_FIRST_MONTH], uid: $uid, torrent: " . $row->torrent_id); $seedTimeCaseWhen[] = sprintf('when %s then %s', $row->id, $row->snatch->seedtime); @@ -290,9 +290,9 @@ class ClaimRepository extends BaseRepository if ($deductTotal) { $msg[] = nexus_trans( "claim.claim_unreached_summary", [ - 'deduct_per_torrent '=> number_format($deductPerTorrent, 2), - 'deduct_total' => number_format($deductTotal, 2) - ], $locale + 'deduct_per_torrent' => number_format($deductPerTorrent, 2), + 'deduct_total' => number_format($deductTotal, 2) + ], $locale ); } return [ diff --git a/app/Repositories/DashboardRepository.php b/app/Repositories/DashboardRepository.php index bdb6e5d3..00761d37 100644 --- a/app/Repositories/DashboardRepository.php +++ b/app/Repositories/DashboardRepository.php @@ -37,7 +37,7 @@ class DashboardRepository extends BaseRepository $result[$name] = [ 'name' => $name, 'text' => nexus_trans("dashboard.system_info.$name"), - 'value' => '2.13.11', + 'value' => "2.13.14", ]; $name = 'php_version'; $result[$name] = [ @@ -287,6 +287,4 @@ class DashboardRepository extends BaseRepository } - - } diff --git a/app/Repositories/ExamRepository.php b/app/Repositories/ExamRepository.php index 22a939b9..332fa228 100644 --- a/app/Repositories/ExamRepository.php +++ b/app/Repositories/ExamRepository.php @@ -70,9 +70,7 @@ class ExamRepository extends BaseRepository if (isset($params['end']) && $params['end'] == '') { $params['end'] = null; } - if (isset($params['priority'])) { - $params['priority'] = intval($params['priority']); - } + $params['priority'] = intval($params['priority'] ?? 0); return $params; } @@ -86,12 +84,15 @@ class ExamRepository extends BaseRepository if (isset($index['checked']) && !$index['checked']) { continue; } + if (isset($validIndex[$index['index']])) { + throw new \InvalidArgumentException(nexus_trans('admin.resources.exam.index_duplicate', ['index' => nexus_trans("exam.index_text_{$index['index']}")])); + } if (isset($index['require_value']) && !ctype_digit((string)$index['require_value'])) { throw new \InvalidArgumentException(sprintf( 'Invalid require value for index: %s.', $index['index'] )); } - $validIndex[] = $index; + $validIndex[$index['index']] = $index; } if (empty($validIndex)) { throw new \InvalidArgumentException("Require valid index."); @@ -861,12 +862,12 @@ class ExamRepository extends BaseRepository $filter = Exam::FILTER_USER_REGISTER_TIME_RANGE; $range = $filters->$filter; if (!empty($range)) { - /** - * begin and end will be exists at the same time - * @see checkBeginEnd() - */ - $baseQuery->where("$userTable.added", ">=", Carbon::parse($range[0])->toDateTimeString()) - ->where("$userTable.added", '<=', Carbon::parse($range[1])->toDateTimeString()); + if (!empty($range[0])) { + $baseQuery->where("$userTable.added", ">=", Carbon::parse($range[0])->toDateTimeString()); + } + if (!empty($range[1])) { + $baseQuery->where("$userTable.added", '<=', Carbon::parse($range[1])->toDateTimeString()); + } } //Does not has this exam $baseQuery->whereDoesntHave('exams', function (Builder $query) use ($exam) { diff --git a/app/Repositories/HitAndRunRepository.php b/app/Repositories/HitAndRunRepository.php index d40f74d4..25448b28 100644 --- a/app/Repositories/HitAndRunRepository.php +++ b/app/Repositories/HitAndRunRepository.php @@ -380,7 +380,7 @@ class HitAndRunRepository extends BaseRepository throw new \LogicException("Can't be pardoned due to status is: " . $model->status_text . " !"); } $model->status = HitAndRun::STATUS_PARDONED; - $model->comment = $this->getCommentUpdateRaw(addslashes('Pardon by ' . $user->username)); + $model->comment = $this->getCommentUpdateRaw(addslashes(date('Y-m-d') . ' - Pardon by ' . $user->username)); $model->save(); return true; } diff --git a/composer.lock b/composer.lock index 245e292a..7bac29db 100644 --- a/composer.lock +++ b/composer.lock @@ -219,16 +219,16 @@ }, { "name": "blade-ui-kit/blade-icons", - "version": "1.2.2", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/blade-ui-kit/blade-icons.git", - "reference": "012496d145bf4ea7fffd0beed9b9acbf434cc7c8" + "reference": "57a7c41e1e79e38aed029d3e6ae690b04344c99e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/blade-ui-kit/blade-icons/zipball/012496d145bf4ea7fffd0beed9b9acbf434cc7c8", - "reference": "012496d145bf4ea7fffd0beed9b9acbf434cc7c8", + "url": "https://api.github.com/repos/blade-ui-kit/blade-icons/zipball/57a7c41e1e79e38aed029d3e6ae690b04344c99e", + "reference": "57a7c41e1e79e38aed029d3e6ae690b04344c99e", "shasum": "", "mirrors": [ { @@ -302,7 +302,7 @@ "type": "github" } ], - "time": "2022-02-28T21:03:33+00:00" + "time": "2022-05-11T12:38:11+00:00" }, { "name": "brick/math", @@ -1619,16 +1619,16 @@ }, { "name": "filament/filament", - "version": "v2.13.11", + "version": "v2.13.14", "source": { "type": "git", "url": "https://github.com/filamentphp/admin.git", - "reference": "766ef94090abf602e4638f1e50aaebdde17be300" + "reference": "88324f6375c1af1ede797b48ad6f25ddeecbc632" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/admin/zipball/766ef94090abf602e4638f1e50aaebdde17be300", - "reference": "766ef94090abf602e4638f1e50aaebdde17be300", + "url": "https://api.github.com/repos/filamentphp/admin/zipball/88324f6375c1af1ede797b48ad6f25ddeecbc632", + "reference": "88324f6375c1af1ede797b48ad6f25ddeecbc632", "shasum": "", "mirrors": [ { @@ -1682,20 +1682,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2022-06-27T09:39:39+00:00" + "time": "2022-06-30T11:55:54+00:00" }, { "name": "filament/forms", - "version": "v2.13.11", + "version": "v2.13.14", "source": { "type": "git", "url": "https://github.com/filamentphp/forms.git", - "reference": "cccff2de15de7478bcdc833c5b8f9cc695e0d760" + "reference": "c40a067644b8b0bf40a17b236b22d2ef31489a8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/forms/zipball/cccff2de15de7478bcdc833c5b8f9cc695e0d760", - "reference": "cccff2de15de7478bcdc833c5b8f9cc695e0d760", + "url": "https://api.github.com/repos/filamentphp/forms/zipball/c40a067644b8b0bf40a17b236b22d2ef31489a8d", + "reference": "c40a067644b8b0bf40a17b236b22d2ef31489a8d", "shasum": "", "mirrors": [ { @@ -1745,20 +1745,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2022-06-27T09:39:40+00:00" + "time": "2022-06-30T11:56:23+00:00" }, { "name": "filament/support", - "version": "v2.13.11", + "version": "v2.13.14", "source": { "type": "git", "url": "https://github.com/filamentphp/support.git", - "reference": "a183becd6cc19a7466703e1f4e262f36dfcea32b" + "reference": "7ede0b21503000d11aed71e088f5f1b268bab0e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/support/zipball/a183becd6cc19a7466703e1f4e262f36dfcea32b", - "reference": "a183becd6cc19a7466703e1f4e262f36dfcea32b", + "url": "https://api.github.com/repos/filamentphp/support/zipball/7ede0b21503000d11aed71e088f5f1b268bab0e5", + "reference": "7ede0b21503000d11aed71e088f5f1b268bab0e5", "shasum": "", "mirrors": [ { @@ -1800,20 +1800,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2022-06-27T09:39:36+00:00" + "time": "2022-06-29T21:09:03+00:00" }, { "name": "filament/tables", - "version": "v2.13.11", + "version": "v2.13.14", "source": { "type": "git", "url": "https://github.com/filamentphp/tables.git", - "reference": "90a907976d70386600064d06d55bd91f59a292f1" + "reference": "3d60211628dc237d98727c4deb157b0897a936fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/tables/zipball/90a907976d70386600064d06d55bd91f59a292f1", - "reference": "90a907976d70386600064d06d55bd91f59a292f1", + "url": "https://api.github.com/repos/filamentphp/tables/zipball/3d60211628dc237d98727c4deb157b0897a936fb", + "reference": "3d60211628dc237d98727c4deb157b0897a936fb", "shasum": "", "mirrors": [ { @@ -1860,7 +1860,7 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2022-06-27T09:39:36+00:00" + "time": "2022-06-30T11:55:52+00:00" }, { "name": "firebase/php-jwt", @@ -2966,16 +2966,16 @@ }, { "name": "laminas/laminas-diactoros", - "version": "2.10.0", + "version": "2.11.2", "source": { "type": "git", "url": "https://github.com/laminas/laminas-diactoros.git", - "reference": "a3f03b3c158a3a7014c6ba553b0cb83bf7da19c4" + "reference": "78846cbce0550ec174508a646f46fd6dee76099b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/a3f03b3c158a3a7014c6ba553b0cb83bf7da19c4", - "reference": "a3f03b3c158a3a7014c6ba553b0cb83bf7da19c4", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/78846cbce0550ec174508a646f46fd6dee76099b", + "reference": "78846cbce0550ec174508a646f46fd6dee76099b", "shasum": "", "mirrors": [ { @@ -3067,20 +3067,20 @@ "type": "community_bridge" } ], - "time": "2022-05-04T15:16:15+00:00" + "time": "2022-06-29T14:15:02+00:00" }, { "name": "laravel/framework", - "version": "v9.18.0", + "version": "v9.19.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "93a1296bca43c1ca8dcb5df8f97107e819a71499" + "reference": "bbce25bd823133f6a5a724f2d62680b711f1d0df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/93a1296bca43c1ca8dcb5df8f97107e819a71499", - "reference": "93a1296bca43c1ca8dcb5df8f97107e819a71499", + "url": "https://api.github.com/repos/laravel/framework/zipball/bbce25bd823133f6a5a724f2d62680b711f1d0df", + "reference": "bbce25bd823133f6a5a724f2d62680b711f1d0df", "shasum": "", "mirrors": [ { @@ -3252,20 +3252,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-06-21T14:40:11+00:00" + "time": "2022-06-28T14:33:19+00:00" }, { "name": "laravel/octane", - "version": "v1.2.13", + "version": "v1.2.14", "source": { "type": "git", "url": "https://github.com/laravel/octane.git", - "reference": "4cc7c1a10630d3ff7988d7d1dd735021665ec753" + "reference": "a746fd50aa973da8c07cffa7da49630ae884dde1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/octane/zipball/4cc7c1a10630d3ff7988d7d1dd735021665ec753", - "reference": "4cc7c1a10630d3ff7988d7d1dd735021665ec753", + "url": "https://api.github.com/repos/laravel/octane/zipball/a746fd50aa973da8c07cffa7da49630ae884dde1", + "reference": "a746fd50aa973da8c07cffa7da49630ae884dde1", "shasum": "", "mirrors": [ { @@ -3333,7 +3333,7 @@ "issues": "https://github.com/laravel/octane/issues", "source": "https://github.com/laravel/octane" }, - "time": "2022-06-23T13:22:37+00:00" + "time": "2022-06-27T13:29:02+00:00" }, { "name": "laravel/sanctum", @@ -3747,16 +3747,16 @@ }, { "name": "league/flysystem", - "version": "3.0.21", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "8f1fcf9d2304ff77a006aa36dd2cb5f236999b12" + "reference": "34a68067b7ae3b836ea5e57e1fc432478372a4f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/8f1fcf9d2304ff77a006aa36dd2cb5f236999b12", - "reference": "8f1fcf9d2304ff77a006aa36dd2cb5f236999b12", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/34a68067b7ae3b836ea5e57e1fc432478372a4f5", + "reference": "34a68067b7ae3b836ea5e57e1fc432478372a4f5", "shasum": "", "mirrors": [ { @@ -3823,7 +3823,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.0.21" + "source": "https://github.com/thephpleague/flysystem/tree/3.1.0" }, "funding": [ { @@ -3839,20 +3839,20 @@ "type": "tidelift" } ], - "time": "2022-06-12T17:54:28+00:00" + "time": "2022-06-29T17:29:54+00:00" }, { "name": "league/flysystem-ftp", - "version": "3.0.19", + "version": "3.0.23", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-ftp.git", - "reference": "aa86ee4643ae2093dac68d2821699ce686cd5689" + "reference": "86fb34a59d97a529fa4666e3698d0f8250763d1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-ftp/zipball/aa86ee4643ae2093dac68d2821699ce686cd5689", - "reference": "aa86ee4643ae2093dac68d2821699ce686cd5689", + "url": "https://api.github.com/repos/thephpleague/flysystem-ftp/zipball/86fb34a59d97a529fa4666e3698d0f8250763d1b", + "reference": "86fb34a59d97a529fa4666e3698d0f8250763d1b", "shasum": "", "mirrors": [ { @@ -3893,7 +3893,7 @@ "ftpd" ], "support": { - "source": "https://github.com/thephpleague/flysystem-ftp/tree/3.0.19" + "source": "https://github.com/thephpleague/flysystem-ftp/tree/3.0.23" }, "funding": [ { @@ -3909,20 +3909,20 @@ "type": "tidelift" } ], - "time": "2022-05-03T21:11:18+00:00" + "time": "2022-06-29T08:05:10+00:00" }, { "name": "league/flysystem-sftp-v3", - "version": "3.0.19", + "version": "3.0.23", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-sftp-v3.git", - "reference": "21d96a7805306e630f581de05a5977bb5dd7052e" + "reference": "344c8ad59c04be36879fc4e6199d7f27b2309229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-sftp-v3/zipball/21d96a7805306e630f581de05a5977bb5dd7052e", - "reference": "21d96a7805306e630f581de05a5977bb5dd7052e", + "url": "https://api.github.com/repos/thephpleague/flysystem-sftp-v3/zipball/344c8ad59c04be36879fc4e6199d7f27b2309229", + "reference": "344c8ad59c04be36879fc4e6199d7f27b2309229", "shasum": "", "mirrors": [ { @@ -3963,7 +3963,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem-sftp-v3/issues", - "source": "https://github.com/thephpleague/flysystem-sftp-v3/tree/3.0.19" + "source": "https://github.com/thephpleague/flysystem-sftp-v3/tree/3.0.23" }, "funding": [ { @@ -3979,7 +3979,7 @@ "type": "tidelift" } ], - "time": "2022-04-27T17:27:37+00:00" + "time": "2022-06-29T08:05:10+00:00" }, { "name": "league/mime-type-detection", @@ -4045,16 +4045,16 @@ }, { "name": "livewire/livewire", - "version": "v2.10.5", + "version": "v2.10.6", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "9ea6237760f627b3b6a05d15137880780ac843b5" + "reference": "020ad095cf1239138b097d22b584e2701ec3edfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/9ea6237760f627b3b6a05d15137880780ac843b5", - "reference": "9ea6237760f627b3b6a05d15137880780ac843b5", + "url": "https://api.github.com/repos/livewire/livewire/zipball/020ad095cf1239138b097d22b584e2701ec3edfb", + "reference": "020ad095cf1239138b097d22b584e2701ec3edfb", "shasum": "", "mirrors": [ { @@ -4112,7 +4112,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v2.10.5" + "source": "https://github.com/livewire/livewire/tree/v2.10.6" }, "funding": [ { @@ -4120,7 +4120,7 @@ "type": "github" } ], - "time": "2022-04-07T21:38:12+00:00" + "time": "2022-06-19T02:54:20+00:00" }, { "name": "masbug/flysystem-google-drive-ext", @@ -4428,16 +4428,16 @@ }, { "name": "nesbot/carbon", - "version": "2.58.0", + "version": "2.59.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "97a34af22bde8d0ac20ab34b29d7bfe360902055" + "reference": "a9000603ea337c8df16cc41f8b6be95a65f4d0f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/97a34af22bde8d0ac20ab34b29d7bfe360902055", - "reference": "97a34af22bde8d0ac20ab34b29d7bfe360902055", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/a9000603ea337c8df16cc41f8b6be95a65f4d0f5", + "reference": "a9000603ea337c8df16cc41f8b6be95a65f4d0f5", "shasum": "", "mirrors": [ { @@ -4458,11 +4458,12 @@ "doctrine/orm": "^2.7", "friendsofphp/php-cs-fixer": "^3.0", "kylekatarnls/multi-tester": "^2.0", + "ondrejmirtes/better-reflection": "*", "phpmd/phpmd": "^2.9", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12.54 || ^1.0", - "phpunit/php-file-iterator": "^2.0.5", - "phpunit/phpunit": "^7.5.20 || ^8.5.23", + "phpstan/phpstan": "^0.12.99 || ^1.7.14", + "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", + "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", "squizlabs/php_codesniffer": "^3.4" }, "bin": [ @@ -4519,15 +4520,19 @@ }, "funding": [ { - "url": "https://opencollective.com/Carbon", - "type": "open_collective" + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", "type": "tidelift" } ], - "time": "2022-04-25T19:31:17+00:00" + "time": "2022-06-29T21:43:55+00:00" }, { "name": "nette/schema", @@ -6117,16 +6122,16 @@ }, { "name": "spatie/laravel-package-tools", - "version": "1.12.0", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/spatie/laravel-package-tools.git", - "reference": "9e6c0382553f1317c02f1ae0ee71c64821eb5af0" + "reference": "09f80fa240d44fafb1c70657c74ee44ffa929357" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/9e6c0382553f1317c02f1ae0ee71c64821eb5af0", - "reference": "9e6c0382553f1317c02f1ae0ee71c64821eb5af0", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/09f80fa240d44fafb1c70657c74ee44ffa929357", + "reference": "09f80fa240d44fafb1c70657c74ee44ffa929357", "shasum": "", "mirrors": [ { @@ -6170,7 +6175,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-package-tools/issues", - "source": "https://github.com/spatie/laravel-package-tools/tree/1.12.0" + "source": "https://github.com/spatie/laravel-package-tools/tree/1.12.1" }, "funding": [ { @@ -6178,7 +6183,7 @@ "type": "github" } ], - "time": "2022-06-19T20:01:24+00:00" + "time": "2022-06-28T14:29:26+00:00" }, { "name": "spiral/goridge", @@ -6677,7 +6682,7 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.0.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", @@ -6730,7 +6735,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.2" }, "funding": [ { @@ -6916,7 +6921,7 @@ }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.0.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", @@ -6981,7 +6986,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.2" }, "funding": [ { @@ -7158,16 +7163,16 @@ }, { "name": "symfony/http-client-contracts", - "version": "v3.0.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "f7525778c712be78ad5b6ca31f47fdcfd404c280" + "reference": "4184b9b63af1edaf35b6a7974c6f1f9f33294129" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/f7525778c712be78ad5b6ca31f47fdcfd404c280", - "reference": "f7525778c712be78ad5b6ca31f47fdcfd404c280", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/4184b9b63af1edaf35b6a7974c6f1f9f33294129", + "reference": "4184b9b63af1edaf35b6a7974c6f1f9f33294129", "shasum": "", "mirrors": [ { @@ -7222,7 +7227,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.0.2" }, "funding": [ { @@ -7238,7 +7243,7 @@ "type": "tidelift" } ], - "time": "2022-03-13T20:10:05+00:00" + "time": "2022-04-12T16:11:42+00:00" }, { "name": "symfony/http-foundation", @@ -8560,16 +8565,16 @@ }, { "name": "symfony/service-contracts", - "version": "v3.0.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c" + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e517458f278c2131ca9f262f8fbaf01410f2c65c", - "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d78d39c1599bd1188b8e26bb341da52c3c6d8a66", + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66", "shasum": "", "mirrors": [ { @@ -8628,7 +8633,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.0.2" }, "funding": [ { @@ -8644,7 +8649,7 @@ "type": "tidelift" } ], - "time": "2022-03-13T20:10:05+00:00" + "time": "2022-05-30T19:17:58+00:00" }, { "name": "symfony/string", @@ -8840,16 +8845,16 @@ }, { "name": "symfony/translation-contracts", - "version": "v3.0.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9" + "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9", - "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/acbfbb274e730e5a0236f619b6168d9dedb3e282", + "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282", "shasum": "", "mirrors": [ { @@ -8904,7 +8909,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/translation-contracts/tree/v3.0.2" }, "funding": [ { @@ -8920,7 +8925,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2022-06-27T17:10:44+00:00" }, { "name": "symfony/var-dumper", @@ -10032,16 +10037,16 @@ }, { "name": "laravel-lang/lang", - "version": "10.9.4", + "version": "10.9.5", "source": { "type": "git", "url": "https://github.com/Laravel-Lang/lang.git", - "reference": "eeb4b38ef7aba493f3915c89b99c803ce096e996" + "reference": "e341421d40f2cd28feca24ab2cb84fa5cb5ddaf6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Laravel-Lang/lang/zipball/eeb4b38ef7aba493f3915c89b99c803ce096e996", - "reference": "eeb4b38ef7aba493f3915c89b99c803ce096e996", + "url": "https://api.github.com/repos/Laravel-Lang/lang/zipball/e341421d40f2cd28feca24ab2cb84fa5cb5ddaf6", + "reference": "e341421d40f2cd28feca24ab2cb84fa5cb5ddaf6", "shasum": "", "mirrors": [ { @@ -10112,7 +10117,7 @@ "type": "open_collective" } ], - "time": "2022-06-22T09:43:06+00:00" + "time": "2022-06-27T01:57:27+00:00" }, { "name": "laravel-lang/publisher", @@ -10431,16 +10436,16 @@ }, { "name": "nunomaduro/collision", - "version": "v6.1.0", + "version": "v6.2.1", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "df09e21a5e5d5a7d51a8b9ecd44d3dd150d97fec" + "reference": "5f058f7e39278b701e455b3c82ec5298cf001d89" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/df09e21a5e5d5a7d51a8b9ecd44d3dd150d97fec", - "reference": "df09e21a5e5d5a7d51a8b9ecd44d3dd150d97fec", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/5f058f7e39278b701e455b3c82ec5298cf001d89", + "reference": "5f058f7e39278b701e455b3c82ec5298cf001d89", "shasum": "", "mirrors": [ { @@ -10457,10 +10462,11 @@ }, "require-dev": { "brianium/paratest": "^6.4.1", - "laravel/framework": "^9.0", + "laravel/framework": "^9.7", + "laravel/pint": "^0.2.1", "nunomaduro/larastan": "^1.0.2", "nunomaduro/mock-final-classes": "^1.1.0", - "orchestra/testbench": "^7.0.0", + "orchestra/testbench": "^7.3.0", "phpunit/phpunit": "^9.5.11" }, "type": "library", @@ -10520,7 +10526,7 @@ "type": "patreon" } ], - "time": "2022-01-18T17:49:08+00:00" + "time": "2022-06-27T16:11:16+00:00" }, { "name": "phar-io/manifest", @@ -12293,16 +12299,16 @@ }, { "name": "sebastian/type", - "version": "3.0.x-dev", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "afad3e987736f63bc54d7c923f0c1ebf247e8618" + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/afad3e987736f63bc54d7c923f0c1ebf247e8618", - "reference": "afad3e987736f63bc54d7c923f0c1ebf247e8618", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", "shasum": "", "mirrors": [ { @@ -12343,7 +12349,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" }, "funding": [ { @@ -12351,7 +12357,7 @@ "type": "github" } ], - "time": "2022-03-27T17:35:59+00:00" + "time": "2022-03-15T09:54:48+00:00" }, { "name": "sebastian/version", diff --git a/include/constants.php b/include/constants.php index dc0b4f2b..2d2a4cd1 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ H&R: %s]', (new \App\Repositories\HitAndRunRepository())->getStatusStats($CURUSER['id']))?> %s]', $CURUSER['id'], (new \App\Repositories\ClaimRepository())->getStats($CURUSER['id']))?> - = UC_SYSOP) { ?> [] + = UC_SYSOP) printf('[%s]', nexus_env('FILAMENT_PATH', 'nexusphp'), $lang_functions['text_management_system'])?>
@@ -3653,7 +3653,7 @@ function get_username($id, $big = false, $link = true, $bold = true, $target = f $disabledpic = "disabled"; $style = "style='margin-left: 2pt'"; } - $pics = $arr["donor"] == "yes" && ($arr['donoruntil'] === null || $arr['donoruntil'] == '0000-00-00 00:00:00' || $arr['donoruntil'] >= date('Y-m-d H:i:s')) ? "\"Donor\"" : ""; + $pics = $arr["donor"] == "yes" && ($arr['donoruntil'] === null || $arr['donoruntil'] < '1970' || $arr['donoruntil'] >= date('Y-m-d H:i:s')) ? "\"Donor\"" : ""; if ($arr["enabled"] == "yes") $pics .= ($arr["leechwarn"] == "yes" ? "\"Leechwarned\"" : "") . ($arr["warned"] == "yes" ? "\"Warned\"" : ""); diff --git a/public/modtask.php b/public/modtask.php index 9a1059f8..7a4c78e5 100644 --- a/public/modtask.php +++ b/public/modtask.php @@ -28,7 +28,7 @@ if ($action == "edituser") $userid = $_POST["userid"]; $class = intval($_POST["class"] ?? 0); $vip_added = ($_POST["vip_added"] == 'yes' ? 'yes' : 'no'); - $vip_until = ($_POST["vip_until"] ? $_POST["vip_until"] : null); + $vip_until = !empty($_POST["vip_until"]) ? $_POST['vip_until'] : null; $warned = $_POST["warned"] ?? ''; $warnlength = intval($_POST["warnlength"] ?? 0); @@ -162,7 +162,7 @@ if ($action == "edituser") $updateset[] = "donated_cny = " . sqlesc($donated_cny); } $updateset[] = "donor = " . sqlesc($donor); - $updateset[] = "donoruntil = " . sqlesc($_POST['donoruntil']); + $updateset[] = "donoruntil = " . sqlesc(!empty($_POST['donoruntil']) ? $_POST['donoruntil'] : null); } if ($chpassword != "" AND $passagain != "") { @@ -339,11 +339,11 @@ if ($action == "edituser") } $updateset[] = "modcomment = " . sqlesc($modcomment); - sql_query("UPDATE users SET " . implode(", ", $updateset) . " WHERE id=$userid") or sqlerr(__FILE__, __LINE__); if (!empty($banLog)) { \App\Models\UserBanLog::query()->insert($banLog); } + \Nexus\Database\NexusDB::cache_del("user_{$userid}_content"); $returnto = htmlspecialchars($_POST["returnto"]); header("Location: " . get_protocol_prefix() . "$BASEURL/$returnto"); die; diff --git a/resources/lang/en/admin.php b/resources/lang/en/admin.php index dd54edf7..87cd0915 100644 --- a/resources/lang/en/admin.php +++ b/resources/lang/en/admin.php @@ -11,6 +11,8 @@ return [ 'exams_list' => 'Exams', 'medals_list' => 'Medals', 'settings' => 'Settings', + 'users_medals' => 'User medals', + 'claims' => 'User claims', ], 'resources' => [ 'agent_allow' => [ @@ -51,6 +53,16 @@ return [ ], 'exam_user' => [ 'bulk_action_avoid_label' => 'Bulk avoid', + 'action_avoid' => 'Avoid', + 'result_passed' => 'Passed!', + 'result_not_passed' => 'Not passed!', + ], + 'exam' => [ + 'index_duplicate' => 'Index::index duplicate !', + ], + 'hit_and_run' => [ + 'bulk_action_pardon' => 'Bulk pardon', + 'action_pardon' => 'Pardon', ], ] ]; diff --git a/resources/lang/en/exam.php b/resources/lang/en/exam.php index 6f045a62..c6c48728 100644 --- a/resources/lang/en/exam.php +++ b/resources/lang/en/exam.php @@ -8,6 +8,11 @@ return [ 'index_text_' . \App\Models\Exam::INDEX_SEED_TIME_AVERAGE => 'Seed time average', 'index_text_' . \App\Models\Exam::INDEX_DOWNLOADED => 'Download increment', 'index_text_' . \App\Models\Exam::INDEX_SEED_BONUS => 'Bonus increment', + 'filters' => [ + \App\Models\Exam::FILTER_USER_CLASS => 'User class', + \App\Models\Exam::FILTER_USER_REGISTER_TIME_RANGE => 'Register time range', + \App\Models\Exam::FILTER_USER_DONATE => 'Donated', + ], 'require_value' => 'Require', 'current_value' => 'Current', 'result' => 'Result', diff --git a/resources/lang/en/label.php b/resources/lang/en/label.php index f69f7d30..2d90a988 100644 --- a/resources/lang/en/label.php +++ b/resources/lang/en/label.php @@ -1,6 +1,30 @@ 'Name', + 'email' => 'Email', + 'image' => 'Image', + 'expire_at' => 'Expire at', + 'username' => 'User', + 'status' => 'Status', + 'enabled' => 'Enabled', + 'disabled' => 'Disabled', + 'created_at' => 'Created at', + 'updated_at' => 'Updated at', + 'begin' => 'Begin time', + 'end' => 'End time', + 'uploaded' => 'Uploaded', + 'downloaded' => 'Downloaded', + 'ratio' => 'Share ratio', + 'seed_time_required' => 'Seed time required', + 'inspect_time_left' => 'Inspect time left', + 'added' => 'Add time', + 'last_access' => 'Last access time', + 'priority' => 'Priority', + 'comment' => 'Comment', + 'duration' => 'Duration', + 'description' => 'Description', + 'price' => 'Price', 'setting' => [ 'nav_text' => 'Setting', 'backup' => [ @@ -36,6 +60,7 @@ return [ ] ], 'user' => [ + 'label' => 'User', 'uploaded' => 'Uploaded', 'downloaded' => 'Downloaded', 'invites' => 'Invites', @@ -45,6 +70,9 @@ return [ 'status' => 'Status', 'enabled' => 'Enabled', 'username' => 'Username', + 'invite_by' => 'Inviter', + 'two_step_authentication' => 'Two-step authentication', + 'seed_points' => 'Seed points', ], 'medal' => [ 'label' => 'Medal', @@ -65,9 +93,24 @@ return [ 'donated' => 'Donated', 'index_formatted' => 'Exam indexes', 'filter_formatted' => 'Target users', + 'section_base_info' => 'Base info', + 'priority_help' => 'The higher the value, the higher the priority, and when multiple exam match the same user, the one with the highest priority is assigned.', + 'section_time' => 'Time', + 'duration_help' => 'Unit: days. When assign to user, begin and end are used if they are specified. Otherwise begin time is the time at assignment, and the end time is the time at assignment plus the duration.', + 'section_target_user' => 'Target user', + 'index_required_value' => 'Require value', + 'index_required_label' => 'Index', + 'index_placeholder' => 'Upload/Download increment in GB and seed time average in hour', + 'index_current_value' => 'Current value', + 'index_result' => 'Result', + ], + 'exam_user' => [ + 'is_done' => 'Is done', ], 'torrent' => [ 'label' => 'Torrent', + 'size' => 'Size', + 'ttl' => 'TTL', ], 'hit_and_run' => [ @@ -98,4 +141,10 @@ return [ 'peer_id' => 'Peer ID', 'agent' => 'Agent', ], + 'claim' => [ + 'last_settle_at' => 'Last settle at', + 'seed_time_this_month' => 'St. this month', + 'uploaded_this_month' => 'Up. this month', + 'is_reached_this_month' => 'Reached', + ], ]; diff --git a/resources/lang/zh_CN/admin.php b/resources/lang/zh_CN/admin.php index 4e63fffa..bb71a1ae 100644 --- a/resources/lang/zh_CN/admin.php +++ b/resources/lang/zh_CN/admin.php @@ -11,7 +11,8 @@ return [ 'exams_list' => '考核', 'medals_list' => '勋章', 'settings' => '设置', - 'users_medal' => '用户勋章', + 'users_medals' => '用户勋章', + 'claims' => '用户认领', ], 'resources' => [ 'agent_allow' => [ @@ -52,6 +53,16 @@ return [ ], 'exam_user' => [ 'bulk_action_avoid_label' => '批量免除', + 'action_avoid' => '免除', + 'result_passed' => '通过!', + 'result_not_passed' => '未通过!', + ], + 'exam' => [ + 'index_duplicate' => '指标::index 重复!', + ], + 'hit_and_run' => [ + 'bulk_action_pardon' => '批量免罪', + 'action_pardon' => '免罪', ], ] ]; diff --git a/resources/lang/zh_CN/exam.php b/resources/lang/zh_CN/exam.php index 486c71ce..bff1252e 100644 --- a/resources/lang/zh_CN/exam.php +++ b/resources/lang/zh_CN/exam.php @@ -8,6 +8,11 @@ return [ 'index_text_' . \App\Models\Exam::INDEX_SEED_TIME_AVERAGE => '平均做种时间', 'index_text_' . \App\Models\Exam::INDEX_DOWNLOADED => '下载增量', 'index_text_' . \App\Models\Exam::INDEX_SEED_BONUS => '魔力增量', + 'filters' => [ + \App\Models\Exam::FILTER_USER_CLASS => '用户等级', + \App\Models\Exam::FILTER_USER_REGISTER_TIME_RANGE => '注册时间范围', + \App\Models\Exam::FILTER_USER_DONATE => '是否捐赠', + ], 'require_value' => '要求', 'current_value' => '当前', 'result' => '结果', diff --git a/resources/lang/zh_CN/label.php b/resources/lang/zh_CN/label.php index 459fae74..dff65135 100644 --- a/resources/lang/zh_CN/label.php +++ b/resources/lang/zh_CN/label.php @@ -7,6 +7,8 @@ return [ 'expire_at' => '过期时间', 'username' => '用户', 'status' => '状态', + 'enabled' => '启用', + 'disabled' => '禁用', 'created_at' => '创建时间', 'updated_at' => '更新时间', 'begin' => '开始时间', @@ -58,6 +60,7 @@ return [ ] ], 'user' => [ + 'label' => '用户', 'uploaded' => '上传量', 'downloaded' => '下载量', 'invites' => '邀请', @@ -67,6 +70,9 @@ return [ 'status' => '状态', 'enabled' => '启用', 'username' => '用户名', + 'invite_by' => '邀请人', + 'two_step_authentication' => '两步验证', + 'seed_points' => '做种积分', ], 'medal' => [ 'label' => '勋章', @@ -78,7 +84,6 @@ return [ ], 'exam' => [ 'label' => '考核', - 'is_done' => '是否完成', 'is_discovered' => '自动发现', 'register_time_range' => [ 'begin' => '注册时间开始', @@ -87,9 +92,24 @@ return [ 'donated' => '是否捐赠', 'index_formatted' => '考核指标', 'filter_formatted' => '目标用户', + 'section_base_info' => '基本信息', + 'priority_help' => '值越大,优先级越高。当用户匹配多个考核时,优先级高的优先分配。', + 'section_time' => '时间', + 'duration_help' => '单位:天。分配给用户时,如果指定了开始/结束时间,用户考核的时间范围就是这个范围。否则,用户考核的开始时间是分配时间,结束时间是开始时间加上时长。', + 'section_target_user' => '目标用户', + 'index_required_value' => '要求量', + 'index_required_label' => '指标', + 'index_placeholder' => '上传增量/下载增量单位为:GB,平均做种时间单位为:小时', + 'index_current_value' => '当前量', + 'index_result' => '结果', + ], + 'exam_user' => [ + 'is_done' => '是否完成', ], 'torrent' => [ 'label' => '种子', + 'size' => '体积', + 'ttl' => '存活时间', ], 'hit_and_run' => [ @@ -120,4 +140,10 @@ return [ 'peer_id' => 'Peer ID', 'agent' => 'Agent', ], + 'claim' => [ + 'last_settle_at' => '上次结算时间', + 'seed_time_this_month' => '本月做种时间', + 'uploaded_this_month' => '本月上传量', + 'is_reached_this_month' => '本月是否达标', + ], ]; diff --git a/resources/lang/zh_TW/admin.php b/resources/lang/zh_TW/admin.php index db540684..7b6b2032 100644 --- a/resources/lang/zh_TW/admin.php +++ b/resources/lang/zh_TW/admin.php @@ -11,7 +11,8 @@ return [ 'exams_list' => '考核', 'medals_list' => '勛章', 'settings' => '設置', - 'users_medal' => '用戶勛章', + 'users_medals' => '用戶勛章', + 'claims' => '用戶認領', ], 'resources' => [ 'agent_allow' => [ @@ -52,6 +53,16 @@ return [ ], 'exam_user' => [ 'bulk_action_avoid_label' => '批量免除', + 'action_avoid' => '免除', + 'result_passed' => '通過!', + 'result_not_passed' => '未通過!', + ], + 'exam' => [ + 'index_duplicate' => '指標::index 重復!', + ], + 'hit_and_run' => [ + 'bulk_action_pardon' => '批量免罪', + 'action_pardon' => '免罪', ], ] ]; diff --git a/resources/lang/zh_TW/exam.php b/resources/lang/zh_TW/exam.php index e863e023..e6e5a1b7 100644 --- a/resources/lang/zh_TW/exam.php +++ b/resources/lang/zh_TW/exam.php @@ -8,6 +8,11 @@ return [ 'index_text_' . \App\Models\Exam::INDEX_SEED_TIME_AVERAGE => '平均做種時間', 'index_text_' . \App\Models\Exam::INDEX_DOWNLOADED => '下載增量', 'index_text_' . \App\Models\Exam::INDEX_SEED_BONUS => '魔力增量', + 'filters' => [ + \App\Models\Exam::FILTER_USER_CLASS => '用戶等級', + \App\Models\Exam::FILTER_USER_REGISTER_TIME_RANGE => '註冊時間範圍', + \App\Models\Exam::FILTER_USER_DONATE => '是否捐贈', + ], 'require_value' => '要求', 'current_value' => '當前', 'result' => '結果', diff --git a/resources/lang/zh_TW/label.php b/resources/lang/zh_TW/label.php index ef944cfb..785ce460 100644 --- a/resources/lang/zh_TW/label.php +++ b/resources/lang/zh_TW/label.php @@ -7,6 +7,8 @@ return [ 'expire_at' => '過期時間', 'username' => '用戶', 'status' => '狀態', + 'enabled' => '啟用', + 'disabled' => '禁用', 'created_at' => '創建時間', 'updated_at' => '更新時間', 'begin' => '開始時間', @@ -58,6 +60,7 @@ return [ ] ], 'user' => [ + 'label' => '用戶', 'uploaded' => '上傳量', 'downloaded' => '下載量', 'invites' => '邀請', @@ -67,6 +70,9 @@ return [ 'status' => '狀態', 'enabled' => '啟用', 'username' => '用戶名', + 'invite_by' => '邀請人', + 'two_step_authentication' => '兩步驗證', + 'seed_points' => '做種積分', ], 'medal' => [ 'label' => '勛章', @@ -87,9 +93,24 @@ return [ 'donated' => '是否捐贈', 'index_formatted' => '考核指標', 'filter_formatted' => '目標用戶', + 'section_base_info' => '基本信息', + 'priority_help' => '值越大,優先級越高。當用戶匹配多個考核時,優先級高的優先分配。', + 'section_time' => '時間', + 'duration_help' => '單位:天。分配給用戶時,如果指定了開始/結束時間,用戶考核的時間範圍就是這個範圍。否則,用戶考核的開始時間是分配時間,結束時間是開始時間加上時長。', + 'section_target_user' => '目標用戶', + 'index_required_value' => '要求量', + 'index_required_label' => '指標', + 'index_placeholder' => '上傳增量/下載增量單位為:GB,平均做種時間單位為:小時', + 'index_current_value' => '當前量', + 'index_result' => '結果', + ], + 'exam_user' => [ + 'is_done' => '是否完成', ], 'torrent' => [ 'label' => '種子', + 'size' => '體積', + 'ttl' => '存活時間', ], 'hit_and_run' => [ @@ -120,4 +141,10 @@ return [ 'peer_id' => 'Peer ID', 'agent' => 'Agent', ], + 'claim' => [ + 'last_settle_at' => '上次結算時間', + 'seed_time_this_month' => '本月做種時間', + 'uploaded_this_month' => '本月上傳量', + 'is_reached_this_month' => '本月是否達標', + ], ]; diff --git a/resources/views/filament/detail-card.blade.php b/resources/views/filament/detail-card.blade.php new file mode 100644 index 00000000..b1de761b --- /dev/null +++ b/resources/views/filament/detail-card.blade.php @@ -0,0 +1,20 @@ + +
+ + + @foreach($cardData as $value) + + + + + @endforeach + +
{{ $value['label'] }}{!! $value['value'] !!}
+
+ + @if (count($relationManagers = $this->getRelationManagers())) + + + + @endif +
diff --git a/resources/views/filament/resources/user/exam-user-resource/pages/detail.blade.php b/resources/views/filament/resources/user/exam-user-resource/pages/detail.blade.php new file mode 100644 index 00000000..74a0649f --- /dev/null +++ b/resources/views/filament/resources/user/exam-user-resource/pages/detail.blade.php @@ -0,0 +1,40 @@ + +
+ + + @foreach($cardData as $value) + + + + + @endforeach + +
{{ $value['label'] }}{!! $value['value'] !!}
+ + + + + + + + + + + @foreach($record->progressFormatted as $index) + + + + + + + @endforeach + +
{{ __('label.exam.index_required_label') }}{{ __('label.exam.index_required_value') }}{{ __('label.exam.index_current_value') }}{{ __('label.exam.index_result') }}
{{ $index['index_formatted'] }}{{ $index['require_value_formatted'] }}{{ $index['current_value_formatted'] }}{{ $index['passed'] ? __('admin.resources.exam_user.result_passed') : __('admin.resources.exam_user.result_not_passed') }}
+
+ + @if (count($relationManagers = $this->getRelationManagers())) + + + + @endif +
diff --git a/resources/views/filament/resources/user/user-resource/pages/user-profile.blade.php b/resources/views/filament/resources/user/user-resource/pages/user-profile.blade.php index 021659fb..ca7ce928 100644 --- a/resources/views/filament/resources/user/user-resource/pages/user-profile.blade.php +++ b/resources/views/filament/resources/user/user-resource/pages/user-profile.blade.php @@ -1,95 +1,89 @@
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
UID{{$record->id}}
Username{{$record->username}}
Email{{$record->email}}
Status{{$record->status}}
Enabled{{$record->enabled}}
Added{{$record->added}}
Last access{{$record->last_access}}
Class{{$record->classText}}
Invite by{{$record->inviter->username ?? ''}}
Tow-step authentication{{$record->two_step_secret ? 'Enabled' : 'Disabled'}}
Seed points{{$record->seed_points}}
Attendance card{{$record->attendance_card}}
Invites{{$record->invites}}
Uploaded{{$record->uploadedText}}
Downloaded{{$record->downloadedText}}
Bonus{{$record->seedbonus}}
-
-
- -
- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
UID{{$record->id}}
{{__('label.user.username')}}{{$record->username}}
{{__('label.email')}}{{$record->email}}
{{__('label.status')}}{{$record->status}}
{{__('label.enabled')}}{{$record->enabled}}
{{__('label.added')}}{{$record->added}}
{{__('label.last_access')}}{{$record->last_access}}
{{__('label.user.class')}}{{$record->classText}}
{{__('label.user.invite_by')}}{{$record->inviter->username ?? ''}}
{{__('label.user.two_step_authentication')}}{{$record->two_step_secret ? 'Enabled' : 'Disabled'}}
{{__('label.user.seed_points')}}{{$record->seed_points}}
{{ __('label.user.attendance_card') }}{{$record->attendance_card}}
{{ __('label.user.invites') }}{{$record->invites}}
{{ __('label.uploaded') }}{{$record->uploadedText}}
{{ __('label.downloaded') }}{{$record->downloadedText}}
{{ __('label.user.seedbonus') }}{{$record->seedbonus}}
@if (count($relationManagers = $this->getRelationManagers()))