CatPtain commited on
Commit
8c596c7
·
verified ·
1 Parent(s): bdc636e

Upload public.js

Browse files
Files changed (1) hide show
  1. backend/src/routes/public.js +53 -75
backend/src/routes/public.js CHANGED
@@ -624,13 +624,13 @@ router.get('/presentation/:userId/:pptId', async (req, res, next) => {
624
  }
625
  });
626
 
627
- // 新增:直接返回图片的端点 - 自动生成Base64图片
628
  router.get('/direct-image/:userId/:pptId/:slideIndex?', async (req, res, next) => {
629
  try {
630
  const { userId, pptId, slideIndex = 0 } = req.params;
631
- const { format = 'jpeg', quality = 90 } = req.query;
632
 
633
- console.log(`Direct image request: userId=${userId}, pptId=${pptId}, slideIndex=${slideIndex}`);
634
 
635
  // Get PPT data
636
  const fileName = `${pptId}.json`;
@@ -649,92 +649,70 @@ router.get('/direct-image/:userId/:pptId/:slideIndex?', async (req, res, next) =
649
  }
650
 
651
  if (!pptData) {
652
- // 返回404图片而不是HTML
653
- const notFoundSvg = `
654
- <svg width="800" height="450" xmlns="http://www.w3.org/2000/svg">
655
- <rect width="100%" height="100%" fill="#f8f9fa"/>
656
- <text x="400" y="200" text-anchor="middle" font-family="Arial" font-size="24" fill="#6c757d">PPT Not Found</text>
657
- <text x="400" y="250" text-anchor="middle" font-family="Arial" font-size="16" fill="#6c757d">PPT ${pptId} does not exist</text>
658
- </svg>
659
- `;
660
- const svgBuffer = Buffer.from(notFoundSvg);
661
- res.setHeader('Content-Type', 'image/svg+xml');
662
  res.setHeader('Cache-Control', 'no-cache');
663
- return res.send(svgBuffer);
 
664
  }
665
 
666
  const slideIdx = parseInt(slideIndex);
667
  if (slideIdx >= pptData.slides.length || slideIdx < 0) {
668
- // 返回404图片
669
- const invalidSlideSvg = `
670
- <svg width="800" height="450" xmlns="http://www.w3.org/2000/svg">
671
- <rect width="100%" height="100%" fill="#f8f9fa"/>
672
- <text x="400" y="200" text-anchor="middle" font-family="Arial" font-size="24" fill="#6c757d">Invalid Slide</text>
673
- <text x="400" y="250" text-anchor="middle" font-family="Arial" font-size="16" fill="#6c757d">Slide ${slideIndex} not found</text>
674
- </svg>
675
- `;
676
- const svgBuffer = Buffer.from(invalidSlideSvg);
677
- res.setHeader('Content-Type', 'image/svg+xml');
678
  res.setHeader('Cache-Control', 'no-cache');
679
- return res.send(svgBuffer);
 
680
  }
681
 
682
- // 生成PPT页面的SVG图片
 
 
 
 
 
 
683
  const slide = pptData.slides[slideIdx];
684
- const width = pptData.viewportSize || 1000;
685
- const height = Math.ceil(width * (pptData.viewportRatio || 0.5625));
686
-
687
- // 生成SVG内容
688
- const svgContent = generateSlideSVG(slide, pptData, { width, height });
689
-
690
- if (format === 'svg') {
691
- res.setHeader('Content-Type', 'image/svg+xml');
692
- res.setHeader('Cache-Control', 'public, max-age=3600'); // 缓存1小时
693
- res.setHeader('X-Generation-Time', '< 10ms');
694
- return res.send(svgContent);
695
- }
696
-
697
- // 对于其他格式,返回占位图片
698
- const placeholderSvg = `
699
- <svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">
700
- <rect width="100%" height="100%" fill="${slide.background?.color || '#ffffff'}"/>
701
- <g>
702
- ${slide.elements.map(el => {
703
- if (el.type === 'text') {
704
- return `<text x="${el.left + 10}" y="${el.top + (el.fontSize || 16)}"
705
- font-family="Arial" font-size="${el.fontSize || 16}"
706
- fill="${el.defaultColor || el.color || '#000'}">${el.content || ''}</text>`;
707
- }
708
- if (el.type === 'shape') {
709
- return `<rect x="${el.left}" y="${el.top}" width="${el.width}" height="${el.height}"
710
- fill="${el.fill || '#cccccc'}" stroke="${el.outline?.color || 'none'}"/>`;
711
- }
712
- return '';
713
- }).join('')}
714
- </g>
715
- <text x="${width/2}" y="${height-20}" text-anchor="middle" font-family="Arial" font-size="12" fill="#999">
716
- ${pptData.title} - Slide ${slideIdx + 1}
717
- </text>
718
- </svg>
719
- `;
720
-
721
- res.setHeader('Content-Type', 'image/svg+xml');
722
- res.setHeader('Cache-Control', 'public, max-age=3600');
723
  res.setHeader('X-Generation-Time', '< 10ms');
724
- res.send(placeholderSvg);
 
 
 
725
 
726
  } catch (error) {
727
  console.error('Direct image generation failed:', error);
728
 
729
- // 返回错误图片
730
- const errorSvg = `
731
- <svg width="800" height="450" xmlns="http://www.w3.org/2000/svg">
732
- <rect width="100%" height="100%" fill="#fee"/>
733
- <text x="400" y="200" text-anchor="middle" font-family="Arial" font-size="24" fill="#c00">Error</text>
734
- <text x="400" y="250" text-anchor="middle" font-family="Arial" font-size="16" fill="#c00">Failed to generate image</text>
735
- </svg>
736
- `;
737
- res.setHeader('Content-Type', 'image/svg+xml');
 
738
  res.send(errorSvg);
739
  }
740
  });
 
