Files
KnowledgeBase/routes/web.php

122 lines
3.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
use App\Http\Controllers\DocumentController;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
Route::get('/', function () {
return view('welcome');
});
// 健康检查路由用于Docker健康检查
Route::get('/health', function () {
$services = [];
$allHealthy = true;
try {
// 检查数据库连接
DB::connection()->getPdo();
$services['database'] = 'connected';
} catch (Exception $e) {
$services['database'] = 'disconnected';
$allHealthy = false;
}
try {
// 检查Redis连接
if (config('cache.default') === 'redis') {
Cache::store('redis')->put('health_check', 'ok', 10);
Cache::store('redis')->forget('health_check');
$services['redis'] = 'connected';
} else {
$services['redis'] = 'not_configured';
}
} catch (Exception $e) {
$services['redis'] = 'disconnected';
$allHealthy = false;
}
try {
// 检查Meilisearch连接
if (config('scout.driver') === 'meilisearch') {
$client = new \GuzzleHttp\Client();
$response = $client->get(config('scout.meilisearch.host') . '/health', [
'timeout' => 5,
'headers' => [
'Authorization' => 'Bearer ' . config('scout.meilisearch.key')
]
]);
if ($response->getStatusCode() === 200) {
$services['meilisearch'] = 'connected';
} else {
$services['meilisearch'] = 'unhealthy';
$allHealthy = false;
}
} else {
$services['meilisearch'] = 'not_configured';
}
} catch (Exception $e) {
$services['meilisearch'] = 'disconnected';
$allHealthy = false;
}
// 检查存储目录是否可写
try {
$testFile = storage_path('logs/health_check_test.tmp');
file_put_contents($testFile, 'test');
unlink($testFile);
$services['storage'] = 'writable';
} catch (Exception $e) {
$services['storage'] = 'not_writable';
$allHealthy = false;
}
$status = $allHealthy ? 'ok' : 'degraded';
$httpCode = $allHealthy ? 200 : 503;
return response()->json([
'status' => $status,
'timestamp' => now()->toISOString(),
'services' => $services,
'version' => config('app.version', '1.0.0')
], $httpCode);
})->name('health.check');
// 指引步骤渲染(供终端 webview 打开,公开访问)
Route::get('/guides/pages/{page}', function (\App\Models\GuidePage $page) {
return view('guides.page', ['page' => $page]);
})->name('guides.pages.show');
// 文档预览和下载路由(需要认证)
Route::middleware(['auth'])->group(function () {
Route::get('/documents/{document}/preview', [DocumentController::class, 'preview'])
->name('documents.preview');
Route::get('/documents/{document}/download', [DocumentController::class, 'download'])
->name('documents.download');
});
// 提供 markdown 目录中 media 文件的访问(需要认证)
// 路径格式: /markdown-media/{path}
Route::middleware(['auth'])->get('/markdown-media/{path}', function ($path) {
$path = trim((string) $path, '/');
if ($path === '' || str_contains($path, '../')) {
abort(404);
}
if (!Storage::disk('markdown')->exists($path)) {
abort(404);
}
$mimeType = Storage::disk('markdown')->mimeType($path);
if (!is_string($mimeType) || !str_starts_with($mimeType, 'image/')) {
abort(404);
}
$file = Storage::disk('markdown')->get($path);
return response($file, 200)->header('Content-Type', $mimeType);
})->where('path', '.*')->name('markdown.media');