diff --git a/src/constants/system.ts b/src/constants/system.ts
index 7c043fd58..f06c689e7 100644
--- a/src/constants/system.ts
+++ b/src/constants/system.ts
@@ -24,6 +24,22 @@ export const themeLayoutModeOptions: Common.OptionWithKey
= {
+ wrapper: '外层滚动',
+ content: '主体滚动'
+};
+
+export const themeScrollModeOptions: Common.OptionWithKey[] = [
+ {
+ value: 'wrapper',
+ label: themeScrollModeLabels.wrapper
+ },
+ {
+ value: 'content',
+ label: themeScrollModeLabels.content
+ }
+];
+
export const themeTabModeLabels: Record = {
chrome: '谷歌风格',
button: '按钮风格'
diff --git a/src/layouts/basic-layout/index.vue b/src/layouts/basic-layout/index.vue
index 4adb561aa..b921515f4 100644
--- a/src/layouts/basic-layout/index.vue
+++ b/src/layouts/basic-layout/index.vue
@@ -1,18 +1,20 @@
@@ -33,7 +35,7 @@
diff --git a/src/layouts/common/global-content/index.vue b/src/layouts/common/global-content/index.vue
index 4cf99c59a..a75b09a39 100644
--- a/src/layouts/common/global-content/index.vue
+++ b/src/layouts/common/global-content/index.vue
@@ -1,16 +1,23 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
diff --git a/src/layouts/common/setting-drawer/components/layout-mode/components/index.ts b/src/layouts/common/setting-drawer/components/layout-mode/components/index.ts
index f724a53b6..d580731f9 100644
--- a/src/layouts/common/setting-drawer/components/layout-mode/components/index.ts
+++ b/src/layouts/common/setting-drawer/components/layout-mode/components/index.ts
@@ -1,3 +1,4 @@
import LayoutCheckbox from './layout-checkbox.vue';
+import LayoutCard from './layout-card.vue';
-export { LayoutCheckbox };
+export { LayoutCheckbox, LayoutCard };
diff --git a/src/layouts/common/setting-drawer/components/layout-mode/components/layout-card.vue b/src/layouts/common/setting-drawer/components/layout-mode/components/layout-card.vue
new file mode 100644
index 000000000..0f6a5a67d
--- /dev/null
+++ b/src/layouts/common/setting-drawer/components/layout-mode/components/layout-card.vue
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+ {{ label }}
+
+
+
+
+
+
+
diff --git a/src/layouts/common/setting-drawer/components/layout-mode/index.vue b/src/layouts/common/setting-drawer/components/layout-mode/index.vue
index d9132d917..b928de3a9 100644
--- a/src/layouts/common/setting-drawer/components/layout-mode/index.vue
+++ b/src/layouts/common/setting-drawer/components/layout-mode/index.vue
@@ -1,24 +1,57 @@
布局模式
-
-
+
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/src/layouts/common/setting-drawer/components/page-func/index.vue b/src/layouts/common/setting-drawer/components/page-func/index.vue
index 5bb5d68cb..b0cfe8e20 100644
--- a/src/layouts/common/setting-drawer/components/page-func/index.vue
+++ b/src/layouts/common/setting-drawer/components/page-func/index.vue
@@ -1,11 +1,14 @@
界面功能
-
-
-
-
-
+
+
diff --git a/src/plugins/assets.ts b/src/plugins/assets.ts
index 8165ea4df..013ba6d06 100644
--- a/src/plugins/assets.ts
+++ b/src/plugins/assets.ts
@@ -1,4 +1,5 @@
import 'uno.css';
+import '@soybeanjs/vue-materials/dist/style.css';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
diff --git a/src/router/helpers/scroll.ts b/src/router/helpers/scroll.ts
index f691ce373..648664e32 100644
--- a/src/router/helpers/scroll.ts
+++ b/src/router/helpers/scroll.ts
@@ -1,8 +1,9 @@
import type { RouterScrollBehavior } from 'vue-router';
-import { useTabStore } from '@/store';
+import { useAppStore, useTabStore } from '@/store';
export const scrollBehavior: RouterScrollBehavior = (to, from) => {
return new Promise(resolve => {
+ const app = useAppStore();
const tab = useTabStore();
if (to.hash) {
@@ -20,17 +21,18 @@ export const scrollBehavior: RouterScrollBehavior = (to, from) => {
left,
top
};
- const { scrollLeft, scrollTop } = document.documentElement;
+ const { scrollEl, scrollLeft, scrollTop } = app.getScrollConfig();
const isFromCached = Boolean(from.meta.keepAlive);
if (isFromCached) {
tab.recordTabScrollPosition(from.path, { left: scrollLeft, top: scrollTop });
}
- const duration = !scrollPosition.left && !scrollPosition.top ? 0 : 350;
-
setTimeout(() => {
- resolve(scrollPosition);
- }, duration);
+ if (scrollEl) {
+ scrollEl.scrollLeft = scrollPosition.left;
+ scrollEl.scrollTop = scrollPosition.top;
+ }
+ }, 400);
});
};
diff --git a/src/router/modules/about.ts b/src/router/modules/about.ts
index a8101afeb..015416aa7 100644
--- a/src/router/modules/about.ts
+++ b/src/router/modules/about.ts
@@ -5,6 +5,7 @@ const about1: AuthRoute.Route = {
meta: {
title: '关于',
requiresAuth: true,
+ keepAlive: true,
singleLayout: 'basic',
permissions: ['super', 'admin', 'user'],
icon: 'fluent:book-information-24-regular',
diff --git a/src/settings/theme.json b/src/settings/theme.json
index a0299b55c..65a81792d 100644
--- a/src/settings/theme.json
+++ b/src/settings/theme.json
@@ -23,6 +23,17 @@
}
]
},
+ "scrollMode": "content",
+ "scrollModeList": [
+ {
+ "value": "wrapper",
+ "label": "外层滚动"
+ },
+ {
+ "value": "content",
+ "label": "主体滚动"
+ }
+ ],
"themeColor": "#1890ff",
"themeColorList": [
"#1890ff",
diff --git a/src/settings/theme.ts b/src/settings/theme.ts
index 1e675d743..ff1c5c07e 100644
--- a/src/settings/theme.ts
+++ b/src/settings/theme.ts
@@ -1,5 +1,6 @@
import {
themeLayoutModeOptions,
+ themeScrollModeOptions,
themeTabModeOptions,
themeHorizontalMenuPositionOptions,
themeAnimateModeOptions
@@ -41,6 +42,8 @@ const defaultThemeSetting: Theme.Setting = {
mode: 'vertical',
modeList: themeLayoutModeOptions
},
+ scrollMode: 'content',
+ scrollModeList: themeScrollModeOptions,
themeColor: themeColorList[0],
themeColorList,
otherColor: {
diff --git a/src/store/modules/app/index.ts b/src/store/modules/app/index.ts
index cb92e485b..1c8568dd3 100644
--- a/src/store/modules/app/index.ts
+++ b/src/store/modules/app/index.ts
@@ -1,7 +1,14 @@
import { nextTick } from 'vue';
import { defineStore } from 'pinia';
+import { SCROLL_EL_ID } from '@soybeanjs/vue-materials';
interface AppState {
+ /** 滚动元素的id */
+ scrollElId: string;
+ /** 主体内容全屏 */
+ contentFull: boolean;
+ /** 禁用主体内容的水平方向的滚动 */
+ disableMainXScroll: boolean;
/** 重载页面(控制页面的显示) */
reloadFlag: boolean;
/** 项目配置的抽屉可见状态 */
@@ -14,12 +21,29 @@ interface AppState {
export const useAppStore = defineStore('app-store', {
state: (): AppState => ({
+ scrollElId: SCROLL_EL_ID,
+ contentFull: false,
+ disableMainXScroll: false,
reloadFlag: true,
settingDrawerVisible: false,
siderCollapse: false,
mixSiderFixed: false
}),
actions: {
+ /**
+ * 获取滚动配置
+ */
+ getScrollConfig() {
+ const scrollEl = document.querySelector(`#${this.scrollElId}`);
+
+ const { scrollLeft = 0, scrollTop = 0 } = scrollEl || {};
+
+ return {
+ scrollEl,
+ scrollLeft,
+ scrollTop
+ };
+ },
/**
* 重载页面
* @param duration - 重载的延迟时间(ms)
@@ -65,6 +89,14 @@ export const useAppStore = defineStore('app-store', {
/** 设置 vertical-mix模式下 侧边栏的固定状态 */
toggleMixSiderFixed() {
this.mixSiderFixed = !this.mixSiderFixed;
+ },
+ /** 设置主体是否禁用滚动 */
+ setDisableMainXScroll(disable: boolean) {
+ this.disableMainXScroll = disable;
+ },
+ /** 设置主体内容全屏 */
+ setContentFull(full: boolean) {
+ this.contentFull = full;
}
}
});
diff --git a/src/store/modules/theme/index.ts b/src/store/modules/theme/index.ts
index 6a7bec083..b61a4c7ac 100644
--- a/src/store/modules/theme/index.ts
+++ b/src/store/modules/theme/index.ts
@@ -61,6 +61,10 @@ export const useThemeStore = defineStore('theme-store', {
setLayoutMode(mode: UnionKey.ThemeLayoutMode) {
this.layout.mode = mode;
},
+ /** 设置滚动模式 */
+ setScrollMode(mode: UnionKey.ThemeScrollMode) {
+ this.scrollMode = mode;
+ },
/** 设置侧边栏反转色 */
setSiderInverted(isInverted: boolean) {
this.sider.inverted = isInverted;
diff --git a/src/store/subscribe/app.ts b/src/store/subscribe/app.ts
index 11083e7da..42980bc03 100644
--- a/src/store/subscribe/app.ts
+++ b/src/store/subscribe/app.ts
@@ -1,4 +1,40 @@
+import { effectScope, onScopeDispose, watch } from 'vue';
+import { useFullscreen } from '@vueuse/core';
+import { useAppStore } from '../modules';
+
/** 订阅app store */
export default function subscribeAppStore() {
- //
+ const { isFullscreen, toggle } = useFullscreen();
+
+ const app = useAppStore();
+
+ const scope = effectScope();
+
+ function update() {
+ if (app.contentFull && !isFullscreen.value) {
+ toggle();
+ }
+ if (!app.contentFull && isFullscreen.value) {
+ toggle();
+ }
+ }
+
+ scope.run(() => {
+ watch(
+ () => app.contentFull,
+ () => {
+ update();
+ }
+ );
+
+ watch(isFullscreen, newValue => {
+ if (!newValue) {
+ app.setContentFull(false);
+ }
+ });
+ });
+
+ onScopeDispose(() => {
+ scope.stop();
+ });
}
diff --git a/src/typings/system.d.ts b/src/typings/system.d.ts
index 77470a570..527c48da9 100644
--- a/src/typings/system.d.ts
+++ b/src/typings/system.d.ts
@@ -92,6 +92,10 @@ declare namespace Theme {
followSystemTheme: boolean;
/** 布局样式 */
layout: Layout;
+ /** 滚动模式 */
+ scrollMode: UnionKey.ThemeScrollMode;
+ /** 滚动模式列表 */
+ scrollModeList: Common.OptionWithKey[];
/** 主题颜色 */
themeColor: string;
/** 主题颜色列表 */
diff --git a/src/typings/union-key.d.ts b/src/typings/union-key.d.ts
index ca82c415f..444ac1ddc 100644
--- a/src/typings/union-key.d.ts
+++ b/src/typings/union-key.d.ts
@@ -28,6 +28,13 @@ declare namespace UnionKey {
*/
type ThemeLayoutMode = 'vertical' | 'horizontal' | 'vertical-mix' | 'horizontal-mix';
+ /**
+ * 内容溢出时的出现滚动条的方式
+ * - wrapper 布局组件最外层的元素出现滚动条
+ * - content 主体内容组件出现滚动条
+ */
+ type ThemeScrollMode = 'wrapper' | 'content';
+
/**
* 多页签风格
* - chrome: 谷歌风格
diff --git a/src/views/dashboard/analysis/components/top-chart/index.vue b/src/views/dashboard/analysis/components/top-chart/index.vue
index 727e990d5..e72b1d4b3 100644
--- a/src/views/dashboard/analysis/components/top-chart/index.vue
+++ b/src/views/dashboard/analysis/components/top-chart/index.vue
@@ -1,27 +1,27 @@
-
+
-
-
-
Dashboard
-
Overview Of Lasted Month
-
-
-
-
Current Month Earnings
-
-
-
-
Current Month Sales
-
Last Month Summary
-
-
+
+
Dashboard
+
Overview Of Lasted Month
+
+
+
+
Current Month Earnings
+
+
+
+
Current Month Sales
+
Last Month Summary
+
+
+
+
+
diff --git a/src/views/dashboard/workbench/components/workbench-main/components/shortcuts-card.vue b/src/views/dashboard/workbench/components/workbench-main/components/shortcuts-card.vue
index 3789b7a6f..ca847da5e 100644
--- a/src/views/dashboard/workbench/components/workbench-main/components/shortcuts-card.vue
+++ b/src/views/dashboard/workbench/components/workbench-main/components/shortcuts-card.vue
@@ -1,6 +1,6 @@
{{ label }}
diff --git a/src/views/dashboard/workbench/components/workbench-main/components/technology-card.vue b/src/views/dashboard/workbench/components/workbench-main/components/technology-card.vue
index d73676277..362fccc59 100644
--- a/src/views/dashboard/workbench/components/workbench-main/components/technology-card.vue
+++ b/src/views/dashboard/workbench/components/workbench-main/components/technology-card.vue
@@ -1,6 +1,6 @@
diff --git a/src/views/dashboard/workbench/components/workbench-main/index.vue b/src/views/dashboard/workbench/components/workbench-main/index.vue
index 281d7cd01..3b449b26f 100644
--- a/src/views/dashboard/workbench/components/workbench-main/index.vue
+++ b/src/views/dashboard/workbench/components/workbench-main/index.vue
@@ -37,7 +37,9 @@
-
+
+
+
diff --git a/src/views/plugin/video/index.vue b/src/views/plugin/video/index.vue
index a5a1f8d04..1975ef352 100644
--- a/src/views/plugin/video/index.vue
+++ b/src/views/plugin/video/index.vue
@@ -1,7 +1,7 @@
@@ -19,7 +19,8 @@ function renderXgPlayer() {
player.value = new Player({
el: domRef.value,
url,
- playbackRate: [0.5, 0.75, 1, 1.5, 2]
+ playbackRate: [0.5, 0.75, 1, 1.5, 2],
+ fluid: true
});
}
function destroyXgPlayer() {
diff --git a/uno.config.ts b/uno.config.ts
index fb791f568..c94d052da 100644
--- a/uno.config.ts
+++ b/uno.config.ts
@@ -47,23 +47,32 @@ export default defineConfig({
primary: 'rgb(var(--primary-color))',
primary_hover: 'rgb(var(--primary-color-hover))',
primary_pressed: 'rgb(var(--primary-color-pressed))',
- primary_active: 'rgb(var(--primary-color-active))',
+ primary_active: 'rgba(var(--primary-color-active),0.1)',
+ primary_1: 'rgb(var(--primary-color1))',
+ primary_2: 'rgb(var(--primary-color2))',
+ primary_3: 'rgb(var(--primary-color3))',
+ primary_4: 'rgb(var(--primary-color4))',
+ primary_5: 'rgb(var(--primary-color5))',
+ primary_6: 'rgb(var(--primary-color6))',
+ primary_7: 'rgb(var(--primary-color7))',
+ primary_8: 'rgb(var(--primary-color8))',
+ primary_9: 'rgb(var(--primary-color9))',
info: 'rgb(var(--info-color))',
info_hover: 'rgb(var(--info-color-hover))',
info_pressed: 'rgb(var(--info-color-pressed))',
- info_active: 'rgb(var(--info-color-active))',
+ info_active: 'rgb(var(--info-color-active),0.1)',
success: 'rgb(var(--success-color))',
success_hover: 'rgb(var(--success-color-hover))',
success_pressed: 'rgb(var(--success-color-pressed))',
- success_active: 'rgb(var(--success-color-active))',
+ success_active: 'rgb(var(--success-color-active),0.1)',
warning: 'rgb(var(--warning-color))',
warning_hover: 'rgb(var(--warning-color-hover))',
warning_pressed: 'rgb(var(--warning-color-pressed))',
- warning_active: 'rgb(var(--warning-color-active))',
+ warning_active: 'rgb(var(--warning-color-active),0.1)',
error: 'rgb(var(--error-color))',
error_hover: 'rgb(var(--error-color-hover))',
error_pressed: 'rgb(var(--error-color-pressed))',
- error_active: 'rgb(var(--error-color-active))',
+ error_active: 'rgb(var(--error-color-active),0.1)',
dark: '#18181c'
}
}