| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- <template>
- <div class="root">
- <div class="logo">
- <img alt="RunForge" src="/logo.svg" height="40">
- <span class="title">RunForge | 用户登录</span>
- </div>
- <a-form size="large" :model="form" :rules="[]" class="form" @submit="handleSubmit">
- <a-form-item field="username" hide-label>
- <a-input placeholder="请输入用户名" allow-clear v-model="form.username">
- <template #prefix>
- <icon-user />
- </template>
- </a-input>
- </a-form-item>
- <a-form-item field="password" hide-label>
- <a-input-password placeholder="请输入密码" allow-clear v-model="form.password">
- <template #prefix>
- <icon-lock />
- </template>
- </a-input-password>
- </a-form-item>
- <a-form-item field="captcha" hide-label>
- <a-input placeholder="请输入验证码" allow-clear v-model="form.captcha">
- <template #prefix>
- <icon-check-circle />
- </template>
- <template #append>
- <img alt="!点我重试" :src="ImageCaptcha" class="captcha" @click="getCaptcha()" v-if="!captchaLoading">
- <icon-loading v-else />
- </template>
- </a-input>
- </a-form-item>
- <div class="forgetpass">
- <!-- <a-button type="text" @click="emit('changeMode', 'uniLogin')">快捷登录</a-button> -->
- <!-- <div class="tip">由于业务变更 现无法通过QQ/微信快捷登录<br>快捷登录用户可在注册新账号后提交工单联系客服找回原账号</div> -->
- <a-button type="text" @click="emit('changeMode', 'register')">注册账号</a-button>
- </div>
- <a-button :style="{ marginTop: '15px' }" class="formitem" type="primary" html-type="submit"
- :loading="loading">登录</a-button>
- </a-form>
- </div>
- </template>
- <script setup>
- import { getImageCaptcha } from '@/api/login'
- import { Notification } from '@arco-design/web-vue'
- import { ref, reactive } from 'vue'
- import { useUserStore } from '@/store/modules/user'
- import { timeFix } from '@/utils/util'
- import { useRoute, useRouter } from 'vue-router'
- const route = useRoute()
- const router = useRouter()
- const emit = defineEmits(['changeMode'])
- const from = route.query.from
- const userStore = useUserStore()
- let captchaLoading = ref(false)
- let CaptchaId = ref('')
- let ImageCaptcha = ref('')
- let loading = ref(false)
- let form = reactive({
- username: '',
- password: '',
- captcha: ''
- })
- const getCaptcha = async () => {
- try {
- captchaLoading.value = true
- const res = await getImageCaptcha()
- if (!res || res.code != 0)
- return requestFailed('获取图片验证码失败!' + res?.msg ?? '')
- ImageCaptcha.value = res.data.img
- CaptchaId.value = res.data.id
- } catch (error) {
- requestFailed('获取图片验证码失败!')
- } finally {
- captchaLoading.value = false
- }
- }
- getCaptcha()
- const handleSubmit = async ({ values, errors }) => {
- if (!values.username || !values.password || !values.captcha)
- return requestFailed('请填写所有信息')
- loading.value = true
- let data = { ...values, id: CaptchaId.value }
- data.password = btoa(data.password)
- userStore.login(data)
- .then((res) => { loginSuccess(res) })
- .catch((err) => {
- getCaptcha()
- requestFailed(err.message)
- })
- .finally(() => {
- form.captcha = ''
- loading.value = false
- })
- }
- const loginSuccess = (res) => {
- Notification.success({
- title: `${timeFix()},${res.username}`,
- content: '欢迎回来!',
- duration: 2000
- })
- // setTimeout(() => { router.push(from || '/')}, 2000)
- router.push(from || '/')
- }
- const requestFailed = (msg) => {
- Notification.error({
- title: '错误',
- content: msg || '请求出现错误,请稍后再试',
- })
- }
- </script>
- <style scoped>
- .root {
- display: flex;
- gap: 40px;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- }
- .form {
- width: 100%;
- }
- .formitem {
- width: 350px;
- min-height: 35px
- }
- .logo {
- display: flex
- }
- .logo .title {
- color: #3370FF;
- font-size: 1.8em;
- font-weight: bold;
- margin-left: 15px;
- font-family: Alimama ShuHeiTi, -apple-system, BlinkMacSystemFont;
- }
- .tip {
- color: #777;
- font-size: 0.9em;
- text-align: left;
- margin-bottom: 20px;
- margin-left: -8px;
- }
- .forgetpass {
- width: 100%;
- margin-top: -10px;
- display: flex;
- justify-content: space-between;
- }
- .captcha {
- max-height: 35px;
- margin-right: -10px;
- }
- </style>
|