2026-01-15 13:15:18 +08:00
|
|
|
<?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,
|
|
|
|
|
]);
|
|
|
|
|
|
2026-01-15 16:55:24 +08:00
|
|
|
// 綁定網域(如果沒有輸入,使用預設網域)
|
|
|
|
|
$defaultDomain = env('TENANT_DEFAULT_DOMAIN', 'star-erp.test');
|
|
|
|
|
$domain = !empty($validated['domain'])
|
|
|
|
|
? $validated['domain']
|
|
|
|
|
: $validated['id'] . '.' . $defaultDomain;
|
|
|
|
|
$tenant->domains()->create(['domain' => $domain]);
|
2026-01-15 13:15:18 +08:00
|
|
|
|
|
|
|
|
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} 已移除!");
|
|
|
|
|
}
|
|
|
|
|
}
|