lsc 2 днів тому
батько
коміт
76dccced71
2 змінених файлів з 177 додано та 101 видалено
  1. 33 8
      src/services/course.ts
  2. 144 93
      src/views/Student/index.vue

+ 33 - 8
src/services/course.ts

@@ -1,14 +1,39 @@
 import axios from './config'
 
-// export const SERVER_URL = 'http://localhost:5000'
 export const API_URL = 'https://pbl.cocorobo.cn/api/pbl/'
 
+/**
+ * 获取课程详情
+ * @param courseId 课程ID
+ * @returns Promise<any>
+ */
+export const getCourseDetail = (courseId: string): Promise<any> => {
+  return axios.get(`${API_URL}selectCourseDetail3`, {
+    params: { courseId },
+  })
+}
+
+/**
+ * 提交作业接口
+ * @param params 参数对象
+ * @returns Promise<any>
+ */
+export interface SubmitWorkParams {
+  uid: string
+  cid: string
+  stage: string
+  task: string
+  tool: string
+  atool: string
+  content: string
+  type: string
+}
+
+export const submitWork = (params: SubmitWorkParams): Promise<any> => {
+  return axios.post(`${API_URL}addCourseWorks_workPage`, [params])
+}
+
 export default {
-  getCourseDetail(courseId: string): Promise<any> {
-    return axios.get(`${API_URL}selectCourseDetail3`, {
-      params: {
-        courseId,
-      },
-    })
-  },
+  getCourseDetail,
+  submitWork,
 }

+ 144 - 93
src/views/Student/index.vue

