chore: 移除微信授权登录
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<!-- 登录卡片 -->
|
||||
<view class="login-card">
|
||||
<!-- 账号密码登录表单 -->
|
||||
<wd-form v-if="loginType === 'account'" ref="loginFormRef" :model="loginFormData">
|
||||
<wd-form v-if="loginMode === 'ACCOUNT'" ref="loginFormRef" :model="loginFormData">
|
||||
<!-- 用户名输入框 -->
|
||||
<view class="login-form__item">
|
||||
<wd-icon name="user" size="22" class="mr-20rpx" />
|
||||
@@ -47,49 +47,51 @@
|
||||
>
|
||||
{{ loading ? "登录中..." : "账号登录" }}
|
||||
</button>
|
||||
|
||||
<!-- 切换登录方式 -->
|
||||
<view class="login-switch" @click="loginType = 'phone'">
|
||||
<text>使用手机号一键登录</text>
|
||||
<wd-icon name="arrow-right" size="12" />
|
||||
</view>
|
||||
</wd-form>
|
||||
|
||||
<!-- 手机号登录 -->
|
||||
<view v-else class="phone-login">
|
||||
<view class="phone-login__title">微信一键登录</view>
|
||||
<view class="phone-login__subtitle">授权后将获取您的手机号</view>
|
||||
<wd-form v-else ref="smsLoginFormRef" :model="smsLoginFormData">
|
||||
<view class="login-form__item">
|
||||
<wd-icon name="phone" size="22" class="mr-20rpx" />
|
||||
<input
|
||||
v-model="smsLoginFormData.mobile"
|
||||
class="login-form__input"
|
||||
placeholder="请输入手机号"
|
||||
placeholder-class="login-form__placeholder"
|
||||
/>
|
||||
</view>
|
||||
<view class="login-form__divider"></view>
|
||||
|
||||
<view class="login-form__item">
|
||||
<wd-icon name="security" size="22" class="mr-20rpx" />
|
||||
<input
|
||||
v-model="smsLoginFormData.code"
|
||||
class="login-form__input"
|
||||
placeholder="请输入验证码"
|
||||
placeholder-class="login-form__placeholder"
|
||||
/>
|
||||
<wd-button
|
||||
size="small"
|
||||
plain
|
||||
:disabled="smsCountdown > 0"
|
||||
@click="handleSendSmsLoginCode"
|
||||
>
|
||||
{{ smsCountdown > 0 ? `${smsCountdown}s后重试` : "发送验证码" }}
|
||||
</wd-button>
|
||||
</view>
|
||||
<view class="login-form__divider"></view>
|
||||
|
||||
<button
|
||||
class="wechat-btn"
|
||||
class="login-btn"
|
||||
:disabled="loading"
|
||||
open-type="getPhoneNumber"
|
||||
@getphonenumber="handleWechatPhoneLogin"
|
||||
:class="{ 'login-btn--loading': loading }"
|
||||
@click="handleSmsLogin"
|
||||
>
|
||||
<wd-icon name="weixin" size="24" color="#ffffff" />
|
||||
<text class="ml-16rpx">微信一键登录</text>
|
||||
{{ loading ? "登录中..." : "短信登录" }}
|
||||
</button>
|
||||
</wd-form>
|
||||
|
||||
<!-- 切换登录方式 -->
|
||||
<view class="login-switch" @click="loginType = 'account'">
|
||||
<text>使用账号密码登录</text>
|
||||
<wd-icon name="arrow-right" size="12" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 其他登录方式 -->
|
||||
<view class="other-login">
|
||||
<view class="other-login__title">
|
||||
<view class="other-login__line"></view>
|
||||
<text class="other-login__text">其他登录方式</text>
|
||||
<view class="other-login__line"></view>
|
||||
</view>
|
||||
|
||||
<view class="flex-center" @click="handleWechatLogin">
|
||||
<view class="wechat-icon">
|
||||
<image src="/static/icons/weixin.png" class="w-40rpx h-40rpx" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="login-switch" @click="loginMode = loginMode === 'ACCOUNT' ? 'SMS' : 'ACCOUNT'">
|
||||
{{ loginMode === "ACCOUNT" ? "使用短信验证码登录" : "使用账号密码登录" }}
|
||||
</view>
|
||||
|
||||
<!-- 底部协议 -->
|
||||
@@ -120,19 +122,21 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import { type LoginData } from "@/api/auth";
|
||||
import AuthAPI, { type LoginData } from "@/api/auth";
|
||||
import { useUserStore } from "@/store/modules/user-store";
|
||||
import { useToast } from "wot-design-uni";
|
||||
import { useWechat } from "@/composables/useWechat";
|
||||
|
||||
const loginFormRef = ref();
|
||||
const smsLoginFormRef = ref();
|
||||
const toast = useToast();
|
||||
const loading = ref(false);
|
||||
const userStore = useUserStore();
|
||||
const showPassword = ref(false);
|
||||
const loginType = ref<"account" | "phone">("account");
|
||||
const isAgreePolicy = ref(false); // 是否同意隐私协议
|
||||
const { authState, getLoginCode, getPhoneNumber } = useWechat();
|
||||
|
||||
const loginMode = ref<"ACCOUNT" | "SMS">("ACCOUNT");
|
||||
const smsCountdown = ref(0);
|
||||
const smsTimer = ref<ReturnType<typeof setInterval> | null>(null);
|
||||
|
||||
// 登录表单数据
|
||||
const loginFormData = ref<LoginData>({
|
||||
@@ -140,9 +144,14 @@ const loginFormData = ref<LoginData>({
|
||||
password: "123456",
|
||||
});
|
||||
|
||||
const smsLoginFormData = ref({
|
||||
mobile: "",
|
||||
code: "",
|
||||
});
|
||||
|
||||
// 仅使用 query 作为重定向来源
|
||||
const redirect = ref("/pages/index/index");
|
||||
onLoad((options) => {
|
||||
onLoad((options: any) => {
|
||||
const fromQuery = options && options.redirect ? decodeURIComponent(options.redirect) : "";
|
||||
if (fromQuery && fromQuery !== "/pages/login/index") {
|
||||
redirect.value = fromQuery;
|
||||
@@ -184,7 +193,7 @@ const handleAccountLogin = () => {
|
||||
uni.reLaunch({ url: redirect.value });
|
||||
}, 1000);
|
||||
})
|
||||
.catch((error) => {
|
||||
.catch((error: any) => {
|
||||
toast.error(error?.message || "登录失败");
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -192,100 +201,63 @@ const handleAccountLogin = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 微信一键登录(通过手机号)
|
||||
const handleWechatPhoneLogin = async (e: any) => {
|
||||
if (loading.value || authState.value.isLogining) return;
|
||||
|
||||
// 检查是否同意隐私协议
|
||||
if (!isAgreePolicy.value) {
|
||||
toast.error("请先阅读并同意用户协议和隐私政策");
|
||||
const handleSendSmsLoginCode = async () => {
|
||||
if (smsCountdown.value > 0) return;
|
||||
if (!smsLoginFormData.value.mobile) {
|
||||
toast.error("请输入手机号");
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
// 获取手机号加密数据
|
||||
const phoneData = await getPhoneNumber(e);
|
||||
|
||||
// 调用登录接口
|
||||
const result: any = await userStore.loginWithWxPhone(phoneData);
|
||||
|
||||
// 获取用户信息
|
||||
await userStore.getInfo();
|
||||
toast.success("登录成功");
|
||||
|
||||
// 检查是否为新用户或信息不完整
|
||||
if (result.isNewUser || !userStore.isUserInfoComplete()) {
|
||||
// 跳转到完善信息页面
|
||||
setTimeout(() => {
|
||||
// 跳转完善资料,redirect 保持在缓存中供目标页读取
|
||||
uni.navigateTo({ url: "/pages/mine/profile/complete-profile" });
|
||||
}, 1000);
|
||||
} else {
|
||||
// 跳转到重定向页面
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({ url: redirect.value });
|
||||
}, 1000);
|
||||
}
|
||||
await AuthAPI.sendSmsLoginCode(smsLoginFormData.value.mobile);
|
||||
toast.success("验证码已发送");
|
||||
smsCountdown.value = 60;
|
||||
if (smsTimer.value) clearInterval(smsTimer.value);
|
||||
smsTimer.value = setInterval(() => {
|
||||
smsCountdown.value -= 1;
|
||||
if (smsCountdown.value <= 0) {
|
||||
smsCountdown.value = 0;
|
||||
if (smsTimer.value) {
|
||||
clearInterval(smsTimer.value);
|
||||
smsTimer.value = null;
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
} catch (error: any) {
|
||||
if (error.message === "用户拒绝授权") {
|
||||
toast.error("您已拒绝授权获取手机号");
|
||||
} else {
|
||||
toast.error(error?.message || "登录失败");
|
||||
}
|
||||
console.error("微信手机号登录失败:", error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
toast.error(error?.message || "发送失败");
|
||||
}
|
||||
};
|
||||
|
||||
// 微信授权登录处理
|
||||
const handleWechatLogin = async () => {
|
||||
const handleSmsLogin = () => {
|
||||
if (loading.value) return;
|
||||
|
||||
// 检查是否同意隐私协议
|
||||
if (!isAgreePolicy.value) {
|
||||
toast.error("请先阅读并同意用户协议和隐私政策");
|
||||
return;
|
||||
}
|
||||
if (!smsLoginFormData.value.mobile) {
|
||||
toast.error("请输入手机号");
|
||||
return;
|
||||
}
|
||||
if (!smsLoginFormData.value.code) {
|
||||
toast.error("请输入验证码");
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
// #ifdef MP-WEIXIN
|
||||
// 获取微信登录的临时 code
|
||||
const code = await getLoginCode();
|
||||
|
||||
// 在微信小程序环境下,使用小程序授权登录接口
|
||||
const result: any = await userStore.loginWithWxMiniAppCode(code);
|
||||
|
||||
// 获取用户信息
|
||||
await userStore.getInfo();
|
||||
toast.success("登录成功");
|
||||
|
||||
// 检查用户信息是否完整
|
||||
if (result.isNewUser || !userStore.isUserInfoComplete()) {
|
||||
// 如果信息不完整,跳转到完善信息页面
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({ url: "/pages/mine/profile/complete-profile" });
|
||||
}, 1000);
|
||||
} else {
|
||||
// 否则直接跳转到重定向页面
|
||||
userStore
|
||||
.loginBySms({ mobile: smsLoginFormData.value.mobile, code: smsLoginFormData.value.code })
|
||||
.then(() => userStore.getInfo())
|
||||
.then(() => {
|
||||
toast.success("登录成功");
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({ url: redirect.value });
|
||||
}, 1000);
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef MP-WEIXIN
|
||||
toast.error("当前环境不支持微信登录");
|
||||
// #endif
|
||||
} catch (error: any) {
|
||||
toast.error(error?.message || "微信登录失败");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
toast.error(error?.message || "登录失败");
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
// 跳转到用户协议页面
|
||||
@@ -416,20 +388,6 @@ const navigateToPrivacy = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 微信按钮
|
||||
.wechat-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
font-size: 32rpx;
|
||||
color: #ffffff;
|
||||
background-color: #07c160;
|
||||
border: none;
|
||||
border-radius: 44rpx;
|
||||
}
|
||||
|
||||
// 其他登录方式
|
||||
.other-login {
|
||||
margin-top: 60rpx;
|
||||
@@ -454,17 +412,6 @@ const navigateToPrivacy = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 微信图标
|
||||
.wechat-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
background-color: #07c160;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
// 登录协议
|
||||
.login-agreement {
|
||||
display: flex;
|
||||
|
||||
@@ -102,22 +102,12 @@
|
||||
手机号
|
||||
<text class="required">*</text>
|
||||
</view>
|
||||
<view v-if="!profileForm.mobile" class="phone-auth">
|
||||
<button
|
||||
class="phone-auth-btn"
|
||||
open-type="getPhoneNumber"
|
||||
:disabled="phoneAuthLoading"
|
||||
@getphonenumber="onGetPhoneNumber"
|
||||
>
|
||||
<wd-icon name="phone" size="20" color="#165DFF" />
|
||||
<text class="auth-text">{{ phoneAuthLoading ? "授权中..." : "授权获取手机号" }}</text>
|
||||
</button>
|
||||
</view>
|
||||
<view v-else class="phone-display">
|
||||
<wd-icon name="phone" size="20" color="#52c41a" />
|
||||
<text class="phone-number">{{ formatPhoneNumber(profileForm.mobile) }}</text>
|
||||
<text class="change-phone" @click="changePhone">更换</text>
|
||||
</view>
|
||||
<wd-input
|
||||
v-model="profileForm.mobile"
|
||||
placeholder="请输入手机号"
|
||||
prop="mobile"
|
||||
custom-class="nickname-input"
|
||||
/>
|
||||
</view>
|
||||
</wd-form>
|
||||
</view>
|
||||
@@ -183,7 +173,6 @@ const rules = {
|
||||
|
||||
// 状态管理
|
||||
const loading = ref(false);
|
||||
const phoneAuthLoading = ref(false);
|
||||
const cropperVisible = ref(false);
|
||||
const originalImageSrc = ref("");
|
||||
const profileFormRef = ref();
|
||||
@@ -280,45 +269,6 @@ const handleAvatarConfirm = async (event: any) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 获取手机号授权
|
||||
const onGetPhoneNumber = async (e: any) => {
|
||||
console.log("手机号授权回调:", e);
|
||||
|
||||
if (e.detail.errMsg === "getPhoneNumber:ok") {
|
||||
phoneAuthLoading.value = true;
|
||||
|
||||
try {
|
||||
// 调用后端接口解析手机号
|
||||
const phoneData = await UserAPI.getPhoneNumber({
|
||||
code: e.detail.code,
|
||||
encryptedData: e.detail.encryptedData,
|
||||
iv: e.detail.iv,
|
||||
});
|
||||
|
||||
profileForm.mobile = phoneData.phoneNumber;
|
||||
toast.success("手机号授权成功");
|
||||
} catch (error: any) {
|
||||
console.error("手机号授权失败:", error);
|
||||
toast.error(error?.message || "手机号授权失败");
|
||||
} finally {
|
||||
phoneAuthLoading.value = false;
|
||||
}
|
||||
} else {
|
||||
toast.error("手机号授权失败");
|
||||
}
|
||||
};
|
||||
|
||||
// 更换手机号
|
||||
const changePhone = () => {
|
||||
profileForm.mobile = "";
|
||||
};
|
||||
|
||||
// 格式化手机号显示
|
||||
const formatPhoneNumber = (phone: string) => {
|
||||
if (!phone) return "";
|
||||
return phone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
|
||||
};
|
||||
|
||||
// 完成信息填写
|
||||
const handleComplete = async () => {
|
||||
try {
|
||||
@@ -327,7 +277,7 @@ const handleComplete = async () => {
|
||||
if (!valid) return;
|
||||
|
||||
if (!profileForm.mobile) {
|
||||
toast.error("请先授权获取手机号");
|
||||
toast.error("请输入手机号");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -477,51 +427,6 @@ const handleSkip = () => {
|
||||
}
|
||||
}
|
||||
|
||||
.phone-auth {
|
||||
.phone-auth-btn {
|
||||
display: flex;
|
||||
gap: 12rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
background: linear-gradient(90deg, #165dff, #4080ff);
|
||||
border: none;
|
||||
border-radius: 12rpx;
|
||||
|
||||
&[disabled] {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.auth-text {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.phone-display {
|
||||
display: flex;
|
||||
gap: 12rpx;
|
||||
align-items: center;
|
||||
padding: 24rpx 20rpx;
|
||||
background: #f0f9ff;
|
||||
border: 1rpx solid #bae6fd;
|
||||
border-radius: 12rpx;
|
||||
|
||||
.phone-number {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.change-phone {
|
||||
font-size: 26rpx;
|
||||
color: #165dff;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
.complete-btn {
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
Reference in New Issue
Block a user