2026-06-18 11:31:43 +08:00
|
|
|
|
const NO_NETWORK_TEXT = '当前无网络,请检查网络连接'
|
|
|
|
|
|
let isNetworkOnline = true
|
|
|
|
|
|
let hasBoundNetworkListener = false
|
|
|
|
|
|
let hasBoundRequestInterceptor = false
|
|
|
|
|
|
let hasPatchedUviewRequest = false
|
|
|
|
|
|
let lastNoNetworkToastAt = 0
|
|
|
|
|
|
|
|
|
|
|
|
const showNoNetworkToast = () => {
|
|
|
|
|
|
const now = Date.now()
|
|
|
|
|
|
if (now - lastNoNetworkToastAt < 2000) return
|
|
|
|
|
|
lastNoNetworkToastAt = now
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: NO_NETWORK_TEXT,
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
duration: 2000
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const updateNetworkOnlineStatus = (online) => {
|
|
|
|
|
|
isNetworkOnline = !!online
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const initNetworkStatus = () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const sysInfo = uni.getSystemInfoSync()
|
|
|
|
|
|
if (sysInfo && typeof sysInfo.networkType === 'string') {
|
|
|
|
|
|
updateNetworkOnlineStatus(sysInfo.networkType !== 'none')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const refreshNetworkStatusSync = () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const sysInfo = uni.getSystemInfoSync()
|
|
|
|
|
|
if (sysInfo && typeof sysInfo.networkType === 'string') {
|
|
|
|
|
|
updateNetworkOnlineStatus(sysInfo.networkType !== 'none')
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
return isNetworkOnline
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const bindNetworkStatusListener = () => {
|
|
|
|
|
|
if (hasBoundNetworkListener) return
|
|
|
|
|
|
hasBoundNetworkListener = true
|
|
|
|
|
|
uni.onNetworkStatusChange((res) => {
|
|
|
|
|
|
updateNetworkOnlineStatus(res && res.isConnected)
|
|
|
|
|
|
if (res && res.isConnected === false) {
|
|
|
|
|
|
showNoNetworkToast()
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const bindGlobalRequestInterceptor = () => {
|
|
|
|
|
|
if (hasBoundRequestInterceptor || typeof uni.addInterceptor !== 'function') return
|
|
|
|
|
|
hasBoundRequestInterceptor = true
|
|
|
|
|
|
uni.addInterceptor('request', {
|
|
|
|
|
|
invoke() {
|
|
|
|
|
|
if (!refreshNetworkStatusSync()) {
|
|
|
|
|
|
showNoNetworkToast()
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
fail(err) {
|
|
|
|
|
|
const msg = (err && err.errMsg) ? String(err.errMsg).toLowerCase() : ''
|
|
|
|
|
|
if (msg.includes('fail') && (msg.includes('network') || msg.includes('internet') || msg.includes('offline'))) {
|
|
|
|
|
|
updateNetworkOnlineStatus(false)
|
|
|
|
|
|
showNoNetworkToast()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const isLikelyNetworkError = (err) => {
|
|
|
|
|
|
const msg = err && err.errMsg ? String(err.errMsg).toLowerCase() : String(err || '').toLowerCase()
|
|
|
|
|
|
if (!msg) return false
|
|
|
|
|
|
return (
|
|
|
|
|
|
msg.includes('request:fail') ||
|
|
|
|
|
|
msg.includes('network') ||
|
|
|
|
|
|
msg.includes('internet') ||
|
|
|
|
|
|
msg.includes('offline') ||
|
|
|
|
|
|
msg.includes('timeout') ||
|
|
|
|
|
|
msg.includes('disconnected') ||
|
|
|
|
|
|
msg.includes('dns')
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-05 16:45:28 +08:00
|
|
|
|
const install = (Vue, vm) => {
|
2026-06-18 11:31:43 +08:00
|
|
|
|
initNetworkStatus()
|
|
|
|
|
|
bindNetworkStatusListener()
|
|
|
|
|
|
bindGlobalRequestInterceptor()
|
|
|
|
|
|
|
2024-03-13 10:54:22 +08:00
|
|
|
|
Vue.prototype.$u.http.setConfig({
|
2026-06-18 11:31:43 +08:00
|
|
|
|
baseUrl: 'https://yxd.ccttiot.com/prod-api',
|
|
|
|
|
|
// baseUrl: 'http://192.168.1.5:8081',
|
|
|
|
|
|
loadingText: '',
|
|
|
|
|
|
loadingTime: 800,
|
|
|
|
|
|
// 设置自定义头部content-type
|
|
|
|
|
|
header: {
|
|
|
|
|
|
'content-type': 'application/json;charset=UTF-8',
|
|
|
|
|
|
},
|
|
|
|
|
|
// ......
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 为uView请求增加统一网络失败兜底(避免页面忘记catch时控制台刷错)
|
|
|
|
|
|
if (!hasPatchedUviewRequest) {
|
|
|
|
|
|
hasPatchedUviewRequest = true
|
|
|
|
|
|
const rawRequest = Vue.prototype.$u.http.request.bind(Vue.prototype.$u.http)
|
|
|
|
|
|
Vue.prototype.$u.http.request = (options = {}) => {
|
|
|
|
|
|
if (!refreshNetworkStatusSync()) {
|
|
|
|
|
|
showNoNetworkToast()
|
|
|
|
|
|
// 与uView拦截return false行为保持一致:中断后不进入then/catch
|
|
|
|
|
|
return new Promise(() => {})
|
|
|
|
|
|
}
|
|
|
|
|
|
return rawRequest(options).catch((err) => {
|
|
|
|
|
|
if (isLikelyNetworkError(err)) {
|
|
|
|
|
|
updateNetworkOnlineStatus(false)
|
|
|
|
|
|
showNoNetworkToast()
|
|
|
|
|
|
return new Promise(() => {})
|
|
|
|
|
|
}
|
|
|
|
|
|
return Promise.reject(err)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 请求拦截部分,如配置,每次请求前都会执行
|
2023-12-05 16:45:28 +08:00
|
|
|
|
Vue.prototype.$u.http.interceptor.request = (config) => {
|
2026-06-18 11:31:43 +08:00
|
|
|
|
if (!refreshNetworkStatusSync()) {
|
|
|
|
|
|
showNoNetworkToast()
|
|
|
|
|
|
// 返回false可中断请求(uView内置约定)
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
config.header = config.header || {}
|
|
|
|
|
|
const token = uni.getStorageSync('token')
|
|
|
|
|
|
config.header.Authorization = token
|
2023-12-06 10:06:54 +08:00
|
|
|
|
// config.header.Tenant-Id=1
|
2023-12-05 16:45:28 +08:00
|
|
|
|
// #ifdef H5
|
2026-06-18 11:31:43 +08:00
|
|
|
|
config.header.Authorization = 'Bearer ' + token
|
2023-12-05 16:45:28 +08:00
|
|
|
|
// #endif
|
|
|
|
|
|
// 可以对某个url进行特别处理,此url参数为this.$u.get(url)中的url值
|
2026-06-18 11:31:43 +08:00
|
|
|
|
if (config.url == '/user/login') config.header.noToken = true
|
2023-12-05 16:45:28 +08:00
|
|
|
|
// 最后需要将config进行return
|
2026-06-18 11:31:43 +08:00
|
|
|
|
return config
|
2023-12-05 16:45:28 +08:00
|
|
|
|
}
|
2026-06-18 11:31:43 +08:00
|
|
|
|
|
2023-12-05 16:45:28 +08:00
|
|
|
|
// 响应拦截,如配置,每次请求结束都会执行本方法
|
2026-06-18 11:31:43 +08:00
|
|
|
|
Vue.prototype.$u.http.interceptor.response = (res) => {
|
|
|
|
|
|
return res
|
|
|
|
|
|
}
|
2023-12-05 16:45:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
install
|
2026-06-18 11:31:43 +08:00
|
|
|
|
}
|