Просмотр исходного кода

feat(editor): add new file type frame element

1. 新增84类型的ssFile帧元素配置与入口按钮
2. 支持office文件预览,替换原有图标并新增预览逻辑
3. 将file类型加入交互式元素检测与内容解析列表
lsc 2 дней назад
Родитель
Сommit
55c2d1c5c8

+ 8 - 1
src/views/Editor/CanvasTool/index2.vue

@@ -33,6 +33,13 @@
             </svg>
             <span>{{ lang.ssPhoto }}</span>
           </div>
+          <div class="popover-item" @click="editContent(84)" v-if="frametype != 84">
+            <svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
+                <path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"></path>
+                <circle cx="12" cy="13" r="4"></circle>
+            </svg>
+            <span>{{ lang.ssFile }}</span>
+          </div>
         </template>
         <div class="handler-item" :class="{ active: toolVisible }">
           <span class="svg-icon">
@@ -329,7 +336,7 @@ const viewMode = computed(() => getInitialViewMode())
 
 const hasInteractiveTool = computed(() => {
   const elements = currentSlide.value?.elements || []
-  return elements.some((el: any) => el.type === 'frame' && (el.toolType === 45 || el.toolType === 15 || el.toolType === 78 || el.toolType === 79))
+  return elements.some((el: any) => el.type === 'frame' && (el.toolType === 45 || el.toolType === 15 || el.toolType === 78 || el.toolType === 79 || el.toolType === 84))
 })
 
 const iframeLabel = computed(() => {

+ 16 - 4
src/views/Student/components/choiceQuestionDetailDialog.vue

@@ -877,13 +877,13 @@
           </svg>
         </div>
         <iframe
-          v-if="docPreviewType === 'pdf'"
-          :src="docPreviewUrl"
+          v-if="docPreviewType === 'pdf' || docPreviewType === 'office'"
+          :src="getDocPreviewUrl(docPreviewType, docPreviewUrl)"
           class="file-preview-frame"
           frameborder="0"
         ></iframe>
         <div v-else class="file-preview-office">
-          <div class="file-preview-office-icon">📝</div>
+          <div class="file-preview-office-icon">📎</div>
           <div class="file-preview-office-name">{{ docPreviewUrl.split('/').pop() }}</div>
           <a :href="docPreviewUrl" target="_blank" class="file-preview-office-link">
             {{ lang.ssClickToOpen }}
@@ -1080,7 +1080,7 @@ const processWorkContent = async (content: string, toolType: number): Promise<an
   }
 
   try {
-    if ([45, 15, 78, 79, 831].includes(toolType)) {
+    if ([45, 15, 78, 79, 84, 831].includes(toolType)) {
       return JSON.parse(decodeURIComponent(contentToParse))
     }
     else if (toolType === 72) {
@@ -1211,6 +1211,17 @@ const docPreviewVisible = ref(false)
 const docPreviewUrl = ref('')
 const docPreviewType = ref('')
 
+// 文档预览(PDF / Office 均使用 Microsoft Office Online Viewer)
+const getDocPreviewUrl = (type: string, url: string) => {
+  if (type === 'office') {
+    return `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}&time=${new Date().getTime()}`
+  }
+  else if (type === 'pdf') {
+    return `https://cloud.cocorobo.cn/pdf.js/web/viewer.html?file=${encodeURIComponent(url)}&time=${new Date().getTime()}`
+  }
+  return url
+}
+
 const lookImage = (file: any) => {
   const url = typeof file === 'string' ? file : file?.url
   if (!url) return
@@ -3835,6 +3846,7 @@ onUnmounted(() => {
   padding: .5rem 0.6rem;
   min-width: 65px;
   justify-content: center;
+  margin-top: 15px;
 }
 
 /* KWL 展示样式 */

+ 1 - 0
src/views/components/element/FrameElement/BaseFrameElement.vue

@@ -188,6 +188,7 @@ const getTypeLabel = (type: number): string => {
     77: 'ssEnglishSpeakingTool',
     78: 'ssVote',
     79: 'ssPhoto',
+    84: 'ssFile',
     [ARTICLE_READING_TOOL_TYPE]: 'ssArticleReadingTool',
     831: 'ssKwlTitle',
   }