From ad4be7a1978927182f4139794beae82bcdb322ca Mon Sep 17 00:00:00 2001 From: "Ray.Hao" <1490493387@qq.com> Date: Thu, 29 May 2025 17:52:37 +0800 Subject: [PATCH] =?UTF-8?q?wip:=20=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/auth.ts | 23 +-- src/composables/useWechat.ts | 159 ++++++++++++++++++ src/pages.json | 10 +- src/pages/login/index.vue | 120 +++++-------- .../profile}/complete-profile.vue | 0 src/services/wechat.service.ts | 148 ---------------- src/store/modules/user.store.ts | 32 +--- src/utils/auth.ts | 30 ---- src/utils/request.ts | 12 +- uni-pages.d.ts | 2 +- 10 files changed, 219 insertions(+), 317 deletions(-) create mode 100644 src/composables/useWechat.ts rename src/pages/{login => mine/profile}/complete-profile.vue (100%) delete mode 100644 src/services/wechat.service.ts diff --git a/src/api/auth.ts b/src/api/auth.ts index d9e2866..799bed8 100644 --- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -38,39 +38,26 @@ const AuthAPI = { }, /** - * 微信登录 (基础版) + * 微信小程序授权登录 (仅使用code获取OpenID) * @param code 微信登录凭证 * @returns 登录结果 */ wechatLogin(code: string): Promise { return request({ - url: `${AUTH_BASE_URL}/wechat/login`, + url: `${AUTH_BASE_URL}/wx/miniapp/code-login`, method: "POST", data: { code }, }); }, /** - * 微信小程序增强登录 (获取手机号) - * @param data 包含code, encryptedData, iv等的登录数据 - * @returns 登录结果 - */ - wechatMiniLogin(data: WxLoginData): Promise { - return request({ - url: `${AUTH_BASE_URL}/wechat/mini-login`, - method: "POST", - data, - }); - }, - - /** - * 微信一键登录 (通过手机号) - * @param data 包含code和phoneCode的登录数据 + * 微信小程序手机号授权登录 + * @param data 包含code、encryptedData、iv等手机号相关数据 * @returns 登录结果 */ wechatPhoneLogin(data: WxLoginData): Promise { return request({ - url: `${AUTH_BASE_URL}/wechat/phone-login`, + url: `${AUTH_BASE_URL}/wx/miniapp/phone-login`, method: "POST", data, }); diff --git a/src/composables/useWechat.ts b/src/composables/useWechat.ts new file mode 100644 index 0000000..871d938 --- /dev/null +++ b/src/composables/useWechat.ts @@ -0,0 +1,159 @@ +/** + * 微信授权服务 + * 处理微信登录授权、获取用户信息等功能 + */ + +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 => { + 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 => { + 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 => { + 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, + }; +} diff --git a/src/pages.json b/src/pages.json index 6119d05..f3cd0fb 100644 --- a/src/pages.json +++ b/src/pages.json @@ -6,11 +6,6 @@ "style": {}, "layout": "tabbar" }, - { - "path": "pages/login/complete-profile", - "type": "page", - "style": {} - }, { "path": "pages/login/index", "type": "page", @@ -37,6 +32,11 @@ "type": "page", "style": {} }, + { + "path": "pages/mine/profile/complete-profile", + "type": "page", + "style": {} + }, { "path": "pages/mine/profile/index", "type": "page", diff --git a/src/pages/login/index.vue b/src/pages/login/index.vue index 01c8b1c..e442e8c 100644 --- a/src/pages/login/index.vue +++ b/src/pages/login/index.vue @@ -3,48 +3,43 @@ + - - 您好,欢迎回来 - 登录您的账号,开始愉快的旅程 + + 有来开源 + 专注于构建高效开发的应用解决方案