Jelajahi Sumber

Merge branch 'beta' of https://git.cocorobo.cn/jack/PPT into beta

lsc 1 bulan lalu
induk
melakukan
82e6fd7c3d

+ 62 - 14
src/views/Student/components/AIWorkModal.vue

@@ -1,21 +1,30 @@
 <template>
   <Modal :visible="visible" :width="720" :closeButton="true" @update:visible="val => emit('update:visible', val)">
     <div class="sddd_box">
-				<template v-for="item in messageList" :key="item.uid">
-					<div>
-						<div class="na_m_item" v-if="item.role == 'user' && item.content">
+      <template v-for="(item,index) in messageList" :key="item.id">
+        <div v-if="item.messages.length">
+          <div class="messageNode">
+            <div class="mn_title">节点{{ index+1 }}</div>
+            <div class="mn_content">
+              <template v-for="(item2,index2) in item.messages" :key="`${index}-${index2}`">
+                <div>
+						<div class="na_m_item" v-if="item2.role == 'user' && item2.content">
 							<div class="na_m_i_name">
-								{{ item.sender }}
+								{{ item2.sender }}
 							</div>
-							<div class="na_m_i_content" v-html="item.content"></div>
+							<div class="na_m_i_content" v-html="item2.content"></div>
 						</div>
-						<div class="na_m_item" v-if="item.role == 'assistant' && item.content">
+						<div class="na_m_item" v-if="item2.role == 'assistant' && item2.content">
 							<div class="na_m_i_name aiName">
-								{{ item.sender }}
+								{{ item2.sender }}
 							</div>
-							<div class="na_m_i_content" v-html="item.content"></div>
+							<div class="na_m_i_content" v-html="item2.content"></div>
 						</div>
 					</div>
+              </template>
+            </div>
+          </div>
+        </div>
 				</template>
 			</div>
   </Modal>
@@ -24,7 +33,8 @@
 <script lang="ts" setup>
 import { computed, watch, ref} from 'vue'
 import Modal from '@/components/Modal.vue'
