JudgeCardTemplateBuilder.php 4.2 KB

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