diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b4afdd93966..bb59abb031d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -30,7 +30,7 @@ jobs: run: pnpm build:play - name: Sync Playground files - uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + uses: SamKirkland/FTP-Deploy-Action@v4.3.6 with: server: ${{ secrets.PRO_FTP_HOST }} username: ${{ secrets.WEB_PLAYGROUND_FTP_ACCOUNT }} @@ -54,7 +54,7 @@ jobs: run: pnpm build:docs - name: Sync Docs files - uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + uses: SamKirkland/FTP-Deploy-Action@v4.3.6 with: server: ${{ secrets.PRO_FTP_HOST }} username: ${{ secrets.WEBSITE_FTP_ACCOUNT }} @@ -85,7 +85,7 @@ jobs: run: pnpm run build:antd - name: Sync files - uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + uses: SamKirkland/FTP-Deploy-Action@v4.3.6 with: server: ${{ secrets.PRO_FTP_HOST }} username: ${{ secrets.WEB_ANTD_FTP_ACCOUNT }} @@ -116,7 +116,7 @@ jobs: run: pnpm run build:ele - name: Sync files - uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + uses: SamKirkland/FTP-Deploy-Action@v4.3.6 with: server: ${{ secrets.PRO_FTP_HOST }} username: ${{ secrets.WEB_ELE_FTP_ACCOUNT }} @@ -147,7 +147,7 @@ jobs: run: pnpm run build:naive - name: Sync files - uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + uses: SamKirkland/FTP-Deploy-Action@v4.3.6 with: server: ${{ secrets.PRO_FTP_HOST }} username: ${{ secrets.WEB_NAIVE_FTP_ACCOUNT }} diff --git a/.npmrc b/.npmrc index 21147aff25f..aeac1ae918f 100644 --- a/.npmrc +++ b/.npmrc @@ -1,4 +1,4 @@ -registry = "https://registry.npmmirror.com/" +registry=https://registry.npmmirror.com public-hoist-pattern[]=lefthook public-hoist-pattern[]=eslint public-hoist-pattern[]=prettier diff --git a/README.md b/README.md index b9dd73eb98a..ce8e89758ed 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

Vue Vben Admin