-
+import MarkdownIt from 'markdown-it'
+// md.render(_addText)
 const props = defineProps<{
   visible: boolean
   work: any
@@ -34,20 +44,46 @@ const emit = defineEmits<{
   (e: 'update:visible', v: boolean): void
 }>()
 
+const md = new MarkdownIt()
+
 const visible = computed({
   get: () => props.visible,
   set: (v: boolean) => emit('update:visible', v)
 })
 
-const messageList = ref<any[]>([])
+// const messageList = ref<any[]>([])
+
+const messageList = computed(() => {
+  let _result = []
 
-watch(() => props.visible, () => {
   if (props.work && props.visible) {
     const messageListRaw = JSON.parse(props.work.content)
-    const messages: any[] = messageListRaw.flatMap((item: any) => item.messages)
-    messageList.value = messages
+    messageListRaw.forEach((item:any) => {
+      if (item.messages.length) {
+        item.messages.forEach((item2: any) => {
+          // 如果已经包含html标签则不再渲染
+          if (!/^(\s*<[^>]+>.*<\/[^>]+>\s*|<[^>]+\/>\s*)$/s.test(item2.content.trim())) {
+            item2.content = md.render(item2.content)
+          }
+        })
+      }
+    })
+    _result = messageListRaw
   }
+
+
+
+  return _result
 })
+
+// watch(() => props.visible, () => {
+//   if (props.work && props.visible) {
+//     const messageListRaw = JSON.parse(props.work.content)
+//     console.log(messageListRaw)
+//     const messages: any[] = messageListRaw
+//     messageList.value = messages
+//   }
+// })
 </script>
 
 
@@ -58,7 +94,8 @@ watch(() => props.visible, () => {
 	overflow: auto;
 	background-color: #f4f4f4;
 	box-sizing: border-box;
-	padding: 20px;
+	padding: 10px;
+  gap: 20px;
 }
 
 .sddd_bottom {
@@ -98,4 +135,15 @@ watch(() => props.visible, () => {
 	border-radius: 0 0 12px 12px;
 	background-color: #fff;
 }
+
+.messageNode{
+  width: 100%;
+  height: auto;
+  box-sizing: border-box;
+  padding: 10px 10px;
+  border: .5px solid #e7e7e7;
+  border-radius: 12px;
+  gap: 10px;
+  margin-top: 20px;
+}
 </style>

+ 7 - 2
src/views/Student/components/answerTheResult.vue

@@ -124,12 +124,14 @@ interface Props {
 	unsubmittedStudents?: object[] | null;
 	workId?: string | null;
   slideIndex?:number
+  toolType?:number
 }
 
 const props = withDefaults(defineProps<Props>(), {
   workArray: () => [],
   unsubmittedStudents: () => [],
   workId: '',
+  toolType: 0,
   slideIndex: 0
 })
 
@@ -352,7 +354,8 @@ const changeShow = (op: any, idx: number) => {
 }
 
 const lookDetail = () => {
-  if (['45', '15'].includes(workDetail.value.type)) {
+  console.log(props.toolType)
+  if ([45, 15, 72, 73].includes(props.toolType)) {
     emit('openChoiceQuestionDetail', props.slideIndex)
   }
 }
@@ -367,7 +370,9 @@ defineExpose({
   workDetail,
   choiceQuestionListData,
   workIndex,
-  workArray: props.workArray
+  workArray: props.workArray,
+  toolType: props.toolType,
+  changeWorkIndex
 })
 
 </script>

+ 542 - 24
src/views/Student/components/choiceQuestionDetailDialog.vue

@@ -10,15 +10,19 @@
       <span class="closeIcon" @click="closeSlideIndex()">
         <img src="../../../assets/img/close.png" />
       </span>
+
+      <!-- 选择题 -->
       <div
         class="c_t45"
         v-if="workDetail && workDetail.type === '45' && props.showData"
       >
         <div class="c_t45_title">
-          {{
+          <div>{{
             props.showData.choiceQuestionListData[props.showData.workIndex]
               .teststitle
-          }}
+          }}</div>
+          <span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex <= 0}" @click="changeWorkIndex(0)">上一题</span>
+          <span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex >= props.showData.choiceQuestionListData.length - 1}" @click="changeWorkIndex(1)">下一题</span>
         </div>
         <img
           class="c_t45_img"
@@ -57,6 +61,7 @@
         </div>
       </div>
 
+      <!-- 问答题 -->
       <div
         class="c_t15"
         v-if="workDetail && workDetail.type === '15' && props.showData"
@@ -90,23 +95,149 @@
             <div>{{ lookWorkData.name }}</div>
           </div>
           <div class="c_t15_wd_content">
+            workId
             <span>{{ lookWorkData.content.answer }}</span>
-            <div class="c_t15_wd_c_imageList" v-if="lookWorkData.content.fileList.length > 0">
-              <img v-for="item in lookWorkData.content.fileList" :src="item.url" :key="item.uploadTime" @click="lookImage(item.url)"/>
+            <div
+              class="c_t15_wd_c_imageList"
+              v-if="lookWorkData.content.fileList.length > 0"
+            >
+              <img
+                v-for="item in lookWorkData.content.fileList"
+                :src="item.url"
+                :key="item.uploadTime"
+                @click="lookImage(item.url)"
+              />
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- AI应用 -->
+      <div
+        class="c_t72"
+        v-if="props.showData && props.showData.toolType === 72"
+      >
+        <div class="c_t72_title">AI应用</div>
+        <span class="c_t72_type">AI应用</span>
+        <div class="c_t72_content" v-show="!lookWorkData">
+          <div
+            class="c_t72_c_item"
+            v-for="item in workArray"
+            :key="item.id"
+            @click="lookWork(item.id)"
+          >
+            <div class="c_t72_c_i_top">
+              <span>S</span>
+              <div>{{ item.name }}</div>
             </div>
           </div>
         </div>
+
+        <div class="c_t72_workDetail" v-if="lookWorkData">
+          <div class="c_t72_wd_top">
+            <img
+              src="../../../assets/img/arrow_left.png"
+              @click="lookWork('')"
+            />
+            <span>S</span>
+            <div>{{ lookWorkData.name }}</div>
+          </div>
+          <div class="c_t72_wd_content">
+            <template
+              v-for="(item, index) in lookWorkData.content"
+              :key="item.id"
+            >
+              <div class="messageNodeArea" v-if="item.messages.length">
+                <div class="messageNode">
+                  <div class="mn_title">节点{{ index + 1 }}</div>
+                  <div class="mn_content">
+                    <template
+                      v-for="(item2, index2) in item.messages"
+                      :key="`${index}-${index2}`"
+                    >
+                      <div>
+                        <div
+                          class="na_m_item"
+                          v-if="item2.role == 'user' && item2.content"
+                        >
+                          <div class="na_m_i_name">
+                            {{ item2.sender }}
+                          </div>
+                          <div
+                            class="na_m_i_content"
+                            v-html="item2.content"
+                          ></div>
+                        </div>
+                        <div
+                          class="na_m_item"
+                          v-if="item2.role == 'assistant' && item2.content"
+                        >
+                          <div class="na_m_i_name aiName">
+                            {{ item2.sender }}
+                          </div>
+                          <div
+                            class="na_m_i_content"
+                            v-html="item2.content"
+                          ></div>
+                        </div>
+                      </div>
+                    </template>
+                  </div>
+                </div>
+              </div>
+            </template>
+          </div>
+        </div>
+      </div>
+
+      <!-- H5页面 -->
+      <div
+        class="c_t73"
+        v-if="props.showData && props.showData.toolType === 73"
+      >
+        <div class="c_t73_title">页面图片</div>
+        <span class="c_t73_type">H5页面</span>
+        <div class="c_t73_content" v-show="!lookWorkData">
+          <div
+            class="c_t73_c_item"
+            v-for="item in workArray"
+            :key="item.id"
+            @click="lookWork(item.id)"
+          >
+            <div class="c_t73_c_i_top">
+              <span>S</span>
+              <div>{{ item.name }}</div>
+            </div>
+            <div class="c_t73_c_i_bottom">
+              <img :src="item.content" />
+            </div>
+          </div>
+        </div>
+
+        <div class="c_t73_workDetail" v-if="lookWorkData">
+          <div class="c_t73_wd_top">
+            <img
+              src="../../../assets/img/arrow_left.png"
+              @click="lookWork('')"
+            />
+            <span>S</span>
+            <div>{{ lookWorkData.name }}</div>
+          </div>
+          <div class="c_t73_wd_content">
+            <img :src="lookWorkData.content" />
+          </div>
+        </div>
       </div>
     </div>
-    <previewImageTool ref="previewImageToolRef"/>
+    <previewImageTool ref="previewImageToolRef" />
   </div>
- 
 </template>
 
 <script setup lang="ts">
 import { computed, ref, watch, onUnmounted, nextTick } from 'vue'
 import * as echarts from 'echarts'
 import previewImageTool from '../../components/tool/previewImageTool.vue'
+import MarkdownIt from 'markdown-it'
 const props = defineProps<{
   visible: number[];
   workIndex: number;
@@ -118,6 +249,7 @@ const props = defineProps<{
 
 const emit = defineEmits<{
   (e: 'update:visible', v: number[]): void;
+  (e: 'changeWorkIndex', v: number): void;
 }>()
 
 const visible = computed({
@@ -135,13 +267,36 @@ const workDetail = computed(() => {
 // 预览图片组件
 const previewImageToolRef = ref<any>(null)
 
+const md = new MarkdownIt()
+
 const workArray = computed(() => {
   let _result = []
   if (props.showData && props.showData.workArray) {
     const _workArray = JSON.parse(JSON.stringify(props.showData.workArray))
-    _workArray.forEach((i: any) => {
-      i.content = JSON.parse(decodeURIComponent(i.content))
-    })
+    if ([45, 15].includes(props.showData.toolType)) {
+      _workArray.forEach((i: any) => {
+        i.content = JSON.parse(decodeURIComponent(i.content))
+      })
+    }
+    if (props.showData.toolType === 72) {
+      _workArray.forEach((i: any) => {
+        i.content = JSON.parse(i.content)
+        i.content.forEach((item: any) => {
+          if (item.messages.length) {
+            item.messages.forEach((item2: any) => {
+              // 如果已经包含html标签则不再渲染
+              if (
+                !/^(\s*<[^>]+>.*<\/[^>]+>\s*|<[^>]+\/>\s*)$/s.test(
+                  item2.content.trim()
+                )
+              ) {
+                item2.content = md.render(item2.content)
+              }
+            })
+          }
+        })
+      })
+    }
     _result = _workArray
   }
 
@@ -153,6 +308,18 @@ const closeSlideIndex = () => {
   visible.value = visible.value.filter((v) => v !== props.slideIndex)
 }
 
+// 切换题目
+const changeWorkIndex = (type:number) => {
+  emit('changeWorkIndex', type)
+  // console.log(props.workIndex, props.showData.choiceQuestionListData.length)
+  // if (type === 0 && props.workIndex > 0) {
+  //   emit('changeWorkIndex', 0)
+  // }
+  // else if (type === 1 && props.workIndex < props.showData.choiceQuestionListData.length) {
+  //   emit('changeWorkIndex', props.workIndex + 1)
+  // }
+}
+
 // 选择题图表div
 const echartsArea1 = ref<any>(null)
 
@@ -175,7 +342,6 @@ const lookWorkData = computed(() => {
   return _result
 })
 
-
 // 查看图片
 const lookImage = (url: string) => {
   if (previewImageToolRef.value) {
@@ -508,6 +674,30 @@ onUnmounted(() => {
         font-weight: 600;
         font-size: 24px;
         line-height: 24px;
+        position: relative;
+        width: 100%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        user-select: none;
+        &>div{
+          max-width: calc(100% - 200px);
+
+        }
+        &>span{
+          position: absolute;
+          top: 20px;
+          cursor: pointer;
+          &:nth-of-type(1){
+            left: 0;
+          }
+          &:nth-of-type(2){
+            right: 0;
+          }
+        }
+        .c_t45_t_btn_noActive{
+          color: #CCCCCC;
+        }
       }
       .c_t45_img {
         max-width: 200px;
@@ -629,20 +819,109 @@ onUnmounted(() => {
         border-radius: 12px;
         display: flex;
         flex-direction: column;
-        .c_t15_wd_top{
+        .c_t15_wd_top {
           width: 100%;
           display: flex;
           align-items: center;
           gap: 15px;
-          &>img{
+          & > img {
             width: 25px;
             height: 25px;
             cursor: pointer;
           }
           & > span {
+            display: block;
+            width: 30px;
+            height: 30px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            background: rgba(252, 207, 0, 1);
+            border-radius: 4px;
+            color: rgba(255, 255, 255, 1);
+            font-weight: bold;
+            font-size: 16px;
+          }
+          & > div {
+            color: rgba(0, 0, 0, 0.7);
+            font-weight: 800;
+            font-size: 18px;
+          }
+        }
+        .c_t15_wd_content {
+          width: 100%;
+          margin-top: 20px;
+          max-height: 100%;
+          overflow: auto;
+          flex-wrap: wrap;
+          .c_t15_wd_c_imageList {
+            width: 100%;
+            gap: 20px;
+            margin-top: 20px;
+            & > img {
+              width: 100px;
+              height: auto;
+              cursor: pointer;
+              margin-right: 20px;
+              object-fit: cover;
+            }
+          }
+        }
+      }
+    }
+    .c_t72 {
+      width: 100%;
+      min-height: 100%;
+      display: flex;
+      align-items: center;
+      flex-direction: column;
+      height: auto;
+      padding: 40px;
+      .c_t72_title {
+        color: rgba(0, 0, 0, 0.9);
+        font-weight: 600;
+        font-size: 24px;
+        line-height: 24px;
+      }
+      .c_t72_type {
+        font-weight: 400;
+        font-size: 15px;
+        line-height: 21px;
+        letter-spacing: 0.5px;
+        color: rgba(0, 0, 0, 1);
+        opacity: 0.5;
+        margin-top: 20px;
+      }
+      .c_t72_content {
+        width: 100%;
+        height: auto;
+        display: grid;
+        grid-template-columns: repeat(4, 1fr);
+        gap: 20px;
+        margin-top: 40px;
+
+        .c_t72_c_item {
+          width: 100%;
+          height: auto;
+          box-shadow: 2px 4px 20px 0px rgba(0, 0, 0, 0.2);
+          box-sizing: border-box;
+          border-radius: 12px;
+          padding: 16px;
+          background: rgba(255, 255, 255, 0.6);
+          transition: 0.3s;
+          cursor: pointer;
+          &:hover {
+            box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
+            background: rgba(255, 255, 255, 0.6);
+          }
+          .c_t72_c_i_top {
+            display: flex;
+            align-items: center;
+            gap: 10px;
+            & > span {
               display: block;
-              width: 30px;
-              height: 30px;
+              width: 25px;
+              height: 25px;
               display: flex;
               align-items: center;
               justify-content: center;
@@ -650,34 +929,273 @@ onUnmounted(() => {
               border-radius: 4px;
               color: rgba(255, 255, 255, 1);
               font-weight: bold;
-              font-size: 16px;
+              font-size: 14px;
             }
             & > div {
               color: rgba(0, 0, 0, 0.7);
               font-weight: 800;
-              font-size: 18px;
             }
+          }
+          .c_t72_c_i_bottom {
+            margin-top: 15px;
+            font-weight: 300;
+            font-size: 14px;
+            // height: 40px;
+            max-width: 100%;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            display: -webkit-box;
+            -webkit-line-clamp: 2;
+            -webkit-box-orient: vertical;
+            img {
+              width: 100%;
+              max-height: 200px;
+              object-fit: cover;
+            }
+          }
         }
-        .c_t15_wd_content{
+      }
+      .c_t72_workDetail {
+        width: 100%;
+        flex: 1;
+        min-height: 400px;
+        margin-top: 40px;
+        box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
+        box-sizing: border-box;
+        padding: 16px;
+        border-radius: 12px;
+        display: flex;
+        flex-direction: column;
+        .c_t72_wd_top {
+          width: 100%;
+          display: flex;
+          align-items: center;
+          gap: 15px;
+          & > img {
+            width: 25px;
+            height: 25px;
+            cursor: pointer;
+          }
+          & > span {
+            display: block;
+            width: 30px;
+            height: 30px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            background: rgba(252, 207, 0, 1);
+            border-radius: 4px;
+            color: rgba(255, 255, 255, 1);
+            font-weight: bold;
+            font-size: 16px;
+          }
+          & > div {
+            color: rgba(0, 0, 0, 0.7);
+            font-weight: 800;
+            font-size: 18px;
+          }
+        }
+        .c_t72_wd_content {
           width: 100%;
           margin-top: 20px;
           max-height: 100%;
           overflow: auto;
           flex-wrap: wrap;
-          .c_t15_wd_c_imageList{
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          .na_m_item {
             width: 100%;
-            gap: 20px;
+            height: auto;
+            margin: 10px 0;
+          }
+
+          .na_m_i_name {
+            width: fit-content;
+            max-width: 100%;
+            height: auto;
+            box-sizing: border-box;
+            padding: 10px 10px;
+            display: flex;
+            align-items: center;
+            border-radius: 10px 10px 0 0;
+            background-color: #9747ff;
+            color: #fff;
+            text-overflow: ellipsis;
+            overflow: hidden;
+            white-space: nowrap;
+          }
+          .aiName {
+            background-color: #0560fc;
+          }
+          .na_m_i_content {
+            padding: 10px;
+            border: solid 1px #e7e7e7;
+            box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.1);
+            border-radius: 0 0 12px 12px;
+            background-color: #fff;
+          }
+
+          .messageNode {
+            width: 100%;
+            height: auto;
+            box-sizing: border-box;
+            padding: 10px 10px;
+            border: 0.5px solid #e7e7e7;
+            border-radius: 12px;
+            gap: 10px;
             margin-top: 20px;
-            &>img{
-              width: 100px;
-              height: auto;
-              cursor: pointer;
-              margin-right: 20px;
+          }
+
+          .messageNodeArea{
+            width: 100%;
+            height: auto;
+          }
+        }
+      }
+    }
+    .c_t73 {
+      width: 100%;
+      min-height: 100%;
+      display: flex;
+      align-items: center;
+      flex-direction: column;
+      height: auto;
+      padding: 40px;
+      .c_t73_title {
+        color: rgba(0, 0, 0, 0.9);
+        font-weight: 600;
+        font-size: 24px;
+        line-height: 24px;
+      }
+      .c_t73_type {
+        font-weight: 400;
+        font-size: 15px;
+        line-height: 21px;
+        letter-spacing: 0.5px;
+        color: rgba(0, 0, 0, 1);
+        opacity: 0.5;
+        margin-top: 20px;
+      }
+      .c_t73_content {
+        width: 100%;
+        height: auto;
+        display: grid;
+        grid-template-columns: repeat(4, 1fr);
+        gap: 20px;
+        margin-top: 40px;
+
+        .c_t73_c_item {
+          width: 100%;
+          height: auto;
+          box-shadow: 2px 4px 20px 0px rgba(0, 0, 0, 0.2);
+          box-sizing: border-box;
+          border-radius: 12px;
+          padding: 16px;
+          background: rgba(255, 255, 255, 0.6);
+          transition: 0.3s;
+          cursor: pointer;
+          &:hover {
+            box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
+            background: rgba(255, 255, 255, 0.6);
+          }
+          .c_t73_c_i_top {
+            display: flex;
+            width: 100%;
+            align-items: center;
+            gap: 10px;
+            & > span {
+              display: block;
+              width: 25px;
+              height: 25px;
+              display: flex;
+              align-items: center;
+              justify-content: center;
+              background: rgba(252, 207, 0, 1);
+              border-radius: 4px;
+              color: rgba(255, 255, 255, 1);
+              font-weight: bold;
+              font-size: 14px;
+            }
+            & > div {
+              color: rgba(0, 0, 0, 0.7);
+              font-weight: 800;
+            }
+          }
+          .c_t73_c_i_bottom {
+            margin-top: 15px;
+            font-weight: 300;
+            font-size: 14px;
+            // height: 40px;
+            max-width: 100%;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            display: -webkit-box;
+            -webkit-line-clamp: 2;
+            -webkit-box-orient: vertical;
+            img {
+              width: 100%;
+              max-height: 200px;
               object-fit: cover;
             }
           }
         }
       }
+      .c_t73_workDetail {
+        width: 100%;
+        flex: 1;
+        min-height: 400px;
+        margin-top: 40px;
+        box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
+        box-sizing: border-box;
+        padding: 16px;
+        border-radius: 12px;
+        display: flex;
+        flex-direction: column;
+        .c_t73_wd_top {
+          width: 100%;
+          display: flex;
+          align-items: center;
+          gap: 15px;
+          & > img {
+            width: 25px;
+            height: 25px;
+            cursor: pointer;
+          }
+          & > span {
+            display: block;
+            width: 30px;
+            height: 30px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            background: rgba(252, 207, 0, 1);
+            border-radius: 4px;
+            color: rgba(255, 255, 255, 1);
+            font-weight: bold;
+            font-size: 16px;
+          }
+          & > div {
+            color: rgba(0, 0, 0, 0.7);
+            font-weight: 800;
+            font-size: 18px;
+          }
+        }
+        .c_t73_wd_content {
+          width: 100%;
+          margin-top: 20px;
+          max-height: 100%;
+          overflow: auto;
+          flex-wrap: wrap;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          & > img {
+            max-width: 100%;
+            object-fit: cover;
+          }
+        }
+      }
     }
   }
 }

+ 15 - 5
src/views/Student/index.vue

@@ -89,7 +89,7 @@
           <ScreenSlideList :style="{ width: isFullscreen ? '100%' : slideWidth2 * canvasScale + 'px', height: isFullscreen ? '100%' : slideHeight2 * canvasScale + 'px', margin: '0 auto' }" :slideWidth="isFullscreen ? slideWidth * canvasScale : slideWidth2 * canvasScale" :slideHeight="isFullscreen ? slideHeight * canvasScale : slideHeight2 * canvasScale"
             :animationIndex="0" :turnSlideToId="() => { }" :manualExitFullscreen="() => { }"  :slideIndex="slideIndex" v-show="!choiceQuestionDetailDialogOpenList.includes(slideIndex)"/>
 
-          <choiceQuestionDetailDialog v-if="choiceQuestionDetailDialogOpenList.includes(slideIndex)" v-model:visible="choiceQuestionDetailDialogOpenList" :showData="answerTheResultRef" :slideIndex="slideIndex" :workIndex="0" :style="{ width: isFullscreen ? '100%' : slideWidth2 * canvasScale + 'px', height: isFullscreen ? '100%' : slideHeight2 * canvasScale + 'px', margin: '0 auto' }" :slideWidth="isFullscreen ? slideWidth * canvasScale : slideWidth2 * canvasScale" :slideHeight="isFullscreen ? slideHeight * canvasScale : slideHeight2 * canvasScale"/>
+          <choiceQuestionDetailDialog v-if="choiceQuestionDetailDialogOpenList.includes(slideIndex)" @changeWorkIndex="changeWorkIndex" v-model:visible="choiceQuestionDetailDialogOpenList" :showData="answerTheResultRef" :slideIndex="slideIndex" :workIndex="0" :style="{ width: isFullscreen ? '100%' : slideWidth2 * canvasScale + 'px', height: isFullscreen ? '100%' : slideHeight2 * canvasScale + 'px', margin: '0 auto' }" :slideWidth="isFullscreen ? slideWidth * canvasScale : slideWidth2 * canvasScale" :slideHeight="isFullscreen ? slideHeight * canvasScale : slideHeight2 * canvasScale"/>
 
 
           <div class="slide-bottom" v-if="!isFullscreen">
@@ -249,7 +249,7 @@
         <!-- 回答结果内容 -->
         <div v-show="!workPanelCollapsed && rightPanelMode === 'homework'" class="panel-content">
           <div v-if="workLoading" class="homework-loading">正在加载作业...</div>
-          <answerTheResult :workId="workId" :workArray="workArray" :unsubmittedStudents="unsubmittedStudents" :slideIndex="slideIndex" v-else ref="answerTheResultRef" @openChoiceQuestionDetail="openChoiceQuestionDetail" />
+          <answerTheResult :toolType="toolType" :workId="workId" :workArray="workArray" :unsubmittedStudents="unsubmittedStudents" :slideIndex="slideIndex" v-else ref="answerTheResultRef" @openChoiceQuestionDetail="openChoiceQuestionDetail" />
           <div class="homework-title">已提交</div>
           <div v-if="workLoading" class="homework-loading">正在加载作业...</div>
           <div v-else>
@@ -451,6 +451,8 @@ const choiceQuestionDetailDialogOpenList = ref<number[]>([])
 
 // 当前作业选择/问答题的ID
 const workId = ref<string>('')
+// 当前作业的type
+const toolType = ref<string>('')
 
 // 回答结果收缩状态
 const workPanelCollapsed = ref(true)
@@ -493,6 +495,13 @@ const reconnectTimer = ref<NodeJS.Timeout | null>(null)
 const isConnecting = ref(false)
 const connectionStatus = ref<'disconnected' | 'connecting' | 'connected'>('disconnected')
 
+//  切换选择题题目
+const changeWorkIndex = (type:number) => {
+  if (answerTheResultRef.value && answerTheResultRef.value.changeWorkIndex) {
+    answerTheResultRef.value.changeWorkIndex(type)
+  }
+}
+
 // 切换到回答结果
 const switchToHomework = () => {
   rightPanelMode.value = 'homework'
@@ -755,14 +764,13 @@ watch(() => slideIndex.value, (newIndex, oldIndex) => {
   if (newIndex !== oldIndex && typeof newIndex === 'number') {
     // 检查新页面是否有iframe
     const hasIframe = currentSlideHasIframe.value
-    
     if (hasIframe) {
       console.log('当前页面有iframe,获取作业数据')
       console.log('触发getWork,当前幻灯片索引:', newIndex)
       getWork()
     }
-    
     if (props.type == '1' && isFollowModeActive.value && isCreator.value) {
+      
       api.updateCourseFollowC(newIndex, props.courseid as string)
       sendMessage({slideIndex: newIndex, courseid: props.courseid, type: 'slideIndex'})
     }
@@ -824,16 +832,18 @@ const handleFullscreenChange = () => {
 const getWorkId = () => {
   // 修复类型报错:elementList 可能没有 toolType 和 url 字段,需先判断类型
   const element = elementList.value[0]
+  console.log(element)
   if (
     element &&
     typeof element === 'object' &&
     ('toolType' in element) &&
     (element as any).toolType !== undefined &&
-    ((element as any).toolType === 45 || (element as any).toolType === 15)
+    ((element as any).toolType === 45 || (element as any).toolType === 15 || (element as any).toolType === 73 || (element as any).toolType === 72)
   ) {
     // 提取链接中的id参数
     const url = (element as any).url
     let id = ''
+    toolType.value = (element as any).toolType
     if (typeof url === 'string') {
       const match = url.match(/[?&]id=([^&]+)/)
       if (match) {