login.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <template>
  2. <div class="auth-form-panel">
  3. <div class="logo">
  4. <img alt="RunForge" src="/logo.svg" height="40">
  5. <span class="title">RunForge | 用户登录</span>
  6. </div>
  7. <a-form size="large" :model="form" :rules="[]" class="form" @submit="handleSubmit">
  8. <a-form-item field="username" hide-label>
  9. <a-input placeholder="请输入用户名" allow-clear v-model="form.username">
  10. <template #prefix>
  11. <icon-user />
  12. </template>
  13. </a-input>
  14. </a-form-item>
  15. <a-form-item field="password" hide-label>
  16. <a-input-password placeholder="请输入密码" allow-clear v-model="form.password">
  17. <template #prefix>
  18. <icon-lock />
  19. </template>
  20. </a-input-password>
  21. </a-form-item>
  22. <a-form-item field="captcha" hide-label>
  23. <a-input placeholder="请输入验证码" allow-clear v-model="form.captcha">
  24. <template #prefix>
  25. <icon-check-circle />
  26. </template>
  27. <template #append>
  28. <img alt="!点我重试" :src="ImageCaptcha" class="captcha" @click="getCaptcha()" v-if="!captchaLoading">
  29. <icon-loading v-else />
  30. </template>
  31. </a-input>
  32. </a-form-item>
  33. <div class="forgetpass">
  34. <a-button v-if="quickLoginEnabled" type="text" @click="emit('changeMode', 'uniLogin')">快捷登录</a-button>
  35. <!-- <div class="tip">由于业务变更 现无法通过QQ/微信快捷登录<br>快捷登录用户可在注册新账号后提交工单联系客服找回原账号</div> -->
  36. <a-button type="text" @click="emit('changeMode', 'register')">注册账号</a-button>
  37. </div>
  38. <a-button :style="{ marginTop: '15px' }" class="formitem" type="primary" html-type="submit"
  39. :loading="loading">登录</a-button>
  40. </a-form>
  41. </div>
  42. </template>
  43. <script setup>
  44. import { getImageCaptcha, getUniLoginOptions } from '@/api/login'
  45. import { Notification } from '@arco-design/web-vue'
  46. import { ref, reactive } from 'vue'
  47. import { useUserStore } from '@/store/modules/user'
  48. import { timeFix } from '@/utils/util'
  49. import { useRoute, useRouter } from 'vue-router'
  50. const route = useRoute()
  51. const router = useRouter()
  52. const emit = defineEmits(['changeMode'])
  53. const from = route.query.from
  54. const userStore = useUserStore()
  55. let captchaLoading = ref(false)
  56. let CaptchaId = ref('')
  57. let ImageCaptcha = ref('')
  58. let loading = ref(false)
  59. let quickLoginEnabled = ref(true)
  60. let form = reactive({
  61. username: '',
  62. password: '',
  63. captcha: ''
  64. })
  65. const getCaptcha = async () => {
  66. try {
  67. captchaLoading.value = true
  68. const res = await getImageCaptcha()
  69. if (!res || res.code != 0)
  70. return requestFailed('获取图片验证码失败!' + res?.msg ?? '')
  71. ImageCaptcha.value = res.data.img
  72. CaptchaId.value = res.data.id
  73. } catch (error) {
  74. requestFailed('获取图片验证码失败!')
  75. } finally {
  76. captchaLoading.value = false
  77. }
  78. }
  79. getCaptcha()
  80. const getQuickLoginOptions = async () => {
  81. try {
  82. const res = await getUniLoginOptions()
  83. if (res?.code === 0 && Array.isArray(res.data?.enabledTypes))
  84. quickLoginEnabled.value = res.data.enabledTypes.length > 0
  85. } catch (error) {
  86. console.log(error)
  87. }
  88. }
  89. getQuickLoginOptions()
  90. const handleSubmit = async ({ values, errors }) => {
  91. if (!values.username || !values.password || !values.captcha)
  92. return requestFailed('请填写所有信息')
  93. loading.value = true
  94. let data = { ...values, id: CaptchaId.value }
  95. data.password = btoa(data.password)
  96. userStore.login(data)
  97. .then((res) => { loginSuccess(res) })
  98. .catch((err) => {
  99. getCaptcha()
  100. requestFailed(err.message)
  101. })
  102. .finally(() => {
  103. form.captcha = ''
  104. loading.value = false
  105. })
  106. }
  107. const loginSuccess = (res) => {
  108. Notification.success({
  109. title: `${timeFix()},${res.username}`,
  110. content: '欢迎回来!',
  111. duration: 2000
  112. })
  113. // setTimeout(() => { router.push(from || '/')}, 2000)
  114. router.push(from || '/')
  115. }
  116. const requestFailed = (msg) => {
  117. Notification.error({
  118. title: '错误',
  119. content: msg || '请求出现错误,请稍后再试',
  120. })
  121. }
  122. </script>
  123. <style scoped lang="less">
  124. @import '@/styles/auth-marketing.less';
  125. .tip {
  126. color: #777;
  127. font-size: 0.9em;
  128. text-align: left;
  129. margin-bottom: 12px;
  130. }
  131. </style>