Files
wxapp_escort/utils/request.js
T
2026-10-07 14:55:06 +08:00

105 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 本地调试开关:置 true 时直连本机进程(health :9004、user :9010)
// 线上由 nginx 按路径分流(/user → 9010、/health → 9004),两个服务共用同一域名
const DEBUG = false
const BASE_URL = DEBUG ? 'http://127.0.0.1:9004' : 'https://api.huashengtec.com'
const USER_BASE_URL = DEBUG ? 'http://127.0.0.1:9010' : 'https://api.huashengtec.com'
class Request {
constructor(baseURL = BASE_URL) {
this.baseURL = baseURL
// 401 兜底回调,由 app.js 注入(静默重登)。
// request 层不直接写登录逻辑:utils/api.js → request.js 是单向依赖,
// 反过来引 api.js 会成环
this.onUnauthorized = null
}
setUnauthorizedHandler(handler) {
this.onUnauthorized = handler
}
request(options) {
return this.send(options).then((body) => this.recoverUnauthorized(body, options))
}
// token 失效时后端返回 HTTP 200 + code 401(api/health/utils/responseUtil.js),
// 这里静默重登一次再重试:token 会被别处登录轮换,小程序长时间停在前台
// 也不会再触发 app.onShow 的重登,本机 token 因此会变陈旧
recoverUnauthorized(body, options) {
if (!body || body.code !== 401 || options._retried || !this.onUnauthorized) {
return body
}
// 重登失败不当成网络错误抛出去:回一句可执行的提示,
// 调用方现有的「res.msg 直接弹 toast」就能显示出来(「登录已失效」是死胡同)
const notLoggedIn = { code: 401, msg: '请先登录', data: null }
return Promise.resolve()
.then(() => this.onUnauthorized())
.then((ok) => (ok ? this.request({ ...options, _retried: true }) : notLoggedIn))
.catch(() => notLoggedIn)
}
send(options) {
const { url, method = 'GET', data = {}, header = {}, _retried, ...rest } = options
return new Promise((resolve, reject) => {
const app = getApp()
const token = app?.globalData?.user?.security?.token || ''
data.appId = 'wxapp-escort'
wx.request({
url: url.startsWith('http') ? url : `${this.baseURL}${url}`,
method,
data,
header: {
'Content-Type': 'application/json',
...(token ? { 'token': token } : {}),
...header
},
...rest,
success: (res) => {
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve(res.data)
} else {
reject(new Error(`HTTP ${res.statusCode}`))
}
},
fail: (err) => {
reject(err)
}
})
})
}
get(url, params = {}, options = {}) {
return this.request({ url, method: 'GET', data: params, ...options })
}
post(url, data = {}, options = {}) {
return this.request({ url, method: 'POST', data, ...options })
}
put(url, data = {}, options = {}) {
return this.request({ url, method: 'PUT', data, ...options })
}
patch(url, data = {}, options = {}) {
return this.request({ url, method: 'PATCH', data, ...options })
}
delete(url, data = {}, options = {}) {
return this.request({ url, method: 'DELETE', data, ...options })
}
}
const request = new Request()
// 默认导出 health 实例(保持既有 require('./request.js') 用法不变);
// 类与 user 侧基址一并挂出,供 api.js 派生 user 服务专用实例
request.Request = Request
request.USER_BASE_URL = USER_BASE_URL
module.exports = request