index.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <template>
  2. <div class="grid full login-view">
  3. <div class="login-modal">
  4. <div class="p-l-large login-modal-header">欢迎登录</div>
  5. <div class="login-modal-content">
  6. <base-form
  7. ref="formRef"
  8. :model="loginModel"
  9. :disabled="loading"
  10. :items="formItems"
  11. :rules="loginRules"
  12. size="large"
  13. >
  14. <el-button type="primary" class="full-w m-t-base" :loading="loading" @click="onSubmit"> 立即登录 </el-button>
  15. </base-form>
  16. </div>
  17. </div>
  18. </div>
  19. </template>
  20. <script setup lang="ts" name="Login">
  21. import { reactive, shallowRef, ref } from 'vue'
  22. import { useRouter } from 'vue-router'
  23. import { ElButton } from 'element-plus'
  24. import BaseForm from '@/components/element/BaseForm.vue'
  25. import useMainStore from '@/store/main'
  26. import useMainLayoutStore from '@/store/layout'
  27. import useFetch from '@/hooks/useFetch'
  28. import useForm from '@/hooks/useForm'
  29. import { sessionStorage } from '@/plugins/storage'
  30. import type { EpFormItem, EpFormRules } from 'global-type'
  31. import type { ExtractApiParams, ExtractApiResponse } from 'api-type'
  32. const { replace } = useRouter()
  33. const mainStore = useMainStore()
  34. const mainLayoutStore = useMainLayoutStore()
  35. const { loading, fetch: login } = useFetch('userLogin')
  36. const { formRef, elFormRef } = useForm()
  37. const loginModel = reactive<ExtractApiParams<'userLogin'>>({ loginName: '', password: '' })
  38. const loginRules: EpFormRules = {
  39. loginName: [{ required: true, message: '请输入登录账号' }],
  40. password: [{ required: true, message: '请输入登录密码' }],
  41. }
  42. const formItems = shallowRef<EpFormItem[]>([
  43. {
  44. slotType: 'input',
  45. prop: 'loginName',
  46. slot: {
  47. placeholder: '请输入登录账号',
  48. },
  49. },
  50. {
  51. slotType: 'input',
  52. prop: 'password',
  53. slot: {
  54. type: 'password',
  55. placeholder: '请输入登录密码',
  56. clearable: true,
  57. showPassword: true,
  58. onKeydown(event) {
  59. if ((event as KeyboardEvent).key === 'Enter') {
  60. onSubmit()
  61. }
  62. },
  63. },
  64. },
  65. ])
  66. async function onSubmit() {
  67. if (!elFormRef?.value) {
  68. return
  69. }
  70. try {
  71. await elFormRef.value.validate()
  72. const loginResult = await login(loginModel)
  73. loginSuccess(loginResult)
  74. } catch (error) {
  75. console.log(error)
  76. }
  77. }
  78. function loginSuccess(loginInfo: ExtractApiResponse<'userLogin'>) {
  79. /** sessionStorage 缓存login result */
  80. sessionStorage.set('LOGIN_RESULT', loginInfo)
  81. /** pinia store 存储 login result */
  82. mainStore.loginInfo = loginInfo
  83. mainLayoutStore.getRenderMenuList()
  84. /**
  85. * 超级管理员每次登录完成之后需要选择考试批次
  86. * 其它角色如果是首次登录,需要去设置名称.
  87. * 否则大小组长进入监控首页, 评卷员进入评卷首页
  88. */
  89. if (loginInfo.role !== 'ADMIN') {
  90. if (loginInfo.name) {
  91. mainStore.getMyUserInfo()
  92. }
  93. replace({
  94. name: !loginInfo.name ? 'InitUserName' : loginInfo.role === 'MARKER' ? 'MarkingMark' : 'AnalysisMonitoring',
  95. })
  96. } else {
  97. replace({ name: 'CheckExam' })
  98. }
  99. }
  100. </script>
  101. <style scoped lang="scss">
  102. .login-view {
  103. place-items: center;
  104. .login-modal {
  105. width: 480px;
  106. height: 416px;
  107. background: $LoginModalBg;
  108. border-radius: $LoginModalRadius;
  109. overflow: hidden;
  110. .login-modal-header {
  111. height: $LoginModalHeaderHeight;
  112. line-height: $LoginModalHeaderHeight;
  113. background: $LoginModalHeaderBg;
  114. font-size: $LoginModalHeaderFontSize;
  115. font-weight: normal;
  116. color: $LoginModalHeaderFontColor;
  117. }
  118. .login-modal-content {
  119. height: 336px;
  120. padding: 52px 80px;
  121. }
  122. }
  123. }
  124. </style>