@@ -374,63 +374,86 @@ const processIframeLinks = () => {
     console.log('开始处理iframe链接')
     console.log('当前props:', { courseid: props.courseid, userid: props.userid })
 
-    // 获取所有iframe元素
-    const iframes = document.querySelectorAll('.viewer-canvas iframe')
-    console.log('找到iframe元素数量:', iframes.length)
+    // 从slides数据中查找包含iframe的元素
+    let hasIframe = false
+    const updatedSlides = slides.value.map((slide, slideIndex) => {
+      if (slide.elements && slide.elements.length > 0) {
+        const updatedElements = slide.elements.map(element => {
+          // 检查是否是iframe元素
+          if (element.type === ElementTypes.FRAME && element.url) {
+            const iframeSrc = element.url
+            
+            if (iframeSrc.includes('workPage')) {
+              hasIframe = true
+              console.log(`处理幻灯片 ${slideIndex + 1} 中的iframe链接:`, iframeSrc)
 
-    if (iframes.length === 0) {
-      return
-    }
+              try {
+                // 解析URL,处理hash部分
+                let baseUrl = iframeSrc
+                let hashPart = ''
+
+                // 分离base URL和hash部分
+                if (iframeSrc.includes('#')) {
+                  const parts = iframeSrc.split('#')
+                  baseUrl = parts[0]
+                  hashPart = parts[1]
+                }
 
-    // 遍历所有iframe元素
-    iframes.forEach((iframe, index) => {
-      const iframeSrc = iframe.src
+                // 构建新的hash部分,添加参数
+                // 使用当前幻灯片索引作为task参数
+                let newHash = hashPart
+                if (newHash.includes('?')) {
+                  // 如果hash中已经有查询参数,添加&
+                  newHash += `&courseid=${props.courseid || ''}&userid=${props.userid || ''}&stage=0&task=${slideIndex}&tool=0`
+                }
+                else {
+                  // 如果hash中没有查询参数,添加?
+                  newHash += `?courseid=${props.courseid || ''}&userid=${props.userid || ''}&stage=0&task=${slideIndex}&tool=0`
+                }
 
-      if (iframeSrc && iframeSrc.includes('workPage')) {
-        console.log(`处理iframe ${index + 1}:`, iframeSrc)
+                // 构建新的URL
+                const newUrl = `${baseUrl}#${newHash}`
 
-        try {
-          // 查找iframe对应的幻灯片索引
-          const slideIndex = findSlideIndexByIframeUrl(iframeSrc)
-          console.log(`iframe ${index + 1} 对应的幻灯片索引:`, slideIndex)
-
-          // 解析URL,处理hash部分
-          let baseUrl = iframeSrc
-          let hashPart = ''
-
-          // 分离base URL和hash部分
-          if (iframeSrc.includes('#')) {
-            const parts = iframeSrc.split('#')
-            baseUrl = parts[0]
-            hashPart = parts[1]
-          }
+                console.log(`幻灯片 ${slideIndex + 1} 的iframe链接已更新:`, newUrl)
 
-          // 构建新的hash部分,添加参数
-          // 使用找到的幻灯片索引作为task参数
-          let newHash = hashPart
-          if (newHash.includes('?')) {
-            // 如果hash中已经有查询参数,添加&
-            newHash += `&courseid=${props.courseid || ''}&userid=${props.userid || ''}&stage=0&task=${slideIndex}&tool=0`
-          }
-          else {
-            // 如果hash中没有查询参数,添加?
-            newHash += `?courseid=${props.courseid || ''}&userid=${props.userid || ''}&stage=0&task=${slideIndex}&tool=0`
+                // 返回更新后的元素
+                return {
+                  ...element,
+                  url: newUrl
+                }
+              }
+              catch (error) {
+                console.error(`处理幻灯片 ${slideIndex + 1} 的iframe链接时出错:`, error)
+                return element
+              }
+            }
           }
-
-          // 构建新的URL
-          const newUrl = `${baseUrl}#${newHash}`
-
-          // 更新iframe的src
-          iframe.src = newUrl
-
-          console.log(`iframe ${index + 1} 链接已更新:`, iframe.src)
-        }
-        catch (error) {
-          console.error(`处理iframe ${index + 1} 链接时出错:`, error)
+          
+          // 不是iframe元素或不需要处理,直接返回
+          return element
+        })
+
+        // 返回更新后的幻灯片
+        return {
+          ...slide,
+          elements: updatedElements
         }
       }
+      
+      // 没有元素的幻灯片直接返回
+      return slide
     })
 
+    if (hasIframe) {
+      console.log('找到iframe元素,更新slides数据')
+      // 更新store中的slides数据
+      slidesStore.setSlides(updatedSlides)
+      console.log('slides数据更新完成')
+    }
+    else {
+      console.log('未找到包含workPage的iframe元素')
+    }
+
     console.log('iframe链接处理完成')
   }
   catch (error) {
@@ -503,7 +526,21 @@ const backToEditor = () => {
   window.location.href = '/'
 }
 
-// 作业提交功能
+const submitWork = async (slideIndex: number, atool: string, content: string, type: string) => {
+  const res = await api.submitWork({
+    uid: props.userid as string,
+    cid: props.courseid as string,
+    stage: '0',
+    task: String(slideIndex), // 转为字符串
+    tool: '0',
+    atool: atool,
+    content: content,
+    type: type
+  })
+  console.log(res)
+}
+
+// 作业提交功能(优化版)
 const handleHomeworkSubmit = async () => {
   console.log('作业提交按钮被点击')
 
@@ -513,11 +550,10 @@ const handleHomeworkSubmit = async () => {
     return
   }
 
-  // 设置提交状态
   isSubmitting.value = true
 
   try {
-    // 获取当前页面的所有iframe元素
+    // 获取所有iframe元素
     const iframes = document.querySelectorAll('.viewer-canvas iframe')
     console.log('找到iframe元素数量:', iframes.length)
 
@@ -526,11 +562,11 @@ const handleHomeworkSubmit = async () => {
       return
     }
 
-    // 遍历所有iframe元素
+    let hasSubmitWork = false
+
     for (let i = 0; i < iframes.length; i++) {
       const iframe = iframes[i] as HTMLIFrameElement
       const iframeSrc = iframe.src
-
       console.log(`iframe ${i + 1} 链接:`, iframeSrc)
 
       // 检查iframe链接是否包含workPage
@@ -538,67 +574,82 @@ const handleHomeworkSubmit = async () => {
         console.log('找到包含workPage的iframe,尝试执行submitWork')
 
         try {
-          // 获取iframe的contentWindow
-          const iframeWindow = iframe.contentWindow as Window & { submitWork?: (...args: any[]) => void }
+          const iframeWindow = iframe.contentWindow as Window & { submitWork?: (...args: any[]) => unknown }
 
           if (iframeWindow && typeof iframeWindow.submitWork === 'function') {
-            // 如果存在submitWork方法,执行它,参数可变
             console.log('执行iframe中的submitWork方法,参数可变')
-
-            // 查找iframe对应的幻灯片索引
-            const iframeSlideIndex = findSlideIndexByIframeUrl(iframeSrc)
+            const iframeSlideIndex = slideIndex.value
             const submitArgs = [iframeSlideIndex]
 
-            // 等待submitWork执行完成
-            await new Promise<void>((resolve, reject) => {
-              try {
-                // 调用submitWork方法
-                const result = iframeWindow.submitWork(...submitArgs)
-
-                // 如果submitWork返回Promise,等待它完成
-                if (result && typeof result.then === 'function') {
-                  result.then(() => {
-                    console.log('submitWork执行完成')
-                    resolve()
-                  }).catch((error: any) => {
-                    console.error('submitWork执行失败:', error)
-                    reject(error)
-                  })
-                }
-                else {
-                  // 如果submitWork是同步方法,直接resolve
-                  console.log('submitWork同步执行完成')
-                  resolve()
-                }
-              }
-              catch (error) {
-                console.error('执行submitWork时出错:', error)
-                reject(error)
-              }
-            })
+            // 支持同步和异步submitWork
+            const result = iframeWindow.submitWork(...submitArgs)
+            if (result instanceof Promise) {
+              await result
+              console.log('submitWork异步执行完成')
+            } 
+            else {
+              console.log('submitWork同步执行完成')
+            }
 
             message.success('作业提交成功')
-            return
+            hasSubmitWork = true
+            break
+          } 
+          else {
+            console.log('iframe中没有找到submitWork方法')
           }
-          console.log('iframe中没有找到submitWork方法')
-
-        }
+        } 
         catch (error) {
           console.error('访问iframe内容时出错:', error)
         }
+      } 
+      else if (iframeSrc && (iframeSrc.includes('aichat.cocorobo') || iframeSrc.includes('knowledge.cocorobo'))) {
+        console.log('找到包含aichat.cocorobo或knowledge.cocorobo的iframe,尝试执行submitWork')
+        // 由于TS类型检查,需通过 any 绕过类型限制
+        const iframeWindow = iframe.contentWindow as any
+        if (iframeWindow && iframeWindow.exposed_outputs) {
+          console.log('执行iframe中的submitWork方法,参数可变')
+          const iframeSlideIndex = slideIndex.value
+          const Cow = JSON.stringify(iframeWindow.exposed_outputs)
+          // 这里假设 submitWork 是全局可用的函数
+          await submitWork(iframeSlideIndex, '72', Cow, '20')
+          message.success('作业提交成功')
+          hasSubmitWork = true
+        }
+      }
+      else {
+        console.log('尝试截图当前页面并提交')
+        try {
+          // 导入html-to-image库
+          const { toPng } = await import('html-to-image')
+            
+          // 截图当前页面
+          const imageData = await toPng(document.querySelector('.viewer-canvas') as HTMLElement, {
+            quality: 0.95,
+            backgroundColor: '#ffffff'
+          })
+            
+          // 提交截图
+          await submitWork(slideIndex.value, '73', imageData, '1') // 73表示截图工具,21表示图片类型
+          message.success('页面截图提交成功')
+          hasSubmitWork = true
+        }
+        catch (error) {
+          console.error('截图提交失败:', error)
+          message.error('截图提交失败')
+        }
       }
     }
 
-    // 如果没有找到包含workPage的iframe或无法执行submitWork
-    message.info('未找到可用的作业提交功能')
-
+    if (!hasSubmitWork) {
+      message.info('未找到可用的作业提交功能')
+    }
   }
   catch (error) {
     console.error('作业提交过程中出错:', error)
     message.error('作业提交失败')
   }
   finally {
-    // 重置提交状态
     isSubmitting.value = false
   }
 }