lsc 3 months ago
parent
commit
1501794f17

+ 6 - 2
src/views/Editor/CanvasTool/WebpageInput.vue

@@ -101,7 +101,9 @@ const getTypeLabel = (type: number) => {
     45: '选择题',
     15: '问答题',
     72: 'AI应用',
-    73: 'H5页面'
+    73: 'H5页面',
+    74: '视频',
+    75: 'B站视频'
   }
   return typeMap[type] || '未知'
 }
@@ -112,7 +114,9 @@ const getTypeClass = (type: number) => {
     45: 'type-choice',
     15: 'type-question',
     72: 'type-ai',
-    73: 'type-h5'
+    73: 'type-h5',
+    74: 'type-video',
+    75: 'type-bilibili'
   }
   return classMap[type] || 'type-default'
 }

+ 11 - 4
src/views/Student/index.vue

@@ -106,8 +106,8 @@
               </div>
               <div class="slide-bottom-right" v-if="!isFullscreen">
                 <Refresh class="tool-btn" v-tooltip="'刷新'" @click="handleRefreshPage" v-if="currentSlideHasIframe"/>
-                <UpTwo @click="handleHomeworkSubmit" v-if="currentSlideHasIframe && !isSubmitting" class="tool-btn upBtn" v-tooltip="'提交作业'"/>
-                <IconLoading v-else-if="currentSlideHasIframe" class="tool-btn loading" v-tooltip="'提交中...'"></IconLoading>
+                <UpTwo @click="handleHomeworkSubmit" v-if="currentSlideHasIframe && !currentSlideHasBilibiliVideo && !isSubmitting" class="tool-btn upBtn" v-tooltip="'提交作业'"/>
+                <IconLoading v-else-if="currentSlideHasIframe && !currentSlideHasBilibiliVideo" class="tool-btn loading" v-tooltip="'提交中...'"></IconLoading>
                 <IconStopwatchStart v-if="props.type == '1' && courseDetail.userid == props.userid && isFollowModeActive" class="tool-btn" v-tooltip="'计时器'" @click="timerlVisible = !timerlVisible"  />
                 <IconWrite v-if="isFollowModeActive && props.type == '1' && courseDetail.userid == props.userid" class="tool-btn" v-tooltip="'画笔工具'" @click="writingBoardToolVisible = true"  />
                 <IconMagic v-if="isFollowModeActive && props.type == '1' && courseDetail.userid == props.userid" class="tool-btn" v-tooltip="'激光笔'" :class="{ 'active': laserPen }" @click="toggleLaserPen"  />
@@ -121,8 +121,8 @@
           <IconRightTwo class="tool-btn" theme="two-tone" :fill="['#111', '#fff']" @click="nextSlide" />
         </div>
 
-        <!-- 作业提交按钮 - 当当前幻灯片包含iframe时显示 -->
-        <div v-if="currentSlideHasIframe && isFullscreen" class="homework-submit-btn" :class="{ 'submitting': isSubmitting }"
+        <!-- 作业提交按钮 - 当当前幻灯片包含iframe时显示(排除B站视频) -->
+        <div v-if="currentSlideHasIframe && !currentSlideHasBilibiliVideo && isFullscreen" class="homework-submit-btn" :class="{ 'submitting': isSubmitting }"
           :style="{ right: getHomeworkButtonRight() + 'px' }" @click="handleHomeworkSubmit"
           v-tooltip="isSubmitting ? '作业提交中...' : '作业提交'">
           <!-- <IconEdit v-if="!isSubmitting" class="tool-btn" />
@@ -797,6 +797,13 @@ const currentSlideHasIframe = computed(() => {
   return elementList.value.some(element => element.type === ElementTypes.FRAME)
 })
 
+// 检测当前幻灯片是否包含B站视频
+const currentSlideHasBilibiliVideo = computed(() => {
+  return elementList.value.some(element => 
+    element.type === ElementTypes.FRAME && element.toolType === 75
+  )
+})
+
 // 跳转到指定幻灯片
 const goToSlide = (index: number) => {
   console.log('goToSlide 被调用,目标索引:', index)

+ 33 - 2
src/views/components/element/FrameElement/BaseFrameElement.vue

@@ -12,11 +12,33 @@
       :style="{ transform: `rotate(${elementInfo.rotate}deg)` }"
     >
       <div class="element-content">
+        <!-- 视频类型(type 74):使用 video 标签 -->
+        <video 
+          v-if="elementInfo.toolType === 74 && !isThumbnail && isVisible"
+          :key="`video-${iframeKey}`"
+          :src="elementInfo.url"
+          :width="elementInfo.width"
+          :height="elementInfo.height"
+          controls
+          :style="{ width: '100%', height: '100%', objectFit: 'contain' }"
+        ></video>
+        <!-- B站视频类型(type 75):使用 iframe -->
+        <iframe 
+          v-else-if="elementInfo.toolType === 75 && !isThumbnail && isVisible"
+          :key="`bilibili-${iframeKey}`"
+          :src="elementInfo.url"
+          :width="elementInfo.width"
+          :height="elementInfo.height"
+          :frameborder="0" 
+          :allowfullscreen="true"
+          allow="camera *; microphone *; display-capture; midi; encrypted-media; fullscreen; geolocation; clipboard-read; clipboard-write; accelerometer; autoplay; gyroscope; payment; picture-in-picture; usb; xr-spatial-tracking;"
+          @load="handleIframeLoad"
+        ></iframe>
         <!-- 延迟加载iframe:只有在可见且不是缩略图时才加载 -->
         <iframe 
           :key="`html-${iframeKey}`"
           :srcdoc="elementInfo.url" 
-          v-if="elementInfo.isHTML && !isThumbnail && isVisible"
+          v-else-if="elementInfo.isHTML && !isThumbnail && isVisible"
           :width="elementInfo.width"
           :height="elementInfo.height"
           :frameborder="0" 
@@ -94,7 +116,9 @@ const getTypeLabel = (type: number) => {
     45: '选择题',
     15: '问答题',
     72: 'AI应用',
-    73: 'H5页面'
+    73: 'H5页面',
+    74: '视频',
+    75: 'B站视频'
   }
   return typeMap[type] || '未知'
 }
@@ -171,6 +195,13 @@ const handleIframeLoad = async (event: Event) => {
   width: 100%;
   height: 100%;
   overflow: hidden;
+  
+  video {
+    width: 100%;
+    height: 100%;
+    object-fit: contain;
+    background-color: #000;
+  }
 }
 .mask {
   position: absolute;