From bb183e89fcbe43526c7b2e38f354e75e6d6966a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=81=E6=9D=B0?= <727475508@qq.com> Date: Fri, 12 Jun 2026 10:45:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=A6=96=E9=A1=B5=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E7=9B=91=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.vue | 3 ++- CHANGE_RECORD.md | 50 +++++++++++++++++++++++++++++++++++++++++++ pages/home/home.vue | 52 ++++++++++++++++++++++++++++++--------------- utils/request.js | 17 +++++++++++---- 4 files changed, 100 insertions(+), 22 deletions(-) create mode 100644 CHANGE_RECORD.md diff --git a/App.vue b/App.vue index 02d00d3..af33f22 100644 --- a/App.vue +++ b/App.vue @@ -183,6 +183,7 @@ export default { onShow: function () { uni.hideTabBar(); console.log('App Show') + uni.$emit('appShowRefresh') }, onHide: function () { console.log('App Hide') @@ -281,4 +282,4 @@ body { -webkit-text-size-adjust: 100% !important; text-size-adjust: 100% !important; } - \ No newline at end of file + diff --git a/CHANGE_RECORD.md b/CHANGE_RECORD.md new file mode 100644 index 0000000..abf7453 --- /dev/null +++ b/CHANGE_RECORD.md @@ -0,0 +1,50 @@ +# 改动记录 + +## 2026-06-12 + +### 后台长时间运行后首页登录态不同步 + +问题现象: + +- APP 后台运行较长时间后再次进入。 +- 商家首页显示未登录或无法及时获取商家信息。 +- “我的”页面仍显示已登录。 +- 从“我的”页面切回首页后,首页才能正常获取商家信息。 + +涉及文件: + +- `App.vue` +- `pages/home/home.vue` +- `utils/request.js` + +改动内容: + +- `App.vue` + - 在全局 `onShow` 中新增 `uni.$emit('appShowRefresh')`。 + - APP 从后台恢复前台时主动通知页面刷新状态,避免只依赖页面级 `onShow`。 + +- `pages/home/home.vue` + - 新增 `refreshPageState` 方法,统一处理首页登录态刷新。 + - `onShow`、下拉刷新、APP 前台恢复事件都调用同一套刷新逻辑。 + - `onLoad` 注册 `appShowRefresh` 事件。 + - `onUnload` 解除 `appShowRefresh` 事件,避免重复监听。 + - 有 token 时主动重新请求 `/sj/user/getUser`。 + - 无 token 时清空 `userInfo`、`authDetails`、`sjId`,并重置 `isUserInfoLoaded`。 + - `getUserInfo` 请求成功后显式设置 `isLogin = true` 和 `isUserInfoLoaded = true`。 + - `getUserInfo` 请求失败时,如果本地 token 已被清理,则同步首页为未登录状态。 + +- `utils/request.js` + - `refreshToken` 兼容后端返回结构: + - 支持 token 在 `res.access_token`。 + - 支持 token 在 `res.data.access_token`。 + - 刷新 token 成功后同步更新: + - `accessToken` + - `refreshToken` + - `refresh_token_expries` + - 如果刷新接口成功但没有返回 `access_token`,主动抛错,避免写入 `undefined` token。 + +验证情况: + +- 已检查相关 diff,未做全文件重构。 +- `pages/home/home.vue` 原文件为 CRLF 行尾;为避免整文件行尾改造造成大面积 diff,本次保留原行尾。 +- 项目 `package.json` 未配置 build/lint 脚本,未执行完整构建校验。 diff --git a/pages/home/home.vue b/pages/home/home.vue index 268ce72..bdb1deb 100644 --- a/pages/home/home.vue +++ b/pages/home/home.vue @@ -401,24 +401,11 @@ export default { } }, onShow() { - // 登录判定逻辑 - this.isLogin = uni.getStorageSync("accessToken") ? true : false; - if (this.isLogin) { - this.getUserInfo(); - } - // 通知、品牌、技能 这三个接口不强依赖登录,无论登没登录都获取 - this.fetchNoticeList(); - this.fetchBrandList(); - this.fetchSkillList(); + this.refreshPageState(); }, onPullDownRefresh() { // 1. 重新请求首页需要的所有数据 - if (this.isLogin) { - this.getUserInfo(); - } - this.fetchNoticeList(); - this.fetchBrandList(); - this.fetchSkillList(); + this.refreshPageState(); // 2. 停止下拉刷新的动画 setTimeout(() => { @@ -427,6 +414,10 @@ export default { }, onLoad() { uni.hideTabBar(); + uni.$on('appShowRefresh', this.refreshPageState); + }, + onUnload() { + uni.$off('appShowRefresh', this.refreshPageState); }, watch: { 'orderDetail.score'() { @@ -434,6 +425,22 @@ export default { } }, methods: { + refreshPageState() { + const hasToken = !!uni.getStorageSync("accessToken"); + this.isLogin = hasToken; + if (hasToken) { + this.getUserInfo(); + } else { + this.userInfo = {}; + this.authDetails = null; + this.isUserInfoLoaded = false; + this.sjId = null; + } + // 通知、品牌、技能 这三个接口不强依赖登录,无论登没登录都获取 + this.fetchNoticeList(); + this.fetchBrandList(); + this.fetchSkillList(); + }, // 金额转换万单位处理 formatMoney(amount) { let num = parseFloat(amount); @@ -589,9 +596,11 @@ export default { }, getUserInfo() { - request.post("/sj/user/getUser").then((result) => { + this.isUserInfoLoaded = false; + return request.post("/sj/user/getUser").then((result) => { if (result.code == 200 && result.data) { this.userInfo = result.data; + this.isLogin = true; this.isUserInfoLoaded = true; // 数据回来了,允许相关 UI 进行渲染 uni.setStorageSync("sjId", result.data.id); this.sjId = result.data.id; @@ -607,6 +616,15 @@ export default { this.fetchAuthDetails(); } } + }).catch((err) => { + if (!uni.getStorageSync("accessToken")) { + this.isLogin = false; + this.userInfo = {}; + this.authDetails = null; + this.sjId = null; + } + this.isUserInfoLoaded = false; + console.error("首页获取商家信息失败:", err); }); }, @@ -1579,4 +1597,4 @@ page { overflow: hidden; } } - \ No newline at end of file + diff --git a/utils/request.js b/utils/request.js index de82905..cfa905c 100644 --- a/utils/request.js +++ b/utils/request.js @@ -279,9 +279,18 @@ async function refreshToken() { }) if (res.state == 1 || res.code == 200) { - uni.setStorageSync('accessToken', res.access_token) - uni.setStorageSync('refreshToken', res.refresh_token) - return res.access_token + const tokenData = res.data || res + if (!tokenData.access_token) { + throw new Error('Refresh token response missing access_token') + } + uni.setStorageSync('accessToken', tokenData.access_token) + if (tokenData.refresh_token) { + uni.setStorageSync('refreshToken', tokenData.refresh_token) + } + if (tokenData.refresh_token_expries) { + uni.setStorageSync('refresh_token_expries', tokenData.refresh_token_expries) + } + return tokenData.access_token } throw new Error('Refresh token failed') @@ -340,4 +349,4 @@ export default { ...options }) } -} \ No newline at end of file +}