-[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=vbenjs_vue-vben-admin&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=vbenjs_vue-vben-admin) ![codeql](https://github.com/vbenjs/vue-vben-admin/actions/workflows/codeql.yml/badge.svg) ![build](https://github.com/vbenjs/vue-vben-admin/actions/workflows/build.yml/badge.svg) ![ci](https://github.com/vbenjs/vue-vben-admin/actions/workflows/ci.yml/badge.svg) ![deploy](https://github.com/vbenjs/vue-vben-admin/actions/workflows/deploy.yml/badge.svg) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=vbenjs_vue-vben-admin&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=vbenjs_vue-vben-admin) [![codeql](https://github.com/vbenjs/vue-vben-admin/actions/workflows/codeql.yml/badge.svg)](https://github.com/vbenjs/vue-vben-admin/actions/workflows/codeql.yml) [![build](https://github.com/vbenjs/vue-vben-admin/actions/workflows/build.yml/badge.svg)](https://github.com/vbenjs/vue-vben-admin/actions/workflows/build.yml) [![ci](https://github.com/vbenjs/vue-vben-admin/actions/workflows/ci.yml/badge.svg)](https://github.com/vbenjs/vue-vben-admin/actions/workflows/ci.yml) [![deploy](https://github.com/vbenjs/vue-vben-admin/actions/workflows/deploy.yml/badge.svg)](https://github.com/vbenjs/vue-vben-admin/actions/workflows/deploy.yml) **English** | [中文](./README.zh-CN.md) | [日本語](./README.ja-JP.md) diff --git a/apps/backend-mock/api/timezone/getTimezone.ts b/apps/backend-mock/api/timezone/getTimezone.ts new file mode 100644 index 00000000000..0cbcb6ec01f --- /dev/null +++ b/apps/backend-mock/api/timezone/getTimezone.ts @@ -0,0 +1,12 @@ +import { eventHandler } from 'h3'; +import { verifyAccessToken } from '~/utils/jwt-utils'; +import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; +import { getTimezone } from '~/utils/timezone-utils'; + +export default eventHandler((event) => { + const userinfo = verifyAccessToken(event); + if (!userinfo) { + return unAuthorizedResponse(event); + } + return useResponseSuccess(getTimezone()); +}); diff --git a/apps/backend-mock/api/timezone/getTimezoneOptions.ts b/apps/backend-mock/api/timezone/getTimezoneOptions.ts new file mode 100644 index 00000000000..6c241864ecb --- /dev/null +++ b/apps/backend-mock/api/timezone/getTimezoneOptions.ts @@ -0,0 +1,11 @@ +import { eventHandler } from 'h3'; +import { TIME_ZONE_OPTIONS } from '~/utils/mock-data'; +import { useResponseSuccess } from '~/utils/response'; + +export default eventHandler(() => { + const data = TIME_ZONE_OPTIONS.map((o) => ({ + label: `${o.timezone} (GMT${o.offset >= 0 ? `+${o.offset}` : o.offset})`, + value: o.timezone, + })); + return useResponseSuccess(data); +}); diff --git a/apps/backend-mock/api/timezone/setTimezone.ts b/apps/backend-mock/api/timezone/setTimezone.ts new file mode 100644 index 00000000000..34d8f19e2cf --- /dev/null +++ b/apps/backend-mock/api/timezone/setTimezone.ts @@ -0,0 +1,22 @@ +import { eventHandler, readBody } from 'h3'; +import { verifyAccessToken } from '~/utils/jwt-utils'; +import { TIME_ZONE_OPTIONS } from '~/utils/mock-data'; +import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response'; +import { setTimezone } from '~/utils/timezone-utils'; + +export default eventHandler(async (event) => { + const userinfo = verifyAccessToken(event); + if (!userinfo) { + return unAuthorizedResponse(event); + } + const body = await readBody<{ timezone?: unknown }>(event); + const timezone = + typeof body?.timezone === 'string' ? body.timezone : undefined; + const allowed = TIME_ZONE_OPTIONS.some((o) => o.timezone === timezone); + if (!timezone || !allowed) { + setResponseStatus(event, 400); + return useResponseError('Bad Request', 'Invalid timezone'); + } + setTimezone(timezone); + return useResponseSuccess({}); +}); diff --git a/apps/backend-mock/utils/mock-data.ts b/apps/backend-mock/utils/mock-data.ts index 192f30a0068..ee38e8ef91f 100644 --- a/apps/backend-mock/utils/mock-data.ts +++ b/apps/backend-mock/utils/mock-data.ts @@ -7,6 +7,11 @@ export interface UserInfo { homePath?: string; } +export interface TimezoneOption { + offset: number; + timezone: string; +} + export const MOCK_USERS: UserInfo[] = [ { id: 0, @@ -276,7 +281,7 @@ export const MOCK_MENU_LIST = [ children: [ { id: 20_401, - pid: 201, + pid: 202, name: 'SystemDeptCreate', status: 1, type: 'button', @@ -285,7 +290,7 @@ export const MOCK_MENU_LIST = [ }, { id: 20_402, - pid: 201, + pid: 202, name: 'SystemDeptEdit', status: 1, type: 'button', @@ -294,7 +299,7 @@ export const MOCK_MENU_LIST = [ }, { id: 20_403, - pid: 201, + pid: 202, name: 'SystemDeptDelete', status: 1, type: 'button', @@ -388,3 +393,29 @@ export function getMenuIds(menus: any[]) { }); return ids; } + +/** + * 时区选项 + */ +export const TIME_ZONE_OPTIONS: TimezoneOption[] = [ + { + offset: -5, + timezone: 'America/New_York', + }, + { + offset: 0, + timezone: 'Europe/London', + }, + { + offset: 8, + timezone: 'Asia/Shanghai', + }, + { + offset: 9, + timezone: 'Asia/Tokyo', + }, + { + offset: 9, + timezone: 'Asia/Seoul', + }, +]; diff --git a/apps/backend-mock/utils/timezone-utils.ts b/apps/backend-mock/utils/timezone-utils.ts new file mode 100644 index 00000000000..da35f920f04 --- /dev/null +++ b/apps/backend-mock/utils/timezone-utils.ts @@ -0,0 +1,9 @@ +let mockTimeZone: null | string = null; + +export const setTimezone = (timeZone: string) => { + mockTimeZone = timeZone; +}; + +export const getTimezone = () => { + return mockTimeZone; +}; diff --git a/apps/web-antd/src/layouts/auth.vue b/apps/web-antd/src/layouts/auth.vue index 18d415bc7fb..8ba66e85aa8 100644 --- a/apps/web-antd/src/layouts/auth.vue +++ b/apps/web-antd/src/layouts/auth.vue @@ -8,12 +8,14 @@ import { $t } from '#/locales'; const appName = computed(() => preferences.app.name); const logo = computed(() => preferences.logo.source); +const logoDark = computed(() => preferences.logo.sourceDark);