request.js
4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import config from '@/config.js'
import _ from 'underscore'
const excludeUrls = ['getMemberCountInfo', 'getInfo']
const SUCCESS_CODES = [0, 200]
const TOKEN_EXPIRE_CODES = [60001, 60002, 401]
// Loading计数器
let loadingCount = 0
// 获取Token
function getToken() {
try {
return uni.getStorageSync('token') || ''
} catch (e) {
console.error('获取token失败:', e)
return ''
}
}
// 获取请求头
function getHeaders() {
return {
'Authorization': getToken(),
'Content-Type': 'application/json',
'Content-Language': 'zh_CN',
'Ztx-Per-Id': uni.getStorageSync('perId') || '-1'
}
}
// 显示Loading
function showLoading(title = '加载中...') {
if (loadingCount == 0) {
uni.showLoading({title, mask: true})
}
loadingCount++
}
// 隐藏Loading
function hideLoading() {
loadingCount--
if (loadingCount == 0) {
uni.hideLoading()
}
}
// Token过期处理
function handleTokenExpire() {
// 清除本地存储
uni.removeStorageSync('token')
uni.removeStorageSync('perId')
// 跳转登录页
setTimeout(() => {
uni.redirectTo({
url: '/login/login'
})
}, 1500)
}
// 显示错误提示
function showError(msg) {
console.log('showError called:', msg)
// 先隐藏可能存在的 loading,确保 Toast 能显示
uni.hideLoading()
uni.showToast({
title: msg || '请求失败',
icon: 'none',
duration: 3000
})
}
const request = function (req) {
// 参数校验
if (!req || !req.url) {
return Promise.reject(new Error('请求参数不完整'))
}
req.method = (req.method || 'GET').toUpperCase()
const validMethods = ['GET', 'POST', 'PUT', 'DELETE']
if (!validMethods.includes(req.method)) {
const error = `暂不支持的请求方式: ${req.method}`
showError(error)
return Promise.reject(new Error(error))
}
// 显示Loading
if (req.showLoading != false) {
showLoading(req.loadingTitle)
}
return new Promise((resolve, reject) => {
uni.request({
url: config.baseUrl_api + req.url,
method: req.method,
data: req.params,
header: getHeaders(),
timeout: req.timeout || 60000 * 5 // 添加超时设置
}).then(response => {
const {statusCode, data} = response
// HTTP状态码处理
if (statusCode != 200) {
throw new Error(`HTTP ${statusCode}`)
}
// 业务状态码处理
const isSuccess = SUCCESS_CODES.includes(data.code) ||
data.pageData?.code == 200 ||
excludeUrls.some(url => req.url.includes(url))
if (isSuccess) {
resolve(data)
return
}
// Token过期处理
if (TOKEN_EXPIRE_CODES.includes(data.code)) {
handleTokenExpire()
reject(new Error('登录已过期,请重新登录'))
return
}
// 业务错误(code != 200 且非 Token 过期)- 统一显示错误提示
const errorMsg = data.msg || '操作失败'
showError(errorMsg)
// code == 500 时仅显示提示,不抛出异常,避免页面 catch 覆盖错误信息
if (data.code == 500) {
return
}
reject(new Error(errorMsg))
}).catch(error => {
console.error('请求失败:', error)
// 网络错误处理
if (error.errMsg) {
if (error.errMsg.includes('timeout')) {
showError('请求超时,请稍后重试')
} else if (error.errMsg.includes('fail')) {
showError('网络连接失败')
} else {
showError('请求失败,请稍后重试')
}
}
reject(error)
}).finally(() => {
// 延迟隐藏 loading,确保错误提示能显示
setTimeout(() => {
if (req.showLoading != false) {
hideLoading()
}
}, 100)
})
})
}
// 添加便捷方法
request.get = (url, params, options = {}) => {
return request({...options, url, method: 'GET', params})
}
request.post = (url, params, options = {}) => {
return request({...options, url, method: 'POST', params})
}
request.put = (url, params, options = {}) => {
return request({...options, url, method: 'PUT', params})
}
request.delete = (url, params, options = {}) => {
return request({...options, url, method: 'DELETE', params})
}
export default request