From d3c6823a488fb786f601a311e115a22d192d848b Mon Sep 17 00:00:00 2001 From: Hygge <1727182921@qq.com> Date: Thu, 21 Aug 2025 10:32:54 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20token=20?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E5=8A=9F=E8=83=BD=E5=8F=8A=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 typings.d.ts 中新增 IUserToken 接口 - 在 login.ts 中添加 refreshToken 函数以支持 token 刷新 - 在 types/login.ts 中新增 IUserTokenVo 接口 - 更新 http.ts 以处理 token 刷新逻辑 - 修改 interceptor.ts 以使用新的 token 类型 - 在 user.ts 中整合 token 状态管理 --- src/api/login.ts | 8 +++++ src/api/types/login.ts | 10 ++++++ src/http/http.ts | 72 +++++++++++++++++++++++++++++++++++++++-- src/http/interceptor.ts | 2 +- src/store/user.ts | 38 ++++++++++++++++++++-- src/typings.d.ts | 7 +++- 6 files changed, 131 insertions(+), 6 deletions(-) diff --git a/src/api/login.ts b/src/api/login.ts index de4266d..fcc72af 100644 --- a/src/api/login.ts +++ b/src/api/login.ts @@ -27,6 +27,14 @@ export function login(loginForm: ILoginForm) { return http.post('/user/login', loginForm) } +/** + * 刷新token + * @param refreshToken 刷新token + */ +export function refreshToken(refreshToken: string) { + return http.post('/user/refreshToken', { refreshToken }) +} + /** * 获取用户信息 */ diff --git a/src/api/types/login.ts b/src/api/types/login.ts index d0638cf..2a926b9 100644 --- a/src/api/types/login.ts +++ b/src/api/types/login.ts @@ -5,7 +5,15 @@ export interface IUserInfoVo { id: number username: string avatar: string +} + +/** + * 用户token + */ +export interface IUserTokenVo { token: string + refreshToken?: string + refreshExpire?: number } /** @@ -15,6 +23,8 @@ export interface IUserLogin { id: string username: string token: string + refreshToken?: string + refreshExpire?: number } /** diff --git a/src/http/http.ts b/src/http/http.ts index 98c7324..0b3c244 100644 --- a/src/http/http.ts +++ b/src/http/http.ts @@ -1,4 +1,10 @@ import type { CustomRequestOptions } from '@/http/types' +import { nextTick } from 'vue' +import { useUserStore } from '@/store/user' + +// 刷新 token 状态管理 +let refreshing = false // 防止重复刷新 token 标识 +let taskQueue: (() => void)[] = [] // 刷新 token 请求队列 export function http(options: CustomRequestOptions) { // 1. 返回 Promise 对象 @@ -10,18 +16,80 @@ export function http(options: CustomRequestOptions) { responseType: 'json', // #endif // 响应成功 - success(res) { + success: async (res) => { // 状态码 2xx,参考 axios 的设计 if (res.statusCode >= 200 && res.statusCode < 300) { // 2.1 提取核心数据 res.data - resolve(res.data as IResData) + return resolve(res.data as IResData) } + // 原策略1: 清理用户信息,跳转到登录页 else if (res.statusCode === 401) { // 401错误 -> 清理用户信息,跳转到登录页 // userStore.clearUserInfo() // uni.navigateTo({ url: '/pages/login/login' }) reject(res) } + + /* -------- 策略2:无感刷新 token ----------- */ + const store = useUserStore() + const { refreshToken } = store.userToken || {} + + // token 失效的,且有刷新 token 的,才放到请求队列里 + const resData: IResData = res.data as IResData + if ((res.statusCode === 401 || resData.code === 401) && refreshToken) { + taskQueue.push(() => { + resolve(http(options)) + }) + } + + // 如果有 refreshToken 且未在刷新中,发起刷新 token 请求 + if ((res.statusCode === 401 || resData.code === 401) && refreshToken && !refreshing) { + refreshing = true + try { + // 发起刷新 token 请求(使用 store 的 refreshToken 方法) + await store.refreshToken() + + // 刷新 token 成功 + refreshing = false + + nextTick(() => { + // 关闭其他弹窗 + uni.hideToast() + uni.showToast({ + title: 'token 刷新成功', + icon: 'none', + }) + }) + + // 将任务队列的所有任务重新请求 + taskQueue.forEach(task => task()) + } + catch (refreshErr) { + refreshing = false + + // 刷新 token 失败,跳转到登录页 + nextTick(() => { + // 关闭其他弹窗 + uni.hideToast() + uni.showToast({ + title: '登录已过期,请重新登录', + icon: 'none', + }) + }) + + // 清除用户信息 + await store.logout() + + // 跳转到登录页 + setTimeout(() => { + uni.navigateTo({ url: '/pages/login/login' }) + }, 2000) + } + finally { + // 不管刷新 token 成功与否,都清空任务队列 + taskQueue = [] + } + } else { // 其他错误 -> 根据后端错误信息轻提示 !options.hideErrorToast diff --git a/src/http/interceptor.ts b/src/http/interceptor.ts index 30350b4..7fb0d63 100644 --- a/src/http/interceptor.ts +++ b/src/http/interceptor.ts @@ -48,7 +48,7 @@ const httpInterceptor = { } // 3. 添加 token 请求头标识 const userStore = useUserStore() - const { token } = userStore.userInfo as unknown as IUserInfo + const { token } = userStore.userToken as unknown as IUserToken if (token) { options.header.Authorization = `Bearer ${token}` } diff --git a/src/store/user.ts b/src/store/user.ts index cec931a..f020f99 100644 --- a/src/store/user.ts +++ b/src/store/user.ts @@ -1,10 +1,11 @@ -import type { IUserInfoVo } from '@/api/types/login' +import type { IUserInfoVo, IUserLogin, IUserTokenVo } from '@/api/types/login' import { defineStore } from 'pinia' import { ref } from 'vue' import { getUserInfo as _getUserInfo, login as _login, logout as _logout, + refreshToken as _refreshToken, wxLogin as _wxLogin, getWxCode, } from '@/api/login' @@ -15,7 +16,12 @@ const userInfoState: IUserInfoVo = { id: 0, username: '', avatar: '/static/images/default-avatar.png', +} + +const userTokenState: IUserTokenVo = { token: '', + refreshToken: '', + refreshExpire: 0, } export const useUserStore = defineStore( @@ -23,6 +29,7 @@ export const useUserStore = defineStore( () => { // 定义用户信息 const userInfo = ref({ ...userInfoState }) + const userToken = ref({ ...userTokenState }) // 设置用户信息 const setUserInfo = (val: IUserInfoVo) => { console.log('设置用户信息', val) @@ -43,9 +50,23 @@ export const useUserStore = defineStore( // 删除用户信息 const removeUserInfo = () => { userInfo.value = { ...userInfoState } + userToken.value = { ...userTokenState } uni.removeStorageSync('userInfo') uni.removeStorageSync('token') + uni.removeStorageSync('refreshToken') } + + /** + * 存储token,非导出 + */ + const setToken = (tokenBody: IUserLogin) => { + userToken.value.token = tokenBody.token + userToken.value.refreshToken = tokenBody.refreshToken + userToken.value.refreshExpire = tokenBody.refreshExpire + uni.setStorageSync('token', tokenBody.token) + uni.setStorageSync('refreshToken', tokenBody.refreshToken) + } + /** * 获取用户信息 */ @@ -54,7 +75,6 @@ export const useUserStore = defineStore( const userInfo = res.data setUserInfo(userInfo) uni.setStorageSync('userInfo', userInfo) - uni.setStorageSync('token', userInfo.token) // TODO 这里可以增加获取用户路由的方法 根据用户的角色动态生成路由 return res } @@ -72,6 +92,18 @@ export const useUserStore = defineStore( const res = await _login(credentials) console.log('登录信息', res) toast.success('登录成功') + // 这里设置token 和 refreshToken + setToken(res.data) + await getUserInfo() + return res + } + + /** + * 刷新token + */ + const refreshToken = async () => { + const res = await _refreshToken(userToken.value.refreshToken) + setToken(res.data) await getUserInfo() return res } @@ -98,11 +130,13 @@ export const useUserStore = defineStore( return { userInfo, + userToken, login, wxLogin, getUserInfo, setUserAvatar, logout, + refreshToken, } }, { diff --git a/src/typings.d.ts b/src/typings.d.ts index 9ead3fb..99d7e65 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -21,7 +21,12 @@ declare global { avatar?: string /** 微信的 openid,非微信没有这个字段 */ openid?: string - token?: string + } + + interface IUserToken { + token: string + refreshToken?: string + refreshExpire?: number } } From d9e16baca991c0fefe01de1895dbc3f643b4e5bd Mon Sep 17 00:00:00 2001 From: Hygge <1727182921@qq.com> Date: Thu, 21 Aug 2025 15:49:14 +0800 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20token=20?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E5=8A=9F=E8=83=BD=E5=8F=8A=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=AE=9A=E4=B9=89=20-=20=E5=9C=A8=20typings.?= =?UTF-8?q?d.ts=20=E4=B8=AD=E6=96=B0=E5=A2=9E=20IUserToken=20=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=20-=20=E5=9C=A8=20login.ts=20=E4=B8=AD=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20refreshToken=20=E5=87=BD=E6=95=B0=E4=BB=A5=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20token=20=E5=88=B7=E6=96=B0=20-=20=E5=9C=A8=20types/?= =?UTF-8?q?login.ts=20=E4=B8=AD=E6=96=B0=E5=A2=9E=20IUserTokenVo=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=20-=20=E6=9B=B4=E6=96=B0=20http.ts=20?= =?UTF-8?q?=E4=BB=A5=E5=A4=84=E7=90=86=20token=20=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E9=80=BB=E8=BE=91=20-=20=E4=BF=AE=E6=94=B9=20interceptor.ts=20?= =?UTF-8?q?=E4=BB=A5=E4=BD=BF=E7=94=A8=E6=96=B0=E7=9A=84=20token=20?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=20-=20=E5=9C=A8=20user.ts=20=E4=B8=AD?= =?UTF-8?q?=E6=95=B4=E5=90=88=20token=20=E7=8A=B6=E6=80=81=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- env/.env | 5 ++- src/api/login.ts | 8 +++++ src/api/types/login.ts | 10 ++++++ src/http/http.ts | 77 +++++++++++++++++++++++++++++++++++++---- src/http/interceptor.ts | 2 +- src/store/user.ts | 39 +++++++++++++++++++-- src/typings.d.ts | 7 +++- 7 files changed, 136 insertions(+), 12 deletions(-) diff --git a/env/.env b/env/.env index 8aa561c..f829255 100644 --- a/env/.env +++ b/env/.env @@ -21,4 +21,7 @@ VITE_APP_PROXY_ENABLE = true VITE_APP_PROXY_PREFIX = '/api' # 第二个请求地址 (目前alova中可以使用) -VITE_API_SECONDARY_URL = 'https://ukw0y1.laf.run' \ No newline at end of file +VITE_API_SECONDARY_URL = 'https://ukw0y1.laf.run' + +# TOKEN策略 +VITE_TOKEN_STRATEGY = 'single' \ No newline at end of file diff --git a/src/api/login.ts b/src/api/login.ts index de4266d..fcc72af 100644 --- a/src/api/login.ts +++ b/src/api/login.ts @@ -27,6 +27,14 @@ export function login(loginForm: ILoginForm) { return http.post('/user/login', loginForm) } +/** + * 刷新token + * @param refreshToken 刷新token + */ +export function refreshToken(refreshToken: string) { + return http.post('/user/refreshToken', { refreshToken }) +} + /** * 获取用户信息 */ diff --git a/src/api/types/login.ts b/src/api/types/login.ts index d0638cf..2a926b9 100644 --- a/src/api/types/login.ts +++ b/src/api/types/login.ts @@ -5,7 +5,15 @@ export interface IUserInfoVo { id: number username: string avatar: string +} + +/** + * 用户token + */ +export interface IUserTokenVo { token: string + refreshToken?: string + refreshExpire?: number } /** @@ -15,6 +23,8 @@ export interface IUserLogin { id: string username: string token: string + refreshToken?: string + refreshExpire?: number } /** diff --git a/src/http/http.ts b/src/http/http.ts index 98c7324..31bfaac 100644 --- a/src/http/http.ts +++ b/src/http/http.ts @@ -1,4 +1,13 @@ import type { CustomRequestOptions } from '@/http/types' +import { nextTick } from 'vue' +import { useUserStore } from '@/store/user' + +// 刷新 token 状态管理 +let refreshing = false // 防止重复刷新 token 标识 +let taskQueue: (() => void)[] = [] // 刷新 token 请求队列 + +// token 刷新策略: single-不刷新,double-无感刷新(需后端配合) +const sessionMode = import.meta.env.VITE_TOKEN_STRATEGY === 'double' ? 'double' : 'single' export function http(options: CustomRequestOptions) { // 1. 返回 Promise 对象 @@ -10,17 +19,71 @@ export function http(options: CustomRequestOptions) { responseType: 'json', // #endif // 响应成功 - success(res) { + success: async (res) => { // 状态码 2xx,参考 axios 的设计 if (res.statusCode >= 200 && res.statusCode < 300) { // 2.1 提取核心数据 res.data - resolve(res.data as IResData) + return resolve(res.data as IResData) } - else if (res.statusCode === 401) { - // 401错误 -> 清理用户信息,跳转到登录页 - // userStore.clearUserInfo() - // uni.navigateTo({ url: '/pages/login/login' }) - reject(res) + const resData: IResData = res.data as IResData + if ((res.statusCode === 401) || (resData.code === 401)) { + const store = useUserStore() + if (sessionMode === 'single') { + // 未启用双token策略,清理用户信息,跳转到登录页 + store.logout() + uni.navigateTo({ url: '/pages/login/login' }) + return reject(res) + } + /* -------- 无感刷新 token ----------- */ + const { refreshToken } = store.userToken || {} + // token 失效的,且有刷新 token 的,才放到请求队列里 + if ((res.statusCode === 401 || resData.code === 401) && refreshToken) { + taskQueue.push(() => { + resolve(http(options)) + }) + } + // 如果有 refreshToken 且未在刷新中,发起刷新 token 请求 + if ((res.statusCode === 401 || resData.code === 401) && refreshToken && !refreshing) { + refreshing = true + try { + // 发起刷新 token 请求(使用 store 的 refreshToken 方法) + await store.refreshToken() + // 刷新 token 成功 + refreshing = false + nextTick(() => { + // 关闭其他弹窗 + uni.hideToast() + uni.showToast({ + title: 'token 刷新成功', + icon: 'none', + }) + }) + // 将任务队列的所有任务重新请求 + taskQueue.forEach(task => task()) + } + catch (refreshErr) { + refreshing = false + // 刷新 token 失败,跳转到登录页 + nextTick(() => { + // 关闭其他弹窗 + uni.hideToast() + uni.showToast({ + title: '登录已过期,请重新登录', + icon: 'none', + }) + }) + // 清除用户信息 + await store.logout() + // 跳转到登录页 + setTimeout(() => { + uni.navigateTo({ url: '/pages/login/login' }) + }, 2000) + } + finally { + // 不管刷新 token 成功与否,都清空任务队列 + taskQueue = [] + } + } } else { // 其他错误 -> 根据后端错误信息轻提示 diff --git a/src/http/interceptor.ts b/src/http/interceptor.ts index 30350b4..7fb0d63 100644 --- a/src/http/interceptor.ts +++ b/src/http/interceptor.ts @@ -48,7 +48,7 @@ const httpInterceptor = { } // 3. 添加 token 请求头标识 const userStore = useUserStore() - const { token } = userStore.userInfo as unknown as IUserInfo + const { token } = userStore.userToken as unknown as IUserToken if (token) { options.header.Authorization = `Bearer ${token}` } diff --git a/src/store/user.ts b/src/store/user.ts index cec931a..4e189fa 100644 --- a/src/store/user.ts +++ b/src/store/user.ts @@ -1,10 +1,11 @@ -import type { IUserInfoVo } from '@/api/types/login' +import type { IUserInfoVo, IUserLogin, IUserTokenVo } from '@/api/types/login' import { defineStore } from 'pinia' import { ref } from 'vue' import { getUserInfo as _getUserInfo, login as _login, logout as _logout, + refreshToken as _refreshToken, wxLogin as _wxLogin, getWxCode, } from '@/api/login' @@ -15,7 +16,12 @@ const userInfoState: IUserInfoVo = { id: 0, username: '', avatar: '/static/images/default-avatar.png', +} + +const userTokenState: IUserTokenVo = { token: '', + refreshToken: '', + refreshExpire: 0, } export const useUserStore = defineStore( @@ -23,6 +29,8 @@ export const useUserStore = defineStore( () => { // 定义用户信息 const userInfo = ref({ ...userInfoState }) + const userToken = ref({ ...userTokenState }) + // 设置用户信息 const setUserInfo = (val: IUserInfoVo) => { console.log('设置用户信息', val) @@ -43,9 +51,23 @@ export const useUserStore = defineStore( // 删除用户信息 const removeUserInfo = () => { userInfo.value = { ...userInfoState } + userToken.value = { ...userTokenState } uni.removeStorageSync('userInfo') uni.removeStorageSync('token') + uni.removeStorageSync('refreshToken') } + + /** + * 存储token,非导出 + */ + const setToken = (tokenBody: IUserLogin) => { + userToken.value.token = tokenBody.token + userToken.value.refreshToken = tokenBody.refreshToken + userToken.value.refreshExpire = tokenBody.refreshExpire + uni.setStorageSync('token', tokenBody.token) + uni.setStorageSync('refreshToken', tokenBody.refreshToken) + } + /** * 获取用户信息 */ @@ -54,7 +76,6 @@ export const useUserStore = defineStore( const userInfo = res.data setUserInfo(userInfo) uni.setStorageSync('userInfo', userInfo) - uni.setStorageSync('token', userInfo.token) // TODO 这里可以增加获取用户路由的方法 根据用户的角色动态生成路由 return res } @@ -72,6 +93,18 @@ export const useUserStore = defineStore( const res = await _login(credentials) console.log('登录信息', res) toast.success('登录成功') + // 这里设置token 和 refreshToken + setToken(res.data) + await getUserInfo() + return res + } + + /** + * 刷新token + */ + const refreshToken = async () => { + const res = await _refreshToken(userToken.value.refreshToken) + setToken(res.data) await getUserInfo() return res } @@ -98,11 +131,13 @@ export const useUserStore = defineStore( return { userInfo, + userToken, login, wxLogin, getUserInfo, setUserAvatar, logout, + refreshToken, } }, { diff --git a/src/typings.d.ts b/src/typings.d.ts index 9ead3fb..99d7e65 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -21,7 +21,12 @@ declare global { avatar?: string /** 微信的 openid,非微信没有这个字段 */ openid?: string - token?: string + } + + interface IUserToken { + token: string + refreshToken?: string + refreshExpire?: number } } From 7036d0d0d63a5a2583935bc18402109bbff9065f Mon Sep 17 00:00:00 2001 From: feige996 <1020102647@qq.com> Date: Thu, 21 Aug 2025 16:10:08 +0800 Subject: [PATCH 3/5] =?UTF-8?q?docs(env):=20=E6=B7=BB=E5=8A=A0TOKEN?= =?UTF-8?q?=E7=AD=96=E7=95=A5=E7=9A=84=E6=B3=A8=E9=87=8A=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在.env和env.d.ts文件中添加关于VITE_TOKEN_STRATEGY的注释,说明single和double两种策略的含义 --- env/.env | 2 +- src/env.d.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/env/.env b/env/.env index f829255..c6d37d8 100644 --- a/env/.env +++ b/env/.env @@ -23,5 +23,5 @@ VITE_APP_PROXY_PREFIX = '/api' # 第二个请求地址 (目前alova中可以使用) VITE_API_SECONDARY_URL = 'https://ukw0y1.laf.run' -# TOKEN策略 +# TOKEN策略,single:单token,double:双token VITE_TOKEN_STRATEGY = 'single' \ No newline at end of file diff --git a/src/env.d.ts b/src/env.d.ts index 47684d4..edc7f8c 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -19,6 +19,8 @@ interface ImportMetaEnv { readonly VITE_APP_PROXY_ENABLE: 'true' | 'false' /** H5是否需要代理,需要的话有个前缀 */ readonly VITE_APP_PROXY_PREFIX: string // 一般是/api + /** TOKEN策略,single:单token,double:双token */ + readonly VITE_TOKEN_STRATEGY: 'single' | 'double' /** 上传图片地址 */ readonly VITE_UPLOAD_BASEURL: string /** 是否清除console */ From 2fb1e63059594ea628bf844d6525ac60c8107d11 Mon Sep 17 00:00:00 2001 From: feige996 <1020102647@qq.com> Date: Thu, 21 Aug 2025 16:13:58 +0800 Subject: [PATCH 4/5] =?UTF-8?q?chore:=20=E6=8D=95=E8=8E=B7=E5=B9=B6?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E5=88=B7=E6=96=B0=20token=20=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 console.error 输出刷新 token 失败的错误信息,便于调试和问题追踪 --- src/http/http.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/http/http.ts b/src/http/http.ts index 31bfaac..bb7555f 100644 --- a/src/http/http.ts +++ b/src/http/http.ts @@ -62,6 +62,7 @@ export function http(options: CustomRequestOptions) { taskQueue.forEach(task => task()) } catch (refreshErr) { + console.error('刷新 token 失败:', refreshErr) refreshing = false // 刷新 token 失败,跳转到登录页 nextTick(() => { From cfd949db3b03c0ca788c29f0decb33863b5ed0e8 Mon Sep 17 00:00:00 2001 From: feige996 <1020102647@qq.com> Date: Thu, 21 Aug 2025 16:18:28 +0800 Subject: [PATCH 5/5] =?UTF-8?q?feat(router):=20=E5=A2=9E=E5=8A=A0=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E6=8B=A6=E6=88=AA=E5=99=A8=E7=9A=84query=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=94=AF=E6=8C=81=E5=B9=B6=E4=BC=98=E5=8C=96=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 处理直接进入页面时传递query参数的情况,同时将路由处理逻辑从onLaunch移到onShow中 --- src/App.vue | 10 +++++----- src/router/interceptor.ts | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/App.vue b/src/App.vue index b0d9043..e948c0f 100644 --- a/src/App.vue +++ b/src/App.vue @@ -5,11 +5,14 @@ import { tabbarStore } from './tabbar/store' import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only' onLaunch((options) => { + console.log('App Launch', options) +}) +onShow((options) => { + console.log('App Show', options) // 处理直接进入页面路由的情况:如h5直接输入路由、微信小程序分享后进入等 // https://github.com/unibest-tech/unibest/issues/192 - console.log('App Launch', options) if (options?.path) { - navigateToInterceptor.invoke({ url: `/${options.path}` }) + navigateToInterceptor.invoke({ url: `/${options.path}`, query: options.query }) } else { navigateToInterceptor.invoke({ url: '/' }) @@ -17,9 +20,6 @@ onLaunch((options) => { // 处理直接进入路由非首页时,tabbarIndex 不正确的问题 tabbarStore.setAutoCurIdx(options.path) }) -onShow((options) => { - console.log('App Show', options) -}) onHide(() => { console.log('App Hide') }) diff --git a/src/router/interceptor.ts b/src/router/interceptor.ts index 14c5535..d4f59e3 100644 --- a/src/router/interceptor.ts +++ b/src/router/interceptor.ts @@ -22,8 +22,9 @@ const isDev = import.meta.env.DEV export const navigateToInterceptor = { // 注意,这里的url是 '/' 开头的,如 '/pages/index/index',跟 'pages.json' 里面的 path 不同 // 增加对相对路径的处理,BY 网友 @ideal - invoke({ url }: { url: string }) { - // console.log(url) // /pages/route-interceptor/index?name=feige&age=30 + invoke({ url, query }: { url: string, query?: Record }) { + console.log(url) // /pages/route-interceptor/index?name=feige&age=30 + console.log(query) // /pages/route-interceptor/index?name=feige&age=30 let path = url.split('?')[0] // 处理相对路径