Skip to content

Commit f8580fd

Browse files
committed
✨ 2023-05-10:feat: 新增锁屏功能
1 parent 4e39c11 commit f8580fd

File tree

13 files changed

+570
-3
lines changed

13 files changed

+570
-3
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"mitt": "^3.0.1",
5656
"nprogress": "^0.2.0",
5757
"pinia": "^2.1.7",
58+
"pinia-plugin-persist": "^1.0.0",
5859
"qrcode": "^1.5.3",
5960
"qs": "^6.11.2",
6061
"steady-xml": "^0.1.0",

src/assets/imgs/avatar.jpg

6.12 KB
Loading

src/components/Editor/src/Editor.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ defineExpose({
185185
<Toolbar
186186
:editor="editorRef"
187187
:editorId="editorId"
188-
class="border-0 b-b-1 border-[var(--el-border-color)] border-solid"
188+
class="border-0 b-b-1 border-solid border-[var(--tags-view-border-color)]"
189189
/>
190190
<!-- 编辑器 -->
191191
<Editor

src/layout/components/UserInfo/src/UserInfo.vue

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import avatarImg from '@/assets/imgs/avatar.gif'
55
import { useDesign } from '@/hooks/web/useDesign'
66
import { useTagsViewStore } from '@/store/modules/tagsView'
77
import { useUserStore } from '@/store/modules/user'
8+
import LockDialog from './components/LockDialog.vue'
9+
import LockPage from './components/LockPage.vue'
10+
import { useLockStore } from '@/store/modules/lock'
811
912
defineOptions({ name: 'UserInfo' })
1013
@@ -23,6 +26,14 @@ const prefixCls = getPrefixCls('user-info')
2326
const avatar = computed(() => userStore.user.avatar ?? avatarImg)
2427
const userName = computed(() => userStore.user.nickname ?? 'Admin')
2528
29+
// 锁定屏幕
30+
const lockStore = useLockStore()
31+
const getIsLock = computed(() => lockStore.getLockInfo?.isLock ?? false)
32+
const dialogVisible = ref<boolean>(false)
33+
const lockScreen = () => {
34+
dialogVisible.value = true
35+
}
36+
2637
const loginOut = async () => {
2738
try {
2839
await ElMessageBox.confirm(t('common.loginOutMessage'), t('common.reminder'), {
@@ -33,8 +44,7 @@ const loginOut = async () => {
3344
await userStore.loginOut()
3445
tagsViewStore.delAllViews()
3546
replace('/login?redirect=/index')
36-
}
37-
catch { }
47+
} catch {}
3848
}
3949
const toProfile = async () => {
4050
push('/user/profile')
@@ -62,11 +72,42 @@ const toDocument = () => {
6272
<Icon icon="ep:menu" />
6373
<div @click="toDocument">{{ t('common.document') }}</div>
6474
</ElDropdownItem>
75+
<ElDropdownItem divided>
76+
<Icon icon="ep:lock" />
77+
<div @click="lockScreen">{{ t('lock.lockScreen') }}</div>
78+
</ElDropdownItem>
6579
<ElDropdownItem divided @click="loginOut">
6680
<Icon icon="ep:switch-button" />
6781
<div>{{ t('common.loginOut') }}</div>
6882
</ElDropdownItem>
6983
</ElDropdownMenu>
7084
</template>
7185
</ElDropdown>
86+
87+
<LockDialog v-if="dialogVisible" v-model="dialogVisible" />
88+
89+
<teleport to="body">
90+
<transition name="fade-bottom" mode="out-in">
91+
<LockPage v-if="getIsLock" />
92+
</transition>
93+
</teleport>
7294
</template>
95+
96+
<style scoped lang="scss">
97+
.fade-bottom-enter-active,
98+
.fade-bottom-leave-active {
99+
transition:
100+
opacity 0.25s,
101+
transform 0.3s;
102+
}
103+
104+
.fade-bottom-enter-from {
105+
opacity: 0;
106+
transform: translateY(-10%);
107+
}
108+
109+
.fade-bottom-leave-to {
110+
opacity: 0;
111+
transform: translateY(10%);
112+
}
113+
</style>
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<script setup lang="ts">
2+
import { useValidator } from '@/hooks/web/useValidator'
3+
import { useDesign } from '@/hooks/web/useDesign'
4+
import { useLockStore } from '@/store/modules/lock'
5+
import avatarImg from '@/assets/imgs/avatar.gif'
6+
import { useUserStore } from '@/store/modules/user'
7+
8+
const { getPrefixCls } = useDesign()
9+
const prefixCls = getPrefixCls('lock-dialog')
10+
11+
const { required } = useValidator()
12+
13+
const { t } = useI18n()
14+
15+
const lockStore = useLockStore()
16+
17+
const props = defineProps({
18+
modelValue: {
19+
type: Boolean
20+
}
21+
})
22+
23+
const userStore = useUserStore()
24+
const avatar = computed(() => userStore.user.avatar ?? avatarImg)
25+
const userName = computed(() => userStore.user.nickname ?? 'Admin')
26+
27+
const emit = defineEmits(['update:modelValue'])
28+
29+
const dialogVisible = computed({
30+
get: () => props.modelValue,
31+
set: (val) => {
32+
console.log('set: ', val)
33+
emit('update:modelValue', val)
34+
}
35+
})
36+
37+
const dialogTitle = ref(t('lock.lockScreen'))
38+
39+
const formData = ref({
40+
password: undefined
41+
})
42+
const formRules = reactive({
43+
password: [required()]
44+
})
45+
46+
const formRef = ref() // 表单 Ref
47+
const handleLock = async () => {
48+
// 校验表单
49+
if (!formRef) return
50+
const valid = await formRef.value.validate()
51+
if (!valid) return
52+
// 提交请求
53+
dialogVisible.value = false
54+
lockStore.setLockInfo({
55+
...formData.value,
56+
isLock: true
57+
})
58+
}
59+
</script>
60+
61+
<template>
62+
<Dialog
63+
v-model="dialogVisible"
64+
width="500px"
65+
max-height="170px"
66+
:class="prefixCls"
67+
:title="dialogTitle"
68+
>
69+
<div class="flex flex-col items-center">
70+
<img :src="avatar" alt="" class="w-70px h-70px rounded-[50%]" />
71+
<span class="text-14px my-10px text-[var(--top-header-text-color)]">
72+
{{ userName }}
73+
</span>
74+
</div>
75+
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px">
76+
<el-form-item :label="t('lock.lockPassword')" prop="password">
77+
<el-input
78+
type="password"
79+
v-model="formData.password"
80+
:placeholder="'请输入' + t('lock.lockPassword')"
81+
clearable
82+
show-password
83+
/>
84+
</el-form-item>
85+
</el-form>
86+
<template #footer>
87+
<ElButton type="primary" @click="handleLock">{{ t('lock.lock') }}</ElButton>
88+
</template>
89+
</Dialog>
90+
</template>
91+
92+
<style lang="scss" scoped>
93+
:global(.v-lock-dialog) {
94+
@media (max-width: 767px) {
95+
max-width: calc(100vw - 16px);
96+
}
97+
}
98+
</style>

0 commit comments

Comments
 (0)