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

feat: 新增拍照题型功能,完善多语言文案与交互

1. 新增多语言的拍照相关文案,包括暂无拍照、上一张/下一张按钮
2. 新增题型79的答题详情展示页面,支持单多张图片查看与切换
3. 开放拍照工具入口,修复查看详情的题型判定逻辑
4. 优化AI聊天的中文提示文案简体字写法
lsc 14 часов назад
Родитель
Сommit
2b2abb3fc6

+ 2 - 2
src/components/CollapsibleToolbar/index2.vue

@@ -250,7 +250,7 @@
           </svg>
           <span class="submenu-label">{{ lang.ssQandA }}</span>
         </div>
-        <!-- <div class="submenu-item" @click="handleToolClick('vote')" @mouseenter="hoveredTool = 'vote'"
+        <div class="submenu-item" @click="handleToolClick('vote')" @mouseenter="hoveredTool = 'vote'"
           @mouseleave="hoveredTool = null">
           <svg class="submenu-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
               <polyline points="9 11 12 14 22 4"></polyline>
@@ -265,7 +265,7 @@
               <circle cx="12" cy="13" r="4"></circle>
           </svg>
           <span class="submenu-label">{{ lang.ssPhoto }}</span>
-        </div> -->
+        </div>
         <div class="submenu-item" @click="handleToolClick('creative')" @mouseenter="hoveredTool = null"
           @mouseleave="hoveredTool = null">
           <svg class="submenu-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">

+ 2 - 2
src/tools/aiChat.ts

@@ -50,7 +50,7 @@ export const chat_no_stream = (msg: string, agentId: string, userId: string, lan
         : language === 'hk'
           ? 'Traditional Chinese'
           : 'Chinese'
-      } ${msg} ${language === 'hk' ? '請用繁體中文回复' : language === 'en' ? 'Please reply in English' : '用中文回复'}`,
+      } ${msg} ${language === 'hk' ? '請用繁體中文回复' : language === 'en' ? 'Please reply in English' : '用中文回复'}`,
       uid: uuidv4(),
       stream: false,
       model: agentData?.modelType || 'open-doubao',
@@ -115,7 +115,7 @@ export const chat_stream = async (
       : language === 'hk'
         ? 'Traditional Chinese'
         : 'Chinese'
-    } ${msg}  ${language === 'hk' ? '請用繁體中文回复' : language === 'en' ? 'Please reply in English' : '用中文回复'}`,
+    } ${msg}  ${language === 'hk' ? '請用繁體中文回复' : language === 'en' ? 'Please reply in English' : '用中文回复'}`,
     uid: uuidv4(),
     stream: true,
     model: agentData?.modelType || 'open-doubao',

+ 2 - 2
src/views/Editor/CanvasTool/index2.vue

@@ -17,7 +17,7 @@
             </svg>
             <span>{{ lang.ssQandA }}</span>
           </div>
-          <!-- <div class="popover-item" @click="editContent(78)" v-if="frametype != 78">
+          <div class="popover-item" @click="editContent(78)" v-if="frametype != 78">
             <svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                 <polyline points="9 11 12 14 22 4"></polyline>
                 <path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11"></path>
@@ -30,7 +30,7 @@
                 <circle cx="12" cy="13" r="4"></circle>
             </svg>
             <span>{{ lang.ssPhoto }}</span>
-          </div> -->
+          </div>
         </template>
         <div class="handler-item" :class="{ active: toolVisible }">
           <span class="svg-icon">

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

