Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
啊嘞嘞EC
vue-vben-admin
提交
4ce1d526
V
vue-vben-admin
项目概览
啊嘞嘞EC
/
vue-vben-admin
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vue-vben-admin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4ce1d526
编写于
12月 09, 2020
作者:
V
vben
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor(lock-page): refactor lock page
上级
e9c28319
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
426 addition
and
192 deletion
+426
-192
CHANGELOG.zh_CN.md
CHANGELOG.zh_CN.md
+1
-0
src/api/sys/user.ts
src/api/sys/user.ts
+3
-2
src/assets/images/lock-page.jpg
src/assets/images/lock-page.jpg
+0
-0
src/design/mixins.less
src/design/mixins.less
+1
-0
src/design/var/breakpoint.less
src/design/var/breakpoint.less
+4
-0
src/hooks/setting/useRootSetting.ts
src/hooks/setting/useRootSetting.ts
+3
-0
src/hooks/web/useLockPage.ts
src/hooks/web/useLockPage.ts
+12
-4
src/layouts/default/index.tsx
src/layouts/default/index.tsx
+1
-1
src/layouts/default/lock/LockAction.tsx
src/layouts/default/lock/LockAction.tsx
+10
-21
src/layouts/default/lock/index.tsx
src/layouts/default/lock/index.tsx
+0
-17
src/layouts/default/lock/index.vue
src/layouts/default/lock/index.vue
+17
-0
src/locales/lang/en/layout/header.ts
src/locales/lang/en/layout/header.ts
+0
-1
src/locales/lang/en/sys/lock.ts
src/locales/lang/en/sys/lock.ts
+2
-0
src/locales/lang/zh_CN/layout/header.ts
src/locales/lang/zh_CN/layout/header.ts
+0
-1
src/locales/lang/zh_CN/sys/lock.ts
src/locales/lang/zh_CN/sys/lock.ts
+2
-0
src/store/modules/app.ts
src/store/modules/app.ts
+2
-61
src/store/modules/lock.ts
src/store/modules/lock.ts
+64
-0
src/store/modules/user.ts
src/store/modules/user.ts
+11
-3
src/utils/http/axios/Axios.ts
src/utils/http/axios/Axios.ts
+1
-0
src/utils/http/axios/index.ts
src/utils/http/axios/index.ts
+2
-2
src/utils/http/axios/types.ts
src/utils/http/axios/types.ts
+3
-1
src/views/sys/lock/index.vue
src/views/sys/lock/index.vue
+224
-78
src/views/sys/lock/useNow.ts
src/views/sys/lock/useNow.ts
+63
-0
未找到文件。
CHANGELOG.zh_CN.md
浏览文件 @
4ce1d526
...
...
@@ -16,6 +16,7 @@
### ✨ Refactor
-
tree 组件 ref 函数调用删除
`$`
-
锁屏界面重构美化,删除不必要的背景图片
### ⚡ Performance Improvements
...
...
src/api/sys/user.ts
浏览文件 @
4ce1d526
...
...
@@ -5,6 +5,7 @@ import {
GetUserInfoByUserIdParams
,
GetUserInfoByUserIdModel
,
}
from
'
./model/userModel
'
;
import
{
ErrorMessageMode
}
from
'
/@/utils/http/axios/types
'
;
enum
Api
{
Login
=
'
/login
'
,
...
...
@@ -15,7 +16,7 @@ enum Api {
/**
* @description: user login api
*/
export
function
loginApi
(
params
:
LoginParams
)
{
export
function
loginApi
(
params
:
LoginParams
,
mode
:
ErrorMessageMode
=
'
modal
'
)
{
return
defHttp
.
request
<
LoginResultModel
>
(
{
url
:
Api
.
Login
,
...
...
@@ -23,7 +24,7 @@ export function loginApi(params: LoginParams) {
params
,
},
{
errorMessageMode
:
'
modal
'
,
errorMessageMode
:
mode
,
}
);
}
...
...
src/assets/images/lock-page.jpg
已删除
100644 → 0
浏览文件 @
e9c28319
217.9 KB
src/design/mixins.less
浏览文件 @
4ce1d526
...
...
@@ -90,6 +90,7 @@
@content();
}
}
.respond-to (xsmall-and-small, @content) {
@media only screen and (max-width: @screen-sm-max) {
@content();
...
...
src/design/var/breakpoint.less
浏览文件 @
4ce1d526
...
...
@@ -26,9 +26,13 @@
@screen-xxl: 1600px;
@screen-xxl-min: @screen-xxl;
@screen-xxxl: 1900px;
@screen-xxxl-min: @screen-xxxl;
// provide a maximum
@screen-xs-max: (@screen-sm-min - 1px);
@screen-sm-max: (@screen-md-min - 1px);
@screen-md-max: (@screen-lg-min - 1px);
@screen-lg-max: (@screen-xl-min - 1px);
@screen-xl-max: (@screen-xxl-min - 1px);
@screen-xxl-max: (@screen-xxxl-min - 1px);
src/hooks/setting/useRootSetting.ts
浏览文件 @
4ce1d526
...
...
@@ -42,6 +42,8 @@ const getColorWeak = computed(() => unref(getRootSetting).colorWeak);
const
getGrayMode
=
computed
(()
=>
unref
(
getRootSetting
).
grayMode
);
const
getLockTime
=
computed
(()
=>
unref
(
getRootSetting
).
lockTime
);
const
getLayoutContentMode
=
computed
(()
=>
unref
(
getRootSetting
).
contentMode
===
ContentEnum
.
FULL
?
ContentEnum
.
FULL
:
ContentEnum
.
FIXED
);
...
...
@@ -71,5 +73,6 @@ export function useRootSetting() {
getShowSettingButton
,
getShowFooter
,
getContentMode
,
getLockTime
,
};
}
src/hooks/web/useLockPage.ts
浏览文件 @
4ce1d526
import
{
computed
,
onUnmounted
,
watchEffect
}
from
'
vue
'
;
import
{
computed
,
onUnmounted
,
unref
,
watchEffect
}
from
'
vue
'
;
import
{
useThrottle
}
from
'
/@/hooks/core/useThrottle
'
;
import
{
appStore
}
from
'
/@/store/modules/app
'
;
import
{
lockStore
}
from
'
/@/store/modules/lock
'
;
import
{
userStore
}
from
'
/@/store/modules/user
'
;
import
{
useRootSetting
}
from
'
../setting/useRootSetting
'
;
export
function
useLockPage
()
{
const
{
getLockTime
}
=
useRootSetting
();
let
timeId
:
TimeoutHandle
;
function
clear
():
void
{
...
...
@@ -30,7 +33,7 @@ export function useLockPage() {
}
function
lockPage
():
void
{
app
Store
.
commitLockInfoState
({
lock
Store
.
commitLockInfoState
({
isLock
:
true
,
pwd
:
undefined
,
});
...
...
@@ -54,8 +57,7 @@ export function useLockPage() {
const
[
keyupFn
]
=
useThrottle
(
resetCalcLockTimeout
,
2000
);
return
computed
(()
=>
{
const
openLockPage
=
appStore
.
getProjectConfig
.
lockTime
;
if
(
openLockPage
)
{
if
(
unref
(
getLockTime
))
{
return
{
onKeyup
:
keyupFn
,
onMousemove
:
keyupFn
};
}
else
{
clear
();
...
...
@@ -63,3 +65,9 @@ export function useLockPage() {
}
});
}
export
const
getIsLock
=
computed
(()
=>
{
const
{
getLockInfo
}
=
lockStore
;
const
{
isLock
}
=
getLockInfo
;
return
isLock
;
});
src/layouts/default/index.tsx
浏览文件 @
4ce1d526
...
...
@@ -6,7 +6,7 @@ import LayoutHeader from './header/LayoutHeader';
import
LayoutContent
from
'
./content
'
;
import
LayoutFooter
from
'
./footer
'
;
import
LayoutLockPage
from
'
./lock
'
;
import
LayoutLockPage
from
'
./lock
/index.vue
'
;
import
LayoutSideBar
from
'
./sider
'
;
import
SettingBtn
from
'
./setting/index.vue
'
;
import
LayoutMultipleHeader
from
'
./header/LayoutMultipleHeader
'
;
...
...
src/layouts/default/lock/LockAction.tsx
浏览文件 @
4ce1d526
...
...
@@ -7,9 +7,9 @@ import { BasicForm, useForm } from '/@/components/Form/index';
import
headerImg
from
'
/@/assets/images/header.jpg
'
;
import
{
appStore
}
from
'
/@/store/modules/app
'
;
import
{
userStore
}
from
'
/@/store/modules/user
'
;
import
{
useI18n
}
from
'
/@/hooks/web/useI18n
'
;
import
{
lockStore
}
from
'
/@/store/modules/lock
'
;
const
prefixCls
=
'
lock-modal
'
;
export
default
defineComponent
({
...
...
@@ -30,24 +30,16 @@ export default defineComponent({
],
});
async
function
lock
(
valid
=
true
)
{
let
password
:
string
|
undefined
=
''
;
async
function
lock
()
{
const
values
=
(
await
validateFields
())
as
any
;
const
password
:
string
|
undefined
=
values
.
password
;
closeModal
();
try
{
if
(
!
valid
)
{
password
=
undefined
;
}
else
{
const
values
=
(
await
validateFields
())
as
any
;
password
=
values
.
password
;
}
closeModal
();
appStore
.
commitLockInfoState
({
isLock
:
true
,
pwd
:
password
,
});
await
resetFields
();
}
catch
(
error
)
{}
lockStore
.
commitLockInfoState
({
isLock
:
true
,
pwd
:
password
,
});
await
resetFields
();
}
return
()
=>
(
...
...
@@ -71,9 +63,6 @@ export default defineComponent({
<
Button
type
=
"primary"
block
class
=
"mt-2"
onClick
=
{
lock
}
>
{
()
=>
t
(
'
layout.header.lockScreenBtn
'
)
}
</
Button
>
<
Button
block
class
=
"mt-2"
onClick
=
{
lock
.
bind
(
null
,
false
)
}
>
{
()
=>
t
(
'
layout.header.notLockScreenPassword
'
)
}
</
Button
>
</
div
>
</
div
>
)
}
...
...
src/layouts/default/lock/index.tsx
已删除
100644 → 0
浏览文件 @
e9c28319
import
{
defineComponent
,
unref
,
computed
}
from
'
vue
'
;
import
{
appStore
}
from
'
/@/store/modules/app
'
;
import
LockPage
from
'
/@/views/sys/lock/index.vue
'
;
export
default
defineComponent
({
name
:
'
LayoutLockPage
'
,
setup
()
{
const
getIsLockRef
=
computed
(()
=>
{
const
{
getLockInfo
}
=
appStore
;
const
{
isLock
}
=
getLockInfo
;
return
isLock
;
});
return
()
=>
{
return
unref
(
getIsLockRef
)
?
<
LockPage
/>
:
null
;
};
},
});
src/layouts/default/lock/index.vue
0 → 100644
浏览文件 @
4ce1d526
<
template
>
<transition
name=
"fade-bottom"
>
<LockPage
v-if=
"getIsLock"
/>
</transition>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
LockPage
from
'
/@/views/sys/lock/index.vue
'
;
import
{
getIsLock
}
from
'
/@/hooks/web/useLockPage
'
;
export
default
defineComponent
({
name
:
'
LayoutLockPage
'
,
components
:
{
LockPage
},
setup
()
{
return
{
getIsLock
};
},
});
</
script
>
src/locales/lang/en/layout/header.ts
浏览文件 @
4ce1d526
...
...
@@ -14,7 +14,6 @@ export default {
lockScreenPassword
:
'
Lock screen password
'
,
lockScreen
:
'
Lock screen
'
,
lockScreenBtn
:
'
Locking
'
,
notLockScreenPassword
:
'
No password lock screen
'
,
home
:
'
Home
'
,
};
src/locales/lang/en/sys/lock.ts
浏览文件 @
4ce1d526
export
default
{
unlock
:
'
Click to unlock
'
,
alert
:
'
Lock screen password error
'
,
backToLogin
:
'
Back to login
'
,
back
:
'
Back
'
,
entry
:
'
Enter the system
'
,
placeholder
:
'
Please enter the lock screen password or user password
'
,
};
src/locales/lang/zh_CN/layout/header.ts
浏览文件 @
4ce1d526
...
...
@@ -15,7 +15,6 @@ export default {
lockScreenPassword
:
'
锁屏密码
'
,
lockScreen
:
'
锁定屏幕
'
,
lockScreenBtn
:
'
锁定
'
,
notLockScreenPassword
:
'
不设置密码锁屏
'
,
home
:
'
首页
'
,
};
src/locales/lang/zh_CN/sys/lock.ts
浏览文件 @
4ce1d526
export
default
{
unlock
:
'
点击解锁
'
,
alert
:
'
锁屏密码错误
'
,
back
:
'
返回
'
,
backToLogin
:
'
返回登录
'
,
entry
:
'
进入系统
'
,
placeholder
:
'
请输入锁屏密码或者用户密码
'
,
...
...
src/store/modules/app.ts
浏览文件 @
4ce1d526
...
...
@@ -3,16 +3,10 @@ import type { ProjectConfig } from '/@/types/config';
import
{
VuexModule
,
getModule
,
Module
,
Mutation
,
Action
}
from
'
vuex-module-decorators
'
;
import
store
from
'
/@/store
'
;
import
{
PROJ_CFG_KEY
,
LOCK_INFO_KEY
}
from
'
/@/enums/cacheEnum
'
;
import
{
PROJ_CFG_KEY
}
from
'
/@/enums/cacheEnum
'
;
import
{
hotModuleUnregisterModule
}
from
'
/@/utils/helper/vuexHelper
'
;
import
{
setLocal
,
getLocal
,
removeLocal
,
clearSession
,
clearLocal
,
}
from
'
/@/utils/helper/persistent
'
;
import
{
setLocal
,
getLocal
,
clearSession
,
clearLocal
}
from
'
/@/utils/helper/persistent
'
;
import
{
deepMerge
}
from
'
/@/utils
'
;
import
{
resetRouter
}
from
'
/@/router
'
;
...
...
@@ -37,9 +31,6 @@ class App extends VuexModule {
// project config
private
projectConfigState
:
ProjectConfig
|
null
=
getLocal
(
PROJ_CFG_KEY
);
// lock info
private
lockInfoState
:
LockInfo
|
null
=
getLocal
(
LOCK_INFO_KEY
);
// set main overflow hidden
private
lockMainScrollState
=
false
;
...
...
@@ -51,10 +42,6 @@ class App extends VuexModule {
return
this
.
lockMainScrollState
;
}
get
getLockInfo
():
LockInfo
{
return
this
.
lockInfoState
||
({}
as
LockInfo
);
}
get
getProjectConfig
():
ProjectConfig
{
return
this
.
projectConfigState
||
({}
as
ProjectConfig
);
}
...
...
@@ -75,18 +62,6 @@ class App extends VuexModule {
setLocal
(
PROJ_CFG_KEY
,
this
.
projectConfigState
);
}
@
Mutation
commitLockInfoState
(
info
:
LockInfo
):
void
{
this
.
lockInfoState
=
Object
.
assign
({},
this
.
lockInfoState
,
info
);
setLocal
(
LOCK_INFO_KEY
,
this
.
lockInfoState
);
}
@
Mutation
resetLockInfo
():
void
{
removeLocal
(
LOCK_INFO_KEY
);
this
.
lockInfoState
=
null
;
}
@
Action
async
resumeAllState
()
{
resetRouter
();
...
...
@@ -111,39 +86,5 @@ class App extends VuexModule {
clearTimeout
(
timeId
);
}
}
/**
* @description: unlock page
*/
@
Action
public
async
unLockAction
({
password
,
valid
=
true
}:
{
password
:
string
;
valid
?:
boolean
})
{
if
(
!
valid
)
{
this
.
resetLockInfo
();
return
true
;
}
const
tryLogin
=
async
()
=>
{
try
{
const
username
=
userStore
.
getUserInfoState
.
username
;
const
res
=
await
userStore
.
login
({
username
,
password
},
false
);
if
(
res
)
{
this
.
resetLockInfo
();
}
return
res
;
}
catch
(
error
)
{
return
false
;
}
};
if
(
this
.
getLockInfo
)
{
if
(
this
.
getLockInfo
.
pwd
===
password
)
{
this
.
resetLockInfo
();
return
true
;
}
const
res
=
await
tryLogin
();
return
res
;
}
const
res
=
await
tryLogin
();
return
res
;
}
}
export
const
appStore
=
getModule
<
App
>
(
App
);
src/store/modules/lock.ts
0 → 100644
浏览文件 @
4ce1d526
import
{
VuexModule
,
getModule
,
Module
,
Mutation
,
Action
}
from
'
vuex-module-decorators
'
;
import
store
from
'
/@/store
'
;
import
{
LOCK_INFO_KEY
}
from
'
/@/enums/cacheEnum
'
;
import
{
hotModuleUnregisterModule
}
from
'
/@/utils/helper/vuexHelper
'
;
import
{
setLocal
,
getLocal
,
removeLocal
}
from
'
/@/utils/helper/persistent
'
;
import
{
userStore
}
from
'
./user
'
;
export
interface
LockInfo
{
pwd
:
string
|
undefined
;
isLock
:
boolean
;
}
const
NAME
=
'
lock
'
;
hotModuleUnregisterModule
(
NAME
);
@
Module
({
dynamic
:
true
,
namespaced
:
true
,
store
,
name
:
NAME
})
class
Lock
extends
VuexModule
{
// lock info
private
lockInfoState
:
LockInfo
|
null
=
getLocal
(
LOCK_INFO_KEY
);
get
getLockInfo
():
LockInfo
{
return
this
.
lockInfoState
||
({}
as
LockInfo
);
}
@
Mutation
commitLockInfoState
(
info
:
LockInfo
):
void
{
this
.
lockInfoState
=
Object
.
assign
({},
this
.
lockInfoState
,
info
);
setLocal
(
LOCK_INFO_KEY
,
this
.
lockInfoState
);
}
@
Mutation
resetLockInfo
():
void
{
removeLocal
(
LOCK_INFO_KEY
);
this
.
lockInfoState
=
null
;
}
/**
* @description: unlock page
*/
@
Action
public
async
unLockAction
({
password
}:
{
password
:
string
})
{
const
tryLogin
=
async
()
=>
{
try
{
const
username
=
userStore
.
getUserInfoState
.
username
;
const
res
=
await
userStore
.
login
({
username
,
password
,
goHome
:
false
,
mode
:
'
none
'
});
if
(
res
)
{
this
.
resetLockInfo
();
}
return
res
;
}
catch
(
error
)
{
return
false
;
}
};
if
(
this
.
getLockInfo
?.
pwd
===
password
)
{
this
.
resetLockInfo
();
return
true
;
}
return
await
tryLogin
();
}
}
export
const
lockStore
=
getModule
<
Lock
>
(
Lock
);
src/store/modules/user.ts
浏览文件 @
4ce1d526
...
...
@@ -21,6 +21,7 @@ import { loginApi, getUserInfoById } from '/@/api/sys/user';
import
{
setLocal
,
getLocal
,
getSession
,
setSession
}
from
'
/@/utils/helper/persistent
'
;
import
{
useProjectSetting
}
from
'
/@/hooks/setting
'
;
import
{
useI18n
}
from
'
/@/hooks/web/useI18n
'
;
import
{
ErrorMessageMode
}
from
'
/@/utils/http/axios/types
'
;
export
type
UserInfo
=
Omit
<
GetUserInfoByUserIdModel
,
'
roles
'
>
;
...
...
@@ -94,9 +95,16 @@ class User extends VuexModule {
* @description: login
*/
@
Action
async
login
(
params
:
LoginParams
,
goHome
=
true
):
Promise
<
GetUserInfoByUserIdModel
|
null
>
{
async
login
(
params
:
LoginParams
&
{
goHome
?:
boolean
;
mode
?:
ErrorMessageMode
;
}
):
Promise
<
GetUserInfoByUserIdModel
|
null
>
{
try
{
const
data
=
await
loginApi
(
params
);
const
{
goHome
=
true
,
mode
,
...
loginParams
}
=
params
;
const
data
=
await
loginApi
(
loginParams
,
mode
);
const
{
token
,
userId
}
=
data
;
// get user info
const
userInfo
=
await
this
.
getUserInfoAction
({
userId
});
...
...
@@ -106,7 +114,7 @@ class User extends VuexModule {
// const name = FULL_PAGE_NOT_FOUND_ROUTE.name;
// name && router.removeRoute(name);
goHome
&&
router
.
push
(
PageEnum
.
BASE_HOME
);
goHome
&&
router
.
replace
(
PageEnum
.
BASE_HOME
);
return
userInfo
;
}
catch
(
error
)
{
return
null
;
...
...
src/utils/http/axios/Axios.ts
浏览文件 @
4ce1d526
...
...
@@ -80,6 +80,7 @@ export class VAxios {
// 请求拦截器配置处理
this
.
axiosInstance
.
interceptors
.
request
.
use
((
config
:
AxiosRequestConfig
)
=>
{
// If cancel repeat request is turned on, then cancel repeat request is prohibited
const
{
headers
:
{
ignoreCancelToken
}
=
{
ignoreCancelToken
:
false
}
}
=
config
;
!
ignoreCancelToken
&&
axiosCanceler
.
addPending
(
config
);
if
(
requestInterceptors
&&
isFunction
(
requestInterceptors
))
{
...
...
src/utils/http/axios/index.ts
浏览文件 @
4ce1d526
...
...
@@ -58,7 +58,7 @@ const transform: AxiosTransform = {
// errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
if
(
options
.
errorMessageMode
===
'
modal
'
)
{
createErrorModal
({
title
:
t
(
'
sys.api.errorTip
'
),
content
:
message
});
}
else
{
}
else
if
(
options
.
errorMessageMode
===
'
message
'
)
{
createMessage
.
error
(
message
);
}
}
...
...
@@ -201,7 +201,7 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
// 格式化提交参数时间
formatDate
:
true
,
// 消息提示类型
errorMessageMode
:
'
non
e
'
,
errorMessageMode
:
'
messag
e
'
,
// 接口地址
apiUrl
:
globSetting
.
apiUrl
,
},
...
...
src/utils/http/axios/types.ts
浏览文件 @
4ce1d526
import
type
{
AxiosRequestConfig
}
from
'
axios
'
;
import
{
AxiosTransform
}
from
'
./axiosTransform
'
;
export
type
ErrorMessageMode
=
'
none
'
|
'
modal
'
|
'
message
'
|
undefined
;
export
interface
RequestOptions
{
// 请求参数拼接到url
joinParamsToUrl
?:
boolean
;
...
...
@@ -13,7 +15,7 @@ export interface RequestOptions {
// 接口地址, 不填则使用默认apiUrl
apiUrl
?:
string
;
// 错误消息提示类型
errorMessageMode
?:
'
none
'
|
'
modal
'
;
errorMessageMode
?:
ErrorMessageMode
;
}
export
interface
CreateAxiosOptions
extends
AxiosRequestConfig
{
...
...
src/views/sys/lock/index.vue
浏览文件 @
4ce1d526
<
template
>
<div
class=
"lock-page"
>
<div
class=
"lock-page__entry"
>
<div
class=
"lock-page__header"
>
<img
src=
"../../../assets/images/header.jpg"
class=
"lock-page__header-img"
/>
<p
class=
"lock-page__header-name"
>
{{
realName
}}
</p>
<div
:class=
"prefixCls"
>
<div
:class=
"`$
{prefixCls}__unlock`" @click="handleShowForm(false)" v-show="showDate">
<LockOutlined
/>
<span>
{{
t
(
'
sys.lock.unlock
'
)
}}
</span>
</div>
<div
:class=
"`$
{prefixCls}__date`">
<div
:class=
"`$
{prefixCls}__hour`">
{{
hour
}}
<span
class=
"meridiem"
v-show=
"showDate"
>
{{
meridiem
}}
</span>
</div>
<BasicForm
@
register=
"register"
v-if=
"!getIsNotPwd"
/>
<Alert
v-if=
"errMsgRef"
type=
"error"
:message=
"t('alert')"
banner
/>
<div
class=
"lock-page__footer"
>
<a-button
type=
"default"
class=
"mt-2 mr-2"
@
click=
"goLogin"
v-if=
"!getIsNotPwd"
>
{{
t
(
'
sys.lock.backToLogin
'
)
}}
</a-button>
<a-button
type=
"primary"
class=
"mt-2"
@
click=
"unLock(!getIsNotPwd)"
:loading=
"loadingRef"
>
{{
t
(
'
sys.lock.entry
'
)
}}
</a-button>
<div
:class=
"`$
{prefixCls}__minute`">
{{
minute
}}
</div>
</div>
<transition
name=
"fade-slide"
>
<div
:class=
"`$
{prefixCls}-entry`" v-show="!showDate">
<div
:class=
"`$
{prefixCls}-entry-content`">
<div
:class=
"`$
{prefixCls}-entry__header`">
<img
src=
"/@/assets/images/header.jpg"
:class=
"`$
{prefixCls}-entry__header-img`" />
<p
:class=
"`$
{prefixCls}-entry__header-name`">
{{
realName
}}
</p>
</div>
<InputPassword
:placeholder=
"t('sys.lock.placeholder')"
v-model:value=
"password"
/>
<span
:class=
"`$
{prefixCls}-entry__err-msg`" v-if="errMsgRef">
{{
t
(
'
sys.lock.alert
'
)
}}
</span>
<div
:class=
"`$
{prefixCls}-entry__footer`">
<a-button
type=
"link"
size=
"small"
class=
"mt-2 mr-2"
:disabled=
"loadingRef"
@
click=
"handleShowForm(true)"
>
{{
t
(
'
sys.lock.back
'
)
}}
</a-button>
<a-button
type=
"link"
size=
"small"
class=
"mt-2 mr-2"
:disabled=
"loadingRef"
@
click=
"goLogin"
>
{{
t
(
'
sys.lock.backToLogin
'
)
}}
</a-button>
<a-button
class=
"mt-2"
type=
"link"
size=
"small"
@
click=
"unLock()"
:loading=
"loadingRef"
>
{{
t
(
'
sys.lock.entry
'
)
}}
</a-button>
</div>
</div>
</div>
</transition>
<div
:class=
"`$
{prefixCls}__footer-date`">
<div
class=
"time"
v-show=
"!showDate"
>
{{
hour
}}
:
{{
minute
}}
<span
class=
"meridiem"
>
{{
meridiem
}}
</span>
</div>
<div
class=
"date"
>
{{
year
}}
/
{{
month
}}
/
{{
day
}}
{{
week
}}
</div>
</div>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
,
ref
,
computed
}
from
'
vue
'
;
import
{
Alert
}
from
'
ant-design-vue
'
;
import
{
BasicForm
,
useForm
}
from
'
/@/components/Form
'
;
import
{
Alert
,
Input
}
from
'
ant-design-vue
'
;
import
{
userStore
}
from
'
/@/store/modules/user
'
;
import
{
appStore
}
from
'
/@/store/modules/app
'
;
import
{
lockStore
}
from
'
/@/store/modules/lock
'
;
import
{
useI18n
}
from
'
/@/hooks/web/useI18n
'
;
import
{
useNow
}
from
'
./useNow
'
;
import
{
useDesign
}
from
'
/@/hooks/web/useDesign
'
;
import
{
LockOutlined
}
from
'
@ant-design/icons-vue
'
;
export
default
defineComponent
({
name
:
'
LockPage
'
,
components
:
{
Alert
,
BasicForm
},
components
:
{
Alert
,
LockOutlined
,
InputPassword
:
Input
.
Password
},
setup
()
{
const
passwordRef
=
ref
(
''
);
const
loadingRef
=
ref
(
false
);
const
errMsgRef
=
ref
(
false
);
const
showDate
=
ref
(
true
);
const
{
prefixCls
}
=
useDesign
(
'
lock-page
'
);
const
{
start
,
stop
,
...
state
}
=
useNow
(
true
);
const
{
t
}
=
useI18n
();
const
[
register
,
{
validateFields
}]
=
useForm
({
showActionButtonGroup
:
false
,
schemas
:
[
{
field
:
'
password
'
,
label
:
''
,
component
:
'
InputPassword
'
,
componentProps
:
{
style
:
{
width
:
'
100%
'
},
placeholder
:
t
(
'
sys.lock.placeholder
'
),
},
rules
:
[{
required
:
true
}],
},
],
});
const
realName
=
computed
(()
=>
{
const
{
realName
}
=
userStore
.
getUserInfoState
||
{};
return
realName
;
});
const
getIsNotPwd
=
computed
(()
=>
{
if
(
!
appStore
.
getLockInfo
)
{
return
true
;
}
return
appStore
.
getLockInfo
.
pwd
===
undefined
;
});
/**
* @description: unLock
*/
async
function
unLock
(
valid
=
true
)
{
let
password
=
''
;
if
(
valid
)
{
try
{
const
values
=
(
await
validateFields
())
as
any
;
password
=
values
.
password
;
}
catch
(
error
)
{
return
;
}
async
function
unLock
()
{
if
(
!
passwordRef
.
value
)
{
return
;
}
let
password
=
passwordRef
.
value
;
try
{
loadingRef
.
value
=
true
;
const
res
=
await
appStore
.
unLockAction
({
password
,
vali
d
});
const
res
=
await
lockStore
.
unLockAction
({
passwor
d
});
errMsgRef
.
value
=
!
res
;
}
finally
{
loadingRef
.
value
=
false
;
...
...
@@ -88,67 +111,190 @@
function
goLogin
()
{
userStore
.
loginOut
(
true
);
appStore
.
resetLockInfo
();
lockStore
.
resetLockInfo
();
}
function
handleShowForm
(
show
=
false
)
{
showDate
.
value
=
show
;
}
return
{
register
,
getIsNotPwd
,
goLogin
,
realName
,
unLock
,
errMsgRef
,
loadingRef
,
t
,
prefixCls
,
showDate
,
password
:
passwordRef
,
handleShowForm
,
...
state
,
};
},
});
</
script
>
<
style
lang=
"less"
scoped
>
@import (reference) '../../../design/index.less';
@prefix-cls: ~'@{namespace}-lock-page';
.
lock-page
{
.
@{prefix-cls}
{
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index:
999999
;
z-index:
3000
;
display: flex;
width: 100vw;
height: 100vh;
background: url(../../../assets/images/lock-page.jpg) no-repeat
;
background
-size: 100% 100%
;
// background: rgba(23, 27, 41)
;
background
: #000
;
align-items: center;
justify-content: flex-end;
justify-content: center;
&__unlock {
position: absolute;
top: 0;
left: 50%;
display: flex;
height: 50px;
padding-top: 20px;
font-size: 18px;
color: #fff;
cursor: pointer;
transform: translate(-50%, 0);
flex-direction: column;
align-items: center;
justify-content: space-between;
transition: all 0.3s;
}
&__date {
display: flex;
width: 100vw;
height: 100vh;
align-items: center;
justify-content: center;
}
&__
entry
{
&__
hour
{
position: relative;
width: 400px;
// height: 260px;
padding: 80px 50px 50px 50px;
margin-right: 50px;
background: #fff;
border-radius: 6px;
margin-right: 80px;
.meridiem {
position: absolute;
top: 20px;
left: 20px;
font-size: 26px;
}
@media (max-width: @screen-xs) {
margin-right: 20px;
}
}
&__header {
&__hour,
&__minute {
display: flex;
width: 40%;
height: 74%;
// font-size: 50em;
font-weight: 700;
color: #bababa;
background: #141313;
border-radius: 30px;
justify-content: center;
align-items: center;
// .respond-to(large-only, { font-size: 25em;});
// .respond-to(large-only, { font-size: 30em;});
@media (min-width: @screen-xxxl-min) {
font-size: 46em;
}
@media (min-width: @screen-xl-max) and (max-width: @screen-xxl-max) {
font-size: 38em;
}
@media (min-width: @screen-lg-max) and (max-width: @screen-xl-max) {
font-size: 30em;
}
@media (min-width: @screen-md-max) and (max-width: @screen-lg-max) {
font-size: 23em;
}
@media (min-width: @screen-sm-max) and (max-width: @screen-md-max) {
font-size: 19em;
}
@media (min-width: @screen-xs-max) and (max-width: @screen-sm-max) {
font-size: 13em;
}
@media (max-width: @screen-xs) {
height: 50%;
font-size: 6em;
border-radius: 20px;
}
}
&__footer-date {
position: absolute;
top: -35px;
left: calc(50% - 45px);
width: auto;
text-align: center;
bottom: 20px;
left: 50%;
font-family: helvetica;
color: #bababa;
transform: translate(-50%, 0);
&-img {
width: 70px;
border-radius: 50%;
.time {
font-size: 50px;
.meridiem {
font-size: 32px;
}
}
&-nam
e {
margin-top: 5
px;
.dat
e {
font-size: 26
px;
}
}
&__footer {
text-align: center;
&-entry {
position: absolute;
top: 0;
left: 0;
display: flex;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(10px);
justify-content: center;
align-items: center;
&-content {
width: 260px;
}
&__header {
text-align: center;
&-img {
width: 70px;
border-radius: 50%;
}
&-name {
margin-top: 5px;
font-weight: 500;
color: #bababa;
}
}
&__err-msg {
display: inline-block;
margin-top: 10px;
color: @error-color;
}
&__footer {
display: flex;
justify-content: space-between;
}
}
}
</
style
>
src/views/sys/lock/useNow.ts
0 → 100644
浏览文件 @
4ce1d526
import
moment
from
'
moment
'
;
import
{
reactive
,
toRefs
}
from
'
vue
'
;
import
{
tryOnMounted
,
tryOnUnmounted
}
from
'
/@/utils/helper/vueHelper
'
;
import
{
useLocaleSetting
}
from
'
/@/hooks/setting/useLocaleSetting
'
;
export
function
useNow
(
immediate
=
true
)
{
const
{
getLang
}
=
useLocaleSetting
();
const
localData
=
moment
.
localeData
(
getLang
.
value
);
let
timer
:
IntervalHandle
;
const
state
=
reactive
({
year
:
0
,
month
:
0
,
week
:
''
,
day
:
0
,
hour
:
''
,
minute
:
''
,
second
:
0
,
meridiem
:
''
,
});
const
update
=
()
=>
{
const
now
=
moment
();
const
h
=
now
.
format
(
'
HH
'
);
const
m
=
now
.
format
(
'
mm
'
);
const
s
=
now
.
get
(
'
s
'
);
state
.
year
=
now
.
get
(
'
y
'
);
state
.
month
=
now
.
get
(
'
M
'
);
state
.
week
=
localData
.
weekdays
()[
now
.
day
()];
state
.
day
=
now
.
get
(
'
D
'
);
state
.
hour
=
h
;
state
.
minute
=
m
;
state
.
second
=
s
;
state
.
meridiem
=
localData
.
meridiem
(
Number
(
h
),
Number
(
h
),
true
);
};
function
start
()
{
update
();
clearInterval
(
timer
);
timer
=
setInterval
(()
=>
update
(),
1000
);
}
function
stop
()
{
clearInterval
(
timer
);
}
tryOnMounted
(()
=>
{
immediate
&&
start
();
});
tryOnUnmounted
(()
=>
{
stop
();
});
return
{
...
toRefs
(
state
),
start
,
stop
,
};
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录