Переглянути джерело

优化AI生成课生成主题内容动态绑定

liyanbo 1 місяць тому
батько
коміт
7a6ee5d1c9
1 змінених файлів з 70 додано та 49 видалено
  1. 70 49
      src/components/study/SelfDirectedLearning.vue

+ 70 - 49
src/components/study/SelfDirectedLearning.vue

@@ -9,14 +9,14 @@
       <div class="dialogue-card user-input-card">
         <div class="dialogue-content">
           <textarea
-            v-model="prompt"
-            class="user-input-textarea"
-            placeholder=""
-            @keyup.enter.exact="doSendMessage(prompt.trim())"
+              v-model="prompt"
+              class="user-input-textarea"
+              placeholder=""
+              @keyup.enter.exact="doSendMessage(prompt.trim())"
           ></textarea>
           <div class="dropdowns-container">
             <!-- 生成主题下拉框 -->
-              <el-select
+            <el-select
                 v-model="courseDropdown.value"
                 filterable
                 placeholder=""
@@ -24,21 +24,21 @@
                 class="custom-select"
                 no-match-text="无匹配数据"
                 @visible-change="handleVisibleChange('course', $event)"
-              >
+            >
               <template #prefix>
                 <el-icon><component :is="courseDropdown.icon" /></el-icon>
               </template>
-                <el-option
+              <el-option
                   v-for="item in courseDropdown.options"
                   :key="item.value"
                   :label="item.label"
                   :value="item.value"
                   class="provinces_select"
                   @click="handleSelect('course', item.value)"
-                />
-              </el-select>
-              <!-- 主讲下拉框 -->
-              <el-select
+              />
+            </el-select>
+            <!-- 主讲下拉框 -->
+            <el-select
                 v-model="teacherDropdown.value"
                 filterable
                 placeholder=""
@@ -46,21 +46,21 @@
                 class="custom-select"
                 no-match-text="无匹配数据"
                 @visible-change="handleVisibleChange('teacher', $event)"
-              >
+            >
               <template #prefix>
                 <el-icon><component :is="teacherDropdown.icon" /></el-icon>
               </template>
-                <el-option
+              <el-option
                   v-for="item in teacherDropdown.options"
                   :key="item.value"
                   :label="item.label"
                   :value="item.value"
                   class="provinces_select"
                   @click="handleSelect('teacher', item.value)"
-                />
-              </el-select>
-              <!-- 助教下拉框 -->
-              <el-select
+              />
+            </el-select>
+            <!-- 助教下拉框 -->
+            <el-select
                 v-model="assistantDropdown.value"
                 filterable
                 placeholder=""
@@ -68,19 +68,19 @@
                 class="custom-select"
                 no-match-text="无匹配数据"
                 @visible-change="handleVisibleChange('assistant', $event)"
-              >
+            >
               <template #prefix>
                 <el-icon><component :is="assistantDropdown.icon" /></el-icon>
               </template>
-                <el-option
+              <el-option
                   v-for="item in assistantDropdown.options"
                   :key="item.value"
                   :label="item.label"
                   :value="item.value"
                   class="provinces_select"
                   @click="handleSelect('assistant', item.value)"
-                />
-              </el-select>
+              />
+            </el-select>
           </div>
           <button class="send-button" :class="{ 'active': prompt.trim().length > 0 && (!showNewContainer || allStepsCompleted) }" @click="doSendMessage(prompt.trim())" :disabled="!prompt.trim().length || (showNewContainer && !allStepsCompleted)">
             <Top />
@@ -135,7 +135,7 @@
 </template>
 
 <script setup>
-import {ref, onMounted, computed, reactive, defineEmits} from "vue";
+import {ref, onMounted, computed, reactive, defineEmits, watch} from "vue";
 
 // 定义事件
 const emit = defineEmits(['refreshData']);
@@ -320,9 +320,9 @@ const generateScript = async () => {
     await createAiRoleIdConversation(256)
     const role = localScriptRoles.value.find((r) => r.name === selectedMainTeacher.value)
     const assistants = selectedAssistants.value.map(rName => {
-        const assistantRole = localScriptRoles.value.find(r => r.name === rName)
-        return `${assistantRole.name}[${assistantRole.description}]`
-      }).join(',')
+      const assistantRole = localScriptRoles.value.find(r => r.name === rName)
+      return `${assistantRole.name}[${assistantRole.description}]`
+    }).join(',')
     let content = `${prompt.value}(主讲人:${role.name},主讲人角色定位:${role.description};助讲有:${assistants});`
     content += `我需要让你生成${lessonList.value.length}节课程;${lessonList.value.map((lesson, index) => `第${index+1}节课程是${lesson.name};`).join('')}`
 
