|
@@ -1,6 +1,7 @@
|
|
|
<template>
|
|
<template>
|
|
|
<!-- AI发展历程 -->
|
|
<!-- AI发展历程 -->
|
|
|
<div class="home-container">
|
|
<div class="home-container">
|
|
|
|
|
+
|
|
|
<!-- 展开收起侧边栏 -->
|
|
<!-- 展开收起侧边栏 -->
|
|
|
<div
|
|
<div
|
|
|
class="icon-expand"
|
|
class="icon-expand"
|
|
@@ -17,248 +18,237 @@
|
|
|
}"
|
|
}"
|
|
|
>||</span
|
|
>||</span
|
|
|
>
|
|
>
|
|
|
- <div class="icon-expand">
|
|
|
|
|
- <el-icon
|
|
|
|
|
- @click="toggleDrawer"
|
|
|
|
|
- :style="{ color: drawerVisible ? 'white' : '#B6B0D8' }"
|
|
|
|
|
- >
|
|
|
|
|
- <component :is="drawerVisible ? Fold : Expand" />
|
|
|
|
|
- <!-- <Tickets /> -->
|
|
|
|
|
- </el-icon>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
- <el-drawer
|
|
|
|
|
- v-model="drawerVisible"
|
|
|
|
|
- direction="ltr"
|
|
|
|
|
- size="18%"
|
|
|
|
|
- :with-header="false"
|
|
|
|
|
- >
|
|
|
|
|
- <!-- 添加抽屉 -->
|
|
|
|
|
- <div class="drawer-box">
|
|
|
|
|
- <el-row class="tac">
|
|
|
|
|
- <el-col :span="12">
|
|
|
|
|
- <span class="mb-2">
|
|
|
|
|
- <img :src="classImages" alt="课程小节图标" />
|
|
|
|
|
- 课程小节
|
|
|
|
|
- </span>
|
|
|
|
|
- <el-menu
|
|
|
|
|
- :default-active="activeMenuIndex"
|
|
|
|
|
- @open="handleOpen"
|
|
|
|
|
- @close="handleClose"
|
|
|
|
|
- @select="handleSelect"
|
|
|
|
|
- :default-openeds="['3']"
|
|
|
|
|
- >
|
|
|
|
|
- <template v-for="item in menuItems" :key="item.index">
|
|
|
|
|
- <el-menu-item v-if="!item.children" :index="item.index">{{
|
|
|
|
|
- item.title
|
|
|
|
|
- }}</el-menu-item>
|
|
|
|
|
- <el-sub-menu v-else :index="item.index">
|
|
|
|
|
- <template #title>
|
|
|
|
|
- <span>{{ item.title }}</span>
|
|
|
|
|
- </template>
|
|
|
|
|
- <el-menu-item-group v-if="item.children">
|
|
|
|
|
- <template
|
|
|
|
|
- v-for="child in item.children"
|
|
|
|
|
- :key="child.index"
|
|
|
|
|
|
|
+ <el-drawer
|
|
|
|
|
+ v-model="drawerVisible"
|
|
|
|
|
+ direction="ltr"
|
|
|
|
|
+ size="18%"
|
|
|
|
|
+ :with-header="false"
|
|
|
|
|
+ >
|
|
|
|
|
+ <!-- 添加抽屉 -->
|
|
|
|
|
+ <div class="drawer-box">
|
|
|
|
|
+ <el-row class="tac">
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <span class="mb-2">
|
|
|
|
|
+ <img :src="classImages" alt="课程小节图标" />
|
|
|
|
|
+ 课程小节
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <el-menu
|
|
|
|
|
+ :default-active="activeMenuIndex"
|
|
|
|
|
+ @open="handleOpen"
|
|
|
|
|
+ @close="handleClose"
|
|
|
|
|
+ @select="handleSelect"
|
|
|
|
|
+ :default-openeds="['3']"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template v-for="item in menuItems" :key="item.index">
|
|
|
|
|
+ <el-menu-item v-if="!item.children" :index="item.index">{{
|
|
|
|
|
+ item.title
|
|
|
|
|
+ }}</el-menu-item>
|
|
|
|
|
+ <el-sub-menu v-else :index="item.index">
|
|
|
|
|
+ <template #title>
|
|
|
|
|
+ <span>{{ item.title }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <el-menu-item-group v-if="item.children">
|
|
|
|
|
+ <template v-for="child in item.children" :key="child.index">
|
|
|
|
|
+ <el-menu-item :index="child.index"
|
|
|
|
|
+ >• {{ child.title }}</el-menu-item
|
|
|
>
|
|
>
|
|
|
- <el-menu-item :index="child.index"
|
|
|
|
|
- >• {{ child.title }}</el-menu-item
|
|
|
|
|
- >
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-menu-item-group>
|
|
|
|
|
- </el-sub-menu>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-menu>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
- </div>
|
|
|
|
|
- </el-drawer>
|
|
|
|
|
-
|
|
|
|
|
- <div class="content-box">
|
|
|
|
|
- <div class="box-1">
|
|
|
|
|
- <div class="inner-box left-box">
|
|
|
|
|
- <div class="box-icon" @click="goBack">
|
|
|
|
|
- <el-icon class="left-icon"><ArrowLeftBold /></el-icon>
|
|
|
|
|
- {{ boxIconTitle }}
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-menu-item-group>
|
|
|
|
|
+ </el-sub-menu>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-menu>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-drawer>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="content-box">
|
|
|
|
|
+ <div class="box-1">
|
|
|
|
|
+ <div class="inner-box left-box">
|
|
|
|
|
+ <div class="box-icon" @click="goBack">
|
|
|
|
|
+ <el-icon class="left-icon"><ArrowLeftBold /></el-icon>
|
|
|
|
|
+ {{ boxIconTitle }}
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="inner-box right-box">
|
|
|
|
|
- <div class="top-right-box">
|
|
|
|
|
- <el-input
|
|
|
|
|
- v-model="SearchInput"
|
|
|
|
|
- class="search-input"
|
|
|
|
|
- placeholder="搜索"
|
|
|
|
|
- >
|
|
|
|
|
- <template #prefix>
|
|
|
|
|
- <el-icon class="el-input__icon"><search /></el-icon>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-input>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="inner-box right-box">
|
|
|
|
|
+ <div class="top-right-box">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="SearchInput"
|
|
|
|
|
+ class="search-input"
|
|
|
|
|
+ placeholder="搜索"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #prefix>
|
|
|
|
|
+ <el-icon class="el-input__icon"><search /></el-icon>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-input>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="box-2">
|
|
|
|
|
+ <!-- 课程标题 autoplay自动播放 @ended="playNextVideo"-->
|
|
|
|
|
+ <div class="small-title">
|
|
|
|
|
+ <span>{{ course.courseName }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="box-video">
|
|
|
|
|
+ <video
|
|
|
|
|
+ class="full-box-video"
|
|
|
|
|
+ :src="course.courseVideoPath"
|
|
|
|
|
+ controlsList="nodownload"
|
|
|
|
|
+ controls
|
|
|
|
|
+ @timeupdate="handleTimeUpdate"
|
|
|
|
|
+ @play="checkVideoPermission"
|
|
|
|
|
+ ref="videoRef"
|
|
|
|
|
+ >
|
|
|
|
|
+ <source :src="course.courseVideoPath" type="video/mp4" />
|
|
|
|
|
+ 您的浏览器不支持视频播放。
|
|
|
|
|
+ </video>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
- <div class="box-2">
|
|
|
|
|
- <!-- 课程标题 autoplay自动播放 @ended="playNextVideo"-->
|
|
|
|
|
- <div class="small-title">
|
|
|
|
|
- <span>{{ course.courseName }}</span>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="box-video">
|
|
|
|
|
- <video
|
|
|
|
|
- class="full-box-video"
|
|
|
|
|
- :src="course.courseVideoPath"
|
|
|
|
|
- controlsList="nodownload"
|
|
|
|
|
- controls
|
|
|
|
|
- @timeupdate="handleTimeUpdate"
|
|
|
|
|
- @play="checkVideoPermission"
|
|
|
|
|
- ref="videoRef"
|
|
|
|
|
|
|
+ <!-- 添加切换视频 -->
|
|
|
|
|
+ <div class="video-switch">
|
|
|
|
|
+ <!-- 上一个视频 -->
|
|
|
|
|
+ <div class="caret-left" @click="playPreviousVideo">
|
|
|
|
|
+ <el-button type="warning" round>
|
|
|
|
|
+ <img :src="leftImg" alt="Left" />
|
|
|
|
|
+ 上一节</el-button
|
|
|
>
|
|
>
|
|
|
- <source :src="course.courseVideoPath" type="video/mp4" />
|
|
|
|
|
- 您的浏览器不支持视频播放。
|
|
|
|
|
- </video>
|
|
|
|
|
</div>
|
|
</div>
|
|
|
-
|
|
|
|
|
- <!-- 添加切换视频 -->
|
|
|
|
|
- <div class="video-switch">
|
|
|
|
|
- <!-- 上一个视频 -->
|
|
|
|
|
- <div class="caret-left" @click="playPreviousVideo">
|
|
|
|
|
- <el-button type="warning" round>
|
|
|
|
|
- <img :src="leftImg" alt="Left" />
|
|
|
|
|
- 上一节</el-button
|
|
|
|
|
- >
|
|
|
|
|
- </div>
|
|
|
|
|
- <!-- 下一个视频 -->
|
|
|
|
|
- <div class="caret-right" @click="playNextVideo">
|
|
|
|
|
- <el-button type="warning" round
|
|
|
|
|
- >下一节
|
|
|
|
|
- <img :src="rightImg" alt="Right" />
|
|
|
|
|
- </el-button>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <!-- 下一个视频 -->
|
|
|
|
|
+ <div class="caret-right" @click="playNextVideo">
|
|
|
|
|
+ <el-button type="warning" round
|
|
|
|
|
+ >下一节
|
|
|
|
|
+ <img :src="rightImg" alt="Right" />
|
|
|
|
|
+ </el-button>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- <!-- 添加试题弹框 -->
|
|
|
|
|
- <transition name="fade-scale">
|
|
|
|
|
- <div
|
|
|
|
|
- v-show="questionDialogVisible"
|
|
|
|
|
- class="child-dialog-wrapper"
|
|
|
|
|
- @click.self="handleCloseQuestionDialog"
|
|
|
|
|
- >
|
|
|
|
|
- <div class="child-dialog">
|
|
|
|
|
- <div class="question-title">
|
|
|
|
|
- <span class="question-icon">?</span>
|
|
|
|
|
- <span v-html="courseConfig.ccQuestContent"></span>
|
|
|
|
|
- </div>
|
|
|
|
|
- <!-- 选项区域 -->
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <!-- 添加试题弹框 -->
|
|
|
|
|
+ <transition name="fade-scale">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-show="questionDialogVisible"
|
|
|
|
|
+ class="child-dialog-wrapper"
|
|
|
|
|
+ @click.self="handleCloseQuestionDialog"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="child-dialog">
|
|
|
|
|
+ <div class="question-title">
|
|
|
|
|
+ <span class="question-icon">?</span>
|
|
|
|
|
+ <span v-html="courseConfig.ccQuestContent"></span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <!-- 选项区域 -->
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-if="
|
|
|
|
|
+ courseConfig.ccQuestOption &&
|
|
|
|
|
+ courseConfig.ccQuestOption.length > 0
|
|
|
|
|
+ "
|
|
|
|
|
+ class="options-container"
|
|
|
|
|
+ >
|
|
|
<div
|
|
<div
|
|
|
- v-if="
|
|
|
|
|
- courseConfig.ccQuestOption &&
|
|
|
|
|
- courseConfig.ccQuestOption.length > 0
|
|
|
|
|
- "
|
|
|
|
|
- class="options-container"
|
|
|
|
|
|
|
+ v-for="(option, index) in courseConfig.ccQuestOption"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ class="question-option"
|
|
|
>
|
|
>
|
|
|
- <div
|
|
|
|
|
- v-for="(option, index) in courseConfig.ccQuestOption"
|
|
|
|
|
- :key="index"
|
|
|
|
|
- class="question-option"
|
|
|
|
|
|
|
+ <el-radio
|
|
|
|
|
+ v-model="selectedOption"
|
|
|
|
|
+ :label="index"
|
|
|
|
|
+ :value="option"
|
|
|
|
|
+ v-cloak="(selectedOption = option)"
|
|
|
>
|
|
>
|
|
|
- <el-radio
|
|
|
|
|
- v-model="selectedOption"
|
|
|
|
|
- :label="index"
|
|
|
|
|
- :value="option"
|
|
|
|
|
- v-cloak="(selectedOption = option)"
|
|
|
|
|
- >
|
|
|
|
|
- <span>{{ option }}</span>
|
|
|
|
|
- </el-radio>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div v-else class="no-options">
|
|
|
|
|
- <!-- 暂无选项-->
|
|
|
|
|
|
|
+ <span>{{ option }}</span>
|
|
|
|
|
+ </el-radio>
|
|
|
</div>
|
|
</div>
|
|
|
- <!-- 底部按钮 -->
|
|
|
|
|
- <div class="dialog-footer">
|
|
|
|
|
- <!-- <el-button class="child-button cancel" @click="questionDialogVisible = false; showAIDialog = false">取消</el-button>-->
|
|
|
|
|
- <el-button
|
|
|
|
|
- class="child-button confirm"
|
|
|
|
|
- @click="handleSubmitAnswer"
|
|
|
|
|
- >确定</el-button
|
|
|
|
|
- >
|
|
|
|
|
- </div>
|
|
|
|
|
- <!-- 右侧小图标 -->
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-else class="no-options">
|
|
|
|
|
+ <!-- 暂无选项-->
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <!-- 底部按钮 -->
|
|
|
|
|
+ <div class="dialog-footer">
|
|
|
|
|
+ <!-- <el-button class="child-button cancel" @click="questionDialogVisible = false; showAIDialog = false">取消</el-button>-->
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ class="child-button confirm"
|
|
|
|
|
+ @click="handleSubmitAnswer"
|
|
|
|
|
+ >确定</el-button
|
|
|
|
|
+ >
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <!-- 右侧小图标 -->
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-if="aiAnswer !== null"
|
|
|
|
|
+ class="ai-icon-container"
|
|
|
|
|
+ @click="handleAIClick"
|
|
|
|
|
+ >
|
|
|
|
|
+ <img
|
|
|
|
|
+ src="@/assets/images/xiaozhi.png"
|
|
|
|
|
+ alt="AI对话"
|
|
|
|
|
+ class="ai-icon"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span class="ai-text">小智智能助手</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </transition>
|
|
|
|
|
+ <!-- AI对话弹框 -->
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-show="showAIDialog"
|
|
|
|
|
+ class="ai-dialog-wrapper"
|
|
|
|
|
+ @click.self="showAIDialog = false"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="ai-dialog">
|
|
|
|
|
+ <div class="ai-dialog-header">
|
|
|
|
|
+ <h3>
|
|
|
|
|
+ <img :src="auto" alt="" />
|
|
|
|
|
+ 小智智能助手
|
|
|
|
|
+ </h3>
|
|
|
|
|
+ <el-button @click="showAIDialog = false" class="close-btn"
|
|
|
|
|
+ >×</el-button
|
|
|
|
|
+ >
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="ai-dialog-content">
|
|
|
|
|
+ <div class="ai-message-history">
|
|
|
<div
|
|
<div
|
|
|
- v-if="aiAnswer !== null"
|
|
|
|
|
- class="ai-icon-container"
|
|
|
|
|
- @click="handleAIClick"
|
|
|
|
|
|
|
+ v-for="(message, index) in messageHistory"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ :class="['message', message.type]"
|
|
|
>
|
|
>
|
|
|
<img
|
|
<img
|
|
|
- src="@/assets/images/xiaozhi.png"
|
|
|
|
|
- alt="AI对话"
|
|
|
|
|
- class="ai-icon"
|
|
|
|
|
|
|
+ v-if="message.type === 'user'"
|
|
|
|
|
+ src="@/assets/images/user.png"
|
|
|
|
|
+ class="avatar user"
|
|
|
/>
|
|
/>
|
|
|
- <span class="ai-text">小智智能助手</span>
|
|
|
|
|
|
|
+ <img v-else src="@/assets/images/xiaozhi.png" class="avatar" />
|
|
|
|
|
+ <div class="message-content" v-html="message.content"></div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- </div>
|
|
|
|
|
- </transition>
|
|
|
|
|
- <!-- AI对话弹框 -->
|
|
|
|
|
- <div
|
|
|
|
|
- v-show="showAIDialog"
|
|
|
|
|
- class="ai-dialog-wrapper"
|
|
|
|
|
- @click.self="showAIDialog = false"
|
|
|
|
|
- >
|
|
|
|
|
- <div class="ai-dialog">
|
|
|
|
|
- <div class="ai-dialog-header">
|
|
|
|
|
- <h3>
|
|
|
|
|
- <img :src="auto" alt="" />
|
|
|
|
|
- 小智智能助手
|
|
|
|
|
- </h3>
|
|
|
|
|
- <el-button @click="showAIDialog = false" class="close-btn"
|
|
|
|
|
- >×</el-button
|
|
|
|
|
- >
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="ai-dialog-content">
|
|
|
|
|
- <div class="ai-message-history">
|
|
|
|
|
- <div
|
|
|
|
|
- v-for="(message, index) in messageHistory"
|
|
|
|
|
- :key="index"
|
|
|
|
|
- :class="['message', message.type]"
|
|
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="userMessage"
|
|
|
|
|
+ placeholder="输入问题..."
|
|
|
|
|
+ class="user-input"
|
|
|
|
|
+ @keyup.enter="sendMessage"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #append class="flex flex-wrap items-center mb-4">
|
|
|
|
|
+ <!-- <el-button @click="sendMessage" class="child-button confirm">发送</el-button>-->
|
|
|
|
|
+ <el-button @click="sendMessage" size="large" round
|
|
|
|
|
+ >发送</el-button
|
|
|
>
|
|
>
|
|
|
- <img
|
|
|
|
|
- v-if="message.type === 'user'"
|
|
|
|
|
- src="@/assets/images/user.png"
|
|
|
|
|
- class="avatar user"
|
|
|
|
|
- />
|
|
|
|
|
- <img
|
|
|
|
|
- v-else
|
|
|
|
|
- src="@/assets/images/xiaozhi.png"
|
|
|
|
|
- class="avatar"
|
|
|
|
|
- />
|
|
|
|
|
- <div class="message-content" v-html="message.content"></div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <el-input
|
|
|
|
|
- v-model="userMessage"
|
|
|
|
|
- placeholder="输入问题..."
|
|
|
|
|
- class="user-input"
|
|
|
|
|
- @keyup.enter="sendMessage"
|
|
|
|
|
- >
|
|
|
|
|
- <template #append class="flex flex-wrap items-center mb-4">
|
|
|
|
|
- <!-- <el-button @click="sendMessage" class="child-button confirm">发送</el-button>-->
|
|
|
|
|
- <el-button @click="sendMessage" size="large" round
|
|
|
|
|
- >发送</el-button
|
|
|
|
|
- >
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-input>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-input>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
|
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
|
|
import { useRouter } from 'vue-router'
|
|
import { useRouter } from 'vue-router'
|
|
|
-import { Expand, Fold, Memo } from '@element-plus/icons-vue'
|
|
|
|
|
|
|
+import {
|
|
|
|
|
+ Expand,
|
|
|
|
|
+ Fold,
|
|
|
|
|
+ Memo
|
|
|
|
|
+} from '@element-plus/icons-vue'
|
|
|
import { Search, ArrowLeftBold } from '@element-plus/icons-vue'
|
|
import { Search, ArrowLeftBold } from '@element-plus/icons-vue'
|
|
|
import {
|
|
import {
|
|
|
ElMessage,
|
|
ElMessage,
|
|
@@ -288,6 +278,7 @@ const toggleDrawer = () => {
|
|
|
drawerVisible.value = !drawerVisible.value
|
|
drawerVisible.value = !drawerVisible.value
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
// 返回上一页
|
|
// 返回上一页
|
|
|
const goBack = () => {
|
|
const goBack = () => {
|
|
|
router.go(-1)
|
|
router.go(-1)
|
|
@@ -303,15 +294,15 @@ const course = ref({})
|
|
|
// 菜单数据
|
|
// 菜单数据
|
|
|
const menuItems = ref([])
|
|
const menuItems = ref([])
|
|
|
// 课程集合数据
|
|
// 课程集合数据
|
|
|
-const videoPathMap = ref({})
|
|
|
|
|
|
|
+const videoPathMap = ref({})
|
|
|
|
|
|
|
|
//课程小节字典(需要新加接口调取字典)
|
|
//课程小节字典(需要新加接口调取字典)
|
|
|
const menuDict = ref({
|
|
const menuDict = ref({
|
|
|
- 1: '课前回顾',
|
|
|
|
|
- 2: '课程引入',
|
|
|
|
|
- 3: '知识讲解',
|
|
|
|
|
- 4: '趣味实操',
|
|
|
|
|
- 5: '课程总结'
|
|
|
|
|
|
|
+ "1": "课前回顾",
|
|
|
|
|
+ "2": "课程引入",
|
|
|
|
|
+ "3": "知识讲解",
|
|
|
|
|
+ "4": "趣味实操",
|
|
|
|
|
+ "5": "课程总结",
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
// 渲染 课程数据结构 以及 视频
|
|
// 渲染 课程数据结构 以及 视频
|
|
@@ -323,58 +314,19 @@ onMounted(async () => {
|
|
|
const res = await ClassType(typeId)
|
|
const res = await ClassType(typeId)
|
|
|
courseList.value = res.data
|
|
courseList.value = res.data
|
|
|
|
|
|
|
|
- // 初始化 videoPauseTimes
|
|
|
|
|
- videoPauseTimes.value = {}
|
|
|
|
|
- courseList.value.forEach(course => {
|
|
|
|
|
- if (course.courseVideoPath && course.courseConfigList) {
|
|
|
|
|
- // 每个课程配置里有 ccTime 和 ccQuestContent、ccAiAnswer 字段
|
|
|
|
|
- course.courseConfigList.forEach(config => {
|
|
|
|
|
- if (!videoPauseTimes.value[course.courseVideoPath]) {
|
|
|
|
|
- videoPauseTimes.value[course.courseVideoPath] = {
|
|
|
|
|
- pauseTimes: [],
|
|
|
|
|
- questions: []
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- // 暂停时间
|
|
|
|
|
- if (config.ccTime) {
|
|
|
|
|
- videoPauseTimes.value[course.courseVideoPath].pauseTimes.push(
|
|
|
|
|
- config.ccTime
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- // 问题信息
|
|
|
|
|
- if (config.ccQuestContent) {
|
|
|
|
|
- const cleanedContent = config.ccQuestContent.replace(
|
|
|
|
|
- /<\/?p>/g,
|
|
|
|
|
- ''
|
|
|
|
|
- )
|
|
|
|
|
- videoPauseTimes.value[course.courseVideoPath].questions.push({
|
|
|
|
|
- title: cleanedContent,
|
|
|
|
|
- options: [],
|
|
|
|
|
- aiQuestion: cleanedContent,
|
|
|
|
|
- aiAnswer: config.ccAiAnswer
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
//课程数据
|
|
//课程数据
|
|
|
- courseList.value.forEach((courseTemp, index) => {
|
|
|
|
|
- let menuIndex = courseTemp.courseLabel + '-' + (index + 1)
|
|
|
|
|
|
|
+ courseList.value.forEach((courseTemp,index) => {
|
|
|
|
|
+ let menuIndex = courseTemp.courseLabel + '-' + (index+1);
|
|
|
//填充大纲小节
|
|
//填充大纲小节
|
|
|
- let menu = menuItems.value.find(
|
|
|
|
|
- menu => courseTemp.courseLabel === menu.index
|
|
|
|
|
- )
|
|
|
|
|
- if (menu) {
|
|
|
|
|
- //小节
|
|
|
|
|
- menu.children = menu.children || []
|
|
|
|
|
|
|
+ let menu = menuItems.value.find(menu => courseTemp.courseLabel === menu.index);
|
|
|
|
|
+ if (menu){//小节
|
|
|
|
|
+ menu.children = menu.children || [];
|
|
|
menu.children.push({
|
|
menu.children.push({
|
|
|
key: menuIndex,
|
|
key: menuIndex,
|
|
|
index: menuIndex,
|
|
index: menuIndex,
|
|
|
title: courseTemp.courseName
|
|
title: courseTemp.courseName
|
|
|
})
|
|
})
|
|
|
- } else {
|
|
|
|
|
- //大节
|
|
|
|
|
|
|
+ }else {//大节
|
|
|
menuItems.value.push({
|
|
menuItems.value.push({
|
|
|
key: menuIndex,
|
|
key: menuIndex,
|
|
|
index: courseTemp.courseLabel,
|
|
index: courseTemp.courseLabel,
|
|
@@ -382,12 +334,12 @@ onMounted(async () => {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- courseTemp['key'] = menuIndex
|
|
|
|
|
|
|
+ courseTemp["key"] = menuIndex;
|
|
|
videoPathMap.value[menuIndex] = courseTemp
|
|
videoPathMap.value[menuIndex] = courseTemp
|
|
|
|
|
|
|
|
//确定默认课程
|
|
//确定默认课程
|
|
|
if (index === 0) {
|
|
if (index === 0) {
|
|
|
- course.value = courseTemp
|
|
|
|
|
|
|
+ course.value = courseTemp;
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
@@ -400,9 +352,9 @@ onMounted(async () => {
|
|
|
boxIconTitle.value = String(title)
|
|
boxIconTitle.value = String(title)
|
|
|
}
|
|
}
|
|
|
// 在视频元素上添加时间更新事件监听
|
|
// 在视频元素上添加时间更新事件监听
|
|
|
- if (videoRef.value) {
|
|
|
|
|
- videoRef.value.addEventListener('timeupdate', onTimeUpdate)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // if (videoRef.value) {
|
|
|
|
|
+ // // videoRef.value.addEventListener('timeupdate', onTimeUpdate)
|
|
|
|
|
+ // }
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
// 菜单打开和关闭的处理函数
|
|
// 菜单打开和关闭的处理函数
|
|
@@ -412,7 +364,7 @@ const handleClose = () => {}
|
|
|
// 菜单选择的处理函数
|
|
// 菜单选择的处理函数
|
|
|
const handleSelect = index => {
|
|
const handleSelect = index => {
|
|
|
//测试账号禁用视频
|
|
//测试账号禁用视频
|
|
|
- if (disableVideo(index)) return
|
|
|
|
|
|
|
+ if (disableVideo(index))return;
|
|
|
|
|
|
|
|
const findTitle = items => {
|
|
const findTitle = items => {
|
|
|
for (const item of items) {
|
|
for (const item of items) {
|
|
@@ -431,9 +383,9 @@ const handleSelect = index => {
|
|
|
// 根据索引切换视频,使用新的 videoPathMap
|
|
// 根据索引切换视频,使用新的 videoPathMap
|
|
|
if (videoPathMap.value[index]) {
|
|
if (videoPathMap.value[index]) {
|
|
|
course.value = videoPathMap.value[index]
|
|
course.value = videoPathMap.value[index]
|
|
|
- } else {
|
|
|
|
|
|
|
+ }else {
|
|
|
//视频不存在
|
|
//视频不存在
|
|
|
- Message().notifyWarning('视频不存在!', true)
|
|
|
|
|
|
|
+ Message().notifyWarning('视频不存在!', true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//测试账号禁用视频
|
|
//测试账号禁用视频
|
|
@@ -459,7 +411,7 @@ const flattenMenuItems = () => {
|
|
|
// 播放下一个视频
|
|
// 播放下一个视频
|
|
|
const playNextVideo = () => {
|
|
const playNextVideo = () => {
|
|
|
//测试账号禁用视频
|
|
//测试账号禁用视频
|
|
|
- if (disableVideo()) return
|
|
|
|
|
|
|
+ if (disableVideo())return;
|
|
|
|
|
|
|
|
const allIndices = flattenMenuItems()
|
|
const allIndices = flattenMenuItems()
|
|
|
const currentIndexInList = allIndices.indexOf(course.value.key)
|
|
const currentIndexInList = allIndices.indexOf(course.value.key)
|
|
@@ -472,11 +424,9 @@ const playNextVideo = () => {
|
|
|
once: true
|
|
once: true
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
- // 更新侧边栏选中状态
|
|
|
|
|
- activeMenuIndex.value = nextIndex
|
|
|
|
|
}
|
|
}
|
|
|
// 重置
|
|
// 重置
|
|
|
- pausedIndices = ref({ time: [], newTime: [] })
|
|
|
|
|
|
|
+ pausedIndices = ref({time: [], newTime: []})
|
|
|
userMessage = ref('')
|
|
userMessage = ref('')
|
|
|
messageHistory = ref([])
|
|
messageHistory = ref([])
|
|
|
}
|
|
}
|
|
@@ -485,7 +435,7 @@ const playNextVideo = () => {
|
|
|
// 播放上一个视频
|
|
// 播放上一个视频
|
|
|
const playPreviousVideo = () => {
|
|
const playPreviousVideo = () => {
|
|
|
//测试账号禁用视频
|
|
//测试账号禁用视频
|
|
|
- if (disableVideo()) return
|
|
|
|
|
|
|
+ if (disableVideo())return;
|
|
|
|
|
|
|
|
const allIndices = flattenMenuItems()
|
|
const allIndices = flattenMenuItems()
|
|
|
const currentIndexInList = allIndices.indexOf(course.value.key)
|
|
const currentIndexInList = allIndices.indexOf(course.value.key)
|
|
@@ -498,15 +448,13 @@ const playPreviousVideo = () => {
|
|
|
once: true
|
|
once: true
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
- // 更新侧边栏选中状态
|
|
|
|
|
- activeMenuIndex.value = nextIndex
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 尝试播放视频,处理浏览器自动播放限制
|
|
// 尝试播放视频,处理浏览器自动播放限制
|
|
|
const tryPlayVideo = () => {
|
|
const tryPlayVideo = () => {
|
|
|
//测试账号禁用视频
|
|
//测试账号禁用视频
|
|
|
- if (disableVideo()) return
|
|
|
|
|
|
|
+ if (disableVideo())return;
|
|
|
|
|
|
|
|
const playPromise = videoRef.value.play()
|
|
const playPromise = videoRef.value.play()
|
|
|
if (playPromise !== undefined) {
|
|
if (playPromise !== undefined) {
|
|
@@ -525,45 +473,33 @@ const checkVideoPermission = () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//记录已暂停的内容
|
|
//记录已暂停的内容
|
|
|
- setVideoStop()
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ setVideoStop();
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
//禁用视频
|
|
//禁用视频
|
|
|
const disableVideo = (index = course.value.key) => {
|
|
const disableVideo = (index = course.value.key) => {
|
|
|
- let dis = [
|
|
|
|
|
- '1-6',
|
|
|
|
|
- '1-7',
|
|
|
|
|
- '1-8',
|
|
|
|
|
- '1-9',
|
|
|
|
|
- '1-10',
|
|
|
|
|
- '1-11',
|
|
|
|
|
- '1-12',
|
|
|
|
|
- '1-13',
|
|
|
|
|
- '1-14',
|
|
|
|
|
- '1-15'
|
|
|
|
|
- ]
|
|
|
|
|
-
|
|
|
|
|
- if (
|
|
|
|
|
- localStorage.getItem('userName') === 'aiTest' &&
|
|
|
|
|
- dis.indexOf(index) !== -1
|
|
|
|
|
- ) {
|
|
|
|
|
|
|
+ let dis = ["1-6","1-7","1-8","1-9","1-10","1-11","1-12","1-13","1-14","1-15"]
|
|
|
|
|
+
|
|
|
|
|
+ if (localStorage.getItem('userName') === "aiTest" &&
|
|
|
|
|
+ dis.indexOf(index) !== -1) {
|
|
|
|
|
+
|
|
|
if (videoRef.value) {
|
|
if (videoRef.value) {
|
|
|
// 记录当前播放时间
|
|
// 记录当前播放时间
|
|
|
videoRef.value.pause()
|
|
videoRef.value.pause()
|
|
|
// 阻止用户跳转到新的时间点,将播放时间重置为之前的时间
|
|
// 阻止用户跳转到新的时间点,将播放时间重置为之前的时间
|
|
|
- videoRef.value.currentTime = 0
|
|
|
|
|
|
|
+ videoRef.value.currentTime = 0;
|
|
|
}
|
|
}
|
|
|
//提示禁用// 显示消息框
|
|
//提示禁用// 显示消息框
|
|
|
- Message().notifyWarning('您的账号并未开放此课程!', true)
|
|
|
|
|
- return true
|
|
|
|
|
|
|
+ Message().notifyWarning('您的账号并未开放此课程!', true);
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|
|
|
- return false
|
|
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 视频 ref
|
|
// 视频 ref
|
|
|
const videoRef = ref(null)
|
|
const videoRef = ref(null)
|
|
|
// 记录已经暂停过的时间点索引
|
|
// 记录已经暂停过的时间点索引
|
|
|
-let pausedIndices = ref({ time: [], newTime: [] })
|
|
|
|
|
|
|
+let pausedIndices = ref({time: [], newTime: []})
|
|
|
// 试题弹框显示状态
|
|
// 试题弹框显示状态
|
|
|
const questionDialogVisible = ref(false)
|
|
const questionDialogVisible = ref(false)
|
|
|
// 当前显示的试题
|
|
// 当前显示的试题
|
|
@@ -578,138 +514,7 @@ let userMessage = ref('')
|
|
|
// 消息历史记录
|
|
// 消息历史记录
|
|
|
let messageHistory = ref([])
|
|
let messageHistory = ref([])
|
|
|
|
|
|
|
|
-// 定义每个视频对应的暂停时间和问题
|
|
|
|
|
-const videoPauseTimes = {
|
|
|
|
|
- [video2]: {
|
|
|
|
|
- pauseTimes: [30],
|
|
|
|
|
- questions: [
|
|
|
|
|
- {
|
|
|
|
|
- title: '视频当中发生了什么事情呢?',
|
|
|
|
|
- options: [],
|
|
|
|
|
- aiQuestion: '视频当中发生了什么事情呢',
|
|
|
|
|
- aiAnswer:
|
|
|
|
|
- '让我来告诉你吧:泡泡怪篡改了Ai历史数据,导致Ai系统发生崩溃,所以要修正Ai历史抓到泡泡怪!'
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- [video3]: {
|
|
|
|
|
- pauseTimes: [49],
|
|
|
|
|
- questions: [
|
|
|
|
|
- {
|
|
|
|
|
- title: '同学们,大家了解图灵测试了吗?',
|
|
|
|
|
- options: [],
|
|
|
|
|
- aiQuestion: '视频当中发生了什么事情呢',
|
|
|
|
|
- aiAnswer:
|
|
|
|
|
- '让我来告诉你吧:泡泡怪篡改了Ai历史数据,导致Ai系统发生崩溃,所以要修正Ai历史抓到泡泡怪!'
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- [video4]: {
|
|
|
|
|
- pauseTimes: [2],
|
|
|
|
|
- questions: [
|
|
|
|
|
- {
|
|
|
|
|
- title: '你觉得deepseek、豆包等大模型可以通过图灵测试吗?为什么?',
|
|
|
|
|
- options: [],
|
|
|
|
|
- aiQuestion: '你觉得deepseek、豆包等大模型可以通过图灵测试吗?为什么?',
|
|
|
|
|
- aiAnswer:
|
|
|
|
|
- '大模型已缩短与图灵测试的标志距离,尤其在表面对话层面,但因缺乏深层次理解、逻辑一致性与真实认知,仍无法在严格测试中稳定通过。'
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- [video5]: {
|
|
|
|
|
- pauseTimes: [49],
|
|
|
|
|
- questions: []
|
|
|
|
|
- },
|
|
|
|
|
- [video6]: {
|
|
|
|
|
- pauseTimes: [5]
|
|
|
|
|
- },
|
|
|
|
|
- [video7]: {
|
|
|
|
|
- pauseTimes: [64.5, 91],
|
|
|
|
|
- questions: [
|
|
|
|
|
- {
|
|
|
|
|
- title: '如果你是聊天机器人,你会怎么回答用户呢?',
|
|
|
|
|
- options: [],
|
|
|
|
|
- aiQuestion: '',
|
|
|
|
|
- aiAnswer: ''
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title:
|
|
|
|
|
- '当我们和聊天机器人对话的内容被人类所查看并回答时,隐私信息是否泄露?',
|
|
|
|
|
- options: [],
|
|
|
|
|
- aiQuestion:
|
|
|
|
|
- '当我们和聊天机器人对话的内容被人类所查看并回答时,隐私信息是否泄露?',
|
|
|
|
|
- aiAnswer:
|
|
|
|
|
- '与聊天机器人的对话被人类查看时,隐私泄露风险客\n' +
|
|
|
|
|
- '观存在,尤其是人类介入或安全漏洞场景下。建议优先选择支持本地'
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- [video8]: {
|
|
|
|
|
- pauseTimes: [72],
|
|
|
|
|
- questions: [
|
|
|
|
|
- {
|
|
|
|
|
- title: '如果你身体不舒服时找这样的专家检查,那么它开的药你敢喝吗?',
|
|
|
|
|
- options: [],
|
|
|
|
|
- aiQuestion:
|
|
|
|
|
- '如果你身体不舒服时找这样的专家检查,那么它开的药你敢喝吗?',
|
|
|
|
|
- aiAnswer: '这题没给答案,你自己去查吧!'
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- [video9]: {
|
|
|
|
|
- pauseTimes: [2],
|
|
|
|
|
- questions: [
|
|
|
|
|
- {
|
|
|
|
|
- title: '在生活中,有哪些正在使用的专家系统呢?',
|
|
|
|
|
- options: [],
|
|
|
|
|
- aiQuestion: '在生活中,有哪些正在使用的专家系统呢?',
|
|
|
|
|
- aiAnswer:
|
|
|
|
|
- '在医疗健康领域有复杂疾病协同决策和Ai医生分身与诊断辅助;在水利交通领域的水利厅专家库系统用于项目验收和抢险督查'
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- [video11]: {
|
|
|
|
|
- pauseTimes: [1, 90, 176],
|
|
|
|
|
- questions: [
|
|
|
|
|
- {
|
|
|
|
|
- title: '怎么会有爆炸声?泡泡怪在这里吗?',
|
|
|
|
|
- options: [],
|
|
|
|
|
- aiQuestion: '',
|
|
|
|
|
- aiAnswer: ''
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '同学们喜欢下围棋吗?',
|
|
|
|
|
- options: [],
|
|
|
|
|
- aiQuestion: '',
|
|
|
|
|
- aiAnswer: ''
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title: '为什么AlphaGo要在围棋上攻克真人冠军呢?',
|
|
|
|
|
- options: [],
|
|
|
|
|
- aiQuestion: '为什么AlphaGo要在围棋上攻克真人冠军呢?',
|
|
|
|
|
- aiAnswer:
|
|
|
|
|
- '围棋是人类智力游戏的巅峰,拥有天文数字级的可能性,每颗棋子价值由全局态势动态决定,所以当前一手可能百步之后才显现价值。AlphaGo战胜人类顶尖选手,它证明了Ai不仅能处理规则明确的事物,更能攻克依赖直觉、策略的“人类专属领域”'
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- [video12]: {
|
|
|
|
|
- pauseTimes: [1]
|
|
|
|
|
- },
|
|
|
|
|
- [video13]: {
|
|
|
|
|
- pauseTimes: [62],
|
|
|
|
|
- questions: [
|
|
|
|
|
- {
|
|
|
|
|
- title: '我们一起来感受一下大模型吧!',
|
|
|
|
|
- options: [],
|
|
|
|
|
- aiQuestion: '',
|
|
|
|
|
- aiAnswer: ''
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
// 处理视频时间更新事件
|
|
// 处理视频时间更新事件
|
|
|
-
|
|
|
|
|
const handleTimeUpdate = () => {
|
|
const handleTimeUpdate = () => {
|
|
|
//测试账号禁用视频
|
|
//测试账号禁用视频
|
|
|
if (!videoRef.value) return
|
|
if (!videoRef.value) return
|
|
@@ -718,16 +523,14 @@ const handleTimeUpdate = () => {
|
|
|
|
|
|
|
|
if (!course.value.courseConfigList) return
|
|
if (!course.value.courseConfigList) return
|
|
|
course.value.courseConfigList.forEach(courseCofig => {
|
|
course.value.courseConfigList.forEach(courseCofig => {
|
|
|
|
|
+
|
|
|
//暂停时间
|
|
//暂停时间
|
|
|
let time = courseCofig.ccTime
|
|
let time = courseCofig.ccTime
|
|
|
// 检查是否到达时间点且还未暂停过
|
|
// 检查是否到达时间点且还未暂停过
|
|
|
- let timeIndex = pausedIndices.value.time.indexOf(time)
|
|
|
|
|
|
|
+ let timeIndex = pausedIndices.value.time.indexOf(time);
|
|
|
|
|
+
|
|
|
|
|
+ if (currentTime === time && (timeIndex === -1 || Date.now() - pausedIndices.value.newTime[timeIndex] > 1000) ) {
|
|
|
|
|
|
|
|
- if (
|
|
|
|
|
- currentTime === time &&
|
|
|
|
|
- (timeIndex === -1 ||
|
|
|
|
|
- Date.now() - pausedIndices.value.newTime[timeIndex] > 1000)
|
|
|
|
|
- ) {
|
|
|
|
|
videoRef.value.pause()
|
|
videoRef.value.pause()
|
|
|
|
|
|
|
|
// 显示对应的问题
|
|
// 显示对应的问题
|
|
@@ -749,6 +552,22 @@ const handleCloseQuestionDialog = () => {
|
|
|
questionDialogVisible.value = false
|
|
questionDialogVisible.value = false
|
|
|
// 继续播放视频
|
|
// 继续播放视频
|
|
|
videoRef.value.play()
|
|
videoRef.value.play()
|
|
|
|
|
+
|
|
|
|
|
+ //记录已暂停的内容
|
|
|
|
|
+ setVideoStop();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//记录已暂停的内容
|
|
|
|
|
+const setVideoStop = () => {
|
|
|
|
|
+ const currentTime = parseInt(videoRef.value.currentTime)
|
|
|
|
|
+ let timeIndex = pausedIndices.value.time.indexOf(currentTime);
|
|
|
|
|
+ if (timeIndex === -1) {
|
|
|
|
|
+ pausedIndices.value.time.push(currentTime)
|
|
|
|
|
+ pausedIndices.value.newTime.push(Date.now())
|
|
|
|
|
+ }else{
|
|
|
|
|
+ pausedIndices.value.time[timeIndex] = currentTime
|
|
|
|
|
+ pausedIndices.value.newTime[timeIndex] = Date.now()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 提交答案
|
|
// 提交答案
|
|
@@ -760,7 +579,7 @@ const handleSubmitAnswer = () => {
|
|
|
selectedOption.value = null
|
|
selectedOption.value = null
|
|
|
|
|
|
|
|
//记录已暂停的内容
|
|
//记录已暂停的内容
|
|
|
- setVideoStop()
|
|
|
|
|
|
|
+ setVideoStop();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 发送消息
|
|
// 发送消息
|
|
@@ -778,6 +597,7 @@ const sendMessage = async () => {
|
|
|
type: 'ai',
|
|
type: 'ai',
|
|
|
content: aiResponse
|
|
content: aiResponse
|
|
|
})
|
|
})
|
|
|
|
|
+
|
|
|
// 清空输入框
|
|
// 清空输入框
|
|
|
userMessage.value = ''
|
|
userMessage.value = ''
|
|
|
}
|
|
}
|
|
@@ -787,14 +607,10 @@ const sendMessage = async () => {
|
|
|
const handleAIClick = () => {
|
|
const handleAIClick = () => {
|
|
|
// 清空输入框
|
|
// 清空输入框
|
|
|
messageHistory = ref([])
|
|
messageHistory = ref([])
|
|
|
- if (currentQuestion.value.aiQuestion) {
|
|
|
|
|
- userMessage.value = currentQuestion.value.aiQuestion
|
|
|
|
|
|
|
+ if (courseConfig.value.ccQuestContent) {
|
|
|
|
|
+ userMessage.value = courseConfig.value.ccQuestContent
|
|
|
sendMessage()
|
|
sendMessage()
|
|
|
userMessage.value = ''
|
|
userMessage.value = ''
|
|
|
- messageHistory.value = [
|
|
|
|
|
- // { role: 'user', content: currentQuestion.value.aiQuestion },
|
|
|
|
|
- { role: 'assistant', content: currentQuestion.value.aiAnswer }
|
|
|
|
|
- ]
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
showAIDialog.value = true
|
|
showAIDialog.value = true
|
|
@@ -818,6 +634,7 @@ const simulateAIResponse = question => {
|
|
|
const handleCloseAIDialog = () => {
|
|
const handleCloseAIDialog = () => {
|
|
|
showAIDialog.value = false
|
|
showAIDialog.value = false
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
<style scoped lang="scss">
|