| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- import appSettings from '@/core/config/app-settings'
- import { isAbsoluteHttpUrl, trimTrailingSlash } from '@/core/network/url-detect'
- import { buildApiSignature } from '@/core/network/request-sign'
- import { applyClientHeaders, readSessionToken } from '@/core/network/client-meta'
- import { adaptiveToast } from '@/core/ui/smart-toast'
- import { parseApiResponse, snapshotEnvelope, applySuccessPayload } from './response-evaluator'
- const LOGIN_ROUTE = '/pages/passport/lobby'
- /** 为 true 时 HTTP 4xx/5xx 不弹 toast(用于网络探测等后台请求) */
- let suppressHttpErrorToast = false
- export function runWithoutHttpErrorToast(fn) {
- suppressHttpErrorToast = true
- return Promise.resolve()
- .then(fn)
- .finally(() => {
- suppressHttpErrorToast = false
- })
- }
- function ensureHeaderObject(cfg) {
- cfg.header = typeof cfg.header === 'object' && cfg.header !== null ? cfg.header : {}
- return cfg.header
- }
- function attachApiAuth(cfg) {
- const headers = ensureHeaderObject(cfg)
- const body = typeof cfg.data === 'object' && cfg.data !== null ? cfg.data : {}
- headers.Sign = buildApiSignature(cfg.url, body)
- cfg.url = trimTrailingSlash(appSettings.appurl) + cfg.url
- const token = readSessionToken()
- if (token) headers.token = token
- Object.assign(headers, applyClientHeaders(headers))
- }
- function decorateRelativeRequest(cfg) {
- if (isAbsoluteHttpUrl(cfg.url)) return
- attachApiAuth(cfg)
- const base = cfg.url
- const langQuery = `lang=${encodeURIComponent(uni.getLocale())}`
- cfg.url = base.includes('?') ? `${base}&${langQuery}` : `${base}?${langQuery}`
- }
- function decorateUpload(cfg) {
- if (isAbsoluteHttpUrl(cfg.url)) {
- const token = readSessionToken()
- if (token) ensureHeaderObject(cfg).token = token
- return
- }
- attachApiAuth(cfg)
- }
- export function registerHttpInterceptors(i18n) {
- const t = (key, fallback) => {
- try {
- return i18n ? i18n.t(key) : fallback
- } catch (_) {
- return fallback
- }
- }
- uni.addInterceptor('uploadFile', {
- invoke(cfg) {
- decorateUpload(cfg)
- },
- success(res) {
- if (res.statusCode !== 200) {
- let message = '上传失败'
- try {
- message = JSON.parse(res.data).msg || message
- } catch (_) {}
- adaptiveToast(message, 'error')
- return false
- }
- uni.showToast({ title: 'Success', position: true })
- return true
- }
- })
- uni.addInterceptor('request', {
- invoke(cfg) {
- cfg.sslVerify = false
- decorateRelativeRequest(cfg)
- if (appSettings.debug) console.log('[http:invoke]', cfg)
- },
- success(res) {
- snapshotEnvelope(res)
- const parsed = parseApiResponse(res)
- if (parsed.kind === 'success') {
- applySuccessPayload(res, parsed)
- if (appSettings.debug) {
- try {
- const reqUrl = res && res.config && res.config.url
- if (reqUrl && /live\/play/.test(reqUrl)) {
- console.log('=== [HTTP-DIAG] live/play raw response ===')
- console.log('[HTTP-DIAG] url =', reqUrl)
- console.log('[HTTP-DIAG] envelope =', res.res)
- console.log('[HTTP-DIAG] parsed.data =', parsed.data)
- console.log('[HTTP-DIAG] envelope JSON =', JSON.stringify(res.res))
- }
- } catch (logErr) {
- console.warn('[HTTP-DIAG] log failed', logErr)
- }
- console.log('[http:ok]', res)
- }
- return true
- }
- if (parsed.kind === 'passthrough') return
- // 业务失败须放行 success,由 http-client finalizeResponse 抛错并结束 Promise;
- // 若 return false 会拦截 success,await 永不 settle,页面 loading 无法结束。
- if (parsed.kind === 'silent_fail') {
- if (appSettings.debug) console.log('[http:silent-fail]', res)
- return true
- }
- if (parsed.kind === 'biz_fail') {
- adaptiveToast(parsed.message, 'error')
- if (appSettings.debug) console.log('[http:biz-fail]', res)
- return true
- }
- const status = parsed.status
- if (suppressHttpErrorToast) {
- if (appSettings.debug) {
- const reqUrl = (res && res.config && res.config.url) || ''
- console.warn('[http:silent-http-error]', status, reqUrl)
- }
- return true
- }
- if (status === 401) {
- adaptiveToast(parsed.message || '未授权', 'error')
- uni.reLaunch({ url: LOGIN_ROUTE })
- } else if (status === 404) {
- adaptiveToast(t('common.apiNotFound', 'API 接口不存在'), 'error')
- } else if (status === 500) {
- adaptiveToast(t('common.apiServerBusy', 'API 服務器繁忙'), 'error')
- } else {
- adaptiveToast(parsed.message || '请求失败', 'error')
- }
- if (appSettings.debug) console.log('[http:fail]', res)
- return true
- },
- fail(err) {
- if (appSettings.debug) console.log('[http:error]', err)
- }
- })
- }
|