潘志宝
9 天以前 273cb85713ed1d194eb4cc245daf29cd33be89e7
提交 | 用户 | 时间
820397 1 <script lang="ts" setup>
H 2 import { resetRouter } from '@/router'
3 import { deleteUserCache } from '@/hooks/web/useCache'
4 import { useLockStore } from '@/store/modules/lock'
5 import { useNow } from '@/hooks/web/useNow'
6 import { useDesign } from '@/hooks/web/useDesign'
7 import { useTagsViewStore } from '@/store/modules/tagsView'
8 import { useUserStore } from '@/store/modules/user'
9 import avatarImg from '@/assets/imgs/avatar.gif'
10
11 const tagsViewStore = useTagsViewStore()
12
13 const { replace } = useRouter()
14
15 const userStore = useUserStore()
16
17 const password = ref('')
18 const loading = ref(false)
19 const errMsg = ref(false)
20 const showDate = ref(true)
21
22 const { getPrefixCls } = useDesign()
23 const prefixCls = getPrefixCls('lock-page')
24
3e359e 25 const avatar = computed(() => userStore.user.avatar || avatarImg)
820397 26 const userName = computed(() => userStore.user.nickname ?? 'Admin')
H 27
28 const lockStore = useLockStore()
29
30 const { hour, month, minute, meridiem, year, day, week } = useNow(true)
31
32 const { t } = useI18n()
33
34 // 解锁
35 async function unLock() {
36   if (!password.value) {
37     return
38   }
39   let pwd = password.value
40   try {
41     loading.value = true
42     const res = await lockStore.unLock(pwd)
43     errMsg.value = !res
44   } finally {
45     loading.value = false
46   }
47 }
48
49 // 返回登录
50 async function goLogin() {
51   await userStore.loginOut().catch(() => {})
52   // 登出后清理
53   deleteUserCache() // 清空用户缓存
54   tagsViewStore.delAllViews()
55   // resetRouter() // 重置静态路由表
56   lockStore.resetLockInfo()
57   replace('/login')
58 }
59
60 function handleShowForm(show = false) {
61   showDate.value = show
62 }
63 </script>
64
65 <template>
66   <div
67     :class="prefixCls"
68     class="fixed inset-0 flex h-screen w-screen bg-black items-center justify-center"
69   >
70     <div
71       :class="`${prefixCls}__unlock`"
72       class="absolute top-0 left-1/2 flex pt-5 h-16 items-center justify-center sm:text-md xl:text-xl text-white flex-col cursor-pointer transform translate-x-1/2"
73       @click="handleShowForm(false)"
74       v-show="showDate"
75     >
76       <Icon icon="ep:lock" />
77       <span>{{ t('lock.unlock') }}</span>
78     </div>
79
80     <div class="flex w-screen h-screen justify-center items-center">
81       <div :class="`${prefixCls}__hour`" class="relative mr-5 md:mr-20 w-2/5 h-2/5 md:h-4/5">
82         <span>{{ hour }}</span>
83         <span class="meridiem absolute left-5 top-5 text-md xl:text-xl" v-show="showDate">
84           {{ meridiem }}
85         </span>
86       </div>
87       <div :class="`${prefixCls}__minute w-2/5 h-2/5 md:h-4/5 `">
88         <span> {{ minute }}</span>
89       </div>
90     </div>
91     <transition name="fade-slide">
92       <div :class="`${prefixCls}-entry`" v-show="!showDate">
93         <div :class="`${prefixCls}-entry-content`">
94           <div class="flex flex-col items-center">
95             <img :src="avatar" alt="" class="w-70px h-70px rounded-[50%]" />
96             <span class="text-14px my-10px text-[var(--logo-title-text-color)]">
97               {{ userName }}
98             </span>
99           </div>
100           <ElInput
101             type="password"
102             :placeholder="t('lock.placeholder')"
103             class="enter-x"
104             v-model="password"
105           />
106           <span :class="`text-14px ${prefixCls}-entry__err-msg enter-x`" v-if="errMsg">
107             {{ t('lock.message') }}
108           </span>
109           <div :class="`${prefixCls}-entry__footer enter-x`">
110             <ElButton
111               type="primary"
112               size="small"
113               class="mt-2 mr-2 enter-x"
114               link
115               :disabled="loading"
116               @click="handleShowForm(true)"
117             >
118               {{ t('common.back') }}
119             </ElButton>
120             <ElButton
121               type="primary"
122               size="small"
123               class="mt-2 mr-2 enter-x"
124               link
125               :disabled="loading"
126               @click="goLogin"
127             >
128               {{ t('lock.backToLogin') }}
129             </ElButton>
130             <ElButton
131               type="primary"
132               class="mt-2"
133               size="small"
134               link
135               @click="unLock()"
136               :disabled="loading"
137             >
138               {{ t('lock.entrySystem') }}
139             </ElButton>
140           </div>
141         </div>
142       </div>
143     </transition>
144
145     <div class="absolute bottom-5 w-full text-gray-300 xl:text-xl 2xl:text-3xl text-center enter-y">
146       <div class="text-5xl mb-4 enter-x" v-show="!showDate">
147         {{ hour }}:{{ minute }} <span class="text-3xl">{{ meridiem }}</span>
148       </div>
149       <div class="text-2xl">{{ year }}/{{ month }}/{{ day }} {{ week }}</div>
150     </div>
151   </div>
152 </template>
153
154 <style lang="scss" scoped>
155 $prefix-cls: '#{$namespace}-lock-page';
156
157 // Small screen / tablet
158 $screen-sm: 576px;
159
160 // Medium screen / desktop
161 $screen-md: 768px;
162
163 // Large screen / wide desktop
164 $screen-lg: 992px;
165
166 // Extra large screen / full hd
167 $screen-xl: 1200px;
168
169 // Extra extra large screen / large desktop
170 $screen-2xl: 1600px;
171
172 $error-color: #ed6f6f;
173
174 .#{$prefix-cls} {
175   z-index: 3000;
176
177   &__unlock {
178     transform: translate(-50%, 0);
179   }
180
181   &__hour,
182   &__minute {
183     display: flex;
184     font-weight: 700;
185     color: #bababa;
186     background-color: #141313;
187     border-radius: 30px;
188     justify-content: center;
189     align-items: center;
190
191     @media screen and (max-width: $screen-md) {
192       span:not(.meridiem) {
193         font-size: 160px;
194       }
195     }
196
197     @media screen and (min-width: $screen-md) {
198       span:not(.meridiem) {
199         font-size: 160px;
200       }
201     }
202
203     @media screen and (max-width: $screen-sm) {
204       span:not(.meridiem) {
205         font-size: 90px;
206       }
207     }
208     @media screen and (min-width: $screen-lg) {
209       span:not(.meridiem) {
210         font-size: 220px;
211       }
212     }
213
214     @media screen and (min-width: $screen-xl) {
215       span:not(.meridiem) {
216         font-size: 260px;
217       }
218     }
219     @media screen and (min-width: $screen-2xl) {
220       span:not(.meridiem) {
221         font-size: 320px;
222       }
223     }
224   }
225
226   &-entry {
227     position: absolute;
228     top: 0;
229     left: 0;
230     display: flex;
231     width: 100%;
232     height: 100%;
233     background-color: rgba(0, 0, 0, 0.5);
234     backdrop-filter: blur(8px);
235     justify-content: center;
236     align-items: center;
237
238     &-content {
239       width: 260px;
240     }
241
242     &__header {
243       text-align: center;
244
245       &-img {
246         width: 70px;
247         margin: 0 auto;
248         border-radius: 50%;
249       }
250
251       &-name {
252         margin-top: 5px;
253         font-weight: 500;
254         color: #bababa;
255       }
256     }
257
258     &__err-msg {
259       display: inline-block;
260       margin-top: 10px;
261       color: $error-color;
262     }
263
264     &__footer {
265       display: flex;
266       justify-content: space-between;
267     }
268   }
269 }
270 </style>