293 lines
6.3 KiB
JavaScript
293 lines
6.3 KiB
JavaScript
import config from '../config.js'
|
|
import storage from './storage.js'
|
|
|
|
let isRefreshing = false
|
|
let refreshSubscribers = []
|
|
|
|
const subscribeTokenRefresh = (callback) => {
|
|
refreshSubscribers.push(callback)
|
|
}
|
|
|
|
const onTokenRefreshed = (token) => {
|
|
refreshSubscribers.forEach(callback => callback(token))
|
|
refreshSubscribers = []
|
|
}
|
|
|
|
const request = (options) => {
|
|
return new Promise((resolve, reject) => {
|
|
const fullUrl = config.baseUrl + options.url
|
|
console.log('=== 请求开始 ===')
|
|
console.log('URL:', fullUrl)
|
|
console.log('Method:', options.method || 'GET')
|
|
console.log('Data:', options.data)
|
|
|
|
const token = storage.getToken()
|
|
const { noAuthModal = false } = options
|
|
|
|
uni.request({
|
|
url: fullUrl,
|
|
method: options.method || 'GET',
|
|
data: options.data || {},
|
|
header: {
|
|
'Content-Type': 'application/json',
|
|
...(token ? { 'Authorization': `Bearer ${token}` } : {}),
|
|
...options.header
|
|
},
|
|
timeout: config.timeout,
|
|
success: async (res) => {
|
|
console.log('=== 请求成功 ===')
|
|
console.log('StatusCode:', res.statusCode)
|
|
console.log('Response:', res.data)
|
|
|
|
const { statusCode, data } = res
|
|
|
|
if (statusCode === 401) {
|
|
console.log('=== Token 过期,尝试刷新 ===')
|
|
|
|
if (isRefreshing) {
|
|
return new Promise((resolve) => {
|
|
subscribeTokenRefresh((newToken) => {
|
|
options.header = options.header || {}
|
|
options.header.Authorization = `Bearer ${newToken}`
|
|
resolve(request(options))
|
|
})
|
|
}).then(resolve).catch(reject)
|
|
}
|
|
|
|
isRefreshing = true
|
|
|
|
try {
|
|
const refreshToken = storage.getRefreshToken()
|
|
if (!refreshToken) {
|
|
throw new Error('没有刷新令牌')
|
|
}
|
|
|
|
const refreshRes = await new Promise((resolve, reject) => {
|
|
uni.request({
|
|
url: config.baseUrl + '/gw/open/refresh_token',
|
|
method: 'POST',
|
|
data: {
|
|
refreshToken
|
|
},
|
|
header: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
success: (res) => {
|
|
if (res.statusCode === 200 && res.data.code === 0) {
|
|
resolve(res.data)
|
|
} else {
|
|
reject(res.data)
|
|
}
|
|
},
|
|
fail: reject
|
|
})
|
|
})
|
|
|
|
if (refreshRes.data && refreshRes.data.accessToken) {
|
|
storage.setToken(refreshRes.data.accessToken)
|
|
if (refreshRes.data.refreshToken) {
|
|
storage.setRefreshToken(refreshRes.data.refreshToken)
|
|
}
|
|
|
|
onTokenRefreshed(refreshRes.data.accessToken)
|
|
isRefreshing = false
|
|
|
|
options.header = options.header || {}
|
|
options.header.Authorization = `Bearer ${refreshRes.data.accessToken}`
|
|
|
|
const retryRes = await request(options)
|
|
resolve(retryRes)
|
|
} else {
|
|
throw new Error('刷新令牌失败')
|
|
}
|
|
} catch (refreshError) {
|
|
console.error('=== 刷新令牌失败 ===', refreshError)
|
|
isRefreshing = false
|
|
storage.removeToken()
|
|
storage.removeRefreshToken()
|
|
storage.removeUserInfo()
|
|
|
|
if (!noAuthModal) {
|
|
uni.showModal({
|
|
title: '登录过期',
|
|
content: '请重新登录',
|
|
showCancel: false,
|
|
success: () => {
|
|
uni.reLaunch({
|
|
url: '/pages/login/login'
|
|
})
|
|
}
|
|
})
|
|
} else {
|
|
// 不弹出窗口,直接返回错误
|
|
const error = new Error('401 Unauthorized')
|
|
error.statusCode = 401
|
|
reject(error)
|
|
return
|
|
}
|
|
|
|
reject(refreshError)
|
|
}
|
|
} else if (statusCode === 200) {
|
|
if (data.code === 0 || data.success === true) {
|
|
resolve(data)
|
|
} else {
|
|
console.error('=== 业务错误 ===')
|
|
console.error('Code:', data.code)
|
|
console.error('Message:', data.message)
|
|
if (!noAuthModal) {
|
|
uni.showModal({
|
|
title: '请求失败',
|
|
content: data.message || '服务器返回错误',
|
|
showCancel: false
|
|
})
|
|
}
|
|
reject(data)
|
|
}
|
|
} else {
|
|
console.error('=== HTTP错误 ===')
|
|
console.error('StatusCode:', statusCode)
|
|
console.error('Response:', data)
|
|
if (!noAuthModal) {
|
|
uni.showModal({
|
|
title: '网络错误',
|
|
content: `状态码: ${statusCode}`,
|
|
showCancel: false
|
|
})
|
|
}
|
|
reject(res)
|
|
}
|
|
},
|
|
fail: (err) => {
|
|
console.error('=== 请求失败 ===')
|
|
console.error('Error:', err)
|
|
console.error('Error Message:', err.errMsg)
|
|
|
|
let errorMsg = '网络连接失败'
|
|
if (err.errMsg) {
|
|
if (err.errMsg.includes('timeout')) {
|
|
errorMsg = '请求超时,请检查网络'
|
|
} else if (err.errMsg.includes('fail')) {
|
|
errorMsg = '网络连接失败,请检查网络设置'
|
|
} else if (err.errMsg.includes('request:fail')) {
|
|
errorMsg = `连接失败: ${err.errMsg}`
|
|
}
|
|
}
|
|
|
|
if (!noAuthModal) {
|
|
uni.showModal({
|
|
title: '错误',
|
|
content: errorMsg,
|
|
showCancel: false
|
|
})
|
|
}
|
|
reject(err)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
const api = {
|
|
wxLogin(code) {
|
|
return request({
|
|
url: config.api.login,
|
|
method: 'POST',
|
|
data: {
|
|
wxMiniCode: code
|
|
}
|
|
})
|
|
},
|
|
|
|
getQuestion(categorySn) {
|
|
return request({
|
|
url: config.api.getQuestion,
|
|
method: 'POST',
|
|
data: categorySn ? { category_sn: categorySn } : {}
|
|
})
|
|
},
|
|
|
|
answerQuestion(sn, answer) {
|
|
return request({
|
|
url: config.api.answerQuestion,
|
|
method: 'POST',
|
|
data: {
|
|
sn,
|
|
answer
|
|
}
|
|
})
|
|
},
|
|
|
|
getAllCategory() {
|
|
return request({
|
|
url: config.api.getAllCategory,
|
|
method: 'POST'
|
|
})
|
|
},
|
|
|
|
getRecord(page = 1, pageSize = 10) {
|
|
return request({
|
|
url: '/qgdzs/auth/get_record',
|
|
method: 'POST',
|
|
data: {
|
|
page,
|
|
page_size: pageSize
|
|
},
|
|
noAuthModal: true
|
|
})
|
|
},
|
|
|
|
getQuestionBySn(questionSn) {
|
|
return request({
|
|
url: '/qgdzs/open/get_question',
|
|
method: 'POST',
|
|
data: {
|
|
question_sn: questionSn
|
|
}
|
|
})
|
|
},
|
|
|
|
getQuestionInfo(questionSn) {
|
|
return request({
|
|
url: '/qgdzs/open/get_question_info',
|
|
method: 'POST',
|
|
data: {
|
|
question_sn: questionSn
|
|
}
|
|
})
|
|
},
|
|
|
|
get(url, data = {}) {
|
|
return request({
|
|
url,
|
|
method: 'GET',
|
|
data
|
|
})
|
|
},
|
|
|
|
post(url, data = {}) {
|
|
return request({
|
|
url,
|
|
method: 'POST',
|
|
data
|
|
})
|
|
},
|
|
|
|
put(url, data = {}) {
|
|
return request({
|
|
url,
|
|
method: 'PUT',
|
|
data
|
|
})
|
|
},
|
|
|
|
delete(url, data = {}) {
|
|
return request({
|
|
url,
|
|
method: 'DELETE',
|
|
data
|
|
})
|
|
}
|
|
}
|
|
|
|
export default api
|