2026-02-05 22:22:10 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Providers;
|
|
|
|
|
|
|
|
|
|
use App\Models\Category;
|
|
|
|
|
use App\Models\SiteSetting;
|
|
|
|
|
use Illuminate\Support\Str;
|
|
|
|
|
use Illuminate\Pagination\Paginator;
|
|
|
|
|
use Illuminate\Support\ServiceProvider;
|
|
|
|
|
use Illuminate\Support\Facades\View;
|
|
|
|
|
use Livewire\Livewire;
|
|
|
|
|
|
|
|
|
|
class AppServiceProvider extends ServiceProvider
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* Register any application services.
|
|
|
|
|
*/
|
|
|
|
|
public function register(): void
|
|
|
|
|
{
|
|
|
|
|
$this->ensureIntlNumberFormatter();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Bootstrap any application services.
|
|
|
|
|
*/
|
|
|
|
|
public function boot(): void
|
|
|
|
|
{
|
|
|
|
|
$this->registerFilamentLivewireResolver();
|
|
|
|
|
|
2026-02-07 22:55:07 +08:00
|
|
|
Paginator::defaultView('frontend.partials.pagination');
|
2026-02-05 22:22:10 +08:00
|
|
|
|
2026-02-07 22:55:07 +08:00
|
|
|
View::composer('frontend.layouts.app', function ($view): void {
|
2026-02-05 22:22:10 +08:00
|
|
|
$categories = Category::with([
|
|
|
|
|
'children' => function ($query) {
|
|
|
|
|
$query->withCount('products')
|
|
|
|
|
->orderBy('sort');
|
|
|
|
|
},
|
|
|
|
|
])
|
|
|
|
|
->withCount('products')
|
|
|
|
|
->whereNull('parent_id')
|
|
|
|
|
->orderBy('sort')
|
|
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
$view->with([
|
|
|
|
|
'sidebarCategories' => $categories,
|
|
|
|
|
'siteTitle' => SiteSetting::value('site_title', 'AI 工具导航'),
|
2026-02-07 22:55:07 +08:00
|
|
|
'siteDescription' => SiteSetting::value('site_description', '发现优质 AI 工具与产品'),
|
2026-02-05 22:22:10 +08:00
|
|
|
'siteLogo' => SiteSetting::value('site_logo'),
|
|
|
|
|
'siteFooter' => SiteSetting::value('site_footer'),
|
|
|
|
|
'gaId' => SiteSetting::value('ga_id'),
|
|
|
|
|
'icpNumber' => SiteSetting::value('icp_number'),
|
|
|
|
|
'socialLinks' => $this->parseSocialLinks(SiteSetting::value('social_links', '')),
|
|
|
|
|
]);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function ensureIntlNumberFormatter(): void
|
|
|
|
|
{
|
|
|
|
|
if (class_exists('NumberFormatter')) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$polyfill = app_path('Support/NumberFormatter.php');
|
|
|
|
|
if (is_file($polyfill)) {
|
|
|
|
|
require_once $polyfill;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function registerFilamentLivewireResolver(): void
|
|
|
|
|
{
|
|
|
|
|
Livewire::resolveMissingComponent(function (string $name): ?string {
|
|
|
|
|
if (! Str::startsWith($name, ['filament.', 'app.'])) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$class = collect(explode('.', $name))
|
|
|
|
|
->map(fn (string $segment) => Str::studly($segment))
|
|
|
|
|
->join('\\');
|
|
|
|
|
|
|
|
|
|
return is_subclass_of($class, \Livewire\Component::class) ? $class : null;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function parseSocialLinks(?string $raw): array
|
|
|
|
|
{
|
|
|
|
|
if (!$raw) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$lines = preg_split('/\r\n|\r|\n/', $raw);
|
|
|
|
|
$links = [];
|
|
|
|
|
foreach ($lines as $line) {
|
|
|
|
|
$line = trim($line);
|
|
|
|
|
if ($line === '') {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
[$name, $url] = array_pad(explode('|', $line, 2), 2, '');
|
|
|
|
|
if ($name && $url) {
|
|
|
|
|
$links[] = ['name' => trim($name), 'url' => trim($url)];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $links;
|
|
|
|
|
}
|
|
|
|
|
}
|