peterguo 2 месяцев назад
Родитель
Сommit
b154b81d67

+ 45 - 34
app/Admin/Controllers/DomainController.php

@@ -5,10 +5,14 @@ namespace App\Admin\Controllers;
 use Encore\Admin\Controllers\AdminController;
 use Encore\Admin\Form;
 use Encore\Admin\Grid;
+use Encore\Admin\Show;
+use Encore\Admin\Widgets\Table;
 use Stancl\Tenancy\Database\Models\Domain;
 
 class DomainController extends AdminController
 {
+    protected $title = 'Domains';
+
     /**
      * Make a grid builder.
      *
@@ -16,24 +20,28 @@ class DomainController extends AdminController
      */
     protected function grid()
     {
-        return Grid::make(new Domain('tenant'), function (Grid $grid) {
-            $grid->model()->orderByDesc('id');
-
-            $grid->column('id')->sortable();
-            $grid->column('domain')->copyable();
-            $grid->column('tenant.name', '关联租户');
-            $grid->column('created_at');
-            $grid->column('updated_at')->sortable();
-
-            $grid->disableCreateButton();
-            $grid->disableEditButton();
-
-            $grid->filter(function (Grid\Filter $filter) {
-                $filter->equal('id');
-                $filter->like('domain');
-                $filter->equal('tenant_id', '关联租户')->select(Tenant::pluck('name', 'id'));
+        $grid = new Grid(new Domain(['tenant']));
+        $grid->model()->orderByDesc('id');
+        $grid->column('id')->sortable();
+        $grid->column('domain')->editable()->copyable();
+        $grid->column('tenant.name')->expand(function ($model) {
+            $tenants = $model->tenant()->take(10)->get()->map(function ($tenant) {
+                return $tenant->only(['id', 'name', 'tenancy_db_connection', 'expired_at']);
             });
+            return new Table(['ID', 'Name', 'Db_connection', 'expired_at'], $tenants->toArray());
         });
+        $grid->column('created_at');
+        $grid->column('updated_at')->sortable();
+        $grid->actions(function (Grid\Displayers\Actions $actions) {
+            $actions->disableEdit();
+            $actions->disableDelete();
+        });
+
+        $grid->filter(function (Grid\Filter $filter) {
+            $filter->like('domain');
+        });
+
+        return $grid;
     }
 
     /**
@@ -45,27 +53,30 @@ class DomainController extends AdminController
      */
     protected function detail($id)
     {
-        return Show::make($id, new Domain('tenant'), function (Show $show) {
-            $show->field('id');
-            $show->field('domain');
-            $show->field('tenant.name', '关联租户');
-            $show->field('created_at');
-            $show->field('updated_at');
+        $show = new Show(Domain::query()->findOrFail($id));
 
-            $show->disableEditButton();
+        $show->field('id');
+        $show->field('domain');
+        $show->field('created_at');
+        $show->field('updated_at');
+        $show->panel()->tools(function ($tools) {
+            $tools->disableDelete();
         });
-    }
-
-    /**
-     * Make a form builder.
-     *
-     * @return Form
-     */
-    protected function form()
-    {
-        // 保留这个方法,否则删除功能失效.
-        return Form::make(new Domain(), function (Form $form) {
 
+        $show->tenant('tenant', function ($tenant) {
+            $tenant->id();
+            $tenant->name();
+            $tenant->tenancy_db_connection();
+            $tenant->expired_at();
+            $tenant->created_at();
+            $tenant->updated_at();
+            $tenant->panel()->tools(function ($tools) {
+                $tools->disableList();
+                $tools->disableEdit();
+                $tools->disableDelete();
+            });
         });
+
+        return $show;
     }
 }

+ 100 - 0
app/Admin/Controllers/GlobalUserController.php

@@ -0,0 +1,100 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+
+use App\Models\GlobalUser;
+use App\Models\Tenant;
+use Encore\Admin\Controllers\AdminController;
+use Encore\Admin\Form;
+use Encore\Admin\Grid;
+use Encore\Admin\Show;
+use Encore\Admin\Widgets\Table;
+
+class GlobalUserController extends AdminController
+{
+    protected $title = '全局用户';
+    protected $description = '';
+
+    /**
+     * Make a grid builder.
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+        $grid = new Grid(new GlobalUser(['tenant']));
+
+        $grid->model()->orderByDesc('created_at');
+
+        $grid->column('id');
+        $grid->column('username')->copyable();
+        $grid->column('tenant.name')->expand(function ($model) {
+            $tenants = $model->tenant()->get()->map(function ($tenant) {
+                return $tenant->only(['id', 'name', 'tenancy_db_connection', 'expired_at']);
+            });
+            return new Table(['ID', 'Name', 'Db_connection', 'expired_at'], $tenants->toArray());
+        });
+        $grid->column('created_at')->datetime();
+        $grid->column('updated_at')->datetime();
+        $grid->actions(function (Grid\Displayers\Actions $actions) {
+            $actions->disableDelete();
+        });
+
+        $grid->filter(function (Grid\Filter $filter) {
+            $filter->like('username');
+            $filter->equal('tenant_id')->select(Tenant::query()->pluck('name', 'id'));
+        });
+
+        return $grid;
+    }
+
+    /**
+     * Make a show builder.
+     *
+     * @param  mixed  $id
+     *
+     * @return Show
+     */
+    protected function detail($id)
+    {
+        $show = new Show(GlobalUser::query()->findOrFail($id));
+        $show->field('id');
+        $show->field('username');
+        $show->field('created_at');
+        $show->field('updated_at');
+
+        $show->tenant('tenant', function ($tenant) {
+            $tenant->id();
+            $tenant->name();
+            $tenant->tenancy_db_connection();
+            $tenant->expired_at();
+            $tenant->panel()->tools(function ($tools) {
+                $tools->disableList();
+                $tools->disableEdit();
+                $tools->disableDelete();
+            });
+        });
+
+        return $show;
+    }
+
+    /**
+     * Make a form builder.
+     *
+     * @return Form
+     */
+    protected function form()
+    {
+        $form = new Form(new GlobalUser());
+        $form->text('username')->placeholder('unique email or mobile')->rules(function ($form) {
+            return 'required|unique:global_users,username,' . $form->model()->id;
+        })->required();
+        $form->select('tenant_id', 'Tenant')
+            ->options(function () {
+                return Tenant::all()->pluck('name', 'id')->toArray();
+            })
+            ->required();
+        return $form;
+    }
+}

+ 25 - 8
app/Admin/Controllers/TenantController.php

@@ -27,6 +27,7 @@ class TenantController extends AdminController
 
         $grid->column('id')->copyable();
         $grid->column('name');
+        $grid->column('tenancy_db_connection', 'tenancy_db_connection');
         $grid->column('domains')->display(function ($domains) {
             if (count($domains) == 0) {
                 return '-';
@@ -37,12 +38,14 @@ class TenantController extends AdminController
             }
             return $domainString;
         });
-        $grid->column('expired_at');
-        $grid->column('created_at');
-        $grid->column('updated_at')->sortable();
+        $grid->column('expired_at')->datetime();
+        $grid->column('created_at')->datetime();
+        $grid->column('updated_at')->datetime();
+        $grid->actions(function (Grid\Displayers\Actions $actions) {
+            $actions->disableDelete();
+        });
 
         $grid->filter(function (Grid\Filter $filter) {
-            $filter->equal('id');
             $filter->like('name');
         });
 
@@ -61,6 +64,7 @@ class TenantController extends AdminController
         $show = new Show(Tenant::query()->findOrFail($id));
         $show->field('id');
         $show->field('name');
+        $show->field('tenancy_db_connection');
         $show->field('expired_at');
         $show->field('created_at');
         $show->field('updated_at');
@@ -72,6 +76,13 @@ class TenantController extends AdminController
             $domain->updated_at();
         });
 
+        $show->users('users', function ($user) {
+            $user->id();
+            $user->username();
+            $user->created_at();
+            $user->updated_at();
+        });
+
         return $show;
     }
 
@@ -82,17 +93,23 @@ class TenantController extends AdminController
      */
     protected function form()
     {
+        $databaseConfig = config('database.connections');
+        $databaseConnections = [];
+        foreach ($databaseConfig as $key => $item) {
+            $databaseConnections[$key] = $key;
+        }
         $form = new Form(new Tenant(['domains']));
-        $form->tab('基本信息', function (Form $form) {
-            $form->text('id')->readonly();
+        $form->tab('基本信息', function (Form $form) use ($databaseConnections) {
+            $form->text('id')->rules('required');
             $form->text('name');
+            $form->radio('tenancy_db_connection')
+                ->options($databaseConnections)->default('mysql');;
             $form->datetime('expired_at');
         })->tab('域名', function (Form $form) {
-            $form->hasMany('domains', function (Form\NestedForm $form) {
+            $form->hasMany('domains', 'domains', function (Form\NestedForm $form) {
                 $form->text('domain');
             });
         });
-
         return $form;
     }
 }

+ 2 - 1
app/Admin/routes.php

@@ -15,5 +15,6 @@ Route::group([
     $router->resource('/tenant', 'TenantController');
     // 域名管理
     $router->resource('/domain', 'DomainController')->only(['index', 'destroy', 'show']);
-
+    // 用户管理
+    $router->resource('/globalUser', 'GlobalUserController');
 });

+ 0 - 65
app/Console/Commands/CreateTenant.php

@@ -1,65 +0,0 @@
-<?php
-
-namespace App\Console\Commands;
-
-use App\Models\Tenant;
-use Illuminate\Console\Command;
-
-/**
- */
-class CreateTenant extends Command
-{
-    /**
-     * The name and signature of the console command.
-     * use php artisan create-tenant {tenantCode} {--db-connection=} {--db-name=}
-     * eg: php artisan create-tenant test --db-connection=central --db-name=tenant_test
-     * @var string
-     */
-    protected $signature = 'create-tenant {tenantCode} {--db-connection=} {--db-name=}';
-
-    /**
-     * The console command description.
-     *
-     * @var string
-     */
-    protected $description = 'create-tenant';
-
-    /**
-     * Execute the console command.
-     */
-    public function handle()
-    {
-        $tenantCode = $this->argument('tenantCode');
-        if (Tenant::query()->where('id', $tenantCode)->exists()) {
-            $this->error("tenant $tenantCode already exists");
-            return;
-        }
-
-        $this->info("creating tenant $tenantCode");
-        $tenant = [
-            'id' => $tenantCode
-        ];
-        // 默认值为 tenancy.database.template_tenant_connection配置
-        $tenant['tenancy_db_connection'] = config('tenancy.database.template_tenant_connection');
-
-        if (!empty($this->option('db-connection'))) {
-            $tenant['tenancy_db_connection'] = $this->option('db-connection');
-        }
-
-        $tenant['tenancy_db_username'] = config("database.connections.{$tenant['tenancy_db_connection']}.username");
-        $tenant['tenancy_db_password'] = config("database.connections.{$tenant['tenancy_db_connection']}.password");
-
-        // 默认值为 tenancy.database.prefix配置 + 租户 ID +tenancy.database.suffix配置
-        if (!empty($this->option('db-name'))) {
-            $tenant['tenancy_db_name'] = $this->option('db-name');
-        }
-
-        try {
-            Tenant::create($tenant);
-            $this->info("create tenant $tenantCode success");
-            $this->info("database info: " . json_encode($tenant, 256));
-        } catch (\Exception $e) {
-            $this->error("create tenant $tenantCode fail:" . $e->getMessage());
-        }
-    }
-}

+ 14 - 1
app/Models/GlobalUser.php

@@ -9,9 +9,22 @@ use Stancl\Tenancy\Database\Concerns;
 class GlobalUser extends Model implements Contracts\Domain
 {
     use Concerns\CentralConnection;
+    use HasFactory;
+
+    protected $guarded = [
+        'id'
+    ];
+    protected $fillable = [
+        'username',
+        'tenant_id'
+    ];
+    protected $casts = [
+        'created_at' => 'datetime:Y-m-d H:i:s',
+        'updated_at' => 'datetime:Y-m-d H:i:s',
+    ];
+
 
     protected $table = 'global_users';
-    use HasFactory;
 
     public function tenant()
     {

+ 7 - 4
app/Models/Tenant.php

@@ -2,6 +2,7 @@
 
 namespace App\Models;
 
+use Illuminate\Database\Eloquent\Relations\HasMany;
 use Stancl\Tenancy\Database\Concerns\HasDatabase;
 use Stancl\Tenancy\Database\Concerns\HasDomains;
 use Stancl\Tenancy\Database\Models\Tenant as BaseTenant;
@@ -15,17 +16,19 @@ class Tenant extends BaseTenant implements TenantWithDatabase
 {
     use HasDatabase, HasDomains;
 
+    public function users(): HasMany
+    {
+        return $this->hasMany(GlobalUser::class, 'tenant_id');
+    }
+
     protected $casts = [
-//        'tenancy_db_username' => 'encrypted',
-//        'tenancy_db_password' => 'encrypted',
     ];
 
     public static function getCustomColumns(): array
     {
         return [
             'id',
-//            'tenancy_db_username' => 'encrypted',
-//            'tenancy_db_password' => 'encrypted',
+            'expired_at'
         ];
     }
 }

+ 1 - 1
config/admin.php

@@ -289,7 +289,7 @@ return [
     | "sidebar-mini".
     |
     */
-    'layout' => ['sidebar-mini', 'sidebar-collapse'],
+    'layout' => ['fixed', "layout-boxed"],
 
     /*
     |--------------------------------------------------------------------------

+ 32 - 0
database/migrations/2025_01_07_114133_add_columns_to_tenants_table.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('tenants', function (Blueprint $table) {
+            //
+            $table->string('name');
+            $table->timestamp('expired_at')->nullable();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('tenants', function (Blueprint $table) {
+            //
+            $table->dropColumn('name');
+            $table->dropColumn('expired_at');
+        });
+    }
+};