-
![]()
+
{{ appName }}
@@ -86,7 +109,14 @@ const { authPanelCenter, authPanelLeft, authPanelRight, isDark } =
class="bg-background-deep absolute inset-0 h-full w-full dark:bg-[#070709]"
>
-
+
![]()
@@ -125,7 +156,8 @@ const { authPanelCenter, authPanelLeft, authPanelRight, isDark } =
diff --git a/packages/effects/layouts/src/authentication/form.vue b/packages/effects/layouts/src/authentication/form.vue
index 80c90749..fa73e128 100644
--- a/packages/effects/layouts/src/authentication/form.vue
+++ b/packages/effects/layouts/src/authentication/form.vue
@@ -2,6 +2,10 @@
defineOptions({
name: 'AuthenticationFormView',
});
+
+defineProps<{
+ dataSide?: 'bottom' | 'left' | 'right' | 'top';
+}>();
@@ -16,7 +20,8 @@ defineOptions({
diff --git a/packages/effects/layouts/src/basic/header/header.vue b/packages/effects/layouts/src/basic/header/header.vue
index 97387460..26c92a64 100644
--- a/packages/effects/layouts/src/basic/header/header.vue
+++ b/packages/effects/layouts/src/basic/header/header.vue
@@ -1,16 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/locales/src/langs/en-US/ui.json b/packages/locales/src/langs/en-US/ui.json
index 645563d2..4afd722f 100644
--- a/packages/locales/src/langs/en-US/ui.json
+++ b/packages/locales/src/langs/en-US/ui.json
@@ -103,6 +103,10 @@
"errorPasswordTip": "Password error, please re-enter",
"backToLogin": "Back to login",
"entry": "Enter the system"
+ },
+ "timezone": {
+ "setTimezone": "Set Timezone",
+ "setSuccess": "Timezone set successfully"
}
}
}
diff --git a/packages/locales/src/langs/zh-CN/ui.json b/packages/locales/src/langs/zh-CN/ui.json
index e4f855ca..36e2ed60 100644
--- a/packages/locales/src/langs/zh-CN/ui.json
+++ b/packages/locales/src/langs/zh-CN/ui.json
@@ -103,6 +103,10 @@
"errorPasswordTip": "密码错误,请重新输入",
"backToLogin": "返回登录",
"entry": "进入系统"
+ },
+ "timezone": {
+ "setTimezone": "设置时区",
+ "setSuccess": "时区设置成功"
}
}
}
diff --git a/packages/stores/src/modules/index.ts b/packages/stores/src/modules/index.ts
index ec764ae8..bb9a66f4 100644
--- a/packages/stores/src/modules/index.ts
+++ b/packages/stores/src/modules/index.ts
@@ -1,3 +1,4 @@
export * from './access';
export * from './tabbar';
+export * from './timezone';
export * from './user';
diff --git a/packages/stores/src/modules/timezone.ts b/packages/stores/src/modules/timezone.ts
new file mode 100644
index 00000000..24180c60
--- /dev/null
+++ b/packages/stores/src/modules/timezone.ts
@@ -0,0 +1,132 @@
+import { ref, unref } from 'vue';
+
+import { DEFAULT_TIME_ZONE_OPTIONS } from '@vben-core/preferences';
+import {
+ getCurrentTimezone,
+ setCurrentTimezone,
+} from '@vben-core/shared/utils';
+
+import { acceptHMRUpdate, defineStore } from 'pinia';
+
+interface TimezoneHandler {
+ getTimezone?: () => Promise;
+ getTimezoneOptions?: () => Promise<
+ {
+ label: string;
+ value: string;
+ }[]
+ >;
+ setTimezone?: (timezone: string) => Promise;
+}
+
+/**
+ * 默认时区处理模块
+ * 时区存储基于pinia存储插件
+ */
+const getDefaultTimezoneHandler = (): TimezoneHandler => {
+ return {
+ getTimezoneOptions: () => {
+ return Promise.resolve(
+ DEFAULT_TIME_ZONE_OPTIONS.map((item) => {
+ return {
+ label: item.label,
+ value: item.timezone,
+ };
+ }),
+ );
+ },
+ };
+};
+
+/**
+ * 自定义时区处理模块
+ */
+let customTimezoneHandler: null | Partial = null;
+const setTimezoneHandler = (handler: Partial) => {
+ customTimezoneHandler = handler;
+};
+
+/**
+ * 获取时区处理模块
+ */
+const getTimezoneHandler = () => {
+ return {
+ ...getDefaultTimezoneHandler(),
+ ...customTimezoneHandler,
+ };
+};
+
+/**
+ * timezone支持模块
+ */
+const useTimezoneStore = defineStore(
+ 'core-timezone',
+ () => {
+ const timezoneRef = ref(getCurrentTimezone());
+
+ /**
+ * 初始化时区
+ * Initialize the timezone
+ */
+ async function initTimezone() {
+ const timezoneHandler = getTimezoneHandler();
+ const timezone = await timezoneHandler.getTimezone?.();
+ if (timezone) {
+ timezoneRef.value = timezone;
+ }
+ // 设置dayjs默认时区
+ setCurrentTimezone(unref(timezoneRef));
+ }
+
+ /**
+ * 设置时区
+ * Set the timezone
+ * @param timezone 时区字符串
+ */
+ async function setTimezone(timezone: string) {
+ const timezoneHandler = getTimezoneHandler();
+ await timezoneHandler.setTimezone?.(timezone);
+ timezoneRef.value = timezone;
+ // 设置dayjs默认时区
+ setCurrentTimezone(timezone);
+ }
+
+ /**
+ * 获取时区选项
+ * Get the timezone options
+ */
+ async function getTimezoneOptions() {
+ const timezoneHandler = getTimezoneHandler();
+ return (await timezoneHandler.getTimezoneOptions?.()) || [];
+ }
+
+ initTimezone().catch((error) => {
+ console.error('Failed to initialize timezone during store setup:', error);
+ });
+
+ function $reset() {
+ timezoneRef.value = getCurrentTimezone();
+ }
+
+ return {
+ timezone: timezoneRef,
+ setTimezone,
+ getTimezoneOptions,
+ $reset,
+ };
+ },
+ {
+ persist: {
+ // 持久化
+ pick: ['timezone'],
+ },
+ },
+);
+
+export { setTimezoneHandler, useTimezoneStore };
+
+// 解决热更新问题
+const hot = import.meta.hot;
+if (hot) {
+ hot.accept(acceptHMRUpdate(useTimezoneStore, hot));
+}
diff --git a/playground/src/api/core/index.ts b/playground/src/api/core/index.ts
index 28a5aef4..7134366b 100644
--- a/playground/src/api/core/index.ts
+++ b/playground/src/api/core/index.ts
@@ -1,3 +1,4 @@
export * from './auth';
export * from './menu';
+export * from './timezone';
export * from './user';
diff --git a/playground/src/api/core/timezone.ts b/playground/src/api/core/timezone.ts
new file mode 100644
index 00000000..13d44d19
--- /dev/null
+++ b/playground/src/api/core/timezone.ts
@@ -0,0 +1,26 @@
+import { requestClient } from '#/api/request';
+
+/**
+ * 获取系统支持的时区列表
+ */
+export async function getTimezoneOptionsApi() {
+ return await requestClient.get<
+ {
+ label: string;
+ value: string;
+ }[]
+ >('/timezone/getTimezoneOptions');
+}
+/**
+ * 获取用户时区
+ */
+export async function getTimezoneApi(): Promise {
+ return requestClient.get('/timezone/getTimezone');
+}
+/**
+ * 设置用户时区
+ * @param timezone 时区
+ */
+export async function setTimezoneApi(timezone: string): Promise {
+ return requestClient.post('/timezone/setTimezone', { timezone });
+}
diff --git a/playground/src/bootstrap.ts b/playground/src/bootstrap.ts
index f0a668b4..fed07340 100644
--- a/playground/src/bootstrap.ts
+++ b/playground/src/bootstrap.ts
@@ -15,6 +15,7 @@ import { router } from '#/router';
import { initComponentAdapter } from './adapter/component';
import { initSetupVbenForm } from './adapter/form';
import App from './app.vue';
+import { initTimezone } from './timezone-init';
async function bootstrap(namespace: string) {
// 初始化组件适配器
@@ -46,6 +47,9 @@ async function bootstrap(namespace: string) {
// 配置 pinia-tore
await initStores(app, { namespace });
+ // 初始化时区HANDLER
+ initTimezone();
+
// 安装权限指令
registerAccessDirective(app);
diff --git a/playground/src/locales/langs/zh-CN/system.json b/playground/src/locales/langs/zh-CN/system.json
index b0f5e7fa..be5a7ae3 100644
--- a/playground/src/locales/langs/zh-CN/system.json
+++ b/playground/src/locales/langs/zh-CN/system.json
@@ -1,4 +1,5 @@
{
+ "title": "系统管理",
"dept": {
"list": "部门列表",
"createTime": "创建时间",
@@ -62,6 +63,5 @@
"operation": "操作",
"permissions": "权限",
"setPermissions": "授权"
- },
- "title": "系统管理"
+ }
}
diff --git a/playground/src/timezone-init.ts b/playground/src/timezone-init.ts
new file mode 100644
index 00000000..1d82bd47
--- /dev/null
+++ b/playground/src/timezone-init.ts
@@ -0,0 +1,20 @@
+import { setTimezoneHandler } from '@vben/stores';
+
+import { getTimezoneApi, getTimezoneOptionsApi, setTimezoneApi } from '#/api';
+
+/**
+ * 初始化时区处理,通过API保存时区设置
+ */
+export function initTimezone() {
+ setTimezoneHandler({
+ getTimezone() {
+ return getTimezoneApi();
+ },
+ setTimezone(timezone: string) {
+ return setTimezoneApi(timezone);
+ },
+ getTimezoneOptions() {
+ return getTimezoneOptionsApi();
+ },
+ });
+}
diff --git a/playground/src/views/examples/layout/col-page.vue b/playground/src/views/examples/layout/col-page.vue
index 5b18330e..5070ac3d 100644
--- a/playground/src/views/examples/layout/col-page.vue
+++ b/playground/src/views/examples/layout/col-page.vue
@@ -22,8 +22,8 @@ const props = reactive({
leftWidth: 30,
resizable: true,
rightWidth: 70,
- splitHandle: false,
- splitLine: false,
+ splitHandle: true,
+ splitLine: true,
});
const leftMinWidth = ref(props.leftMinWidth || 1);
const leftMaxWidth = ref(props.leftMaxWidth || 100);
@@ -42,7 +42,11 @@ const leftMaxWidth = ref(props.leftMaxWidth || 100);
-