oArticlesService = $oService; } public function search(Request $oRequest, string $sKeyword) { $page = \App\Services\Seo::page($oRequest); $data = $this->oArticlesService->search($sKeyword, 'view'); $data['seo'] = \App\Services\Seo::listMeta('搜索:'.$data['sKeywords'], '本站文章搜索结果', '/search/'.rawurlencode($data['sKeywords']), $page, false); return $this->listing($oRequest, $data); } public function like(int $iArticleId, Request $oRequest) { // 1. 获取/生成指纹 $sFingerprint = $oRequest->cookie('visitor_token') ?? md5($oRequest->ip() . $oRequest->userAgent()); // 2. 调用 Service $aResult = $this->oArticlesService->like($iArticleId, $oRequest->ip(), $sFingerprint); if (!$aResult['status']) { return response()->json($aResult); } // 3. 成功后下发持久 Cookie return response()->json($aResult) ->withCookie(cookie()->forever('visitor_token', $sFingerprint)); } public function listByTag(Request $oRequest, string $sSlug) { $page = \App\Services\Seo::page($oRequest); $data = $this->oArticlesService->getTagArticles($sSlug, 'view'); $data['seo'] = \App\Services\Seo::listMeta($data['oTag']->sName.'相关文章', '按标签浏览本站内容', '/tag/'.$sSlug, $page, false); return $this->listing($oRequest, $data); } public function home(Request $oRequest) { if ($oRequest->filled('s')) { abort_unless(is_string($oRequest->query('s')),404); return redirect(\App\Services\Seo::url('/search/'.rawurlencode(trim($oRequest->query('s')))),301); } $page = \App\Services\Seo::page($oRequest); if ($oRequest->has('page')) return redirect(\App\Services\Seo::url($page>1?'/freenode':'/', $page),301); $slug = $this->oArticlesService->getLatestFreeNodeSlug(); if (!$slug) return response()->view('pages.articles.default.unavailable', [], 503)->header('Retry-After','3600'); $data = $this->articleData($slug, $oRequest); $data['bIsHome'] = true; $data['seo'] = \App\Services\Seo::articleMeta($data['oArticle'], true); return view('pages.articles.default.show', $data); } public function list(Request $oRequest, string $sSlug1, ?string $sSlug2 = null) { $page = \App\Services\Seo::page($oRequest); $data = $this->oArticlesService->getCategoryArticles($sSlug2 ?? $sSlug1, 'view'); $category = $data['oCategory']; $path = \App\Services\Seo::categoryPath($category); if ($sSlug2) abort_unless($path === '/'.$sSlug1.'/'.$sSlug2, 404); $heading = $category->sSlug === 'freenode' ? '免费节点更新记录' : \App\Services\Seo::categoryName($category); $desc = $category->sSlug === 'freenode' ? '按发布时间查看免费节点历史记录;获取当前订阅请访问首页。' : ($category->sDescription ?: $heading.'相关文章与使用说明'); $data['seo'] = \App\Services\Seo::listMeta($heading, $desc, $path, $page, $data['oArticles']->total()>0); if ('/'.$sSlug1 !== $path && !$sSlug2) return redirect(\App\Services\Seo::url($path,$page),301); return $this->listing($oRequest, $data); } private function listing(Request $request, array $data) { $page = \App\Services\Seo::page($request); abort_if($page > $data['oArticles']->lastPage(),404); if ($request->has('page') && $page === 1) return redirect($data['seo']['canonical'],301); $data['oArticles']->withPath(strtok($data['seo']['canonical'],'?')); return view('pages.articles.default.index', $data); } private function articleData(string $slug, Request $request): array { return $this->oArticlesService->getArticle($slug, $request->ip(), $request->cookie('visitor_token') ?? md5($request->ip().$request->userAgent())); } public function show(string $sArticleSlug, Request $oRequest) { $data = $this->articleData($sArticleSlug,$oRequest); $data['seo'] = \App\Services\Seo::articleMeta($data['oArticle']); return view('pages.articles.default.show',$data); } }