{"version":3,"file":"index.js","sources":["../../../../../src/sheep/request/index.js"],"sourcesContent":["/**\r\n * Shopro-request\r\n * @description api模块管理,loading配置,请求拦截,错误处理\r\n */\r\n\r\nimport Request from 'luch-request'\r\nimport { apiPath, baseUrl, tenantId } from '@/sheep/config'\r\nimport $store from '@/sheep/store'\r\nimport $platform from '@/sheep/platform'\r\nimport { showAuthModal } from '@/sheep/hooks/useModal'\r\nimport AuthUtil from '@/sheep/api/member/auth'\r\nimport { getTerminal } from '@/sheep/util/const'\r\n\r\nconst options = {\r\n // 显示操作成功消息 默认不显示\r\n showSuccess: false,\r\n // 成功提醒 默认使用后端返回值\r\n successMsg: '',\r\n // 显示失败消息 默认显示\r\n showError: true,\r\n // 失败提醒 默认使用后端返回信息\r\n errorMsg: '',\r\n // 显示请求时loading模态框 默认显示\r\n showLoading: true,\r\n // loading提醒文字\r\n loadingMsg: '加载中',\r\n // 需要授权才能请求 默认放开\r\n auth: false,\r\n // ...\r\n}\r\n\r\n// Loading全局实例\r\nconst LoadingInstance = {\r\n target: null,\r\n count: 0,\r\n}\r\n\r\n/**\r\n * 关闭loading\r\n */\r\nfunction closeLoading() {\r\n if (LoadingInstance.count > 0) LoadingInstance.count--\r\n if (LoadingInstance.count === 0) uni.hideLoading()\r\n}\r\n\r\n/**\r\n * @description 请求基础配置 可直接使用访问自定义请求\r\n */\r\nconst http = new Request({\r\n baseURL: baseUrl + apiPath,\r\n timeout: 8000,\r\n method: 'GET',\r\n header: {\r\n Accept: 'text/json',\r\n 'Content-Type': 'application/json;charset=UTF-8',\r\n platform: $platform.name,\r\n },\r\n // #ifdef APP-PLUS\r\n sslVerify: false,\r\n // #endif\r\n // #ifdef H5\r\n // 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+)\r\n withCredentials: false,\r\n // #endif\r\n custom: options,\r\n})\r\n\r\n/**\r\n * @description 请求拦截器\r\n */\r\nhttp.interceptors.request.use(\r\n (config) => {\r\n // 自定义处理【auth 授权】:必须登录的接口,则跳出 AuthModal 登录弹窗\r\n if (config.custom.auth && !$store('user').isLogin) {\r\n showAuthModal()\r\n return Promise.reject()\r\n }\r\n\r\n // 自定义处理【loading 加载中】:如果需要显示 loading,则显示 loading\r\n if (config.custom.showLoading) {\r\n LoadingInstance.count++\r\n LoadingInstance.count === 1 &&\r\n uni.showLoading({\r\n title: config.custom.loadingMsg,\r\n mask: true,\r\n fail: () => {\r\n uni.hideLoading()\r\n },\r\n })\r\n }\r\n\r\n // 增加 token 令牌、terminal 终端、tenant 租户的请求头\r\n const token = getAccessToken()\r\n if (token) {\r\n config.header.Authorization = token\r\n }\r\n config.header.terminal = getTerminal()\r\n\r\n config.header.Accept = '*/*'\r\n config.header['tenant-id'] = tenantId\r\n return config\r\n },\r\n (error) => {\r\n return Promise.reject(error)\r\n },\r\n)\r\n\r\n/**\r\n * @description 响应拦截器\r\n */\r\nhttp.interceptors.response.use(\r\n (response) => {\r\n // 约定:如果是 /auth/ 下的 URL 地址,并且返回了 accessToken 说明是登录相关的接口,则自动设置登陆令牌\r\n if (response.config.url.indexOf('/member/auth/') >= 0 && response.data?.data?.accessToken) {\r\n $store('user').setToken(response.data.data.accessToken, response.data.data.refreshToken)\r\n }\r\n\r\n // 自定处理【loading 加载中】:如果需要显示 loading,则关闭 loading\r\n response.config.custom.showLoading && closeLoading()\r\n\r\n // 自定义处理【error 错误提示】:如果需要显示错误提示,则显示错误提示\r\n if (response.data.code !== 0) {\r\n // 特殊:如果 401 错误码,则跳转到登录页 or 刷新令牌\r\n if (response.data.code === 401) {\r\n return refreshToken(response.config)\r\n }\r\n\r\n // 错误提示\r\n if (response.config.custom.showError) {\r\n uni.showToast({\r\n title: response.data.msg || '服务器开小差啦,请稍后再试~',\r\n icon: 'none',\r\n mask: true,\r\n })\r\n }\r\n }\r\n\r\n // 自定义处理【showSuccess 成功提示】:如果需要显示成功提示,则显示成功提示\r\n if (\r\n response.config.custom.showSuccess &&\r\n response.config.custom.successMsg !== '' &&\r\n response.data.code === 0\r\n ) {\r\n uni.showToast({\r\n title: response.config.custom.successMsg,\r\n icon: 'none',\r\n })\r\n }\r\n\r\n // 返回结果:包括 code + data + msg\r\n return Promise.resolve(response.data)\r\n },\r\n (error) => {\r\n const userStore = $store('user')\r\n const isLogin = userStore.isLogin\r\n let errorMessage = '网络请求出错'\r\n if (error !== undefined) {\r\n switch (error.statusCode) {\r\n case 400:\r\n errorMessage = '请求错误'\r\n break\r\n case 401:\r\n errorMessage = isLogin ? '您的登陆已过期' : '请先登录'\r\n // 正常情况下,后端不会返回 401 错误,所以这里不处理 handleAuthorized\r\n break\r\n case 403:\r\n errorMessage = '拒绝访问'\r\n break\r\n case 404:\r\n errorMessage = '请求出错'\r\n break\r\n case 408:\r\n errorMessage = '请求超时'\r\n break\r\n case 429:\r\n errorMessage = '请求频繁, 请稍后再访问'\r\n break\r\n case 500:\r\n errorMessage = '服务器开小差啦,请稍后再试~'\r\n break\r\n case 501:\r\n errorMessage = '服务未实现'\r\n break\r\n case 502:\r\n errorMessage = '网络错误'\r\n break\r\n case 503:\r\n errorMessage = '服务不可用'\r\n break\r\n case 504:\r\n errorMessage = '网络超时'\r\n break\r\n case 505:\r\n errorMessage = 'HTTP 版本不受支持'\r\n break\r\n }\r\n if (error.errMsg.includes('timeout')) errorMessage = '请求超时'\r\n // #ifdef H5\r\n if (error.errMsg.includes('Network'))\r\n errorMessage = window.navigator.onLine ? '服务器异常' : '请检查您的网络连接'\r\n // #endif\r\n }\r\n\r\n if (error && error.config) {\r\n if (error.config.custom.showError === false) {\r\n uni.showToast({\r\n title: error.data?.msg || errorMessage,\r\n icon: 'none',\r\n mask: true,\r\n })\r\n }\r\n error.config.custom.showLoading && closeLoading()\r\n }\r\n\r\n return false\r\n },\r\n)\r\n\r\n// Axios 无感知刷新令牌,参考 https://www.dashingdog.cn/article/11 与 https://segmentfault.com/a/1190000020210980 实现\r\nlet requestList = [] // 请求队列\r\nlet isRefreshToken = false // 是否正在刷新中\r\nconst refreshToken = async (config) => {\r\n // 如果当前已经是 refresh-token 的 URL 地址,并且还是 401 错误,说明是刷新令牌失败了,直接返回 Promise.reject(error)\r\n if (config.url.indexOf('/member/auth/refresh-token') >= 0) {\r\n return Promise.reject('error')\r\n }\r\n\r\n // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了\r\n if (!isRefreshToken) {\r\n isRefreshToken = true\r\n // 1. 如果获取不到刷新令牌,则只能执行登出操作\r\n const refreshToken = getRefreshToken()\r\n if (!refreshToken) {\r\n return handleAuthorized()\r\n }\r\n // 2. 进行刷新访问令牌\r\n try {\r\n const refreshTokenResult = await AuthUtil.refreshToken(refreshToken)\r\n if (refreshTokenResult.code !== 0) {\r\n // 如果刷新不成功,直接抛出 e 触发 2.2 的逻辑\r\n // noinspection ExceptionCaughtLocallyJS\r\n throw new Error('刷新令牌失败')\r\n }\r\n // 2.1 刷新成功,则回放队列的请求 + 当前请求\r\n config.header.Authorization = 'Bearer ' + getAccessToken()\r\n requestList.forEach((cb) => {\r\n cb()\r\n })\r\n requestList = []\r\n return request(config)\r\n } catch (e) {\r\n // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。\r\n // 2.2 刷新失败,只回放队列的请求\r\n requestList.forEach((cb) => {\r\n cb()\r\n })\r\n // 提示是否要登出。即不回放当前请求!不然会形成递归\r\n return handleAuthorized()\r\n } finally {\r\n requestList = []\r\n isRefreshToken = false\r\n }\r\n } else {\r\n // 添加到队列,等待刷新获取到新的令牌\r\n return new Promise((resolve) => {\r\n requestList.push(() => {\r\n config.header.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改\r\n resolve(request(config))\r\n })\r\n })\r\n }\r\n}\r\n\r\n/**\r\n * 处理 401 未登录的错误\r\n */\r\nconst handleAuthorized = () => {\r\n const userStore = $store('user')\r\n userStore.logout(true)\r\n showAuthModal()\r\n // 登录超时\r\n return Promise.reject({\r\n code: 401,\r\n msg: userStore.isLogin ? '您的登陆已过期' : '请先登录',\r\n })\r\n}\r\n\r\n/** 获得访问令牌 */\r\nconst getAccessToken = () => {\r\n return uni.getStorageSync('token')\r\n}\r\n\r\n/** 获得刷新令牌 */\r\nconst getRefreshToken = () => {\r\n return uni.getStorageSync('refresh-token')\r\n}\r\n\r\nconst request = (config) => {\r\n return http.middleware(config)\r\n}\r\n\r\nexport default request\r\n"],"names":["uni","Request","baseUrl","apiPath","$platform","$store","showAuthModal","getTerminal","tenantId","refreshToken","AuthUtil"],"mappings":"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"}