feat(初始化安装): 新增初始化安装的脚本,一键迁移数据库,初始化基础数据,添加默认管理员账号
This commit is contained in:
parent
fa966ab489
commit
10a9ae4553
87
app/Console/Commands/InstallApplicationCommand.php
Normal file
87
app/Console/Commands/InstallApplicationCommand.php
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class InstallApplicationCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'app:install
|
||||||
|
{--fresh : Drop all tables and re-run all migrations}
|
||||||
|
{--force : Force install commands in production}
|
||||||
|
{--admin-email=admin@example.com : Super admin email}
|
||||||
|
{--admin-phone=admin : Super admin phone}
|
||||||
|
{--admin-nickname=admin : Super admin nickname}
|
||||||
|
{--admin-password=admin : Super admin password}';
|
||||||
|
|
||||||
|
protected $description = 'Install app with migration, default RBAC data, and super admin account';
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$this->components->info('Starting application installation...');
|
||||||
|
|
||||||
|
$migrationExitCode = $this->call(
|
||||||
|
$this->option('fresh') ? 'migrate:fresh' : 'migrate',
|
||||||
|
['--force' => (bool) $this->option('force')]
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($migrationExitCode !== self::SUCCESS) {
|
||||||
|
$this->error('Database migration failed.');
|
||||||
|
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rbacExitCode = $this->call('user:manage', [
|
||||||
|
'action' => 'init-rbac',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($rbacExitCode !== self::SUCCESS) {
|
||||||
|
$this->error('Default RBAC initialization failed.');
|
||||||
|
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$adminEmail = trim((string) $this->option('admin-email'));
|
||||||
|
$adminPhone = trim((string) $this->option('admin-phone'));
|
||||||
|
$adminNickname = trim((string) $this->option('admin-nickname'));
|
||||||
|
$adminPassword = (string) $this->option('admin-password');
|
||||||
|
|
||||||
|
if ($adminEmail === '' || $adminNickname === '' || $adminPassword === '') {
|
||||||
|
$this->error('admin-email, admin-nickname and admin-password are required.');
|
||||||
|
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$adminUser = User::query()->updateOrCreate(
|
||||||
|
['email' => $adminEmail],
|
||||||
|
[
|
||||||
|
'nickname' => $adminNickname,
|
||||||
|
'phone' => $adminPhone !== '' ? $adminPhone : null,
|
||||||
|
'password' => $adminPassword,
|
||||||
|
'force_password_change' => false,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$setAdminExitCode = $this->call('user:manage', [
|
||||||
|
'action' => 'set-admin',
|
||||||
|
'--email' => $adminUser->email,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($setAdminExitCode !== self::SUCCESS) {
|
||||||
|
$this->error('Failed to set admin role and permissions.');
|
||||||
|
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->newLine();
|
||||||
|
$this->components->info('Application installed successfully.');
|
||||||
|
$this->line("Admin email: {$adminUser->email}");
|
||||||
|
if ($adminUser->phone) {
|
||||||
|
$this->line("Admin phone: {$adminUser->phone}");
|
||||||
|
}
|
||||||
|
$this->line("Admin password: {$adminPassword}");
|
||||||
|
|
||||||
|
return self::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
46
tests/Feature/InstallApplicationCommandTest.php
Normal file
46
tests/Feature/InstallApplicationCommandTest.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Spatie\Permission\Models\Permission;
|
||||||
|
use Spatie\Permission\Models\Role;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class InstallApplicationCommandTest extends TestCase
|
||||||
|
{
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
public function test_install_command_bootstraps_default_rbac_and_admin_user(): void
|
||||||
|
{
|
||||||
|
$this->artisan('app:install')
|
||||||
|
->assertExitCode(0);
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('permissions', [
|
||||||
|
'name' => 'platform.users.manage',
|
||||||
|
'guard_name' => 'api',
|
||||||
|
]);
|
||||||
|
$this->assertDatabaseHas('roles', [
|
||||||
|
'name' => 'admin',
|
||||||
|
'guard_name' => 'api',
|
||||||
|
]);
|
||||||
|
$this->assertDatabaseHas('users', [
|
||||||
|
'email' => 'admin@example.com',
|
||||||
|
'nickname' => 'admin',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$adminUser = User::query()->where('email', 'admin@example.com')->first();
|
||||||
|
$this->assertNotNull($adminUser);
|
||||||
|
$this->assertTrue(Hash::check('admin', (string) $adminUser->password));
|
||||||
|
$this->assertTrue($adminUser->hasRole('admin', 'api'));
|
||||||
|
|
||||||
|
$adminRole = Role::query()->where('name', 'admin')->where('guard_name', 'api')->first();
|
||||||
|
$this->assertNotNull($adminRole);
|
||||||
|
$this->assertSame(
|
||||||
|
Permission::query()->where('guard_name', 'api')->count(),
|
||||||
|
$adminRole->permissions()->count()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user