TestEShopDist/src/use/useHttp.ts

219 lines
5.7 KiB
TypeScript

import Taro, { useRouter } from '@tarojs/taro'
import { useEffect, useRef, useState } from 'react'
import qs from 'qs'
import useUserInfo from './useUserInfo'
import useLogin from './useLogin'
import useLoginRequest from './useLoginRequest'
import { BASE_URL, WX_APPID } from '@/common/constant'
import { getFilterData } from '@/common/util'
interface Params {
code: string | null
success: true | false
data: any
msg: string
loading: true | false
error: any
query: any
filter: any
sort: any
total: number
multiple: true | false // 请求多次
count: number // 第几次请求
token: string // token
page?: number
pageSize?: number
}
interface option {
url?: string
method?: 'get' | 'post' | 'put' | 'delete'
type?: string
data?: any
page?: number
pageSize?: number
pagination?: true | false
base_url?: string
apiMsgStatus?: true | false
}
/**
* 返回状态信息,根据 http 状态错
* @param {Number} status
* @returns
*/
const showStatus = (status) => {
let message = ''
switch (status) {
case 400:
message = '请求错误(400)'
break
case 401:
message = '未授权,请重新登录(401)'
break
case 403:
message = '拒绝访问(403)'
break
case 404:
message = '请求出错(404)'
break
case 408:
message = '请求超时(408)'
break
case 500:
message = '服务器错误(500)'
break
case 501:
message = '服务未实现(501)'
break
case 502:
message = '网络错误(502)'
break
case 503:
message = '服务不可用(503)'
break
case 504:
message = '网络超时(504)'
break
case 505:
message = 'HTTP版本不受支持(505)'
break
default:
message = `连接出错(${status})!`
}
return `${message},请检查网络或联系管理员!`
}
/**
* axios 请求状态封装,返回响应式数据 fetch(), loading, error, code, msg 等常用方法/状态
* @param {Object} options 对象
* @param {String} options.url 请求的URL
* @param {String} options.method 请求的方法
* @param {Object} options.data 请求的参数
* @returns {Object} 返回fetch(), loading, error, code, msg
*/
export const useRequest = (
options: option = {
url: '/',
method: 'get',
type: 'json',
data: {},
page: 1,
pageSize: 24,
pagination: false, // 是否分页
base_url: '',
apiMsgStatus: true, // 是否直接弹出后端错误
},
) => {
options.url = `${options.base_url || BASE_URL}${options.url}`
const params: Params = {
code: null, // 业务码
success: false, // 请求是否成功
data: {},
msg: '',
loading: false,
error: null,
query: {},
filter: null,
sort: '',
total: 0,
multiple: true, // 请求多次
count: 0, // 第几次请求
token: '', // token
}
const stateRef = useRef({ ...params })
const [state, setState] = useState({ ...stateRef.current })
const { removeToken, removeSessionKey, removeUserInfo } = useUserInfo()
const { login } = useLoginRequest()
// 请求函数
const fetchData = async(sub_options?: any) => {
stateRef.current.loading = true
setState(e => ({ ...e, loading: true }))
stateRef.current.query = {
...sub_options,
...(options.pagination && {
page: stateRef.current.page || '',
size: stateRef.current.pageSize || '',
}),
...stateRef.current.filter,
...stateRef.current.sort,
}
const query = getFilterData(stateRef.current.query)
try {
const token = Taro.getStorageSync('token')
const q = {
...options,
...{
header: {
Platform: 6,
Appid: WX_APPID,
Authorization: token || stateRef.current.token,
},
},
...(options.method?.toUpperCase() == 'GET'
? {
data: query,
}
: {
data: options.type?.toUpperCase() == 'FORMDATA' ? qs.stringify(stateRef.current?.query) : query,
}),
}
const result = await Taro.request(q as any)
const { statusCode } = result
const { code, msg, data } = result.data
if (statusCode === 200) {
stateRef.current.success = code === 0
stateRef.current.code = code
stateRef.current.msg = msg
stateRef.current.data = data
stateRef.current.total = data?.list ? data?.total : 0
if (code !== 0) {
if (code === 50332) {
Taro.switchTab({
url: '/pages/index/index',
})
}
options.apiMsgStatus !== false
&& Taro.showToast({
title: `${msg}`,
icon: 'none',
duration: 3000,
})
console.log('错误::', msg)
}
}
else {
if (statusCode === 401) {
removeToken()
removeSessionKey()
removeUserInfo()
login()
}
else {
Taro.showToast({
title: `错误:${showStatus(statusCode)}`,
icon: 'none',
})
}
}
}
catch (e) {
stateRef.current.success = false
stateRef.current.error = true
stateRef.current.msg = e.errMsg
console.log('后台错误信息::', e.errMsg)
}
stateRef.current.error = false
stateRef.current.loading = false
setState(() => ({ ...stateRef.current }))
return stateRef.current
}
return {
fetchData,
state,
}
}