feat: add app and database modules
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\SystemSettings;
|
||||
|
||||
use App\Http\Requests\SystemSettings\UpdateSystemConfigRequest;
|
||||
use App\Models\AI\AiUsageLog;
|
||||
use App\Services\AI\AiService;
|
||||
use App\Services\System\MaintenanceManagementService;
|
||||
use App\Services\SystemConfig\SystemConfigService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use SAPNWRFC\Connection;
|
||||
|
||||
class SystemConfigController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
protected SystemConfigService $systemConfig,
|
||||
protected MaintenanceManagementService $maintenanceService,
|
||||
protected AiService $aiService
|
||||
) {
|
||||
// Middleware handled in web.php
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view('pages.system_settings.system-config', [
|
||||
'settings' => $this->systemConfig->all(),
|
||||
'groups' => $this->systemConfig->grouped(),
|
||||
'is_down' => $this->maintenanceService->isDown(),
|
||||
'ai_models' => AiService::getSupportedModels(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(UpdateSystemConfigRequest $request)
|
||||
{
|
||||
$this->systemConfig->update(
|
||||
input: $request->validated(),
|
||||
files: $request->allFiles(),
|
||||
actorId: $request->user()?->id,
|
||||
request: $request,
|
||||
);
|
||||
|
||||
// ✍️ Log "Action Log" bulk update
|
||||
activity('system-config')
|
||||
->causedBy($request->user())
|
||||
->withProperties([
|
||||
'ip' => $request->ip(),
|
||||
'agent' => $request->userAgent(),
|
||||
'details' => __('Bulk system configuration update performed.'),
|
||||
])
|
||||
->log(__('Updated System Settings'));
|
||||
|
||||
// Only sync maintenance state if maintenance fields were part of the request
|
||||
$maintenanceKeys = [
|
||||
'maintenance_mode_enabled',
|
||||
'maintenance_mode_secret',
|
||||
'maintenance_mode_allowed_ips',
|
||||
'maintenance_mode_end_at',
|
||||
];
|
||||
|
||||
if ($request->hasAny($maintenanceKeys)) {
|
||||
$this->maintenanceService->syncState();
|
||||
}
|
||||
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => __('Configuration updated successfully!'),
|
||||
'settings' => $this->systemConfig->all(true),
|
||||
'is_down' => $this->maintenanceService->isDown(),
|
||||
]);
|
||||
}
|
||||
|
||||
return back()->with('success', __('Configuration updated successfully!'));
|
||||
}
|
||||
|
||||
public function testEmail(Request $request): JsonResponse
|
||||
{
|
||||
$to = $request->input('to') ?: $this->systemConfig->get('mail_from_address');
|
||||
|
||||
if (! $to || ! filter_var($to, FILTER_VALIDATE_EMAIL)) {
|
||||
return response()->json(['success' => false, 'message' => __('No valid recipient email address. Please enter a valid email.')], 422);
|
||||
}
|
||||
|
||||
try {
|
||||
Mail::raw(
|
||||
__('This automated message confirms that the SMTP configuration for :app has been successfully verified and is operating correctly.', ['app' => config('app.name')]),
|
||||
function ($message) use ($to) {
|
||||
$message->to($to)
|
||||
->subject(__('SMTP Configuration Verification — :app', ['app' => config('app.name')]));
|
||||
}
|
||||
);
|
||||
|
||||
// ✍️ Log "Action Log" test email
|
||||
activity('system-config')
|
||||
->causedBy($request->user())
|
||||
->withProperties([
|
||||
'ip' => $request->ip(),
|
||||
'agent' => $request->userAgent(),
|
||||
'recipient' => $to,
|
||||
'details' => __('Sent a test email to :email to verify SMTP configuration.', ['email' => $to]),
|
||||
])
|
||||
->log(__('Sent Test Email'));
|
||||
|
||||
return response()->json(['success' => true, 'message' => __('Test email sent successfully to :email', ['email' => $to])]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Test email failed: '.$e->getMessage());
|
||||
|
||||
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function testSapConnection(Request $request): JsonResponse
|
||||
{
|
||||
$config = [
|
||||
'ashost' => $request->input('sap_rfc_ashost'),
|
||||
'sysnr' => $request->input('sap_rfc_sysnr'),
|
||||
'client' => $request->input('sap_rfc_client'),
|
||||
'user' => $request->input('sap_rfc_user'),
|
||||
'passwd' => $request->input('sap_rfc_passwd'),
|
||||
'router' => $request->input('sap_rfc_router'),
|
||||
];
|
||||
|
||||
// Check if required fields are present
|
||||
if (empty($config['ashost']) || empty($config['sysnr']) || empty($config['user'])) {
|
||||
return response()->json(['success' => false, 'message' => __('Host, System Number, and User are required for testing.')], 422);
|
||||
}
|
||||
|
||||
if (! extension_loaded('sapnwrfc')) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => __('The sapnwrfc PHP extension is not installed on this server. Connection cannot be established.'),
|
||||
], 500);
|
||||
}
|
||||
|
||||
try {
|
||||
// Attempt to connect using the extension
|
||||
$conn = new Connection($config);
|
||||
$attributes = $conn->getAttributes();
|
||||
$conn->close();
|
||||
|
||||
activity('system-config')
|
||||
->causedBy($request->user())
|
||||
->withProperties(['host' => $config['ashost']])
|
||||
->log(__('Successful SAP RFC connection test'));
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => __('Successfully connected to SAP! (System: :sysid)', ['sysid' => $attributes['sysId'] ?? 'N/A']),
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['success' => false, 'message' => 'SAP Error: '.$e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function testDatabaseConnection(Request $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
\Illuminate\Support\Facades\DB::connection()->getPdo();
|
||||
$dbName = \Illuminate\Support\Facades\DB::connection()->getDatabaseName();
|
||||
|
||||
activity('system-config')
|
||||
->causedBy($request->user())
|
||||
->withProperties(['db' => $dbName])
|
||||
->log(__('Successful database connection test'));
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => __('Database connection verified successfully! Connected to: :db', ['db' => $dbName]),
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['success' => false, 'message' => 'Database Error: '.$e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function publicConfig(): JsonResponse
|
||||
{
|
||||
$settings = $this->systemConfig->getPublicSettings();
|
||||
|
||||
if (! empty($settings['app_logo'])) {
|
||||
$settings['app_logo_url'] = asset($settings['app_logo']);
|
||||
}
|
||||
|
||||
if (! empty($settings['app_favicon'])) {
|
||||
$settings['app_favicon_url'] = asset($settings['app_favicon']);
|
||||
}
|
||||
|
||||
return response()
|
||||
->json([
|
||||
'data' => $settings,
|
||||
'generated_at' => now()->toIso8601String(),
|
||||
])
|
||||
->header('Cache-Control', 'public, max-age=300, s-maxage=300');
|
||||
}
|
||||
|
||||
public function simulateAi(Request $request): JsonResponse
|
||||
{
|
||||
$prompt = $request->input('prompt');
|
||||
$providerId = $request->input('ai_provider', $this->systemConfig->get('ai_provider', 'gpt'));
|
||||
|
||||
if (! $prompt) {
|
||||
return response()->json(['success' => false, 'message' => __('Prompt is required.')], 422);
|
||||
}
|
||||
|
||||
try {
|
||||
$options = [
|
||||
'key' => $request->input('ai_key'),
|
||||
'model' => $request->input('ai_model'),
|
||||
'instruction' => $request->input('ai_instruction'),
|
||||
'temperature' => $request->input('ai_temperature'),
|
||||
'max_tokens' => $request->input('ai_max_tokens'),
|
||||
];
|
||||
|
||||
$result = $this->aiService->provider($providerId)->generate($prompt, $options);
|
||||
|
||||
if (! $result['success']) {
|
||||
return response()->json(['success' => false, 'message' => $result['error']], 500);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'provider' => $providerId,
|
||||
'response' => $result['response'],
|
||||
'usage' => $result['usage'] ?? null,
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function getAiUsageStats(Request $request): JsonResponse
|
||||
{
|
||||
$period = $request->input('period', 'all');
|
||||
$query = AiUsageLog::query();
|
||||
|
||||
if ($period !== 'all') {
|
||||
$date = match ($period) {
|
||||
'day' => now()->startOfDay(),
|
||||
'week' => now()->startOfWeek(),
|
||||
'month' => now()->startOfMonth(),
|
||||
'year' => now()->startOfYear(),
|
||||
default => null
|
||||
};
|
||||
|
||||
if ($date) {
|
||||
$query->where('created_at', '>=', $date);
|
||||
}
|
||||
}
|
||||
|
||||
$stats = [
|
||||
'total_requests' => (clone $query)->count(),
|
||||
'total_tokens' => (clone $query)->sum('total_tokens'),
|
||||
'total_cost' => (clone $query)->sum('estimated_cost'),
|
||||
'providers' => (clone $query)->select('provider', \DB::raw('count(*) as count'))
|
||||
->groupBy('provider')
|
||||
->get(),
|
||||
'recent' => (clone $query)->latest()->take(5)->get(),
|
||||
'period' => $period,
|
||||
];
|
||||
|
||||
return response()->json(['success' => true, 'stats' => $stats]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user