JudgeCardTemplateBuilder.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <?php
  2. namespace App\Support;
  3. class JudgeCardTemplateBuilder
  4. {
  5. private const TOTAL_QUESTIONS = 20;
  6. public function build(): array
  7. {
  8. $template = config('exam.judge_card_template', []);
  9. $page = [
  10. 'width' => (int) data_get($template, 'page.width', 2480),
  11. 'height' => (int) data_get($template, 'page.height', 3508),
  12. 'dpi' => (int) data_get($template, 'page.dpi', 300),
  13. 'margin_top' => (int) data_get($template, 'page.margin_top', 260),
  14. 'margin_right' => (int) data_get($template, 'page.margin_right', 236),
  15. 'margin_bottom' => (int) data_get($template, 'page.margin_bottom', 272),
  16. 'margin_left' => (int) data_get($template, 'page.margin_left', 236),
  17. ];
  18. $box = [
  19. 'width' => (int) data_get($template, 'box.width', 30),
  20. 'height' => (int) data_get($template, 'box.height', 30),
  21. ];
  22. $layout = [
  23. 'start_x' => (int) data_get($template, 'layout.start_x', 522),
  24. 'start_y' => (int) data_get($template, 'layout.start_y', 709),
  25. 'row_height' => (int) data_get($template, 'layout.row_height', 100),
  26. 'col_spacing' => (int) data_get($template, 'layout.col_spacing', 72),
  27. 'header_top_offset' => (int) data_get($template, 'layout.header_top_offset', 0),
  28. 'row_left_x' => (int) data_get($template, 'layout.row_left_x', 244),
  29. 'row_width' => (int) data_get($template, 'layout.row_width', 1992),
  30. 'row_padding_top' => (int) data_get($template, 'layout.row_padding_top', 8),
  31. 'row_padding_bottom' => (int) data_get($template, 'layout.row_padding_bottom', 8),
  32. 'label_x' => (int) data_get($template, 'layout.label_x', 260),
  33. 'label_width' => (int) data_get($template, 'layout.label_width', 180),
  34. 'label_to_box_gap' => (int) data_get($template, 'layout.label_to_box_gap', 16),
  35. ];
  36. $questions = self::TOTAL_QUESTIONS;
  37. $questionBoxCounts = $this->buildQuestionBoxCountsByRule($questions);
  38. return [
  39. 'page' => $page,
  40. 'box' => $box,
  41. 'layout' => $layout,
  42. 'questions' => $questions,
  43. 'question_box_counts' => $questionBoxCounts,
  44. 'mark_rules' => [
  45. 'correct' => array_values((array) data_get($template, 'mark_rules.correct', ['/', '\\'])),
  46. 'wrong' => array_values((array) data_get($template, 'mark_rules.wrong', ['X'])),
  47. 'blank_is_wrong' => (bool) data_get($template, 'mark_rules.blank_is_wrong', true),
  48. ],
  49. 'question_boxes' => $this->buildQuestionBoxes($questions, $questionBoxCounts, $layout, $box),
  50. ];
  51. }
  52. private function buildQuestionBoxCountsByRule(int $questions): array
  53. {
  54. $result = ['default' => 1];
  55. for ($q = 1; $q <= $questions; $q++) {
  56. $count = $this->resolveBoxCountByRule($q);
  57. if ($count !== 1) {
  58. $result[(string) $q] = $count;
  59. }
  60. }
  61. return $result;
  62. }
  63. private function buildQuestionBoxes(int $questions, array $questionBoxCounts, array $layout, array $box): array
  64. {
  65. $result = [];
  66. $defaultCount = (int) ($questionBoxCounts['default'] ?? 1);
  67. for ($q = 1; $q <= $questions; $q++) {
  68. $count = (int) ($questionBoxCounts[(string) $q] ?? $defaultCount);
  69. $boxes = [];
  70. $y = (int) $layout['start_y'] + (($q - 1) * (int) $layout['row_height']);
  71. for ($i = 0; $i < $count; $i++) {
  72. $boxes[] = [
  73. 'box_index' => $i,
  74. 'x' => (int) $layout['start_x'] + ($i * (int) $layout['col_spacing']),
  75. 'y' => $y,
  76. 'width' => (int) $box['width'],
  77. 'height' => (int) $box['height'],
  78. ];
  79. }
  80. $result[] = [
  81. 'question' => $q,
  82. 'box_count' => $count,
  83. 'boxes' => $boxes,
  84. ];
  85. }
  86. return $result;
  87. }
  88. private function resolveBoxCountByRule(int $questionNo): int
  89. {
  90. // 固定规则:17、18题双框,其余单框
  91. return in_array($questionNo, [17, 18], true) ? 2 : 1;
  92. }
  93. }