AIGeneralCourse.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915
  1. <template>
  2. <!-- AI智能课 -->
  3. <div class="home-container">
  4. <!-- 展开收起侧边栏 -->
  5. <div class="sidebar-container">
  6. <div class="sidebar-layout">
  7. <div
  8. class="icon-expand"
  9. :style="{
  10. backgroundColor: drawerVisible ? '#44449c' : '#7F70C840',
  11. left: drawerVisible ? '18%' : '0'
  12. }"
  13. @click="toggleDrawer"
  14. >
  15. <span
  16. class="vertical-lines"
  17. :style="{
  18. color: drawerVisible ? '#8a78d0' : 'white'
  19. }"
  20. >||</span
  21. >
  22. </div>
  23. </div>
  24. <transition name="drawer-slide">
  25. <div class="main-content" v-if="drawerVisible">
  26. <!-- 菜单栏 -->
  27. <div class="drawer-box">
  28. <el-row class="tac">
  29. <el-col :span="12">
  30. <el-menu
  31. :default-active="currentActiveIndex"
  32. :default-openeds="[currentOpenedMenu]"
  33. :class="{ 'el-menu-vertical-demo': true }"
  34. unique-opened
  35. >
  36. <!-- 课程菜单 -->
  37. <el-sub-menu
  38. v-for="menu in menuList"
  39. :key="menu.id"
  40. :index="menu.id"
  41. @click="showPracticalCourse = menu.isPractical; showAICourse = menu.isAICourse; currentOpenedMenu = menu.id"
  42. >
  43. <template #title>
  44. <span>{{ menu.title }}</span>
  45. </template>
  46. <el-menu-item
  47. v-for="(item, index) in menu.data"
  48. :key="menu.id + '-' + index"
  49. :index="menu.id + '-' + (index + 1).toString()"
  50. @click="goToAIExperience(item)"
  51. >
  52. {{ item.ctTypeSort }} {{ item.ctType }}
  53. </el-menu-item>
  54. </el-sub-menu>
  55. </el-menu>
  56. </el-col>
  57. </el-row>
  58. </div>
  59. </div>
  60. </transition>
  61. </div>
  62. <div class="content-box">
  63. <div class="box-1">
  64. <div class="inner-box left-box">
  65. <div class="box-icon" @click="goBack">
  66. <el-icon class="left-icon"><ArrowLeftBold /></el-icon>
  67. {{ pageTitle }}
  68. </div>
  69. <div class="dropdown-box">
  70. <!-- 下拉菜单 -->
  71. <el-dropdown v-model="selectedGrade" @command="handleGradeSelect" @visible-change="handleVisibleChange">
  72. <el-button type="primary">
  73. {{ selectedGrade }}
  74. <!-- 根据下拉框状态显示不同的箭头图标 -->
  75. <el-icon class="el-icon--right" v-if="!dropdownVisible"><ArrowDownBold /></el-icon>
  76. <el-icon class="el-icon--right" v-else><ArrowUpBold /></el-icon>
  77. </el-button>
  78. <template #dropdown>
  79. <el-dropdown-menu class="dropdown-menu">
  80. <el-dropdown-item
  81. v-for="item in classData"
  82. :key="item.id"
  83. :command="item.ctType"
  84. >{{ item.ctType }}</el-dropdown-item
  85. >
  86. </el-dropdown-menu>
  87. </template>
  88. </el-dropdown>
  89. </div>
  90. </div>
  91. <div class="inner-box right-box">
  92. <div class="top-right-box">
  93. <el-autocomplete
  94. v-model="SearchInput"
  95. :fetch-suggestions="querySearch"
  96. placeholder="搜索"
  97. @select="handleSearchSelect"
  98. class="search-input"
  99. value-key="ctType"
  100. :trigger-on-focus="false"
  101. :key="searchKey"
  102. >
  103. <template #prefix>
  104. <el-icon class="el-input__icon"><search /></el-icon>
  105. </template>
  106. <!-- 下拉项模板 -->
  107. <template #default="{ item }">
  108. <div class="scrollbar">
  109. <!-- 序号和标题 -->
  110. {{ item.ctTypeSort }} {{ item.ctType }}
  111. </div>
  112. </template>
  113. </el-autocomplete>
  114. </div>
  115. </div>
  116. </div>
  117. <div class="box-2">
  118. <div
  119. class="small-box"
  120. v-for="(outlineData, index) in currentCourseData"
  121. :key="index"
  122. @click="goToAIExperience(outlineData)"
  123. >
  124. <div
  125. class="nested-box"
  126. :style="{
  127. backgroundImage: `url(${outlineData.ctTypeImage})`,
  128. backgroundSize: 'cover'
  129. }"
  130. ></div>
  131. <div class="additional-text">
  132. {{ outlineData.ctTypeSort }} {{ outlineData.ctType }}
  133. </div>
  134. </div>
  135. </div>
  136. </div>
  137. </div>
  138. </template>
  139. <script setup>
  140. import { ref, onMounted, computed, watch, onBeforeUnmount } from 'vue'
  141. import { ClassList, ClassOutline } from '@/api/class.js'
  142. // Element Plus 组件引入
  143. import {
  144. ArrowUpBold,
  145. ArrowDownBold,
  146. ArrowRightBold,
  147. Expand,
  148. Reading,
  149. Fold,
  150. Tickets
  151. } from '@element-plus/icons-vue'
  152. import { Search, ArrowLeftBold } from '@element-plus/icons-vue'
  153. import { ElAutocomplete } from 'element-plus' // 导入ElAutocomplete组件
  154. import { Message } from '@/utils/message/Message.js'
  155. import { useRouter } from 'vue-router'
  156. import teachingImg from '@/assets/icon/teaching.png'
  157. const router = useRouter() // 获取当前路由对象
  158. // 下拉菜单选中项
  159. const selectedGrade = ref('')
  160. // 抽屉显示状态
  161. const drawerVisible = ref(true)
  162. // 下拉框可见性状态
  163. const dropdownVisible = ref(false)
  164. // 处理下拉框显示/隐藏事件
  165. const handleVisibleChange = (visible) => {
  166. dropdownVisible.value = visible
  167. }
  168. // 通识课
  169. const classOutlineData = ref([])
  170. // 实操课
  171. const practicalCourseData = ref([])
  172. // AI生成课
  173. const aiGeneratedCourseData = ref([])
  174. // 状态变量,跟踪当前显示的是通识课、实操课还是AI生成课
  175. const showPracticalCourse = ref(false)
  176. // 状态变量,跟踪当前显示的是实操课还是AI生成课
  177. const showAICourse = ref(false)
  178. // 当前选中的菜单索引
  179. const currentActiveIndex = ref('general-1')
  180. // 当前打开的菜单
  181. const currentOpenedMenu = ref('general')
  182. // 存储选中状态的键名
  183. const activeMenuKey = 'aiGeneralCourseActiveMenu'
  184. const activeIndexKey = 'aiGeneralCourseActiveIndex'
  185. // 菜单列表计算属性
  186. const menuList = computed(() => [
  187. {
  188. id: 'general',
  189. title: '通识课',
  190. data: classOutlineData.value,
  191. isPractical: false,
  192. isAICourse: false
  193. },
  194. {
  195. id: 'practical',
  196. title: '实操课',
  197. data: practicalCourseData.value,
  198. isPractical: true,
  199. isAICourse: false
  200. },
  201. {
  202. id: 'ai',
  203. title: 'AI生成课',
  204. data: aiGeneratedCourseData.value,
  205. isPractical: false,
  206. isAICourse: true
  207. }
  208. ])
  209. // 处理课程数据,添加序号
  210. const processCourseData = (data) => {
  211. return data.map((item, index) => {
  212. item.ctTypeSort = index + 1
  213. item.ctTypeSort = item.ctTypeSort > 9 ? item.ctTypeSort : "0" + item.ctTypeSort
  214. return item
  215. })
  216. }
  217. // 保存当前选中状态
  218. const saveActiveState = (menuId, index) => {
  219. localStorage.setItem(activeMenuKey, menuId)
  220. localStorage.setItem(activeIndexKey, index)
  221. }
  222. // 统一函数来获取课程大纲数据 通识课/实操课/AI生成课
  223. const fetchClassOutline = async (classId) => {
  224. try {
  225. // 课程类型配置
  226. const courseTypes = [
  227. { type: "1", dataRef: classOutlineData },
  228. { type: "2", dataRef: practicalCourseData },
  229. { type: "3", dataRef: aiGeneratedCourseData }
  230. ]
  231. // 并行获取所有课程类型数据
  232. await Promise.all(courseTypes.map(async (courseType) => {
  233. const res = await ClassOutline(classId, courseType.type)
  234. console.log(res)
  235. if (res.code === 0) {
  236. courseType.dataRef.value = processCourseData(res.data)
  237. }
  238. }))
  239. } catch (error) {
  240. console.error('获取课程大纲数据失败:', error)
  241. }
  242. }
  243. // 处理下拉菜单选择
  244. const handleGradeSelect = command => {
  245. selectedGrade.value = command
  246. // 保存选中值到localStorage
  247. localStorage.setItem('selectedGrade', command)
  248. // 年级切换时重新加载数据的逻辑
  249. const selectedItem = classData.value.find(item => item.ctType === command)
  250. // 清空搜索框内容
  251. SearchInput.value = ''
  252. // 存储年级id
  253. if (selectedItem) {
  254. localStorage.setItem('selectedGradeId', selectedItem.id)
  255. // 获取课程大纲
  256. fetchClassOutline(selectedItem.id).then(() => {
  257. // 检查是否当前显示的是实操课但没有实操课数据
  258. // if (showPracticalCourse.value && ClassOutlineScData.value.length === 0) {
  259. // // 切换回通识课
  260. // showPracticalCourse.value = false
  261. // // 显示提示
  262. // Message().notifyWarning('此版本未开放,敬请期待!', true)
  263. // // 更新localStorage中的状态
  264. // localStorage.setItem('showPracticalCourse', 'false')
  265. // }
  266. })
  267. }
  268. }
  269. // 切换抽屉显示状态的函数
  270. const toggleDrawer = () => {
  271. drawerVisible.value = !drawerVisible.value
  272. }
  273. // 获取年级
  274. const classData = ref([])
  275. const fetchCtTypes = async () => {
  276. try {
  277. const response = await ClassList()
  278. if (response.code === 0) {
  279. classData.value = response.data
  280. // 获取到数据,优先从localStorage读取选中值
  281. const savedGrade = localStorage.getItem('selectedGrade')
  282. selectedGrade.value =
  283. savedGrade ||
  284. (classData.value.length > 0 ? classData.value[0].ctType : '')
  285. // 初始化时获取课程大纲数据
  286. const selectedItem =
  287. classData.value.find(item => item.ctType === selectedGrade.value) ||
  288. classData.value[0]
  289. if (selectedItem) {
  290. // 使用新函数获取课程大纲
  291. fetchClassOutline(selectedItem.id)
  292. }
  293. }
  294. } catch (error) {
  295. console.error('获取 ctType 数据失败:', error)
  296. }
  297. }
  298. // 获取课程标题
  299. const getCourseTitle = index => {
  300. if (
  301. classOutlineData.value.length > 0 &&
  302. index > 0 &&
  303. index <= classOutlineData.value.length
  304. ) {
  305. return classOutlineData.value[index - 1].ctType
  306. }
  307. return ''
  308. }
  309. // 首页点击渲染后的页面title
  310. const pageTitle = ref('返回首页')
  311. onMounted(() => {
  312. fetchCtTypes()
  313. // 读取之前保存的选中状态
  314. const savedMenu = localStorage.getItem(activeMenuKey)
  315. const savedIndex = localStorage.getItem(activeIndexKey)
  316. if (savedMenu && savedIndex) {
  317. currentOpenedMenu.value = savedMenu
  318. currentActiveIndex.value = savedIndex
  319. // 根据保存的菜单类型设置对应的显示状态
  320. showPracticalCourse.value = savedMenu === 'practical'
  321. showAICourse.value = savedMenu === 'ai'
  322. }
  323. // const title = history.state?.title
  324. // if (title) {
  325. // pageTitle.value = title
  326. // }
  327. })
  328. // 搜索框
  329. const SearchInput = ref('')
  330. // 用于强制重新渲染搜索组件的key
  331. const searchKey = ref(Date.now())
  332. // 当前显示的课程数据
  333. const currentCourseData = computed(() => {
  334. if (showAICourse.value) return aiGeneratedCourseData.value
  335. if (showPracticalCourse.value) return practicalCourseData.value
  336. return classOutlineData.value
  337. })
  338. // 搜索建议查询方法
  339. const querySearch = (queryString, cb) => {
  340. const data = currentCourseData.value
  341. const results = queryString
  342. ? data.filter(item => {
  343. // 课程标题和序号查询
  344. return item.ctType.toLowerCase().includes(queryString.toLowerCase()) ||
  345. item.ctTypeSort.includes(queryString)
  346. })
  347. : data
  348. cb(results)
  349. }
  350. // 搜索选择处理方法
  351. const handleSearchSelect = item => {
  352. goToAIExperience(item)
  353. // 清空输入框
  354. SearchInput.value = '';
  355. }
  356. // 修改过滤逻辑,直接使用currentCourseData
  357. const filteredTitles = computed(() => {
  358. const data = currentCourseData.value
  359. if (!SearchInput.value) {
  360. return data
  361. }
  362. return data.filter(title =>
  363. title.ctType.toLowerCase().includes(SearchInput.value.toLowerCase()) ||
  364. title.ctTypeSort.includes(SearchInput.value)
  365. )
  366. })
  367. // 添加按钮显示状态
  368. const buttonVisible = ref(false)
  369. const goBack = () => {
  370. router.push('/home') // 跳转到HomePage
  371. }
  372. const goToAIExperience = outlineData => {
  373. // 确定当前课程所属的菜单类型
  374. let menuId = 'general'
  375. if (showPracticalCourse.value) {
  376. menuId = 'practical'
  377. } else if (showAICourse.value) {
  378. menuId = 'ai'
  379. }
  380. // 找到当前课程在对应菜单中的索引
  381. const currentData = showPracticalCourse.value ? practicalCourseData.value :
  382. showAICourse.value ? aiGeneratedCourseData.value : classOutlineData.value
  383. const index = currentData.findIndex(item => item.id === outlineData.id)
  384. if (index !== -1) {
  385. const menuIndex = menuId + '-' + (index + 1)
  386. // 保存选中状态
  387. saveActiveState(menuId, menuIndex)
  388. }
  389. // 课程跳转逻辑
  390. router.push({
  391. path: '/ai-develop', // 跳转视频页面
  392. state: { typeId: outlineData.id, typeName: outlineData.ctType, typeSort: outlineData.ctTypeSort }
  393. })
  394. }
  395. </script>
  396. <style scoped lang="scss">
  397. @use 'sass:math';
  398. // 定义rpx转换函数
  399. @function rpx($px) {
  400. @return math.div($px, 750) * 100vw;
  401. }
  402. /* 添加过渡样式 */
  403. .drawer-slide-enter-active,
  404. .drawer-slide-leave-active {
  405. transition: all 0.3s ease;
  406. }
  407. .drawer-slide-enter-from,
  408. .drawer-slide-leave-to {
  409. transform: translateX(-100%);
  410. opacity: 0;
  411. transition: all 0.3s ease;
  412. }
  413. .home-container {
  414. position: fixed;
  415. top: 0;
  416. left: 0;
  417. right: 0;
  418. bottom: 0;
  419. display: flex;
  420. flex-direction: row;
  421. background: linear-gradient(
  422. to bottom,
  423. #e2ddfc,
  424. #f1effd
  425. ); /* 设置悬停、聚焦、点击状态下的背景色 */
  426. gap: rpx(0);
  427. }
  428. .sidebar-layout {
  429. display: flex;
  430. flex-direction: row;
  431. align-items: flex-start;
  432. }
  433. .icon-wrapper {
  434. width: 40px; /* 根据实际需要调整宽度 */
  435. flex-shrink: 0;
  436. background-color: saddlebrown;
  437. }
  438. .main-content {
  439. width: rpx(135);
  440. height: 100%;
  441. flex-grow: 1;
  442. background: linear-gradient(to bottom, hsl(230, 100%, 21%), #8a78d0); position: relative;
  443. overflow-y: auto; /* 添加垂直滚动条 */
  444. max-height: 100%; /* 设置最大高度 */
  445. transition: all 0.3s ease;
  446. // 自定义滚动条样式
  447. &::-webkit-scrollbar {
  448. width: rpx(0); // 滚动条宽度
  449. }
  450. &::-webkit-scrollbar-track {
  451. background-color: rgba(255, 255, 255, 0.1); // 滚动条轨道背景色
  452. border-radius: rpx(2); // 滚动条轨道圆角
  453. }
  454. &::-webkit-scrollbar-thumb {
  455. background-color: rgba(255, 255, 255, 0.3); // 滚动条滑块颜色
  456. border-radius: rpx(2); // 滚动条滑块圆角
  457. transition: background-color 0.3s ease; // 滑块颜色过渡效果
  458. }
  459. &::-webkit-scrollbar-thumb:hover {
  460. background-color: rgba(255, 255, 255, 0.5); // 鼠标悬停时的滑块颜色
  461. }
  462. }
  463. .icon-expand {
  464. width: rpx(8);
  465. height: rpx(35);
  466. border-top-right-radius: rpx(5);
  467. border-bottom-right-radius: rpx(5);
  468. z-index: 9999;
  469. position: absolute;
  470. top: 50%;
  471. transform: translateY(-50%);
  472. cursor: pointer; // 鼠标指针样式
  473. // 修改裁剪路径使右侧边缘垂直无缝贴合
  474. clip-path: polygon(0 0, 100% 15%, 100% 90%, 0 100%);
  475. display: flex;
  476. justify-content: center;
  477. align-items: center;
  478. // 统一过渡时间与菜单保持同步
  479. transition: all 0.3s ease;
  480. }
  481. .icon-expand .vertical-lines {
  482. color: #8a78d0;
  483. font-size: rpx(10);
  484. }
  485. .content-box {
  486. flex: 1;
  487. height: 100%;
  488. display: flex;
  489. flex-direction: column; /* 子元素上下排列 */
  490. background: linear-gradient(
  491. to bottom,
  492. #e2ddfc,
  493. #f1effd
  494. ); /* 设置悬停、聚焦、点击状态下的背景色 */
  495. }
  496. .tac .el-menu {
  497. background-color: transparent;
  498. border: none;
  499. width: 100%;
  500. margin-left: rpx(10);
  501. margin-top: rpx(10);
  502. }
  503. .el-sub-menu ::v-deep(.el-menu){
  504. background-color: transparent;
  505. }
  506. .el-menu-item {
  507. width: rpx(115);
  508. height: rpx(25);
  509. margin-bottom: rpx(5);
  510. border-radius: rpx(6);
  511. color: white;
  512. font-size: rpx(8);
  513. }
  514. .el-sub-menu ::v-deep(.el-sub-menu__title) {
  515. width: rpx(115);
  516. margin-bottom: rpx(5);
  517. border-radius: rpx(6);
  518. color: white;
  519. font-size: rpx(9);
  520. font-weight: bold;
  521. padding-left: rpx(10) !important;
  522. height: rpx(25);
  523. line-height: rpx(30);
  524. background: rgba(255, 255, 255, 0.1);
  525. transition: all 0.3s ease;
  526. // flex布局使标题和图标两端对齐
  527. display: flex;
  528. justify-content: space-between;
  529. align-items: center;
  530. }
  531. .el-sub-menu ::v-deep(.el-sub-menu__title:hover) {
  532. background: linear-gradient(
  533. to bottom,
  534. #ffefb0,
  535. #ffcc00
  536. );
  537. color: black;
  538. box-shadow: 0 4px 8px rgb(0, 0, 0, 0.2);
  539. }
  540. .el-sub-menu.is-opened ::v-deep(.el-sub-menu__title) {
  541. background: linear-gradient(
  542. to bottom,
  543. #ffefb0,
  544. #ffcc00
  545. );
  546. color: black;
  547. box-shadow: 0 4px 8px rgb(0, 0, 0, 0.2);
  548. }
  549. .el-sub-menu ::v-deep(.el-icon) {
  550. font-size: rpx(12);
  551. color: white;
  552. }
  553. // 添加折叠图标样式
  554. .el-sub-menu ::v-deep(.el-sub-menu__icon-arrow) {
  555. color: white;
  556. font-size: rpx(10);
  557. margin-left: auto; // 将图标推到右侧
  558. margin-top: rpx(-5);
  559. display: block;
  560. width: rpx(16); // 确保有明确宽度
  561. }
  562. .el-sub-menu.is-opened ::v-deep(.el-icon) {
  563. color: black;
  564. }
  565. .el-sub-menu ::v-deep(.el-sub-menu__title:hover .el-icon) {
  566. color: black;
  567. }
  568. .el-menu ::v-deep(.el-menu-item:hover),
  569. .el-menu ::v-deep(.el-menu-item:focus),
  570. .el-menu ::v-deep(.el-menu-item:active) {
  571. background: linear-gradient(
  572. to bottom,
  573. #ffefb0,
  574. #ffcc00
  575. ); /* 设置悬停、聚焦、点击状态下的背景色 */
  576. box-shadow: 0 4px 8px rgb(0, 0, 0, 0.2);
  577. color: black;
  578. }
  579. .drawer-box {
  580. position: absolute;
  581. display: flex;
  582. // align-items: center;
  583. margin-top: rpx(10);
  584. height: 100%;
  585. width: 100%;
  586. }
  587. .drawer-box .toggle-button {
  588. width: rpx(10);
  589. height: rpx(50);
  590. background-color: rgba(165, 209, 247, 0.2);
  591. border: none;
  592. position: relative;
  593. writing-mode: vertical-lr; // 文字垂直排列,从左到右
  594. text-orientation: upright; // 文字保持正立
  595. }
  596. .toggle-button:hover {
  597. left: 0;
  598. }
  599. .drawer-box ::v-deep(.el-drawer.ltr) {
  600. background-color: rgb(255, 255, 255, 0.7);
  601. box-shadow: 0 8px 8px rgba(202, 52, 52, 0.1);
  602. }
  603. .drawer-box ::v-deep(.el-drawer__header) {
  604. margin-bottom: rpx(0);
  605. }
  606. .drawer-box ::v-deep(.el-drawer__body)::-webkit-scrollbar {
  607. width: rpx(4);
  608. }
  609. .drawer-box ::v-deep(.el-drawer__body)::-webkit-scrollbar-thumb {
  610. background-color: rgba(0, 0, 0, 0.2);
  611. border-radius: 8px;
  612. }
  613. .drawer-box ::v-deep(.el-drawer__body)::-webkit-scrollbar-track {
  614. background-color: rgba(0, 0, 0, 0.05);
  615. border-radius: 8px;
  616. }
  617. .toggle-button.is-active,
  618. .toggle-button:active,
  619. .toggle-button:focus {
  620. background-color: rgba(165, 209, 247, 0.8);
  621. color: black;
  622. border: none; // 移除点击时的边框
  623. outline: none; // 移除点击时的外边框
  624. }
  625. .box-1 {
  626. width: 100%;
  627. height: rpx(50);
  628. display: flex;
  629. justify-content: center;
  630. align-items: center;
  631. box-sizing: border-box;
  632. font-size: rpx(16); // 默认字体大小
  633. }
  634. .inner-box {
  635. height: 100%;
  636. display: flex;
  637. justify-content: center;
  638. align-items: center;
  639. font-size: rpx(16); // 默认字体大小
  640. }
  641. .left-box {
  642. position: relative;
  643. justify-content: left;
  644. flex: 1;
  645. display: flex;
  646. align-items: center;
  647. gap: rpx(5); // 间距控制
  648. }
  649. .box-icon {
  650. height: 100%;
  651. display: flex;
  652. align-items: center; // 垂直居中
  653. color: black; // 设置图标颜色为白色
  654. padding-left: rpx(15);
  655. font-size: rpx(10); // 设置图标大小,可按需调整
  656. cursor: pointer; // 鼠标指针样式
  657. z-index: 999;
  658. }
  659. // .box-icon .left-icon {
  660. // margin-left: rpx(10);
  661. // margin-right: rpx(5); // 设置图标和文字之间的间距 ;
  662. // }
  663. .left-box span {
  664. position: absolute;
  665. top: 20px;
  666. left: 20px;
  667. font-size: rpx(11); // 默认字体大小
  668. color: white;
  669. }
  670. .dropdown-box {
  671. height: 100%;
  672. display: flex; // flex 布局;
  673. align-items: center; // 垂直居中;
  674. }
  675. .dropdown-box .el-button {
  676. width: rpx(60); // 设置按钮宽度;
  677. height: rpx(15); // 设置按钮高度;
  678. background-color: rgb(255, 255, 255, 0.7);
  679. border: 1px white solid;
  680. box-shadow: 0 4px 8px rgb(0, 0, 0, 0.3);
  681. color: black;
  682. border: none;
  683. margin-left: rpx(10);
  684. border-radius: rpx(12);
  685. font-size: rpx(8); // 设置字体大小;
  686. }
  687. .dropdown-box .el-button:hover,
  688. .dropdown-box .el-button:focus,
  689. .dropdown-box .el-button:active {
  690. border: none; /* 移除悬停、聚焦、点击状态下的边框 */
  691. outline: none; /* 移除悬停、聚焦、点击状态下的轮廓线 el-scrollbar__view el-dropdown__list */
  692. }
  693. .dropdown-menu {
  694. width: rpx(100);
  695. border-radius: rpx(5);
  696. border: 1px white solid;
  697. background-color: rgb(255, 255, 255, 0.5);
  698. backdrop-filter: blur(rpx(5));
  699. box-shadow: 0 4px 8px rgba(202, 52, 52, 0.1);
  700. margin-left: rpx(40);
  701. }
  702. .dropdown-menu ::v-deep(.el-dropdown-menu__item) {
  703. font-size: rpx(8);
  704. color: black;
  705. border-radius: rpx(5);
  706. width: rpx(78);
  707. height: rpx(20);
  708. margin-left: rpx(4);
  709. margin-bottom: rpx(8);
  710. }
  711. .dropdown-menu ::v-deep(.el-dropdown-menu__item:hover),
  712. .dropdown-menu ::v-deep(.el-dropdown-menu__item:focus),
  713. .dropdown-menu ::v-deep(.el-dropdown-menu__item:active) {
  714. background: linear-gradient(
  715. to bottom,
  716. #fee78a,
  717. #ffce1b
  718. ); /* 设置悬停、聚焦、点击状态下的背景色 */
  719. }
  720. .right-box {
  721. flex: 1;
  722. position: relative; // 添加相对定位;
  723. // background-color: #fff;
  724. display: flex;
  725. justify-content: right;
  726. align-items: center;
  727. }
  728. .top-right-box {
  729. width: rpx(130);
  730. display: flex;
  731. justify-content: flex;
  732. }
  733. .top-right-box {
  734. ::v-deep(.el-input__wrapper) {
  735. height: rpx(15);
  736. font-size: rpx(6);
  737. background-color: rgb(255, 255, 255, 0.5);
  738. border-radius: rpx(12);
  739. border: white 1px solid;
  740. color: #aaa5c5;
  741. }
  742. ::v-deep(.el-input__icon) {
  743. color: #aaa5c5; // 设置输入框图标颜色为白色
  744. }
  745. // 添加占位符样式
  746. ::v-deep(.el-input__inner::placeholder) {
  747. color: #aaa5c5;
  748. }
  749. // 添加输入框文字颜色样式
  750. ::v-deep(.el-input__inner) {
  751. color: black;
  752. }
  753. ::v-deep(.el-input--prefix){
  754. width: rpx(100);
  755. text-align: right;
  756. }
  757. }
  758. // 搜索
  759. .search-input {
  760. width: rpx(200); // 增加搜索框宽度
  761. height: rpx(30); // 增加搜索框高度
  762. font-size: rpx(9);
  763. border-radius: rpx(8); // 添加圆角
  764. border: 1px solid #dcdfe6; // 添加边框
  765. }
  766. ::v-deep(.el-input__inner) {
  767. color: #333; // 调整文字颜色
  768. }
  769. .box-2 {
  770. width: 100%;
  771. // flex: 1;
  772. box-sizing: border-box;
  773. display: flex; // 确保子元素水平排列
  774. flex-wrap: wrap; // 允许子元素换行;
  775. cursor: pointer; // 添加鼠标指针样式
  776. // margin: rpx(10) 0;
  777. overflow-y: auto;
  778. }
  779. // Chrome、Edge等浏览器的滚动条样式
  780. .box-2::-webkit-scrollbar {
  781. width: rpx(2);
  782. }
  783. .box-2::-webkit-scrollbar-track {
  784. background: transparent; // 设置滚动条轨道背景
  785. border-radius: rpx(3); // 设置滚动条轨道圆角
  786. }
  787. .box-2::-webkit-scrollbar-thumb {
  788. background: linear-gradient(to bottom, hsl(230, 100%, 21%), #8a78d0);
  789. border-radius: rpx(3); // 设置滚动条滑块圆角
  790. }
  791. .box-2::-webkit-scrollbar-thumb:hover {
  792. background: linear-gradient(to bottom, hsl(230, 100%, 21%), #8a78d0);
  793. }
  794. .small-box {
  795. flex: 0 0 calc(33.333% - rpx(10)); // 每个小盒子占三分之一宽度,减去间距
  796. margin-left: rpx(10); // 设置小盒子间距
  797. margin-top: rpx(3); // 设置小盒子间距
  798. display: flex;
  799. flex-direction: column;
  800. justify-content: flex-start;
  801. align-items: center;
  802. color: black;
  803. font-size: rpx(8);
  804. }
  805. .nested-box {
  806. width: rpx(150);
  807. height: rpx(80);
  808. border-radius: rpx(10);
  809. margin-top: rpx(5);
  810. display: flex;
  811. border: 1px solid white; // 添加边框;
  812. justify-content: center;
  813. align-items: center;
  814. }
  815. .nested-box:hover,
  816. .nested-box:active {
  817. box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
  818. }
  819. .additional-text {
  820. margin-bottom: rpx(4);
  821. font-size: rpx(8);
  822. }
  823. </style>
  824. <style lang="scss">
  825. /* 消除小三角 */
  826. .el-popper__arrow {
  827. display: none;
  828. }
  829. .el-popper.is-light,
  830. .el-dropdown__popper.el-popper {
  831. background: transparent;
  832. border: none;
  833. box-shadow: none;
  834. }
  835. .el-dropdown__popper {
  836. --el-dropdown-menuItem-hover-color: none;
  837. }
  838. </style>
  839. <style lang='scss'>
  840. // 搜索下拉框样式
  841. @use 'sass:math';
  842. // 定义rpx转换函数
  843. @function rpx($px) {
  844. @return math.div($px, 750) * 100vw;
  845. }
  846. .el-autocomplete-suggestion .el-scrollbar__wrap{
  847. margin: 0 auto;
  848. background-color: rgba(255, 255, 255, 0.7);
  849. border: 2px solid white;
  850. border-radius: rpx(5);
  851. backdrop-filter: blur(rpx(5));
  852. }
  853. .el-autocomplete-suggestion li{
  854. color: black;
  855. font-size: rpx(7);
  856. padding: rpx(5) rpx(8); // 调整下拉项内边距
  857. }
  858. .el-autocomplete-suggestion li:hover{
  859. background: linear-gradient(
  860. to bottom,
  861. #ffefb0,
  862. #ffcc00
  863. );
  864. }
  865. </style>