chengjie 4 months ago
parent
commit
4d3fdd37e7
1 changed files with 131 additions and 34 deletions
  1. 131 34
      src/api/yjbdc/yjbdcController.js

+ 131 - 34
src/api/yjbdc/yjbdcController.js

@@ -375,6 +375,8 @@ export async function GeneratePDF(ctx) {
375 375
         return;
376 376
     }
377 377
 
378
+    const content = params.Content;
379
+
378 380
     // 文章类型映射
379 381
     const ARTICLE_STYLE = {
380 382
         "成长": "Personal Growth",
@@ -398,8 +400,6 @@ export async function GeneratePDF(ctx) {
398 400
         "High school vocabulary size",
399 401
         "College vocabulary size"
400 402
     ];
401
-
402
-    const content = params.Content;
403 403
     
404 404
     try {
405 405
         // 创建新的 PDF 文档 - 使用A4尺寸
@@ -456,10 +456,10 @@ export async function GeneratePDF(ctx) {
456 456
             questions = content.Question;
457 457
         }
458 458
 
459
-        doc.image('./public/images/PDF.png', 0, 0, {
460
-                width: pixelToPt(2100),
461
-                height: pixelToPt(2970)
462
-        });
459
+        // doc.image('./public/images/PDF.png', 0, 0, {
460
+        //         width: pixelToPt(2100),
461
+        //         height: pixelToPt(2970)
462
+        // });
463 463
 
464 464
         // 1. 标题 - 文章类型
465 465
         doc.font(selectFont(ARTICLE_STYLE[content.ArticleStyle] || "Story"))
@@ -556,13 +556,38 @@ export async function GeneratePDF(ctx) {
556 556
                     
557 557
                     // 渲染选项
558 558
                     const options = questions[i].OptionsEnglish || [];
559
-                    options.forEach((opt) => {
560
-                        doc.font('Helvetica')
561
-                           .fontSize(pixelToPt(36))
562
-                           .text(`${opt}`, currentX, optionY);
563
-                        
564
-                        // 更新选项Y坐标,为下一个选项做准备
565
-                        optionY = doc.y + pixelToPt(8);
559
+                    const optionLabels = ['A', 'B', 'C', 'D'];
560
+                    
561
+                    // 设置选项标签宽度和选项总宽度
562
+                    const labelWidth = pixelToPt(40); // 标签(A./B./C./D.)的宽度
563
+                    const totalWidth = pixelToPt(496); // 选项的总宽度
564
+                    const contentWidth = totalWidth - labelWidth; // 选项内容的宽度
565
+                    
566
+                    options.forEach((opt, index) => {
567
+                        if (index < optionLabels.length) {
568
+                            // 提取选项内容,移除可能存在的标签前缀
569
+                            let optionContent = opt.replace(/^[A-D]\.\s*/, '');
570
+                            
571
+                            // 渲染选项标签(A./B./C./D.)
572
+                            doc.font('Helvetica')
573
+                               .fontSize(pixelToPt(36))
574
+                               .text(`${optionLabels[index]}.`, currentX, optionY, {
575
+                                   width: labelWidth,
576
+                                   align: 'left'
577
+                               });
578
+                            
579
+                            // 渲染选项内容,确保折行时与内容第一行对齐
580
+                            doc.font('Helvetica')
581
+                               .fontSize(pixelToPt(36))
582
+                               .text(optionContent, currentX + labelWidth, optionY, {
583
+                                   width: contentWidth,
584
+                                   align: 'left'
585
+                               });
586
+                            
587
+                            // 更新选项Y坐标,为下一个选项做准备
588
+                            // 获取当前位置,确保下一个选项在当前选项完全渲染后的位置
589
+                            optionY = doc.y + pixelToPt(8);
590
+                        }
566 591
                     });
567 592
                     
568 593
                     // 保存该列最后一个选项的Y坐标
@@ -595,13 +620,37 @@ export async function GeneratePDF(ctx) {
595 620
                 
596 621
                 // 渲染选项
597 622
                 const options = questions[1].OptionsEnglish || [];
598
-                options.forEach((opt) => {
599
-                    doc.font('Helvetica')
600
-                       .fontSize(pixelToPt(36))
601
-                       .text(`${opt}`, questionXPositions[1], optionY);
602
-                    
603
-                    // 更新选项Y坐标,为下一个选项做准备
604
-                    optionY = doc.y + pixelToPt(8);
623
+                const optionLabels = ['A', 'B', 'C', 'D'];
624
+                
625
+                // 设置选项标签宽度和选项总宽度
626
+                const labelWidth = pixelToPt(40); // 标签(A./B./C./D.)的宽度
627
+                const totalWidth = pixelToPt(496); // 选项的总宽度
628
+                const contentWidth = totalWidth - labelWidth; // 选项内容的宽度
629
+                
630
+                options.forEach((opt, index) => {
631
+                    if (index < optionLabels.length) {
632
+                        // 提取选项内容,移除可能存在的标签前缀
633
+                        let optionContent = opt.replace(/^[A-D]\.\s*/, '');
634
+                        
635
+                        // 渲染选项标签(A./B./C./D.)
636
+                        doc.font('Helvetica')
637
+                           .fontSize(pixelToPt(36))
638
+                           .text(`${optionLabels[index]}.`, questionXPositions[1], optionY, {
639
+                               width: labelWidth,
640
+                               align: 'left'
641
+                           });
642
+                        
643
+                        // 渲染选项内容,确保折行时与内容第一行对齐
644
+                        doc.font('Helvetica')
645
+                           .fontSize(pixelToPt(36))
646
+                           .text(optionContent, questionXPositions[1] + labelWidth, optionY, {
647
+                               width: contentWidth,
648
+                               align: 'left'
649
+                           });
650
+                        
651
+                        // 更新选项Y坐标,为下一个选项做准备
652
+                        optionY = doc.y + pixelToPt(8);
653
+                    }
605 654
                 });
606 655
             }
607 656
             
@@ -625,13 +674,37 @@ export async function GeneratePDF(ctx) {
625 674
                 
626 675
                 // 渲染选项
627 676
                 const options = questions[3].OptionsEnglish || [];
628
-                options.forEach((opt) => {
629
-                    doc.font('Helvetica')
630
-                       .fontSize(pixelToPt(36))
631
-                       .text(`${opt}`, questionXPositions[3], optionY);
632
-                    
633
-                    // 更新选项Y坐标,为下一个选项做准备
634
-                    optionY = doc.y + pixelToPt(8);
677
+                const optionLabels = ['A', 'B', 'C', 'D'];
678
+                
679
+                // 设置选项标签宽度和选项总宽度
680
+                const labelWidth = pixelToPt(40); // 标签(A./B./C./D.)的宽度
681
+                const totalWidth = pixelToPt(496); // 选项的总宽度
682
+                const contentWidth = totalWidth - labelWidth; // 选项内容的宽度
683
+                
684
+                options.forEach((opt, index) => {
685
+                    if (index < optionLabels.length) {
686
+                        // 提取选项内容,移除可能存在的标签前缀
687
+                        let optionContent = opt.replace(/^[A-D]\.\s*/, '');
688
+                        
689
+                        // 渲染选项标签(A./B./C./D.)
690
+                        doc.font('Helvetica')
691
+                           .fontSize(pixelToPt(36))
692
+                           .text(`${optionLabels[index]}.`, questionXPositions[3], optionY, {
693
+                               width: labelWidth,
694
+                               align: 'left'
695
+                           });
696
+                        
697
+                        // 渲染选项内容,确保折行时与内容第一行对齐
698
+                        doc.font('Helvetica')
699
+                           .fontSize(pixelToPt(36))
700
+                           .text(optionContent, questionXPositions[3] + labelWidth, optionY, {
701
+                               width: contentWidth,
702
+                               align: 'left'
703
+                           });
704
+                        
705
+                        // 更新选项Y坐标,为下一个选项做准备
706
+                        optionY = doc.y + pixelToPt(8);
707
+                    }
635 708
                 });
636 709
             }
637 710
             
@@ -654,13 +727,37 @@ export async function GeneratePDF(ctx) {
654 727
                 
655 728
                 // 渲染选项
656 729
                 const options = questions[4].OptionsEnglish || [];
657
-                options.forEach((opt) => {
658
-                    doc.font('Helvetica')
659
-                       .fontSize(pixelToPt(36))
660
-                       .text(`${opt}`, currentX, optionY);
661
-                    
662
-                    // 更新选项Y坐标,为下一个选项做准备
663
-                    optionY = doc.y + pixelToPt(8);
730
+                const optionLabels = ['A', 'B', 'C', 'D'];
731
+                
732
+                // 设置选项标签宽度和选项总宽度
733
+                const labelWidth = pixelToPt(40); // 标签(A./B./C./D.)的宽度
734
+                const totalWidth = pixelToPt(496); // 选项的总宽度
735
+                const contentWidth = totalWidth - labelWidth; // 选项内容的宽度
736
+                
737
+                options.forEach((opt, index) => {
738
+                    if (index < optionLabels.length) {
739
+                        // 提取选项内容,移除可能存在的标签前缀
740
+                        let optionContent = opt.replace(/^[A-D]\.\s*/, '');
741
+                        
742
+                        // 渲染选项标签(A./B./C./D.)
743
+                        doc.font('Helvetica')
744
+                           .fontSize(pixelToPt(36))
745
+                           .text(`${optionLabels[index]}.`, currentX, optionY, {
746
+                               width: labelWidth,
747
+                               align: 'left'
748
+                           });
749
+                        
750
+                        // 渲染选项内容,确保折行时与内容第一行对齐
751
+                        doc.font('Helvetica')
752
+                           .fontSize(pixelToPt(36))
753
+                           .text(optionContent, currentX + labelWidth, optionY, {
754
+                               width: contentWidth,
755
+                               align: 'left'
756
+                           });
757
+                        
758
+                        // 更新选项Y坐标,为下一个选项做准备
759
+                        optionY = doc.y + pixelToPt(8);
760
+                    }
664 761
                 });
665 762
             }
666 763
         }