const { BASE_URL } = require('./config.js'); const TOKEN_KEY = 'pets_token'; function getToken() { return wx.getStorageSync(TOKEN_KEY) || ''; } function setToken(t) { wx.setStorageSync(TOKEN_KEY, t); } function clearToken() { wx.removeStorageSync(TOKEN_KEY); } // token 失效时的重新登录钩子,由 store 注册(放在这里避免 request ← api ← store 循环依赖) let reAuth = null; function setReAuthHandler(fn) { reAuth = fn; } const TIMEOUT = 15000; // 统一请求:注入 token,解析 {code,message,data},成功返回 data,失败 reject(Error)。 // token 失效(40100)时自动重新登录并重试一次,避免 JWT 过期后小程序静默白屏。 function request(options, _retried) { const { url, method = 'GET', data, header = {} } = options; return new Promise((resolve, reject) => { const token = getToken(); wx.request({ url: BASE_URL + url, method, data, timeout: TIMEOUT, header: Object.assign( { 'Content-Type': 'application/json' }, token ? { Authorization: 'Bearer ' + token } : {}, header, ), success(res) { const body = res.data; if (body && typeof body === 'object' && 'code' in body) { if (body.code === 0) return resolve(body.data); if (body.code === 40100) { clearToken(); // 只重试一次,防止登录接口本身出问题时无限循环 if (!_retried && reAuth) { return reAuth() .then(() => request(options, true).then(resolve, reject)) .catch(() => reject(new Error(body.message || '登录已过期,请重进小程序'))); } } return reject(new Error(body.message || '请求失败')); } resolve(body); }, fail(err) { const msg = (err && err.errMsg) || '网络错误'; reject(new Error(/timeout/i.test(msg) ? '网络超时,请稍后重试' : msg)); }, }); }); } // 文件上传(multipart) function uploadFile(filePath) { return new Promise((resolve, reject) => { const token = getToken(); wx.uploadFile({ url: BASE_URL + '/api/upload', filePath, name: 'file', timeout: 60000, header: token ? { Authorization: 'Bearer ' + token } : {}, success(res) { try { const body = JSON.parse(res.data); if (body.code === 0) return resolve(body.data); reject(new Error(body.message || '上传失败')); } catch (e) { reject(new Error('上传响应解析失败')); } }, fail(err) { reject(new Error((err && err.errMsg) || '上传失败')); }, }); }); } module.exports = { request, uploadFile, getToken, setToken, clearToken, setReAuthHandler };