chore: 🔨 适配后端发送验证码和微信登录接口路径调整

This commit is contained in:
ray
2025-01-13 18:25:48 +08:00
parent b5eaf1f21b
commit 01b8a6840c
3 changed files with 83 additions and 76 deletions

View File

@@ -163,22 +163,17 @@ const UserAPI = {
}); });
}, },
/** /** 发送短信验证码(绑定或更换手机号)*/
* 发送手机/邮箱验证码 sendMobileCode(mobile: string) {
*
* @param contact 联系方式 手机号/邮箱
* @param contactType 联系方式类型 MOBILE:手机;EMAIL:邮箱
*/
sendVerificationCode(contact: string, contactType: string) {
return request({ return request({
url: `${USER_BASE_URL}/send-verification-code`, url: `${USER_BASE_URL}/mobile/code`,
method: "get", method: "post",
params: { contact: contact, contactType: contactType }, params: { mobile: mobile },
}); });
}, },
/** 绑定个人中心用户手机 */ /** 绑定或更换手机 */
bindMobile(data: MobileBindingForm) { bindOrChangeMobile(data: MobileUpdateForm) {
return request({ return request({
url: `${USER_BASE_URL}/mobile`, url: `${USER_BASE_URL}/mobile`,
method: "put", method: "put",
@@ -186,8 +181,17 @@ const UserAPI = {
}); });
}, },
/** 绑定个人中心用户邮箱 */ /** 发送邮箱验证码(绑定或更换邮箱*/
bindEmail(data: EmailBindingForm) { sendEmailCode(email: string) {
return request({
url: `${USER_BASE_URL}/email/code`,
method: "post",
params: { email: email },
});
},
/** 绑定或更换邮箱 */
bindOrChangeEmail(data: EmailUpdateForm) {
return request({ return request({
url: `${USER_BASE_URL}/email`, url: `${USER_BASE_URL}/email`,
method: "put", method: "put",
@@ -364,7 +368,7 @@ export interface PasswordChangeForm {
} }
/** 修改手机表单 */ /** 修改手机表单 */
export interface MobileBindingForm { export interface MobileUpdateForm {
/** 手机号 */ /** 手机号 */
mobile?: string; mobile?: string;
/** 验证码 */ /** 验证码 */
@@ -372,7 +376,7 @@ export interface MobileBindingForm {
} }
/** 修改邮箱表单 */ /** 修改邮箱表单 */
export interface EmailBindingForm { export interface EmailUpdateForm {
/** 邮箱 */ /** 邮箱 */
email?: string; email?: string;
/** 验证码 */ /** 验证码 */

View File

@@ -16,7 +16,7 @@
<!-- 登录页内容 --> <!-- 登录页内容 -->
<div class="login-form"> <div class="login-form">
<el-form ref="loginFormRef" :model="loginData" :rules="loginRules"> <el-form ref="loginFormRef" :model="loginFormData" :rules="loginRules">
<div class="form-title"> <div class="form-title">
<h2>{{ defaultSettings.title }}</h2> <h2>{{ defaultSettings.title }}</h2>
<el-dropdown style="position: absolute; right: 0"> <el-dropdown style="position: absolute; right: 0">
@@ -52,7 +52,7 @@
</el-icon> </el-icon>
<el-input <el-input
ref="username" ref="username"
v-model="loginData.username" v-model="loginFormData.username"
:placeholder="$t('login.username')" :placeholder="$t('login.username')"
name="username" name="username"
size="large" size="large"
@@ -69,7 +69,7 @@
<Lock /> <Lock />
</el-icon> </el-icon>
<el-input <el-input
v-model="loginData.password" v-model="loginFormData.password"
:placeholder="$t('login.password')" :placeholder="$t('login.password')"
type="password" type="password"
name="password" name="password"
@@ -88,7 +88,7 @@
<div class="input-wrapper"> <div class="input-wrapper">
<svg-icon icon-class="captcha" class="mx-2" /> <svg-icon icon-class="captcha" class="mx-2" />
<el-input <el-input
v-model="loginData.captchaCode" v-model="loginFormData.captchaCode"
auto-complete="off" auto-complete="off"
size="large" size="large"
class="flex-1" class="flex-1"
@@ -148,7 +148,7 @@
import { LocationQuery, useRoute } from "vue-router"; import { LocationQuery, useRoute } from "vue-router";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import AuthAPI, { type LoginData } from "@/api/auth"; import AuthAPI, { type LoginFormData } from "@/api/auth";
import router from "@/router"; import router from "@/router";
import type { FormInstance } from "element-plus"; import type { FormInstance } from "element-plus";
@@ -171,7 +171,7 @@ const loading = ref(false); // 按钮 loading 状态
const isCapslock = ref(false); // 是否大写锁定 const isCapslock = ref(false); // 是否大写锁定
const captchaBase64 = ref(); // 验证码图片Base64字符串 const captchaBase64 = ref(); // 验证码图片Base64字符串
const loginData = ref<LoginData>({ const loginFormData = ref<LoginFormData>({
username: "admin", username: "admin",
password: "123456", password: "123456",
captchaKey: "", captchaKey: "",
@@ -212,7 +212,7 @@ const loginRules = computed(() => {
// 获取验证码 // 获取验证码
function getCaptcha() { function getCaptcha() {
AuthAPI.getCaptcha().then((data) => { AuthAPI.getCaptcha().then((data) => {
loginData.value.captchaKey = data.captchaKey; loginFormData.value.captchaKey = data.captchaKey;
captchaBase64.value = data.captchaBase64; captchaBase64.value = data.captchaBase64;
}); });
} }
@@ -223,7 +223,7 @@ async function handleLoginSubmit() {
if (valid) { if (valid) {
loading.value = true; loading.value = true;
userStore userStore
.login(loginData.value) .login(loginFormData.value)
.then(async () => { .then(async () => {
await userStore.getUserInfo(); await userStore.getUserInfo();
// 需要在路由跳转前加载字典数据,否则会出现字典数据未加载完成导致页面渲染异常 // 需要在路由跳转前加载字典数据,否则会出现字典数据未加载完成导致页面渲染异常
@@ -281,8 +281,8 @@ function checkCapslock(event: KeyboardEvent) {
// 设置登录凭证 // 设置登录凭证
const setLoginCredentials = (username: string, password: string) => { const setLoginCredentials = (username: string, password: string) => {
loginData.value.username = username; loginFormData.value.username = username;
loginData.value.password = password; loginFormData.value.password = password;
}; };
onMounted(() => { onMounted(() => {

View File

@@ -204,21 +204,17 @@
<el-form <el-form
v-else-if="dialog.type === DialogType.MOBILE" v-else-if="dialog.type === DialogType.MOBILE"
ref="mobileBindingFormRef" ref="mobileBindingFormRef"
:model="mobileBindingForm" :model="mobileUpdateForm"
:rules="mobileBindingRules" :rules="mobileBindingRules"
:label-width="100" :label-width="100"
> >
<el-form-item label="手机号码" prop="mobile"> <el-form-item label="手机号码" prop="mobile">
<el-input v-model="mobileBindingForm.mobile" style="width: 250px" /> <el-input v-model="mobileUpdateForm.mobile" style="width: 250px" />
</el-form-item> </el-form-item>
<el-form-item label="验证码" prop="code"> <el-form-item label="验证码" prop="code">
<el-input v-model="mobileBindingForm.code" style="width: 250px"> <el-input v-model="mobileUpdateForm.code" style="width: 250px">
<template #append> <template #append>
<el-button <el-button class="ml-5" :disabled="mobileCountdown > 0" @click="handleSendMobileCode">
class="ml-5"
:disabled="mobileCountdown > 0"
@click="handleSendVerificationCode('MOBILE')"
>
{{ mobileCountdown > 0 ? `${mobileCountdown}s后重新发送` : "发送验证码" }} {{ mobileCountdown > 0 ? `${mobileCountdown}s后重新发送` : "发送验证码" }}
</el-button> </el-button>
</template> </template>
@@ -230,21 +226,17 @@
<el-form <el-form
v-else-if="dialog.type === DialogType.EMAIL" v-else-if="dialog.type === DialogType.EMAIL"
ref="emailBindingFormRef" ref="emailBindingFormRef"
:model="emailBindingForm" :model="emailUpdateForm"
:rules="emailBindingRules" :rules="emailBindingRules"
:label-width="100" :label-width="100"
> >
<el-form-item label="邮箱" prop="email"> <el-form-item label="邮箱" prop="email">
<el-input v-model="emailBindingForm.email" style="width: 250px" /> <el-input v-model="emailUpdateForm.email" style="width: 250px" />
</el-form-item> </el-form-item>
<el-form-item label="验证码" prop="code"> <el-form-item label="验证码" prop="code">
<el-input v-model="emailBindingForm.code" style="width: 250px"> <el-input v-model="emailUpdateForm.code" style="width: 250px">
<template #append> <template #append>
<el-button <el-button class="ml-5" :disabled="emailCountdown > 0" @click="handleSendEmailCode">
class="ml-5"
:disabled="emailCountdown > 0"
@click="handleSendVerificationCode('EMAIL')"
>
{{ emailCountdown > 0 ? `${emailCountdown}s后重新发送` : "发送验证码" }} {{ emailCountdown > 0 ? `${emailCountdown}s后重新发送` : "发送验证码" }}
</el-button> </el-button>
</template> </template>
@@ -265,8 +257,8 @@
import UserAPI, { import UserAPI, {
UserProfileVO, UserProfileVO,
PasswordChangeForm, PasswordChangeForm,
MobileBindingForm, MobileUpdateForm,
EmailBindingForm, EmailUpdateForm,
UserProfileForm, UserProfileForm,
} from "@/api/system/user"; } from "@/api/system/user";
@@ -291,8 +283,8 @@ const dialog = reactive({
const userProfileForm = reactive<UserProfileForm>({}); const userProfileForm = reactive<UserProfileForm>({});
const passwordChangeForm = reactive<PasswordChangeForm>({}); const passwordChangeForm = reactive<PasswordChangeForm>({});
const mobileBindingForm = reactive<MobileBindingForm>({}); const mobileUpdateForm = reactive<MobileUpdateForm>({});
const emailBindingForm = reactive<EmailBindingForm>({}); const emailUpdateForm = reactive<EmailUpdateForm>({});
const mobileCountdown = ref(0); const mobileCountdown = ref(0);
const mobileTimer = ref<NodeJS.Timeout | null>(null); const mobileTimer = ref<NodeJS.Timeout | null>(null);
@@ -361,23 +353,24 @@ const handleOpenDialog = (type: DialogType) => {
}; };
/** /**
* 发送验证码 * 发送手机验证码
*
* @param contactType 联系方式类型 MOBILE: 手机号码 EMAIL: 邮箱
*/ */
const handleSendVerificationCode = async (contactType: string) => { function handleSendMobileCode() {
if (contactType === "MOBILE") { if (!mobileUpdateForm.mobile) {
if (!mobileBindingForm.mobile) {
ElMessage.error("请输入手机号"); ElMessage.error("请输入手机号");
return; return;
} }
// 验证手机号格式 // 验证手机号格式
const reg = /^1[3-9]\d{9}$/; const reg = /^1[3-9]\d{9}$/;
if (!reg.test(mobileBindingForm.mobile)) { if (!reg.test(mobileUpdateForm.mobile)) {
ElMessage.error("手机号格式不正确"); ElMessage.error("手机号格式不正确");
return; return;
} }
// 发送短信验证码
UserAPI.sendMobileCode(mobileUpdateForm.mobile).then(() => {
ElMessage.success("验证码发送成功");
// 倒计时 60s 重新发送
mobileCountdown.value = 60; mobileCountdown.value = 60;
mobileTimer.value = setInterval(() => { mobileTimer.value = setInterval(() => {
if (mobileCountdown.value > 0) { if (mobileCountdown.value > 0) {
@@ -386,18 +379,28 @@ const handleSendVerificationCode = async (contactType: string) => {
clearInterval(mobileTimer.value!); clearInterval(mobileTimer.value!);
} }
}, 1000); }, 1000);
} else if (contactType === "EMAIL") { });
if (!emailBindingForm.email) { }
/**
* 发送邮箱验证码
*/
function handleSendEmailCode() {
if (!emailUpdateForm.email) {
ElMessage.error("请输入邮箱"); ElMessage.error("请输入邮箱");
return; return;
} }
// 验证邮箱格式 // 验证邮箱格式
const reg = /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/; const reg = /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/;
if (!reg.test(emailBindingForm.email)) { if (!reg.test(emailUpdateForm.email)) {
ElMessage.error("邮箱格式不正确"); ElMessage.error("邮箱格式不正确");
return; return;
} }
// 发送邮箱验证码
UserAPI.sendEmailCode(emailUpdateForm.email).then(() => {
ElMessage.success("验证码发送成功");
// 倒计时 60s 重新发送
emailCountdown.value = 60; emailCountdown.value = 60;
emailTimer.value = setInterval(() => { emailTimer.value = setInterval(() => {
if (emailCountdown.value > 0) { if (emailCountdown.value > 0) {
@@ -406,8 +409,8 @@ const handleSendVerificationCode = async (contactType: string) => {
clearInterval(emailTimer.value!); clearInterval(emailTimer.value!);
} }
}, 1000); }, 1000);
} });
}; }
/** /**
* 提交表单 * 提交表单
@@ -429,13 +432,13 @@ const handleSubmit = async () => {
dialog.visible = false; dialog.visible = false;
}); });
} else if (dialog.type === DialogType.MOBILE) { } else if (dialog.type === DialogType.MOBILE) {
UserAPI.bindMobile(mobileBindingForm).then(() => { UserAPI.bindOrChangeMobile(mobileUpdateForm).then(() => {
ElMessage.success("手机号绑定成功"); ElMessage.success("手机号绑定成功");
dialog.visible = false; dialog.visible = false;
loadUserProfile(); loadUserProfile();
}); });
} else if (dialog.type === DialogType.EMAIL) { } else if (dialog.type === DialogType.EMAIL) {
UserAPI.bindEmail(emailBindingForm).then(() => { UserAPI.bindOrChangeEmail(emailUpdateForm).then(() => {
ElMessage.success("邮箱绑定成功"); ElMessage.success("邮箱绑定成功");
dialog.visible = false; dialog.visible = false;
loadUserProfile(); loadUserProfile();