فهرست منبع

feat(学生组件): 添加未提交学生查看功能并优化选择题详情界面

添加未提交学生列表展示功能,支持在选择题详情中查看未提交学生
优化选择题详情界面布局,添加回答人数统计和题目切换按钮
更新多语言文件添加相关翻译字段
重构selectUserDialog组件支持自定义标题
SanHQin 2 هفته پیش
والد
کامیت
109b15f7f0

+ 1 - 0
src/views/Student/components/answerTheResult.vue

@@ -410,6 +410,7 @@ defineExpose({
   choiceQuestionListData,
   workIndex,
   workArray: props.workArray,
+  unsubmittedStudents: props.unsubmittedStudents,
   toolType: props.toolType,
   changeWorkIndex
 })

+ 278 - 159
src/views/Student/components/choiceQuestionDetailDialog.vue

@@ -1,80 +1,86 @@
 <template>
   <div class="choiceQuestionDetailDialog">
-    <div
-      class="content"
-      :style="{
-        width: slideWidth + 'px',
-        height: slideHeight + 'px',
-      }"
-    >
+    <div class="content" :style="{
+      width: slideWidth + 'px',
+      height: slideHeight + 'px',
+    }">
       <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" v-if="workDetail && workDetail.type === '45' && props.showData">
         <div class="c_t45_title">
-          <div v-if=" props.showData.choiceQuestionListData[props.showData.workIndex]">{{
+          <div v-if="props.showData.choiceQuestionListData[props.showData.workIndex]">{{
             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)">{{ lang.ssPrevQ }}</span>
-          <span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex >= props.showData.choiceQuestionListData.length - 1}" @click="changeWorkIndex(1)">{{ lang.ssNextQ }}</span>
+          <div class="c_t45_msg">
+            <div>{{ lang.ssAnswerCount }} {{ props.showData.workArray.length}}<span v-if="props.showData.unsubmittedStudents.length > 0">/{{ props.showData.unsubmittedStudents.length }}</span></div>
+            <span v-if="props.showData.unsubmittedStudents.length > 0" @click="viewUnsubmittedStudents()">{{ lang.ssViewUnsubmittedStudents }}</span>
+          </div>
+          <!--<span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex <= 0}" @click="changeWorkIndex(0)">{{ lang.ssPrevQ }}</span>-->
+          <!--<span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex >= props.showData.choiceQuestionListData.length - 1}" @click="changeWorkIndex(1)">{{ lang.ssNextQ }}</span>-->
         </div>
-        <img
-          class="c_t45_img"
-          :src="
-            props.showData.choiceQuestionListData[props.showData.workIndex]
-              .timuList[0].src
-          "
-          v-if=" props.showData.choiceQuestionListData[props.showData.workIndex] &&
+        <img class="c_t45_img" :src="props.showData.choiceQuestionListData[props.showData.workIndex]
+            .timuList[0].src
+          " v-if="props.showData.choiceQuestionListData[props.showData.workIndex] &&
             props.showData.choiceQuestionListData[props.showData.workIndex]
               .timuList.length > 0
-          "
-        />
-        <span
-          class="c_t45_type"
-          v-if="
-            props.showData.choiceQuestionListData[props.showData.workIndex]
-              .type === '1'
-          "
-          >{{ lang.ssSingleSel }}</span
-        >
-        <span
-          class="c_t45_type"
-          v-if="
-            props.showData.choiceQuestionListData[props.showData.workIndex]
-              .type === '2'
-          "
-          >{{ lang.ssMultiOpt }}</span
-        >
-        <div
-          class="c_t45_echarts"
-          :style="{
-            width: slideWidth - 40 + 'px',
-          }"
-        >
+          " @click="previewImageToolRef.previewImage(props.showData.choiceQuestionListData[props.showData.workIndex]
+            .timuList[0].src)"/>
+        <!-- <span class="c_t45_type" v-if="
+          props.showData.choiceQuestionListData[props.showData.workIndex]
+            .type === '1'
+        ">{{ lang.ssSingleSel }}</span>
+        <span class="c_t45_type" v-if="
+          props.showData.choiceQuestionListData[props.showData.workIndex]
+            .type === '2'
+        ">{{ lang.ssMultiOpt }}</span> -->
+        <!-- <span class="c_t45_type">{{ lang.ssChoiceQuestion }}</span> -->
+        <div class="c_t45_echarts" :style="{
+          width: slideWidth - 40 + 'px',
+        }">
           <div id="echartsArea1" ref="echartsArea1"></div>
         </div>
