From bdd6bd1066076983065f2b234d9d402b35df066f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Fri, 13 Mar 2026 10:17:12 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=20=20token=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=20=20=E5=8F=8A=20=E9=87=8D=E5=AE=9A=E5=90=91=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.vue | 7 +++ api/apiT.js | 62 ++++++++++++++++++++++++-- manifest.json | 2 +- pages.json | 6 +-- pages/index/index.vue | 2 +- project.config.json | 25 +++++++++++ project.private.config.json | 14 ++++++ utils/auth.js | 88 +++++++++++++++++++++++++++++++++++++ 8 files changed, 198 insertions(+), 8 deletions(-) create mode 100644 project.config.json create mode 100644 project.private.config.json create mode 100644 utils/auth.js diff --git a/App.vue b/App.vue index ede0bba..43212e3 100644 --- a/App.vue +++ b/App.vue @@ -21,6 +21,13 @@ onHide: function() { console.log('App Hide') }, + onPageNotFound: function(res) { + console.log('页面不存在', res); + // 重定向到首页 + uni.reLaunch({ + url: '/pages/index/index' + }); + }, globalData: { test: '' }, diff --git a/api/apiT.js b/api/apiT.js index 90bfbde..63b788f 100644 --- a/api/apiT.js +++ b/api/apiT.js @@ -2,23 +2,79 @@ // const baseUrl = "https://api.collect.xyh.muzili.top/"; //这里放置url域名32044 const baseUrl = "https://bsh.info.yw.hnzhwlkj.cn/"; //这里放置url域名32044 // const baseUrl = "https://114.215.24.240:8106/api/v1/"; //这里放置url域名32044 +import { loginOnce } from '@/utils/auth.js'; + +// 正在重试的请求队列 +const retryQueue = []; +let isRefreshing = false; + +/** + * 处理 401 错误,重新登录后重试请求 + */ +async function handle401Error(originalOptions) { + return new Promise((resolve, reject) => { + // 将请求加入队列 + retryQueue.push({ options: originalOptions, resolve, reject }); + + // 如果没有正在刷新 token,开始刷新 + if (!isRefreshing) { + isRefreshing = true; + + loginOnce().then((result) => { + isRefreshing = false; + + if (result.success) { + // 登录成功,重试所有队列中的请求 + retryQueue.forEach(({ options, resolve, reject }) => { + request(options).then(resolve).catch(reject); + }); + // 清空队列 + retryQueue.length = 0; + } else { + // 登录失败,拒绝所有队列中的请求 + retryQueue.forEach(({ reject }) => { + reject({ data: { message: '登录失败,请重新登录' } }); + }); + retryQueue.length = 0; + } + }); + } + }); +} + export function request(options){//封装的requset let { url,data,method } = options; data = data || {}, uni.showLoading({ title: '' }); - + return new Promise((resolve,rejext)=>{ uni.request({//这里是uniapp网络请求的api url: baseUrl + url, //仅为示例,并非真实接口地址。 data, header:{'content-type': 'application/x-www-form-urlencoded','Fdesk-Auth-Token': 'Bearer ' + uni.getStorageSync('token'),'Fdesk-Language': uni.getStorageSync('i18locale')?uni.getStorageSync('i18locale'):'zh','Fdesk-Login-Type': 'wechat','Fdesk-System-Code':'wechat'}, method:method||"GET",//默认请求方式是get - success: (res) => { + success: async (res) => { uni.hideLoading(); - resolve(res) + + // 检查 401 错误(可能是 res.statusCode === 401 或 res.data.code === 401) + if (res.statusCode === 401 || (res.data && res.data.code === 401)) { + console.log('Token expired, attempting silent login...'); + try { + const retryResult = await handle401Error(options); + resolve(retryResult); + } catch (error) { + resolve(res); // 返回原始错误响应 + } + } else { + resolve(res); + } }, + fail: (err) => { + uni.hideLoading(); + rejext(err); + }, complete: (data)=>{ uni.hideLoading(); } diff --git a/manifest.json b/manifest.json index a9d671c..c5aa389 100644 --- a/manifest.json +++ b/manifest.json @@ -1,5 +1,5 @@ { - "name" : "uniapp", + "name" : "家电样机处理平台", "appid" : "__UNI__C9A60ED", "description" : "应用描述", "versionName" : "1.0.0", diff --git a/pages.json b/pages.json index ed80f17..7b1a388 100644 --- a/pages.json +++ b/pages.json @@ -1,7 +1,7 @@ { "pages": [ // pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages - + { "path": "pages/index/index", "style" : @@ -157,9 +157,9 @@ ], "globalStyle": { "pageOrientation": "portrait", - "navigationBarTitleText": "Hello uniapp", + "navigationBarTitleText": "首页", "navigationBarTextStyle": "white", - "navigationBarBackgroundColor": "#007AFF", + "navigationBarBackgroundColor": "#3BC6BD", "backgroundColor": "#F8F8F8", "backgroundColorTop": "#F4F5F6", "backgroundColorBottom": "#F4F5F6", diff --git a/pages/index/index.vue b/pages/index/index.vue index 70dcb81..9289f11 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -88,7 +88,7 @@ export default { homemapurl:'' }; }, - onLoad() { + onLoad(options) { // 数据加载逻辑 if (!uni.getStorageSync('token')) { this.mini_login().then(() => { diff --git a/project.config.json b/project.config.json new file mode 100644 index 0000000..fd034ca --- /dev/null +++ b/project.config.json @@ -0,0 +1,25 @@ +{ + "setting": { + "es6": true, + "postcss": true, + "minified": true, + "uglifyFileName": false, + "enhance": true, + "packNpmRelationList": [], + "babelSetting": { + "ignore": [], + "disablePlugins": [], + "outputPath": "" + }, + "useCompilerPlugins": false, + "minifyWXML": true + }, + "compileType": "miniprogram", + "simulatorPluginLibVersion": {}, + "packOptions": { + "ignore": [], + "include": [] + }, + "appid": "wx58c09d95a245d0bb", + "editorSetting": {} +} \ No newline at end of file diff --git a/project.private.config.json b/project.private.config.json new file mode 100644 index 0000000..1c5ae01 --- /dev/null +++ b/project.private.config.json @@ -0,0 +1,14 @@ +{ + "libVersion": "3.12.1", + "projectname": "product-uniapp", + "setting": { + "urlCheck": true, + "coverView": true, + "lazyloadPlaceholderEnable": false, + "skylineRenderEnable": false, + "preloadBackgroundData": false, + "autoAudits": false, + "showShadowRootInWxmlPanel": true, + "compileHotReLoad": true + } +} \ No newline at end of file diff --git a/utils/auth.js b/utils/auth.js new file mode 100644 index 0000000..07ff985 --- /dev/null +++ b/utils/auth.js @@ -0,0 +1,88 @@ +/** + * 静默登录 - 重新获取 token + * 完全静默,不会跳转登录页 + * @returns {Promise<{success: boolean, token?: string, error?: string}>} + */ +export function silentLogin() { + return new Promise((resolve, reject) => { + uni.login({ + provider: 'weixin', + success: (loginRes) => { + console.log('Silent login code:', loginRes.code); + // 调用后端接口获取新 token + uni.request({ + url: 'https://bsh.info.yw.hnzhwlkj.cn/miniapp/login', + method: 'POST', + data: { + code: loginRes.code + }, + header: { + 'content-type': 'application/x-www-form-urlencoded', + 'Fdesk-Language': uni.getStorageSync('i18locale') || 'zh', + 'Fdesk-Login-Type': 'wechat', + 'Fdesk-System-Code': 'wechat' + }, + success: (res) => { + if (res.data.code == 0) { + const { token, openid } = res.data.data; + // 更新本地存储 + uni.setStorageSync('token', token); + uni.setStorageSync('openid', openid); + console.log('Silent login success, new token obtained'); + resolve({ success: true, token }); + } else { + console.error('Silent login failed:', res.data.msg); + // 不跳转登录页,只返回失败状态 + resolve({ success: false, error: res.data.msg }); + } + }, + fail: (err) => { + console.error('Silent login request failed:', err); + // 不跳转登录页,只返回失败状态 + resolve({ success: false, error: err.errMsg }); + } + }); + }, + fail: (err) => { + console.error('uni.login failed:', err); + // 不跳转登录页,只返回失败状态 + resolve({ success: false, error: err.errMsg }); + } + }); + }); +} + +/** + * 清除认证信息并跳转登录页 + */ +export function clearAuthAndRedirect() { + // 清除登录信息 + uni.removeStorageSync('token'); + uni.removeStorageSync('openid'); + uni.removeStorageSync('is_login'); + + // 跳转到登录页 + uni.reLaunch({ + url: '/pages/login/index' + }); +} + +/** + * 检查是否正在登录中(防止并发重复登录) + */ +let isLoggingIn = false; +let loginPromise = null; + +export function loginOnce() { + if (isLoggingIn) { + return loginPromise; + } + + isLoggingIn = true; + loginPromise = silentLogin().finally(() => { + isLoggingIn = false; + loginPromise = null; + }); + + return loginPromise; +}