chore: 移除微信授权登录
This commit is contained in:
@@ -7,13 +7,6 @@ export interface LoginData {
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface WxLoginData {
|
||||
code: string;
|
||||
encryptedData?: string;
|
||||
iv?: string;
|
||||
phoneCode?: string;
|
||||
}
|
||||
|
||||
export interface LoginResult {
|
||||
accessToken: string;
|
||||
refreshToken?: string;
|
||||
@@ -23,6 +16,11 @@ export interface LoginResult {
|
||||
isProfileComplete?: boolean;
|
||||
}
|
||||
|
||||
export interface SmsLoginData {
|
||||
mobile: string;
|
||||
code: string;
|
||||
}
|
||||
|
||||
const AuthAPI = {
|
||||
/**
|
||||
* 账号密码登录
|
||||
@@ -37,42 +35,20 @@ const AuthAPI = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 微信Web授权登录 (使用code进行授权登录)
|
||||
* @param code 微信授权码
|
||||
* @returns 登录结果
|
||||
*/
|
||||
loginByWechat(code: string): Promise<LoginResult> {
|
||||
return publicRequest<LoginResult>({
|
||||
url: `${AUTH_BASE_URL}/login/wechat`,
|
||||
sendSmsLoginCode(mobile: string): Promise<void> {
|
||||
const mobileSafe = encodeURIComponent(mobile);
|
||||
return publicRequest<void>({
|
||||
url: `${AUTH_BASE_URL}/sms/code?mobile=${mobileSafe}`,
|
||||
method: "POST",
|
||||
data: { code },
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 微信小程序授权登录 (仅使用code获取OpenID)
|
||||
* @param code 微信登录凭证
|
||||
* @returns 登录结果
|
||||
*/
|
||||
loginByWxMiniAppCode(code: string): Promise<LoginResult> {
|
||||
loginBySms(data: SmsLoginData): Promise<LoginResult> {
|
||||
const mobileSafe = encodeURIComponent(data.mobile);
|
||||
const codeSafe = encodeURIComponent(data.code);
|
||||
return publicRequest<LoginResult>({
|
||||
url: `${AUTH_BASE_URL}/wx/miniapp/code-login`,
|
||||
url: `${AUTH_BASE_URL}/login/sms?mobile=${mobileSafe}&code=${codeSafe}`,
|
||||
method: "POST",
|
||||
data: { code },
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 微信小程序手机号授权登录
|
||||
* @param data 包含code、encryptedData、iv等手机号相关数据
|
||||
* @returns 登录结果
|
||||
*/
|
||||
loginByWxMiniAppPhone(data: WxLoginData): Promise<LoginResult> {
|
||||
return publicRequest<LoginResult>({
|
||||
url: `${AUTH_BASE_URL}/wx/miniapp/phone-login`,
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -25,10 +25,7 @@ const UserAPI = {
|
||||
url: `${USER_BASE_URL}`,
|
||||
method: "GET",
|
||||
data: queryParams,
|
||||
}).then((res: { data: UserPageVO[]; page?: { total?: number } }) => ({
|
||||
list: res.data,
|
||||
total: res.page?.total ?? 0,
|
||||
}));
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 添加用户
|
||||
@@ -138,15 +135,6 @@ const UserAPI = {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
|
||||
/** 获取微信手机号 */
|
||||
getPhoneNumber(data: WechatPhoneData): Promise<PhoneNumberResult> {
|
||||
return request<PhoneNumberResult>({
|
||||
url: `${USER_BASE_URL}/wechat-phone`,
|
||||
method: "POST",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
};
|
||||
export default UserAPI;
|
||||
|
||||
@@ -326,23 +314,3 @@ export interface UserForm {
|
||||
/** 用户名 */
|
||||
username?: string;
|
||||
}
|
||||
|
||||
/** 微信手机号授权数据 */
|
||||
export interface WechatPhoneData {
|
||||
/** 微信授权码 */
|
||||
code: string;
|
||||
/** 加密数据 */
|
||||
encryptedData?: string;
|
||||
/** 初始向量 */
|
||||
iv?: string;
|
||||
}
|
||||
|
||||
/** 手机号获取结果 */
|
||||
export interface PhoneNumberResult {
|
||||
/** 手机号 */
|
||||
phoneNumber: string;
|
||||
/** 纯手机号(去除+86) */
|
||||
purePhoneNumber?: string;
|
||||
/** 国家代码 */
|
||||
countryCode?: string;
|
||||
}
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
/**
|
||||
* 微信授权服务
|
||||
* 处理微信登录授权、获取用户信息等功能
|
||||
*/
|
||||
|
||||
import { ref } from "vue";
|
||||
import { getAccessToken } from "@/utils/auth";
|
||||
|
||||
export function useWechat() {
|
||||
// 定义微信授权状态
|
||||
const authState = ref({
|
||||
isLogining: false,
|
||||
authDenied: false,
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取微信登录凭证code
|
||||
* @returns Promise 返回登录凭证code
|
||||
*/
|
||||
const getLoginCode = (): Promise<string> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.login({
|
||||
provider: "weixin",
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
resolve(res.code);
|
||||
} else {
|
||||
reject(new Error("获取微信登录凭证失败"));
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(err);
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifndef MP-WEIXIN
|
||||
reject(new Error("当前环境不支持微信登录"));
|
||||
// #endif
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取微信用户手机号
|
||||
* @param e 微信授权返回的事件对象
|
||||
* @returns Promise 返回包含手机号加密数据的对象
|
||||
*/
|
||||
const getPhoneNumber = (
|
||||
e: any
|
||||
): Promise<{ code: string; encryptedData?: string; iv?: string }> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
authState.value.isLogining = true;
|
||||
|
||||
// 判断授权是否成功
|
||||
if (e.detail.errMsg !== "getPhoneNumber:ok") {
|
||||
authState.value.isLogining = false;
|
||||
authState.value.authDenied = true;
|
||||
reject(new Error("用户拒绝授权"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取登录凭证code
|
||||
getLoginCode()
|
||||
.then((code) => {
|
||||
// 在微信小程序环境下,可以获取encryptedData和iv
|
||||
// #ifdef MP-WEIXIN
|
||||
resolve({
|
||||
code,
|
||||
encryptedData: e.detail.encryptedData,
|
||||
iv: e.detail.iv,
|
||||
});
|
||||
// #endif
|
||||
|
||||
// 其他环境或新版本接口
|
||||
// #ifndef MP-WEIXIN
|
||||
resolve({
|
||||
code,
|
||||
// 新版本接口在e.detail.code中包含手机号获取凭证
|
||||
...(e.detail.code ? { phoneCode: e.detail.code } : {}),
|
||||
});
|
||||
// #endif
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
})
|
||||
.finally(() => {
|
||||
authState.value.isLogining = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 检查会话有效性
|
||||
* @returns Promise 返回会话是否有效
|
||||
*/
|
||||
const checkSession = (): Promise<boolean> => {
|
||||
return new Promise((resolve) => {
|
||||
const token = getAccessToken();
|
||||
|
||||
if (!token) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用后端接口验证token有效性
|
||||
uni.request({
|
||||
url: "/api/v1/auth/check-session",
|
||||
method: "GET",
|
||||
header: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
success: (res: any) => {
|
||||
if (res.statusCode === 200 && res.data.valid) {
|
||||
resolve(true);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
resolve(false);
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取用户头像昵称
|
||||
* 注意:此接口已于2021年弃用,仅作为兼容保留
|
||||
* 推荐使用button组件的open-type="chooseAvatar"让用户选择头像
|
||||
*/
|
||||
const getUserProfile = (): Promise<any> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.getUserProfile({
|
||||
desc: "用于完善用户资料",
|
||||
success: (res) => {
|
||||
resolve(res.userInfo);
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(err);
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifndef MP-WEIXIN
|
||||
reject(new Error("当前环境不支持获取用户信息"));
|
||||
// #endif
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
authState,
|
||||
getLoginCode,
|
||||
getPhoneNumber,
|
||||
checkSession,
|
||||
getUserProfile,
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defineStore } from "pinia";
|
||||
import AuthAPI, { type LoginData, type WxLoginData } from "@/api/auth";
|
||||
import AuthAPI, { type LoginData, type SmsLoginData } from "@/api/auth";
|
||||
import UserAPI, { type UserInfo } from "@/api/user";
|
||||
import { setAccessToken, clearTokens } from "@/utils/auth";
|
||||
import { getUserInfo, setUserInfo } from "@/utils/storage";
|
||||
@@ -24,46 +24,15 @@ export const useUserStore = defineStore("user", () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 微信Web授权登录
|
||||
const loginWithWxCode = (code: string) => {
|
||||
const loginBySms = (data: SmsLoginData) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
AuthAPI.loginByWechat(code)
|
||||
AuthAPI.loginBySms(data)
|
||||
.then((data) => {
|
||||
setAccessToken(data.accessToken);
|
||||
resolve(data);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error("微信授权登录失败", error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 微信小程序授权登录 (仅使用code获取OpenID)
|
||||
const loginWithWxMiniAppCode = (code: string) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
AuthAPI.loginByWxMiniAppCode(code)
|
||||
.then((data) => {
|
||||
setAccessToken(data.accessToken);
|
||||
resolve(data);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error("微信小程序授权登录失败", error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 微信手机号授权登录
|
||||
const loginWithWxPhone = (data: WxLoginData): Promise<any> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
AuthAPI.loginByWxMiniAppPhone(data)
|
||||
.then((result: any) => {
|
||||
setAccessToken(result.accessToken);
|
||||
resolve(result);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error("微信手机号登录失败", error);
|
||||
.catch((error) => {
|
||||
console.error("登录失败", error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
@@ -126,9 +95,7 @@ export const useUserStore = defineStore("user", () => {
|
||||
return {
|
||||
userInfo,
|
||||
login,
|
||||
loginWithWxCode,
|
||||
loginWithWxMiniAppCode,
|
||||
loginWithWxPhone,
|
||||
loginBySms,
|
||||
logout,
|
||||
getInfo,
|
||||
checkSession,
|
||||
|
||||
2
src/types/auto-imports.d.ts
vendored
2
src/types/auto-imports.d.ts
vendored
@@ -179,7 +179,6 @@ declare global {
|
||||
const useUploadFile: typeof import('@uni-helper/uni-use')['useUploadFile']
|
||||
const useUserStore: typeof import('../store/modules/user-store')['useUserStore']
|
||||
const useVisible: typeof import('@uni-helper/uni-use')['useVisible']
|
||||
const useWechat: typeof import('../composables/useWechat')['useWechat']
|
||||
const user: typeof import('../api/user')['default']
|
||||
const watch: typeof import('vue')['watch']
|
||||
const watchEffect: typeof import('vue')['watchEffect']
|
||||
@@ -320,7 +319,6 @@ declare module 'vue' {
|
||||
readonly useThemeStore: UnwrapRef<typeof import('../store/modules/theme-store')['useThemeStore']>
|
||||
readonly useToast: UnwrapRef<typeof import('wot-design-uni')['useToast']>
|
||||
readonly useUserStore: UnwrapRef<typeof import('../store/modules/user-store')['useUserStore']>
|
||||
readonly useWechat: UnwrapRef<typeof import('../composables/useWechat')['useWechat']>
|
||||
readonly user: UnwrapRef<typeof import('../api/user')['default']>
|
||||
readonly watch: UnwrapRef<typeof import('vue')['watch']>
|
||||
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
|
||||
|
||||
@@ -54,11 +54,7 @@ function request<T = any>(options: RequestOptions): Promise<T> {
|
||||
success: (res: any) => {
|
||||
// 请求成功
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
if (res.data && typeof res.data === "object" && "page" in res.data && res.data.page != null) {
|
||||
resolve({ data: res.data.data, page: res.data.page } as any);
|
||||
} else {
|
||||
resolve(res.data.data);
|
||||
}
|
||||
resolve(res.data.data);
|
||||
}
|
||||
// 未授权错误
|
||||
else if (res.statusCode === 401) {
|
||||
|
||||
Reference in New Issue
Block a user