Kaynağa Gözat

1、用户信息加入AI诗词课权限状态
2、生成课程模版提示词拆分通用和诗词课

liyanbo 3 hafta önce
ebeveyn
işleme
1c1cc44a37

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

@@ -192,7 +192,7 @@ const SCRIPT_DATA_KEY = 'scriptData'
 // 小节列表(包含详细讲解要求,适用于所有课程类型)
 const lessonList = ref([
   {
-    id: '1', 
+    id: '1',
     name: '课程引入',
     description: '作为课程的开篇,建立学习背景,引发学生兴趣',
     requirements: `
@@ -205,7 +205,7 @@ const lessonList = ref([
     `.trim()
   },
   {
-    id: '2', 
+    id: '2',
     name: '知识讲解',
     description: '深入解析课程内容,详细讲解知识点',
     requirements: `
@@ -218,7 +218,7 @@ const lessonList = ref([
     `.trim()
   },
   {
-    id: '3', 
+    id: '3',
     name: '课程总结',
     description: '回顾课程内容,总结要点,拓展延伸',
     requirements: `
@@ -229,7 +229,39 @@ const lessonList = ref([
       5. 布置简单的课后思考或练习建议
       要求:条理清晰,重点突出,语言简洁,易于记忆,篇幅适中,结构为:回顾要点→总结方法→拓展延伸→课后建议
     `.trim()
-  }
+  },
+
+
+  {
+    id: '4',
+    name: '初识诗境',
+    description: '读·共读辨情,初识诗境',
+    requirements: ``.trim()
+  },
+  {
+    id: '5',
+    name: '解码精神',
+    description: '悟·深究共情,解码精神',
+    requirements: ``.trim()
+  },
+  {
+    id: '6',
+    name: '联结现实',
+    description: '用·印证文脉,联结现实',
+    requirements: ``.trim()
+  },
+  {
+    id: '7',
+    name: '创意表达',
+    description: '创·汲智明志,创意表达',
+    requirements: ``.trim()
+  },
+  {
+    id: '8',
+    name: '知行合一',
+    description: '评·多元评价,知行合一',
+    requirements: ``.trim()
+  },
 ])
 // 主讲人、助讲人
 const selectedMainTeacher = ref('')
