Explorar o código

三藏分类页:提供 channel 时显示当前频道并隐藏类型/语言过滤器

- 调用 ChannelApi::getById 获取频道名展示在过滤器卡片
- channel 作为生效过滤项纳入清除按钮判断,清除后去掉尾部 ?
- 新增 library.current_channel 多语言文案

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
visuddhinanda hai 3 días
pai
achega
6e99450dc0

+ 65 - 74
api-v13/app/Http/Controllers/Library/TipitakaController.php

@@ -2,20 +2,17 @@
 
 
 namespace App\Http\Controllers\Library;
 namespace App\Http\Controllers\Library;
 
 
+use App\Http\Api\ChannelApi;
 use App\Http\Controllers\Controller;
 use App\Http\Controllers\Controller;
-use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Cookie;
-use Illuminate\Support\Facades\File;
-use Illuminate\Support\Str;
-use Illuminate\Support\Facades\Log;
-
-
 use App\Models\PaliText;
 use App\Models\PaliText;
 use App\Models\ProgressChapter;
 use App\Models\ProgressChapter;
-use App\Services\TermService;
 use App\Models\Tag;
 use App\Models\Tag;
 use App\Models\TagMap;
 use App\Models\TagMap;
-
+use App\Services\TermService;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Cookie;
+use Illuminate\Support\Facades\File;
+use Illuminate\Support\Str;
 
 
 class TipitakaController extends Controller
 class TipitakaController extends Controller
 {
 {
@@ -31,8 +28,6 @@ class TipitakaController extends Controller
 
 
     /**
     /**
      * 构造函数,注入 TermService
      * 构造函数,注入 TermService
-     *
-     * @param  \App\Services\TermService  $termService
      */
      */
     public function __construct(
     public function __construct(
         protected TermService $termService,
         protected TermService $termService,
@@ -45,8 +40,8 @@ class TipitakaController extends Controller
     {
     {
         return hexdec(substr(str_replace('-', '', $uid), 0, 4)) % 255;
         return hexdec(substr(str_replace('-', '', $uid), 0, 4)) % 255;
     }
     }
-    protected static int $nextId = 1;
 
 
+    protected static int $nextId = 1;
 
 
     // app/Http/Controllers/Library/CategoryController.php
     // app/Http/Controllers/Library/CategoryController.php
     // category() 方法修改版
     // category() 方法修改版
@@ -67,32 +62,32 @@ class TipitakaController extends Controller
         // ── 当前分类 ──────────────────────────────────────────
         // ── 当前分类 ──────────────────────────────────────────
         if ($id) {
         if ($id) {
             $currentCategory = collect($categories)->firstWhere('id', $id);
             $currentCategory = collect($categories)->firstWhere('id', $id);
-            if (!$currentCategory) {
+            if (! $currentCategory) {
                 abort(404);
                 abort(404);
             }
             }
             $breadcrumbs = $this->getBreadcrumbs($currentCategory, $categories);
             $breadcrumbs = $this->getBreadcrumbs($currentCategory, $categories);
         } else {
         } else {
             // 首页:虚拟顶级分类
             // 首页:虚拟顶级分类
             $currentCategory = ['id' => null, 'name' => '三藏'];
             $currentCategory = ['id' => null, 'name' => '三藏'];
-            $breadcrumbs     = [];
+            $breadcrumbs = [];
         }
         }
 
 
         // ── 子分类 ─────────────────────────────────────────────
         // ── 子分类 ─────────────────────────────────────────────
         $subCategories = array_values(array_filter(
         $subCategories = array_values(array_filter(
             $categories,
             $categories,
-            fn($cat) => $cat['parent_id'] == $id
+            fn ($cat) => $cat['parent_id'] == $id
         ));
         ));
-        if (count($subCategories) === 0 && !$request->has('book')) {
+        if (count($subCategories) === 0 && ! $request->has('book')) {
             $paliBooks = $this->getPaliBooks($categories, $id);
             $paliBooks = $this->getPaliBooks($categories, $id);
-            foreach ($paliBooks as  $value) {
+            foreach ($paliBooks as $value) {
                 $subCategories[] = [
                 $subCategories[] = [
                     'id' => $id,
                     'id' => $id,
                     'name' => $value->text,
                     'name' => $value->text,
-                    'book' => "{$value->book}-{$value->paragraph}"
+                    'book' => "{$value->book}-{$value->paragraph}",
                 ];
                 ];
             }
             }
         }
         }
-        $allNames = array_map(fn($item) => $item['name'], $subCategories);
+        $allNames = array_map(fn ($item) => $item['name'], $subCategories);
 
 
         // 去重
         // 去重
         $allNames = array_values(array_unique($allNames));
         $allNames = array_values(array_unique($allNames));
@@ -112,25 +107,28 @@ class TipitakaController extends Controller
             $subCategories[$key]['name'] = $termMap[$name] ?? $name;
             $subCategories[$key]['name'] = $termMap[$name] ?? $name;
         }
         }
 
 
-
-
         // ── 过滤参数 ────────────────────────────────────────────
         // ── 过滤参数 ────────────────────────────────────────────
-        $selectedType   = request('type',   'all');
-        $selectedLang   = request('lang',   'all');
+        $selectedType = request('type', 'all');
+        $selectedLang = request('lang', 'all');
         $selectedAuthor = request('author', 'all');
         $selectedAuthor = request('author', 'all');
-        $selectedSort   = request('sort',   'new');
-        $selectedChannel   = request('channel',   'all');
+        $selectedSort = request('sort', 'new');
+        $selectedChannel = request('channel', 'all');
+
+        // ── 当前频道(提供 channel 参数时) ──────────────────────
+        $currentChannel = $selectedChannel !== 'all'
+            ? (ChannelApi::getById($selectedChannel) ?: null)
+            : null;
 
 
         $sortList = [
         $sortList = [
-            ['key' => 'new',         'label' => __('library.badge_updated'),],
-            ['key' => 'progress',    'label' => '完成度',],
+            ['key' => 'new',         'label' => __('library.badge_updated')],
+            ['key' => 'progress',    'label' => '完成度'],
         ];
         ];
 
 
         $selected = [
         $selected = [
-            'type'   => $selectedType,
-            'lang'   => $selectedLang,
+            'type' => $selectedType,
+            'lang' => $selectedLang,
             'author' => $selectedAuthor,
             'author' => $selectedAuthor,
-            'sort'   => $selectedSort,
+            'sort' => $selectedSort,
             'channel' => $selectedChannel,
             'channel' => $selectedChannel,
         ];
         ];
         if ($request->has('book')) {
         if ($request->has('book')) {
@@ -168,7 +166,8 @@ class TipitakaController extends Controller
             'totalCount',
             'totalCount',
             'recommended',
             'recommended',
             'activeAuthors',
             'activeAuthors',
-            'sortList'
+            'sortList',
+            'currentChannel'
         ));
         ));
     }
     }
 
 
