AppLayout.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. <template>
  2. <div class="layout-wrapper" :class="{ 'full-screen': isFullScreen }">
  3. <!-- 背景层 - 只在需要透明的地方显示 -->
  4. <div
  5. class="background-layer"
  6. v-if="!isFullScreen && !isSelectCity && !isExcludedRoute"
  7. ></div>
  8. <!-- Header 部分 -->
  9. <el-header
  10. class="layout-header"
  11. v-if="!isFullScreen"
  12. :class="{ 'excluded-bg-header': isExcludedRoute }"
  13. >
  14. <div class="logo-title-row">
  15. <img src="@/assets/logo.png" alt="Logo" class="logo" />
  16. <div class="title-and-user">
  17. <span
  18. class="project-name"
  19. :class="{ 'excluded-text': isExcludedRoute }"
  20. >
  21. 区域土壤重金属污染风险评估
  22. </span>
  23. <!-- 用户信息 - 在select-city页面隐藏 -->
  24. <div
  25. class="user-info-row"
  26. v-if="!isSelectCity"
  27. :class="{ 'excluded-text': isExcludedRoute }"
  28. >
  29. <span class="welcome-text">
  30. 欢迎{{
  31. tokenStore.token.loginType === "admin" ? "管理员" : "用户"
  32. }}登录成功
  33. </span>
  34. <el-dropdown>
  35. <span class="el-dropdown-link">
  36. <el-avatar
  37. :size="40"
  38. :class="{ 'excluded-avatar-border': isExcludedRoute }"
  39. src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png"
  40. />
  41. </span>
  42. <template #dropdown>
  43. <el-dropdown-menu>
  44. <el-dropdown-item disabled
  45. >用户名:{{ userInfo.name }}</el-dropdown-item
  46. >
  47. <el-dropdown-item divided @click="handleLogout"
  48. >退出登录</el-dropdown-item
  49. >
  50. </el-dropdown-menu>
  51. </template>
  52. </el-dropdown>
  53. </div>
  54. </div>
  55. </div>
  56. </el-header>
  57. <!-- Tab 区域 - 不透明 -->
  58. <div class="tabs-row" v-if="!isFullScreen">
  59. <el-tabs
  60. v-if="showTabs"
  61. v-model="activeName"
  62. class="demo-tabs"
  63. :style="tabStyle"
  64. @tab-click="handleClick"
  65. >
  66. <el-tab-pane v-for="tab in tabs" :key="tab.name" :name="tab.name">
  67. <template #label>
  68. <i :class="['tab-icon', tab.icon]"></i>
  69. <span class="tab-label-text">{{ tab.label }}</span>
  70. </template>
  71. </el-tab-pane>
  72. </el-tabs>
  73. <div v-else class="single-tab" @click="handleClick(tabs[0], $event)">
  74. <i :class="['tab-icon', tabs[0].icon]"></i>
  75. <span class="tab-label-text">{{ tabs[0].label }}</span>
  76. </div>
  77. </div>
  78. <!-- 主体区域 -->
  79. <el-container class="layout-main-container">
  80. <!-- 侧边栏 - 不透明 -->
  81. <el-aside v-if="showAside && showTabs" class="layout-aside">
  82. <component
  83. :is="AsideComponent"
  84. :activeTab="activeName"
  85. :showTabs="showTabs"
  86. />
  87. </el-aside>
  88. <!-- 内容区域 -->
  89. <el-main
  90. class="layout-content-wrapper"
  91. :style="mainStyle"
  92. :class="{ 'excluded-bg-content': isExcludedRoute }"
  93. >
  94. <div
  95. class="scrollable-content"
  96. :style="{
  97. backgroundImage: currentBgImage,
  98. }"
  99. >
  100. <div :class="{ 'select-city-container': isSelectCity }">
  101. <RouterView />
  102. </div>
  103. </div>
  104. </el-main>
  105. </el-container>
  106. </div>
  107. </template>
  108. <script setup lang="ts">
  109. import { ref, reactive, computed, watch, defineAsyncComponent } from "vue";
  110. import { useRouter, useRoute } from "vue-router";
  111. import { useTokenStore } from "@/stores/mytoken";
  112. import { ElMessageBox, ElMessage } from "element-plus";
  113. import { logout } from "@/API/users";
  114. // 使用更可靠的图片导入方式
  115. function getImageUrl(name: string) {
  116. try {
  117. return new URL(`../../assets/bg/${name}`, import.meta.url).href;
  118. } catch (error) {
  119. console.error("加载背景图失败:", error);
  120. return "";
  121. }
  122. }
  123. const router = useRouter();
  124. const route = useRoute();
  125. const tokenStore = useTokenStore();
  126. const currentBgImage = ref("");
  127. // 是否为全屏页面
  128. const isFullScreen = computed(() => route.meta.fullScreen === true);
  129. // 判断是否是select-city页面
  130. const isSelectCity = computed(() => route.path === "/select-city");
  131. // 背景图路径映射 - 使用简单路径
  132. const routeBackgroundMap: Record<string, string> = {
  133. "/samplingMethodDevice1": getImageUrl("irrigation.jpg"),
  134. "/irriSampleData": getImageUrl("irrigation.jpg"),
  135. "/csSampleData": getImageUrl("irrigation.jpg"),
  136. "/irriInputFlux": getImageUrl("irrigation.jpg"),
  137. "/prodInputFlux": getImageUrl("agricultural_input.png"),
  138. "/airSampleData": getImageUrl("atmospheric_deposition.png"),
  139. "/airInputFlux": getImageUrl("atmospheric_deposition.png"),
  140. "/heavyMetalEnterprise": getImageUrl("atmospheric_deposition.png"),
  141. "/grainRemovalInputFlux": getImageUrl("grain_removal.png"),
  142. "/strawRemovalInputFlux": getImageUrl("straw_removal.png"),
  143. "/subsurfaceLeakageInputFlux": getImageUrl("subsurface_leakage.jpg"),
  144. "/surfaceRunoffInputFlux": getImageUrl("surface_runoff.jpg"),
  145. };
  146. // Tab 配置
  147. const tabs = computed(() => {
  148. if (tokenStore.token.loginType === "admin") {
  149. return [
  150. {
  151. name: "dataManagement",
  152. label: "数据管理",
  153. icon: "el-icon-folder",
  154. routes: [
  155. "/soilAcidReductionData",
  156. "/soilAcidificationData",
  157. "/AdminRegionData",
  158. "/SoilAssessmentUnitData",
  159. "/SoilHeavyMetalData",
  160. "/CropHeavyMetalData",
  161. "/LandUseTypeData",
  162. "/ClimateInfoData",
  163. "/GeographicEnvInfoData",
  164. ],
  165. },
  166. {
  167. name: "infoManagement",
  168. label: "信息管理",
  169. icon: "el-icon-document",
  170. routes: ["/IntroductionUpdate"],
  171. },
  172. {
  173. name: "modelManagement",
  174. label: "模型管理及配置",
  175. icon: "el-icon-cpu",
  176. routes: [
  177. "/CadmiumPredictionModel",
  178. "/EffectiveCadmiumModel",
  179. "/Admin/RiceRiskModel",
  180. "/AdminModelSelection",
  181. "/Admin/thres",
  182. "/Admin/ModelTrain",
  183. "/Admin/WheatRiskModel",
  184. "/Admin/VegetableRiskModel",
  185. ],
  186. },
  187. {
  188. name: "userManagement",
  189. label: "用户管理",
  190. icon: "el-icon-user",
  191. routes: ["/UserManagement", "/UserRegistration"],
  192. },
  193. ];
  194. } else {
  195. return [
  196. {
  197. name: "shuJuKanBan",
  198. label: "数据看板",
  199. icon: "el-icon-data-analysis",
  200. routes: ["/shuJuKanBan"],
  201. },
  202. {
  203. name: "introduction",
  204. label: "软件简介",
  205. icon: "el-icon-info-filled",
  206. routes: ["/SoilPro", "/Overview", "/ResearchFindings", "/Unit"],
  207. },
  208. {
  209. name: "HmOutFlux",
  210. label: "重金属输入通量",
  211. icon: "el-icon-refresh",
  212. routes: [
  213. "/samplingMethodDevice1",
  214. "/irriSampleData",
  215. "/csSampleData",
  216. "/irriInputFlux",
  217. "/samplingDesc2",
  218. "/prodInputFlux",
  219. "/samplingDesc3",
  220. "/airSampleData",
  221. "/airInputFlux",
  222. ],
  223. },
  224. {
  225. name: "hmInFlux",
  226. label: "重金属输出通量",
  227. icon: "el-icon-refresh",
  228. routes: [
  229. "/samplingDesc1",
  230. "/grainRemovalInputFlux",
  231. "/samplingDesc2",
  232. "/strawRemovalInputFlux",
  233. "/samplingDesc3",
  234. "/subsurfaceLeakageInputFlux",
  235. "/samplingDesc4",
  236. "/surfaceRunoffInputFlux",
  237. ],
  238. },
  239. {
  240. name: "mapView",
  241. label: "地图展示",
  242. icon: "el-icon-map-location",
  243. routes: ["/mapView"],
  244. },
  245. {
  246. name: "cadmiumPrediction",
  247. label: "土壤污染物含量预测",
  248. icon: "el-icon-c-scale-to-original",
  249. routes: [
  250. "/totalInputFlux",
  251. "/TotalCadmiumPrediction",
  252. "/totalOutputFlux",
  253. "/netFlux",
  254. "/currentYearConcentration",
  255. "/EffectiveCadmiumPrediction",
  256. "CropCadmiumPrediction",
  257. ],
  258. },
  259. {
  260. name: "cropRiskAssessment",
  261. label: "作物风险评估",
  262. icon: "el-icon-warning",
  263. routes: ["/cropRiskAssessment"],
  264. },
  265. {
  266. name: "farmlandQualityAssessment",
  267. label: "耕地质量评估",
  268. icon: "el-icon-rank",
  269. routes: ["/farmlandQualityAssessment"],
  270. },
  271. {
  272. name: "soilAcidificationPrediction",
  273. label: "土壤酸化预测",
  274. icon: "el-icon-magic-stick",
  275. routes: ["/Calculation", "/AcidNeutralizationModel"],
  276. },
  277. {
  278. name: "scenarioSimulation",
  279. label: "情景模拟",
  280. icon: "el-icon-s-operation",
  281. routes: [
  282. "/TraditionalFarmingRisk",
  283. "/HeavyMetalCadmiumControl",
  284. "/SoilAcidificationControl",
  285. ],
  286. },
  287. {
  288. name: "dataStatistics",
  289. label: "数据统计",
  290. icon: "el-icon-pie-chart",
  291. routes: [
  292. "/DetectionStatistics",
  293. "/FarmlandPollutionStatistics",
  294. "/PlantingRiskStatistics",
  295. ],
  296. },
  297. ].filter(tab => !["shuJuKanBan", "mapView", "introduction"].includes(tab.name));
  298. }
  299. });
  300. // 计算:当前激活 tab - 保持不变
  301. const activeName = ref(tabs.value[0]?.name || "");
  302. const showTabs = computed(() => tabs.value.length > 1);
  303. const tabStyle = computed(() =>
  304. tabs.value.length === 1 ? { width: "100%", justifyContent: "center" } : {}
  305. );
  306. let hasNavigated = false;
  307. watch(
  308. () => activeName.value,
  309. (newTab) => {
  310. const tab = tabs.value.find((t) => t.name === newTab);
  311. const targetPath = tab?.routes?.[0];
  312. if (!hasNavigated) {
  313. hasNavigated = true;
  314. return;
  315. }
  316. if (tab && targetPath && router.currentRoute.value.path !== targetPath) {
  317. router.push({ path: targetPath });
  318. }
  319. },
  320. { immediate: true }
  321. );
  322. // 显式列出所有不需要背景图的路由路径
  323. const bgExcludedRoutes = computed(() => {
  324. return [
  325. // 列出所有不需要背景图的路由路径
  326. "/shuJuKanBan",
  327. "/mapView",
  328. "/cropRiskAssessment",
  329. "/farmlandQualityAssessment",
  330. "/dataStatistics",
  331. // 强制"重金属输入通量"和"重金属输出通量"下的所有路由为白色背景
  332. ...tabs.value
  333. .filter(tab => ["HmOutFlux", "hmInFlux"].includes(tab.name))
  334. .flatMap(tab => tab.routes)
  335. ];
  336. });
  337. // 判断当前路由是否在排除列表中
  338. const isExcludedRoute = computed(() => bgExcludedRoutes.value.includes(route.path));
  339. // 获取当前页面的背景图
  340. const getBgImage = (path: string) => {
  341. // 若当前路径属于排除项,不显示背景图
  342. if (isExcludedRoute.value) return "";
  343. return routeBackgroundMap[path] || "";
  344. };
  345. // 当前背景图
  346. watch(
  347. () => route.path,
  348. (newPath) => {
  349. currentBgImage.value = getBgImage(newPath) ? `url(${getBgImage(newPath)})` : "";
  350. },
  351. { immediate: true }
  352. );
  353. // 点击切换 tab
  354. const handleClick = (tab: any, event: Event) => {
  355. activeAsideTab.value = tab.props.name;
  356. };
  357. // 动态加载侧边栏组件
  358. const AsideComponent = computed(() => {
  359. if (
  360. ["parameterConfig", "dataManagement", "infoManagement", "modelManagement", "userManagement"]
  361. .includes(activeName.value)
  362. ) {
  363. return defineAsyncComponent(() => import("./AppAsideForTab2.vue"));
  364. } else {
  365. return defineAsyncComponent(() => import("./AppAside.vue"));
  366. }
  367. });
  368. // 是否显示侧边栏
  369. const showAside = computed(() => {
  370. return (
  371. !isFullScreen.value &&
  372. activeName.value !== "mapView" &&
  373. activeName.value !== "cropRiskAssessment" &&
  374. activeName.value !== "farmlandQualityAssessment"
  375. );
  376. });
  377. const activeAsideTab = ref(activeName.value || "");
  378. const userInfo = reactive({ name: tokenStore.token.name || "未登录" });
  379. const handleLogout = async () => {
  380. try {
  381. await ElMessageBox.confirm("确定要退出登录吗?", "提示", {
  382. confirmButtonText: "确定",
  383. cancelButtonText: "取消",
  384. type: "warning",
  385. });
  386. await logout();
  387. tokenStore.clearToken();
  388. ElMessage.success("退出成功");
  389. router.push("/login");
  390. } catch {
  391. ElMessage.info("已取消退出");
  392. }
  393. };
  394. // 内容区样式
  395. const mainStyle = computed(() => {
  396. return {
  397. padding: ["mapView", "infoManagement"].includes(activeName.value) ? "0" : "20px",
  398. overflow: "hidden",
  399. };
  400. });
  401. </script>
  402. <style>
  403. /* 隐藏所有滚动条 */
  404. *::-webkit-scrollbar {
  405. display: none; /* Chrome, Safari, Opera */
  406. }
  407. * {
  408. -ms-overflow-style: none; /* IE and Edge */
  409. scrollbar-width: none; /* Firefox */
  410. }
  411. /* 整体布局容器 */
  412. .layout-wrapper {
  413. display: flex;
  414. flex-direction: column;
  415. height: 100vh;
  416. overflow: hidden;
  417. position: relative;
  418. }
  419. /* 全屏页面特殊处理 */
  420. .layout-wrapper.full-screen {
  421. background: none;
  422. min-height: 100vh;
  423. }
  424. /* 背景层 - 用于透明部分 */
  425. .background-layer {
  426. position: fixed;
  427. top: 0;
  428. left: 0;
  429. right: 0;
  430. bottom: 0;
  431. background: url("@/assets/header-bg.jpg") center center / cover no-repeat;
  432. background-attachment: fixed;
  433. z-index: -1; /* 确保在内容下方 */
  434. }
  435. /* 透明 Header */
  436. .layout-header {
  437. height: 150px;
  438. display: flex;
  439. align-items: center;
  440. justify-content: space-between;
  441. background-color: transparent !important;
  442. backdrop-filter: none !important;
  443. -webkit-backdrop-filter: none !important;
  444. border-bottom: none;
  445. box-shadow: none !important;
  446. color: #f0f3f7;
  447. flex-shrink: 0;
  448. position: relative; /* 确保在背景层上方 */
  449. z-index: 1;
  450. }
  451. /* 排除背景图页面的Header样式 */
  452. .excluded-bg-header {
  453. background-color: #ffffff !important;
  454. border-bottom: 1px solid #eee !important;
  455. }
  456. .logo-title-row {
  457. display: flex;
  458. align-items: center;
  459. gap: 24px;
  460. width: 100%;
  461. }
  462. .title-and-user {
  463. display: flex;
  464. flex-direction: column;
  465. flex: 1;
  466. }
  467. /* 用户信息区域 */
  468. .user-info-row {
  469. display: flex;
  470. align-items: center;
  471. justify-content: flex-end;
  472. gap: 24px;
  473. background-color: transparent !important;
  474. box-shadow: none !important;
  475. color: #ffffff;
  476. padding-top: 1px;
  477. position: static;
  478. z-index: 100;
  479. }
  480. /* 排除背景图页面的文字颜色 */
  481. .excluded-text {
  482. color: #333 !important;
  483. }
  484. /* 头像边框白色 */
  485. .el-dropdown-link .el-avatar {
  486. border: 2px solid white;
  487. }
  488. /* 排除背景图页面的头像边框 */
  489. .excluded-avatar-border {
  490. border: 2px solid #333 !important;
  491. }
  492. .welcome-text {
  493. font-size: 28px;
  494. font-weight: 500;
  495. color: #ffffff !important;
  496. }
  497. /* 排除背景图页面的欢迎文字颜色 */
  498. .excluded-text .welcome-text {
  499. color: #333 !important;
  500. }
  501. /* Tab 区域 - 不透明 */
  502. .tabs-row {
  503. height: 48px;
  504. display: flex;
  505. justify-content: center;
  506. align-items: center;
  507. padding: 0 24px;
  508. background: linear-gradient(to right, #1092d8, #02c3ad);
  509. backdrop-filter: blur(10px);
  510. -webkit-backdrop-filter: blur(10px);
  511. border-bottom: none !important;
  512. box-shadow: none !important;
  513. margin-bottom: 0 !important;
  514. flex-shrink: 0;
  515. position: relative; /* 确保在背景层上方 */
  516. z-index: 1;
  517. }
  518. /* el-tabs 外层容器 */
  519. .demo-tabs {
  520. height: 48px !important;
  521. display: flex;
  522. align-items: center;
  523. width: 100%;
  524. padding: 0 !important;
  525. margin: 0 !important;
  526. border-bottom: none !important;
  527. }
  528. /* 清除滑块条和底部线条 */
  529. .el-tabs__nav-wrap::after,
  530. .el-tabs__active-bar {
  531. display: none !important;
  532. height: 0 !important;
  533. border: none !important;
  534. }
  535. .el-tabs__nav-scroll {
  536. padding: 0 !important;
  537. margin: 0 !important;
  538. }
  539. /* Tabs 单项样式 */
  540. .el-tabs__item {
  541. height: 48px !important;
  542. line-height: 48px !important;
  543. display: flex !important;
  544. align-items: center;
  545. justify-content: center;
  546. padding: 0 20px !important;
  547. font-size: 20px;
  548. font-weight: 600;
  549. color: #cfd8dc;
  550. border-radius: 10px;
  551. transition: all 0.2s ease-in-out;
  552. background-color: transparent;
  553. position: relative;
  554. z-index: 1;
  555. }
  556. /* 激活 Tab */
  557. .el-tabs__item.is-active {
  558. background-color: #2a53ba;
  559. color: #ffffff;
  560. font-weight: 700;
  561. box-shadow: 0 4px 16px rgba(26, 188, 156, 0.4);
  562. z-index: 2;
  563. }
  564. /* 鼠标悬停 */
  565. .el-tabs__item:hover {
  566. background-color: #455a64;
  567. color: #ffffff;
  568. }
  569. /* 图标样式 */
  570. .tab-icon {
  571. font-size: 24px;
  572. margin-right: 4px;
  573. color: inherit;
  574. }
  575. /* 文字样式 */
  576. .tab-label-text {
  577. font-size: 20px;
  578. color: inherit;
  579. line-height: 1;
  580. display: inline-block;
  581. }
  582. .logo {
  583. height: 60px;
  584. }
  585. .project-name {
  586. font-size: 48px;
  587. font-weight: bold;
  588. margin-top: 30px;
  589. color: #f0f3f7;
  590. }
  591. /* 排除背景图页面的项目名称颜色 */
  592. .excluded-text.project-name {
  593. color: #333 !important;
  594. }
  595. .layout-main-container {
  596. flex: 1;
  597. display: flex;
  598. overflow: hidden;
  599. min-height: 0;
  600. position: relative;
  601. z-index: 1;
  602. }
  603. /* 侧边栏 - 不透明 */
  604. .layout-aside {
  605. width: 360px;
  606. background: linear-gradient(to bottom, #B7F1FC, #FFF8F0 );
  607. border-right: 1px solid;
  608. overflow-y: auto;
  609. color: #000000;
  610. padding-top: 8px;
  611. height: 100%;
  612. position: relative;
  613. z-index: 2; /* 确保在背景层上方 */
  614. }
  615. /* 隐藏侧边栏滚动条 */
  616. .layout-aside::-webkit-scrollbar {
  617. display: none;
  618. }
  619. .layout-aside .el-menu-item,
  620. .layout-aside .el-sub-menu__title {
  621. font-size: 18px;
  622. font-weight: 500;
  623. color: #000000;
  624. background-color: transparent;
  625. transition: all 0.2s ease;
  626. border-radius: 6px;
  627. padding: 12px 16px !important;
  628. }
  629. .layout-aside .el-menu-item:hover,
  630. .layout-aside .el-sub-menu__title:hover {
  631. background-color: rgba(16, 146, 216, 0.1);
  632. color: #1092d8;
  633. }
  634. .layout-aside .el-menu-item.is-active,
  635. .layout-aside .el-sub-menu__title.is-active {
  636. background: linear-gradient(to right, #1092d8, #02c3ad);
  637. color: #000000 !important;
  638. border-radius: 8px;
  639. font-weight: 600;
  640. box-shadow: 0 2px 8px rgba(16, 146, 216, 0.25);
  641. }
  642. .layout-content-wrapper {
  643. flex: 1;
  644. overflow: hidden;
  645. display: flex;
  646. flex-direction: column;
  647. position: relative;
  648. }
  649. /* 排除背景图页面的内容区域 */
  650. .excluded-bg-content {
  651. background-color: #ffffff !important;
  652. }
  653. /* 可滑动内容区域 */
  654. .scrollable-content {
  655. flex: 1;
  656. overflow: auto;
  657. padding: 0 20px;
  658. box-sizing: border-box;
  659. }
  660. /* 强制重置 el-tabs header 高度/边距/背景/阴影,避免背景层穿透错位 */
  661. .el-tabs__header.is-top {
  662. height: 48px !important;
  663. margin: 0 !important;
  664. padding: 0 !important;
  665. border: none !important;
  666. background: transparent !important;
  667. box-shadow: none !important;
  668. z-index: 0 !important;
  669. }
  670. /* 全屏页面特殊处理 */
  671. .layout-wrapper.full-screen .layout-main-container {
  672. height: 100vh;
  673. }
  674. .scrollable-content {
  675. flex: 1;
  676. overflow: auto;
  677. padding: 0 20px;
  678. box-sizing: border-box;
  679. background-size: cover;
  680. background-repeat: no-repeat;
  681. background-position: center;
  682. transition: background-image 0.3s ease-in-out;
  683. }
  684. </style>