Initialer Laravel Commit für BetiX
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled

This commit is contained in:
2026-04-04 18:01:50 +02:00
commit 0280278978
374 changed files with 65210 additions and 0 deletions

View File

@@ -0,0 +1,127 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Inertia\Inertia;
use Inertia\Response;
class SupportAdminController extends Controller
{
private function assertAdmin(): void
{
if (!Auth::check() || strtolower((string) Auth::user()->role) !== 'admin') {
abort(403, 'Nur für Admins');
}
}
private function ollamaStatus(): array
{
$host = rtrim(env('OLLAMA_HOST', 'http://127.0.0.1:11434'), '/');
$model = env('OLLAMA_MODEL', 'llama3');
try {
$res = Http::timeout(2)->get($host . '/api/tags');
return ['healthy' => $res->ok(), 'host' => $host, 'model' => $model, 'error' => $res->ok() ? null : 'Keine Verbindung'];
} catch (\Throwable $e) {
return ['healthy' => false, 'host' => $host, 'model' => $model, 'error' => $e->getMessage()];
}
}
private function getThreads(): array
{
$index = cache()->get('support_threads_index', []);
$threads = [];
foreach (array_reverse($index) as $row) {
$full = cache()->get('support_threads:' . $row['id']);
if (is_array($full)) {
$threads[] = $full;
} else {
$threads[] = $row;
}
}
return $threads;
}
public function index(Request $request): Response
{
$this->assertAdmin();
$enabled = (bool) (cache()->get('support_chat_enabled') ?? config('app.support_chat_enabled', true));
return Inertia::render('Admin/Support', [
'enabled' => $enabled,
'threads' => $this->getThreads(),
'ollama' => $this->ollamaStatus(),
]);
}
public function settings(Request $request)
{
$this->assertAdmin();
$data = $request->validate(['enabled' => 'required|boolean']);
cache()->put('support_chat_enabled', (bool) $data['enabled'], now()->addYear());
return back()->with('success', 'Support-Chat Einstellungen gespeichert.');
}
public function reply(Request $request, string $thread)
{
$this->assertAdmin();
$data = $request->validate(['text' => 'required|string|min:1|max:1000']);
$record = cache()->get('support_threads:' . $thread);
if (!is_array($record)) {
return back()->withErrors(['text' => 'Thread nicht gefunden.']);
}
$record['messages'][] = [
'id' => Str::uuid()->toString(),
'sender' => 'agent',
'body' => $data['text'],
'at' => now()->toIso8601String(),
];
$record['status'] = 'agent';
$record['updated_at'] = now()->toIso8601String();
cache()->put('support_threads:' . $thread, $record, now()->addDay());
// Update index entry
$index = cache()->get('support_threads_index', []);
foreach ($index as &$row) {
if (($row['id'] ?? null) === $thread) {
$row['status'] = 'agent';
$row['updated_at'] = $record['updated_at'];
break;
}
}
cache()->put('support_threads_index', $index, now()->addDay());
return back()->with('success', 'Nachricht gesendet.');
}
public function close(Request $request, string $thread)
{
$this->assertAdmin();
$record = cache()->get('support_threads:' . $thread);
if (is_array($record)) {
$record['status'] = 'closed';
$record['updated_at'] = now()->toIso8601String();
cache()->put('support_threads:' . $thread, $record, now()->addDay());
}
$index = cache()->get('support_threads_index', []);
foreach ($index as &$row) {
if (($row['id'] ?? null) === $thread) {
$row['status'] = 'closed';
break;
}
}
cache()->put('support_threads_index', $index, now()->addDay());
return back()->with('success', 'Chat geschlossen.');
}
}