index.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <script lang="tsx">
  2. import { defineComponent, ref, unref, reactive, watch } from 'vue'
  3. import { useRouter } from 'vue-router'
  4. import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router'
  5. import { usePermissionStore } from '@/store/modules/permission'
  6. import { useAppStore } from '@/store/modules/app'
  7. import { ElNotification } from 'element-plus'
  8. import { useCache } from '@/hooks/web/useCache'
  9. const { wsCache } = useCache()
  10. interface FormModule {
  11. userName: string
  12. passWord: string
  13. }
  14. export default defineComponent({
  15. name: 'Login',
  16. setup() {
  17. const appStore = useAppStore()
  18. const permissionStore = usePermissionStore()
  19. const { currentRoute, addRoute, push } = useRouter()
  20. const loginForm = ref<Nullable<HTMLElement>>(null)
  21. const loading = ref<boolean>(false)
  22. const redirect = ref<string>('')
  23. const form = reactive<FormModule>({
  24. userName: '',
  25. passWord: ''
  26. })
  27. const rules = reactive<IObj>({
  28. userName: [{ required: true, message: '请输入账号' }],
  29. passWord: [{ required: true, message: '请输入密码' }]
  30. })
  31. watch(
  32. () => currentRoute.value,
  33. (route: RouteLocationNormalizedLoaded) => {
  34. redirect.value = route?.query?.redirect as string
  35. },
  36. {
  37. immediate: true
  38. }
  39. )
  40. async function login(): Promise<void> {
  41. const formWrap = unref(loginForm) as any
  42. if (!formWrap) return
  43. formWrap.validate(async (valid: boolean) => {
  44. if (valid) {
  45. try {
  46. loading.value = true
  47. // 模拟登录接口之后返回角色信息
  48. wsCache.set(appStore.getUserInfo, form)
  49. permissionStore.generateRoutes().then(() => {
  50. permissionStore.getAddRouters.forEach(async (route) => {
  51. await addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
  52. })
  53. permissionStore.setIsAddRouters(true)
  54. push({ path: redirect.value || '/' })
  55. })
  56. } finally {
  57. loading.value = false
  58. }
  59. } else {
  60. console.log('error submit!!')
  61. return false
  62. }
  63. })
  64. }
  65. ElNotification({
  66. title: '提示',
  67. message: '账号 admin 为 前端 控制路由权限,账号 test 为 后端 控制路由权限。密码与账号相同',
  68. duration: 60000
  69. })
  70. return () => {
  71. return (
  72. <div
  73. class="login-wrap"
  74. onKeydown={(event) => {
  75. if (event.code !== 'Enter') return
  76. // 停止事件传播
  77. event.stopPropagation()
  78. // 阻止该元素默认的 keyup 事件
  79. event.preventDefault()
  80. login()
  81. }}
  82. >
  83. <div class="login-con">
  84. <el-card class="box-card">
  85. {{
  86. header: () => <span class="login--header">登录</span>,
  87. default: () => (
  88. <el-form ref={loginForm} model={form} rules={rules} class="login-form">
  89. <el-form-item prop="userName">
  90. <el-input
  91. v-model={form.userName}
  92. placeholder="请输入账号 admin or test"
  93. class="form--input"
  94. >
  95. {{
  96. prefix: () => (
  97. <span class="svg-container">
  98. <svg-icon icon-class="user" />
  99. </span>
  100. )
  101. }}
  102. </el-input>
  103. </el-form-item>
  104. <el-form-item prop="passWord">
  105. <el-input
  106. v-model={form.passWord}
  107. show-password={true}
  108. minlength={3}
  109. maxlength={18}
  110. placeholder="请输入密码 admin or test"
  111. class="form--input"
  112. >
  113. {{
  114. prefix: () => (
  115. <span class="svg-container">
  116. <svg-icon icon-class="password" />
  117. </span>
  118. )
  119. }}
  120. </el-input>
  121. </el-form-item>
  122. <el-form-item>
  123. <el-button
  124. loading={loading.value}
  125. type="primary"
  126. class="login--button"
  127. onClick={login}
  128. >
  129. 登录
  130. </el-button>
  131. </el-form-item>
  132. </el-form>
  133. )
  134. }}
  135. </el-card>
  136. </div>
  137. </div>
  138. )
  139. }
  140. }
  141. })
  142. </script>
  143. <style lang="less" scoped>
  144. .login-wrap {
  145. position: relative;
  146. width: 100%;
  147. height: 100%;
  148. background-image: url('@/assets/img/login-bg.jpg');
  149. background-position: center;
  150. background-size: cover;
  151. .box-card {
  152. width: 400px;
  153. .login--header {
  154. font-size: 24px;
  155. font-weight: 600;
  156. }
  157. .svg-container {
  158. display: inline-block;
  159. width: 30px;
  160. color: #889aa4;
  161. vertical-align: middle;
  162. }
  163. .form--input {
  164. width: 100%;
  165. :deep(.el-input__inner) {
  166. padding-left: 40px;
  167. }
  168. }
  169. .login--button {
  170. width: 100%;
  171. }
  172. }
  173. .login-con {
  174. position: absolute;
  175. top: 50%;
  176. right: 160px;
  177. transform: translateY(-60%);
  178. }
  179. }
  180. </style>