LockPage.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <template>
  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. <div :class="`${prefixCls}__date`">
  8. <div :class="`${prefixCls}__hour`">
  9. {{ hour }}
  10. <span class="meridiem" v-show="showDate">{{ meridiem }}</span>
  11. </div>
  12. <div :class="`${prefixCls}__minute`">
  13. {{ minute }}
  14. </div>
  15. </div>
  16. <transition name="fade-slide">
  17. <div :class="`${prefixCls}-entry`" v-show="!showDate">
  18. <div :class="`${prefixCls}-entry-content`">
  19. <div :class="`${prefixCls}-entry__header`">
  20. <img :src="headerImg" :class="`${prefixCls}-entry__header-img`" />
  21. <p :class="`${prefixCls}-entry__header-name`">
  22. {{ realName }}
  23. </p>
  24. </div>
  25. <InputPassword :placeholder="t('sys.lock.placeholder')" v-model:value="password" />
  26. <span :class="`${prefixCls}-entry__err-msg`" v-if="errMsgRef">
  27. {{ t('sys.lock.alert') }}
  28. </span>
  29. <div :class="`${prefixCls}-entry__footer`">
  30. <a-button
  31. type="link"
  32. size="small"
  33. class="mt-2 mr-2"
  34. :disabled="loadingRef"
  35. @click="handleShowForm(true)"
  36. >
  37. {{ t('common.back') }}
  38. </a-button>
  39. <a-button
  40. type="link"
  41. size="small"
  42. class="mt-2 mr-2"
  43. :disabled="loadingRef"
  44. @click="goLogin"
  45. >
  46. {{ t('sys.lock.backToLogin') }}
  47. </a-button>
  48. <a-button class="mt-2" type="link" size="small" @click="unLock()" :loading="loadingRef">
  49. {{ t('sys.lock.entry') }}
  50. </a-button>
  51. </div>
  52. </div>
  53. </div>
  54. </transition>
  55. <div :class="`${prefixCls}__footer-date`">
  56. <div class="time" v-show="!showDate">
  57. {{ hour }}:{{ minute }} <span class="meridiem">{{ meridiem }}</span>
  58. </div>
  59. <div class="date"> {{ year }}/{{ month }}/{{ day }} {{ week }} </div>
  60. </div>
  61. </div>
  62. </template>
  63. <script lang="ts">
  64. import { defineComponent, ref, computed } from 'vue';
  65. import { Input } from 'ant-design-vue';
  66. import { userStore } from '/@/store/modules/user';
  67. import { lockStore } from '/@/store/modules/lock';
  68. import { useI18n } from '/@/hooks/web/useI18n';
  69. import { useNow } from './useNow';
  70. import { useDesign } from '/@/hooks/web/useDesign';
  71. import { LockOutlined } from '@ant-design/icons-vue';
  72. import headerImg from '/@/assets/images/header.jpg';
  73. export default defineComponent({
  74. name: 'LockPage',
  75. components: { LockOutlined, InputPassword: Input.Password },
  76. setup() {
  77. const passwordRef = ref('');
  78. const loadingRef = ref(false);
  79. const errMsgRef = ref(false);
  80. const showDate = ref(true);
  81. const { prefixCls } = useDesign('lock-page');
  82. const { ...state } = useNow(true);
  83. const { t } = useI18n();
  84. const realName = computed(() => {
  85. const { realName } = userStore.getUserInfoState || {};
  86. return realName;
  87. });
  88. /**
  89. * @description: unLock
  90. */
  91. async function unLock() {
  92. if (!passwordRef.value) {
  93. return;
  94. }
  95. let password = passwordRef.value;
  96. try {
  97. loadingRef.value = true;
  98. const res = await lockStore.unLockAction({ password });
  99. errMsgRef.value = !res;
  100. } finally {
  101. loadingRef.value = false;
  102. }
  103. }
  104. function goLogin() {
  105. userStore.loginOut(true);
  106. lockStore.resetLockInfo();
  107. }
  108. function handleShowForm(show = false) {
  109. showDate.value = show;
  110. }
  111. return {
  112. goLogin,
  113. realName,
  114. unLock,
  115. errMsgRef,
  116. loadingRef,
  117. t,
  118. prefixCls,
  119. showDate,
  120. password: passwordRef,
  121. handleShowForm,
  122. headerImg,
  123. ...state,
  124. };
  125. },
  126. });
  127. </script>
  128. <style lang="less" scoped>
  129. @prefix-cls: ~'@{namespace}-lock-page';
  130. .@{prefix-cls} {
  131. position: fixed;
  132. top: 0;
  133. right: 0;
  134. bottom: 0;
  135. left: 0;
  136. z-index: @lock-page-z-index;
  137. display: flex;
  138. width: 100vw;
  139. height: 100vh;
  140. // background: rgba(23, 27, 41);
  141. background: #000;
  142. align-items: center;
  143. justify-content: center;
  144. &__unlock {
  145. position: absolute;
  146. top: 0;
  147. left: 50%;
  148. display: flex;
  149. height: 50px;
  150. padding-top: 20px;
  151. font-size: 18px;
  152. color: #fff;
  153. cursor: pointer;
  154. transform: translate(-50%, 0);
  155. flex-direction: column;
  156. align-items: center;
  157. justify-content: space-between;
  158. transition: all 0.3s;
  159. }
  160. &__date {
  161. display: flex;
  162. width: 100vw;
  163. height: 100vh;
  164. align-items: center;
  165. justify-content: center;
  166. }
  167. &__hour {
  168. position: relative;
  169. margin-right: 80px;
  170. .meridiem {
  171. position: absolute;
  172. top: 20px;
  173. left: 20px;
  174. font-size: 26px;
  175. }
  176. @media (max-width: @screen-xs) {
  177. margin-right: 20px;
  178. }
  179. }
  180. &__hour,
  181. &__minute {
  182. display: flex;
  183. width: 40%;
  184. height: 74%;
  185. font-weight: 700;
  186. color: #bababa;
  187. background: #141313;
  188. border-radius: 30px;
  189. justify-content: center;
  190. align-items: center;
  191. @media (min-width: @screen-xxxl-min) {
  192. font-size: 46em;
  193. }
  194. @media (min-width: @screen-xl-max) and (max-width: @screen-xxl-max) {
  195. font-size: 38em;
  196. }
  197. @media (min-width: @screen-lg-max) and (max-width: @screen-xl-max) {
  198. font-size: 30em;
  199. }
  200. @media (min-width: @screen-md-max) and (max-width: @screen-lg-max) {
  201. font-size: 23em;
  202. }
  203. @media (min-width: @screen-sm-max) and (max-width: @screen-md-max) {
  204. height: 50%;
  205. font-size: 12em;
  206. border-radius: 10px;
  207. .meridiem {
  208. font-size: 20px;
  209. }
  210. }
  211. @media (min-width: @screen-xs-max) and (max-width: @screen-sm-max) {
  212. font-size: 13em;
  213. }
  214. @media (max-width: @screen-xs) {
  215. height: 30%;
  216. font-size: 5em;
  217. border-radius: 10px;
  218. .meridiem {
  219. font-size: 14px;
  220. }
  221. }
  222. }
  223. &__footer-date {
  224. position: absolute;
  225. bottom: 20px;
  226. width: 100%;
  227. font-family: helvetica;
  228. color: #bababa;
  229. text-align: center;
  230. .time {
  231. font-size: 50px;
  232. .meridiem {
  233. font-size: 32px;
  234. }
  235. }
  236. .date {
  237. font-size: 26px;
  238. }
  239. }
  240. &-entry {
  241. position: absolute;
  242. top: 0;
  243. left: 0;
  244. display: flex;
  245. width: 100%;
  246. height: 100%;
  247. background: rgba(0, 0, 0, 0.5);
  248. backdrop-filter: blur(8px);
  249. justify-content: center;
  250. align-items: center;
  251. &-content {
  252. width: 260px;
  253. }
  254. &__header {
  255. text-align: center;
  256. &-img {
  257. width: 70px;
  258. border-radius: 50%;
  259. }
  260. &-name {
  261. margin-top: 5px;
  262. font-weight: 500;
  263. color: #bababa;
  264. }
  265. }
  266. &__err-msg {
  267. display: inline-block;
  268. margin-top: 10px;
  269. color: @error-color;
  270. }
  271. &__footer {
  272. display: flex;
  273. justify-content: space-between;
  274. }
  275. }
  276. }
  277. </style>