AIInitialExperience.vue 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443
  1. <template>
  2. <!-- AI发展历程 -->
  3. <div class="home-container">
  4. <!-- 添加抽屉 -->
  5. <div class="drawer-box">
  6. <el-button
  7. v-if="!drawerVisible"
  8. type="primary"
  9. @click="drawerVisible = true"
  10. @closed="buttonVisible = false"
  11. class="toggle-button"
  12. >
  13. 课程小节
  14. </el-button>
  15. <el-drawer v-model="drawerVisible" direction="ltr" size="20%">
  16. <el-row class="tac">
  17. <el-col :span="12">
  18. <h3 class="mb-2">课程小节</h3>
  19. <el-menu
  20. default-active="1"
  21. class="el-menu-vertical-demo"
  22. @open="handleOpen"
  23. @close="handleClose"
  24. @select="handleSelect"
  25. :default-openeds="['1']"
  26. >
  27. <template v-for="item in menuItems" :key="item.index">
  28. <el-menu-item v-if="!item.children" :index="item.index">{{
  29. item.title
  30. }}</el-menu-item>
  31. <el-sub-menu v-else :index="item.index">
  32. <template #title>
  33. <span>{{ item.title }}</span>
  34. </template>
  35. <el-menu-item-group v-if="item.children">
  36. <template v-for="child in item.children" :key="child.index">
  37. <el-menu-item :index="child.index">{{
  38. child.title
  39. }}</el-menu-item>
  40. </template>
  41. </el-menu-item-group>
  42. </el-sub-menu>
  43. </template>
  44. </el-menu>
  45. </el-col>
  46. </el-row>
  47. </el-drawer>
  48. </div>
  49. <div class="box-1">
  50. <div class="inner-box left-box">
  51. <div class="box-icon" @click="goBack">
  52. <el-icon class="left-icon"><ArrowLeftBold /></el-icon>
  53. {{ boxIconTitle }}
  54. </div>
  55. </div>
  56. <div class="inner-box right-box">
  57. <div class="top-right-box">
  58. <el-input
  59. v-model="SearchInput"
  60. class="search-input"
  61. placeholder="搜索"
  62. >
  63. <template #prefix>
  64. <el-icon class="el-input__icon"><search /></el-icon>
  65. </template>
  66. </el-input>
  67. </div>
  68. </div>
  69. </div>
  70. <div class="box-2">
  71. <!-- 课程标题 autoplay自动播放 @ended="playNextVideo"-->
  72. <div class="small-title">
  73. <span>{{ smallTitle }}</span>
  74. </div>
  75. <div class="box-video">
  76. <video
  77. class="full-box-video"
  78. :src="videoSrc"
  79. controlsList="nodownload"
  80. controls
  81. @timeupdate="handleTimeUpdate"
  82. ref="videoRef"
  83. >
  84. <source :src="videoSrc" type="video/mp4" />
  85. 您的浏览器不支持视频播放。
  86. </video>
  87. </div>
  88. <!-- 添加切换视频 -->
  89. <div class="video-switch">
  90. <!-- 上一个视频 -->
  91. <div class="caret-left" @click="playPreviousVideo">
  92. <el-button type="warning" round>上一节</el-button>
  93. </div>
  94. <!-- 下一个视频 -->
  95. <div class="caret-right" @click="playNextVideo">
  96. <el-button type="warning" round>下一节</el-button>
  97. </div>
  98. </div>
  99. </div>
  100. <!-- 添加试题弹框 -->
  101. <transition name="fade-scale">
  102. <div
  103. v-show="questionDialogVisible"
  104. class="child-dialog-wrapper"
  105. @click.self="handleCloseQuestionDialog"
  106. >
  107. <div class="child-dialog">
  108. <div class="question-title">
  109. <span class="question-icon">?</span>
  110. {{ currentQuestion.title }}
  111. </div>
  112. <!-- 选项区域 -->
  113. <div
  114. v-if="currentQuestion.options && currentQuestion.options.length > 0"
  115. class="options-container"
  116. >
  117. <div
  118. v-for="(option, index) in currentQuestion.options"
  119. :key="index"
  120. class="question-option"
  121. >
  122. <el-radio v-model="selectedOption" :label="index" :value="option" v-cloak="selectedOption = option">
  123. <span>{{ option }}</span>
  124. </el-radio>
  125. </div>
  126. </div>
  127. <div v-else class="no-options">
  128. <!-- 暂无选项-->
  129. </div>
  130. <!-- 底部按钮 -->
  131. <div class="dialog-footer">
  132. <!-- <el-button class="child-button cancel" @click="questionDialogVisible = false; showAIDialog = false">取消</el-button>-->
  133. <el-button class="child-button confirm" @click="handleSubmitAnswer">确定</el-button>
  134. </div>
  135. <!-- 右侧小图标 -->
  136. <div class="ai-icon-container" @click="handleAIClick">
  137. <img src="@/assets/images/xiaozhi.png" alt="AI对话" class="ai-icon" />
  138. <span class="ai-text">AI助手</span>
  139. </div>
  140. </div>
  141. </div>
  142. </transition>
  143. <!-- AI对话弹框 -->
  144. <div
  145. v-show="showAIDialog"
  146. class="ai-dialog-wrapper"
  147. @click.self="showAIDialog = false"
  148. >
  149. <div class="ai-dialog">
  150. <div class="ai-dialog-header">
  151. <h3>小智智能助手</h3>
  152. <el-button @click="showAIDialog = false" class="close-btn"
  153. >×</el-button
  154. >
  155. </div>
  156. <div class="ai-dialog-content">
  157. <div class="ai-message-history">
  158. <div
  159. v-for="(message, index) in messageHistory"
  160. :key="index"
  161. :class="['message', message.type]"
  162. >
  163. <img
  164. v-if="message.type === 'user'"
  165. src="@/assets/images/user.png"
  166. class="avatar user"
  167. />
  168. <img v-else src="@/assets/images/xiaozhi.png" class="avatar" />
  169. <div class="message-content">
  170. {{ message.content }}
  171. </div>
  172. </div>
  173. </div>
  174. <el-input
  175. v-model="userMessage"
  176. placeholder="输入问题..."
  177. class="user-input"
  178. @keyup.enter="sendMessage"
  179. >
  180. <template #append class="flex flex-wrap items-center mb-4">
  181. <!-- <el-button @click="sendMessage" class="child-button confirm">发送</el-button>-->
  182. <el-button @click="sendMessage" size="large" round
  183. >发送</el-button
  184. >
  185. </template>
  186. </el-input>
  187. </div>
  188. </div>
  189. </div>
  190. </div>
  191. </template>
  192. <script setup>
  193. import { ref, onMounted } from 'vue'
  194. import { useRouter } from 'vue-router'
  195. import {
  196. ArrowDown,
  197. ArrowRightBold,
  198. CaretRight,
  199. CaretLeft
  200. } from '@element-plus/icons-vue'
  201. import { Search, ArrowLeftBold } from '@element-plus/icons-vue'
  202. import { valueEquals } from 'element-plus'
  203. // 引入视频
  204. import video1 from '@/assets/02video/01video.mp4'
  205. import video2 from '@/assets/02video/02video.mp4'
  206. import video3 from '@/assets/02video/03video.mp4'
  207. import video4 from '@/assets/02video/04video.mp4'
  208. import video5 from '@/assets/02video/05video.mp4'
  209. import video6 from '@/assets/02video/06video.mp4'
  210. import video7 from '@/assets/02video/07video.mp4'
  211. import video8 from '@/assets/02video/08video.mp4'
  212. import video9 from '@/assets/02video/09video.mp4'
  213. import video10 from '@/assets/02video/10video.mp4'
  214. import video11 from '@/assets/02video/11video.mp4'
  215. import video12 from '@/assets/02video/12video.mp4'
  216. import video13 from '@/assets/02video/13video.mp4'
  217. import video14 from '@/assets/02video/14video.mp4'
  218. import video15 from '@/assets/02video/15video.mp4'
  219. const router = useRouter() // 获取当前路由对象
  220. // 搜索框
  221. const SearchInput = ref('')
  222. // 添加按钮显示状态
  223. const buttonVisible = ref(false)
  224. // 添加抽屉显示状态
  225. const drawerVisible = ref(false)
  226. // 定义映射
  227. const videoMap = {
  228. '1-1': video1,
  229. '1-2': video2,
  230. '1-3': video3,
  231. '1-4': video4,
  232. '1-5': video5,
  233. '1-6': video6,
  234. '1-7': video7,
  235. '1-8': video8,
  236. '1-9': video9,
  237. '1-10': video10,
  238. '1-11': video11,
  239. '1-12': video12,
  240. '1-13': video13,
  241. '1-14': video14,
  242. '1-15': video15
  243. }
  244. // 定义视频源
  245. const videoSrc = ref(video1)
  246. // 返回上一页
  247. const goBack = () => {
  248. router.go(-1)
  249. }
  250. // 渲染页面标题
  251. const boxIconTitle = ref('')
  252. onMounted(() => {
  253. const title = router.currentRoute.value.query.title
  254. if (title) {
  255. boxIconTitle.value = String(title)
  256. }
  257. })
  258. // 菜单打开和关闭的处理函数
  259. const handleOpen = () => {}
  260. const handleClose = () => {}
  261. // 动态渲染树型结构
  262. const menuItems = ref([
  263. { index: '1-1', title: '课前回顾' },
  264. { index: '1-2', title: '课程引入' },
  265. {
  266. index: '1',
  267. title: '知识讲解',
  268. children: [
  269. { index: '1-3', title: '图灵测试' },
  270. { index: '1-4', title: '课堂提问' },
  271. { index: '1-5', title: '达特茅斯会议' },
  272. { index: '1-6', title: '课堂选择' },
  273. { index: '1-7', title: '聊天机器人' },
  274. { index: '1-8', title: '专家系统' },
  275. { index: '1-9', title: '课堂互动' },
  276. { index: '1-10', title: '互联网快速发展' },
  277. { index: '1-11', title: '黄金时代' },
  278. { index: '1-12', title: '课堂提问' },
  279. { index: '1-13', title: '大模型时代' }
  280. ]
  281. },
  282. { index: '1-14', title: '趣味实操' },
  283. { index: '1-15', title: '课程总结' }
  284. ])
  285. // 当前播放的索引
  286. const currentIndex = ref('1-1')
  287. // 渲染课程标题到视频上方
  288. const smallTitle = ref('课前回顾')
  289. const handleSelect = index => {
  290. const findTitle = items => {
  291. for (const item of items) {
  292. if (item.index === index) {
  293. return item.title
  294. }
  295. if (item.children) {
  296. const result = findTitle(item.children)
  297. if (result) {
  298. return result
  299. }
  300. }
  301. }
  302. return null
  303. }
  304. const title = findTitle(menuItems.value)
  305. if (title) {
  306. smallTitle.value = title
  307. }
  308. // 根据索引切换视频
  309. if (videoMap[index]) {
  310. videoSrc.value = videoMap[index]
  311. currentIndex.value = index
  312. }
  313. // 选中标题后关闭抽屉
  314. drawerVisible.value = false
  315. }
  316. // 展平所有菜单项索引
  317. const flattenMenuItems = () => {
  318. const indices = []
  319. const traverse = items => {
  320. for (const item of items) {
  321. if (!item.children) {
  322. indices.push(item.index)
  323. } else {
  324. traverse(item.children)
  325. }
  326. }
  327. }
  328. traverse(menuItems.value)
  329. return indices
  330. }
  331. // 播放下一个视频
  332. const playNextVideo = () => {
  333. const allIndices = flattenMenuItems()
  334. const currentIndexInList = allIndices.indexOf(currentIndex.value)
  335. if (currentIndexInList !== -1 && currentIndexInList < allIndices.length - 1) {
  336. const nextIndex = allIndices[currentIndexInList + 1]
  337. handleSelect(nextIndex)
  338. // 切换视频后自动播放
  339. if (videoRef.value) {
  340. videoRef.value.addEventListener('loadedmetadata', tryPlayVideo, {
  341. once: true
  342. })
  343. }
  344. }
  345. // 重置
  346. pausedIndices = ref([])
  347. userMessage = ref('')
  348. messageHistory = ref([])
  349. }
  350. // 切换视频
  351. // 播放上一个视频
  352. const playPreviousVideo = () => {
  353. const allIndices = flattenMenuItems()
  354. const currentIndexInList = allIndices.indexOf(currentIndex.value)
  355. if (currentIndexInList > 0) {
  356. const previousIndex = allIndices[currentIndexInList - 1]
  357. handleSelect(previousIndex)
  358. // 切换视频后自动播放
  359. if (videoRef.value) {
  360. videoRef.value.addEventListener('loadedmetadata', tryPlayVideo, {
  361. once: true
  362. })
  363. }
  364. }
  365. }
  366. // 尝试播放视频,处理浏览器自动播放限制
  367. const tryPlayVideo = () => {
  368. const playPromise = videoRef.value.play()
  369. if (playPromise !== undefined) {
  370. playPromise.catch(error => {
  371. console.error('视频播放失败,可能是浏览器自动播放限制:', error)
  372. })
  373. }
  374. }
  375. // 视频 ref
  376. const videoRef = ref(null)
  377. // 记录已经暂停过的时间点索引
  378. let pausedIndices = ref([])
  379. // 试题弹框显示状态
  380. const questionDialogVisible = ref(false)
  381. // 当前显示的试题
  382. const currentQuestion = ref({ title: '', options: [] })
  383. // 用户选择的选项
  384. const selectedOption = ref(null)
  385. // AI对话弹出框显示状态
  386. let showAIDialog = ref(false)
  387. // 用户输入的消息
  388. let userMessage = ref('')
  389. // 消息历史记录
  390. let messageHistory = ref([])
  391. // 定义每个视频对应的暂停时间和问题
  392. const videoPauseTimes = {
  393. [video2]: {
  394. pauseTimes: [30],
  395. questions: [
  396. {
  397. title: '视频当中发生了什么事情呢?',
  398. options: [],
  399. aiQuestion: '视频当中发生了什么事情呢',
  400. aiAnswer: '让我来告诉你吧:泡泡怪篡改了Ai历史数据,导致Ai系统发生崩溃,所以要修正Ai历史抓到泡泡怪!'
  401. }
  402. ]
  403. },
  404. [video3]: {
  405. pauseTimes: [49],
  406. questions: [
  407. {
  408. title: '同学们,大家了解图灵测试了吗?',
  409. options: [],
  410. aiQuestion: '视频当中发生了什么事情呢',
  411. aiAnswer: '让我来告诉你吧:泡泡怪篡改了Ai历史数据,导致Ai系统发生崩溃,所以要修正Ai历史抓到泡泡怪!'
  412. }
  413. ]
  414. },
  415. [video4]: {
  416. pauseTimes: [2],
  417. questions: [
  418. {
  419. title: '你觉得deepseek、豆包等大模型可以通过图灵测试吗?为什么?',
  420. options: [],
  421. aiQuestion: '你觉得deepseek、豆包等大模型可以通过图灵测试吗?为什么?',
  422. aiAnswer: '大模型已缩短与图灵测试的标志距离,尤其在表面对话层面,但因缺乏深层次理解、逻辑一致性与真实认知,仍无法在严格测试中稳定通过。'
  423. }
  424. ]
  425. },
  426. [video5]: {
  427. pauseTimes: [49],
  428. questions: []
  429. },
  430. [video6]: {
  431. pauseTimes: [5],
  432. },
  433. [video7]: {
  434. pauseTimes: [64.5,91],
  435. questions: [
  436. {
  437. title: '如果你是聊天机器人,你会怎么回答用户呢?',
  438. options: [],
  439. aiQuestion: '',
  440. aiAnswer: ''
  441. },
  442. {
  443. title: '当我们和聊天机器人对话的内容被人类所查看并回答时,隐私信息是否泄露?',
  444. options: [],
  445. aiQuestion: '当我们和聊天机器人对话的内容被人类所查看并回答时,隐私信息是否泄露?',
  446. aiAnswer: '与聊天机器人的对话被人类查看时,隐私泄露风险客\n' +
  447. '观存在,尤其是人类介入或安全漏洞场景下。建议优先选择支持本地'
  448. }
  449. ]
  450. },
  451. [video8]: {
  452. pauseTimes: [72],
  453. questions: [
  454. {
  455. title: '如果你身体不舒服时找这样的专家检查,那么它开的药你敢喝吗?',
  456. options: [],
  457. aiQuestion: '如果你身体不舒服时找这样的专家检查,那么它开的药你敢喝吗?',
  458. aiAnswer: '这题没给答案,你自己去查吧!'
  459. }
  460. ]
  461. },
  462. [video9]: {
  463. pauseTimes: [2],
  464. questions: [
  465. {
  466. title: '在生活中,有哪些正在使用的专家系统呢?',
  467. options: [],
  468. aiQuestion: '在生活中,有哪些正在使用的专家系统呢?',
  469. aiAnswer: '在医疗健康领域有复杂疾病协同决策和Ai医生分身与诊断辅助;在水利交通领域的水利厅专家库系统用于项目验收和抢险督查'
  470. }
  471. ]
  472. },
  473. [video11]: {
  474. pauseTimes: [1,90,176],
  475. questions: [
  476. {
  477. title: '怎么会有爆炸声?泡泡怪在这里吗?',
  478. options: [],
  479. aiQuestion: '',
  480. aiAnswer: ''
  481. },
  482. {
  483. title: '同学们喜欢下围棋吗?',
  484. options: [],
  485. aiQuestion: '',
  486. aiAnswer: ''
  487. },
  488. {
  489. title: '为什么AlphaGo要在围棋上攻克真人冠军呢?',
  490. options: [],
  491. aiQuestion: '为什么AlphaGo要在围棋上攻克真人冠军呢?',
  492. aiAnswer: '围棋是人类智力游戏的巅峰,拥有天文数字级的可能性,每颗棋子价值由全局态势动态决定,所以当前一手可能百步之后才显现价值。AlphaGo战胜人类顶尖选手,它证明了Ai不仅能处理规则明确的事物,更能攻克依赖直觉、策略的“人类专属领域”'
  493. }
  494. ]
  495. },
  496. [video12]: {
  497. pauseTimes: [1],
  498. },
  499. [video13]: {
  500. pauseTimes: [62],
  501. questions: [
  502. {
  503. title: '我们一起来感受一下大模型吧!',
  504. options: [],
  505. aiQuestion: '',
  506. aiAnswer: ''
  507. }
  508. ]
  509. }
  510. }
  511. // 处理视频时间更新事件
  512. const handleTimeUpdate = () => {
  513. if (!videoRef.value) return
  514. const currentTime = videoRef.value.currentTime
  515. const currentPauseTimes = videoPauseTimes[videoSrc.value]
  516. if (currentPauseTimes) {
  517. currentPauseTimes.pauseTimes.forEach((time, index) => {
  518. // 检查是否到达时间点且还未暂停过
  519. if (currentTime >= time && !pausedIndices.value.includes(index)) {
  520. videoRef.value.pause()
  521. pausedIndices.value.push(index)
  522. // 显示对应的问题
  523. if (currentPauseTimes.questions[index]) {
  524. currentQuestion.value = currentPauseTimes.questions[index]
  525. questionDialogVisible.value = true
  526. }
  527. }
  528. })
  529. }
  530. }
  531. // 关闭试题弹框
  532. const handleCloseQuestionDialog = () => {
  533. questionDialogVisible.value = false
  534. // 继续播放视频
  535. videoRef.value.play()
  536. }
  537. // 提交答案
  538. const handleSubmitAnswer = () => {
  539. // 这里可以添加答案验证逻辑
  540. console.log('用户选择的答案是:', selectedOption.value)
  541. questionDialogVisible.value = false
  542. // 继续播放视频
  543. videoRef.value.play()
  544. selectedOption.value = null
  545. }
  546. // 发送消息
  547. const sendMessage = async () => {
  548. if (userMessage.value.trim()) {
  549. // 添加用户消息到历史记录
  550. messageHistory.value.push({
  551. type: 'user',
  552. content: userMessage.value
  553. })
  554. // 模拟 AI 回复
  555. const aiResponse = await simulateAIResponse(userMessage.value)
  556. messageHistory.value.push({
  557. type: 'ai',
  558. content: aiResponse
  559. })
  560. // 清空输入框
  561. userMessage.value = ''
  562. }
  563. }
  564. // 处理 AI 助手点击事件
  565. const handleAIClick = () => {
  566. // 清空输入框
  567. messageHistory = ref([])
  568. if (currentQuestion.value.aiQuestion) {
  569. userMessage.value = currentQuestion.value.aiQuestion
  570. sendMessage()
  571. userMessage.value = ''
  572. }
  573. showAIDialog.value = true
  574. }
  575. // 模拟 AI 回复
  576. const simulateAIResponse = question => {
  577. return new Promise(resolve => {
  578. setTimeout(() => {
  579. const currentVideoInfo = videoPauseTimes[videoSrc.value]
  580. if (currentVideoInfo) {
  581. const currentQuestionObj = currentVideoInfo.questions.find(
  582. q => q.aiQuestion === question
  583. )
  584. if (currentQuestionObj && currentQuestionObj.aiAnswer) {
  585. resolve(currentQuestionObj.aiAnswer)
  586. return
  587. }
  588. }
  589. // 若未匹配到自定义回复,给出默认回复
  590. resolve(`您的问题是:${question},这是 AI 的回复示例。`)
  591. }, 1000)
  592. })
  593. }
  594. // 关闭AI对话弹出框
  595. const handleCloseAIDialog = () => {
  596. showAIDialog.value = false
  597. }
  598. </script>
  599. <style scoped lang="scss">
  600. @use 'sass:math';
  601. @use 'sass:color'; // 引入 color 模块
  602. // 定义rpx转换函数
  603. @function rpx($px) {
  604. @return math.div($px, 750) * 100vw;
  605. }
  606. // 定义儿童风格的蓝紫色调
  607. $primary-color: rgba(106, 90, 205, 0.52); // 主色调:蓝紫色
  608. $secondary-color: rgba(147, 112, 219, 0.66); // 辅助色:亮蓝紫色
  609. $accent-color: rgb(133, 89, 220); // 强调色:暗蓝紫色
  610. $light-color: #e6e6fa; // 浅色背景:淡紫色
  611. $text-color: #483d8b; // 文本颜色:靛蓝色
  612. .home-container {
  613. position: fixed;
  614. top: 0;
  615. left: 0;
  616. right: 0;
  617. bottom: 0;
  618. background: linear-gradient(to bottom, #001169, #b4a8e1);
  619. display: flex;
  620. flex-direction: column;
  621. gap: rpx(0);
  622. }
  623. .tac ::v-deep(.el-menu) {
  624. background-color: transparent;
  625. border: none;
  626. width: 100%;
  627. }
  628. /* 取消点击后的蓝色字体 el-sub-menu__title*/
  629. .tac ::v-deep(.el-menu-item.is-active),
  630. .tac ::v-deep(.el-sub-menu__title.is-active) {
  631. color: black;
  632. }
  633. // 取消鼠标悬浮颜色
  634. .tac ::v-deep(.el-sub-menu__title) {
  635. width: rpx(130);
  636. height: rpx(20);
  637. margin-bottom: rpx(5);
  638. border-radius: rpx(6);
  639. }
  640. .el-menu ::v-deep(.el-sub-menu__title:hover),
  641. .el-menu ::v-deep(.el-sub-menu__title:focus),
  642. .el-menu ::v-deep(.el-sub-menu__title:active) {
  643. background: linear-gradient(
  644. to bottom,
  645. #fee78a,
  646. #ffce1b
  647. ); /* 设置悬停、聚焦、点击状态下的背景色 */
  648. background-color: transparent;
  649. }
  650. .drawer-box ::v-deep(.el-drawer__header) {
  651. margin-bottom: rpx(0);
  652. }
  653. .mb-2 {
  654. color: black;
  655. margin-top: rpx(1);
  656. }
  657. .el-menu-item {
  658. width: rpx(130);
  659. height: rpx(20);
  660. margin-bottom: rpx(5);
  661. border-radius: rpx(6);
  662. }
  663. .el-menu-item span {
  664. color: black;
  665. font-size: rpx(8);
  666. }
  667. .el-menu ::v-deep(.el-menu-item:hover),
  668. .el-menu ::v-deep(.el-menu-item:focus),
  669. .el-menu ::v-deep(.el-menu-item:active) {
  670. background: linear-gradient(
  671. to bottom,
  672. #fee78a,
  673. #ffce1b
  674. ); /* 设置悬停、聚焦、点击状态下的背景色 */
  675. }
  676. .drawer-box {
  677. position: absolute;
  678. display: flex;
  679. align-items: center;
  680. height: 100%;
  681. }
  682. .drawer-box .toggle-button {
  683. width: rpx(10);
  684. height: rpx(50);
  685. font-size: rpx(7);
  686. background-color: rgba(17, 23, 29, 0.2);
  687. border: none;
  688. position: relative;
  689. writing-mode: vertical-lr; // 文字垂直排列,从左到右
  690. text-orientation: upright; // 文字保持正立
  691. }
  692. .toggle-button:hover {
  693. left: 0;
  694. }
  695. // 抽屉滚动条样式
  696. .drawer-box ::v-deep(.el-drawer.ltr) {
  697. background-color: rgb(255, 255, 255, 0.7);
  698. box-shadow: 0 8px 8px rgba(202, 52, 52, 0.1);
  699. }
  700. .drawer-box ::v-deep(.el-drawer__body)::-webkit-scrollbar {
  701. width: rpx(2);
  702. }
  703. .drawer-box ::v-deep(.el-drawer__body)::-webkit-scrollbar-thumb {
  704. background-color: rgba(0, 0, 0, 0.2);
  705. border-radius: 8px;
  706. }
  707. .drawer-box ::v-deep(.el-drawer__body)::-webkit-scrollbar-track {
  708. background-color: rgba(0, 0, 0, 0.05);
  709. border-radius: 8px;
  710. }
  711. .toggle-button.is-active,
  712. .toggle-button:active,
  713. .toggle-button:focus {
  714. background-color: rgba(165, 209, 247, 0.8);
  715. color: black;
  716. border: none; // 移除点击时的边框
  717. outline: none; // 移除点击时的外边框
  718. }
  719. .box-1 {
  720. width: 100%;
  721. height: rpx(50);
  722. // margin-top: rpx(10);
  723. display: flex;
  724. justify-content: center;
  725. align-items: center;
  726. box-sizing: border-box;
  727. font-size: rpx(15); // 默认字体大小
  728. }
  729. .inner-box {
  730. height: 100%;
  731. display: flex;
  732. justify-content: center;
  733. align-items: center;
  734. font-size: rpx(16); // 默认字体大小
  735. }
  736. .left-box {
  737. position: relative;
  738. justify-content: flex-start;
  739. align-items: flex-start;
  740. flex: 1; // 设置左侧盒子占比为 2
  741. cursor: pointer; // 添加鼠标指针样式
  742. }
  743. .box-icon {
  744. width: 100%;
  745. height: 100%;
  746. flex: 1;
  747. display: flex; // 添加 flex 布局
  748. align-items: center; // 垂直居中
  749. color: white; // 设置图标颜色为白色
  750. padding-left: rpx(15);
  751. font-size: rpx(10); // 设置图标大小,可按需调整
  752. }
  753. .box-icon .left-icon {
  754. margin-left: rpx(10);
  755. margin-right: rpx(5); // 设置图标和文字之间的间距 ;
  756. }
  757. .left-box span {
  758. position: absolute;
  759. font-size: rpx(11); // 默认字体大小
  760. color: white;
  761. }
  762. .right-box {
  763. flex: 1;
  764. position: relative; // 添加相对定位;
  765. }
  766. .top-right-box {
  767. position: absolute; // 添加绝对定位
  768. margin-top: rpx(20); // 调整上边距离
  769. margin-right: rpx(50); // 调整右边距离
  770. width: 100%; // 设置盒子宽度,可按需调整
  771. height: 60px; // 设置盒子高度,可按需调整
  772. display: flex;
  773. justify-content: flex-end;
  774. }
  775. .top-right-box {
  776. ::v-deep(.el-input__wrapper) {
  777. background-color: rgb(255, 255, 255, 0.5);
  778. border-radius: rpx(12);
  779. color: white;
  780. }
  781. ::v-deep(.el-input__icon) {
  782. color: white; // 设置输入框图标颜色为白色
  783. }
  784. // 添加占位符样式
  785. ::v-deep(.el-input__inner::placeholder) {
  786. color: white;
  787. }
  788. // 添加输入框文字颜色样式
  789. ::v-deep(.el-input__inner) {
  790. color: black;
  791. }
  792. }
  793. // 搜索框
  794. .search-input {
  795. width: rpx(100);
  796. height: rpx(15);
  797. font-size: rpx(7);
  798. }
  799. .box-2 {
  800. width: 100%;
  801. flex: 1;
  802. box-shadow: 0 4px 8px rgba(202, 52, 52, 0.1);
  803. box-sizing: border-box;
  804. // padding: rpx(-20) rpx(20); // 添加左右内边距
  805. display: flex; // 确保子元素水平排列
  806. flex-wrap: wrap; // 允许子元素换行;
  807. align-content: center; // 顶部对齐;
  808. cursor: pointer; // 添加鼠标指针样式
  809. }
  810. .box-video {
  811. width: 100%;
  812. height: rpx(300);
  813. video.full-box-video {
  814. // width: 100%;
  815. height: rpx(280);
  816. margin: 0 auto;
  817. border-radius: rpx(12);
  818. box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
  819. object-fit: cover;
  820. // object-fit: contain;
  821. }
  822. }
  823. /* 隐藏 Chrome 视频控件的渐变背景等默认样式 */
  824. video::-webkit-media-controls-panel {
  825. background: transparent !important; /* 去掉背景渐变,设为透明 */
  826. }
  827. .small-title {
  828. width: 100%;
  829. margin-top: rpx(-20);
  830. height: rpx(20);
  831. color: white;
  832. font-size: rpx(10);
  833. justify-content: center; //使子元素水平居中
  834. }
  835. .video-switch {
  836. width: 100%;
  837. // height: rpx(50);
  838. display: flex;
  839. margin-top: rpx(-20);
  840. // background-color: saddlebrown;
  841. }
  842. .caret-right,
  843. .caret-left {
  844. width: rpx(50);
  845. // height: rpx(50);
  846. margin: auto;
  847. display: flex;
  848. // grid: rpx(4);
  849. margin-top: rpx(5);
  850. margin-bottom: rpx(15);
  851. }
  852. .caret-left ::v-deep(.el-button.is-round),
  853. .caret-right ::v-deep(.el-button.is-round) {
  854. width: rpx(50);
  855. height: rpx(15);
  856. color: black;
  857. border-radius: none;
  858. border: 1px white solid;
  859. background-color: rgb(255, 255, 255, 0.5); // 进度条背景颜色,调浅为半透明白色
  860. box-shadow: 0 4px 8px rgba(202, 52, 52, 0.1);
  861. }
  862. // 儿童风格试题弹框样式
  863. .child-dialog {
  864. .el-dialog__header {
  865. display: none; // 隐藏原有的标题栏
  866. }
  867. .el-dialog__body {
  868. padding: rpx(20);
  869. position: relative;
  870. }
  871. .el-dialog__footer {
  872. border-top: none;
  873. padding: rpx(10) rpx(20);
  874. text-align: center;
  875. }
  876. .el-dialog__wrapper {
  877. // 修改半透明背景色
  878. background-color: rgba(0, 0, 0, 0.6);
  879. }
  880. .el-dialog {
  881. border: none;
  882. border-radius: rpx(20);
  883. background: linear-gradient(
  884. 135deg,
  885. $light-color,
  886. #d8bfd8
  887. ); // 柔和的蓝紫色渐变
  888. // 添加边框边晕效果
  889. box-shadow: 0 0 20px 5px rgba($primary-color, 0.6),
  890. 0 0 40px 10px rgba($primary-color, 0.4),
  891. 0 0 60px 15px rgba($primary-color, 0.2);
  892. overflow: hidden;
  893. // 添加装饰元素
  894. &::before {
  895. content: '';
  896. position: absolute;
  897. top: 0;
  898. left: 0;
  899. width: 100%;
  900. height: rpx(10);
  901. background: linear-gradient(
  902. 90deg,
  903. $primary-color,
  904. $secondary-color,
  905. $accent-color
  906. );
  907. }
  908. }
  909. }
  910. // AI对话弹出框样式
  911. .ai-dialog {
  912. .el-dialog__header {
  913. background: linear-gradient(90deg, $primary-color, $secondary-color);
  914. color: white;
  915. padding: rpx(10) rpx(20);
  916. border-radius: rpx(10) rpx(10) 0 0;
  917. .el-dialog__title {
  918. font-size: rpx(12);
  919. }
  920. }
  921. .el-dialog__body {
  922. padding: rpx(15);
  923. background-color: white;
  924. }
  925. .el-dialog__footer {
  926. border-top: none;
  927. padding: rpx(10) rpx(20);
  928. text-align: right;
  929. }
  930. .el-dialog {
  931. border-radius: rpx(10);
  932. // 修改半透明背景色
  933. background-color: rgba(255, 255, 255, 0.95);
  934. // 添加边框边晕效果
  935. box-shadow: 0 0 20px 5px rgba($primary-color, 0.6),
  936. 0 0 40px 10px rgba($primary-color, 0.4),
  937. 0 0 60px 15px rgba($primary-color, 0.2);
  938. }
  939. }
  940. // 问题标题样式
  941. .question-title {
  942. background: linear-gradient(
  943. 90deg,
  944. rgba($primary-color, 0.2),
  945. rgba($secondary-color, 0.2)
  946. );
  947. padding: rpx(15);
  948. border-radius: rpx(12);
  949. margin-bottom: rpx(20);
  950. color: $accent-color;
  951. font-weight: bold;
  952. font-size: rpx(14);
  953. box-shadow: 0 rpx(3) rpx(10) rgba($primary-color, 0.1);
  954. position: relative;
  955. display: flex;
  956. align-items: center;
  957. .question-icon {
  958. background-color: $accent-color;
  959. color: white;
  960. width: rpx(24);
  961. height: rpx(24);
  962. border-radius: 50%;
  963. display: flex;
  964. align-items: center;
  965. justify-content: center;
  966. margin-right: rpx(10);
  967. font-weight: bold;
  968. box-shadow: 0 rpx(2) rpx(5) rgba($accent-color, 0.3);
  969. }
  970. }
  971. // 选项容器样式
  972. .options-container {
  973. margin-bottom: rpx(20);
  974. }
  975. // 问题选项样式
  976. .question-option {
  977. margin: rpx(8) 0;
  978. padding: rpx(10) rpx(15);
  979. border-radius: rpx(12);
  980. border: rpx(1) solid rgba($primary-color, 0.3);
  981. transition: all 0.3s ease;
  982. display: flex;
  983. align-items: center;
  984. background-color: white;
  985. box-shadow: 0 rpx(2) rpx(5) rgba($primary-color, 0.05);
  986. ::v-deep(.el-radio__label) {
  987. color: $text-color;
  988. margin-left: rpx(8);
  989. flex: 1;
  990. text-align: left;
  991. // 增大字体大小
  992. font-size: rpx(12);
  993. }
  994. // 选中时的样式变化
  995. .el-radio__input.is-checked + .el-radio__label {
  996. font-weight: bold;
  997. color: $accent-color;
  998. }
  999. &:hover {
  1000. background-color: rgba($primary-color, 0.05);
  1001. border-color: rgba($primary-color, 0.5);
  1002. transform: translateY(-rpx(1));
  1003. }
  1004. }
  1005. // 暂无选项样式
  1006. .no-options {
  1007. color: rgba($text-color, 0.7);
  1008. text-align: center;
  1009. padding: rpx(20);
  1010. font-size: rpx(12);
  1011. }
  1012. // 底部按钮样式
  1013. .child-button {
  1014. min-width: rpx(80);
  1015. height: rpx(30);
  1016. border-radius: rpx(15);
  1017. font-size: rpx(12);
  1018. font-weight: 500;
  1019. transition: all 0.3s ease;
  1020. box-shadow: 0 rpx(2) rpx(8) rgba(0, 0, 0, 0.1);
  1021. &.confirm {
  1022. background: linear-gradient(to right, $primary-color, $secondary-color);
  1023. border: none;
  1024. border-right: 15px;
  1025. color: white;
  1026. &:hover {
  1027. background: linear-gradient(
  1028. to right,
  1029. color.adjust($primary-color, $lightness: -5%),
  1030. color.adjust($secondary-color, $lightness: -5%)
  1031. );
  1032. box-shadow: 0 rpx(3) rpx(10) rgba($primary-color, 0.4);
  1033. transform: translateY(-rpx(1));
  1034. color: white;
  1035. }
  1036. }
  1037. &.cancel {
  1038. background: white;
  1039. border: rpx(1) solid rgba($primary-color, 0.3);
  1040. color: $text-color;
  1041. &:hover {
  1042. background: rgba($primary-color, 0.05);
  1043. border-color: rgba($primary-color, 0.5);
  1044. transform: translateY(-rpx(1));
  1045. }
  1046. }
  1047. }
  1048. // AI对话图标样式
  1049. .ai-icon-container {
  1050. position: absolute;
  1051. bottom: rpx(20);
  1052. right: rpx(20);
  1053. display: flex;
  1054. flex-direction: column;
  1055. align-items: center;
  1056. cursor: pointer;
  1057. transition: all 0.3s ease;
  1058. &:hover {
  1059. transform: translateY(-rpx(2));
  1060. }
  1061. .ai-icon {
  1062. width: rpx(30);
  1063. height: rpx(30);
  1064. margin-bottom: rpx(0);
  1065. filter: drop-shadow(0 rpx(2) rpx(4) rgba($primary-color, 0.3));
  1066. // 添加过渡动画
  1067. transition: transform 0.3s ease;
  1068. }
  1069. // 悬浮时放大效果
  1070. .ai-icon:hover {
  1071. transform: scale(1.5);
  1072. }
  1073. .ai-text {
  1074. color: $text-color;
  1075. font-size: rpx(8);
  1076. background-color: rgba(255, 255, 255, 0.7);
  1077. padding: rpx(2) rpx(5);
  1078. border-radius: rpx(5);
  1079. }
  1080. }
  1081. // AI对话弹出框样式
  1082. .ai-dialog {
  1083. .el-dialog__header {
  1084. background: linear-gradient(90deg, $primary-color, $secondary-color);
  1085. color: white;
  1086. padding: rpx(10) rpx(20);
  1087. border-radius: rpx(10) rpx(10) 0 0;
  1088. .el-dialog__title {
  1089. font-size: rpx(12);
  1090. }
  1091. }
  1092. .el-dialog__body {
  1093. padding: rpx(15);
  1094. background-color: white;
  1095. }
  1096. .el-dialog__footer {
  1097. border-top: none;
  1098. padding: rpx(10) rpx(20);
  1099. text-align: right;
  1100. }
  1101. .el-dialog {
  1102. border-radius: rpx(10);
  1103. box-shadow: 0 rpx(10) rpx(30) rgba(0, 0, 0, 0.15);
  1104. }
  1105. }
  1106. // AI消息样式
  1107. .ai-message {
  1108. display: flex;
  1109. align-items: flex-start;
  1110. margin-bottom: rpx(15);
  1111. .ai-avatar {
  1112. width: rpx(30);
  1113. height: rpx(30);
  1114. border-radius: 50%;
  1115. margin-right: rpx(10);
  1116. background-color: $primary-color;
  1117. padding: rpx(5);
  1118. box-shadow: 0 rpx(2) rpx(5) rgba($primary-color, 0.2);
  1119. }
  1120. .ai-text-content {
  1121. background-color: $light-color;
  1122. padding: rpx(8) rpx(12);
  1123. border-radius: rpx(10);
  1124. font-size: rpx(10);
  1125. color: $text-color;
  1126. max-width: 80%;
  1127. box-shadow: 0 rpx(1) rpx(3) rgba(0, 0, 0, 0.05);
  1128. }
  1129. }
  1130. // 用户输入框样式
  1131. .user-input {
  1132. ::v-deep(.el-input__wrapper) {
  1133. border-radius: rpx(15);
  1134. border-color: rgba($primary-color, 0.3);
  1135. margin-right: 10px;
  1136. &:focus-within {
  1137. box-shadow: 0 0 0 rpx(1) rgba($primary-color, 0.5);
  1138. }
  1139. }
  1140. ::v-deep(.el-input__inner) {
  1141. font-size: rpx(10);
  1142. color: $text-color;
  1143. text-indent: 1em;
  1144. }
  1145. }
  1146. /* 定义淡入和缩放动画 */
  1147. .fade-scale-enter-active,
  1148. .fade-scale-leave-active {
  1149. transition: all 0.5s ease;
  1150. }
  1151. .fade-scale-enter-from,
  1152. .fade-scale-leave-to {
  1153. opacity: 0.1;
  1154. transform: scale(0.9);
  1155. }
  1156. // 自定义试题弹框背景
  1157. .child-dialog-wrapper {
  1158. position: fixed;
  1159. top: 0;
  1160. left: 0;
  1161. right: 0;
  1162. bottom: 0;
  1163. background-color: rgba(0, 0, 0, 0.6); // 半透明背景
  1164. display: flex;
  1165. justify-content: center;
  1166. align-items: center;
  1167. z-index: 1000;
  1168. }
  1169. .child-dialog {
  1170. border: none;
  1171. border-radius: rpx(20);
  1172. background: linear-gradient(
  1173. 135deg,
  1174. $light-color,
  1175. #d8bfd8
  1176. ); // 柔和的蓝紫色渐变
  1177. box-shadow: 0 0 20px 5px rgba($primary-color, 0.6),
  1178. 0 0 40px 10px rgba($primary-color, 0.4),
  1179. 0 0 60px 15px rgba($primary-color, 0.2);
  1180. overflow: hidden;
  1181. padding: rpx(20);
  1182. width: 60%;
  1183. position: relative;
  1184. }
  1185. // AI对话弹框样式
  1186. .ai-dialog-wrapper {
  1187. position: fixed;
  1188. top: 0;
  1189. left: 0;
  1190. right: 0;
  1191. bottom: 0;
  1192. display: flex;
  1193. justify-content: flex-end;
  1194. align-items: center;
  1195. z-index: 1001;
  1196. pointer-events: none;
  1197. }
  1198. .ai-dialog {
  1199. border: none;
  1200. border-radius: rpx(20);
  1201. background: linear-gradient(135deg, $light-color, #d8bfd8);
  1202. box-shadow: 0 0 20px 5px rgba($primary-color, 0.6),
  1203. 0 0 40px 10px rgba($primary-color, 0.4),
  1204. 0 0 60px 15px rgba($primary-color, 0.2);
  1205. overflow: hidden;
  1206. padding: rpx(20);
  1207. width: 30%;
  1208. // 增加高度
  1209. height: 80%;
  1210. margin-right: rpx(50);
  1211. pointer-events: auto;
  1212. position: relative;
  1213. display: flex;
  1214. flex-direction: column;
  1215. &::before {
  1216. content: '';
  1217. position: absolute;
  1218. top: 0;
  1219. left: 0;
  1220. width: 100%;
  1221. height: rpx(10);
  1222. background: linear-gradient(
  1223. 90deg,
  1224. $primary-color,
  1225. $secondary-color,
  1226. $accent-color
  1227. );
  1228. }
  1229. }
  1230. .ai-dialog-header {
  1231. display: flex;
  1232. justify-content: space-between;
  1233. align-items: center;
  1234. margin-bottom: rpx(15);
  1235. h3 {
  1236. color: $text-color;
  1237. font-size: rpx(12);
  1238. }
  1239. .close-btn {
  1240. padding: 0;
  1241. width: rpx(20);
  1242. height: rpx(20);
  1243. font-size: rpx(16);
  1244. line-height: 1;
  1245. }
  1246. }
  1247. .ai-dialog-content {
  1248. flex: 1;
  1249. display: flex;
  1250. flex-direction: column;
  1251. }
  1252. .ai-message-history {
  1253. flex: 1;
  1254. // 当内容超出容器高度时,显示垂直滚动条
  1255. overflow-y: auto;
  1256. margin-bottom: rpx(15);
  1257. // 可以根据实际情况调整最大高度
  1258. max-height: 50vh;
  1259. padding: 5px 10px;
  1260. .message {
  1261. display: flex;
  1262. align-items: flex-start;
  1263. margin-bottom: rpx(10);
  1264. &.user {
  1265. flex-direction: row-reverse;
  1266. }
  1267. .avatar {
  1268. width: rpx(30);
  1269. height: rpx(30);
  1270. border-radius: 50%;
  1271. margin: 0 rpx(10);
  1272. }
  1273. .user {
  1274. width: 15px;
  1275. height: 15px;
  1276. }
  1277. .message-content {
  1278. background-color: $light-color;
  1279. padding: rpx(8) rpx(12);
  1280. border-radius: rpx(10);
  1281. font-size: rpx(10);
  1282. color: $text-color;
  1283. max-width: 80%;
  1284. box-shadow: 0 rpx(1) rpx(3) rgba(0, 0, 0, 0.05);
  1285. }
  1286. }
  1287. // 滚动条整体样式
  1288. &::-webkit-scrollbar {
  1289. width: rpx(4); // 滚动条宽度
  1290. }
  1291. // 滚动条滑块样式
  1292. &::-webkit-scrollbar-thumb {
  1293. background-color: $primary-color; // 滑块颜色
  1294. border-radius: rpx(4); // 滑块圆角
  1295. transition: background-color 0.3s ease; // 颜色过渡效果
  1296. &:hover {
  1297. //background-color: darken($primary-color, 10%); // 悬停时滑块颜色加深
  1298. }
  1299. }
  1300. // 滚动条轨道样式
  1301. &::-webkit-scrollbar-track {
  1302. background-color: rgba($primary-color, 0.2); // 轨道颜色
  1303. border-radius: rpx(4); // 轨道圆角
  1304. }
  1305. .message {
  1306. display: flex;
  1307. align-items: flex-start;
  1308. margin-bottom: rpx(10);
  1309. &.user {
  1310. flex-direction: row-reverse;
  1311. }
  1312. .avatar {
  1313. width: rpx(30);
  1314. height: rpx(30);
  1315. border-radius: 50%;
  1316. margin: 0 rpx(10);
  1317. }
  1318. .message-content {
  1319. background-color: $light-color;
  1320. padding: rpx(8) rpx(12);
  1321. border-radius: rpx(10);
  1322. font-size: rpx(10);
  1323. color: $text-color;
  1324. max-width: 80%;
  1325. box-shadow: 0 rpx(1) rpx(3) rgba(0, 0, 0, 0.05);
  1326. }
  1327. }
  1328. }
  1329. // 优化发送按钮样式
  1330. .send-button {
  1331. //background: linear-gradient(90deg, $primary-color, $secondary-color);
  1332. border: none;
  1333. color: white;
  1334. &:hover {
  1335. //background: linear-gradient(90deg, darken($primary-color, 5%), darken($secondary-color, 5%));
  1336. }
  1337. }
  1338. </style>