+        <!-- <div class="c_t45_aiAnalysis">
+          <div class="c_t45_aa_header">
+            <div class="c_t45_aa_h_title">
+              <svg viewBox="0 0 1024 1024" width="200" height="200"><path d="M512 170.666667C323.477333 170.666667 170.666667 323.477333 170.666667 512s152.810667 341.333333 341.333333 341.333333 341.333333-152.810667 341.333333-341.333333S700.522667 170.666667 512 170.666667zM85.333333 512C85.333333 276.352 276.352 85.333333 512 85.333333s426.666667 191.018667 426.666667 426.666667-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512z"></path><path d="M693.013333 330.986667a42.666667 42.666667 0 0 1 10.304 43.648l-75.413333 226.282666a42.666667 42.666667 0 0 1-26.986667 26.986667l-226.282666 75.413333a42.666667 42.666667 0 0 1-53.973334-53.973333l75.434667-226.261333a42.666667 42.666667 0 0 1 26.986667-26.986667l226.282666-75.413333a42.666667 42.666667 0 0 1 43.648 10.304z m-222.72 139.306666l-41.685333 125.098667 125.077333-41.706667 41.706667-125.077333-125.077333 41.706667z"></path></svg>分析
+            </div>
+            <div class="c_t45_aa_h_refresh">
+              AI生成
+             <svg viewBox="0 0 1024 1024" width="200" height="200"><path d="M875 483c-33.4 0-60.5 27.1-60.5 60.5v0.1C814.4 710.3 678.8 846 512 846S209.5 710.3 209.5 543.5 345.2 241 512 241c36.8 0 71.7 7.6 104.4 19.7-32 3-57.4 29.1-57.4 61.9 0 34.8 28.2 63 63 63h201.9c34.8 0 63-28.2 63-63V120c0-34.8-28.2-63-63-63s-63 28.2-63 63v81.4C691 150.5 605.2 120 512 120 278.1 120 88.5 309.6 88.5 543.5S278.1 967 512 967s423.5-189.6 423.5-423.5c0-33.4-27.1-60.5-60.5-60.5z"></path></svg>
+
+            </div>
+          </div>
+        </div> -->
+        <div class="cq_changeBtn" v-if="props.showData.choiceQuestionListData.length > 1">
+          <div :class="{ cq_cb_disabled: props.showData.workIndex <= 0 }" @click="changeWorkIndex(0)">
+            <svg style="transform: rotate(-90deg);" viewBox="0 0 1024 1024" version="1.1" width="200" height="200">
+              <path
+                d="M512 330.666667c14.933333 0 29.866667 4.266667 40.533333 14.933333l277.33333399 234.666667c27.733333 23.466667 29.866667 64 8.53333301 89.6-23.466667 27.733333-64 29.866667-89.6 8.53333299L512 477.866667l-236.8 200.53333299c-27.733333 23.466667-68.266667 19.19999999-89.6-8.53333299-23.466667-27.733333-19.19999999-68.266667 8.53333301-89.6l277.33333399-234.666667c10.666667-10.666667 25.6-14.933333 40.533333-14.933333z"
+                fill=""></path>
+            </svg>
+          </div>
+          <span>{{ props.showData.workIndex+1 }}/{{ props.showData.choiceQuestionListData.length }}</span>
+          <div :class="{ cq_cb_disabled: props.showData.workIndex >= props.showData.choiceQuestionListData.length - 1 }"
+            @click="changeWorkIndex(1)">
+            <svg style="transform: rotate(90deg);" viewBox="0 0 1024 1024" version="1.1" width="200" height="200">
+              <path
+                d="M512 330.666667c14.933333 0 29.866667 4.266667 40.533333 14.933333l277.33333399 234.666667c27.733333 23.466667 29.866667 64 8.53333301 89.6-23.466667 27.733333-64 29.866667-89.6 8.53333299L512 477.866667l-236.8 200.53333299c-27.733333 23.466667-68.266667 19.19999999-89.6-8.53333299-23.466667-27.733333-19.19999999-68.266667 8.53333301-89.6l277.33333399-234.666667c10.666667-10.666667 25.6-14.933333 40.533333-14.933333z"
+                fill=""></path>
+            </svg>
+          </div>
+        </div>
       </div>
 
       <!-- 问答题 -->