@@ -405,7 +405,7 @@ const changeShow = (op: any, idx: number) => {
 
 const lookDetail = () => {
   console.log(props.toolType)
-  if ([45, 15, 72, 73, 78].includes(props.toolType)) {
+  if ([45, 15, 72, 73, 78, 79].includes(props.toolType)) {
     emit('openChoiceQuestionDetail', props.slideIndex)
   }
 }

+ 218 - 1
src/views/Student/components/choiceQuestionDetailDialog.vue

@@ -265,6 +265,59 @@
         </div>
       </div>
 
+      <!-- 拍照 -->
+      <div class="c_t15" v-if="workDetail && workDetail.type === '79' && props.showData">
+        <div class="c_t15_title">{{ workDetail.json.answerQ }}</div>
+        <span class="c_t15_type">{{ lang.ssPhoto }}</span>
+        <div class="c_t15_content" v-show="!lookWorkData">
+          <div class="c_t15_c_item" v-for="item in processedWorkArray" :key="item.id" @click="item.content && item.content.fileList.length > 0 ? lookWork(item.id) : ''">
+            <div class="c_t15_c_i_top">
+              <span>S</span>
+              <div>{{ item.name }}</div>
+            </div>
+            <div class="c_t73_c_i_bottom" v-if="item.content && item.content.fileList.length > 0">
+              <img :src="item.content.fileList[0].url" />
+            </div>
+            <div class="c_t73_c_i_bottom" v-else>
+              <span>{{ lang.ssNoPhoto }}</span>
+            </div>
+          </div>
+        </div>
+
+        <div class="c_t79_workDetail" v-if="lookWorkData">
+          <div class="c_t79_wd_top">
+            <img src="../../../assets/img/arrow_left.png" @click="lookWork('')" />
+            <span>S</span>
+            <div>{{ lookWorkData.name }}</div>
+          </div>
+          <div class="c_t79_wd_content">
+            <img :src="lookWorkData.content.fileList[lookWorkIndex].url" @click="lookImage(lookWorkData.content.fileList[lookWorkIndex].url)" />
+          </div>
+          <!-- <div class="nextAndUpBtn" v-if="lookWorkData.content.fileList.length>1">
+            <span :class="{no_active:lookWorkIndex==0}" @click="changelookWorkIndex(0)">{{ lang.ssPrevP }}</span>
+            <span :class="{no_active:lookWorkData.content.fileList.length-1<=lookWorkIndex}"  @click="changelookWorkIndex(1)">{{ lang.ssNextP }}</span>
+          </div> -->
+          <div class="cq_changeBtn" v-if="lookWorkData.content.fileList.length > 1">
+            <div :class="{ cq_cb_disabled: lookWorkIndex <= 0 }" @click="changelookWorkIndex(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>{{ lookWorkIndex + 1 }}/{{ lookWorkData.content.fileList.length }}</span>
+            <div :class="{ cq_cb_disabled: lookWorkIndex >= lookWorkData.content.fileList.length - 1 }"
+              @click="changelookWorkIndex(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>
+
       <!-- AI应用 -->
       <div class="c_t72" v-if="props.showData && props.showData.toolType === 72">
         <div class="c_t72_title">{{ lang.ssAiApp }}</div>
@@ -488,7 +541,7 @@ const processWorkContent = async (content: string, toolType: number): Promise<an
   }
 
   try {
-    if ([45, 15, 78].includes(toolType)) {
+    if ([45, 15, 78, 79].includes(toolType)) {
       return JSON.parse(decodeURIComponent(contentToParse))
     }
     else if (toolType === 72) {
@@ -596,11 +649,23 @@ const lookImage = (url: string) => {
   }
 }
 
+const lookWorkIndex = ref<number>(0)
 // 查看作业
 const lookWork = (id: string) => {
+  lookWorkIndex.value = 0
   lookWorkDetail.value = id
 }
 
+// 切换查看作业图片
+const changelookWorkIndex = (type: number) => {
+  if (type === 0 && lookWorkIndex.value > 0) {
+    lookWorkIndex.value = lookWorkIndex.value - 1
+  }
+  else if (type === 1 && lookWorkIndex.value < lookWorkData.value.content.fileList.length - 1) {
+    lookWorkIndex.value = lookWorkIndex.value + 1
+  }
+}
+
 // 选择题图表实例
 const myChart = ref<any>(null)
 
@@ -1703,6 +1768,33 @@ onUnmounted(() => {
             -webkit-line-clamp: 2;
             -webkit-box-orient: vertical;
           }
+
+          .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%;
+              height: 200px;
+              object-fit: cover;
+            }
+
+            span {
+              width: 100%;
+              height: 200px;
+              display: flex;
+              align-items: center;
+              justify-content: center;
+            }
+          }
         }
       }
 
@@ -1772,6 +1864,103 @@ onUnmounted(() => {
           }
         }
       }
+      .c_t79_workDetail {
+        width: 100%;
+        height: auto;
+        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_t79_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_t79_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%;
+            height: 300px;
+            object-fit: cover;
+          }
+        }
+      }
+
+      .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_t72 {
@@ -2246,4 +2435,32 @@ onUnmounted(() => {
     font-weight: 500;
   }
 }
+
+.nextAndUpBtn{
+  width: 100%;
+  height: auto;
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  margin-top: 20px;
+  gap: 15px;
+  &>span{
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 100%;
+    height: 40px;
+    border-radius: 5px;
+    font-size: 14px;
+    font-weight: 500;
+    color: #fff;
+    background: #f6c82b;
+    cursor: pointer;
+  }
+  &>.no_active{
+    background: #cccccc !important;
+    color: #999999 !important;
+    cursor: not-allowed !important;
+    pointer-events: none !important;
+  }
+}
 </style>

+ 3 - 0
src/views/lang/cn.json

@@ -163,6 +163,7 @@
   "ssQandA": "问答",
   "ssVote": "投票",
   "ssPhoto": "拍照",
+  "ssNoPhoto": "暂无拍照",
   "ssNoLearn": "暂无学习内容",
   "ssNeedUpload": "请先上传或创建学习内容",
   "ssPreview": "预览",
@@ -236,6 +237,8 @@
   "ssClose": "关闭",
   "ssPrevQ": "上一题",
   "ssNextQ": "下一题",
+  "ssPrevP": "上一张",
+  "ssNextP": "下一张",
   "ssSingleSel": "单选题",
   "ssMultiSel": "多选题",
   "ssNodeTitle": "节点*",

+ 3 - 0
src/views/lang/en.json

@@ -162,6 +162,7 @@
   "ssQandA": "Q&A",
   "ssVote": "Vote",
   "ssPhoto": "Photo",
+  "ssNoPhoto": "No photo",
   "ssNoLearn": "No learning content",
   "ssNeedUpload": "Please upload or create learning content first",
   "ssPreview": "Preview",
@@ -236,6 +237,8 @@
   "ssClose": "Close",
   "ssPrevQ": "Previous question",
   "ssNextQ": "Next question",
+  "ssPrevP": "Previous photo",
+  "ssNextP": "Next photo",
   "ssSingleSel": "Single Choice",
   "ssMultiSel": "Multiple Choice",
   "ssNodeTitle": "Node *",

+ 3 - 0
src/views/lang/hk.json

@@ -162,6 +162,7 @@
   "ssQandA": "問答",
   "ssVote": "投票",
   "ssPhoto": "拍照",
+  "ssNoPhoto": "暫無拍照",
   "ssNoLearn": "暫無學習內容",
   "ssNeedUpload": "請先上傳或創建學習內容",
   "ssPreview": "預覽",
@@ -236,6 +237,8 @@
   "ssClose": "關閉",
   "ssPrevQ": "上一題",
   "ssNextQ": "下一題",
+  "ssPrevP": "上一張",
+  "ssNextP": "下一張",
   "ssSingleSel": "單選題",
   "ssMultiSel": "多選題",
   "ssNodeTitle": "節點*",