Files
ShaFaFanXin/前端/utils/request.uts

205 lines
4.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 网络请求封装
* 预留后端接口对接
*/
import { getEnvConfig, useMock, STORAGE_KEYS } from './config.uts'
import { getMockData } from './mock.uts'
// 请求配置类型
type RequestOptions = {
url : string
method ?: 'GET' | 'POST' | 'PUT' | 'DELETE'
data ?: UTSJSONObject | null
header ?: UTSJSONObject | null
showLoading ?: boolean
loadingText ?: string
}
// 响应数据类型
type ResponseData = {
code : number
message : string
data : any | null
}
/**
* 请求拦截器
*/
const requestInterceptor = (options : RequestOptions) : RequestOptions => {
// 添加token
const token = uni.getStorageSync(STORAGE_KEYS.TOKEN) as string
if (token != '') {
if (options.header == null) {
options.header = {} as UTSJSONObject
}
options.header!['Authorization'] = `Bearer ${token}`
}
return options
}
/**
* 响应拦截器
*/
const responseInterceptor = (response : UTSJSONObject) : ResponseData => {
const statusCode = response['statusCode'] as number
const data = response['data'] as UTSJSONObject | null
console.log('响应拦截器 - statusCode:', statusCode)
console.log('响应拦截器 - data:', data)
// 处理空响应
if (data == null) {
return {
code: statusCode,
message: '响应数据为空',
data: null
} as ResponseData
}
if (statusCode == 200) {
const code = (data['code'] ?? 0) as number
console.log('响应拦截器 - 解析的 code:', code)
if (code == 0 || code == 200) {
const result = {
code: 0,
message: (data['message'] ?? 'success') as string,
data: data['data'] ?? null
} as ResponseData
console.log('响应拦截器 - 返回成功结果:', result)
return result
} else if (code == 401) {
// token过期,跳转登录
uni.removeStorageSync(STORAGE_KEYS.TOKEN)
uni.showToast({
title: '请重新登录',
icon: 'none'
})
return {
code: code,
message: (data['message'] ?? '请重新登录') as string,
data: null
} as ResponseData
} else {
return {
code: code,
message: (data['message'] ?? '请求失败') as string,
data: data['data'] ?? null
} as ResponseData
}
} else {
return {
code: statusCode,
message: '网络请求失败',
data: null
} as ResponseData
}
}
/**
* 统一请求方法
*/
export const request = (options : RequestOptions) : Promise<ResponseData> => {
return new Promise((resolve, reject) => {
// 使用Mock数据
if (useMock) {
const mockData = getMockData(options.url, options.method ?? 'GET', options.data)
if (mockData != null) {
setTimeout(() => {
resolve({
code: 0,
message: 'success',
data: mockData
} as ResponseData)
}, 300) // 模拟网络延迟
return
}
}
// 请求拦截
const finalOptions = requestInterceptor(options)
// 显示loading
if (finalOptions.showLoading == true) {
uni.showLoading({
title: finalOptions.loadingText ?? '加载中...'
})
}
const config = getEnvConfig()
const BASE_URL = 'http://192.168.1.43:3000/api'
const baseUrl = config['baseUrl'] as string
// 清理 data 中的 undefined 字段,避免被序列化为 'undefined'
if (finalOptions.data && typeof finalOptions.data === 'object') {
for (const key in finalOptions.data) {
if (finalOptions.data[key] === undefined) {
delete finalOptions.data[key]
}
}
}
uni.request({
url: baseUrl + finalOptions.url,
method: finalOptions.method ?? 'GET',
data: finalOptions.data as UTSJSONObject | null,
header: finalOptions.header as UTSJSONObject | null,
success: (res) => {
if (finalOptions.showLoading == true) {
uni.hideLoading()
}
console.log('请求成功原始响应:', res)
const result = responseInterceptor(res as UTSJSONObject)
console.log('拦截器处理后结果:', result)
console.log('result.code 类型:', typeof result.code, '值:', result.code)
if (result.code == 0) {
console.log('判断为成功resolve')
resolve(result)
} else {
console.log('判断为失败,显示 toast 并 reject')
uni.showToast({
title: result.message,
icon: 'none'
})
reject(result)
}
},
fail: (err) => {
if (finalOptions.showLoading == true) {
uni.hideLoading()
}
uni.showToast({
title: '网络连接失败',
icon: 'none'
})
reject({
code: -1,
message: '网络连接失败',
data: null
} as ResponseData)
}
})
})
}
/**
* GET请求
*/
export const get = (url : string, data ?: UTSJSONObject | null) : Promise<ResponseData> => {
return request({
url: url,
method: 'GET',
data: data
} as RequestOptions)
}
/**
* POST请求
*/
export const post = (url : string, data ?: UTSJSONObject | null) : Promise<ResponseData> => {
return request({
url: url,
method: 'POST',
data: data
} as RequestOptions)
}