AIPoetryCourse.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  1. <template>
  2. <div class="home-container">
  3. <div class="sidebar-container">
  4. <div class="sidebar-layout">
  5. <div
  6. class="icon-expand"
  7. :style="{
  8. backgroundColor: drawerVisible ? '#44449c' : '#7F70C840',
  9. left: drawerVisible ? '20%' : '0'
  10. }"
  11. @click="toggleDrawer"
  12. >
  13. <span
  14. class="vertical-lines"
  15. :style="{
  16. color: drawerVisible ? '#8a78d0' : 'white'
  17. }"
  18. >||</span
  19. >
  20. </div>
  21. </div>
  22. <transition name="drawer-slide">
  23. <div class="main-content" :class="{ 'hidden': !drawerVisible }" v-if="drawerVisible">
  24. <div class="drawer-box">
  25. <el-row class="tac">
  26. <el-col :span="12">
  27. <el-menu
  28. v-if="menuInitialized"
  29. :default-active="currentActiveIndex"
  30. :default-openeds="[currentOpenedMenu]"
  31. :class="{ 'el-menu-vertical-demo': true }"
  32. unique-opened
  33. >
  34. <el-sub-menu
  35. v-for="menu in menuList"
  36. :key="menu.id"
  37. :index="menu.id"
  38. @click="handleMenuClick(menu)"
  39. >
  40. <template #title>
  41. <span>{{ menu.title }}</span>
  42. </template>
  43. <el-menu-item
  44. v-for="(item, index) in menu.data"
  45. :key="menu.id + '-' + index"
  46. :index="menu.id + '-' + (index + 1).toString()"
  47. @click="goToAIExperience(item)"
  48. >
  49. {{ item.ctTypeSort }} {{ item.ctType }}
  50. </el-menu-item>
  51. </el-sub-menu>
  52. </el-menu>
  53. </el-col>
  54. </el-row>
  55. </div>
  56. </div>
  57. </transition>
  58. </div>
  59. <div class="content-box">
  60. <div class="box-1">
  61. <div class="inner-box left-box">
  62. <div class="box-icon" @click="goBack">
  63. <el-icon class="left-icon"><ArrowLeftBold /></el-icon>
  64. {{ pageTitle }}
  65. </div>
  66. <div class="dropdown-box">
  67. <el-dropdown v-model="selectedGrade" @command="handleGradeSelect" @visible-change="handleVisibleChange">
  68. <el-button type="primary">
  69. {{ selectedGrade }}
  70. <el-icon class="el-icon--right" v-if="!dropdownVisible"><ArrowDownBold /></el-icon>
  71. <el-icon class="el-icon--right" v-else><ArrowUpBold /></el-icon>
  72. </el-button>
  73. <template #dropdown>
  74. <el-dropdown-menu class="dropdown-menu">
  75. <el-dropdown-item
  76. v-for="item in classData"
  77. :key="item.id"
  78. :command="item.ctType"
  79. >{{ item.ctType }}</el-dropdown-item
  80. >
  81. </el-dropdown-menu>
  82. </template>
  83. </el-dropdown>
  84. </div>
  85. </div>
  86. <div class="inner-box right-box">
  87. <div class="top-right-box">
  88. <el-autocomplete
  89. v-model="SearchInput"
  90. :fetch-suggestions="querySearch"
  91. placeholder="搜索"
  92. @select="handleSearchSelect"
  93. class="search-input"
  94. value-key="ctType"
  95. :trigger-on-focus="false"
  96. :key="searchKey"
  97. >
  98. <template #prefix>
  99. <el-icon class="el-input__icon"><search /></el-icon>
  100. </template>
  101. <template #default="{ item }">
  102. <div class="scrollbar">
  103. {{ item.ctTypeSort }} {{ item.ctType }}
  104. </div>
  105. </template>
  106. </el-autocomplete>
  107. </div>
  108. </div>
  109. </div>
  110. <div class="box-2">
  111. <div
  112. class="small-box parent-mobile-course-item"
  113. v-for="(course, index) in currentCourseData"
  114. :key="course.id"
  115. >
  116. <div
  117. class="nested-box"
  118. :style="{
  119. backgroundImage: `url(${course.ctTypeImage})`,
  120. backgroundSize: 'cover'
  121. }"
  122. @click="goToAIExperience(course)"
  123. ></div>
  124. <div class="additional-text">
  125. {{ course.ctTypeSort }} {{ course.ctType }}
  126. </div>
  127. </div>
  128. <div class="parent-mobile-container">
  129. <div
  130. class="parent-mobile-item"
  131. v-for="(course, index) in currentCourseData"
  132. :key="course.id"
  133. @click="goToAIExperience(course)"
  134. >
  135. <div class="parent-mobile-image">
  136. <img :src="course.ctTypeImage" :alt="course.title" />
  137. </div>
  138. <div class="parent-mobile-content">
  139. <div class="parent-mobile-title">
  140. <span class="parent-mobile-index">{{ course.ctTypeSort }}</span>
  141. {{ course.ctType }}
  142. </div>
  143. <div class="parent-mobile-desc">{{ course.ctTypeDescribe || '' }}</div>
  144. </div>
  145. </div>
  146. </div>
  147. <div v-if="currentCourseData.length === 0" class="empty-state" style="width: 100%; text-align: center; padding: 40px;">
  148. <p>暂无课程</p>
  149. </div>
  150. </div>
  151. </div>
  152. </div>
  153. </template>
  154. <script setup>
  155. import { ref, onMounted, computed, watch } from 'vue'
  156. import { ClassList, ClassOutline } from '@/api/class.js'
  157. import {
  158. ArrowUpBold,
  159. ArrowDownBold,
  160. ArrowRightBold,
  161. Expand,
  162. Reading,
  163. Fold,
  164. Tickets
  165. } from '@element-plus/icons-vue'
  166. import { Search, ArrowLeftBold } from '@element-plus/icons-vue'
  167. import { Message } from '@/utils/message/Message.js'
  168. import { useRouter } from 'vue-router'
  169. import { CONFIG } from '@/utils/roleUtils.js'
  170. import '@/styles/parentMobileCourse.css'
  171. const router = useRouter()
  172. const selectedGrade = ref('')
  173. const isMobile = ref(false)
  174. const drawerVisible = ref(true)
  175. const dropdownVisible = ref(false)
  176. const handleVisibleChange = (visible) => {
  177. dropdownVisible.value = visible
  178. }
  179. const poetryCourseData = ref([])
  180. const menuConfigTemp = [
  181. { id: '/poetry', title: 'AI诗词课', type: '3', data: poetryCourseData }
  182. ]
  183. const menuConfig = computed(() => {
  184. return menuConfigTemp.filter(item => {
  185. return roleRouteMenuSet.value.includes(item.id)
  186. })
  187. })
  188. const menuList = computed(() => {
  189. return menuConfig.value.map(menu => ({
  190. ...menu,
  191. data: menu.data.value
  192. }))
  193. })
  194. const roleRouteMenuSet = computed(() => {
  195. try {
  196. const roleRouteMenuStr = localStorage.getItem(CONFIG.USER_ROLE_ROUTE_MENU_KEY)
  197. return roleRouteMenuStr ? JSON.parse(roleRouteMenuStr) : []
  198. } catch (error) {
  199. console.error('Error parsing roleRouteMenuSet:', error)
  200. return []
  201. }
  202. })
  203. const currentActiveIndex = ref('/poetry-1')
  204. const currentOpenedMenu = ref('/poetry')
  205. const menuInitialized = ref(false)
  206. const activeMenuKey = 'aiPoetryCourseActiveMenu'
  207. const activeIndexKey = 'aiPoetryCourseActiveIndex'
  208. const encodeImageUrl = (url) => {
  209. if (!url) return url
  210. try {
  211. const decoded = decodeURI(url)
  212. const lastSlash = decoded.lastIndexOf('/')
  213. if (lastSlash === -1) {
  214. return encodeURIComponent(decoded).replace(/[!'()*]/g, c => '%' + c.charCodeAt(0).toString(16).toUpperCase())
  215. }
  216. const base = decoded.substring(0, lastSlash + 1)
  217. const filename = decoded.substring(lastSlash + 1)
  218. const encodedFilename = encodeURIComponent(filename)
  219. .replace(/[!'()*]/g, c => '%' + c.charCodeAt(0).toString(16).toUpperCase())
  220. return base + encodedFilename
  221. } catch {
  222. try {
  223. const lastSlash = url.lastIndexOf('/')
  224. if (lastSlash === -1) {
  225. return encodeURIComponent(url).replace(/[!'()*]/g, c => '%' + c.charCodeAt(0).toString(16).toUpperCase())
  226. }
  227. const base = url.substring(0, lastSlash + 1)
  228. const filename = url.substring(lastSlash + 1)
  229. const encodedFilename = encodeURIComponent(filename)
  230. .replace(/[!'()*]/g, c => '%' + c.charCodeAt(0).toString(16).toUpperCase())
  231. return base + encodedFilename
  232. } catch {
  233. return url
  234. }
  235. }
  236. }
  237. const processCourseData = (data) => {
  238. return data.map((item, index) => {
  239. item.ctTypeSort = index + 1
  240. item.ctTypeSort = item.ctTypeSort > 9 ? item.ctTypeSort : "0" + item.ctTypeSort
  241. item.ctTypeImage = encodeImageUrl(item.ctTypeImage)
  242. return item
  243. })
  244. }
  245. const saveActiveState = (menuId, index) => {
  246. localStorage.setItem(activeMenuKey, menuId)
  247. localStorage.setItem(activeIndexKey, index)
  248. }
  249. const fetchClassOutline = async (classId) => {
  250. try {
  251. await Promise.all(menuConfig.value.map(async (menu) => {
  252. const res = await ClassOutline(classId, menu.type)
  253. if (res.code === 0) {
  254. menu.data.value = processCourseData(res.data)
  255. }
  256. }))
  257. } catch (error) {
  258. console.error('获取课程大纲数据失败:', error)
  259. }
  260. }
  261. const handleMenuClick = (menu) => {
  262. currentOpenedMenu.value = menu.id
  263. saveActiveState(menu.id, menu.id)
  264. SearchInput.value = ''
  265. if (menu.data.value && menu.data.value.length > 0) {
  266. currentActiveIndex.value = menu.id + '-1'
  267. }
  268. }
  269. const handleGradeSelect = command => {
  270. selectedGrade.value = command
  271. localStorage.setItem('selectedGrade', command)
  272. SearchInput.value = ''
  273. const selectedItem = classData.value.find(item => item.ctType === command)
  274. if (selectedItem) {
  275. localStorage.setItem('selectedGradeId', selectedItem.id)
  276. fetchClassOutline(selectedItem.id).then(() => {
  277. const savedMenu = localStorage.getItem(activeMenuKey)
  278. const savedIndex = localStorage.getItem(activeIndexKey)
  279. if (savedMenu && savedIndex) {
  280. currentOpenedMenu.value = savedMenu
  281. currentActiveIndex.value = savedIndex
  282. }
  283. })
  284. }
  285. }
  286. const checkIsMobile = () => {
  287. if (typeof window !== 'undefined') {
  288. return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||
  289. window.innerWidth <= 768;
  290. }
  291. return false;
  292. }
  293. const toggleDrawer = () => {
  294. drawerVisible.value = !drawerVisible.value
  295. }
  296. const classData = ref([])
  297. const fetchCtTypes = async () => {
  298. try {
  299. const response = await ClassList()
  300. if (response.code === 0) {
  301. classData.value = response.data
  302. const savedGrade = localStorage.getItem('selectedGrade')
  303. selectedGrade.value = savedGrade || (classData.value.length > 0 ? classData.value[0].ctType : '')
  304. const selectedItem = classData.value.find(item => item.ctType === selectedGrade.value) || classData.value[0]
  305. if (selectedItem) {
  306. fetchClassOutline(selectedItem.id)
  307. }
  308. }
  309. } catch (error) {
  310. console.error('获取 ctType 数据失败:', error)
  311. }
  312. }
  313. const pageTitle = ref('返回首页')
  314. onMounted(() => {
  315. isMobile.value = checkIsMobile();
  316. if (isMobile.value) {
  317. drawerVisible.value = false;
  318. }
  319. fetchCtTypes()
  320. const savedMenu = localStorage.getItem(activeMenuKey)
  321. const savedIndex = localStorage.getItem(activeIndexKey)
  322. if (savedMenu && savedIndex) {
  323. currentOpenedMenu.value = savedMenu
  324. currentActiveIndex.value = savedIndex
  325. }
  326. menuInitialized.value = true
  327. })
  328. const SearchInput = ref('')
  329. const searchKey = ref(Date.now())
  330. const currentCourseData = computed(() => {
  331. const menu = menuConfig.value.find(m => m.id == currentOpenedMenu.value)
  332. return (menu && menu.data.value) || poetryCourseData.value
  333. })
  334. const querySearch = (queryString, cb) => {
  335. const data = currentCourseData.value
  336. const results = queryString
  337. ? data.filter(item => {
  338. return item.ctType.toLowerCase().includes(queryString.toLowerCase()) ||
  339. (item.ctTypeSort && item.ctTypeSort.toString().includes(queryString))
  340. })
  341. : data
  342. cb(results)
  343. }
  344. const handleSearchSelect = item => {
  345. goToAIExperience(item)
  346. SearchInput.value = '';
  347. }
  348. const buttonVisible = ref(false)
  349. const goBack = () => {
  350. router.push('/aiPoetryHome')
  351. }
  352. const goToAIExperience = (outlineData) => {
  353. const menuId = currentOpenedMenu.value
  354. const menu = menuConfig.value.find(m => m.id === menuId)
  355. const currentData = menu ? menu.data.value : []
  356. const index = currentData.findIndex(item => item.id === outlineData.id)
  357. if (index !== -1) {
  358. const menuIndex = menuId + '-' + (index + 1)
  359. saveActiveState(menuId, menuIndex)
  360. }
  361. router.push({
  362. path: '/ai-poetry-develop',
  363. state: { typeId: outlineData.id, typeName: outlineData.ctType, typeSort: outlineData.ctTypeSort }
  364. })
  365. }
  366. </script>
  367. <style scoped lang="scss">
  368. @use 'sass:math';
  369. @function rpx($px) {
  370. @return math.div($px, 750) * 100vw;
  371. }
  372. .drawer-slide-enter-active,
  373. .drawer-slide-leave-active {
  374. transition: all 0.3s ease;
  375. }
  376. .drawer-slide-enter-from,
  377. .drawer-slide-leave-to {
  378. transform: translateX(-100%);
  379. opacity: 0;
  380. transition: all 0.3s ease;
  381. }
  382. .home-container {
  383. position: fixed;
  384. top: 0;
  385. left: 0;
  386. right: 0;
  387. bottom: 0;
  388. display: flex;
  389. flex-direction: row;
  390. background: linear-gradient(
  391. to bottom,
  392. #e2ddfc,
  393. #f1effd
  394. );
  395. gap: rpx(0);
  396. }
  397. .sidebar-layout {
  398. display: flex;
  399. flex-direction: row;
  400. align-items: flex-start;
  401. }
  402. .main-content {
  403. width: rpx(150);
  404. height: 100%;
  405. flex-grow: 1;
  406. background: linear-gradient(to bottom, hsl(230, 100%, 21%), #8a78d0);
  407. position: relative;
  408. overflow-y: auto;
  409. max-height: 100%;
  410. transition: all 0.3s ease;
  411. &::-webkit-scrollbar {
  412. width: rpx(0);
  413. }
  414. &::-webkit-scrollbar-track {
  415. background-color: rgba(255, 255, 255, 0.1);
  416. border-radius: rpx(2);
  417. }
  418. &::-webkit-scrollbar-thumb {
  419. background-color: rgba(255, 255, 255, 0.3);
  420. border-radius: rpx(2);
  421. transition: background-color 0.3s ease;
  422. }
  423. &::-webkit-scrollbar-thumb:hover {
  424. background-color: rgba(255, 255, 255, 0.5);
  425. }
  426. }
  427. .icon-expand {
  428. width: rpx(8);
  429. height: rpx(35);
  430. border-top-right-radius: rpx(5);
  431. border-bottom-right-radius: rpx(5);
  432. z-index: 9999;
  433. position: absolute;
  434. top: 50%;
  435. transform: translateY(-50%);
  436. cursor: pointer;
  437. clip-path: polygon(0 0, 100% 15%, 100% 90%, 0 100%);
  438. display: flex;
  439. justify-content: center;
  440. align-items: center;
  441. transition: all 0.3s ease;
  442. }
  443. .icon-expand .vertical-lines {
  444. color: #8a78d0;
  445. font-size: rpx(10);
  446. }
  447. .content-box {
  448. flex: 1;
  449. height: 100%;
  450. display: flex;
  451. flex-direction: column;
  452. background: linear-gradient(
  453. to bottom,
  454. #e2ddfc,
  455. #f1effd
  456. );
  457. }
  458. .tac .el-menu {
  459. background-color: transparent;
  460. border: none;
  461. width: 100%;
  462. margin-left: rpx(10);
  463. margin-top: rpx(10);
  464. }
  465. .el-sub-menu ::v-deep(.el-menu){
  466. background-color: transparent;
  467. }
  468. .el-menu-item {
  469. width: rpx(130);
  470. height: rpx(25);
  471. margin-bottom: rpx(5);
  472. border-radius: rpx(6);
  473. color: white;
  474. font-size: rpx(8);
  475. }
  476. .el-sub-menu ::v-deep(.el-sub-menu__title) {
  477. width: rpx(130);
  478. margin-bottom: rpx(5);
  479. border-radius: rpx(6);
  480. color: white;
  481. font-size: rpx(9);
  482. font-weight: bold;
  483. padding-left: rpx(10) !important;
  484. height: rpx(25);
  485. line-height: rpx(30);
  486. background: rgba(255, 255, 255, 0.1);
  487. transition: all 0.3s ease;
  488. display: flex;
  489. justify-content: space-between;
  490. align-items: center;
  491. }
  492. .el-sub-menu ::v-deep(.el-sub-menu__title:hover) {
  493. background: linear-gradient(
  494. to bottom,
  495. #ffd700,
  496. #ffa500
  497. );
  498. color: black;
  499. box-shadow: 0 4px 8px rgb(0, 0, 0, 0.2);
  500. }
  501. .el-sub-menu.is-opened ::v-deep(.el-sub-menu__title) {
  502. background: linear-gradient(
  503. to bottom,
  504. #ffd700,
  505. #ffa500
  506. );
  507. color: black;
  508. box-shadow: 0 4px 8px rgb(0, 0, 0, 0.2);
  509. }
  510. .el-sub-menu ::v-deep(.el-icon) {
  511. font-size: rpx(12);
  512. color: white;
  513. }
  514. .el-sub-menu ::v-deep(.el-sub-menu__icon-arrow) {
  515. color: white;
  516. font-size: rpx(10);
  517. margin-left: auto;
  518. margin-top: rpx(-5);
  519. display: block;
  520. width: rpx(16);
  521. }
  522. .el-sub-menu.is-opened ::v-deep(.el-icon) {
  523. color: black;
  524. }
  525. .el-sub-menu ::v-deep(.el-sub-menu__title:hover .el-icon) {
  526. color: black;
  527. }
  528. .el-menu ::v-deep(.el-menu-item:hover),
  529. .el-menu ::v-deep(.el-menu-item:focus),
  530. .el-menu ::v-deep(.el-menu-item:active) {
  531. background: linear-gradient(
  532. to bottom,
  533. #ffd700,
  534. #ffa500
  535. );
  536. box-shadow: 0 4px 8px rgb(0, 0, 0, 0.2);
  537. color: black;
  538. }
  539. .drawer-box {
  540. position: absolute;
  541. display: flex;
  542. margin-top: rpx(10);
  543. height: 100%;
  544. width: 100%;
  545. }
  546. .box-1 {
  547. width: 100%;
  548. height: rpx(50);
  549. display: flex;
  550. justify-content: center;
  551. align-items: center;
  552. box-sizing: border-box;
  553. font-size: rpx(16);
  554. }
  555. .inner-box {
  556. height: 100%;
  557. display: flex;
  558. justify-content: center;
  559. align-items: center;
  560. font-size: rpx(16);
  561. }
  562. .left-box {
  563. position: relative;
  564. justify-content: left;
  565. flex: 1;
  566. display: flex;
  567. align-items: center;
  568. gap: rpx(5);
  569. }
  570. .box-icon {
  571. height: 100%;
  572. display: flex;
  573. align-items: center;
  574. color: black;
  575. padding-left: rpx(15);
  576. font-size: rpx(10);
  577. cursor: pointer;
  578. z-index: 999;
  579. }
  580. .dropdown-box {
  581. height: 100%;
  582. display: flex;
  583. align-items: center;
  584. }
  585. .dropdown-box .el-button {
  586. width: rpx(60);
  587. height: rpx(15);
  588. background-color: rgb(255, 255, 255, 0.7);
  589. border: 1px white solid;
  590. box-shadow: 0 4px 8px rgb(0, 0, 0, 0.3);
  591. color: black;
  592. border: none;
  593. margin-left: rpx(10);
  594. border-radius: rpx(12);
  595. font-size: rpx(8);
  596. }
  597. .dropdown-box .el-button:hover,
  598. .dropdown-box .el-button:focus,
  599. .dropdown-box .el-button:active {
  600. border: none;
  601. outline: none;
  602. }
  603. .dropdown-menu {
  604. width: rpx(100);
  605. border-radius: rpx(5);
  606. border: 1px white solid;
  607. background-color: rgb(255, 255, 255, 0.5);
  608. backdrop-filter: blur(rpx(5));
  609. box-shadow: 0 4px 8px rgba(202, 52, 52, 0.1);
  610. margin-left: rpx(40);
  611. }
  612. .dropdown-menu ::v-deep(.el-dropdown-menu__item) {
  613. font-size: rpx(8);
  614. color: black;
  615. border-radius: rpx(5);
  616. width: rpx(78);
  617. height: rpx(20);
  618. margin-left: rpx(4);
  619. margin-bottom: rpx(8);
  620. }
  621. .dropdown-menu ::v-deep(.el-dropdown-menu__item:hover),
  622. .dropdown-menu ::v-deep(.el-dropdown-menu__item:focus),
  623. .dropdown-menu ::v-deep(.el-dropdown-menu__item:active) {
  624. background: linear-gradient(
  625. to bottom,
  626. #fee78a,
  627. #ffce1b
  628. );
  629. }
  630. .right-box {
  631. flex: 1;
  632. position: relative;
  633. display: flex;
  634. justify-content: right;
  635. align-items: center;
  636. }
  637. .top-right-box {
  638. width: rpx(130);
  639. display: flex;
  640. justify-content: flex;
  641. }
  642. .top-right-box {
  643. ::v-deep(.el-input__wrapper) {
  644. height: rpx(15);
  645. font-size: rpx(6);
  646. background-color: rgb(255, 255, 255, 0.5);
  647. border-radius: rpx(12);
  648. border: white 1px solid;
  649. color: #aaa5c5;
  650. }
  651. ::v-deep(.el-input__icon) {
  652. color: #aaa5c5;
  653. }
  654. ::v-deep(.el-input__inner::placeholder) {
  655. color: #aaa5c5;
  656. }
  657. ::v-deep(.el-input__inner) {
  658. color: black;
  659. }
  660. ::v-deep(.el-input--prefix){
  661. width: rpx(100);
  662. text-align: right;
  663. }
  664. }
  665. .search-input {
  666. width: rpx(200);
  667. height: rpx(30);
  668. font-size: rpx(9);
  669. border-radius: rpx(8);
  670. border: 1px solid #8B4513;
  671. }
  672. .box-2 {
  673. width: 100%;
  674. flex: 1;
  675. box-sizing: border-box;
  676. display: flex;
  677. flex-wrap: wrap;
  678. cursor: pointer;
  679. overflow-y: auto;
  680. }
  681. .box-2::-webkit-scrollbar {
  682. width: rpx(2);
  683. }
  684. .box-2::-webkit-scrollbar-track {
  685. background: transparent;
  686. border-radius: rpx(3);
  687. }
  688. .box-2::-webkit-scrollbar-thumb {
  689. background: linear-gradient(to bottom, #8B4513, #D2691E);
  690. border-radius: rpx(3);
  691. }
  692. .box-2::-webkit-scrollbar-thumb:hover {
  693. background: linear-gradient(to bottom, #8B4513, #D2691E);
  694. }
  695. .small-box {
  696. flex: 0 0 calc(33.333% - rpx(10));
  697. margin-left: rpx(10);
  698. margin-top: rpx(3);
  699. display: flex;
  700. flex-direction: column;
  701. justify-content: flex-start;
  702. align-items: center;
  703. color: #8B4513;
  704. font-size: rpx(8);
  705. }
  706. .nested-box {
  707. width: rpx(150);
  708. height: rpx(80);
  709. border-radius: rpx(10);
  710. margin-top: rpx(5);
  711. display: flex;
  712. border: 1px solid #8B4513;
  713. justify-content: center;
  714. align-items: center;
  715. }
  716. .nested-box:hover,
  717. .nested-box:active {
  718. box-shadow: 0 4px 8px rgba(139, 69, 19, 0.5);
  719. }
  720. .additional-text {
  721. margin-bottom: rpx(4);
  722. font-size: rpx(8);
  723. }
  724. </style>
  725. <style lang="scss">
  726. .el-popper__arrow {
  727. display: none;
  728. }
  729. .el-popper.is-light,
  730. .el-dropdown__popper.el-popper {
  731. background: transparent;
  732. border: none;
  733. box-shadow: none;
  734. }
  735. .el-dropdown__popper {
  736. --el-dropdown-menuItem-hover-color: none;
  737. }
  738. </style>
  739. <style lang='scss'>
  740. @use 'sass:math';
  741. @function rpx($px) {
  742. @return math.div($px, 750) * 100vw;
  743. }
  744. .el-autocomplete-suggestion .el-scrollbar__wrap{
  745. margin: 0 auto;
  746. background-color: rgba(255, 255, 255, 0.7);
  747. border: 2px solid #8B4513;
  748. border-radius: rpx(5);
  749. backdrop-filter: blur(rpx(5));
  750. }
  751. .el-autocomplete-suggestion li{
  752. color: #8B4513;
  753. font-size: rpx(7);
  754. padding: rpx(5) rpx(8);
  755. }
  756. .el-autocomplete-suggestion li:hover{
  757. background: linear-gradient(
  758. to bottom,
  759. #ffd700,
  760. #ffa500
  761. );
  762. }
  763. </style>