@@ -691,8 +691,8 @@ const stopImagePolling = () => {
 // 轮询生成中的图片列表
 const refreshWatchImages = async () => {
   const imageIds = Object.keys(inProgressImageMap.value)
-    .map(Number)
-    .filter(id => !isNaN(id))
+      .map(Number)
+      .filter(id => !isNaN(id))
   if (imageIds.length === 0) {
     return
   }
@@ -768,7 +768,7 @@ const refreshWatchImages = async () => {
       }
     })
     inProgressImageMap.value = newWatchImages
-    
+
     // 更新进度
     progressCounters.value.images.current = completedCount
     if (progressCounters.value.images.total > 0) {
@@ -918,14 +918,31 @@ const assistantOptions = computed(() => {
   return options;
 });
 
-// 计算生成主题下拉框选项
-const courseOptions = computed(() => {
-  const options = lessonList.value.map(lesson => ({
-    label: lesson.name,
-    value: lesson.id
-  }));
-  return options;
-});
+// 生成主题下拉框选项
+const themeOptions = computed(() => {
+  // 主题数据数组,可以根据需要添加更多主题
+  const themes = [
+    {
+      name: '诗词课',
+      value: 256, // 诗词课生成脚本id
+      sections: [1, 2, 3] // 绑定课程小节id
+    },
+  ]
+  
+  // 为每个主题添加label getter
+  return themes.map(theme => ({
+    ...theme,
+    get label() {
+      const lessonNames = this.sections
+        .map(sectionId => {
+          const lesson = lessonList.value.find(l => l.id === sectionId.toString())
+          return lesson ? lesson.name : ''
+        })
+        .filter(Boolean)
+      return `${this.name}(${lessonNames.join(', ')})`
+    }
+  }))
+})
 
 /**
  * 获取角色列表
@@ -956,9 +973,14 @@ const courseDropdown = ref({
   value: '生成主题',
   visible: false,
   icon: Search,
-  options: courseOptions.value
+  options: []
 });
 
+// 监听themeOptions变化,更新courseDropdown.options
+watch(themeOptions, (newOptions) => {
+  courseDropdown.value.options = newOptions;
+}, { immediate: true });
+
 const teacherDropdown = ref({
   key: 'teacher',
   value: '主讲',
@@ -975,11 +997,10 @@ const assistantDropdown = ref({
   options: assistantOptions.value
 });
 
-
 // 处理下拉框选择
 const handleSelect = (key, command) => {
   if (key === 'course' && courseDropdown.value) {
-     courseDropdown.value.value = command;
+    courseDropdown.value.value = command;
   }
   else if (key === 'teacher' && teacherDropdown.value) {
     teacherDropdown.value.value = command;
@@ -1050,11 +1071,11 @@ const allStepsCompleted = computed(() => {
 onMounted(async () => {
   // 初始状态下不显示生成进度
   showNewContainer.value = false;
-  
+
   await getRoleList();
 
   // 初始化生成主题下拉框选项
-  courseDropdown.value.options = courseOptions.value;
+  courseDropdown.value.options = themeOptions.value;
   // 初始化主讲下拉框选项
   teacherDropdown.value.options = teacherOptions.value;
   // 初始化助教下拉框选项
@@ -1226,7 +1247,7 @@ onMounted(async () => {
   background: #a8a8a8;
 }
 
- .provinces_select {
+.provinces_select {
   font-size: rpx(8);
   color: black;
   border-radius: rpx(5);
@@ -1244,9 +1265,9 @@ onMounted(async () => {
 .provinces_select:focus,
 .provinces_select.is-active {
   background: linear-gradient(
-    to bottom,
-    #fee78a,
-    #ffce1b
+          to bottom,
+          #fee78a,
+          #ffce1b
   );
   border: none;
   outline: none;
@@ -1313,9 +1334,9 @@ onMounted(async () => {
 
 .send-button.active {
   background: linear-gradient(
-    to bottom,
-    #ffefb0,
-    #ffcc00
+          to bottom,
+          #ffefb0,
+          #ffcc00
   );
   color: white;
   border: none;
@@ -1617,4 +1638,4 @@ onMounted(async () => {
   50% { opacity: 0.6; transform: scale(1.2); }
 }
 
-</style>
+</style>