index.vue 7.3 KB

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