get()->map(function ($tenant) { return [ 'id' => $tenant->id, 'name' => $tenant->name ?? $tenant->id, 'short_name' => $tenant->short_name ?? null, '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'], 'short_name' => ['nullable', 'string', 'max:50'], 'email' => ['nullable', 'email', 'max:100'], 'domain' => ['nullable', 'string', 'max:100'], ]); $tenant = Tenant::create([ 'id' => $validated['id'], 'name' => $validated['name'], 'short_name' => $validated['short_name'] ?? null, 'email' => $validated['email'] ?? null, 'is_active' => true, 'branding' => [ 'logo_path' => 'defaults/logo.png', // 預設 Logo 路徑 'login_background_path' => 'defaults/login_bg.jpg', // 預設登入背景 'primary_color' => '#4F46E5', // 預設主色系 (Indigo-600) ], ]); // 綁定網域(如果沒有輸入,使用預設網域) $defaultDomain = env('TENANT_DEFAULT_DOMAIN', 'star-erp.test'); $domain = !empty($validated['domain']) ? $validated['domain'] : $validated['id'] . '.' . $defaultDomain; $tenant->domains()->create(['domain' => $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, 'short_name' => $tenant->short_name ?? null, '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 showBranding(Tenant $tenant) { $logoUrl = null; if (isset($tenant->branding['logo_path'])) { $logoUrl = \Storage::url($tenant->branding['logo_path']); } return Inertia::render('Landlord/Tenant/Branding', [ 'tenant' => [ 'id' => $tenant->id, 'name' => $tenant->name ?? $tenant->id, 'branding' => $tenant->branding ?? [], ], 'logo_url' => $logoUrl, ]); } /** * 顯示編輯租戶表單 */ public function edit(string $id) { $tenant = Tenant::findOrFail($id); return Inertia::render('Landlord/Tenant/Edit', [ 'tenant' => [ 'id' => $tenant->id, 'name' => $tenant->name ?? $tenant->id, 'short_name' => $tenant->short_name ?? null, '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'], 'short_name' => ['nullable', 'string', 'max:50'], '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} 已移除!"); } /** * 更新租戶品牌樣式設定 */ public function updateBranding(Request $request, Tenant $tenant) { $validated = $request->validate([ 'logo' => 'nullable|image|max:2048', 'primary_color' => 'required|regex:/^#[0-9A-Fa-f]{6}$/', 'text_color' => 'nullable|regex:/^#[0-9A-Fa-f]{6}$/', ]); $branding = $tenant->branding ?? []; // 處理 Logo 上傳 if ($request->hasFile('logo')) { // 刪除舊 Logo if (isset($branding['logo_path'])) { \Storage::disk('public')->delete($branding['logo_path']); } // 儲存新 Logo $path = $request->file('logo')->store('tenant-logos', 'public'); $branding['logo_path'] = $path; } // 更新主色系 $branding['primary_color'] = $validated['primary_color']; // 如果有傳入字體顏色則更新,否則保留原值(或預設值) if (isset($validated['text_color'])) { $branding['text_color'] = $validated['text_color']; } elseif (!isset($branding['text_color'])) { $branding['text_color'] = '#1a1a1a'; } $tenant->update(['branding' => $branding]); return redirect()->back()->with('success', '樣式設定已更新'); } }