|
@@ -20,46 +20,102 @@
|
|
|
<template #icon><RollbackIcon /></template>
|
|
|
返回登录
|
|
|
</t-button>
|
|
|
+ <t-button
|
|
|
+ variant="outline"
|
|
|
+ theme="primary"
|
|
|
+ v-else
|
|
|
+ @click="loginType = loginType === 'ACCOUNT' ? 'PHONE' : 'ACCOUNT'"
|
|
|
+ >
|
|
|
+ <template #icon><SwapRightIcon /></template>
|
|
|
+ {{ loginType === 'ACCOUNT' ? '手机号' : '账号' }}登录
|
|
|
+ </t-button>
|
|
|
</div>
|
|
|
- <div class="title2">{{
|
|
|
- `请输入${forgetStatus ? '新的' : ''}账号与密码`
|
|
|
+ <div class="title2" v-if="forgetStatus">{{ `请输入新的账号与密码` }}</div>
|
|
|
+ <div class="title2" v-else>{{
|
|
|
+ `请输入${loginType === 'ACCOUNT' ? '账号与密码' : '手机号与验证码'}`
|
|
|
}}</div>
|
|
|
- <t-form
|
|
|
- v-if="!forgetStatus"
|
|
|
- ref="form"
|
|
|
- :data="formData"
|
|
|
- :label-width="0"
|
|
|
- class="login-form"
|
|
|
- :rules="rules"
|
|
|
- >
|
|
|
- <t-form-item name="loginName">
|
|
|
- <t-input
|
|
|
- v-model="formData.loginName"
|
|
|
- clearable
|
|
|
- placeholder="请输入账号"
|
|
|
- size="large"
|
|
|
- @enter="loginHandle"
|
|
|
- >
|
|
|
- <template #prefix-icon>
|
|
|
- <desktop-icon />
|
|
|
- </template>
|
|
|
- </t-input>
|
|
|
- </t-form-item>
|
|
|
+ <template v-if="!forgetStatus">
|
|
|
+ <t-form
|
|
|
+ ref="form"
|
|
|
+ :data="formData"
|
|
|
+ :label-width="0"
|
|
|
+ class="login-form"
|
|
|
+ :rules="rules"
|
|
|
+ v-if="loginType === 'ACCOUNT'"
|
|
|
+ >
|
|
|
+ <t-form-item name="loginName">
|
|
|
+ <t-input
|
|
|
+ v-model="formData.loginName"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入账号"
|
|
|
+ size="large"
|
|
|
+ @enter="loginHandle"
|
|
|
+ >
|
|
|
+ <template #prefix-icon>
|
|
|
+ <desktop-icon />
|
|
|
+ </template>
|
|
|
+ </t-input>
|
|
|
+ </t-form-item>
|
|
|
|
|
|
- <t-form-item name="password">
|
|
|
- <t-input
|
|
|
- v-model="formData.password"
|
|
|
- type="password"
|
|
|
- clearable
|
|
|
- placeholder="请输入密码"
|
|
|
- size="large"
|
|
|
- @enter="loginHandle"
|
|
|
- >
|
|
|
- <template #prefix-icon>
|
|
|
- <lock-on-icon />
|
|
|
- </template>
|
|
|
- </t-input>
|
|
|
- </t-form-item>
|
|
|
+ <t-form-item name="password">
|
|
|
+ <t-input
|
|
|
+ v-model="formData.password"
|
|
|
+ type="password"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入密码"
|
|
|
+ size="large"
|
|
|
+ @enter="loginHandle"
|
|
|
+ >
|
|
|
+ <template #prefix-icon>
|
|
|
+ <lock-on-icon />
|
|
|
+ </template>
|
|
|
+ </t-input>
|
|
|
+ </t-form-item>
|
|
|
+ </t-form>
|
|
|
+
|
|
|
+ <t-form
|
|
|
+ v-else
|
|
|
+ ref="form2"
|
|
|
+ :data="formData2"
|
|
|
+ :label-width="0"
|
|
|
+ class="login-form"
|
|
|
+ :rules="rules2"
|
|
|
+ >
|
|
|
+ <t-form-item name="mobileNumber">
|
|
|
+ <t-input
|
|
|
+ v-model="formData2.mobileNumber"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入你的手机号"
|
|
|
+ size="large"
|
|
|
+ >
|
|
|
+ <template #prefix-icon>
|
|
|
+ <CallIcon />
|
|
|
+ </template>
|
|
|
+ </t-input>
|
|
|
+ </t-form-item>
|
|
|
+ <t-form-item name="code">
|
|
|
+ <div class="flex items-center">
|
|
|
+ <t-input
|
|
|
+ style="width: 170px"
|
|
|
+ v-model="formData2.code"
|
|
|
+ clearable
|
|
|
+ placeholder="验证码"
|
|
|
+ size="large"
|
|
|
+ >
|
|
|
+ <template #prefix-icon>
|
|
|
+ <MobileIcon />
|
|
|
+ </template>
|
|
|
+ </t-input>
|
|
|
+ <t-button
|
|
|
+ class="m-l-20px"
|
|
|
+ style="width: 110px"
|
|
|
+ :loading="loading"
|
|
|
+ @click="getCode"
|
|
|
+ >{{ isActive ? lastSeconds + 's' : '获取验证码' }}</t-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </t-form-item>
|
|
|
+ </t-form>
|
|
|
<t-link theme="primary" class="m-t-20px" @click="forgetStatus = true"
|
|
|
>忘记密码</t-link
|
|
|
>
|
|
@@ -71,7 +127,7 @@
|
|
|
theme="primary"
|
|
|
>登 录</t-button
|
|
|
>
|
|
|
- </t-form>
|
|
|
+ </template>
|
|
|
<ForgetPwd v-else @success="findSuccess" />
|
|
|
</div>
|
|
|
</div>
|
|
@@ -80,16 +136,57 @@
|
|
|
|
|
|
<script setup name="Login">
|
|
|
import { ref, reactive, computed, watch } from 'vue';
|
|
|
-import { DesktopIcon, LockOnIcon, RollbackIcon } from 'tdesign-icons-vue-next';
|
|
|
+import {
|
|
|
+ DesktopIcon,
|
|
|
+ LockOnIcon,
|
|
|
+ RollbackIcon,
|
|
|
+ SwapRightIcon,
|
|
|
+ CallIcon,
|
|
|
+ MobileIcon,
|
|
|
+} from 'tdesign-icons-vue-next';
|
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
|
import { useUserStore, useAppStore } from '@/store';
|
|
|
import { MessagePlugin } from 'tdesign-vue-next';
|
|
|
import { getBase64 } from '@/utils/crypto';
|
|
|
import ForgetPwd from './forget-pwd.vue';
|
|
|
-
|
|
|
+import { useRequest } from 'vue-request';
|
|
|
+import { getVerifyCode } from '@/api/user';
|
|
|
+import { useIntervalFn } from '@vueuse/core';
|
|
|
+const { run, loading } = useRequest(getVerifyCode, {
|
|
|
+ onSuccess: () => {
|
|
|
+ MessagePlugin.success('验证码已发送');
|
|
|
+ },
|
|
|
+});
|
|
|
+const lastSeconds = ref(10);
|
|
|
+const countdown = () => {
|
|
|
+ if (lastSeconds.value == 0) {
|
|
|
+ pause();
|
|
|
+ } else {
|
|
|
+ lastSeconds.value = lastSeconds.value - 1;
|
|
|
+ }
|
|
|
+};
|
|
|
+const { pause, resume, isActive } = useIntervalFn(
|
|
|
+ () => {
|
|
|
+ countdown();
|
|
|
+ },
|
|
|
+ 1000,
|
|
|
+ { immediate: false }
|
|
|
+);
|
|
|
+const getCode = () => {
|
|
|
+ if (!formData2.mobileNumber) {
|
|
|
+ MessagePlugin.error('请先输入手机号');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ run({
|
|
|
+ mobileNumber: formData2.mobileNumber,
|
|
|
+ });
|
|
|
+ // resume();
|
|
|
+};
|
|
|
+const loginType = ref('ACCOUNT');
|
|
|
const appStore = useAppStore();
|
|
|
const forgetStatus = ref(false);
|
|
|
const form = ref(null);
|
|
|
+const form2 = ref(null);
|
|
|
|
|
|
const route = useRoute();
|
|
|
const router = useRouter();
|
|
@@ -98,6 +195,10 @@ const formData = reactive({
|
|
|
loginName: '',
|
|
|
password: '',
|
|
|
});
|
|
|
+const formData2 = reactive({
|
|
|
+ mobileNumber: '',
|
|
|
+ code: '',
|
|
|
+});
|
|
|
const rules = {
|
|
|
loginName: [
|
|
|
{ required: true, message: '请输入账号', type: 'error', trigger: 'change' },
|
|
@@ -106,29 +207,55 @@ const rules = {
|
|
|
{ required: true, message: '请输入密码', type: 'error', trigger: 'change' },
|
|
|
],
|
|
|
};
|
|
|
+const rules2 = {
|
|
|
+ mobileNumber: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入手机号',
|
|
|
+ type: 'error',
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ code: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入验证码',
|
|
|
+ type: 'error',
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+};
|
|
|
|
|
|
const userStore = useUserStore();
|
|
|
|
|
|
const loginHandle = () => {
|
|
|
- form.value.validate().then(async (result) => {
|
|
|
- const redirect = route.query.redirect
|
|
|
- ? route.query.redirect
|
|
|
- : '/my-workbenches';
|
|
|
- if (result === true) {
|
|
|
- await userStore.login({
|
|
|
- loginName: formData.loginName,
|
|
|
- password: getBase64(formData.password),
|
|
|
- type: 'ACCOUNT',
|
|
|
- });
|
|
|
- await userStore.requestUserMenu();
|
|
|
- await appStore.getFlowParams();
|
|
|
- if (redirect) {
|
|
|
- router.push(redirect);
|
|
|
- } else {
|
|
|
- router.push({ name: userStore.menus[0].name });
|
|
|
+ (loginType.value === 'ACCOUNT' ? form.value : form2.value)
|
|
|
+ .validate()
|
|
|
+ .then(async (result) => {
|
|
|
+ const redirect = route.query.redirect
|
|
|
+ ? route.query.redirect
|
|
|
+ : '/my-workbenches';
|
|
|
+ if (result === true) {
|
|
|
+ let params =
|
|
|
+ loginType.value === 'ACCOUNT'
|
|
|
+ ? {
|
|
|
+ loginName: formData.loginName,
|
|
|
+ password: getBase64(formData.password),
|
|
|
+ }
|
|
|
+ : formData2;
|
|
|
+ await userStore.login({
|
|
|
+ ...params,
|
|
|
+ type: loginType.value,
|
|
|
+ });
|
|
|
+ await userStore.requestUserMenu();
|
|
|
+ await appStore.getFlowParams();
|
|
|
+ if (redirect) {
|
|
|
+ router.push(redirect);
|
|
|
+ } else {
|
|
|
+ router.push({ name: userStore.menus[0].name });
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- });
|
|
|
+ });
|
|
|
};
|
|
|
const findSuccess = () => {
|
|
|
forgetStatus.value = false;
|