Commit 4ce1d526c80cd859c815b9e629ae1838f441cf0b

Authored by vben
1 parent e9c28319

refactor(lock-page): refactor lock page

CHANGELOG.zh_CN.md
... ... @@ -16,6 +16,7 @@
16 16 ### ✨ Refactor
17 17  
18 18 - tree 组件 ref 函数调用删除 `$`
  19 +- 锁屏界面重构美化,删除不必要的背景图片
19 20  
20 21 ### ⚡ Performance Improvements
21 22  
... ...
src/api/sys/user.ts
... ... @@ -5,6 +5,7 @@ import {
5 5 GetUserInfoByUserIdParams,
6 6 GetUserInfoByUserIdModel,
7 7 } from './model/userModel';
  8 +import { ErrorMessageMode } from '/@/utils/http/axios/types';
8 9  
9 10 enum Api {
10 11 Login = '/login',
... ... @@ -15,7 +16,7 @@ enum Api {
15 16 /**
16 17 * @description: user login api
17 18 */
18   -export function loginApi(params: LoginParams) {
  19 +export function loginApi(params: LoginParams, mode: ErrorMessageMode = 'modal') {
19 20 return defHttp.request<LoginResultModel>(
20 21 {
21 22 url: Api.Login,
... ... @@ -23,7 +24,7 @@ export function loginApi(params: LoginParams) {
23 24 params,
24 25 },
25 26 {
26   - errorMessageMode: 'modal',
  27 + errorMessageMode: mode,
27 28 }
28 29 );
29 30 }
... ...
src/assets/images/lock-page.jpg deleted 100644 → 0

218 KB

src/design/mixins.less
... ... @@ -90,6 +90,7 @@
90 90 @content();
91 91 }
92 92 }
  93 +
93 94 .respond-to (xsmall-and-small, @content) {
94 95 @media only screen and (max-width: @screen-sm-max) {
95 96 @content();
... ...
src/design/var/breakpoint.less
... ... @@ -26,9 +26,13 @@
26 26 @screen-xxl: 1600px;
27 27 @screen-xxl-min: @screen-xxl;
28 28  
  29 +@screen-xxxl: 1900px;
  30 +@screen-xxxl-min: @screen-xxxl;
  31 +
29 32 // provide a maximum
30 33 @screen-xs-max: (@screen-sm-min - 1px);
31 34 @screen-sm-max: (@screen-md-min - 1px);
32 35 @screen-md-max: (@screen-lg-min - 1px);
33 36 @screen-lg-max: (@screen-xl-min - 1px);
34 37 @screen-xl-max: (@screen-xxl-min - 1px);
  38 +@screen-xxl-max: (@screen-xxxl-min - 1px);
... ...
src/hooks/setting/useRootSetting.ts
... ... @@ -42,6 +42,8 @@ const getColorWeak = computed(() =&gt; unref(getRootSetting).colorWeak);
42 42  
43 43 const getGrayMode = computed(() => unref(getRootSetting).grayMode);
44 44  
  45 +const getLockTime = computed(() => unref(getRootSetting).lockTime);
  46 +
45 47 const getLayoutContentMode = computed(() =>
46 48 unref(getRootSetting).contentMode === ContentEnum.FULL ? ContentEnum.FULL : ContentEnum.FIXED
47 49 );
... ... @@ -71,5 +73,6 @@ export function useRootSetting() {
71 73 getShowSettingButton,
72 74 getShowFooter,
73 75 getContentMode,
  76 + getLockTime,
74 77 };
75 78 }
... ...
src/hooks/web/useLockPage.ts
1   -import { computed, onUnmounted, watchEffect } from 'vue';
  1 +import { computed, onUnmounted, unref, watchEffect } from 'vue';
2 2 import { useThrottle } from '/@/hooks/core/useThrottle';
3 3  
4 4 import { appStore } from '/@/store/modules/app';
  5 +import { lockStore } from '/@/store/modules/lock';
5 6 import { userStore } from '/@/store/modules/user';
  7 +import { useRootSetting } from '../setting/useRootSetting';
6 8  
7 9 export function useLockPage() {
  10 + const { getLockTime } = useRootSetting();
8 11 let timeId: TimeoutHandle;
9 12  
10 13 function clear(): void {
... ... @@ -30,7 +33,7 @@ export function useLockPage() {
30 33 }
31 34  
32 35 function lockPage(): void {
33   - appStore.commitLockInfoState({
  36 + lockStore.commitLockInfoState({
34 37 isLock: true,
35 38 pwd: undefined,
36 39 });
... ... @@ -54,8 +57,7 @@ export function useLockPage() {
54 57 const [keyupFn] = useThrottle(resetCalcLockTimeout, 2000);
55 58  
56 59 return computed(() => {
57   - const openLockPage = appStore.getProjectConfig.lockTime;
58   - if (openLockPage) {
  60 + if (unref(getLockTime)) {
59 61 return { onKeyup: keyupFn, onMousemove: keyupFn };
60 62 } else {
61 63 clear();
... ... @@ -63,3 +65,9 @@ export function useLockPage() {
63 65 }
64 66 });
65 67 }
  68 +
  69 +export const getIsLock = computed(() => {
  70 + const { getLockInfo } = lockStore;
  71 + const { isLock } = getLockInfo;
  72 + return isLock;
  73 +});
... ...
src/layouts/default/index.tsx
... ... @@ -6,7 +6,7 @@ import LayoutHeader from &#39;./header/LayoutHeader&#39;;
6 6  
7 7 import LayoutContent from './content';
8 8 import LayoutFooter from './footer';
9   -import LayoutLockPage from './lock';
  9 +import LayoutLockPage from './lock/index.vue';
10 10 import LayoutSideBar from './sider';
11 11 import SettingBtn from './setting/index.vue';
12 12 import LayoutMultipleHeader from './header/LayoutMultipleHeader';
... ...
src/layouts/default/lock/LockAction.tsx
... ... @@ -7,9 +7,9 @@ import { BasicForm, useForm } from &#39;/@/components/Form/index&#39;;
7 7  
8 8 import headerImg from '/@/assets/images/header.jpg';
9 9  
10   -import { appStore } from '/@/store/modules/app';
11 10 import { userStore } from '/@/store/modules/user';
12 11 import { useI18n } from '/@/hooks/web/useI18n';
  12 +import { lockStore } from '/@/store/modules/lock';
13 13  
14 14 const prefixCls = 'lock-modal';
15 15 export default defineComponent({
... ... @@ -30,24 +30,16 @@ export default defineComponent({
30 30 ],
31 31 });
32 32  
33   - async function lock(valid = true) {
34   - let password: string | undefined = '';
  33 + async function lock() {
  34 + const values = (await validateFields()) as any;
  35 + const password: string | undefined = values.password;
  36 + closeModal();
35 37  
36   - try {
37   - if (!valid) {
38   - password = undefined;
39   - } else {
40   - const values = (await validateFields()) as any;
41   - password = values.password;
42   - }
43   - closeModal();
44   -
45   - appStore.commitLockInfoState({
46   - isLock: true,
47   - pwd: password,
48   - });
49   - await resetFields();
50   - } catch (error) {}
  38 + lockStore.commitLockInfoState({
  39 + isLock: true,
  40 + pwd: password,
  41 + });
  42 + await resetFields();
51 43 }
52 44  
53 45 return () => (
... ... @@ -71,9 +63,6 @@ export default defineComponent({
71 63 <Button type="primary" block class="mt-2" onClick={lock}>
72 64 {() => t('layout.header.lockScreenBtn')}
73 65 </Button>
74   - <Button block class="mt-2" onClick={lock.bind(null, false)}>
75   - {() => t('layout.header.notLockScreenPassword')}
76   - </Button>
77 66 </div>
78 67 </div>
79 68 )}
... ...
src/layouts/default/lock/index.tsx deleted 100644 → 0
1   -import { defineComponent, unref, computed } from 'vue';
2   -import { appStore } from '/@/store/modules/app';
3   -import LockPage from '/@/views/sys/lock/index.vue';
4   -
5   -export default defineComponent({
6   - name: 'LayoutLockPage',
7   - setup() {
8   - const getIsLockRef = computed(() => {
9   - const { getLockInfo } = appStore;
10   - const { isLock } = getLockInfo;
11   - return isLock;
12   - });
13   - return () => {
14   - return unref(getIsLockRef) ? <LockPage /> : null;
15   - };
16   - },
17   -});
src/layouts/default/lock/index.vue 0 → 100644
  1 +<template>
  2 + <transition name="fade-bottom">
  3 + <LockPage v-if="getIsLock" />
  4 + </transition>
  5 +</template>
  6 +<script lang="ts">
  7 + import { defineComponent } from 'vue';
  8 + import LockPage from '/@/views/sys/lock/index.vue';
  9 + import { getIsLock } from '/@/hooks/web/useLockPage';
  10 + export default defineComponent({
  11 + name: 'LayoutLockPage',
  12 + components: { LockPage },
  13 + setup() {
  14 + return { getIsLock };
  15 + },
  16 + });
  17 +</script>
... ...
src/locales/lang/en/layout/header.ts
... ... @@ -14,7 +14,6 @@ export default {
14 14 lockScreenPassword: 'Lock screen password',
15 15 lockScreen: 'Lock screen',
16 16 lockScreenBtn: 'Locking',
17   - notLockScreenPassword: 'No password lock screen',
18 17  
19 18 home: 'Home',
20 19 };
... ...
src/locales/lang/en/sys/lock.ts
1 1 export default {
  2 + unlock: 'Click to unlock',
2 3 alert: 'Lock screen password error',
3 4 backToLogin: 'Back to login',
  5 + back: 'Back',
4 6 entry: 'Enter the system',
5 7 placeholder: 'Please enter the lock screen password or user password',
6 8 };
... ...
src/locales/lang/zh_CN/layout/header.ts
... ... @@ -15,7 +15,6 @@ export default {
15 15 lockScreenPassword: '锁屏密码',
16 16 lockScreen: '锁定屏幕',
17 17 lockScreenBtn: '锁定',
18   - notLockScreenPassword: '不设置密码锁屏',
19 18  
20 19 home: '首页',
21 20 };
... ...
src/locales/lang/zh_CN/sys/lock.ts
1 1 export default {
  2 + unlock: '点击解锁',
2 3 alert: '锁屏密码错误',
  4 + back: '返回',
3 5 backToLogin: '返回登录',
4 6 entry: '进入系统',
5 7 placeholder: '请输入锁屏密码或者用户密码',
... ...
src/store/modules/app.ts
... ... @@ -3,16 +3,10 @@ import type { ProjectConfig } from &#39;/@/types/config&#39;;
3 3 import { VuexModule, getModule, Module, Mutation, Action } from 'vuex-module-decorators';
4 4 import store from '/@/store';
5 5  
6   -import { PROJ_CFG_KEY, LOCK_INFO_KEY } from '/@/enums/cacheEnum';
  6 +import { PROJ_CFG_KEY } from '/@/enums/cacheEnum';
7 7  
8 8 import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
9   -import {
10   - setLocal,
11   - getLocal,
12   - removeLocal,
13   - clearSession,
14   - clearLocal,
15   -} from '/@/utils/helper/persistent';
  9 +import { setLocal, getLocal, clearSession, clearLocal } from '/@/utils/helper/persistent';
16 10 import { deepMerge } from '/@/utils';
17 11  
18 12 import { resetRouter } from '/@/router';
... ... @@ -37,9 +31,6 @@ class App extends VuexModule {
37 31 // project config
38 32 private projectConfigState: ProjectConfig | null = getLocal(PROJ_CFG_KEY);
39 33  
40   - // lock info
41   - private lockInfoState: LockInfo | null = getLocal(LOCK_INFO_KEY);
42   -
43 34 // set main overflow hidden
44 35 private lockMainScrollState = false;
45 36  
... ... @@ -51,10 +42,6 @@ class App extends VuexModule {
51 42 return this.lockMainScrollState;
52 43 }
53 44  
54   - get getLockInfo(): LockInfo {
55   - return this.lockInfoState || ({} as LockInfo);
56   - }
57   -
58 45 get getProjectConfig(): ProjectConfig {
59 46 return this.projectConfigState || ({} as ProjectConfig);
60 47 }
... ... @@ -75,18 +62,6 @@ class App extends VuexModule {
75 62 setLocal(PROJ_CFG_KEY, this.projectConfigState);
76 63 }
77 64  
78   - @Mutation
79   - commitLockInfoState(info: LockInfo): void {
80   - this.lockInfoState = Object.assign({}, this.lockInfoState, info);
81   - setLocal(LOCK_INFO_KEY, this.lockInfoState);
82   - }
83   -
84   - @Mutation
85   - resetLockInfo(): void {
86   - removeLocal(LOCK_INFO_KEY);
87   - this.lockInfoState = null;
88   - }
89   -
90 65 @Action
91 66 async resumeAllState() {
92 67 resetRouter();
... ... @@ -111,39 +86,5 @@ class App extends VuexModule {
111 86 clearTimeout(timeId);
112 87 }
113 88 }
114   -
115   - /**
116   - * @description: unlock page
117   - */
118   - @Action
119   - public async unLockAction({ password, valid = true }: { password: string; valid?: boolean }) {
120   - if (!valid) {
121   - this.resetLockInfo();
122   - return true;
123   - }
124   - const tryLogin = async () => {
125   - try {
126   - const username = userStore.getUserInfoState.username;
127   - const res = await userStore.login({ username, password }, false);
128   - if (res) {
129   - this.resetLockInfo();
130   - }
131   - return res;
132   - } catch (error) {
133   - return false;
134   - }
135   - };
136   -
137   - if (this.getLockInfo) {
138   - if (this.getLockInfo.pwd === password) {
139   - this.resetLockInfo();
140   - return true;
141   - }
142   - const res = await tryLogin();
143   - return res;
144   - }
145   - const res = await tryLogin();
146   - return res;
147   - }
148 89 }
149 90 export const appStore = getModule<App>(App);
... ...
src/store/modules/lock.ts 0 → 100644
  1 +import { VuexModule, getModule, Module, Mutation, Action } from 'vuex-module-decorators';
  2 +import store from '/@/store';
  3 +
  4 +import { LOCK_INFO_KEY } from '/@/enums/cacheEnum';
  5 +
  6 +import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper';
  7 +import { setLocal, getLocal, removeLocal } from '/@/utils/helper/persistent';
  8 +
  9 +import { userStore } from './user';
  10 +
  11 +export interface LockInfo {
  12 + pwd: string | undefined;
  13 + isLock: boolean;
  14 +}
  15 +
  16 +const NAME = 'lock';
  17 +hotModuleUnregisterModule(NAME);
  18 +@Module({ dynamic: true, namespaced: true, store, name: NAME })
  19 +class Lock extends VuexModule {
  20 + // lock info
  21 + private lockInfoState: LockInfo | null = getLocal(LOCK_INFO_KEY);
  22 +
  23 + get getLockInfo(): LockInfo {
  24 + return this.lockInfoState || ({} as LockInfo);
  25 + }
  26 +
  27 + @Mutation
  28 + commitLockInfoState(info: LockInfo): void {
  29 + this.lockInfoState = Object.assign({}, this.lockInfoState, info);
  30 + setLocal(LOCK_INFO_KEY, this.lockInfoState);
  31 + }
  32 +
  33 + @Mutation
  34 + resetLockInfo(): void {
  35 + removeLocal(LOCK_INFO_KEY);
  36 + this.lockInfoState = null;
  37 + }
  38 +
  39 + /**
  40 + * @description: unlock page
  41 + */
  42 + @Action
  43 + public async unLockAction({ password }: { password: string }) {
  44 + const tryLogin = async () => {
  45 + try {
  46 + const username = userStore.getUserInfoState.username;
  47 + const res = await userStore.login({ username, password, goHome: false, mode: 'none' });
  48 + if (res) {
  49 + this.resetLockInfo();
  50 + }
  51 + return res;
  52 + } catch (error) {
  53 + return false;
  54 + }
  55 + };
  56 +
  57 + if (this.getLockInfo?.pwd === password) {
  58 + this.resetLockInfo();
  59 + return true;
  60 + }
  61 + return await tryLogin();
  62 + }
  63 +}
  64 +export const lockStore = getModule<Lock>(Lock);
... ...
src/store/modules/user.ts
... ... @@ -21,6 +21,7 @@ import { loginApi, getUserInfoById } from &#39;/@/api/sys/user&#39;;
21 21 import { setLocal, getLocal, getSession, setSession } from '/@/utils/helper/persistent';
22 22 import { useProjectSetting } from '/@/hooks/setting';
23 23 import { useI18n } from '/@/hooks/web/useI18n';
  24 +import { ErrorMessageMode } from '/@/utils/http/axios/types';
24 25  
25 26 export type UserInfo = Omit<GetUserInfoByUserIdModel, 'roles'>;
26 27  
... ... @@ -94,9 +95,16 @@ class User extends VuexModule {
94 95 * @description: login
95 96 */
96 97 @Action
97   - async login(params: LoginParams, goHome = true): Promise<GetUserInfoByUserIdModel | null> {
  98 + async login(
  99 + params: LoginParams & {
  100 + goHome?: boolean;
  101 + mode?: ErrorMessageMode;
  102 + }
  103 + ): Promise<GetUserInfoByUserIdModel | null> {
98 104 try {
99   - const data = await loginApi(params);
  105 + const { goHome = true, mode, ...loginParams } = params;
  106 + const data = await loginApi(loginParams, mode);
  107 +
100 108 const { token, userId } = data;
101 109 // get user info
102 110 const userInfo = await this.getUserInfoAction({ userId });
... ... @@ -106,7 +114,7 @@ class User extends VuexModule {
106 114  
107 115 // const name = FULL_PAGE_NOT_FOUND_ROUTE.name;
108 116 // name && router.removeRoute(name);
109   - goHome && router.push(PageEnum.BASE_HOME);
  117 + goHome && router.replace(PageEnum.BASE_HOME);
110 118 return userInfo;
111 119 } catch (error) {
112 120 return null;
... ...
src/utils/http/axios/Axios.ts
... ... @@ -80,6 +80,7 @@ export class VAxios {
80 80  
81 81 // 请求拦截器配置处理
82 82 this.axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => {
  83 + // If cancel repeat request is turned on, then cancel repeat request is prohibited
83 84 const { headers: { ignoreCancelToken } = { ignoreCancelToken: false } } = config;
84 85 !ignoreCancelToken && axiosCanceler.addPending(config);
85 86 if (requestInterceptors && isFunction(requestInterceptors)) {
... ...
src/utils/http/axios/index.ts
... ... @@ -58,7 +58,7 @@ const transform: AxiosTransform = {
58 58 // errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
59 59 if (options.errorMessageMode === 'modal') {
60 60 createErrorModal({ title: t('sys.api.errorTip'), content: message });
61   - } else {
  61 + } else if (options.errorMessageMode === 'message') {
62 62 createMessage.error(message);
63 63 }
64 64 }
... ... @@ -201,7 +201,7 @@ function createAxios(opt?: Partial&lt;CreateAxiosOptions&gt;) {
201 201 // 格式化提交参数时间
202 202 formatDate: true,
203 203 // 消息提示类型
204   - errorMessageMode: 'none',
  204 + errorMessageMode: 'message',
205 205 // 接口地址
206 206 apiUrl: globSetting.apiUrl,
207 207 },
... ...
src/utils/http/axios/types.ts
1 1 import type { AxiosRequestConfig } from 'axios';
2 2 import { AxiosTransform } from './axiosTransform';
3 3  
  4 +export type ErrorMessageMode = 'none' | 'modal' | 'message' | undefined;
  5 +
4 6 export interface RequestOptions {
5 7 // 请求参数拼接到url
6 8 joinParamsToUrl?: boolean;
... ... @@ -13,7 +15,7 @@ export interface RequestOptions {
13 15 // 接口地址, 不填则使用默认apiUrl
14 16 apiUrl?: string;
15 17 // 错误消息提示类型
16   - errorMessageMode?: 'none' | 'modal';
  18 + errorMessageMode?: ErrorMessageMode;
17 19 }
18 20  
19 21 export interface CreateAxiosOptions extends AxiosRequestConfig {
... ...
src/views/sys/lock/index.vue
1 1 <template>
2   - <div class="lock-page">
3   - <div class="lock-page__entry">
4   - <div class="lock-page__header">
5   - <img src="../../../assets/images/header.jpg" class="lock-page__header-img" />
6   - <p class="lock-page__header-name">{{ realName }}</p>
  2 + <div :class="prefixCls">
  3 + <div :class="`${prefixCls}__unlock`" @click="handleShowForm(false)" v-show="showDate">
  4 + <LockOutlined />
  5 + <span>{{ t('sys.lock.unlock') }}</span>
  6 + </div>
  7 +
  8 + <div :class="`${prefixCls}__date`">
  9 + <div :class="`${prefixCls}__hour`">
  10 + {{ hour }}
  11 + <span class="meridiem" v-show="showDate">{{ meridiem }}</span>
7 12 </div>
8   - <BasicForm @register="register" v-if="!getIsNotPwd" />
9   - <Alert v-if="errMsgRef" type="error" :message="t('alert')" banner />
10   - <div class="lock-page__footer">
11   - <a-button type="default" class="mt-2 mr-2" @click="goLogin" v-if="!getIsNotPwd">
12   - {{ t('sys.lock.backToLogin') }}
13   - </a-button>
14   - <a-button type="primary" class="mt-2" @click="unLock(!getIsNotPwd)" :loading="loadingRef">
15   - {{ t('sys.lock.entry') }}
16   - </a-button>
  13 + <div :class="`${prefixCls}__minute`">{{ minute }} </div>
  14 + </div>
  15 + <transition name="fade-slide">
  16 + <div :class="`${prefixCls}-entry`" v-show="!showDate">
  17 + <div :class="`${prefixCls}-entry-content`">
  18 + <div :class="`${prefixCls}-entry__header`">
  19 + <img src="/@/assets/images/header.jpg" :class="`${prefixCls}-entry__header-img`" />
  20 + <p :class="`${prefixCls}-entry__header-name`">{{ realName }}</p>
  21 + </div>
  22 + <InputPassword :placeholder="t('sys.lock.placeholder')" v-model:value="password" />
  23 + <span :class="`${prefixCls}-entry__err-msg`" v-if="errMsgRef">
  24 + {{ t('sys.lock.alert') }}
  25 + </span>
  26 + <div :class="`${prefixCls}-entry__footer`">
  27 + <a-button
  28 + type="link"
  29 + size="small"
  30 + class="mt-2 mr-2"
  31 + :disabled="loadingRef"
  32 + @click="handleShowForm(true)"
  33 + >
  34 + {{ t('sys.lock.back') }}
  35 + </a-button>
  36 + <a-button
  37 + type="link"
  38 + size="small"
  39 + class="mt-2 mr-2"
  40 + :disabled="loadingRef"
  41 + @click="goLogin"
  42 + >
  43 + {{ t('sys.lock.backToLogin') }}
  44 + </a-button>
  45 + <a-button class="mt-2" type="link" size="small" @click="unLock()" :loading="loadingRef">
  46 + {{ t('sys.lock.entry') }}
  47 + </a-button>
  48 + </div>
  49 + </div>
17 50 </div>
  51 + </transition>
  52 +
  53 + <div :class="`${prefixCls}__footer-date`">
  54 + <div class="time" v-show="!showDate">
  55 + {{ hour }}:{{ minute }} <span class="meridiem">{{ meridiem }}</span>
  56 + </div>
  57 + <div class="date"> {{ year }}/{{ month }}/{{ day }} {{ week }} </div>
18 58 </div>
19 59 </div>
20 60 </template>
21 61 <script lang="ts">
22 62 import { defineComponent, ref, computed } from 'vue';
23   - import { Alert } from 'ant-design-vue';
24   -
25   - import { BasicForm, useForm } from '/@/components/Form';
  63 + import { Alert, Input } from 'ant-design-vue';
26 64  
27 65 import { userStore } from '/@/store/modules/user';
28   - import { appStore } from '/@/store/modules/app';
  66 + import { lockStore } from '/@/store/modules/lock';
29 67 import { useI18n } from '/@/hooks/web/useI18n';
30 68  
  69 + import { useNow } from './useNow';
  70 + import { useDesign } from '/@/hooks/web/useDesign';
  71 +
  72 + import { LockOutlined } from '@ant-design/icons-vue';
  73 +
31 74 export default defineComponent({
32 75 name: 'LockPage',
33   - components: { Alert, BasicForm },
  76 + components: { Alert, LockOutlined, InputPassword: Input.Password },
34 77  
35 78 setup() {
  79 + const passwordRef = ref('');
36 80 const loadingRef = ref(false);
37 81 const errMsgRef = ref(false);
  82 + const showDate = ref(true);
  83 +
  84 + const { prefixCls } = useDesign('lock-page');
  85 +
  86 + const { start, stop, ...state } = useNow(true);
38 87  
39 88 const { t } = useI18n();
40   - const [register, { validateFields }] = useForm({
41   - showActionButtonGroup: false,
42   - schemas: [
43   - {
44   - field: 'password',
45   - label: '',
46   - component: 'InputPassword',
47   - componentProps: {
48   - style: { width: '100%' },
49   - placeholder: t('sys.lock.placeholder'),
50   - },
51   - rules: [{ required: true }],
52   - },
53   - ],
54   - });
  89 +
55 90 const realName = computed(() => {
56 91 const { realName } = userStore.getUserInfoState || {};
57 92 return realName;
58 93 });
59 94  
60   - const getIsNotPwd = computed(() => {
61   - if (!appStore.getLockInfo) {
62   - return true;
63   - }
64   - return appStore.getLockInfo.pwd === undefined;
65   - });
66   -
67 95 /**
68 96 * @description: unLock
69 97 */
70   - async function unLock(valid = true) {
71   - let password = '';
72   - if (valid) {
73   - try {
74   - const values = (await validateFields()) as any;
75   - password = values.password;
76   - } catch (error) {
77   - return;
78   - }
  98 + async function unLock() {
  99 + if (!passwordRef.value) {
  100 + return;
79 101 }
  102 + let password = passwordRef.value;
80 103 try {
81 104 loadingRef.value = true;
82   - const res = await appStore.unLockAction({ password, valid });
  105 + const res = await lockStore.unLockAction({ password });
83 106 errMsgRef.value = !res;
84 107 } finally {
85 108 loadingRef.value = false;
... ... @@ -88,67 +111,190 @@
88 111  
89 112 function goLogin() {
90 113 userStore.loginOut(true);
91   - appStore.resetLockInfo();
  114 + lockStore.resetLockInfo();
  115 + }
  116 +
  117 + function handleShowForm(show = false) {
  118 + showDate.value = show;
92 119 }
93 120  
94 121 return {
95   - register,
96   - getIsNotPwd,
97 122 goLogin,
98 123 realName,
99 124 unLock,
100 125 errMsgRef,
101 126 loadingRef,
102 127 t,
  128 + prefixCls,
  129 + showDate,
  130 + password: passwordRef,
  131 + handleShowForm,
  132 + ...state,
103 133 };
104 134 },
105 135 });
106 136 </script>
107 137 <style lang="less" scoped>
108 138 @import (reference) '../../../design/index.less';
  139 + @prefix-cls: ~'@{namespace}-lock-page';
109 140  
110   - .lock-page {
  141 + .@{prefix-cls} {
111 142 position: fixed;
112 143 top: 0;
  144 + right: 0;
  145 + bottom: 0;
113 146 left: 0;
114   - z-index: 999999;
  147 + z-index: 3000;
115 148 display: flex;
116 149 width: 100vw;
117 150 height: 100vh;
118   - background: url(../../../assets/images/lock-page.jpg) no-repeat;
119   - background-size: 100% 100%;
  151 + // background: rgba(23, 27, 41);
  152 + background: #000;
120 153 align-items: center;
121   - justify-content: flex-end;
  154 + justify-content: center;
  155 +
  156 + &__unlock {
  157 + position: absolute;
  158 + top: 0;
  159 + left: 50%;
  160 + display: flex;
  161 + height: 50px;
  162 + padding-top: 20px;
  163 + font-size: 18px;
  164 + color: #fff;
  165 + cursor: pointer;
  166 + transform: translate(-50%, 0);
  167 + flex-direction: column;
  168 + align-items: center;
  169 + justify-content: space-between;
  170 + transition: all 0.3s;
  171 + }
  172 +
  173 + &__date {
  174 + display: flex;
  175 + width: 100vw;
  176 + height: 100vh;
  177 + align-items: center;
  178 + justify-content: center;
  179 + }
122 180  
123   - &__entry {
  181 + &__hour {
124 182 position: relative;
125   - width: 400px;
126   - // height: 260px;
127   - padding: 80px 50px 50px 50px;
128   - margin-right: 50px;
129   - background: #fff;
130   - border-radius: 6px;
  183 + margin-right: 80px;
  184 +
  185 + .meridiem {
  186 + position: absolute;
  187 + top: 20px;
  188 + left: 20px;
  189 + font-size: 26px;
  190 + }
  191 + @media (max-width: @screen-xs) {
  192 + margin-right: 20px;
  193 + }
131 194 }
132 195  
133   - &__header {
  196 + &__hour,
  197 + &__minute {
  198 + display: flex;
  199 + width: 40%;
  200 + height: 74%;
  201 + // font-size: 50em;
  202 + font-weight: 700;
  203 + color: #bababa;
  204 + background: #141313;
  205 + border-radius: 30px;
  206 + justify-content: center;
  207 + align-items: center;
  208 + // .respond-to(large-only, { font-size: 25em;});
  209 + // .respond-to(large-only, { font-size: 30em;});
  210 + @media (min-width: @screen-xxxl-min) {
  211 + font-size: 46em;
  212 + }
  213 + @media (min-width: @screen-xl-max) and (max-width: @screen-xxl-max) {
  214 + font-size: 38em;
  215 + }
  216 +
  217 + @media (min-width: @screen-lg-max) and (max-width: @screen-xl-max) {
  218 + font-size: 30em;
  219 + }
  220 + @media (min-width: @screen-md-max) and (max-width: @screen-lg-max) {
  221 + font-size: 23em;
  222 + }
  223 + @media (min-width: @screen-sm-max) and (max-width: @screen-md-max) {
  224 + font-size: 19em;
  225 + }
  226 + @media (min-width: @screen-xs-max) and (max-width: @screen-sm-max) {
  227 + font-size: 13em;
  228 + }
  229 + @media (max-width: @screen-xs) {
  230 + height: 50%;
  231 + font-size: 6em;
  232 + border-radius: 20px;
  233 + }
  234 + }
  235 +
  236 + &__footer-date {
134 237 position: absolute;
135   - top: -35px;
136   - left: calc(50% - 45px);
137   - width: auto;
138   - text-align: center;
  238 + bottom: 20px;
  239 + left: 50%;
  240 + font-family: helvetica;
  241 + color: #bababa;
  242 + transform: translate(-50%, 0);
139 243  
140   - &-img {
141   - width: 70px;
142   - border-radius: 50%;
  244 + .time {
  245 + font-size: 50px;
  246 +
  247 + .meridiem {
  248 + font-size: 32px;
  249 + }
143 250 }
144 251  
145   - &-name {
146   - margin-top: 5px;
  252 + .date {
  253 + font-size: 26px;
147 254 }
148 255 }
149 256  
150   - &__footer {
151   - text-align: center;
  257 + &-entry {
  258 + position: absolute;
  259 + top: 0;
  260 + left: 0;
  261 + display: flex;
  262 + width: 100%;
  263 + height: 100%;
  264 + background: rgba(0, 0, 0, 0.5);
  265 + backdrop-filter: blur(10px);
  266 + justify-content: center;
  267 + align-items: center;
  268 +
  269 + &-content {
  270 + width: 260px;
  271 + }
  272 +
  273 + &__header {
  274 + text-align: center;
  275 +
  276 + &-img {
  277 + width: 70px;
  278 + border-radius: 50%;
  279 + }
  280 +
  281 + &-name {
  282 + margin-top: 5px;
  283 + font-weight: 500;
  284 + color: #bababa;
  285 + }
  286 + }
  287 +
  288 + &__err-msg {
  289 + display: inline-block;
  290 + margin-top: 10px;
  291 + color: @error-color;
  292 + }
  293 +
  294 + &__footer {
  295 + display: flex;
  296 + justify-content: space-between;
  297 + }
152 298 }
153 299 }
154 300 </style>
... ...
src/views/sys/lock/useNow.ts 0 → 100644
  1 +import moment from 'moment';
  2 +import { reactive, toRefs } from 'vue';
  3 +import { tryOnMounted, tryOnUnmounted } from '/@/utils/helper/vueHelper';
  4 +import { useLocaleSetting } from '/@/hooks/setting/useLocaleSetting';
  5 +
  6 +export function useNow(immediate = true) {
  7 + const { getLang } = useLocaleSetting();
  8 + const localData = moment.localeData(getLang.value);
  9 + let timer: IntervalHandle;
  10 +
  11 + const state = reactive({
  12 + year: 0,
  13 + month: 0,
  14 + week: '',
  15 + day: 0,
  16 + hour: '',
  17 + minute: '',
  18 + second: 0,
  19 + meridiem: '',
  20 + });
  21 +
  22 + const update = () => {
  23 + const now = moment();
  24 +
  25 + const h = now.format('HH');
  26 + const m = now.format('mm');
  27 + const s = now.get('s');
  28 +
  29 + state.year = now.get('y');
  30 + state.month = now.get('M');
  31 + state.week = localData.weekdays()[now.day()];
  32 + state.day = now.get('D');
  33 + state.hour = h;
  34 + state.minute = m;
  35 + state.second = s;
  36 +
  37 + state.meridiem = localData.meridiem(Number(h), Number(h), true);
  38 + };
  39 +
  40 + function start() {
  41 + update();
  42 + clearInterval(timer);
  43 + timer = setInterval(() => update(), 1000);
  44 + }
  45 +
  46 + function stop() {
  47 + clearInterval(timer);
  48 + }
  49 +
  50 + tryOnMounted(() => {
  51 + immediate && start();
  52 + });
  53 +
  54 + tryOnUnmounted(() => {
  55 + stop();
  56 + });
  57 +
  58 + return {
  59 + ...toRefs(state),
  60 + start,
  61 + stop,
  62 + };
  63 +}
... ...