QuestionPreviewTool.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <?php
  2. namespace App\Livewire;
  3. use App\Services\ExamPdfExportService;
  4. use Illuminate\Support\Facades\Log;
  5. use Illuminate\Support\Str;
  6. use Livewire\Component;
  7. /**
  8. * 题目预览验证工具
  9. * 用于验证题目在网页和PDF中的显示效果
  10. */
  11. class QuestionPreviewTool extends Component
  12. {
  13. // 表单输入
  14. public string $stem = '';
  15. public string $optionA = '';
  16. public string $optionB = '';
  17. public string $optionC = '';
  18. public string $optionD = '';
  19. public string $answer = '';
  20. public string $solution = '';
  21. // 预览状态
  22. public bool $showWebPreview = false;
  23. public bool $showPdfPreview = false;
  24. public ?string $pdfUrl = null;
  25. public ?string $pdfError = null;
  26. /**
  27. * 触发网页预览
  28. */
  29. public function previewWeb(): void
  30. {
  31. $this->showWebPreview = true;
  32. $this->dispatch('render-math');
  33. }
  34. /**
  35. * 触发 PDF 预览
  36. */
  37. public function previewPdf(): void
  38. {
  39. $this->pdfError = null;
  40. $this->pdfUrl = null;
  41. try {
  42. // 构建题目数据
  43. $questionData = $this->buildQuestionData();
  44. // 调用 PDF 生成服务
  45. $pdfService = app(ExamPdfExportService::class);
  46. $result = $pdfService->generatePreviewPdf($questionData);
  47. if ($result && isset($result['url'])) {
  48. $this->pdfUrl = $result['url'];
  49. $this->showPdfPreview = true;
  50. } else {
  51. $this->pdfError = 'PDF 生成失败,请检查输入内容';
  52. }
  53. } catch (\Exception $e) {
  54. Log::error('QuestionPreviewTool: PDF生成失败', [
  55. 'error' => $e->getMessage(),
  56. 'trace' => $e->getTraceAsString(),
  57. ]);
  58. $this->pdfError = 'PDF 生成出错: ' . $e->getMessage();
  59. }
  60. }
  61. /**
  62. * 同时预览网页和 PDF
  63. */
  64. public function previewBoth(): void
  65. {
  66. $this->previewWeb();
  67. $this->previewPdf();
  68. }
  69. /**
  70. * 清空表单
  71. */
  72. public function clearForm(): void
  73. {
  74. $this->stem = '';
  75. $this->optionA = '';
  76. $this->optionB = '';
  77. $this->optionC = '';
  78. $this->optionD = '';
  79. $this->answer = '';
  80. $this->solution = '';
  81. $this->showWebPreview = false;
  82. $this->showPdfPreview = false;
  83. $this->pdfUrl = null;
  84. $this->pdfError = null;
  85. }
  86. /**
  87. * 构建题目数据结构
  88. */
  89. private function buildQuestionData(): array
  90. {
  91. $hasOptions = !empty($this->optionA) || !empty($this->optionB) ||
  92. !empty($this->optionC) || !empty($this->optionD);
  93. $options = null;
  94. $questionType = 'fill'; // 默认填空题
  95. if ($hasOptions) {
  96. $questionType = 'choice';
  97. $options = [];
  98. if (!empty($this->optionA)) $options['A'] = $this->optionA;
  99. if (!empty($this->optionB)) $options['B'] = $this->optionB;
  100. if (!empty($this->optionC)) $options['C'] = $this->optionC;
  101. if (!empty($this->optionD)) $options['D'] = $this->optionD;
  102. }
  103. return [
  104. 'stem' => $this->stem,
  105. 'options' => $options,
  106. 'answer' => $this->answer,
  107. 'solution' => $this->solution,
  108. 'question_type' => $questionType,
  109. ];
  110. }
  111. /**
  112. * 获取用于网页预览的数据
  113. */
  114. public function getPreviewDataProperty(): array
  115. {
  116. return $this->buildQuestionData();
  117. }
  118. public function render()
  119. {
  120. return view('livewire.question-preview-tool')
  121. ->layout('layouts.preview-tool');
  122. }
  123. }