@@ -545,13 +577,13 @@ const generateScript = async () => {
 
           let lesson = lessonList.value[i]
           progressSteps.value[1].text = "生成课程小节【" + lesson.name + "】..."
-          
+
           // 构建当前小节的专属提示词(只针对当前小节)
           let content = `${baseContent}。这是系列课程的第${i+1}节,本节主题:【${lesson.name}】。${lesson.requirements}`
 
           // 创建独立的输出对象,避免数据污染
           let lessonInfo = {courseName: lesson.name, courseLabel: lesson.id};
-          
+
           try {
             await doSendMessageStream(activeConversationId.value, content, lessonInfo)
           } catch (error) {
@@ -591,7 +623,7 @@ const generateScript = async () => {
       if (isCancelled.value) return
 
       currentStep.value = 2
-      
+
       // 重置图片进度为0%
       progressSteps.value[2].progress = 0
       progressCounters.value.images.current = 0
@@ -853,15 +885,15 @@ const generateAllImages = async () => {
       // ========== 计算总图片数 ==========
       // 清空轮询列表,每次都重新生成
       inProgressImageMap.value = {}
-      
+
       // 统计需要生成的图片总数(有prompt且无url的图片)
       progressCounters.value.images.total = 0
-      
+
       // 统计封面图
       if (scriptData.coverImage && scriptData.coverImage.prompt && !scriptData.coverImage.url) {
         progressCounters.value.images.total++
       }
-      
+
       // 统计所有环节的背景图
       if (scriptData.lessons && scriptData.lessons.length > 0) {
         for (let lessonIndex = 0; lessonIndex < scriptData.lessons.length; lessonIndex++) {
@@ -876,10 +908,10 @@ const generateAllImages = async () => {
           }
         }
       }
-      
+
       // 初始化已完成数为0
       progressCounters.value.images.current = 0
-      
+
       // 更新进度显示
       if (progressCounters.value.images.total > 0) {
         progressSteps.value[2].progress = 0
@@ -936,7 +968,7 @@ const generateAllImages = async () => {
       } else {
         // 先停止之前的定时器,避免多个定时器同时运行
         stopImagePolling()
-        
+
         // 启动轮询检查图片生成状态
         startImagePolling()
         console.log('启动图片完成检查定时器')
@@ -1169,7 +1201,7 @@ const refreshWatchImages = async () => {
     // 计算当前已完成的图片数量(重新统计,避免刷新后累加导致超过100%)
     const completedImages = progressCounters.value.images.total - Object.keys(inProgressImageMap.value).length
     progressCounters.value.images.current = completedImages
-    
+
     // 更新进度百分比
     if (progressCounters.value.images.total > 0) {
       const newProgress = Math.round((completedImages / progressCounters.value.images.total) * 100)
@@ -1365,7 +1397,7 @@ const themeOptions = ref([
   {
     name: '诗词课',
     value: 256,
-    sections: [1, 2, 3],
+    sections: [4, 5, 6, 7, 8],
     show: true,
     get label() {
       const lessonNames = this.sections
@@ -1642,7 +1674,7 @@ onUnmounted(() => {
 
   // 清除脚本数据缓存
   localStorage.removeItem(SCRIPT_DATA_KEY)
-  
+
   console.log('组件已卸载,所有资源已清理')
 });
 </script>
@@ -2219,4 +2251,4 @@ onUnmounted(() => {
   min-width: rpx(30);
   text-align: right;
 }
-</style>
+</style>

+ 9 - 1
src/components/user/UserInfoPopover.vue

@@ -37,8 +37,15 @@
               <span v-if="userInfo.isRegister">{{ userInfo.aiCourseExpireTime ? userInfo.aiCourseExpireTime+' 到期' : '无权限' }}</span>
               <span v-else>{{userInfo.roleRouteSet.includes(ROLE_KEY.AI_COURSE) ? '已开通' : '未开通'}}</span>
             </div>
+            <div class="course-item">
+              <div class="check-circle">✓</div>
+              <span>AI诗词课:</span>
+              <span v-if="userInfo.isRegister">{{ userInfo.aiPoetryExpireTime ? userInfo.aiPoetryExpireTime+' 到期' : '无权限' }}</span>
+              <span v-else>{{userInfo.roleRouteSet.includes(ROLE_KEY.AI_POETRY) ? '已开通' : '未开通'}}</span>
+            </div>
           </div>
         </div>
+
         <!-- 激活码 -->
         <div class="bottom-box">
            <el-input
@@ -86,6 +93,7 @@ const userInfo = ref({
   courseExpireTime: null,
   blocklyExpireTime: null,
   aiCourseExpireTime: null,
+  aiPoetryExpireTime: null,
 })
 
 // 下拉框可见性状态
@@ -364,4 +372,4 @@ onMounted(() => {
   outline: none;
   box-shadow: none;
 }
-</style>
+</style>

+ 3 - 2
src/utils/roleUtils.js

@@ -12,7 +12,8 @@ const CONFIG = {
 const ROLE_KEY = {
     COURSE: 'course',
     BLOCKLY: 'blockly',
-    AI_COURSE: 'aiCourse'
+    AI_COURSE: 'aiCourse',
+    AI_POETRY: 'aiPoetry'
 }
 
 /**
@@ -87,4 +88,4 @@ const getRoleRouteCache = () => {
 }
 
 
-export { CONFIG,ROLE_KEY,setCacheWithExpiry,getRoleRouteCache };
+export { CONFIG,ROLE_KEY,setCacheWithExpiry,getRoleRouteCache };