@@ -203,36 +202,23 @@ class TipitakaController extends Controller
             ['id' => 5, 'title' => '长部·梵网经',    'category' => '经藏'],
             ['id' => 5, 'title' => '长部·梵网经',    'category' => '经藏'],
         ];
         ];
     }
     }
+
     private function mockActiveAuthors()
     private function mockActiveAuthors()
     {
     {
         return [
         return [
             [
             [
-                'name'    => 'Bhikkhu Bodhi',
-                'avatar'  => null,
-                'color'   => '#2d5a8e',
+                'name' => 'Bhikkhu Bodhi',
+                'avatar' => null,
+                'color' => '#2d5a8e',
                 'initials' => 'BB',
                 'initials' => 'BB',
-                'count'   => 24,
+                'count' => 24,
             ],
             ],
             [
             [
-                'name'    => 'Bhikkhu Sujato',
-                'avatar'  => null,
-                'color'   => '#5a2d8e',
+                'name' => 'Bhikkhu Sujato',
+                'avatar' => null,
+                'color' => '#5a2d8e',
                 'initials' => 'BS',
                 'initials' => 'BS',
-                'count'   => 18,
-            ],
-            [
-                'name'    => 'Buddhaghosa',
-                'avatar'  => null,
-                'color'   => '#8e5a2d',
-                'initials' => 'BG',
-                'count'   => 12,
-            ],
-            [
-                'name'    => 'Bhikkhu Brahmali',
-                'avatar'  => null,
-                'color'   => '#2d8e5a',
-                'initials' => 'BR',
-                'count'   => 9,
+                'count' => 18,
             ],
             ],
         ];
         ];
     }
     }
