index.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <script setup lang="ts">
  2. import type { FormInstance, FormRules } from 'element-plus'
  3. import useUserStore from '@/store/modules/user'
  4. import { ref, useTemplateRef, onMounted } from 'vue'
  5. defineOptions({
  6. name: 'LoginForm',
  7. })
  8. const props = defineProps<{
  9. userName?: string
  10. passWord?: string
  11. captcha?: string
  12. system?: string
  13. captchaId?: number
  14. }>()
  15. const emits = defineEmits<{
  16. onLogin: [userName: string]
  17. onRegister: [userName: string]
  18. onResetPassword: [userName: string]
  19. }>()
  20. const userStore = useUserStore()
  21. const title = import.meta.env.VITE_APP_TITLE
  22. const baseurl = import.meta.env.VITE_APP_API_BASEURL
  23. const loading = ref(false)
  24. const remember = ref(false)
  25. const captchaSrc = ref("")//验证码图片
  26. // const system = ref([
  27. // 'PLATFORM',
  28. // 'JZG'
  29. // ])
  30. // 登录方式,default 账号密码登录,qrcode 扫码登录
  31. const type = ref('default')
  32. const formRef = useTemplateRef<FormInstance>('formRef')
  33. const form = ref({
  34. userName: props.userName ?? localStorage.login_account ?? '',
  35. passWord: '',
  36. captcha: "",
  37. system: "PLATFORM",
  38. captchaId: 0,
  39. })
  40. const rules = ref<FormRules>({
  41. userName: [
  42. { required: true, trigger: 'blur', message: '请输入用户名' },
  43. ],
  44. passWord: [
  45. { required: true, trigger: 'blur', message: '请输入密码' },
  46. { min: 6, max: 18, trigger: 'blur', message: '密码长度为6到18位' },
  47. ],
  48. })
  49. onMounted(() => {
  50. refreshCaptcha()
  51. })
  52. //获取验证码接口
  53. function refreshCaptcha() {
  54. let randnum = Math.floor(Math.random() * (1000000 - 1 + 1)) + 1;
  55. captchaSrc.value =
  56. baseurl +
  57. "/auth/captchaById?t=" +
  58. new Date().getTime() +
  59. "&captchaId=" +
  60. randnum;
  61. form.value.captchaId = randnum;
  62. }
  63. function handleLogin() {
  64. formRef.value?.validate((valid) => {
  65. if (valid) {
  66. loading.value = true
  67. userStore.login(form.value).then(() => {
  68. if (remember) {
  69. localStorage.setItem('login_account', form.value.userName)
  70. }
  71. else {
  72. localStorage.removeItem('login_account')
  73. }
  74. emits('onLogin', form.value.userName)
  75. }).finally(() => {
  76. loading.value = false
  77. refreshCaptcha();
  78. })
  79. }
  80. })
  81. }
  82. function testAccount(userName: string) {
  83. form.value.userName = userName
  84. form.value.passWord = '123456'
  85. handleLogin()
  86. }
  87. </script>
  88. <template>
  89. <ElForm ref="formRef" :model="form" :rules="rules" class="min-h-500px w-full flex-col-stretch-center p-12"
  90. size="large">
  91. <div class="mb-6">
  92. <HTabList v-model="type" :options="[
  93. { label: '账号密码登录', value: 'default' },
  94. { label: '扫码登录', value: 'qrcode' },
  95. ]" />
  96. </div>
  97. <template v-if="type === 'default'">
  98. <h3 class="mb-8 text-xl color-[var(--el-text-color-primary)] font-bold">
  99. 欢迎使用 {{ title }} ! 👋🏻
  100. </h3>
  101. <div>
  102. <ElFormItem prop="userName">
  103. <ElInput v-model="form.userName" placeholder="用户名" type="text" tabindex="1">
  104. <template #prefix>
  105. <SvgIcon name="i-ri:user-3-fill" />
  106. </template>
  107. </ElInput>
  108. </ElFormItem>
  109. <ElFormItem prop="passWord">
  110. <ElInput v-model="form.passWord" type="password" placeholder="密码" tabindex="2" show-password
  111. @keyup.enter="handleLogin">
  112. <template #prefix>
  113. <SvgIcon name="i-ri:lock-2-fill" />
  114. </template>
  115. </ElInput>
  116. </ElFormItem>
  117. <ElFormItem prop="captcha">
  118. <ElCol :md="14" :sm="14" :xs="14">
  119. <ElInput v-model="form.captcha" placeholder="验证码" type="text" tabindex="3">
  120. <template #prefix>
  121. <SvgIcon name="i-ri:user-3-fill" />
  122. </template>
  123. </ElInput>
  124. </ElCol>
  125. <ElCol :md="10" :sm="10" :xs="10" flex>
  126. <img style="width: 100%; height: 32px; margin-left: 20px;" class="pointer" :src="captchaSrc"
  127. @click="refreshCaptcha" />
  128. </ElCol>
  129. </ElFormItem>
  130. </div>
  131. <div class="mb-4 flex-center-between">
  132. <ElCheckbox v-model="remember">
  133. 记住密码
  134. </ElCheckbox>
  135. <ElLink type="primary" :underline="false" @click="emits('onResetPassword', form.userName)">
  136. 忘记密码了?
  137. </ElLink>
  138. </div>
  139. <ElButton :loading="loading" type="primary" size="large" style="width: 100%;" @click.prevent="handleLogin">
  140. 登录
  141. </ElButton>
  142. <div class="mt-4 flex-center gap-2 text-sm color-[var(--el-text-color-secondary)]">
  143. 还没有帐号?
  144. <ElLink type="primary" :underline="false" @click="emits('onRegister', form.userName)">
  145. 创建新帐号
  146. </ElLink>
  147. </div>
  148. </template>
  149. <template v-else-if="type === 'qrcode'">
  150. <div class="flex-col-center">
  151. <el-image src="https://s2.loli.net/2024/04/26/GsahtuIZ9XOg5jr.png" class="h-[250px] w-[250px]" />
  152. <div class="mt-2 op-50">
  153. 请使用微信扫码登录
  154. </div>
  155. </div>
  156. </template>
  157. <div class="mt-4 text-center -mb-4">
  158. <ElDivider>演示账号一键登录</ElDivider>
  159. <ElButton type="primary" size="small" plain @click="testAccount('admin')">
  160. admin
  161. </ElButton>
  162. <ElButton size="small" plain @click="testAccount('test')">
  163. test
  164. </ElButton>
  165. </div>
  166. </ElForm>
  167. </template>