diff --git a/huakai-app/manifest.json b/huakai-app/manifest.json index 568f43f..78f1196 100644 --- a/huakai-app/manifest.json +++ b/huakai-app/manifest.json @@ -96,7 +96,7 @@ "quickapp" : {}, /* 小程序特有相关 */ "mp-weixin" : { - "appid" : "wxa6184796ceba80ca", + "appid" : "wx40625124315d2de1", "setting" : { "urlCheck" : false }, diff --git a/huakai-app/pageSubPack/api/auth.js b/huakai-app/pageSubPack/api/auth.js new file mode 100644 index 0000000..e790384 --- /dev/null +++ b/huakai-app/pageSubPack/api/auth.js @@ -0,0 +1,85 @@ +/** + * 登录状态管理工具 + * 仅在用户点击需要身份认证的功能时才要求登录 + */ + +/** + * 检查用户是否已登录 + * @returns {boolean} true 已登录,false 未登录 + */ +export function isLoggedIn() { + const token = uni.getStorageSync('token'); + return !!token; +} + +/** + * 要求登录 — 未登录时跳转登录页,已登录直接执行回调 + * 登录页提供返回/取消按钮,用户可拒绝登录 + * + * @param {Object} options + * @param {Function} [options.onLoggedIn] - 已登录或登录成功后执行的回调 + * @param {string} [options.title] - 展示给用户的提示标题(为什么需要登录) + * @param {Function} [options.onCancel] - 用户取消登录后的回调 + */ +export function requireAuth({ onLoggedIn, title, onCancel } = {}) { + if (isLoggedIn()) { + if (onLoggedIn) onLoggedIn(); + return; + } + + // 弹窗询问用户是否去登录,用户可拒绝("暂不") + const tipTitle = title ? `"${title}"需要登录` : '该功能需要登录'; + uni.showModal({ + title: '提示', + content: `${tipTitle},是否去登录?`, + confirmText: '去登录', + cancelText: '暂不', + success: (modalRes) => { + if (modalRes.confirm) { + // 用户点击"去登录" + uni.setStorageSync('pendingAuthCallback', { + time: Date.now(), + title: title || '' + }); + + uni.navigateTo({ + url: '/pageSubPack/loginSub/pwd-login', + events: { + loginSuccess: () => { + if (onLoggedIn) onLoggedIn(); + uni.removeStorageSync('pendingAuthCallback'); + } + } + }); + } else { + // 用户点击"暂不",留在当前页 + if (onCancel) onCancel(); + } + } + }); +} + +/** + * 清除登录状态 + */ +export function clearLoginState() { + uni.removeStorageSync('token'); + uni.removeStorageSync('userId'); + uni.removeStorageSync('currentVillageId'); + uni.removeStorageSync('pendingAuthCallback'); +} + +/** + * 保存登录成功后的 token 和用户信息 + * @param {Object} data - 登录接口返回的 data + */ +export function saveLoginData(data) { + if (data.token) { + uni.setStorageSync('token', data.token); + } + if (data.userId) { + uni.setStorageSync('userId', data.userId); + } + const currentVillageId = data.currentVillageId || 0; + uni.setStorageSync('currentVillageId', currentVillageId); +} diff --git a/huakai-app/pageSubPack/api/request.js b/huakai-app/pageSubPack/api/request.js index c52df1f..0d29659 100644 --- a/huakai-app/pageSubPack/api/request.js +++ b/huakai-app/pageSubPack/api/request.js @@ -42,12 +42,20 @@ export default function request(url, data = {}, method = "GET") { const resData = res.data || {}; - // token 过期 + // token 过期 — 清除登录态,提示用户,但不强制跳转(用户可继续浏览非敏感页面) if (resData.code === 401) { - uni.showToast({ title: '登录过期,请重新登录', icon: 'none' }); - uni.clearStorageSync('token'); + uni.showToast({ title: '登录已过期,请重新登录', icon: 'none', duration: 2000 }); + uni.removeStorageSync('token'); + uni.removeStorageSync('userId'); + // 使用 navigateTo 而非 reLaunch,用户可通过返回按钮退出登录页 setTimeout(() => { - uni.reLaunch({ url: '/pageSubPack/loginSub/pwd-login' }); + uni.navigateTo({ + url: '/pageSubPack/loginSub/pwd-login', + fail: () => { + // 如果 navigateTo 失败(如页面栈满),则用 reLaunch + uni.reLaunch({ url: '/pageSubPack/loginSub/pwd-login' }); + } + }); }, 1500); reject({ msg: '登录过期', code: 401 }); return; @@ -102,4 +110,4 @@ export const upload = (filePath, url) => { } }); }); -}; \ No newline at end of file +}; diff --git a/huakai-app/pageSubPack/loginSub/login.vue b/huakai-app/pageSubPack/loginSub/login.vue index 89f3e53..9018a10 100644 --- a/huakai-app/pageSubPack/loginSub/login.vue +++ b/huakai-app/pageSubPack/loginSub/login.vue @@ -1,6 +1,13 @@