view.blade.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <div class="ui-page">
  2. <div class="mx-auto flex max-w-7xl flex-col gap-6 px-4 py-8">
  3. @include('filament.partials.page-header', [
  4. 'kicker' => '教材详情',
  5. 'title' => $this->record->official_title ?? '教材详情',
  6. 'subtitle' => '查看教材信息、目录结构与关联卷子',
  7. 'actions' => new \Illuminate\Support\HtmlString(
  8. ($this->record?->id
  9. ? '<a class="btn btn-primary" href="' . route('filament.admin.resources.textbooks.edit', ['record' => $this->record->id]) . '">编辑教材</a>'
  10. . '<a class="btn btn-outline" href="' . route('filament.admin.resources.textbooks.edit', ['record' => $this->record->id]) . '#cover">上传封面</a>'
  11. : ''
  12. )
  13. . '<a class="btn btn-secondary" href="' . route('filament.admin.pages.textbook-excel-import-page') . '?type=textbook_catalog">导入目录</a>'
  14. ),
  15. ])
  16. <div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
  17. <div class="space-y-6">
  18. <div class="ui-card">
  19. <div class="ui-card-header">
  20. <div class="ui-section-title">教材信息</div>
  21. </div>
  22. <div class="ui-card-body space-y-4">
  23. <div class="flex items-start gap-4">
  24. @php
  25. $cover = $this->record->cover_path ?? null;
  26. $coverUrl = null;
  27. $coverUrls = [];
  28. if ($cover) {
  29. $covers = array_values(array_filter(array_map('trim', explode(',', (string) $cover))));
  30. foreach ($covers as $item) {
  31. $coverUrls[] = \Illuminate\Support\Str::startsWith($item, ['http://', 'https://', '/'])
  32. ? $item
  33. : \Illuminate\Support\Facades\Storage::disk('public')->url($item);
  34. }
  35. $coverUrl = $coverUrls[0] ?? null;
  36. }
  37. @endphp
  38. @if($coverUrl)
  39. <img src="{{ $coverUrl }}" alt="封面" class="h-28 w-20 rounded-lg border border-slate-200 object-cover" />
  40. @else
  41. <div class="flex h-28 w-20 items-center justify-center rounded-lg border border-dashed border-slate-200 bg-slate-50 text-xs text-slate-400">暂无封面</div>
  42. @endif
  43. <div class="space-y-2">
  44. <div class="text-lg font-semibold text-slate-900">{{ $this->record->official_title ?? '未命名教材' }}</div>
  45. <div class="text-sm text-slate-500">系列:{{ $this->record->series_name ?? '未归类系列' }}</div>
  46. <div class="flex flex-wrap gap-2">
  47. <span class="ui-tag">学段:{{ $this->record->stage ?? '未标注' }}</span>
  48. <span class="ui-tag">年级:{{ $this->record->grade ? $this->record->grade . '年级' : '未标注' }}</span>
  49. <span class="ui-tag">学期:{{ $this->record->semester == 1 ? '上学期' : ($this->record->semester == 2 ? '下学期' : '未标注') }}</span>
  50. </div>
  51. </div>
  52. </div>
  53. <div class="grid grid-cols-2 gap-3 text-sm text-slate-600">
  54. <div class="ui-badge-muted">ISBN:{{ $this->record->isbn ?? '未填写' }}</div>
  55. <div class="ui-badge-muted">状态:{{ $this->record->status ?? '未知' }}</div>
  56. <div class="ui-badge-muted">ID:{{ $this->record->id }}</div>
  57. </div>
  58. @if(!empty($coverUrls))
  59. <div>
  60. <div class="mb-2 text-sm font-medium text-slate-700">教材配图({{ count($coverUrls) }})</div>
  61. <div class="grid grid-cols-2 gap-2">
  62. @foreach($coverUrls as $index => $url)
  63. <a href="{{ $url }}" target="_blank" rel="noopener noreferrer" class="group block overflow-hidden rounded-lg border border-slate-200">
  64. <img src="{{ $url }}" alt="教材配图{{ $index + 1 }}" class="h-28 w-full object-cover transition group-hover:scale-[1.02]" />
  65. <div class="border-t border-slate-100 px-2 py-1 text-center text-xs text-slate-500">第 {{ $index + 1 }} 张</div>
  66. </a>
  67. @endforeach
  68. </div>
  69. </div>
  70. @endif
  71. </div>
  72. </div>
  73. <div class="ui-card">
  74. <div class="ui-card-header">
  75. <div>
  76. <div class="ui-section-title">绑定卷子</div>
  77. <div class="ui-subtitle">基于教材系列匹配的最近卷子</div>
  78. </div>
  79. </div>
  80. <div class="ui-card-body">
  81. @if(empty($this->linkedPapers))
  82. @include('filament.partials.empty-state', [
  83. 'title' => '暂无关联卷子',
  84. 'description' => '当前教材系列尚未关联到源卷子。',
  85. ])
  86. @else
  87. <div class="mb-3 text-xs text-slate-500">
  88. 目录未绑定卷子:{{ $this->unlinkedPaperCount }} 套
  89. </div>
  90. <div class="space-y-3">
  91. @foreach($this->linkedPapers as $paper)
  92. <div class="rounded-xl border border-slate-200 px-4 py-3">
  93. <div class="text-sm font-semibold text-slate-900">{{ $paper['title'] }}</div>
  94. <div class="mt-1 flex flex-wrap gap-2 text-xs text-slate-500">
  95. <span class="ui-tag">章节:{{ $paper['chapter'] ?? '未标注' }}</span>
  96. <span class="ui-tag">年级:{{ $paper['grade'] ?? '未标注' }}</span>
  97. <span class="ui-tag">学期:{{ $paper['term'] ?? '未标注' }}</span>
  98. <span class="ui-tag">来源:{{ $paper['source_type'] ?? '未知' }}</span>
  99. </div>
  100. </div>
  101. @endforeach
  102. </div>
  103. @endif
  104. </div>
  105. </div>
  106. </div>
  107. <div class="lg:col-span-2">
  108. <div class="ui-card">
  109. <div class="ui-card-header">
  110. <div>
  111. <div class="ui-section-title">目录结构</div>
  112. <div class="ui-subtitle">教材章节目录树</div>
  113. </div>
  114. <a class="btn btn-outline btn-sm" href="{{ route('filament.admin.resources.textbook-catalogs.index', ['tableFilters[textbook_id][value]' => $this->record->id]) }}">管理目录</a>
  115. </div>
  116. <div class="ui-card-body">
  117. @if(empty($this->catalogTree))
  118. @include('filament.partials.empty-state', [
  119. 'title' => '暂无目录',
  120. 'description' => '请先导入或维护教材目录结构。',
  121. 'action' => new \Illuminate\Support\HtmlString('<a class="btn btn-primary btn-sm" href="' . route('filament.admin.pages.textbook-excel-import-page') . '?type=textbook_catalog">导入目录</a>'),
  122. ])
  123. @else
  124. @include('filament.partials.catalog-tree', ['nodes' => $this->catalogTree, 'coverage' => $this->catalogCoverage])
  125. @endif
  126. </div>
  127. </div>
  128. </div>
  129. </div>
  130. </div>
  131. </div>