- 安裝並設定 stancl/tenancy 套件 - 分離 Central / Tenant migrations - 建立 Tenant Model 與資料遷移指令 - 建立房東後台 CRUD (Landlord Dashboard) - 新增租戶管理頁面 (列表、新增、編輯、詳情) - 新增域名管理功能 - 更新部署手冊
173 lines
4.8 KiB
PHP
173 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Landlord;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Tenant;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Validation\Rule;
|
|
use Inertia\Inertia;
|
|
|
|
class TenantController extends Controller
|
|
{
|
|
/**
|
|
* 顯示租戶列表
|
|
*/
|
|
public function index()
|
|
{
|
|
$tenants = Tenant::with('domains')->get()->map(function ($tenant) {
|
|
return [
|
|
'id' => $tenant->id,
|
|
'name' => $tenant->name ?? $tenant->id,
|
|
'email' => $tenant->email ?? null,
|
|
'is_active' => $tenant->is_active ?? true,
|
|
'created_at' => $tenant->created_at->format('Y-m-d H:i'),
|
|
'domains' => $tenant->domains->pluck('domain')->toArray(),
|
|
];
|
|
});
|
|
|
|
return Inertia::render('Landlord/Tenant/Index', [
|
|
'tenants' => $tenants,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 顯示新增租戶表單
|
|
*/
|
|
public function create()
|
|
{
|
|
return Inertia::render('Landlord/Tenant/Create');
|
|
}
|
|
|
|
/**
|
|
* 儲存新租戶
|
|
*/
|
|
public function store(Request $request)
|
|
{
|
|
$validated = $request->validate([
|
|
'id' => ['required', 'string', 'max:50', 'alpha_dash', Rule::unique('tenants', 'id')],
|
|
'name' => ['required', 'string', 'max:100'],
|
|
'email' => ['nullable', 'email', 'max:100'],
|
|
'domain' => ['nullable', 'string', 'max:100'],
|
|
]);
|
|
|
|
$tenant = Tenant::create([
|
|
'id' => $validated['id'],
|
|
'name' => $validated['name'],
|
|
'email' => $validated['email'] ?? null,
|
|
'is_active' => true,
|
|
]);
|
|
|
|
// 如果有指定域名,則綁定
|
|
if (!empty($validated['domain'])) {
|
|
$tenant->domains()->create(['domain' => $validated['domain']]);
|
|
}
|
|
|
|
return redirect()->route('landlord.tenants.index')
|
|
->with('success', "租戶 {$validated['name']} 建立成功!");
|
|
}
|
|
|
|
/**
|
|
* 顯示單一租戶詳情
|
|
*/
|
|
public function show(string $id)
|
|
{
|
|
$tenant = Tenant::with('domains')->findOrFail($id);
|
|
|
|
return Inertia::render('Landlord/Tenant/Show', [
|
|
'tenant' => [
|
|
'id' => $tenant->id,
|
|
'name' => $tenant->name ?? $tenant->id,
|
|
'email' => $tenant->email ?? null,
|
|
'is_active' => $tenant->is_active ?? true,
|
|
'created_at' => $tenant->created_at->format('Y-m-d H:i'),
|
|
'updated_at' => $tenant->updated_at->format('Y-m-d H:i'),
|
|
'domains' => $tenant->domains->map(fn($d) => [
|
|
'id' => $d->id,
|
|
'domain' => $d->domain,
|
|
])->toArray(),
|
|
],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 顯示編輯租戶表單
|
|
*/
|
|
public function edit(string $id)
|
|
{
|
|
$tenant = Tenant::findOrFail($id);
|
|
|
|
return Inertia::render('Landlord/Tenant/Edit', [
|
|
'tenant' => [
|
|
'id' => $tenant->id,
|
|
'name' => $tenant->name ?? $tenant->id,
|
|
'email' => $tenant->email ?? null,
|
|
'is_active' => $tenant->is_active ?? true,
|
|
],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 更新租戶
|
|
*/
|
|
public function update(Request $request, string $id)
|
|
{
|
|
$tenant = Tenant::findOrFail($id);
|
|
|
|
$validated = $request->validate([
|
|
'name' => ['required', 'string', 'max:100'],
|
|
'email' => ['nullable', 'email', 'max:100'],
|
|
'is_active' => ['boolean'],
|
|
]);
|
|
|
|
$tenant->update($validated);
|
|
|
|
return redirect()->route('landlord.tenants.index')
|
|
->with('success', "租戶 {$validated['name']} 更新成功!");
|
|
}
|
|
|
|
/**
|
|
* 刪除租戶
|
|
*/
|
|
public function destroy(string $id)
|
|
{
|
|
$tenant = Tenant::findOrFail($id);
|
|
$name = $tenant->name ?? $id;
|
|
|
|
$tenant->delete();
|
|
|
|
return redirect()->route('landlord.tenants.index')
|
|
->with('success', "租戶 {$name} 已刪除!");
|
|
}
|
|
|
|
/**
|
|
* 新增域名到租戶
|
|
*/
|
|
public function addDomain(Request $request, string $id)
|
|
{
|
|
$tenant = Tenant::findOrFail($id);
|
|
|
|
$validated = $request->validate([
|
|
'domain' => ['required', 'string', 'max:100', Rule::unique('domains', 'domain')],
|
|
]);
|
|
|
|
$tenant->domains()->create(['domain' => $validated['domain']]);
|
|
|
|
return back()->with('success', "域名 {$validated['domain']} 已綁定!");
|
|
}
|
|
|
|
/**
|
|
* 移除租戶的域名
|
|
*/
|
|
public function removeDomain(string $id, int $domainId)
|
|
{
|
|
$tenant = Tenant::findOrFail($id);
|
|
$domain = $tenant->domains()->findOrFail($domainId);
|
|
$domainName = $domain->domain;
|
|
|
|
$domain->delete();
|
|
|
|
return back()->with('success', "域名 {$domainName} 已移除!");
|
|
}
|
|
}
|