import $app from "./app"; import $config from "./config"; const api = {}; // 网络请求封装 const Request = function (opts) { const originalComplete = opts.complete; return new Promise((resolve, reject) => { uni.request( Object.assign({}, opts, { complete: (res) => { const hasSuccess = Boolean( res.errMsg == "request:ok" && res.statusCode >= 200 && res.statusCode < 300 ); hasSuccess ? resolve(res.data) : reject(res); if (originalComplete && typeof originalComplete == "function") originalComplete(res); }, }) ); }); }; // 路径拼接 const pathJoin = function (...args) { return args.join("/").replace(/(? { const options = Object.assign( { // 请求地址 url: pathJoin($config.url.request, url), // 请求数据 data: data || {}, // 请求类型 method: method || "post", // 数据类型 dataType: "json", // 自动显示LOADING loading: true, // 启用错误自动拦截 error: true, // 请求头设定 header: { "content-type": "application/json", Authorization: "Bearer " + getAccessToken(), // 修改这里,使用新的获取token方法 }, // 设置显示LOADING的方法 showLoading: showLoading, // 设置关闭LOADING的方法 hideLoading: hideLoading, }, opts || {} ); if (options.loading && typeof options.showLoading == "function") { options.showLoading(); } Request(options) .then(async (res) => { if (options.loading && typeof options.hideLoading == "function") { options.hideLoading(); } switch (res.code) { // 请求正常 case "00000": resolve(res); break; // 约定401为未登录状态 case "A0230": try { // 尝试刷新token console.log("进入刷新请求"); const refreshResult = await refreshToken(); if (refreshResult) { // 刷新成功,更新header中的token并重新请求 options.header.token = getAccessToken(); try { const db = await Request(options); resolve(db); } catch (err) { reject(err); } } else { // 刷新失败,执行登录 // await api.login(); options.header.token = getAccessToken(); try { const db = await Request(options); resolve(db); } catch (err) { reject(err); } } } catch (err) { reject(err); } break; // 其他错误请求 default: if (options.error) { $app.popup.alert(res.msg || `${url}\r\n未知错误`, "数据请求"); } else { reject(res); } break; } }) .catch(async (err) => { if (err.data.code == "A0230") { try { // 尝试刷新token const refreshResult = await refreshToken(); if (refreshResult) { // 刷新成功,更新header中的token并重新请求 options.header.token = getAccessToken(); try { const db = await Request(options); resolve(db); } catch (err) { reject(err); } } else { // 刷新失败,执行登录 $app.popup .confirm( `服务器响应失败\r\n${err.data.msg},点击确定去登录`, "提示", { showCancel: true, } ) .then((confirmed) => { if (confirmed) { uni.navigateTo({ url: "/pages/login/login" }); } }); } } catch (err) { reject(err); } } else { $app.popup.alert(`服务器响应失败\r\n${err.data.msg}`, "数据请求"); } /*失败处理,此处为非200状态码引起的错误*/ options.hideLoading(); }); }); }; // 新增:获取accessToken的方法 const getAccessToken = function () { return uni.getStorageSync($config.keyname.accessToken); }; // 新增:刷新token的方法 const refreshToken = async function () { const refreshToken = uni.getStorageSync($config.keyname.refreshToken); console.log("刷新token", refreshToken); if (!refreshToken) return false; try { const res = await Request({ url: pathJoin($config.url.request, $config.api.refreshToken), method: "post", data: { refreshToken }, header: { "content-type": "application/json", }, }); if (res.code === "00000") { uni.setStorageSync($config.keyname.accessToken, res.data.accessToken); uni.setStorageSync($config.keyname.refreshToken, res.data.refreshToken); return true; } return false; } catch (e) { return false; } }; /** * POST请求 * @param {String} url 请求地址 * @param {Object} data 请求数据 * @param {Object} opts 配置参数 */ api.post = function (url, data, opts) { return api.base("post", url, data, Object.assign({}, opts)); }; /** * GET请求 * @param {String} url 请求地址 * @param {Object} data 请求数据 * @param {Object} opts 配置参数 */ api.get = function (url, data, opts) { return api.base("get", url, data, Object.assign({}, opts)); }; /** * PUT请求 * @param {String} url 请求地址 * @param {Object} data 请求数据 * @param {Object} opts 配置参数 */ api.put = function (url, data, opts) { return api.base("put", url, data, Object.assign({}, opts)); }; /** * 获取静态数据 * @param {String} url 静态文件地址 * @param {Object} data 参数数据 * @param {Object} opts 配置参数 */ api.static = function (url, data, opts) { return new Promise(async (resolve, reject) => { // 设置选项 var _opts = Object.assign( { url: /^http/.test(url) ? url : API_BASE + (url || ""), data: Object.assign({ cache: Date.now() }, data), }, opts || {} ); uni.request({ ..._opts, success: (res) => { resolve(res.data); }, }); }); }; /** * 文件上传 * @param {String} file 文件临时路径 * @param {Object} opts 上传参数 */ api.upload = function (file, opts) { return new Promise((resolve, reject) => { const options = Object.assign( { // 请求地址 url: pathJoin($config.url.upload, opts?.url || ""), // 请求数据 filePath: file, // 自动显示LOADING loading: true, // 启用错误自动拦截 error: true, // 请求头设定 header: { token: uni.getStorageSync($config.keyname.userToken), }, // 设置显示LOADING的方法 showLoading: showLoading, // 设置关闭LOADING的方法 hideLoading: hideLoading, }, opts || {} ); }); }; /** * 获取登录code */ api.userCode = function () { return new Promise((resolve, reject) => { uni.login({ provider: "weixin", success: (res) => resolve(res.code), fail: (err) => reject(err), }); }); }; /** * 自动登录 * @param {Object} data 登录数据(非必填) */ api.login = function (data) { return new Promise(async (resolve, reject) => { const code = await api.userCode(); api .post($config.api.login, { ...(data || {}), code }) .then(async (res) => { // 保存 accessToken 和 refreshToken uni.setStorageSync($config.keyname.accessToken, res?.data?.accessToken); uni.setStorageSync( $config.keyname.refreshToken, res?.data?.refreshToken ); // 保留原有的 userInfo 存储 uni.setStorageSync($config.keyname.userInfo, res?.data?.userInfo); // 返回 accessToken 保持向后兼容 resolve(res.data.accessToken); }) .catch((err) => reject(err)); }); }; export default api;