-      <div
-        class="c_t15"
-        v-if="workDetail && workDetail.type === '15' && props.showData"
-      >
+      <div class="c_t15" v-if="workDetail && workDetail.type === '15' && props.showData">
         <div class="c_t15_title">{{ workDetail.json.answerQ }}</div>
         <span class="c_t15_type">{{ lang.ssQATest }}</span>
         <div class="c_t15_content" v-show="!lookWorkData">
-          <div
-            class="c_t15_c_item"
-            v-for="item in processedWorkArray"
-            :key="item.id"
-            @click="lookWork(item.id)"
-          >
+          <div class="c_t15_c_item" v-for="item in processedWorkArray" :key="item.id" @click="lookWork(item.id)">
             <div class="c_t15_c_i_top">
               <span>S</span>
               <div>{{ item.name }}</div>
@@ -87,44 +93,26 @@
 
         <div class="c_t15_workDetail" v-if="lookWorkData">
           <div class="c_t15_wd_top">
-            <img
-              src="../../../assets/img/arrow_left.png"
-              @click="lookWork('')"
-            />
+            <img src="../../../assets/img/arrow_left.png" @click="lookWork('')" />
             <span>S</span>
             <div>{{ lookWorkData.name }}</div>
           </div>
           <div class="c_t15_wd_content">
             <span v-html="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" v-if="props.showData && props.showData.toolType === 72">
         <div class="c_t72_title">{{ lang.ssAiApp }}</div>
         <span class="c_t72_type">{{ lang.ssAiApp }}</span>
         <div class="c_t72_content" v-show="!lookWorkData">
-          <div
-            class="c_t72_c_item"
-            v-for="item in processedWorkArray"
-            :key="item.id"
-            @click="lookWork(item.id)"
-          >
+          <div class="c_t72_c_item" v-for="item in processedWorkArray" :key="item.id" @click="lookWork(item.id)">
             <div class="c_t72_c_i_top">
               <span>S</span>
               <div>{{ item.name }}</div>
@@ -134,54 +122,34 @@
 
         <div class="c_t72_workDetail" v-if="lookWorkData">
           <div class="c_t72_wd_top">
-            <img
-              src="../../../assets/img/arrow_left.png"
-              @click="lookWork('')"
-            />
+            <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"
-            >
+            <template v-for="(item, index) in lookWorkData.content" :key="item.id">
               <div class="messageNodeArea" v-if="item.messages || item.imageUrls">
-                  <div class="messageNode">
+                <div class="messageNode">
                   <div class="mn_title">{{ lang.ssNodeTitle.replace(/\*/g, String(index + 1)) }}</div>
                   <div class="mn_content">
-                    <template
-                      v-for="(item2, index2) in item.messages"
-                      :key="`${index}-${index2}`"
-                    >
+                    <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_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 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_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 class="na_m_i_content" v-html="item2.content"></div>
                         </div>
                       </div>
                     </template>
-                    <template v-if="item.imageUrls" v-for="(item3,index3) in item.imageUrls" :key="`${index}-${index3}`">
+                    <template v-if="item.imageUrls" v-for="(item3, index3) in item.imageUrls"
+                      :key="`${index}-${index3}`">
                       <div class="na_m_item">
                         <div class="na_m_i_name">
                           {{ item.type }}
