['freq' => 'daily', 'pri' => '1.0'], '/about' => ['freq' => 'monthly', 'pri' => '0.8'], '/products' => ['freq' => 'weekly', 'pri' => '0.8'], '/articles' => ['freq' => 'weekly', 'pri' => '0.8'], '/solutions' => ['freq' => 'weekly', 'pri' => '0.8'], '/news' => ['freq' => 'weekly', 'pri' => '0.8'], '/glossary' => ['freq' => 'weekly', 'pri' => '0.8'], '/forum' => ['freq' => 'daily', 'pri' => '0.7'], '/contact' => ['freq' => 'yearly', 'pri' => '0.6'], '/sitemap' => ['freq' => 'monthly', 'pri' => '0.3'], ]; foreach ($core as $path => $meta) { $urls[] = [ 'loc' => url($path), 'freq' => $meta['freq'], 'pri' => $meta['pri'], ]; } // ── 动态内容:产品 ──────────────────────────── foreach (Product::published()->get() as $p) { $urls[] = [ 'loc' => route('products.show', $p->slug), 'last' => $p->updated_at?->toW3CString(), 'freq' => 'weekly', 'pri' => '0.7', ]; } // ── 动态内容:技术文章 ──────────────────────── foreach (Article::published()->get() as $a) { $urls[] = [ 'loc' => route('articles.show', $a->slug), 'last' => $a->published_at?->toW3CString(), 'freq' => 'monthly', 'pri' => '0.6', ]; } // ── 动态内容:术语库 ────────────────────────── foreach (GlossaryTerm::ordered()->get() as $g) { $urls[] = [ 'loc' => route('glossary.show', $g->slug), 'freq' => 'monthly', 'pri' => '0.4', ]; } // ── 动态内容:解决方案 ──────────────────────── foreach (Solution::published()->get() as $s) { $urls[] = [ 'loc' => route('solutions.show', $s->slug), 'last' => $s->updated_at?->toW3CString(), 'freq' => 'weekly', 'pri' => '0.7', ]; } // ── 动态内容:新闻动态 ──────────────────────── foreach (News::published()->get() as $n) { $urls[] = [ 'loc' => route('news.show', $n->slug), 'last' => $n->published_at?->toW3CString(), 'freq' => 'monthly', 'pri' => '0.6', ]; } $xml = '' . "\n"; $xml .= '' . "\n"; foreach ($urls as $u) { $xml .= ' ' . "\n"; $xml .= ' ' . e($u['loc']) . '' . "\n"; if (!empty($u['last'])) { $xml .= ' ' . e($u['last']) . '' . "\n"; } $xml .= ' ' . e($u['freq']) . '' . "\n"; $xml .= ' ' . e($u['pri']) . '' . "\n"; $xml .= ' ' . "\n"; } $xml .= ''; return response($xml, 200, [ 'Content-Type' => 'application/xml; charset=UTF-8', ]); } /** * robots.txt:开放前台收录,屏蔽后台与用户接口,并指向 sitemap.xml。 * 访问 /robots.txt 获取(动态读取 APP_URL,域名随环境自动变化)。 */ public function robots() { $base = rtrim(config('app.url'), '/'); $content = "User-agent: *\n"; $content .= "Allow: /\n\n"; $content .= "# 后台与管理 / 用户接口不向搜索引擎开放\n"; $content .= "Disallow: /admin/\n"; $content .= "Disallow: /login\n"; $content .= "Disallow: /register\n"; $content .= "Disallow: /logout\n"; $content .= "Disallow: /settings\n"; $content .= "Disallow: /upload\n"; $content .= "Disallow: /forum/threads\n"; $content .= "Disallow: /api/\n\n"; $content .= "Sitemap: {$base}/sitemap.xml\n"; return response($content, 200, [ 'Content-Type' => 'text/plain; charset=UTF-8', ]); } /** * 可视化「网站地图」页面(用户可见,列出全站主要页面与内容)。 * 访问 /sitemap 获取。 */ public function index() { $products = Product::published()->get(); $articles = Article::published()->get(); $terms = GlossaryTerm::ordered()->get(); $solutions = Solution::published()->get(); $news = News::published()->get(); return view('sitemap', compact('products', 'articles', 'terms', 'solutions', 'news')); } }