index.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <script lang="ts" setup>
  2. import { useUserStore } from '@/store/modules/user'
  3. import { useSettingsStore } from '@/store/modules/settings'
  4. import { translate } from '@/i18n'
  5. import { toLoginRoute } from '@/utils/routes'
  6. import { getUnlock } from './api/index'
  7. import { ElMessage } from 'element-plus'
  8. import { VabRoute } from '/#/router'
  9. const vFocus: any = {
  10. mounted(el: HTMLElement) {
  11. el.querySelector('input')?.focus()
  12. },
  13. }
  14. const userStore = useUserStore()
  15. const { avatar, id, username } = storeToRefs(userStore)
  16. const { logout } = userStore
  17. const settingsStore = useSettingsStore()
  18. const { theme, lock, title } = storeToRefs(settingsStore)
  19. const { handleLock: _handleLock, handleUnLock: _handleUnLock } = settingsStore
  20. const route: VabRoute = useRoute()
  21. const router = useRouter()
  22. const background = ref(
  23. 'https://fastly.jsdelivr.net/gh/' +
  24. 'chuzh' +
  25. 'ixin/image/vab-im' +
  26. 'age-lock/' +
  27. `${Math.round(Math.random() * 31)}.jpg`
  28. )
  29. const randomBackground = () => {
  30. background.value =
  31. 'https://fastly.jsdelivr.net/gh/' +
  32. 'chuzh' +
  33. 'ixin/image/vab-im' +
  34. 'age-lock/' +
  35. `${Math.round(Math.random() * 31)}.jpg`
  36. }
  37. const validatePass = (rule: any, value: string, callback: any) => {
  38. if (value === '' || value !== '123456') {
  39. callback(new Error('请输入正确的密码'))
  40. } else {
  41. callback()
  42. }
  43. }
  44. const formRef = ref()
  45. const lockpwdStatus = ref()
  46. const form = ref({
  47. password: '',
  48. })
  49. const rules = {
  50. password: [{ required: true, trigger: 'blur', message: '请输入密码' }],
  51. }
  52. let lockIcon = true
  53. const handleUnLock = () => {
  54. formRef.value.validate(async (valid: boolean) => {
  55. if (valid) {
  56. lockIcon = false
  57. setTimeout(async () => {
  58. await unLockApi()
  59. if (!lockpwdStatus.value) {
  60. ElMessage.error('密码错误,请重新输入!')
  61. return
  62. }
  63. await _handleUnLock()
  64. lockIcon = true
  65. form.value.password = ''
  66. await randomBackground()
  67. const el = document.querySelector('.vab-side-bar') as HTMLElement
  68. if (el) el.removeAttribute('style')
  69. }, 500)
  70. }
  71. })
  72. }
  73. //返回登录页
  74. const backLogin = async () => {
  75. await _handleUnLock()
  76. await logout()
  77. localStorage.removeItem('dictsSetting')
  78. localStorage.removeItem('factory')
  79. localStorage.removeItem('factory_list')
  80. await router.push(toLoginRoute(route.fullPath))
  81. }
  82. //解锁接口
  83. const unLockApi = async () => {
  84. const data = {
  85. id: id.value,
  86. password: btoa(form.value.password),
  87. }
  88. await getUnlock(data).then((res) => {
  89. lockpwdStatus.value = res.data.status
  90. })
  91. }
  92. const handleLock = () => {
  93. _handleLock()
  94. const el = document.querySelector('.vab-side-bar') as HTMLElement
  95. if (el) el.style.display = 'none'
  96. }
  97. </script>
  98. <template>
  99. <vab-icon v-if="theme.showLock" icon="lock-line" @click="handleLock" />
  100. <transition v-if="theme.showLock" mode="out-in" name="fade-transform">
  101. <div v-if="lock" class="vab-screen-lock">
  102. <div
  103. class="vab-screen-lock-background"
  104. :style="{
  105. background: `fixed url(${background}) center`,
  106. backgroundSize: '100% 100%',
  107. filter: 'blur(10px)',
  108. }"
  109. ></div>
  110. <div class="vab-screen-lock-content">
  111. <div class="vab-screen-lock-content-title">
  112. <el-avatar :size="100" :src="avatar" />
  113. <div>{{ username }}</div>
  114. <vab-icon :icon="lockIcon ? 'lock-line' : 'lock-unlock-line'" />
  115. {{ title }} {{ translate('屏幕已锁定') }}
  116. </div>
  117. <div class="vab-screen-lock-content-form">
  118. <el-form ref="formRef" :model="form" :rules="rules" @submit.prevent>
  119. <el-form-item label="" :label-width="0" prop="password">
  120. <el-input
  121. v-model="form.password"
  122. v-focus
  123. autocomplete="off"
  124. placeholder="请输入登录密码"
  125. show-password
  126. style="width: 80%; padding-right: 10px"
  127. type="password"
  128. >
  129. <!-- <template #suffix>
  130. </template> -->
  131. </el-input>
  132. <el-button
  133. native-type="submit"
  134. style="height: 42px; line-height: 42px"
  135. type="primary"
  136. @click="handleUnLock"
  137. >
  138. <vab-icon :icon="lockIcon ? 'lock-line' : 'lock-unlock-line'" />
  139. {{ translate('解锁') }}
  140. </el-button>
  141. </el-form-item>
  142. </el-form>
  143. </div>
  144. <span @click="randomBackground">{{ translate('切换壁纸') }}</span>
  145. <span style="margin-left: 30px" @click="backLogin">返回登录页</span>
  146. </div>
  147. </div>
  148. </transition>
  149. </template>
  150. <style lang="scss" scoped>
  151. .vab-screen-lock {
  152. position: fixed;
  153. top: 0;
  154. right: 0;
  155. bottom: 0;
  156. left: 0;
  157. z-index: $base-z-index;
  158. // z-index: 9999999;
  159. display: flex;
  160. flex-wrap: wrap;
  161. align-items: center;
  162. justify-content: center;
  163. font-weight: bold;
  164. background-color: rgba(255, 255, 255, 0.6);
  165. transition: $base-transition;
  166. backdrop-filter: blur(10px);
  167. &-background {
  168. position: absolute;
  169. top: 0;
  170. right: 0;
  171. bottom: 0;
  172. left: 0;
  173. z-index: $base-z-index - 1;
  174. }
  175. &-content {
  176. z-index: $base-z-index;
  177. padding: 40px 95px 40px 95px;
  178. color: #252a30;
  179. text-align: center;
  180. background: rgba(255, 255, 255, 0.6);
  181. backdrop-filter: blur(10px);
  182. border-radius: 15px;
  183. > span {
  184. font-size: $base-font-size-small;
  185. cursor: pointer;
  186. }
  187. &-title {
  188. line-height: 50px;
  189. color: #252a30;
  190. text-align: center;
  191. .ri-lock-line,
  192. .ri-lock-unlock-line {
  193. display: block;
  194. margin: auto !important;
  195. font-size: 30px;
  196. color: #252a30 !important;
  197. transition: $base-transition;
  198. }
  199. }
  200. &-form {
  201. :deep() {
  202. .el-input__inner {
  203. width: 280px;
  204. height: 40px;
  205. line-height: 40px;
  206. }
  207. .el-input__wrapper {
  208. // padding-right: 0;
  209. .el-input__suffix {
  210. right: 0;
  211. .el-button {
  212. height: 40px;
  213. line-height: 40px;
  214. border-top-left-radius: 0;
  215. border-bottom-left-radius: 0;
  216. i {
  217. margin-left: 0 !important;
  218. }
  219. }
  220. .el-input__validateIcon {
  221. display: none;
  222. }
  223. }
  224. }
  225. }
  226. }
  227. }
  228. @media (max-width: 576px) {
  229. .vab-screen-lock-content {
  230. width: auto !important;
  231. margin: 5vw;
  232. }
  233. }
  234. }
  235. </style>