@@ -200,19 +168,11 @@
       </div>
 
       <!-- H5页面 -->
-      <div
-        class="c_t73"
-        v-if="props.showData && props.showData.toolType === 73"
-      >
+      <div class="c_t73" v-if="props.showData && props.showData.toolType === 73">
         <div class="c_t73_title">{{ lang.ssPageImage }}</div>
         <span class="c_t73_type">{{ lang.ssHPage }}</span>
         <div class="c_t73_content" v-show="!lookWorkData">
-          <div
-            class="c_t73_c_item"
-            v-for="item in processedWorkArray"
-            :key="item.id"
-            @click="lookWork(item.id)"
-          >
+          <div class="c_t73_c_item" v-for="item in processedWorkArray" :key="item.id" @click="lookWork(item.id)">
             <div class="c_t73_c_i_top">
               <span>S</span>
               <div>{{ item.name }}</div>
@@ -225,10 +185,7 @@
 
         <div class="c_t73_workDetail" v-if="lookWorkData">
           <div class="c_t73_wd_top">
-            <img
-              src="../../../assets/img/arrow_left.png"
-              @click="lookWork('')"
-            />
+            <img src="../../../assets/img/arrow_left.png" @click="lookWork('')" />
             <span>S</span>
             <div>{{ lookWorkData.name }}</div>
           </div>
