lsc 3 dagar sedan
förälder
incheckning
b7fe6a7617
1 ändrade filer med 27 tillägg och 85 borttagningar
  1. 27 85
      src/views/Student/index.vue

+ 27 - 85
src/views/Student/index.vue

@@ -1101,87 +1101,58 @@ const handleHomeworkSubmit = async () => {
           // 尝试使用html2canvas,对iframe支持更好
           let imageData: string
           const screenSlides = document.querySelectorAll('.viewer-canvas .screen-slide')
-          let iframeElement: HTMLElement | null = null
+          let iframeElement: HTMLIFrameElement | null = null
+          let iframeBody: HTMLElement | null = null
+
+          // 获取iframe元素
           if (
             screenSlides &&
             screenSlides[slideIndex.value] &&
-            screenSlides[slideIndex.value].querySelector('iframe') &&
-            (screenSlides[slideIndex.value].querySelector('iframe') as HTMLIFrameElement).contentWindow &&
-            (screenSlides[slideIndex.value].querySelector('iframe') as HTMLIFrameElement).contentWindow!.document &&
-            (screenSlides[slideIndex.value].querySelector('iframe') as HTMLIFrameElement).contentWindow!.document.body
+            screenSlides[slideIndex.value].querySelector('iframe')
           ) {
-            iframeElement = (screenSlides[slideIndex.value].querySelector('iframe') as HTMLIFrameElement).contentWindow!.document.body as HTMLElement
+            iframeElement = screenSlides[slideIndex.value].querySelector('iframe') as HTMLIFrameElement
+          }
+          else {
+            throw new Error('未能获取到iframe元素,无法截图')
+          }
+
+          // 获取iframe内部的body元素(同源)
+          if (
+            iframeElement.contentWindow &&
+            iframeElement.contentWindow.document &&
+            iframeElement.contentWindow.document.body
+          ) {
+            iframeBody = iframeElement.contentWindow.document.body as HTMLElement
           }
           else {
             throw new Error('未能获取到iframe的body元素,无法截图')
           }
 
           try {
-            // 方案1:使用html2canvas的iframe特殊处理
+            // 直接对iframe内部的body进行截图
             const html2canvas = await import('html2canvas')
-            const canvas = await html2canvas.default(iframeElement, {
+            const canvas = await html2canvas.default(iframeBody, {
               useCORS: true,
               allowTaint: true,
               scale: 1,
               backgroundColor: '#ffffff',
               logging: false,
-              // 关键配置:处理iframe内容
               foreignObjectRendering: true,
-              removeContainer: true,
-              // 特殊处理iframe
-              onclone: (clonedDoc, element) => {
-                // 在克隆的文档中处理iframe
-                const clonedIframes = clonedDoc.querySelectorAll('iframe')
-                clonedIframes.forEach((iframe) => {
-                  const src = iframe.getAttribute('src')
-                  if (src) {
-                    // 创建一个包含iframe信息的占位符
-                    const placeholder = clonedDoc.createElement('div')
-                    placeholder.style.width = iframe.style.width || iframe.getAttribute('width') || '100%'
-                    placeholder.style.height = iframe.style.height || iframe.getAttribute('height') || '300px'
-                    placeholder.style.backgroundColor = '#f8f9fa'
-                    placeholder.style.border = '2px solid #dee2e6'
-                    placeholder.style.borderRadius = '8px'
-                    placeholder.style.display = 'flex'
-                    placeholder.style.flexDirection = 'column'
-                    placeholder.style.alignItems = 'center'
-                    placeholder.style.justifyContent = 'center'
-                    placeholder.style.padding = '20px'
-                    placeholder.style.fontFamily = 'Arial, sans-serif'
-                    
-                    // 创建iframe占位符内容
-                    placeholder.innerHTML = `
-                      <div style="font-size: 24px; margin-bottom: 10px;">🌐</div>
-                      <div style="font-size: 16px; font-weight: bold; color: #495057; margin-bottom: 8px;">iframe内容</div>
-                      <div style="font-size: 12px; color: #6c757d; text-align: center; word-break: break-all; max-width: 100%;">
-                        ${src.length > 60 ? src.substring(0, 60) + '...' : src}
-                      </div>
-                      <div style="font-size: 10px; color: #adb5bd; margin-top: 8px;">
-                        (跨域限制,无法截图内部内容)
-                      </div>
-                    `
-                    
-                    // 替换iframe
-                    iframe.parentNode?.replaceChild(placeholder, iframe)
-                  }
-                })
-              }
+              removeContainer: true
             })
             imageData = canvas.toDataURL('image/png', 0.95)
-            console.log('使用html2canvas iframe特殊处理截图成功')
+            console.log('成功截图iframe内部内容')
           }
           catch (html2canvasError) {
-            console.log('html2canvas iframe处理失败,尝试html-to-image:', html2canvasError)
+            console.log('html2canvas失败,尝试html-to-image:', html2canvasError)
             
             try {
-              // 方案2:使用html-to-image
+              // 回退到html-to-image
               const { toPng } = await import('html-to-image')
-              imageData = await toPng(iframeElement, {
+              imageData = await toPng(iframeBody, {
                 quality: 0.95,
                 backgroundColor: '#ffffff',
-                // html-to-image的iframe处理
                 filter: (node) => {
-                  // 过滤掉可能引起问题的元素
                   if (node.tagName === 'SCRIPT' || node.tagName === 'STYLE') {
                     return false
                   }
@@ -1193,11 +1164,10 @@ const handleHomeworkSubmit = async () => {
             catch (htmlToImageError) {
               console.log('html-to-image也失败了,使用canvas绘制方案:', htmlToImageError)
               
-              // 方案3:使用canvas直接绘制iframe占位符
+              // 最后的备用方案:使用canvas绘制
               const canvas = document.createElement('canvas')
               const ctx = canvas.getContext('2d')
               if (ctx) {
-                // 设置canvas尺寸
                 canvas.width = iframeElement.offsetWidth || 800
                 canvas.height = iframeElement.offsetHeight || 600
                 
@@ -1241,7 +1211,7 @@ const handleHomeworkSubmit = async () => {
                 // 绘制提示信息
                 ctx.font = '12px Arial'
                 ctx.fillStyle = '#adb5bd'
-                ctx.fillText('(跨域限制,无法截图内部内容)', canvas.width / 2, canvas.height / 2 + 80)
+                ctx.fillText('(截图失败)', canvas.width / 2, canvas.height / 2 + 80)
                 
                 // 绘制装饰性元素
                 ctx.strokeStyle = '#dee2e6'
@@ -1257,34 +1227,6 @@ const handleHomeworkSubmit = async () => {
                 throw new Error('无法创建canvas上下文')
               }
             }
-
-            // 将base64字符串转换为File对象
-            const base64ToFile = (base64String: string, filename: string): File => {
-              const arr = base64String.split(',')
-              const mime = arr[0].match(/:(.*?);/)?.[1] || 'image/png'
-              const bstr = atob(arr[1])
-              let n = bstr.length
-              const u8arr = new Uint8Array(n)
-              while (n--) {
-                u8arr[n] = bstr.charCodeAt(n)
-              }
-              return new File([u8arr], filename, { type: mime })
-            }
-          
-            const imageFile = base64ToFile(imageData, `screenshot_${Date.now()}.png`)
-            const imageUrl = await uploadFile(imageFile)
-            // 提交截图
-            await submitWork(slideIndex.value, '73', imageUrl, '1') // 73表示截图工具,21表示图片类型
-            message.success('页面截图提交成功')
-            hasSubmitWork = true
-          
-            // 发送作业提交成功的socket消息
-            sendMessage({
-              type: 'homework_submitted',
-              courseid: props.courseid,
-              slideIndex: slideIndex.value,
-              userid: props.userid
-            })
           }
         }
         catch (error) {