a
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* Material Design风格的网络请求工具
|
||||
* 封装uni.request,提供统一的错误处理和加载状态
|
||||
*/
|
||||
|
||||
const BASE_URL = 'https://www.wanandroid.com'
|
||||
|
||||
// 请求配置
|
||||
const defaultConfig = {
|
||||
baseURL: BASE_URL,
|
||||
timeout: 10000,
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
}
|
||||
|
||||
// 错误码映射
|
||||
const errorMessages = {
|
||||
0: '请求成功',
|
||||
'-1': '请求失败',
|
||||
'-1001': '登录失效,请重新登录',
|
||||
400: '请求参数错误',
|
||||
401: '未授权',
|
||||
403: '禁止访问',
|
||||
404: '资源不存在',
|
||||
500: '服务器错误',
|
||||
502: '网关错误',
|
||||
503: '服务不可用',
|
||||
504: '网关超时'
|
||||
}
|
||||
|
||||
class Request {
|
||||
constructor(config = {}) {
|
||||
this.config = { ...defaultConfig, ...config }
|
||||
this.interceptors = {
|
||||
request: [],
|
||||
response: []
|
||||
}
|
||||
}
|
||||
|
||||
// 添加请求拦截器
|
||||
useRequestInterceptor(interceptor) {
|
||||
this.interceptors.request.push(interceptor)
|
||||
}
|
||||
|
||||
// 添加响应拦截器
|
||||
useResponseInterceptor(interceptor) {
|
||||
this.interceptors.response.push(interceptor)
|
||||
}
|
||||
|
||||
// 执行请求拦截器
|
||||
async runRequestInterceptors(config) {
|
||||
let result = config
|
||||
for (const interceptor of this.interceptors.request) {
|
||||
result = await interceptor(result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 执行响应拦截器
|
||||
async runResponseInterceptors(response) {
|
||||
let result = response
|
||||
for (const interceptor of this.interceptors.response) {
|
||||
result = await interceptor(result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 统一请求方法
|
||||
async request(method, url, data = {}, config = {}) {
|
||||
// 合并配置
|
||||
const requestConfig = {
|
||||
...this.config,
|
||||
...config,
|
||||
method: method.toUpperCase(),
|
||||
url: url.startsWith('http') ? url : `${this.config.baseURL}${url}`,
|
||||
data
|
||||
}
|
||||
|
||||
try {
|
||||
// 执行请求拦截器
|
||||
const finalConfig = await this.runRequestInterceptors(requestConfig)
|
||||
|
||||
// 显示加载状态
|
||||
if (finalConfig.showLoading !== false) {
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
mask: true
|
||||
})
|
||||
}
|
||||
|
||||
// 发送请求
|
||||
const [error, res] = await uni.request(finalConfig)
|
||||
|
||||
// 隐藏加载状态
|
||||
if (finalConfig.showLoading !== false) {
|
||||
uni.hideLoading()
|
||||
}
|
||||
|
||||
if (error) {
|
||||
throw this.handleRequestError(error)
|
||||
}
|
||||
|
||||
// 执行响应拦截器
|
||||
const finalResponse = await this.runResponseInterceptors(res)
|
||||
|
||||
// 处理业务错误
|
||||
return this.handleBusinessError(finalResponse)
|
||||
|
||||
} catch (error) {
|
||||
// 隐藏加载状态
|
||||
uni.hideLoading()
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// 处理网络错误
|
||||
handleRequestError(error) {
|
||||
console.error('网络请求错误:', error)
|
||||
|
||||
let message = '网络请求失败'
|
||||
if (error.errMsg) {
|
||||
if (error.errMsg.includes('timeout')) {
|
||||
message = '请求超时,请检查网络'
|
||||
} else if (error.errMsg.includes('fail')) {
|
||||
message = '网络连接失败'
|
||||
}
|
||||
}
|
||||
|
||||
// 显示错误提示
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
})
|
||||
|
||||
return new Error(message)
|
||||
}
|
||||
|
||||
// 处理业务错误
|
||||
handleBusinessError(response) {
|
||||
const { statusCode, data } = response
|
||||
|
||||
if (statusCode !== 200) {
|
||||
const message = errorMessages[statusCode] || `请求失败,状态码: ${statusCode}`
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
})
|
||||
throw new Error(message)
|
||||
}
|
||||
|
||||
if (data && data.errorCode !== undefined) {
|
||||
if (data.errorCode !== 0) {
|
||||
const message = data.errorMsg || errorMessages[data.errorCode] || '请求失败'
|
||||
|
||||
// 特殊处理登录失效
|
||||
if (data.errorCode === -1001) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '登录已失效,是否重新登录?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 跳转到登录页面
|
||||
uni.navigateTo({
|
||||
url: '/pages/login/login'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
})
|
||||
}
|
||||
|
||||
throw new Error(message)
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// GET请求
|
||||
get(url, params = {}, config = {}) {
|
||||
return this.request('GET', url, params, config)
|
||||
}
|
||||
|
||||
// POST请求
|
||||
post(url, data = {}, config = {}) {
|
||||
return this.request('POST', url, data, config)
|
||||
}
|
||||
|
||||
// PUT请求
|
||||
put(url, data = {}, config = {}) {
|
||||
return this.request('PUT', url, data, config)
|
||||
}
|
||||
|
||||
// DELETE请求
|
||||
delete(url, data = {}, config = {}) {
|
||||
return this.request('DELETE', url, data, config)
|
||||
}
|
||||
}
|
||||
|
||||
// 创建默认实例
|
||||
const request = new Request()
|
||||
|
||||
// 添加请求拦截器 - 添加Token
|
||||
request.useRequestInterceptor(async (config) => {
|
||||
// 从存储中获取Token
|
||||
const token = uni.getStorageSync('token')
|
||||
if (token) {
|
||||
config.header = {
|
||||
...config.header,
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
return config
|
||||
})
|
||||
|
||||
// 添加响应拦截器 - 处理通用逻辑
|
||||
request.useResponseInterceptor(async (response) => {
|
||||
// 可以在这里添加通用处理逻辑
|
||||
return response
|
||||
})
|
||||
|
||||
// API接口定义
|
||||
const api = {
|
||||
// 首页相关
|
||||
getBanners: () => request.get('/banner/json'),
|
||||
getHotWords: () => request.get('/hotkey/json'),
|
||||
getTopArticles: () => request.get('/article/top/json'),
|
||||
getArticles: (page = 0, pageSize = 20) =>
|
||||
request.get(`/article/list/${page}/json`, { page_size: pageSize }),
|
||||
|
||||
// 搜索相关
|
||||
searchArticles: (keyword, page = 0) =>
|
||||
request.post(`/article/query/${page}/json`, { k: keyword }),
|
||||
|
||||
// 体系相关
|
||||
getTreeData: () => request.get('/tree/json'),
|
||||
getTreeArticles: (cid, page = 0) =>
|
||||
request.get(`/article/list/${page}/json`, { cid }),
|
||||
|
||||
// 项目相关
|
||||
getProjectTree: () => request.get('/project/tree/json'),
|
||||
getProjectList: (cid, page = 1) =>
|
||||
request.get(`/project/list/${page}/json`, { cid }),
|
||||
|
||||
// 公众号相关
|
||||
getWxChapters: () => request.get('/wxarticle/chapters/json'),
|
||||
getWxArticles: (id, page = 1) =>
|
||||
request.get(`/wxarticle/list/${id}/${page}/json`),
|
||||
|
||||
// 登录相关
|
||||
login: (username, password) =>
|
||||
request.post('/user/login', { username, password }),
|
||||
register: (username, password, repassword) =>
|
||||
request.post('/user/register', { username, password, repassword })
|
||||
}
|
||||
|
||||
// 导出
|
||||
export default request
|
||||
export { api }
|
||||
Reference in New Issue
Block a user