156 lines
5.6 KiB
PHP
156 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Article;
|
|
use App\Models\GlossaryTerm;
|
|
use App\Models\Product;
|
|
use App\Models\Solution;
|
|
use App\Models\News;
|
|
|
|
class SitemapController extends Controller
|
|
{
|
|
/**
|
|
* 机读站点地图(SEO:供百度 / Google 等搜索引擎提交)。
|
|
* 访问 /sitemap.xml 获取。
|
|
*/
|
|
public function xml()
|
|
{
|
|
$urls = [];
|
|
|
|
// ── 核心静态页面 ──────────────────────────────
|
|
$core = [
|
|
'/' => ['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 = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
|
$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
|
|
|
|
foreach ($urls as $u) {
|
|
$xml .= ' <url>' . "\n";
|
|
$xml .= ' <loc>' . e($u['loc']) . '</loc>' . "\n";
|
|
|
|
if (!empty($u['last'])) {
|
|
$xml .= ' <lastmod>' . e($u['last']) . '</lastmod>' . "\n";
|
|
}
|
|
|
|
$xml .= ' <changefreq>' . e($u['freq']) . '</changefreq>' . "\n";
|
|
$xml .= ' <priority>' . e($u['pri']) . '</priority>' . "\n";
|
|
$xml .= ' </url>' . "\n";
|
|
}
|
|
|
|
$xml .= '</urlset>';
|
|
|
|
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'));
|
|
}
|
|
}
|