Răsfoiți Sursa

知识点讲解功能添加(9成熟),缺少和正式知识点字段关联匹配;
todo:页码的问题需要和谢老师沟通确认

yemeishu 2 săptămâni în urmă
părinte
comite
81d222f34f

+ 17 - 1
app/Http/Controllers/ExamPdfController.php

@@ -1005,12 +1005,28 @@ class ExamPdfController extends Controller
         // 生成日期
         $generateDate = now()->locale('zh_CN')->isoFormat('M月D日');
 
-        // 提取并去重知识点代码
+        // 提取并去重知识点代码(优先 paper_questions.knowledge_point,缺失时回退到题库 kp_code)
         $paperQuestions = \App\Models\PaperQuestion::where('paper_id', $paper_id)->get();
         $kpCodes = [];
         $seen = [];
+
+        $questionBankIds = $paperQuestions
+            ->pluck('question_bank_id')
+            ->filter()
+            ->unique()
+            ->values();
+        $questionKpMap = [];
+        if ($questionBankIds->isNotEmpty()) {
+            $questionKpMap = \App\Models\Question::whereIn('id', $questionBankIds)
+                ->pluck('kp_code', 'id')
+                ->toArray();
+        }
+
         foreach ($paperQuestions as $pq) {
             $kpCode = trim((string) ($pq->knowledge_point ?? ''));
+            if ($kpCode === '' && ! empty($pq->question_bank_id)) {
+                $kpCode = trim((string) ($questionKpMap[$pq->question_bank_id] ?? ''));
+            }
             if ($kpCode === '') {
                 continue;
             }

+ 48 - 7
app/Services/ExamPdfExportService.php

@@ -8,6 +8,7 @@ use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\File;
 use Illuminate\Support\Facades\Http;
 use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Schema;
 use Illuminate\Support\Facades\Storage;
 use Illuminate\Support\Facades\URL;
 use Symfony\Component\Process\Exception\ProcessSignaledException;
@@ -76,13 +77,10 @@ class ExamPdfExportService
      */
     public function generateUnifiedPdf(string $paperId, ?bool $includeKpExplain = null): ?string
     {
-        // 【临时禁用】强制不包含知识点讲解,等待后续修复
-        $includeKpExplain = false;
-
         // 决定是否包含知识点讲解
-        // if ($includeKpExplain === null) {
-        //     $includeKpExplain = config('pdf.include_kp_explain_default', false);
-        // }
+        if ($includeKpExplain === null) {
+            $includeKpExplain = config('pdf.include_kp_explain_default', false);
+        }
 
         Log::info('generateUnifiedPdf 开始(终极优化版本,直接HTML合并生成PDF):', [
             'paper_id' => $paperId,
@@ -348,7 +346,10 @@ class ExamPdfExportService
                         'length' => strlen($html),
                     ]);
 
-                    return $this->ensureUtf8Html($html);
+                    $html = $this->ensureUtf8Html($html);
+                    $html = $this->renderKpExplainMarkdown($html);
+
+                    return $html;
                 }
             }
 
@@ -369,6 +370,26 @@ class ExamPdfExportService
         }
     }
 
+    private function renderKpExplainMarkdown(string $html): string
+    {
+        if (! class_exists(\Michelf\MarkdownExtra::class)) {
+            return $html;
+        }
+
+        $parser = new \Michelf\MarkdownExtra;
+
+        return preg_replace_callback(
+            '/<div class="kp-markdown-source"[^>]*>([\s\S]*?)<\/div>\s*<div class="kp-markdown-container[^"]*"[^>]*><\/div>/i',
+            function ($matches) use ($parser) {
+                $markdown = html_entity_decode(trim($matches[1]), ENT_QUOTES, 'UTF-8');
+                $rendered = $parser->transform($markdown);
+
+                return '<div class="kp-markdown-container kp-markdown-content">'.$rendered.'</div>';
+            },
+            $html
+        );
+    }
+
     /**
      * 【新增】渲染试卷HTML(通过HTTP调用路由)
      */
@@ -2409,6 +2430,10 @@ class ExamPdfExportService
      */
     public function buildExplanation(string $kpCode, string $kpName): string
     {
+        if ($this->shouldUseDefaultExplanations()) {
+            return $this->getDefaultExplanation($kpCode, $kpName);
+        }
+
         try {
             // 从数据库获取知识点讲解
             $kp = \App\Models\KnowledgePoint::where('kp_code', $kpCode)->first();
@@ -2441,6 +2466,13 @@ class ExamPdfExportService
             return $result;
         }
 
+        if ($this->shouldUseDefaultExplanations()) {
+            foreach ($kpCodes as $kpCode) {
+                $result[$kpCode] = $this->getDefaultExplanation($kpCode, $kpCode);
+            }
+            return $result;
+        }
+
         try {
             // 批量获取知识点讲解
             $kps = \App\Models\KnowledgePoint::whereIn('kp_code', $kpCodes)->get()->keyBy('kp_code');
@@ -2514,4 +2546,13 @@ $$
 - 结论:每支笔 3.2 元,每本本子 4.2 元(两者均 $> 0$,符合题意)。
 MARKDOWN;
     }
+
+    private function shouldUseDefaultExplanations(): bool
+    {
+        if (!Schema::hasTable('knowledge_points')) {
+            return true;
+        }
+
+        return !Schema::hasColumn('knowledge_points', 'explanation');
+    }
 }

+ 1 - 1
resources/views/pdf/partials/common-styles.blade.php

@@ -342,7 +342,7 @@
 
     /* ==================== KaTeX数学公式样式 ==================== */
     .katex {
-        font-size: 1.1em !important;
+        font-size: 0.95em !important;
     }
     .katex-display {
         margin: 0.5em 0 !important;

+ 4 - 0
resources/views/pdf/partials/kp-explain-styles.blade.php

@@ -195,6 +195,10 @@
     .kp-markdown th,
     .kp-markdown-content th { background: #f5f5f5; font-weight: bold; }
 
+    /* ========== KaTeX数学公式样式 ========== */
+    .katex { font-size: 0.95em !important; }
+    .katex-display { margin: 0.5em 0 !important; }
+
     /* ========== 打印专用(不分页) ========== */
     @media print {
         .kp-block-content img,