添加邮件验证码登录

This commit is contained in:
lijun 2025-09-27 13:36:35 +08:00
parent a6312198c3
commit 9aa1191a44
2 changed files with 126 additions and 2 deletions

View File

@ -32,6 +32,23 @@ export const registerService = (registerData) => {
return request.post('/user/register', params)
}
export const sendLoginCode = (Data) => {
return request.post('/user/login_code', Data, {
headers: {
'token': Data.token,
"Content-Type": "application/json"
}
});
}
export const loginByCode = (Data) => {
return request.post('/user/login_by_code', Data, {
headers: {
'token': Data.token,
"Content-Type": "application/json"
}
});
}
export const getUUIDService = (registerData) => {

View File

@ -6,6 +6,7 @@
<div class="login-title">统一登录平台</div>
</div>
<el-form :model="param" :rules="rules" ref="login" size="large">
<template v-if="login_type === 'pwd'">
<el-form-item prop="username">
<el-input v-model="param.username" placeholder="用户名或邮箱">
<template #prepend>
@ -37,7 +38,45 @@
<el-link type="primary" @click="$router.push('/reset-pwd')"
>忘记密码</el-link
>
<el-link type="primary" @click="toggleLoginType"
>验证码登录</el-link
>
</div>
</template>
<!-- 邮箱验证码登录表单切换后显示 -->
<template v-else>
<!-- 邮箱输入 -->
<el-form-item prop="email">
<el-input v-model="code_login_form.email" placeholder="请输入邮箱">
<template #prepend>
<el-icon><Message /></el-icon>
</template>
</el-input>
</el-form-item>
<!-- 验证码输入 + 发送按钮 -->
<el-form-item prop="code">
<el-input v-model="code_login_form.code" placeholder="请输入验证码">
<template #prepend>
<el-icon><VerificationCode /></el-icon>
</template>
<template #append>
<el-button
type="text"
:disabled="countdown > 0"
@click="sendCode"
class="code-btn"
>
{{ countdown > 0 ? `${countdown}s后重发` : "发送验证码" }}
</el-button>
</template>
</el-input>
</el-form-item>
<!-- 切换链接无记住密码 -->
<div class="pwd-tips">
<el-link type="primary" @click="toggleLoginType"
>密码登录</el-link>
</div>
</template>
<el-button
class="login-btn"
type="primary"
@ -74,7 +113,7 @@
</template>
<script setup lang="ts">
import { ref, reactive, inject, onMounted } from "vue";
import { ref, reactive, inject, onMounted, h } from "vue";
import { useRouter,useRoute } from "vue-router";
import { ElMessage } from "element-plus";
import { loginService } from "@/api/user";
@ -82,7 +121,8 @@ import { GetUserInfoService } from "@/api/user";
import { UserToken } from "@/types/user";
import { usePermissStore } from "@/store/permiss";
import Cookies from 'js-cookie';
import {getThirdPartyUUID,getThirdPartyLoginStatus,getThirdPartyLoginUrl} from "@/api/user";
import {getThirdPartyUUID,getThirdPartyLoginStatus,getThirdPartyLoginUrl,sendLoginCode, loginByCode} from "@/api/user";
import { time } from "console";
//
const lgStr = localStorage.getItem("login-param");
const defParam = lgStr ? JSON.parse(lgStr) : null;
@ -90,6 +130,8 @@ const globalData = inject("globalData");
const permiss = usePermissStore();
//
const checked = ref(lgStr ? true : false);
const login_type = ref("pwd"); // pwd: qr:
const countdown = ref(0); //
const router = useRouter();
const route = useRoute();
@ -99,6 +141,12 @@ const param = reactive({
password: defParam ? defParam.password : "",
});
//
const code_login_form = ref({
email: '',
code: '',
login_type: 1, // 1: 2:
});
//
const rules = {
@ -281,8 +329,63 @@ const thirdLogin = async (type) => {
};
const sendCode = async () => {
if (code_login_form.value.email === ""){
ElMessage.error("请输入邮箱地址!");
return;
}
let result = await sendLoginCode(code_login_form.value);
if (result["code"] !== 0) {
ElMessage.error(result["message"] || "发送验证码失败!请稍后再试");
return;
}else{
countdown.value = 60;
timer.value = setInterval(() => {
countdown.value--;
if (countdown.value <= 0) {
clearInterval(timer.value); //
}
}, 1000);
ElMessage.success("验证码已发送,请注意查收!");
}
}
const HandleLoginByCode =async () => {
if(code_login_form.value.email === "" || code_login_form.value.code === ""){
ElMessage.error("请输入邮箱和验证码!");
return;
}
let result = await loginByCode(code_login_form.value);
if (result["code"] !== 0) {
ElMessage.error(result["message"] || "登录失败!请稍后再试");
return;
}else{
let userTokenInfo: UserToken = result["data"];
globalData["token"] = result.data;
localStorage.setItem("token", userTokenInfo.access_token);
localStorage.setItem("refresh_token", userTokenInfo.refresh_token);
localStorage.setItem("userId", userTokenInfo.user_id.toString());
localStorage.setItem("username", userTokenInfo.username);
let now = new Date();
localStorage.setItem("end_time", (now.setDate(now.getHours())).toString()); //
await getMyUserInfo(userTokenInfo.user_id);
}
};
const toggleLoginType = () => {
if(login_type.value === "pwd"){
login_type.value = "code";
}else{
login_type.value = "pwd";
}
};
//
const onLogin = async () => {
if (login_type.value !== "pwd") {
HandleLoginByCode();
return;
}
console.log("params:", param);
loginData.value.username = param.username;
@ -440,4 +543,8 @@ const getMyUserInfo = async (id) => {
.google-btn {
background-image: url(../../assets/img/google-logo_resized.png) !important;
}
.code-btn :deep(.el-button--text:not(.is-disabled)):hover {
color: #0d66d0 !important;
background: rgba(22, 119, 255, 0.05) !important;
}
</style>