@@ -256,12 +242,10 @@ class TipitakaController extends Controller
             ['id' => '1', 'name' => 'sutta'],
             ['id' => '1', 'name' => 'sutta'],
             ['id' => '48', 'name' => 'vinaya'],
             ['id' => '48', 'name' => 'vinaya'],
             ['id' => '66', 'name' => 'abhidhamma'],
             ['id' => '66', 'name' => 'abhidhamma'],
-            ['id' => '82', 'name' => 'añña']
+            ['id' => '82', 'name' => 'añña'],
         ];
         ];
     }
     }
 
 
-
-
     private function subCategories($categories, int $id)
     private function subCategories($categories, int $id)
     {
     {
         return array_filter($categories, function ($cat) use ($id) {
         return array_filter($categories, function ($cat) use ($id) {
@@ -273,7 +257,7 @@ class TipitakaController extends Controller
     {
     {
         if ($id) {
         if ($id) {
             $currentCategory = collect($categories)->firstWhere('id', $id);
             $currentCategory = collect($categories)->firstWhere('id', $id);
-            if (!$currentCategory) {
+            if (! $currentCategory) {
                 abort(404);
                 abort(404);
             }
             }
             // 标签查章节
             // 标签查章节
@@ -290,18 +274,22 @@ class TipitakaController extends Controller
         foreach ($booksChapter as $key => $value) {
         foreach ($booksChapter as $key => $value) {
             $chapters[] = [$value->book, $value->paragraph];
             $chapters[] = [$value->book, $value->paragraph];
         }
         }
+
         return $chapters;
         return $chapters;
     }
     }
+
     private function getPaliBooks(array $categories, string $id)
     private function getPaliBooks(array $categories, string $id)
     {
     {
         $chapters = $this->getBooksIdInCat($categories, $id);
         $chapters = $this->getBooksIdInCat($categories, $id);
 
 
         $books = PaliText::whereIns(['book', 'paragraph'], $chapters)->get();
         $books = PaliText::whereIns(['book', 'paragraph'], $chapters)->get();
+
         return $books;
         return $books;
     }
     }
+
     private function getBooks(array $categories, ?string $id, array $filters)
     private function getBooks(array $categories, ?string $id, array $filters)
     {
     {
-        //根据分类获取书号
+        // 根据分类获取书号
         if (isset($filters['book'])) {
         if (isset($filters['book'])) {
             $chapters = [explode('-', $filters['book'])];
             $chapters = [explode('-', $filters['book'])];
         } else {
         } else {
@@ -328,10 +316,11 @@ class TipitakaController extends Controller
             ->whereIns(['book', 'para'], $chapters);
             ->whereIns(['book', 'para'], $chapters);
         if ($filters['sort'] === 'new') {
         if ($filters['sort'] === 'new') {
             $table = $table->orderBy('last_chapter_completed_at', 'desc');
             $table = $table->orderBy('last_chapter_completed_at', 'desc');
-        } else if ($filters['sort'] === 'progress') {
+        } elseif ($filters['sort'] === 'progress') {
             $table = $table->orderBy('progress', 'desc');
             $table = $table->orderBy('progress', 'desc');
         }
         }
         $books = $table->take(100)->get();
         $books = $table->take(100)->get();
+
         return $this->getBooksInfo($books);
         return $this->getBooksInfo($books);
     }
     }
 
 
@@ -340,7 +329,7 @@ class TipitakaController extends Controller
         $pali = PaliText::where('level', 1)->get();
         $pali = PaliText::where('level', 1)->get();
         // 获取该分类下的书籍
         // 获取该分类下的书籍
         $categoryBooks = [];
         $categoryBooks = [];
-        $books->each(function ($book) use (&$categoryBooks,  $pali) {
+        $books->each(function ($book) use (&$categoryBooks, $pali) {
             $title = $book->title;
             $title = $book->title;
             if (empty($title)) {
             if (empty($title)) {
                 $title = $pali->firstWhere('book', $book->book)->toc;
                 $title = $pali->firstWhere('book', $book->book)->toc;
@@ -361,23 +350,23 @@ class TipitakaController extends Controller
             $subTitle = $this->getBookType($book->book, $book->para);
             $subTitle = $this->getBookType($book->book, $book->para);
 
 
             $categoryBooks[] = [
             $categoryBooks[] = [
-                "id" => $book->uid,
-                "title" => $title,
-                "author" => $book->channel->name,
+                'id' => $book->uid,
+                'title' => $title,
+                'author' => $book->channel->name,
                 'subTitle' => $subTitle,
                 'subTitle' => $subTitle,
-                "publisher" => $book->channel->owner,
+                'publisher' => $book->channel->owner,
                 'completed_chapters' => $book->completed_chapters,
                 'completed_chapters' => $book->completed_chapters,
-                "type" => __('labels.' . $book->channel->type),
-                "cover" => $coverUrl,
+                'type' => __('labels.'.$book->channel->type),
+                'cover' => $coverUrl,
                 'cover_gradient' => $this->coverGradients[$colorIdx % count($this->coverGradients)],
                 'cover_gradient' => $this->coverGradients[$colorIdx % count($this->coverGradients)],
-                "description" => $book->summary ?? "比库戒律的详细说明",
-                "language" => __('language.' . $book->channel->lang),
+                'description' => $book->summary ?? '比库戒律的详细说明',
+                'language' => __('language.'.$book->channel->lang),
             ];
             ];
         });
         });
+
         return $categoryBooks;
         return $categoryBooks;
     }
     }
 
 
-
     private function getBookType(int $book, int $para)
     private function getBookType(int $book, int $para)
     {
     {
 
 
@@ -386,21 +375,23 @@ class TipitakaController extends Controller
         $tags = Tag::whereIn('id', $tagIds)->select('name')->get();
         $tags = Tag::whereIn('id', $tagIds)->select('name')->get();
         foreach ($tags as $key => $tag) {
         foreach ($tags as $key => $tag) {
             if (in_array($tag->name, ['pāḷi', 'aṭṭhakathā', 'ṭīkā'])) {
             if (in_array($tag->name, ['pāḷi', 'aṭṭhakathā', 'ṭīkā'])) {
-                return __('library.' . $tag->name);
+                return __('library.'.$tag->name);
             }
             }
         }
         }
 
 
         return null;
         return null;
     }
     }
+
     private function loadCategories()
     private function loadCategories()
     {
     {
-        $json = file_get_contents(public_path("data/category/default.json"));
+        $json = file_get_contents(public_path('data/category/default.json'));
         $tree = json_decode($json, true);
         $tree = json_decode($json, true);
         $flat = self::flattenWithIds($tree);
         $flat = self::flattenWithIds($tree);
+
         return $flat;
         return $flat;
     }
     }
 
 
-    public static function flattenWithIds(array $tree,  int $parentId = 0, int $level = 1): array
+    public static function flattenWithIds(array $tree, int $parentId = 0, int $level = 1): array
     {
     {
 
 
         $flat = [];
         $flat = [];
@@ -413,7 +404,7 @@ class TipitakaController extends Controller
                 'parent_id' => $parentId,
                 'parent_id' => $parentId,
                 'name' => $node['name'] ?? null,
                 'name' => $node['name'] ?? null,
                 'tag' => $node['tag'] ?? [],
                 'tag' => $node['tag'] ?? [],
-                "description" => "佛教戒律经典",
+                'description' => '佛教戒律经典',
                 'level' => $level,
                 'level' => $level,
             ];
             ];
 
 
@@ -421,7 +412,7 @@ class TipitakaController extends Controller
 
 
             if (isset($node['children']) && is_array($node['children'])) {
             if (isset($node['children']) && is_array($node['children'])) {
                 $childrenLevel = $level + 1;
                 $childrenLevel = $level + 1;
-                $flat = array_merge($flat, self::flattenWithIds($node['children'],  $currentId, $childrenLevel));
+                $flat = array_merge($flat, self::flattenWithIds($node['children'], $currentId, $childrenLevel));
             }
             }
         }
         }
 
 

+ 1 - 0
api-v13/resources/lang/en/library.php

@@ -87,6 +87,7 @@ return [
     'about_anthology' => 'About This Anthology',
     'about_anthology' => 'About This Anthology',
     'anthology_info' => 'Anthology Info',
     'anthology_info' => 'Anthology Info',
     'language' => 'Language',
     'language' => 'Language',
+    'current_channel' => 'Current Channel',
     'created' => 'Created',
     'created' => 'Created',
     'updated' => 'Updated',
     'updated' => 'Updated',
     'related_anthology' => 'Related Anthologies',
     'related_anthology' => 'Related Anthologies',

+ 1 - 0
api-v13/resources/lang/my/library.php

@@ -87,6 +87,7 @@ return [
     'about_anthology' => 'ဤလက်ရွေးစင်စာစုအကြောင်း',
     'about_anthology' => 'ဤလက်ရွေးစင်စာစုအကြောင်း',
     'anthology_info' => 'လက်ရွေးစင်စာစု သတင်းအချက်အလက်',
     'anthology_info' => 'လက်ရွေးစင်စာစု သတင်းအချက်အလက်',
     'language' => 'ဘာသာစကား',
     'language' => 'ဘာသာစကား',
+    'current_channel' => 'လက်ရှိချန်နယ်',
     'created' => 'ဖန်တီးသည်',
     'created' => 'ဖန်တီးသည်',
     'updated' => 'အပ်ဒိတ်လုပ်သည်',
     'updated' => 'အပ်ဒိတ်လုပ်သည်',
     'related_anthology' => 'ဆက်စပ်သော လက်ရွေးစင်စာစုများ',
     'related_anthology' => 'ဆက်စပ်သော လက်ရွေးစင်စာစုများ',

+ 1 - 0
api-v13/resources/lang/si/library.php

@@ -87,6 +87,7 @@ return [
     'about_anthology' => 'මෙම සංග්‍රහය ගැන',
     'about_anthology' => 'මෙම සංග්‍රහය ගැන',
     'anthology_info' => 'සංග්‍රහ තොරතුරු',
     'anthology_info' => 'සංග්‍රහ තොරතුරු',
     'language' => 'භාෂාව',
     'language' => 'භාෂාව',
+    'current_channel' => 'වත්මන් නාලිකාව',
     'created' => 'නිර්මිත',
     'created' => 'නිර්මිත',
     'updated' => 'යාවත්කාලීන',
     'updated' => 'යාවත්කාලීන',
     'related_anthology' => 'සම්බන්ධිත සංග්‍රහ',
     'related_anthology' => 'සම්බන්ධිත සංග්‍රහ',

+ 1 - 0
api-v13/resources/lang/th/library.php

@@ -87,6 +87,7 @@ return [
     'about_anthology' => 'เกี่ยวกับรวมบทความนี้',
     'about_anthology' => 'เกี่ยวกับรวมบทความนี้',
     'anthology_info' => 'ข้อมูลรวมบทความ',
     'anthology_info' => 'ข้อมูลรวมบทความ',
     'language' => 'ภาษา',
     'language' => 'ภาษา',
+    'current_channel' => 'ช่องปัจจุบัน',
     'created' => 'วันที่สร้าง',
     'created' => 'วันที่สร้าง',
     'updated' => 'อัปเดต',
     'updated' => 'อัปเดต',
     'related_anthology' => 'รวมบทความที่เกี่ยวข้อง',
     'related_anthology' => 'รวมบทความที่เกี่ยวข้อง',

+ 2 - 1
api-v13/resources/lang/zh-Hans/library.php

@@ -87,6 +87,7 @@ return [
     'about_anthology' => '关于本文集',
     'about_anthology' => '关于本文集',
     'anthology_info' => '文集信息',
     'anthology_info' => '文集信息',
     'language' => '语言',
     'language' => '语言',
+    'current_channel' => '当前频道',
     'created' => '创建',
     'created' => '创建',
     'updated' => '更新',
     'updated' => '更新',
     'related_anthology' => '相关文集',
     'related_anthology' => '相关文集',
@@ -133,5 +134,5 @@ return [
     'no_toc' => '此书没有目录',
     'no_toc' => '此书没有目录',
     'pāḷi' => '巴利原典',
     'pāḷi' => '巴利原典',
     'aṭṭhakathā' => '义注',
     'aṭṭhakathā' => '义注',
-    'ṭīkā' => '复注'
+    'ṭīkā' => '复注',
 ];
 ];

+ 1 - 0
api-v13/resources/lang/zh-Hant/library.php

@@ -87,6 +87,7 @@ return [
     'about_anthology' => '關於此文集',
     'about_anthology' => '關於此文集',
     'anthology_info' => '文集資訊',
     'anthology_info' => '文集資訊',
     'language' => '語言',
     'language' => '語言',
+    'current_channel' => '目前頻道',
     'created' => '建立時間',
     'created' => '建立時間',
     'updated' => '更新時間',
     'updated' => '更新時間',
     'related_anthology' => '相關文集',
     'related_anthology' => '相關文集',

+ 13 - 2
api-v13/resources/views/library/tipitaka/category.blade.php

@@ -82,6 +82,15 @@
             {{-- 2. 过滤器区 --}}
             {{-- 2. 过滤器区 --}}
             <div class="wiki-card tipitaka-filters">
             <div class="wiki-card tipitaka-filters">
 
 
+                @if($currentChannel)
+                {{-- 当前频道 --}}
+                <div class="tipitaka-filter-row">
+                    <span class="tipitaka-filter-label">{{ __('library.current_channel') }}</span>
+                    <div class="tipitaka-filter-pills">
+                        <span class="tipitaka-pill tipitaka-pill--active">{{ $currentChannel['name'] }}</span>
+                    </div>
+                </div>
+                @else
                 {{-- 类型 --}}
                 {{-- 类型 --}}
                 <div class="tipitaka-filter-row">
                 <div class="tipitaka-filter-row">
                     <span class="tipitaka-filter-label">{{ __('library.type') }}</span>
                     <span class="tipitaka-filter-label">{{ __('library.type') }}</span>
@@ -113,6 +122,7 @@
                         @endforeach
                         @endforeach
                     </div>
                     </div>
                 </div>
                 </div>
+                @endif
 
 
                 {{-- 作者 --}}
                 {{-- 作者 --}}
                 <div class="tipitaka-filter-row" style="display:none">
                 <div class="tipitaka-filter-row" style="display:none">
@@ -132,11 +142,12 @@
                 @php
                 @php
                 $hasFilter = $selected['type'] !== 'all'
                 $hasFilter = $selected['type'] !== 'all'
                 || $selected['lang'] !== 'all'
                 || $selected['lang'] !== 'all'
-                || $selected['author'] !== 'all';
+                || $selected['author'] !== 'all'
+                || $selected['channel'] !== 'all';
                 @endphp
                 @endphp
                 @if($hasFilter)
                 @if($hasFilter)
                 <div class="tipitaka-filter-clear">
                 <div class="tipitaka-filter-clear">
-                    <a href="{{ request()->fullUrlWithQuery(['type' => null, 'lang' => null, 'author' => null, 'page' => null]) }}"
+                    <a href="{{ rtrim(request()->fullUrlWithQuery(['type' => null, 'lang' => null, 'author' => null, 'channel' => null, 'page' => null]), '?') }}"
                         class="tipitaka-clear-btn">
                         class="tipitaka-clear-btn">
                         <i class="ti ti-x"></i> {{ __('library.clear_filters') }}
                         <i class="ti ti-x"></i> {{ __('library.clear_filters') }}
                     </a>
                     </a>