@@ -318,16 +275,16 @@ const loadContentFromUrl = async (url: string): Promise<string> => {
 // 处理单个作业内容
 const processWorkContent = async (content: string, toolType: number): Promise<any> => {
   let contentToParse = content
-  
+
   // 如果是链接,先获取文件内容
   if (isUrl(content)) {
     contentToParse = await loadContentFromUrl(content)
   }
-  
+
   if (!contentToParse) {
     return null
   }
-  
+
   try {
     if ([45, 15].includes(toolType)) {
       return JSON.parse(decodeURIComponent(contentToParse))
@@ -369,7 +326,7 @@ watch(
   async () => {
     if (props.workArray && props.showData) {
       const _workArray = JSON.parse(JSON.stringify(props.workArray))
-      
+
       // 处理每个作业内容
       for (const i of _workArray) {
         if (i.content) {
@@ -379,7 +336,7 @@ watch(
           }
         }
       }
-      
+
       processedWorkArray.value = _workArray
     }
     else {
@@ -395,7 +352,7 @@ const closeSlideIndex = () => {
 }
 
 // 切换题目
-const changeWorkIndex = (type:number) => {
+const changeWorkIndex = (type: number) => {
   emit('changeWorkIndex', type)
   // console.log(props.workIndex, props.showData.choiceQuestionListData.length)
   // if (type === 0 && props.workIndex > 0) {
@@ -514,7 +471,7 @@ const setEchartsArea1 = () => {
           fontSize: 17,
           lineHeight: 20,
           interval: 0,
-          formatter: function(value: any, idx: number) {
+          formatter: function (value: any, idx: number) {
             // 如果是字符串且格式为JSON(图片),则解析处理
             if (typeof value === 'string') {
               try {
@@ -649,7 +606,8 @@ const setEchartsArea1 = () => {
       const selectedOption = _work.choiceUser[idx]
       if (selectedOption && selectUserDialogRef.value) {
         // console.log(selectedOption)
-        selectUserDialogRef.value.open(selectedOption)
+        console.log("selectedOption",selectedOption)
+        selectUserDialogRef.value.open(`${lang.ssSelectUser.replace("{a}","<span>"+selectedOption.index+"</span>")}`,selectedOption)
       }
     })
   }
@@ -759,6 +717,14 @@ watch(
   }
 )
 
+// 查看未提交学生
+const viewUnsubmittedStudents = () => {
+  selectUserDialogRef.value.open(lang.ssUnsubmittedStudents,{user:props.showData.unsubmittedStudents.map((item: any) => item.name)})
+  // if (props.unsubmittedStudents.length > 0) {
+    // unsubmittedStudentsDialogRef.value.open(props.unsubmittedStudents)
+  // }
+}
+
 // 组件卸载时清理ECharts实例
 onUnmounted(() => {
   // 清除定时器
@@ -782,6 +748,7 @@ onUnmounted(() => {
   width: 100%;
   height: 100%;
   z-index: 1;
+
   .content {
     width: 100%;
     height: 100%;
@@ -790,6 +757,7 @@ onUnmounted(() => {
     box-sizing: border-box;
     padding: 40px;
     overflow: auto;
+
     .closeIcon {
       position: absolute;
       right: 20px;
@@ -797,18 +765,21 @@ onUnmounted(() => {
       cursor: pointer;
       width: 20px;
       height: 20px;
+
       img {
         width: 100%;
         height: 100%;
       }
     }
+
     .c_t45 {
       width: 100%;
       min-height: 100%;
       display: flex;
-      align-items: center;
+      // align-items: center;
       flex-direction: column;
       height: auto;
+
       .c_t45_title {
         color: rgba(0, 0, 0, 0.9);
         font-weight: 600;
@@ -817,33 +788,55 @@ onUnmounted(() => {
         position: relative;
         width: 100%;
         display: flex;
-        align-items: center;
-        justify-content: center;
+        flex-direction: column;
+        // align-items: center;
+        // justify-content: center;
         user-select: none;
-        &>div{
+        gap: .4rem;
+
+        &>div {
           max-width: calc(100% - 200px);
 
         }
-        &>span{
+
+        &>span {
           position: absolute;
           top: 20px;
           cursor: pointer;
-          &:nth-of-type(1){
+
+          &:nth-of-type(1) {
             left: 0;
           }
-          &:nth-of-type(2){
+
+          &:nth-of-type(2) {
             right: 0;
           }
         }
-        .c_t45_t_btn_noActive{
+
+        .c_t45_t_btn_noActive {
           color: #CCCCCC;
         }
+
+        .c_t45_msg{
+          display: flex;
+          align-items: center;
+          font-size: .9rem;
+          font-weight: 400;
+          gap: 1rem;
+          &>span{
+            text-decoration: underline;
+            cursor: pointer;
+          }
+        }
       }
+
       .c_t45_img {
         max-width: 200px;
+        max-height: 200px;
         object-fit: cover;
         margin-top: 20px;
       }
+
       .c_t45_type {
         font-weight: 400;
         font-size: 15px;
@@ -856,17 +849,90 @@ onUnmounted(() => {
 
       .c_t45_echarts {
         width: 100%;
+        max-width: 100%;
         flex: 1;
         min-height: 400px;
         display: flex;
         align-items: center;
         box-sizing: border-box;
-        & > div {
+
+        &>div {
           width: 100%;
           height: 400px;
         }
       }
+
+      .cq_changeBtn {
+        display: flex;
+        align-items: center;
+        gap: 1.5rem;
+        margin: 1rem auto;
+        &>div {
+          padding: .6rem;
+          border-radius: .5rem;
+          border: solid 2px #F6C82B;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          cursor: pointer;
+
+          &>svg {
+            fill: #F6C82D;
+            width: 1rem;
+            height: 1rem;
+          }
+
+          &.cq_cb_disabled {
+            cursor: not-allowed !important;
+            border-color: #FEF8E9 !important;
+          }
+
+          &.cq_cb_disabled>svg {
+            fill: #A3A3A3 !important;
+          }
+        }
+
+        &>span {
+          font-weight: 500;
+        }
+      }
+
+      .c_t45_aiAnalysis{
+        display: flex;
+        flex-direction: column;
+        padding: 1rem;
+        border: solid 1px #F6C82B;
+        border-left-width: 4px;
+        border-radius: 1rem;
+        &>.c_t45_aa_header{
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          gap: 1rem;
+          &>div{
+            display: flex;
+            align-items: center;
+            gap: .5rem;
+            &>svg{
+              width: 1rem;
+              height: 1rem;
+              
+            }
+          }
+          &>.c_t45_aa_h_title{
+            color: #F7CD49;
+            font-weight: 500;
+            &>svg{
+              fill: #F7CD49;
+            }
+          }
+          // &>.c_t45_aa_h_refresh{
+            
+          // }
+        }
+      }
     }
+
     .c_t15 {
       width: 100%;
       min-height: 100%;
@@ -875,12 +941,14 @@ onUnmounted(() => {
       flex-direction: column;
       height: auto;
       padding: 40px;
+
       .c_t15_title {
         color: rgba(0, 0, 0, 0.9);
         font-weight: 600;
         font-size: 24px;
         line-height: 24px;
       }
+
       .c_t15_type {
         font-weight: 400;
         font-size: 15px;
@@ -890,6 +958,7 @@ onUnmounted(() => {
         opacity: 0.5;
         margin-top: 20px;
       }
+
       .c_t15_content {
         width: 100%;
         height: auto;
@@ -908,15 +977,18 @@ onUnmounted(() => {
           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_t15_c_i_top {
             display: flex;
             align-items: center;
             gap: 10px;
-            & > span {
+
+            &>span {
               display: block;
               width: 25px;
               height: 25px;
@@ -929,11 +1001,13 @@ onUnmounted(() => {
               font-weight: bold;
               font-size: 14px;
             }
-            & > div {
+
+            &>div {
               color: rgba(0, 0, 0, 0.7);
               font-weight: 800;
             }
           }
+
           .c_t15_c_i_bottom {
             margin-top: 15px;
             font-weight: 300;
@@ -948,6 +1022,7 @@ onUnmounted(() => {
           }
         }
       }
+
       .c_t15_workDetail {
         width: 100%;
         height: auto;
@@ -958,17 +1033,20 @@ onUnmounted(() => {
         border-radius: 12px;
         display: flex;
         flex-direction: column;
+
         .c_t15_wd_top {
           width: 100%;
           display: flex;
           align-items: center;
           gap: 15px;
-          & > img {
+
+          &>img {
             width: 25px;
             height: 25px;
             cursor: pointer;
           }
-          & > span {
+
+          &>span {
             display: block;
             width: 30px;
             height: 30px;
@@ -981,23 +1059,27 @@ onUnmounted(() => {
             font-weight: bold;
             font-size: 16px;
           }
-          & > div {
+
+          &>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 {
+
+            &>img {
               width: 100px;
               height: auto;
               cursor: pointer;
@@ -1008,6 +1090,7 @@ onUnmounted(() => {
         }
       }
     }
+
     .c_t72 {
       width: 100%;
       min-height: 100%;
@@ -1016,12 +1099,14 @@ onUnmounted(() => {
       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;
@@ -1031,6 +1116,7 @@ onUnmounted(() => {
         opacity: 0.5;
         margin-top: 20px;
       }
+
       .c_t72_content {
         width: 100%;
         height: auto;
@@ -1049,15 +1135,18 @@ onUnmounted(() => {
           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 {
+
+            &>span {
               display: block;
               width: 25px;
               height: 25px;
@@ -1070,11 +1159,13 @@ onUnmounted(() => {
               font-weight: bold;
               font-size: 14px;
             }
-            & > div {
+
+            &>div {
               color: rgba(0, 0, 0, 0.7);
               font-weight: 800;
             }
           }
+
           .c_t72_c_i_bottom {
             margin-top: 15px;
             font-weight: 300;
@@ -1086,6 +1177,7 @@ onUnmounted(() => {
             display: -webkit-box;
             -webkit-line-clamp: 2;
             -webkit-box-orient: vertical;
+
             img {
               width: 100%;
               max-height: 200px;
@@ -1094,6 +1186,7 @@ onUnmounted(() => {
           }
         }
       }
+
       .c_t72_workDetail {
         width: 100%;
         height: auto;
@@ -1104,17 +1197,20 @@ onUnmounted(() => {
         border-radius: 12px;
         display: flex;
         flex-direction: column;
+
         .c_t72_wd_top {
           width: 100%;
           display: flex;
           align-items: center;
           gap: 15px;
-          & > img {
+
+          &>img {
             width: 25px;
             height: 25px;
             cursor: pointer;
           }
-          & > span {
+
+          &>span {
             display: block;
             width: 30px;
             height: 30px;
@@ -1127,12 +1223,14 @@ onUnmounted(() => {
             font-weight: bold;
             font-size: 16px;
           }
-          & > div {
+
+          &>div {
             color: rgba(0, 0, 0, 0.7);
             font-weight: 800;
             font-size: 18px;
           }
         }
+
         .c_t72_wd_content {
           width: 100%;
           margin-top: 20px;
@@ -1142,6 +1240,7 @@ onUnmounted(() => {
           display: flex;
           align-items: center;
           justify-content: center;
+
           .na_m_item {
             width: 100%;
             height: auto;
@@ -1163,16 +1262,19 @@ onUnmounted(() => {
             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;
-            :deep(img){
+
+            :deep(img) {
               max-width: 100%;
             }
           }
@@ -1188,13 +1290,14 @@ onUnmounted(() => {
             margin-top: 20px;
           }
 
-          .messageNodeArea{
+          .messageNodeArea {
             width: 100%;
             height: auto;
           }
         }
       }
     }
+
     .c_t73 {
       width: 100%;
       min-height: 100%;
@@ -1203,12 +1306,14 @@ onUnmounted(() => {
       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;
@@ -1218,6 +1323,7 @@ onUnmounted(() => {
         opacity: 0.5;
         margin-top: 20px;
       }
+
       .c_t73_content {
         width: 100%;
         height: auto;
@@ -1236,16 +1342,19 @@ onUnmounted(() => {
           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 {
+
+            &>span {
               display: block;
               width: 25px;
               height: 25px;
@@ -1258,11 +1367,13 @@ onUnmounted(() => {
               font-weight: bold;
               font-size: 14px;
             }
-            & > div {
+
+            &>div {
               color: rgba(0, 0, 0, 0.7);
               font-weight: 800;
             }
           }
+
           .c_t73_c_i_bottom {
             margin-top: 15px;
             font-weight: 300;
@@ -1274,6 +1385,7 @@ onUnmounted(() => {
             display: -webkit-box;
             -webkit-line-clamp: 2;
             -webkit-box-orient: vertical;
+
             img {
               width: 100%;
               max-height: 200px;
@@ -1282,6 +1394,7 @@ onUnmounted(() => {
           }
         }
       }
+
       .c_t73_workDetail {
         width: 100%;
         height: auto;
@@ -1292,17 +1405,20 @@ onUnmounted(() => {
         border-radius: 12px;
         display: flex;
         flex-direction: column;
+
         .c_t73_wd_top {
           width: 100%;
           display: flex;
           align-items: center;
           gap: 15px;
-          & > img {
+
+          &>img {
             width: 25px;
             height: 25px;
             cursor: pointer;
           }
-          & > span {
+
+          &>span {
             display: block;
             width: 30px;
             height: 30px;
@@ -1315,12 +1431,14 @@ onUnmounted(() => {
             font-weight: bold;
             font-size: 16px;
           }
-          & > div {
+
+          &>div {
             color: rgba(0, 0, 0, 0.7);
             font-weight: 800;
             font-size: 18px;
           }
         }
+
         .c_t73_wd_content {
           width: 100%;
           margin-top: 20px;
@@ -1330,7 +1448,8 @@ onUnmounted(() => {
           display: flex;
           align-items: center;
           justify-content: center;
-          & > img {
+
+          &>img {
             max-width: 100%;
             object-fit: cover;
           }

+ 5 - 2
src/views/Student/components/selectUserDialog.vue

@@ -1,7 +1,7 @@
 <template>
    <Modal :visible="show" :class="'modalArea'" style="padding: 0;background: none;" :width="400" :closeButton="false" :closeOnClickMask="true" @closed="close()">
     <div class="header">
-      <div class="title">选择<span>{{ data.index }}</span>的成员</div>
+      <div class="title" v-html="title"></div>
       <div class="close" @click="close()"><svg  viewBox="0 0 1024 1024" width="200" height="200"><path d="M999.819275 905.894092c26.805506 27.003004 26.78811 70.77902-0.051166 97.756441-13.398148 13.484106-30.970362 20.234857-48.534389 20.234857-17.58961 0-35.171034-6.758937-48.577369-20.277836L511.657192 609.698113 120.30704 1003.263723c-13.407358 13.475919-30.970362 20.217461-48.53439 20.217461-17.58961 0-35.17922-6.758937-48.585555-20.269649-26.813692-27.003004-26.78811-70.77902 0.042979-97.764628l391.33378-393.557424L23.572882 117.989251c-26.813692-27.012214-26.796296-70.780043 0.034792-97.764627 26.839275-26.985608 70.332858-26.960025 97.137341 0.042979l390.989949 393.909441L903.07693 20.61962c26.831089-26.977421 70.315462-26.960025 97.129154 0.042979 26.813692 27.01119 26.78811 70.770833-0.042979 97.764627L608.812953 511.98465l391.006322 393.909442z"></path></svg></div>
     </div>
     <div class="content">
@@ -17,11 +17,13 @@ import { ref } from 'vue'
 import Modal from '@/components/Modal.vue'
 const show = ref(false)
 const data = ref({})
+const title = ref("")
 
 // 打开
-const open = (value) => {
+const open = (tit,value) => {
   init()
   show.value = true
+  title.value = tit
   data.value = JSON.parse(JSON.stringify(value))
 }
 
@@ -32,6 +34,7 @@ const close = () => {
 }
 
 const init = () => {
+  title.value = ""
   data.value = {}
 }
 

+ 6 - 1
src/views/lang/cn.json

@@ -718,5 +718,10 @@
   "ssConfirmOperation": "确认操作",
   "ssClearToolContent": "该操作将清除当前工具的编辑内容,是否继续?",
   "ssUploadWebpageLink": "上传链接",
-  "ssCocoLinkTip":"请添加 Cocorobo 同域、亚马逊或可访问的 HTML 链接。"
+  "ssCocoLinkTip":"请添加 Cocorobo 同域、亚马逊或可访问的 HTML 链接。",
+  "ssChoiceQuestion":"选择题",
+  "ssAnswerCount":"回答人数",
+  "ssViewUnsubmittedStudents":"点击查看未提交学生",
+  "ssSelectUser":"选择{a}的成员",
+  "ssUnsubmittedStudents":"未提交学生"
 }

+ 6 - 1
src/views/lang/en.json

@@ -718,5 +718,10 @@
   "ssConfirmOperation": "Confirm Operation",
   "ssClearToolContent": "This operation will clear the current tool's editing content. Continue?",
   "ssUploadWebpageLink": "Upload Webpage Link",
-  "ssCocoLinkTip":"Please add Cocorobo, Amazon, or accessible HTML link."
+  "ssCocoLinkTip":"Please add Cocorobo, Amazon, or accessible HTML link.",
+  "ssChoiceQuestion":"Choice Question",
+  "ssAnswerCount":"Answer count",
+  "ssViewUnsubmittedStudents":"Click to view unsubmitted students",
+  "ssSelectUser":"Select members of {a}",
+  "ssUnsubmittedStudents":"Unsubmitted students"
 }

+ 6 - 1
src/views/lang/hk.json

@@ -718,5 +718,10 @@
   "ssConfirmOperation": "確認操作",
   "ssClearToolContent": "該操作將清除當前工具的編輯內容,是否繼續?",
   "ssUploadWebpageLink": "上傳鏈接",
-  "ssCocoLinkTip":"請添加 Cocorobo 同域、亚马逊或可访问的 HTML 链接。"
+  "ssCocoLinkTip":"請添加 Cocorobo 同域、亚马逊或可访问的 HTML 链接。",
+  "ssChoiceQuestion":"選擇題",
+  "ssAnswerCount":"回答人數",
+  "ssViewUnsubmittedStudents":"點擊查看未提交學生",
+  "ssSelectUser":"選擇{a}的成員",
+  "ssUnsubmittedStudents":"未提交學生"
 }