22
33namespace NexaMerchant \Blog \Http \Controllers \Api ;
44
5- use Illuminate \Support \Str ;
65use Illuminate \Http \Request ;
76use Illuminate \Support \Carbon ;
87use Illuminate \Validation \Rule ;
98use Illuminate \Support \Facades \DB ;
109use Illuminate \Support \Facades \Log ;
1110use Maatwebsite \Excel \Facades \Excel ;
1211use Illuminate \Support \Facades \Cache ;
13- use Illuminate \Support \Facades \Storage ;
1412use NexaMerchant \Blog \Models \BlogArticle ;
1513use NexaMerchant \Blog \Models \BlogCategory ;
1614use NexaMerchant \Blog \Http \Requests \StoreBlogArticleRequest ;
@@ -86,7 +84,7 @@ public function storeArticle(StoreBlogArticleRequest $request)
8684 $ validated = $ request ->validated ();
8785
8886 // 自动从content提取封面图
89- $ coverImage = $ this -> extractFirstImageFromContent ($ validated ['content ' ]);
87+ $ coverImage = BlogArticle:: extractFirstImageFromContent ($ validated ['content ' ]);
9088
9189 // 合并数据
9290 $ validated = array_merge ($ validated , [
@@ -267,8 +265,6 @@ public function recommendArticles(Request $request)
267265 {
268266 $ validated = $ request ->validate ([
269267 'limit ' => 'nullable|integer|min:1|max:20 ' ,
270- // 'exclude_id' => 'nullable|integer|exists:blog_articles,id',
271- // 'exclude_id' => 'integer|exists:blog_articles,id',
272268 'type ' => 'nullable|in:latest,popular '
273269 ]);
274270
@@ -293,10 +289,9 @@ public function recommendArticles(Request $request)
293289 ->where ('status ' , 1 ) // 只推荐已发布文章
294290 ->when ($ validated ['seo_url_key ' ] ?? false , function ($ q ) use ($ validated ) {
295291 $ q ->where ('seo_url_key ' , '!= ' , $ validated ['seo_url_key ' ]); // 排除当前文章
296- })
297- ->when ($ validated ['type ' ] === 'popular ' , function ($ q ) {
292+ })->when ($ validated ['type ' ] === 'popular ' , function ($ q ) {
298293 $ q ->orderBy ('view_count ' , 'desc ' );
299- }, function ($ q ) {
294+ })-> when ( $ validated [ ' type ' ] === ' latest ' , function ($ q ) {
300295 $ q ->latest ();
301296 })
302297 ->take ($ validated ['limit ' ] ?? 3 )
@@ -313,54 +308,11 @@ public function recommendArticles(Request $request)
313308 ], 200 );
314309 }
315310
316- /**
317- * 从HTML内容中提取第一张图片URL
318- */
319- public function extractFirstImageFromContent (string $ content ): ?string
320- {
321- // 方案1:正则匹配(简单HTML内容)
322- preg_match ('/<img[^>]+src="([^">]+)"/ ' , $ content , $ matches );
323- $ imageUrl = $ matches [1 ] ?? '' ;
324-
325- // 方案2:DOM解析(更复杂的HTML)
326- /*
327- $dom = new \DOMDocument();
328- @$dom->loadHTML($content);
329- $images = $dom->getElementsByTagName('img');
330- $imageUrl = $images->length > 0 ? $images->item(0)->getAttribute('src') : null;
331- */
332-
333- // 如果是本地相对路径,转换为存储路径
334- if ($ imageUrl && !Str::startsWith ($ imageUrl , ['http:// ' , 'https:// ' ])) {
335- return Storage::url (ltrim (parse_url ($ imageUrl , PHP_URL_PATH ), '/ ' ));
336- }
337-
338- return $ imageUrl ;
339- }
340-
341311 public function showArticle ($ id )
342312 {
343313 try {
344- // 验证ID有效性
345- // $validated = $request->validate([
346- // 'with_category' => 'nullable|boolean',
347- // 'with_related' => 'nullable|integer|min:1|max:5' // 相关文章数量
348- // ]);
349-
350- // 构建查询
351- $ article = BlogArticle::query ()
352- // ->when($request->boolean('with_category'), function ($query) {
353- // $query->with(['category' => function ($q) {
354- // $q->select('id', 'name', 'seo_url_key');
355- // }]);
356- // })
357- // ->when($request->filled('with_related'), function ($query) use ($id, $request) {
358- // $query->with(['relatedArticles' => function ($q) use ($request) {
359- // $q->limit($request->input('with_related', 3))
360- // ->select('id', 'title', 'seo_url_key', 'created_at');
361- // }]);
362- // })
363- ->findOrFail ($ id );
314+
315+ $ article = BlogArticle::query ()->findOrFail ($ id );
364316
365317 // 记录访问量(队列处理)
366318 dispatch (function () use ($ id ) {
@@ -393,10 +345,6 @@ public function showArticle($id)
393345 public function showCategory ($ id )
394346 {
395347 try {
396- // $validated = $request->validate([
397- // 'with_latest' => 'nullable|integer|min:1|max:5' // 最新文章数量
398- // ]);
399-
400348 $ category = BlogCategory::query ()->withCount (['articles ' => function ($ q ) {
401349 $ q ->where ('status ' , 1 ); // 只统计已发布文章
402350 }])->with (['latestArticles ' => function ($ q ) {
@@ -508,7 +456,6 @@ protected function formatArticleResponse($article)
508456 'category ' => $ article ->category ?: null ,
509457 'view_count ' => $ article ->view_count ,
510458 'related_articles ' => $ article ->relatedArticles ->isEmpty () ? null : $ article ->relatedArticles ,
511- // 'recommended_articles' => BlogArticle::query()->latest('updated_at')->take(3)->get(),
512459 'seo_meta ' => [
513460 'title ' => $ article ->seo_meta_title ,
514461 'keywords ' => $ article ->seo_meta_keywords ,
@@ -771,6 +718,12 @@ public function batchDeleteCategory(Request $request)
771718 });
772719 }
773720
721+ /**
722+ * @description: 批量上传文章
723+ * @param {Request} $request
724+ * @Author: rickon
725+ * @Date: 2025-04-29 10:22:17
726+ */
774727 public function articlesUpload (Request $ request )
775728 {
776729 $ this ->validate ($ request , [
0 commit comments