624
  }
625
  });
626
 
627
+ // 新增:直接返回图片的端点 - 返回纯SVG图片,可被其他网站直接引用
628
  router.get('/direct-image/:userId/:pptId/:slideIndex?', async (req, res, next) => {
629
  try {
630
  const { userId, pptId, slideIndex = 0 } = req.params;
631
+ const { format = 'svg', quality = 90, width: requestWidth, height: requestHeight } = req.query;
632
 
633
+ console.log(`Direct image request: userId=${userId}, pptId=${pptId}, slideIndex=${slideIndex}, format=${format}`);
634
 
635
  // Get PPT data
636
  const fileName = `${pptId}.json`;
 
649
  }
650
 
651
  if (!pptData) {
652
+ // 返回404图片SVG
653
+ const notFoundSvg = `<svg width="800" height="450" xmlns="http://www.w3.org/2000/svg">
654
+ <rect width="100%" height="100%" fill="#f8f9fa"/>
655
+ <text x="400" y="200" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" fill="#6c757d">PPT Not Found</text>
656
+ <text x="400" y="250" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6c757d">PPT ${pptId} does not exist</text>
657
+ </svg>`;
658
+
659
+ res.setHeader('Content-Type', 'image/svg+xml; charset=utf-8');
 
 
660
  res.setHeader('Cache-Control', 'no-cache');
661
+ res.setHeader('Access-Control-Allow-Origin', '*'); // 允许跨域引用
662
+ return res.send(notFoundSvg);
663
  }
664
 
665
  const slideIdx = parseInt(slideIndex);
666
  if (slideIdx >= pptData.slides.length || slideIdx < 0) {
667
+ // 返回404幻灯片SVG
668
+ const invalidSlideSvg = `<svg width="800" height="450" xmlns="http://www.w3.org/2000/svg">
669
+ <rect width="100%" height="100%" fill="#f8f9fa"/>
670
+ <text x="400" y="200" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" fill="#6c757d">Invalid Slide</text>
671
+ <text x="400" y="250" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#6c757d">Slide ${slideIndex} not found</text>
672
+ </svg>`;
673
+
674
+ res.setHeader('Content-Type', 'image/svg+xml; charset=utf-8');
 
 
675
  res.setHeader('Cache-Control', 'no-cache');
676
+ res.setHeader('Access-Control-Allow-Origin', '*');
677
+ return res.send(invalidSlideSvg);
678
  }
679
 
680
+ // 计算图片尺寸
681
+ const defaultWidth = pptData.viewportSize || 1000;
682
+ const defaultHeight = Math.ceil(defaultWidth * (pptData.viewportRatio || 0.5625));
683
+ const finalWidth = requestWidth ? parseInt(requestWidth) : defaultWidth;
684
+ const finalHeight = requestHeight ? parseInt(requestHeight) : defaultHeight;
685
+
686
+ // 生成PPT幻灯片的SVG图片
687
  const slide = pptData.slides[slideIdx];
688
+ const svgContent = generateSlideSVG(slide, pptData, {
689
+ width: finalWidth,
690
+ height: finalHeight
691
+ });
692
+
693
+ // 设置正确的响应头,使其可以被其他网站作为图片引用
694
+ res.setHeader('Content-Type', 'image/svg+xml; charset=utf-8');
695
+ res.setHeader('Cache-Control', 'public, max-age=3600'); // 缓存1小时
696
+ res.setHeader('Access-Control-Allow-Origin', '*'); // 允许跨域引用
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
697
  res.setHeader('X-Generation-Time', '< 10ms');
698
+ res.setHeader('X-Content-Source', 'direct-svg-generation');
699
+
700
+ // 直接返回SVG图片内容
701
+ res.send(svgContent);
702
 
703
  } catch (error) {
704
  console.error('Direct image generation failed:', error);
705
 
706
+ // 返回错误图片SVG
707
+ const errorSvg = `<svg width="800" height="450" xmlns="http://www.w3.org/2000/svg">
708
+ <rect width="100%" height="100%" fill="#ffe6e6"/>
709
+ <text x="400" y="200" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" fill="#cc0000">Generation Error</text>
710
+ <text x="400" y="250" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="#cc0000">Failed to generate image: ${error.message}</text>
711
+ </svg>`;
712
+
713
+ res.setHeader('Content-Type', 'image/svg+xml; charset=utf-8');
714
+ res.setHeader('Cache-Control', 'no-cache');
715
+ res.setHeader('Access-Control-Allow-Origin', '*');
716
  res.send(errorSvg);
717
  }
718
  });