mirror of
https://github.com/lkddi/nexusphp.git
synced 2026-04-24 12:07:23 +08:00
Introduce filament
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
namespace App\Auth;
|
||||
|
||||
use Illuminate\Auth\GuardHelpers;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class NexusWebGuard implements Guard
|
||||
{
|
||||
use GuardHelpers;
|
||||
|
||||
/**
|
||||
* The request instance.
|
||||
*
|
||||
* @var \Illuminate\Http\Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* Create a new authentication guard.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Illuminate\Contracts\Auth\UserProvider|null $provider
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Request $request, UserProvider $provider = null)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->provider = $provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently authenticated user.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
if (! is_null($this->user)) {
|
||||
return $this->user;
|
||||
}
|
||||
return $this->user = $this->provider->retrieveByCredentials($this->request->cookie());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate a user's credentials.
|
||||
*
|
||||
* @param array $credentials
|
||||
* @return bool
|
||||
*/
|
||||
public function validate(array $credentials = [])
|
||||
{
|
||||
$required = ['c_secure_pass', 'c_secure_uid', 'c_secure_login'];
|
||||
foreach ($required as $value) {
|
||||
if (empty($credentials[$value])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$b_id = base64($credentials["c_secure_uid"],false);
|
||||
$id = intval($b_id ?? 0);
|
||||
if (!$id || !is_valid_id($id) || strlen($credentials["c_secure_pass"]) != 32) {
|
||||
return false;
|
||||
}
|
||||
if ($this->provider->retrieveById($id)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function logout()
|
||||
{
|
||||
logoutcookie();
|
||||
return nexus_redirect('login.php');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
namespace App\Auth;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
|
||||
class NexusWebUserProvider implements UserProvider
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->query = User::query();
|
||||
}
|
||||
/**
|
||||
* Retrieve a user by their unique identifier.
|
||||
*
|
||||
* @param mixed $identifier
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
||||
*/
|
||||
public function retrieveById($identifier)
|
||||
{
|
||||
return $this->query->find($identifier);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve a user by their unique identifier and "remember me" token.
|
||||
*
|
||||
* @param mixed $identifier
|
||||
* @param string $token
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
||||
*/
|
||||
public function retrieveByToken($identifier, $token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the "remember me" token for the given user in storage.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\Authenticatable $user
|
||||
* @param string $token
|
||||
* @return void
|
||||
*/
|
||||
public function updateRememberToken(Authenticatable $user, $token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve a user by the given credentials.
|
||||
*
|
||||
* @param array $credentials
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
||||
*/
|
||||
public function retrieveByCredentials(array $credentials)
|
||||
{
|
||||
if (!empty($credentials['c_secure_uid'])) {
|
||||
$b_id = base64($credentials["c_secure_uid"],false);
|
||||
return $this->query->find($b_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a user against the given credentials.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\Authenticatable $user
|
||||
* @param array $credentials
|
||||
* @return bool
|
||||
*/
|
||||
public function validateCredentials(Authenticatable $user, array $credentials)
|
||||
{
|
||||
if ($credentials["c_secure_login"] == base64("yeah")) {
|
||||
if ($credentials["c_secure_pass"] != md5($user->passhash . $_SERVER["REMOTE_ADDR"])) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ($credentials["c_secure_pass"] !== md5($user->passhash)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -78,13 +78,10 @@ class Test extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$a = 2;
|
||||
$b = 2;
|
||||
if ($a != 1 && $b == 2) {
|
||||
echo "OK";
|
||||
} else {
|
||||
echo 'Bad';
|
||||
}
|
||||
$r = 'MTAwNDI%3D';
|
||||
$r = 'MTAwNDI%3D';
|
||||
$r = 'MTAwMDM%3D';
|
||||
dd(base64_decode($r));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament;
|
||||
|
||||
trait NexusOptionsTrait
|
||||
{
|
||||
private static array $matchTypes = ['dec' => 'dec', 'hex' => 'hex'];
|
||||
|
||||
private static array $yesOrNo = ['yes' => 'yes', 'no' => 'no'];
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament;
|
||||
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class PageList extends ListRecords
|
||||
{
|
||||
protected ?string $maxContentWidth = 'full';
|
||||
|
||||
protected function getTableRecordUrlUsing(): ?\Closure
|
||||
{
|
||||
return function (Model $record): ?string {
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
class Dashboard extends \Filament\Pages\Dashboard
|
||||
{
|
||||
protected ?string $maxContentWidth = 'full';
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System;
|
||||
|
||||
use App\Filament\NexusOptionsTrait;
|
||||
use App\Filament\Resources\System\AgentAllowResource\Pages;
|
||||
use App\Filament\Resources\System\AgentAllowResource\RelationManagers;
|
||||
use App\Models\AgentAllow;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Resources\Table;
|
||||
use Filament\Tables;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class AgentAllowResource extends Resource
|
||||
{
|
||||
use NexusOptionsTrait;
|
||||
|
||||
protected static ?string $model = AgentAllow::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-check';
|
||||
|
||||
protected static ?string $navigationGroup = 'System';
|
||||
|
||||
protected static function getNavigationLabel(): string
|
||||
{
|
||||
return __('admin.sidebar.agent_allows');
|
||||
}
|
||||
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('family')->required(),
|
||||
Forms\Components\TextInput::make('start_name')->required(),
|
||||
Forms\Components\TextInput::make('peer_id_start')->required(),
|
||||
Forms\Components\TextInput::make('peer_id_pattern')->required(),
|
||||
Forms\Components\Radio::make('peer_id_matchtype')->options(self::$matchTypes)->required(),
|
||||
Forms\Components\TextInput::make('peer_id_match_num')->integer()->required(),
|
||||
Forms\Components\TextInput::make('agent_start')->required(),
|
||||
Forms\Components\TextInput::make('agent_pattern')->required(),
|
||||
Forms\Components\Radio::make('agent_matchtype')->options(self::$matchTypes)->required(),
|
||||
Forms\Components\TextInput::make('agent_match_num')->required(),
|
||||
Forms\Components\Radio::make('exception')->options(self::$yesOrNo)->required(),
|
||||
Forms\Components\Radio::make('allowhttps')->options(self::$yesOrNo)->required(),
|
||||
|
||||
Forms\Components\Textarea::make('comment'),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('family')->searchable(),
|
||||
Tables\Columns\TextColumn::make('start_name')->searchable(),
|
||||
Tables\Columns\TextColumn::make('peer_id_start'),
|
||||
Tables\Columns\TextColumn::make('agent_start'),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
RelationManagers\DeniesRelationManager::class,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListAgentAllows::route('/'),
|
||||
'create' => Pages\CreateAgentAllow::route('/create'),
|
||||
'edit' => Pages\EditAgentAllow::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\AgentAllowResource\Pages;
|
||||
|
||||
use App\Filament\Resources\System\AgentAllowResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateAgentAllow extends CreateRecord
|
||||
{
|
||||
protected static string $resource = AgentAllowResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\AgentAllowResource\Pages;
|
||||
|
||||
use App\Filament\Resources\System\AgentAllowResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditAgentAllow extends EditRecord
|
||||
{
|
||||
protected static string $resource = AgentAllowResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\AgentAllowResource\Pages;
|
||||
|
||||
use App\Filament\PageList;
|
||||
use App\Filament\Resources\System\AgentAllowResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListAgentAllows extends PageList
|
||||
{
|
||||
protected static string $resource = AgentAllowResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\AgentAllowResource\RelationManagers;
|
||||
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\Form;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Resources\Table;
|
||||
use Filament\Tables;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class DeniesRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'denies';
|
||||
|
||||
protected static ?string $recordTitleAttribute = 'name';
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('name')->required()->maxLength(255),
|
||||
Forms\Components\TextInput::make('peer_id')->required()->maxLength(255),
|
||||
Forms\Components\TextInput::make('agent')->required()->maxLength(255),
|
||||
Forms\Components\Textarea::make('comment'),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('name'),
|
||||
Tables\Columns\TextColumn::make('peer_id'),
|
||||
Tables\Columns\TextColumn::make('agent'),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
Tables\Actions\CreateAction::make(),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System;
|
||||
|
||||
use App\Filament\Resources\System\AgentDenyResource\Pages;
|
||||
use App\Filament\Resources\System\AgentDenyResource\RelationManagers;
|
||||
use App\Models\AgentDeny;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Resources\Table;
|
||||
use Filament\Tables;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class AgentDenyResource extends Resource
|
||||
{
|
||||
protected static ?string $model = AgentDeny::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-ban';
|
||||
|
||||
protected static ?string $navigationGroup = 'System';
|
||||
|
||||
protected static function getNavigationLabel(): string
|
||||
{
|
||||
return __('admin.sidebar.agent_denies');
|
||||
}
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Select::make('family_id')->label('Allow family')
|
||||
->relationship('family', 'family')->required(),
|
||||
Forms\Components\TextInput::make('name')->required(),
|
||||
Forms\Components\TextInput::make('peer_id')->required(),
|
||||
Forms\Components\TextInput::make('agent')->required(),
|
||||
Forms\Components\Textarea::make('comment'),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('family.family')->label('Family'),
|
||||
Tables\Columns\TextColumn::make('name')->searchable(),
|
||||
Tables\Columns\TextColumn::make('peer_id')->searchable(),
|
||||
Tables\Columns\TextColumn::make('agent')->searchable(),
|
||||
])
|
||||
->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\ListAgentDenies::route('/'),
|
||||
'create' => Pages\CreateAgentDeny::route('/create'),
|
||||
'edit' => Pages\EditAgentDeny::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\AgentDenyResource\Pages;
|
||||
|
||||
use App\Filament\Resources\System\AgentDenyResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateAgentDeny extends CreateRecord
|
||||
{
|
||||
protected static string $resource = AgentDenyResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\AgentDenyResource\Pages;
|
||||
|
||||
use App\Filament\Resources\System\AgentDenyResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditAgentDeny extends EditRecord
|
||||
{
|
||||
protected static string $resource = AgentDenyResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\AgentDenyResource\Pages;
|
||||
|
||||
use App\Filament\PageList;
|
||||
use App\Filament\Resources\System\AgentDenyResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListAgentDenies extends PageList
|
||||
{
|
||||
protected static string $resource = AgentDenyResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System;
|
||||
|
||||
use App\Filament\Resources\System\ExamResource\Pages;
|
||||
use App\Filament\Resources\System\ExamResource\RelationManagers;
|
||||
use App\Models\Exam;
|
||||
use App\Repositories\UserRepository;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Resources\Table;
|
||||
use Filament\Tables;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class ExamResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Exam::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-exclamation';
|
||||
|
||||
protected static ?string $navigationGroup = 'System';
|
||||
|
||||
protected static function getNavigationLabel(): string
|
||||
{
|
||||
return __('admin.sidebar.exams_list');
|
||||
}
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
$userRep = new UserRepository();
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\Section::make('Base info')->schema([
|
||||
Forms\Components\TextInput::make('name')->required()->columnSpan(['sm' => 2]),
|
||||
Forms\Components\TextInput::make('priority')->columnSpan(['sm' => 2])->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\Radio::make('status')->options(['0' => 'Enabled', '1' => 'Disabled'])->inline()->columnSpan(['sm' => 2]),
|
||||
Forms\Components\Radio::make('is_discovered')->options(['0' => 'No', '1' => 'Yes'])->label('Discovered')->inline()->columnSpan(['sm' => 2]),
|
||||
])->columns(2),
|
||||
|
||||
Forms\Components\Section::make('Time')->schema([
|
||||
Forms\Components\DateTimePicker::make('begin'),
|
||||
Forms\Components\DateTimePicker::make('end'),
|
||||
Forms\Components\TextInput::make('duration')->integer()->columnSpan(['sm' => 2])
|
||||
->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.'),
|
||||
])->columns(2),
|
||||
|
||||
Forms\Components\Section::make('Select user')->schema([
|
||||
Forms\Components\CheckboxList::make('filters.classes')->options($userRep->listClass())->columnSpan(['sm' => 2])->columns(4)->label('Classes'),
|
||||
Forms\Components\DateTimePicker::make('filters.register_time_range.0')->label('Register time begin'),
|
||||
Forms\Components\DateTimePicker::make('filters.register_time_range.1')->label('Register time end'),
|
||||
Forms\Components\Toggle::make('filters.donate_status')->label('Donated'),
|
||||
])->columns(2),
|
||||
|
||||
|
||||
Forms\Components\Textarea::make('description')->columnSpan(['sm' => 2]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('name'),
|
||||
Tables\Columns\TextColumn::make('indexFormatted')->label('Indexes')->html(),
|
||||
Tables\Columns\TextColumn::make('begin'),
|
||||
Tables\Columns\TextColumn::make('end'),
|
||||
Tables\Columns\TextColumn::make('durationText')->label('Duration'),
|
||||
Tables\Columns\TextColumn::make('filterFormatted')->label('Target users')->html(),
|
||||
Tables\Columns\BooleanColumn::make('is_discovered')->label('Discovered'),
|
||||
Tables\Columns\TextColumn::make('priority')->label('Priority'),
|
||||
Tables\Columns\TextColumn::make('statusText')->label('Status'),
|
||||
])
|
||||
->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\ListExams::route('/'),
|
||||
'create' => Pages\CreateExam::route('/create'),
|
||||
'edit' => Pages\EditExam::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\ExamResource\Pages;
|
||||
|
||||
use App\Filament\Resources\System\ExamResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateExam extends CreateRecord
|
||||
{
|
||||
protected static string $resource = ExamResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\ExamResource\Pages;
|
||||
|
||||
use App\Filament\Resources\System\ExamResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditExam extends EditRecord
|
||||
{
|
||||
protected static string $resource = ExamResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\ExamResource\Pages;
|
||||
|
||||
use App\Filament\PageList;
|
||||
use App\Filament\Resources\System\ExamResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListExams extends PageList
|
||||
{
|
||||
protected static string $resource = ExamResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System;
|
||||
|
||||
use App\Filament\Resources\System\MedalResource\Pages;
|
||||
use App\Filament\Resources\System\MedalResource\RelationManagers;
|
||||
use App\Models\Medal;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Resources\Table;
|
||||
use Filament\Tables;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class MedalResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Medal::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-badge-check';
|
||||
|
||||
protected static ?string $navigationGroup = 'System';
|
||||
|
||||
protected static function getNavigationLabel(): string
|
||||
{
|
||||
return __('admin.sidebar.medals_list');
|
||||
}
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('name')->required(),
|
||||
Forms\Components\TextInput::make('price')->required()->integer(),
|
||||
Forms\Components\TextInput::make('image_large')->required(),
|
||||
Forms\Components\TextInput::make('image_small')->required(),
|
||||
Forms\Components\Radio::make('get_type')->options(Medal::listGetTypes(true))->inline()->columnSpan(['sm' => 2])->required(),
|
||||
Forms\Components\TextInput::make('duration')->integer()->columnSpan(['sm' => 2])->helperText('Unit: day, if empty, belongs to user forever.'),
|
||||
Forms\Components\Textarea::make('description')->columnSpan(['sm' => 2]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('name'),
|
||||
Tables\Columns\ImageColumn::make('image_large')->height(120),
|
||||
Tables\Columns\ImageColumn::make('image_small')->height(120),
|
||||
Tables\Columns\TextColumn::make('getTypeText')->label('Get type'),
|
||||
Tables\Columns\TextColumn::make('price'),
|
||||
Tables\Columns\TextColumn::make('duration'),
|
||||
])
|
||||
->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\ListMedals::route('/'),
|
||||
'create' => Pages\CreateMedal::route('/create'),
|
||||
'edit' => Pages\EditMedal::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\MedalResource\Pages;
|
||||
|
||||
use App\Filament\Resources\System\MedalResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateMedal extends CreateRecord
|
||||
{
|
||||
protected static string $resource = MedalResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\MedalResource\Pages;
|
||||
|
||||
use App\Filament\Resources\System\MedalResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditMedal extends EditRecord
|
||||
{
|
||||
protected static string $resource = MedalResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\MedalResource\Pages;
|
||||
|
||||
use App\Filament\PageList;
|
||||
use App\Filament\Resources\System\MedalResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListMedals extends PageList
|
||||
{
|
||||
protected static string $resource = MedalResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System;
|
||||
|
||||
use App\Filament\NexusOptionsTrait;
|
||||
use App\Filament\Resources\System\SettingResource\Pages;
|
||||
use App\Filament\Resources\System\SettingResource\RelationManagers;
|
||||
use App\Models\Setting;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Resources\Table;
|
||||
use Filament\Tables;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class SettingResource extends Resource
|
||||
{
|
||||
use NexusOptionsTrait;
|
||||
|
||||
protected static ?string $model = Setting::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-cog';
|
||||
|
||||
protected static ?string $navigationGroup = 'System';
|
||||
|
||||
protected static function getNavigationLabel(): string
|
||||
{
|
||||
return __('admin.sidebar.settings');
|
||||
}
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('name')->required()->disabled()->columnSpan(['sm' => 2]),
|
||||
Forms\Components\Textarea::make('value')->required()->columnSpan(['sm' => 2])
|
||||
->afterStateHydrated(function (Forms\Components\Textarea $component, $state) {
|
||||
$arr = json_decode($state, true);
|
||||
if (is_array($arr)) {
|
||||
$component->disabled();
|
||||
}
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('name')->searchable(),
|
||||
Tables\Columns\TextColumn::make('value')->limit(),
|
||||
Tables\Columns\BadgeColumn::make('autoload')->colors(['success' => 'yes', 'warning' => 'no']),
|
||||
Tables\Columns\TextColumn::make('updated_at'),
|
||||
])
|
||||
->filters([
|
||||
Tables\Filters\SelectFilter::make('autoload')->options(self::$yesOrNo),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
// Tables\Actions\DeleteBulkAction::make(),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListSettings::route('/'),
|
||||
// 'create' => Pages\CreateSetting::route('/create'),
|
||||
'edit' => Pages\EditSetting::route('/{record}/edit'),
|
||||
'hit-and-run' => Pages\EditHitAndRun::route('/hit-and-run'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\SettingResource\Pages;
|
||||
|
||||
use App\Filament\Resources\System\SettingResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateSetting extends CreateRecord
|
||||
{
|
||||
protected static string $resource = SettingResource::class;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\SettingResource\Pages;
|
||||
|
||||
use App\Filament\Resources\System\SettingResource;
|
||||
use Filament\Resources\Pages\Page;
|
||||
|
||||
class EditHitAndRun extends Page
|
||||
{
|
||||
protected static string $resource = SettingResource::class;
|
||||
|
||||
protected static string $view = 'filament.resources.system.setting-resource.pages.edit-hit-and-run';
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\SettingResource\Pages;
|
||||
|
||||
use App\Filament\Resources\System\SettingResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditSetting extends EditRecord
|
||||
{
|
||||
protected static string $resource = SettingResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRedirectUrl(): ?string
|
||||
{
|
||||
return $this->getResource()::getUrl('index');
|
||||
}
|
||||
|
||||
protected function mutateFormDataBeforeSave(array $data): array
|
||||
{
|
||||
$arr = json_decode($data['value'], true);
|
||||
if (is_array($arr)) {
|
||||
throw new \LogicException("Not support edit this !");
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\System\SettingResource\Pages;
|
||||
|
||||
use App\Filament\PageList;
|
||||
use App\Filament\Resources\System\SettingResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListSettings extends PageList
|
||||
{
|
||||
protected static string $resource = SettingResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
// Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Torrent;
|
||||
|
||||
use App\Filament\Resources\Torrent\TagResource\Pages;
|
||||
use App\Filament\Resources\Torrent\TagResource\RelationManagers;
|
||||
use App\Models\Tag;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Resources\Table;
|
||||
use Filament\Tables;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class TagResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Tag::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-tag';
|
||||
|
||||
protected static ?string $navigationGroup = 'Torrent';
|
||||
|
||||
protected static function getNavigationLabel(): string
|
||||
{
|
||||
return __('admin.sidebar.tags_list');
|
||||
}
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Forms\Components\TextInput::make('name')->required(),
|
||||
Forms\Components\TextInput::make('color')->required()->label('Background color'),
|
||||
Forms\Components\TextInput::make('font_color')->required(),
|
||||
Forms\Components\TextInput::make('font_size')->required(),
|
||||
Forms\Components\TextInput::make('margin')->required(),
|
||||
Forms\Components\TextInput::make('padding')->required(),
|
||||
Forms\Components\TextInput::make('border_radius')->required(),
|
||||
Forms\Components\TextInput::make('priority')->integer(),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('name'),
|
||||
Tables\Columns\TextColumn::make('color')->label('Background color'),
|
||||
Tables\Columns\TextColumn::make('font_color'),
|
||||
Tables\Columns\TextColumn::make('font_size'),
|
||||
Tables\Columns\TextColumn::make('margin'),
|
||||
Tables\Columns\TextColumn::make('padding'),
|
||||
Tables\Columns\TextColumn::make('border_radius'),
|
||||
Tables\Columns\TextColumn::make('priority'),
|
||||
Tables\Columns\TextColumn::make('updated_at')->dateTime('Y-m-d H:i'),
|
||||
])
|
||||
->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\ListTags::route('/'),
|
||||
'create' => Pages\CreateTag::route('/create'),
|
||||
'edit' => Pages\EditTag::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Torrent\TagResource\Pages;
|
||||
|
||||
use App\Filament\Resources\Torrent\TagResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateTag extends CreateRecord
|
||||
{
|
||||
protected static string $resource = TagResource::class;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Torrent\TagResource\Pages;
|
||||
|
||||
use App\Filament\Resources\Torrent\TagResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditTag extends EditRecord
|
||||
{
|
||||
protected static string $resource = TagResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRedirectUrl(): ?string
|
||||
{
|
||||
return $this->getResource()::getUrl('index');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Torrent\TagResource\Pages;
|
||||
|
||||
use App\Filament\PageList;
|
||||
use App\Filament\Resources\Torrent\TagResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListTags extends PageList
|
||||
{
|
||||
protected static string $resource = TagResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User;
|
||||
|
||||
use App\Filament\Resources\User\ExamUserResource\Pages;
|
||||
use App\Filament\Resources\User\ExamUserResource\RelationManagers;
|
||||
use App\Models\ExamUser;
|
||||
use App\Repositories\ExamRepository;
|
||||
use App\Repositories\HitAndRunRepository;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Resources\Table;
|
||||
use Filament\Tables;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ExamUserResource extends Resource
|
||||
{
|
||||
protected static ?string $model = ExamUser::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-user';
|
||||
|
||||
protected static ?string $navigationGroup = 'User';
|
||||
|
||||
protected static function getNavigationLabel(): string
|
||||
{
|
||||
return __('admin.sidebar.exam_users');
|
||||
}
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('user.username')->label('User')->searchable(),
|
||||
Tables\Columns\TextColumn::make('exam.name')->label('Exam'),
|
||||
Tables\Columns\BooleanColumn::make('is_done')->label('Is done'),
|
||||
Tables\Columns\TextColumn::make('statusText')->label('Status'),
|
||||
Tables\Columns\TextColumn::make('created_at')->dateTime('Y-m-d H:i'),
|
||||
])
|
||||
->filters([
|
||||
Tables\Filters\SelectFilter::make('status')->options(ExamUser::listStatus(true)),
|
||||
Tables\Filters\SelectFilter::make('is_done')->options(['0' => 'No', '1' => 'yes']),
|
||||
])
|
||||
->actions([
|
||||
// Tables\Actions\ViewAction::make(),
|
||||
])
|
||||
->prependBulkActions([
|
||||
Tables\Actions\BulkAction::make('Avoid')->action(function (Collection $records) {
|
||||
$idArr = $records->pluck('id')->toArray();
|
||||
$rep = new ExamRepository();
|
||||
$rep->avoidExamUserBulk(['id' => $idArr], Auth::user());
|
||||
})
|
||||
->deselectRecordsAfterCompletion()
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListExamUsers::route('/'),
|
||||
'create' => Pages\CreateExamUser::route('/create'),
|
||||
'edit' => Pages\EditExamUser::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\ExamUserResource\Pages;
|
||||
|
||||
use App\Filament\Resources\User\ExamUserResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateExamUser extends CreateRecord
|
||||
{
|
||||
protected static string $resource = ExamUserResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\ExamUserResource\Pages;
|
||||
|
||||
use App\Filament\Resources\User\ExamUserResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditExamUser extends EditRecord
|
||||
{
|
||||
protected static string $resource = ExamUserResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\ExamUserResource\Pages;
|
||||
|
||||
use App\Filament\PageList;
|
||||
use App\Filament\Resources\User\ExamUserResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListExamUsers extends PageList
|
||||
{
|
||||
protected static string $resource = ExamUserResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
// Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User;
|
||||
|
||||
use App\Filament\Resources\User\HitAndRunResource\Pages;
|
||||
use App\Filament\Resources\User\HitAndRunResource\RelationManagers;
|
||||
use App\Models\HitAndRun;
|
||||
use App\Repositories\HitAndRunRepository;
|
||||
use Filament\Forms;
|
||||
use Filament\Resources\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Resources\Table;
|
||||
use Filament\Tables;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class HitAndRunResource extends Resource
|
||||
{
|
||||
protected static ?string $model = HitAndRun::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-beaker';
|
||||
|
||||
protected static ?string $navigationGroup = 'User';
|
||||
|
||||
protected static function getNavigationLabel(): string
|
||||
{
|
||||
return __('admin.sidebar.hit_and_runs');
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id'),
|
||||
Tables\Columns\TextColumn::make('user.username')->searchable(),
|
||||
Tables\Columns\TextColumn::make('torrent.name')->limit(50),
|
||||
Tables\Columns\TextColumn::make('snatch.uploadText')->label('Uploaded'),
|
||||
Tables\Columns\TextColumn::make('snatch.downloadText')->label('Downloaded'),
|
||||
Tables\Columns\TextColumn::make('snatch.shareRatio')->label('Ratio'),
|
||||
Tables\Columns\TextColumn::make('seedTimeRequired'),
|
||||
Tables\Columns\TextColumn::make('inspectTimeLeft'),
|
||||
Tables\Columns\TextColumn::make('statusText')->label('Status'),
|
||||
])
|
||||
->filters([
|
||||
Tables\Filters\SelectFilter::make('status')->options(HitAndRun::listStatus(true)),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\ViewAction::make(),
|
||||
])
|
||||
->prependBulkActions([
|
||||
Tables\Actions\BulkAction::make('Pardon')->action(function (Collection $records) {
|
||||
$idArr = $records->pluck('id')->toArray();
|
||||
$rep = new HitAndRunRepository();
|
||||
$rep->bulkPardon(['id' => $idArr], Auth::user());
|
||||
})
|
||||
->deselectRecordsAfterCompletion()
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListHitAndRuns::route('/'),
|
||||
// 'create' => Pages\CreateHitAndRun::route('/create'),
|
||||
// 'edit' => Pages\EditHitAndRun::route('/{record}/edit'),
|
||||
'view' => Pages\ViewHitAndRun::route('/{record}'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\HitAndRunResource\Pages;
|
||||
|
||||
use App\Filament\Resources\User\HitAndRunResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateHitAndRun extends CreateRecord
|
||||
{
|
||||
protected static string $resource = HitAndRunResource::class;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\HitAndRunResource\Pages;
|
||||
|
||||
use App\Filament\Resources\User\HitAndRunResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditHitAndRun extends EditRecord
|
||||
{
|
||||
protected static string $resource = HitAndRunResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\HitAndRunResource\Pages;
|
||||
|
||||
use App\Filament\PageList;
|
||||
use App\Filament\Resources\User\HitAndRunResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListHitAndRuns extends PageList
|
||||
{
|
||||
protected static string $resource = HitAndRunResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
// Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\HitAndRunResource\Pages;
|
||||
|
||||
use App\Filament\Resources\User\HitAndRunResource;
|
||||
use App\Models\HitAndRun;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
use Filament\Forms;
|
||||
|
||||
class ViewHitAndRun extends ViewRecord
|
||||
{
|
||||
protected static string $resource = HitAndRunResource::class;
|
||||
|
||||
protected function getFormSchema(): 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'),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User;
|
||||
|
||||
use App\Filament\Resources\User\UserResource\Pages;
|
||||
use App\Filament\Resources\User\UserResource\RelationManagers;
|
||||
use App\Models\User;
|
||||
use Filament\Forms;
|
||||
use Filament\Forms\Components\Grid;
|
||||
use Filament\Resources\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Resources\Table;
|
||||
use Filament\Tables;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class UserResource extends Resource
|
||||
{
|
||||
protected static ?string $model = User::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-users';
|
||||
|
||||
protected static ?string $navigationGroup = 'User';
|
||||
|
||||
protected static function getNavigationLabel(): string
|
||||
{
|
||||
return __('admin.sidebar.users_list');
|
||||
}
|
||||
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema(Forms\Components\Card::make()->schema([
|
||||
Forms\Components\TextInput::make('username')->required(),
|
||||
Forms\Components\TextInput::make('email')->required(),
|
||||
Forms\Components\TextInput::make('password')->password()->required(),
|
||||
Forms\Components\TextInput::make('password_confirmation')->password()->required()->same('password'),
|
||||
Forms\Components\TextInput::make('id')->integer(),
|
||||
Forms\Components\Select::make('class')->options(array_column(User::$classes, 'text')),
|
||||
]));
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('id')->sortable(),
|
||||
Tables\Columns\TextColumn::make('username')->searchable(),
|
||||
Tables\Columns\TextColumn::make('email')->searchable(),
|
||||
Tables\Columns\TextColumn::make('class')->label('Class')
|
||||
->formatStateUsing(fn(Tables\Columns\Column $column) => $column->getRecord()->classText)
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('uploaded')->label('Uploaded')
|
||||
->formatStateUsing(fn(Tables\Columns\Column $column) => $column->getRecord()->uploadedText)
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('downloaded')->label('Downloaded')
|
||||
->formatStateUsing(fn(Tables\Columns\Column $column) => $column->getRecord()->downloadedText)
|
||||
->sortable(),
|
||||
Tables\Columns\BadgeColumn::make('status')->colors(['success' => 'confirmed', 'warning' => 'pending']),
|
||||
Tables\Columns\BadgeColumn::make('enabled')->colors(['success' => 'yes', 'danger' => 'no']),
|
||||
Tables\Columns\TextColumn::make('added')->sortable()->dateTime('Y-m-d H:i'),
|
||||
Tables\Columns\TextColumn::make('last_access')->dateTime('Y-m-d H:i'),
|
||||
])
|
||||
->defaultSort('added', 'desc')
|
||||
->filters([
|
||||
Tables\Filters\SelectFilter::make('class')->options(array_column(User::$classes, 'text')),
|
||||
Tables\Filters\SelectFilter::make('status')->options(['confirmed' => 'confirmed', 'pending' => 'pending']),
|
||||
Tables\Filters\SelectFilter::make('enabled')->options(['enabled' => 'enabled', 'disabled' => 'disabled']),
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\ViewAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
// Tables\Actions\DeleteBulkAction::make(),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => Pages\ListUsers::route('/'),
|
||||
'create' => Pages\CreateUser::route('/create'),
|
||||
// 'edit' => Pages\EditUser::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\UserResource\Pages;
|
||||
|
||||
use App\Filament\Resources\User\UserResource;
|
||||
use App\Repositories\UserRepository;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class CreateUser extends CreateRecord
|
||||
{
|
||||
protected static string $resource = UserResource::class;
|
||||
|
||||
public function create(bool $another = false): void
|
||||
{
|
||||
$userRep = new UserRepository();
|
||||
$data = $this->form->getState();
|
||||
try {
|
||||
$this->record = $userRep->store($data);
|
||||
$this->notify(
|
||||
'success ',
|
||||
$this->getCreatedNotificationMessage(),
|
||||
);
|
||||
$this->redirect($this->getRedirectUrl());
|
||||
} catch (\Exception $exception) {
|
||||
$this->notify(
|
||||
'danger',
|
||||
$exception->getMessage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\UserResource\Pages;
|
||||
|
||||
use App\Filament\Resources\User\UserResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditUser extends EditRecord
|
||||
{
|
||||
protected static string $resource = UserResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\User\UserResource\Pages;
|
||||
|
||||
use App\Filament\PageList;
|
||||
use App\Filament\Resources\User\UserResource;
|
||||
use Filament\Pages\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ListUsers extends PageList
|
||||
{
|
||||
protected static string $resource = UserResource::class;
|
||||
|
||||
protected function getActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
// public function isTableSearchable(): bool
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use Filament\Widgets\Widget;
|
||||
|
||||
class AccountInfo extends Widget
|
||||
{
|
||||
protected static string $view = 'filament.widgets.account-info';
|
||||
|
||||
protected int | string | array $columnSpan = 'full';
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\Torrent;
|
||||
use Closure;
|
||||
use Filament\Tables;
|
||||
use Filament\Widgets\TableWidget as BaseWidget;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class LatestTorrents extends BaseWidget
|
||||
{
|
||||
protected static ?int $sort = 2;
|
||||
|
||||
protected function getTableHeading(): string | Closure | null
|
||||
{
|
||||
return __('dashboard.latest_torrent.page_title');
|
||||
}
|
||||
|
||||
protected function isTablePaginationEnabled(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return Torrent::query()->orderBy('id', 'desc')->limit(5);
|
||||
}
|
||||
|
||||
protected function getTableColumns(): array
|
||||
{
|
||||
return [
|
||||
Tables\Columns\TextColumn::make('name')->limit(40),
|
||||
Tables\Columns\TextColumn::make('user.username'),
|
||||
Tables\Columns\TextColumn::make('size')->formatStateUsing(fn ($state) => mksize($state)),
|
||||
Tables\Columns\TextColumn::make('added')->dateTime(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\User;
|
||||
use Closure;
|
||||
use Filament\Tables;
|
||||
use Filament\Widgets\TableWidget as BaseWidget;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class LatestUsers extends BaseWidget
|
||||
{
|
||||
protected static ?int $sort = 1;
|
||||
|
||||
protected function getTableHeading(): string | Closure | null
|
||||
{
|
||||
return __('dashboard.latest_user.page_title');
|
||||
}
|
||||
|
||||
protected function isTablePaginationEnabled(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getTableQuery(): Builder
|
||||
{
|
||||
return User::query()->orderBy('id', 'desc')->limit(5);
|
||||
}
|
||||
|
||||
protected function getTableColumns(): array
|
||||
{
|
||||
return [
|
||||
Tables\Columns\TextColumn::make('username'),
|
||||
Tables\Columns\TextColumn::make('email'),
|
||||
Tables\Columns\BadgeColumn::make('status')->colors(['success' => 'confirmed', 'danger' => 'pending']),
|
||||
Tables\Columns\TextColumn::make('added')->dateTime(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\Torrent;
|
||||
use Carbon\Carbon;
|
||||
use Filament\Widgets\LineChartWidget;
|
||||
use Flowframe\Trend\Trend;
|
||||
use Flowframe\Trend\TrendValue;
|
||||
|
||||
class TorrentTrend extends LineChartWidget
|
||||
{
|
||||
protected static ?int $sort = 4;
|
||||
|
||||
protected function getHeading(): ?string
|
||||
{
|
||||
return __('dashboard.torrent_trend.page_title');
|
||||
}
|
||||
|
||||
protected function getData(): array
|
||||
{
|
||||
$data = Trend::model(Torrent::class)
|
||||
->dateColumn('added')
|
||||
->between(
|
||||
start: now()->subDays(30),
|
||||
end: now(),
|
||||
)
|
||||
->perDay()
|
||||
->count();
|
||||
|
||||
return [
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => 'Torrent',
|
||||
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
|
||||
],
|
||||
],
|
||||
'labels' => $data->map(fn (TrendValue $value) => Carbon::parse($value->date)->format('m-d')),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\Torrent;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Filament\Widgets\LineChartWidget;
|
||||
use Flowframe\Trend\Trend;
|
||||
use Flowframe\Trend\TrendValue;
|
||||
|
||||
class UserTrend extends LineChartWidget
|
||||
{
|
||||
|
||||
protected static ?int $sort = 3;
|
||||
|
||||
protected function getHeading(): ?string
|
||||
{
|
||||
return __('dashboard.user_trend.page_title');
|
||||
}
|
||||
|
||||
protected function getData(): array
|
||||
{
|
||||
$data = Trend::model(User::class)
|
||||
->dateColumn('added')
|
||||
->between(
|
||||
start: now()->subDays(30),
|
||||
end: now(),
|
||||
)
|
||||
->perDay()
|
||||
->count();
|
||||
|
||||
return [
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => 'User',
|
||||
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
|
||||
],
|
||||
],
|
||||
'labels' => $data->map(fn (TrendValue $value) => Carbon::parse($value->date)->format('m-d')),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,7 @@ class Kernel extends HttpKernel
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.nexus' => \App\Http\Middleware\NexusAuth::class,
|
||||
'auth.filament' => \Filament\Http\Middleware\Authenticate::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
|
||||
@@ -12,6 +12,11 @@ class EncryptCookies extends Middleware
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
'c_secure_pass',
|
||||
'c_secure_uid',
|
||||
'c_secure_login',
|
||||
'c_secure_ssl',
|
||||
'c_secure_tracker_ssl',
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Filament\Http\Middleware\Authenticate;
|
||||
|
||||
class Filament extends Authenticate
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
protected function redirectTo($request): string
|
||||
{
|
||||
return getSchemeAndHttpHost() . '/login.php';
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Middleware;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Closure;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\App;
|
||||
@@ -26,15 +27,18 @@ class Locale
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$user = $request->user();
|
||||
$language = $user->language;
|
||||
$locale = self::$languageMaps[$language->site_lang_folder] ?? 'en';
|
||||
do_log("user: {$user->id}, language: {$language->id}, set locale: $locale");
|
||||
App::setLocale($locale);
|
||||
Carbon::setLocale($locale);
|
||||
|
||||
if ($user) {
|
||||
$language = $user->language;
|
||||
$locale = self::$languageMaps[$language->site_lang_folder] ?? 'en';
|
||||
do_log("user: {$user->id}, language: {$language->id}, set locale: $locale");
|
||||
App::setLocale($locale);
|
||||
Carbon::setLocale($locale);
|
||||
}
|
||||
/** @var Response $response */
|
||||
$response = $next($request);
|
||||
$response->header('Request-Id', nexus()->getRequestId())->header('Running-In-Octane', RUNNING_IN_OCTANE ? 1 : 0);
|
||||
if ($response instanceof Response || $response instanceof JsonResponse) {
|
||||
$response->header('Request-Id', nexus()->getRequestId())->header('Running-In-Octane', RUNNING_IN_OCTANE ? 1 : 0);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@ class ExamResource extends JsonResource
|
||||
'duration' => $this->duration ?: '',
|
||||
'duration_text' => $this->duration_text,
|
||||
'filters' => $this->normalizeFilters($this->resource),
|
||||
'filters_formatted' => $this->formatFilters($this->resource),
|
||||
'filters_formatted' => $this->filterFormatted,
|
||||
'indexes' => $this->indexes,
|
||||
'indexes_formatted' => $this->formatIndexes($this->resource),
|
||||
'indexes_formatted' => $this->indexFormatted,
|
||||
'status' => $this->status,
|
||||
'status_text' => $this->statusText,
|
||||
'is_discovered' => $this->is_discovered,
|
||||
@@ -48,50 +48,4 @@ class ExamResource extends JsonResource
|
||||
return $filters;
|
||||
}
|
||||
|
||||
private function formatFilters(Exam $exam)
|
||||
{
|
||||
$currentFilters = $exam->filters;
|
||||
$arr = [];
|
||||
$filter = Exam::FILTER_USER_CLASS;
|
||||
if (!empty($currentFilters->{$filter})) {
|
||||
$classes = collect(User::$classes)->only($currentFilters->{$filter});
|
||||
$arr[] = sprintf('%s: %s', Exam::$filters[$filter]['name'], $classes->pluck('text')->implode(', '));
|
||||
}
|
||||
|
||||
$filter = Exam::FILTER_USER_REGISTER_TIME_RANGE;
|
||||
if (!empty($currentFilters->{$filter})) {
|
||||
$range = $currentFilters->{$filter};
|
||||
$arr[] = sprintf(
|
||||
"%s: \n%s ~ %s",
|
||||
Exam::$filters[$filter]['name'],
|
||||
$range[0] ? Carbon::parse($range[0])->toDateTimeString() : '-',
|
||||
$range[1] ? Carbon::parse($range[1])->toDateTimeString() : '-'
|
||||
);
|
||||
}
|
||||
|
||||
$filter = Exam::FILTER_USER_DONATE;
|
||||
if (!empty($currentFilters->{$filter})) {
|
||||
$donateStatus = $classes = collect(User::$donateStatus)->only($currentFilters->{$filter});
|
||||
$arr[] = sprintf('%s: %s', Exam::$filters[$filter]['name'], $donateStatus->pluck('text')->implode(', '));
|
||||
}
|
||||
|
||||
return implode("\n", $arr);
|
||||
}
|
||||
|
||||
private function formatIndexes(Exam $exam)
|
||||
{
|
||||
$indexes = $exam->indexes;
|
||||
$arr = [];
|
||||
foreach ($indexes as $index) {
|
||||
if (isset($index['checked']) && $index['checked']) {
|
||||
$arr[] = sprintf(
|
||||
'%s: %s %s',
|
||||
Exam::$indexes[$index['index']]['name'] ?? '',
|
||||
$index['require_value'],
|
||||
Exam::$indexes[$index['index']]['unit'] ?? ''
|
||||
);
|
||||
}
|
||||
}
|
||||
return implode("\n", $arr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Exam extends NexusModel
|
||||
@@ -78,4 +79,51 @@ class Exam extends NexusModel
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getIndexFormattedAttribute(): string
|
||||
{
|
||||
$indexes = $this->indexes;
|
||||
$arr = [];
|
||||
foreach ($indexes as $index) {
|
||||
if (isset($index['checked']) && $index['checked']) {
|
||||
$arr[] = sprintf(
|
||||
'%s: %s %s',
|
||||
self::$indexes[$index['index']]['name'] ?? '',
|
||||
$index['require_value'],
|
||||
self::$indexes[$index['index']]['unit'] ?? ''
|
||||
);
|
||||
}
|
||||
}
|
||||
return implode("<br/>", $arr);
|
||||
}
|
||||
|
||||
public function getFilterFormattedAttribute(): string
|
||||
{
|
||||
$currentFilters = $this->filters;
|
||||
$arr = [];
|
||||
$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(', '));
|
||||
}
|
||||
|
||||
$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() : '-'
|
||||
);
|
||||
}
|
||||
|
||||
$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(', '));
|
||||
}
|
||||
|
||||
return implode("<br/>", $arr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,6 +41,21 @@ class ExamUser extends NexusModel
|
||||
return self::$isDoneInfo[$this->is_done]['text'] ?? '';
|
||||
}
|
||||
|
||||
public static function listStatus($onlyKeyValue = false): array
|
||||
{
|
||||
$result = self::$status;
|
||||
$keyValues = [];
|
||||
foreach ($result as $key => &$value) {
|
||||
$text = nexus_trans('exam-user.status.' . $key);
|
||||
$value['text'] = $text;
|
||||
$keyValues[$key] = $text;
|
||||
}
|
||||
if ($onlyKeyValue) {
|
||||
return $keyValues;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getBeginAttribute()
|
||||
{
|
||||
$begin = $this->getRawOriginal('begin');
|
||||
|
||||
@@ -55,11 +55,17 @@ class HitAndRun extends NexusModel
|
||||
return nexus_trans('hr.status_' . $this->status);
|
||||
}
|
||||
|
||||
public static function listStatus(): array
|
||||
public static function listStatus($onlyKeyValue = false): array
|
||||
{
|
||||
$result = self::$status;
|
||||
$keyValues = [];
|
||||
foreach ($result as $key => &$value) {
|
||||
$value['text'] = nexus_trans('hr.status_' . $key);
|
||||
$text = nexus_trans('hr.status_' . $key);
|
||||
$value['text'] = $text;
|
||||
$keyValues[$key] = $text;
|
||||
}
|
||||
if ($onlyKeyValue) {
|
||||
return $keyValues;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
+16
-1
@@ -10,7 +10,7 @@ class Medal extends NexusModel
|
||||
|
||||
const GET_TYPE_GRANT = 2;
|
||||
|
||||
public static $getTypeText = [
|
||||
public static array $getTypeText = [
|
||||
self::GET_TYPE_EXCHANGE => ['text' => 'Exchange'],
|
||||
self::GET_TYPE_GRANT => ['text' => 'Grant'],
|
||||
];
|
||||
@@ -19,6 +19,21 @@ class Medal extends NexusModel
|
||||
|
||||
public $timestamps = true;
|
||||
|
||||
public static function listGetTypes($onlyKeyValues = false): array
|
||||
{
|
||||
$results = self::$getTypeText;
|
||||
$keyValues = [];
|
||||
foreach ($results as $type => &$info) {
|
||||
$text = nexus_trans("medal.get_types.$type");
|
||||
$keyValues[$type] = $text;
|
||||
$info['text'] = $text;
|
||||
}
|
||||
if ($onlyKeyValues) {
|
||||
return $keyValues;
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function getGetTypeTextAttribute($value): string
|
||||
{
|
||||
return self::$getTypeText[$this->get_type]['text'] ?? '';
|
||||
|
||||
@@ -23,7 +23,7 @@ class NexusModel extends Model
|
||||
*/
|
||||
protected function serializeDate(\DateTimeInterface $date)
|
||||
{
|
||||
return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
|
||||
return $date->format($this->dateFormat ?: 'Y-m-d H:i');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+30
-2
@@ -6,6 +6,7 @@ use App\Http\Middleware\Locale;
|
||||
use App\Repositories\ExamRepository;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
@@ -13,8 +14,10 @@ use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
use Nexus\Database\NexusDB;
|
||||
use Filament\Models\Contracts\FilamentUser;
|
||||
use Filament\Models\Contracts\HasName;
|
||||
|
||||
class User extends Authenticatable
|
||||
class User extends Authenticatable implements FilamentUser, HasName
|
||||
{
|
||||
use HasFactory, Notifiable, HasApiTokens;
|
||||
|
||||
@@ -99,6 +102,17 @@ class User extends Authenticatable
|
||||
return $classText;
|
||||
}
|
||||
|
||||
public function canAccessFilament(): bool
|
||||
{
|
||||
return true;
|
||||
// return str_ends_with($this->email, '@yourdomain.com') && $this->hasVerifiedEmail();
|
||||
}
|
||||
|
||||
public function getFilamentName(): string
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ExamRepository::isExamMatchUser()
|
||||
*
|
||||
@@ -120,7 +134,7 @@ class User extends Authenticatable
|
||||
*/
|
||||
protected function serializeDate(\DateTimeInterface $date): string
|
||||
{
|
||||
return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
|
||||
return $date->format($this->dateFormat ?: 'Y-m-d H:i');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -244,6 +258,20 @@ class User extends Authenticatable
|
||||
return 'en';
|
||||
}
|
||||
|
||||
protected function uploadedText(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn($value, $attributes) => mksize($attributes['uploaded'])
|
||||
);
|
||||
}
|
||||
|
||||
protected function downloadedText(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: fn($value, $attributes) => mksize($attributes['downloaded'])
|
||||
);
|
||||
}
|
||||
|
||||
public static function getMinSeedPoints($class)
|
||||
{
|
||||
$setting = Setting::get("account.{$class}_min_seed_points");
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Nexus\Nexus;
|
||||
use Filament\Facades\Filament;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -30,5 +32,13 @@ class AppServiceProvider extends ServiceProvider
|
||||
// JsonResource::withoutWrapping();
|
||||
DB::connection(config('database.default'))->enableQueryLog();
|
||||
|
||||
Filament::serving(function () {
|
||||
Filament::registerNavigationGroups([
|
||||
'User',
|
||||
'Torrent',
|
||||
'System',
|
||||
]);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Auth\NexusWebGuard;
|
||||
use App\Auth\NexusWebUserProvider;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -31,6 +33,11 @@ class AuthServiceProvider extends ServiceProvider
|
||||
Auth::viaRequest('nexus-cookie', function (Request $request) {
|
||||
return $this->getUserByCookie($request->cookie());
|
||||
});
|
||||
|
||||
Auth::extend('nexus-web', function ($app, $name, array $config) {
|
||||
// 返回 Illuminate\Contracts\Auth\Guard 的实例 ...
|
||||
return new NexusWebGuard($app->make('request'), new NexusWebUserProvider());
|
||||
});
|
||||
}
|
||||
|
||||
private function getUserByCookie($cookie)
|
||||
|
||||
@@ -115,7 +115,7 @@ class UserRepository extends BaseRepository
|
||||
'class' => $class
|
||||
];
|
||||
$user = new User($data);
|
||||
if ($params['id']) {
|
||||
if (!empty($params['id'])) {
|
||||
if (User::query()->where('id', $params['id'])->exists()) {
|
||||
throw new \InvalidArgumentException("uid: {$params['id']} already exists.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user