| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- import $app from "./app";
- import $config from "./config";
- const api = {};
- // 标志位:控制登录提示弹窗只显示一次
- let isLoginPromptShown = false;
- // 网络请求封装
- 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(/(?<!:)(\/{2,})/g, "/");
- };
- // 显示LOADING
- const showLoading = function () {
- uni.showLoading({ title: "", mask: true });
- };
- // 关闭LOADING
- const hideLoading = function () {
- uni.hideLoading();
- };
- // 获取用户TOKEN
- const getUserToken = function () {
- return uni.getStorageSync($config.keyname.userToken);
- };
- /**
- * 基础请求
- * @param {String} method 请求类型
- * @param {String} url 请求地址
- * @param {Object} data 请求数据
- * @param {Object} opts 配置参数
- */
- api.base = function (method, url, data, opts) {
- return new Promise(async (resolve, reject) => {
- 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 {
- // 刷新失败,执行登录
- if (!isLoginPromptShown) {
- isLoginPromptShown = true;
- $app.popup
- .confirm(
- `服务器响应失败\r\n${err.data.msg},点击确定去登录`,
- "提示",
- {
- showCancel: true,
- }
- )
- .then((confirmed) => {
- isLoginPromptShown = false;
- 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;
|