[admin] add username change log

This commit is contained in:
xiaomlove
2022-08-10 23:38:10 +08:00
parent c074b1e1ed
commit b539eff587
16 changed files with 204 additions and 17 deletions

View File

@@ -86,9 +86,7 @@ class Test extends Command
*/
public function handle()
{
$a = Carbon::parse('2022-08-06 23:08:03');
$b = $a->clone()->addHours(1);
dd($a, $b);
}

View File

@@ -0,0 +1,77 @@
<?php
namespace App\Filament\Resources\System;
use App\Filament\Resources\System\UsernameChangeLogResource\Pages;
use App\Filament\Resources\System\UsernameChangeLogResource\RelationManagers;
use App\Models\UsernameChangeLog;
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 UsernameChangeLogResource extends Resource
{
protected static ?string $model = UsernameChangeLog::class;
protected static ?string $navigationIcon = 'heroicon-o-pencil-alt';
protected static ?string $navigationGroup = 'User';
protected static ?int $navigationSort = 8;
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.username_change_log');
}
public static function getBreadcrumb(): string
{
return self::getNavigationLabel();
}
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')->sortable(),
Tables\Columns\TextColumn::make('changeTypeText')->label(__('username-change-log.labels.change_type')),
Tables\Columns\TextColumn::make('uid')->searchable(),
Tables\Columns\TextColumn::make('user.username')->searchable()->label(__('label.username')),
Tables\Columns\TextColumn::make('username_old')->searchable()->label(__('username-change-log.labels.username_old')),
Tables\Columns\TextColumn::make('username_new')->searchable()->label(__('username-change-log.labels.username_new')),
Tables\Columns\TextColumn::make('operator')->searchable()->label(__('label.operator')),
Tables\Columns\TextColumn::make('created_at')->label(__('label.created_at'))->formatStateUsing(fn ($state) => format_datetime($state)),
])
->defaultSort('id', 'desc')
->filters([
Tables\Filters\SelectFilter::make('change_type')->options(UsernameChangeLog::listChangeType())->label(__('username-change-log.labels.change_type')),
])
->actions([
// Tables\Actions\EditAction::make(),
// Tables\Actions\DeleteAction::make(),
])
->bulkActions([
// Tables\Actions\DeleteBulkAction::make(),
]);
}
public static function getPages(): array
{
return [
'index' => Pages\ManageUsernameChangeLogs::route('/'),
];
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Filament\Resources\System\UsernameChangeLogResource\Pages;
use App\Filament\Resources\System\UsernameChangeLogResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ManageRecords;
class ManageUsernameChangeLogs extends ManageRecords
{
protected ?string $maxContentWidth = 'full';
protected static string $resource = UsernameChangeLogResource::class;
protected function getActions(): array
{
return [
// Actions\CreateAction::make(),
];
}
}

View File

@@ -4,13 +4,35 @@ namespace App\Models;
class UsernameChangeLog extends NexusModel
{
protected $fillable = ['uid', 'username_old', 'username_new', ];
protected $fillable = ['uid', 'username_old', 'username_new', 'operator', 'change_type'];
public $timestamps = true;
const CHANGE_TYPE_USER = 1;
const CHANGE_TYPE_ADMIN = 2;
public static array $changeTypes = [
self::CHANGE_TYPE_USER => ['text' => 'User'],
self::CHANGE_TYPE_ADMIN => ['text' => 'Administrator'],
];
public function getChangeTypeTextAttribute()
{
return nexus_trans('username-change-log.change_type.' . $this->change_type);
}
public function user()
{
return $this->belongsTo(User::class, 'uid');
}
public static function listChangeType()
{
$result = [];
foreach (self::$changeTypes as $type => $info) {
$result[$type] = nexus_trans('username-change-log.change_type.' . $type);
}
return $result;
}
}

View File

@@ -11,6 +11,7 @@ use App\Models\Setting;
use App\Models\User;
use App\Models\UserBanLog;
use App\Models\UserMeta;
use App\Models\UsernameChangeLog;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
@@ -359,6 +360,9 @@ class UserRepository extends BaseRepository
private function checkPermission($operator, User $user, $minAuthClass = 'authority.prfmanage')
{
$operator = $this->getUser($operator);
if ($operator->id == $user->id) {
return;
}
$classRequire = Setting::get($minAuthClass);
if ($operator->class < $classRequire || $operator->class <= $user->class) {
throw new InsufficientPermissionException();
@@ -396,7 +400,7 @@ class UserRepository extends BaseRepository
$user = User::query()->findOrFail($uid, User::$commonFields);
if ($metaKey == UserMeta::META_KEY_CHANGE_USERNAME) {
NexusDB::transaction(function () use ($user, $meta, $params) {
$this->changeUsername($user, $params['username']);
$this->changeUsername($user, UsernameChangeLog::CHANGE_TYPE_USER, $user, $params['username']);
$meta->delete();
clear_user_cache($user->id, $user->passkey);
});
@@ -406,22 +410,32 @@ class UserRepository extends BaseRepository
throw new \InvalidArgumentException("Invalid meta_key: $metaKey");
}
private function changeUsername(User $user, $newUsername): bool
private function changeUsername($operator, $changeType, $targetUser, $newUsername): bool
{
if ($user->username == $newUsername) {
$operator = $this->getUser($operator);
$targetUser = $this->getUser($targetUser);
$this->checkPermission($operator, $targetUser);
if ($targetUser->username == $newUsername) {
throw new \RuntimeException("New username can not be the same with current username !");
}
if (!validusername($newUsername)) {
throw new \InvalidArgumentException("Invalid username, length must between 4 and 20 characters");
$strWidth = mb_strwidth($newUsername);
if ($strWidth < 4 || $strWidth > 20) {
throw new \InvalidArgumentException("Invalid username, maybe too long or too short");
}
if (User::query()->where('username', $newUsername)->where('id', '!=', $user->id)->exists()) {
if (User::query()->where('username', $newUsername)->where('id', '!=', $targetUser->id)->exists()) {
throw new \RuntimeException("Username: $newUsername already exists !");
}
NexusDB::transaction(function () use ($user, $newUsername) {
$oldUsername = $user->username;
$user->usernameChangeLogs()->create(['username_old' => $oldUsername, 'username_new' => $newUsername]);
$user->username = $newUsername;
$user->save();
$changeLog = [
'uid' => $targetUser->id,
'operator' => $operator->username,
'change_type' => $changeType,
'username_old' => $targetUser->username,
'username_new' => $newUsername
];
NexusDB::transaction(function () use ($operator, $changeType,$targetUser, $changeLog) {
$targetUser->usernameChangeLogs()->create($changeLog);
$targetUser->username = $changeLog['username_new'];
$targetUser->save();
});
return true;
}