|
|
@@ -0,0 +1,62 @@
|
|
|
+@php
|
|
|
+ // 判题卡项目:保留题号与题目对应方框数(用于OCR锚点+判卷标记)
|
|
|
+ $scanSheetItems = [];
|
|
|
+ $countBlanks = function ($text) {
|
|
|
+ $text = (string)$text;
|
|
|
+ // 与判卷正文保持一致:下划线、中文空括号、英文空括号
|
|
|
+ $count = 0;
|
|
|
+ $count += preg_match_all('/_{2,}/u', $text, $m);
|
|
|
+ $count += preg_match_all('/(\s*)/u', $text, $m);
|
|
|
+ $count += preg_match_all('/\(\s*\)/', $text, $m);
|
|
|
+ return max(1, $count);
|
|
|
+ };
|
|
|
+ $countSteps = function ($text) {
|
|
|
+ $text = (string)$text;
|
|
|
+ // 与判卷正文保持一致:支持“步骤1”与“第1步”两种写法
|
|
|
+ $count = preg_match_all('/(步骤\s*\d+|第\s*\d+\s*步)/u', $text, $m);
|
|
|
+ return max(1, $count);
|
|
|
+ };
|
|
|
+
|
|
|
+ foreach (($questions['choice'] ?? []) as $q) {
|
|
|
+ $scanSheetItems[] = ['no' => (int)($q->question_number ?? 0), 'box_count' => 1];
|
|
|
+ }
|
|
|
+ foreach (($questions['fill'] ?? []) as $q) {
|
|
|
+ $scanSheetItems[] = ['no' => (int)($q->question_number ?? 0), 'box_count' => $countBlanks($q->content ?? '')];
|
|
|
+ }
|
|
|
+ foreach (($questions['answer'] ?? []) as $q) {
|
|
|
+ $scanSheetItems[] = ['no' => (int)($q->question_number ?? 0), 'box_count' => $countSteps($q->solution ?? '')];
|
|
|
+ }
|
|
|
+
|
|
|
+ usort($scanSheetItems, function ($a, $b) {
|
|
|
+ return ($a['no'] <=> $b['no']);
|
|
|
+ });
|
|
|
+ // 每页容量不是上限20,而是保证至少可容纳20题,并尽量提高单页承载
|
|
|
+ $scanSheetPerPage = 24;
|
|
|
+ $scanSheetPages = array_chunk($scanSheetItems, $scanSheetPerPage);
|
|
|
+@endphp
|
|
|
+@foreach($scanSheetPages as $pageIndex => $scanSheetPageItems)
|
|
|
+ <div class="page scan-sheet-page" style="page-break-before: always; break-before: page; width:100%; max-width:100%; margin:0 auto; padding:0 8px; box-sizing:border-box;">
|
|
|
+ <div class="scan-sheet-header" style="text-align:center;margin-bottom:1.5rem;border-bottom:2px solid #000;padding-bottom:1rem;">
|
|
|
+ <div style="font-size:22px;font-weight:bold;">判题卡</div>
|
|
|
+ <div style="display:flex;justify-content:space-between;font-size:14px;margin-top:8px;">
|
|
|
+ <span>老师:{{ $teacher['name'] ?? '________' }}</span>
|
|
|
+ <span>年级:@formatGrade($student['grade'] ?? '________')</span>
|
|
|
+ <span>姓名:{{ $student['name'] ?? '________' }}</span>
|
|
|
+ <span>得分:________</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="scan-sheet-hint" style="font-size:13px;color:#444;margin-bottom:10px;line-height:1.5;">提示:请根据答案和解析进行批改,在回答正确的 □ 前划 / ,在回答错误的 □ 前打 X 或置空</div>
|
|
|
+ <div class="scan-sheet-list" style="display:grid;grid-template-columns:minmax(0,1fr);gap:4px;width:100%;box-sizing:border-box;">
|
|
|
+ @foreach($scanSheetPageItems as $scanItem)
|
|
|
+ <div class="scan-sheet-item" style="border:1px solid #b5b5b5;border-radius:4px;padding:4px 8px;min-height:28px;display:grid;grid-template-columns:auto 1fr;align-items:center;column-gap:8px;font-size:13px;line-height:1.2;page-break-inside:avoid;break-inside:avoid;width:100%;box-sizing:border-box;">
|
|
|
+ <span class="scan-sheet-no" style="font-weight:700;text-align:center;min-width:58px;">题目 {{ $scanItem['no'] > 0 ? $scanItem['no'] : ($pageIndex * $scanSheetPerPage + $loop->iteration) }}.</span>
|
|
|
+ <span class="scan-sheet-marks" style="display:flex;align-items:center;gap:4px 6px;justify-content:flex-start;flex-wrap:wrap;max-width:100%;">
|
|
|
+ @for($i = 0; $i < max(1, (int)($scanItem['box_count'] ?? 1)); $i++)
|
|
|
+ <span class="scan-grade-box" style="width:17px;height:17px;border:1px solid #333;display:inline-block;vertical-align:middle;box-sizing:border-box;"></span>
|
|
|
+ @endfor
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ @endforeach
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+@endforeach
|