exam-history-simple.blade.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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' => '卷子历史记录',
  6. 'subtitle' => '查看生成卷子、导出与编辑配置',
  7. 'actions' => new \Illuminate\Support\HtmlString(
  8. '<a class="btn btn-primary" href="' . url('/admin/intelligent-exam-generation') . '">新建卷子</a>'
  9. . view('filament.partials.density-toggle')->render()
  10. ),
  11. ])
  12. @php
  13. $total = \App\Models\Paper::count();
  14. $draft = \App\Models\Paper::where('status', 'draft')->count();
  15. $completed = \App\Models\Paper::where('status', 'completed')->count();
  16. $graded = \App\Models\Paper::where('status', 'graded')->count();
  17. @endphp
  18. <div class="grid grid-cols-1 gap-4 md:grid-cols-4">
  19. <div class="ui-stat">
  20. <div class="ui-stat-label">总卷数</div>
  21. <div class="ui-stat-value">{{ $total }}</div>
  22. </div>
  23. <div class="ui-stat">
  24. <div class="ui-stat-label">草稿</div>
  25. <div class="ui-stat-value text-amber-600">{{ $draft }}</div>
  26. </div>
  27. <div class="ui-stat">
  28. <div class="ui-stat-label">已完成</div>
  29. <div class="ui-stat-value text-emerald-600">{{ $completed }}</div>
  30. </div>
  31. <div class="ui-stat">
  32. <div class="ui-stat-label">已评分</div>
  33. <div class="ui-stat-value text-blue-600">{{ $graded }}</div>
  34. </div>
  35. </div>
  36. <div class="ui-filter-bar">
  37. <div class="grid grid-cols-1 gap-4 md:grid-cols-4">
  38. <input
  39. type="text"
  40. wire:model.live="search"
  41. placeholder="搜索试卷名称..."
  42. class="input input-bordered w-full"
  43. />
  44. <select wire:model.live="statusFilter" class="select select-bordered w-full">
  45. <option value="">-- 全部状态 --</option>
  46. <option value="draft">草稿</option>
  47. <option value="completed">已完成</option>
  48. <option value="graded">已评分</option>
  49. </select>
  50. <select wire:model.live="difficultyFilter" class="select select-bordered w-full">
  51. <option value="">-- 全部难度 --</option>
  52. <option value="基础">基础</option>
  53. <option value="进阶">进阶</option>
  54. <option value="竞赛">竞赛</option>
  55. </select>
  56. <button wire:click="$refresh" type="button" class="btn btn-secondary">重置</button>
  57. </div>
  58. </div>
  59. <div class="ui-card">
  60. <div class="ui-card-header">
  61. <div>
  62. <div class="ui-section-title">卷子列表</div>
  63. <div class="ui-subtitle">卷名、状态、题量与操作入口</div>
  64. </div>
  65. <div class="ui-badge-muted">支持批量查看</div>
  66. </div>
  67. <div class="ui-card-body overflow-x-auto">
  68. <table class="table w-full">
  69. <thead class="ui-table-head">
  70. <tr>
  71. <th>试卷名称</th>
  72. <th>状态</th>
  73. <th>难度</th>
  74. <th>题目/总分</th>
  75. <th>创建时间</th>
  76. <th class="text-right">操作</th>
  77. </tr>
  78. </thead>
  79. <tbody>
  80. @forelse($this->exams()['data'] as $exam)
  81. <tr class="hover">
  82. <td>
  83. <div class="font-semibold text-slate-900">{{ $exam['paper_name'] }}</div>
  84. <div class="text-xs text-slate-400">{{ $exam['id'] }}</div>
  85. </td>
  86. <td>
  87. <span class="badge badge-{{ $this->getStatusColor($exam['status']) }} badge-sm">
  88. {{ $this->getStatusLabel($exam['status']) }}
  89. </span>
  90. </td>
  91. <td>
  92. <span class="badge badge-{{ $this->getDifficultyColor($exam['difficulty_category']) }} badge-sm">
  93. {{ $exam['difficulty_category'] }}
  94. </span>
  95. </td>
  96. <td>
  97. <div class="text-sm">{{ $exam['question_count'] }} 题</div>
  98. <div class="text-xs text-slate-400">{{ $exam['total_score'] }} 分</div>
  99. </td>
  100. <td class="text-sm">
  101. {{ \Carbon\Carbon::parse($exam['created_at'])->format('Y-m-d H:i') }}
  102. </td>
  103. <td class="text-right">
  104. <div class="inline-flex items-center gap-2">
  105. <a href="{{ url('/admin/exam-detail?paperId=' . $exam['id']) }}" class="btn btn-ghost btn-xs">查看</a>
  106. <button wire:click.stop="exportPdf('{{ $exam['id'] }}')" class="btn btn-outline btn-xs">导出</button>
  107. <div class="dropdown dropdown-end">
  108. <label tabindex="0" class="btn btn-ghost btn-xs">更多</label>
  109. <ul tabindex="0" class="dropdown-content z-[1] menu rounded-box w-32 bg-base-100 p-2 shadow">
  110. <li><button wire:click.stop="duplicateExam({{ json_encode($exam) }})">复制配置</button></li>
  111. <li><button wire:click.stop="startEditExam('{{ $exam['id'] }}')">编辑</button></li>
  112. <li><button class="text-error" wire:click.stop="deleteExam('{{ $exam['id'] }}')" wire:confirm="确定要删除这份试卷吗?此操作不可恢复!">删除</button></li>
  113. </ul>
  114. </div>
  115. </div>
  116. </td>
  117. </tr>
  118. @empty
  119. <tr>
  120. <td colspan="6" class="py-10">
  121. @include('filament.partials.empty-state', [
  122. 'title' => '暂无试卷记录',
  123. 'description' => '请先生成卷子以便管理。',
  124. 'action' => new \Illuminate\Support\HtmlString('<a class="btn btn-primary btn-sm" href="' . url('/admin/intelligent-exam-generation') . '">去出卷</a>'),
  125. ])
  126. </td>
  127. </tr>
  128. @endforelse
  129. </tbody>
  130. </table>
  131. </div>
  132. <div class="border-t border-slate-200 px-4 py-3">
  133. <div class="flex items-center justify-between">
  134. <div class="text-sm text-slate-500">共 {{ $this->meta()['total'] }} 条记录</div>
  135. <div class="join">
  136. <button class="join-item btn btn-sm" wire:click="$set('currentPage', {{ max(1, $this->currentPage - 1) }})" {{ $this->currentPage <= 1 ? 'disabled' : '' }}>«</button>
  137. <button class="join-item btn btn-sm">第 {{ $this->currentPage }} 页</button>
  138. <button class="join-item btn btn-sm" wire:click="$set('currentPage', {{ $this->currentPage + 1 }})" {{ $this->currentPage >= $this->meta()['total_pages'] ? 'disabled' : '' }}>»</button>
  139. </div>
  140. </div>
  141. </div>
  142. </div>
  143. </div>
  144. @if($editingExamId)
  145. <div class="modal modal-open">
  146. <div class="modal-box">
  147. <h3 class="text-lg font-semibold text-slate-900">编辑试卷</h3>
  148. <div class="mt-4 space-y-4">
  149. <div class="form-control">
  150. <label class="label">
  151. <span class="label-text">试卷名称</span>
  152. </label>
  153. <input type="text" wire:model="editForm.paper_name" class="input input-bordered" placeholder="请输入试卷名称" />
  154. </div>
  155. <div class="form-control">
  156. <label class="label">
  157. <span class="label-text">难度分类</span>
  158. </label>
  159. <select wire:model="editForm.difficulty_category" class="select select-bordered">
  160. <option value="">-- 请选择难度 --</option>
  161. <option value="基础">基础</option>
  162. <option value="进阶">进阶</option>
  163. <option value="竞赛">竞赛</option>
  164. </select>
  165. </div>
  166. <div class="form-control">
  167. <label class="label">
  168. <span class="label-text">状态</span>
  169. </label>
  170. <select wire:model="editForm.status" class="select select-bordered">
  171. <option value="">-- 请选择状态 --</option>
  172. <option value="draft">草稿</option>
  173. <option value="completed">已完成</option>
  174. <option value="graded">已评分</option>
  175. </select>
  176. </div>
  177. </div>
  178. <div class="modal-action">
  179. <button wire:click="cancelEdit" class="btn btn-ghost">取消</button>
  180. <button wire:click="saveExamEdit" class="btn btn-primary">保存</button>
  181. </div>
  182. </div>
  183. </div>
  184. @endif
  185. @include('filament.partials.loading-overlay')
  186. </div>