220 lines
6.2 KiB
TypeScript
220 lines
6.2 KiB
TypeScript
import { toast } from 'sard-uniapp'
|
|
import dbJson from '@/static/db.json'
|
|
import { useUserStore } from '@/store'
|
|
import { joinUrl } from '@/utils/common'
|
|
import { isH5 } from '@/utils/platform'
|
|
|
|
function request<T = any>(option: UniApp.RequestOptions): Promise<IResData<T>> & { abort: () => void } {
|
|
let task: UniApp.RequestTask | undefined
|
|
let aborted = false
|
|
|
|
const promise = new Promise<IResData<T>>((resolve, reject) => {
|
|
// 判断是否是登录请求
|
|
const isLogin = option.url?.includes('login')
|
|
|
|
const readDbJson = new Promise<Record<string, string>>((res, rej) => {
|
|
if (isH5) {
|
|
// H5:用 request 请求,带时间戳保证最新
|
|
const timestamp = Date.now()
|
|
uni.request({
|
|
url: `/static/db.json?t=${timestamp}`,
|
|
method: 'GET',
|
|
success: r => res(r.data as Record<string, string>),
|
|
fail: err => rej(err),
|
|
})
|
|
}
|
|
else {
|
|
// 非 H5 直接返回本地导入的 JSON
|
|
res(dbJson)
|
|
}
|
|
})
|
|
|
|
readDbJson
|
|
.then((dbRes) => {
|
|
if (aborted)
|
|
return reject(new Error('请求已取消'))
|
|
|
|
// 组织请求 URL
|
|
let reqUrl = ''
|
|
const userStore = useUserStore()
|
|
const { token, userid, orgid } = userStore.userInfo || {}
|
|
|
|
if (!dbRes || Object.keys(dbRes).length === 0) {
|
|
toast.fail('机构配置获取失败,请联系管理人员!')
|
|
return reject(new Error('机构配置获取失败,请联系管理人员!'))
|
|
}
|
|
|
|
if (isLogin) {
|
|
const orgidFromData = (option.data as any)?.orgid || ''
|
|
reqUrl = dbRes[orgidFromData]
|
|
}
|
|
else {
|
|
reqUrl = dbRes[orgid || '']
|
|
}
|
|
|
|
if (!reqUrl) {
|
|
const pages = getCurrentPages()
|
|
const currentPage = pages[pages.length - 1]
|
|
const currentRoute = `/${currentPage.route}`
|
|
|
|
if (currentRoute !== '/pages-sub/login/index') {
|
|
uni.showToast({ title: '当前登录已过期,请重新登录', icon: 'error' })
|
|
|
|
uni.navigateTo({
|
|
url: '/pages-sub/login/index',
|
|
})
|
|
}
|
|
else {
|
|
uni.showToast({ title: '机构码错误', icon: 'error' })
|
|
}
|
|
|
|
return reject(new Error('机构码错误'))
|
|
}
|
|
|
|
// 设置 headers
|
|
const headers: Record<string, any> = { ...(option.header || {}) }
|
|
if (!isLogin) {
|
|
headers.Authorization = `Bearer ${token}`
|
|
headers.userid = encodeURIComponent(userid)
|
|
headers.orgid = orgid
|
|
}
|
|
|
|
// 拼接完整 URL
|
|
option.url = joinUrl(reqUrl, option.url || '')
|
|
option.header = headers
|
|
|
|
// 发请求
|
|
task = uni.request({
|
|
...option,
|
|
url: option.url,
|
|
success: (res) => {
|
|
if (aborted)
|
|
return reject(new Error('请求已取消'))
|
|
|
|
let data: IResData<T>
|
|
try {
|
|
// 解析最外层响应
|
|
data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
|
|
|
|
// 如果 data.data 是字符串,则解析成对象
|
|
if (data.data && typeof data.data === 'string') {
|
|
try {
|
|
data.data = JSON.parse(data.data)
|
|
}
|
|
catch {
|
|
// 如果解析失败,保持原始字符串即可
|
|
console.warn('data.data 不是合法 JSON 字符串', data.data)
|
|
}
|
|
}
|
|
}
|
|
catch (err) {
|
|
console.log(`解析响应JSON失败:${err}`)
|
|
toast.fail('响应数据解析失败')
|
|
return reject(new Error('响应数据解析失败'))
|
|
}
|
|
|
|
if (data.code === 200) {
|
|
resolve(data)
|
|
}
|
|
else {
|
|
toast.fail(data.message || '请求错误')
|
|
reject(new Error(data.message || '请求错误'))
|
|
}
|
|
|
|
// 登录失效处理
|
|
if (data.code === 600) {
|
|
uni.showToast({ title: '请重新登录', icon: 'none' })
|
|
|
|
const pages = getCurrentPages()
|
|
const currentPage = pages[pages.length - 1]
|
|
const currentRoute = `/${currentPage.route}`
|
|
if (currentRoute !== '/pages-sub/login/index') {
|
|
uni.navigateTo({ url: '/pages-sub/login/index' })
|
|
}
|
|
}
|
|
},
|
|
fail: (err) => {
|
|
if (aborted)
|
|
return reject(new Error('请求已取消'))
|
|
console.log(err)
|
|
toast.fail('网络请求失败,请联系管理人员')
|
|
|
|
reject(new Error(err.errMsg || '网络请求失败'))
|
|
},
|
|
})
|
|
})
|
|
.catch((err) => {
|
|
toast.fail('机构配置获取失败,请联系管理人员!')
|
|
console.error(err)
|
|
reject(new Error('机构配置获取失败,请联系管理人员!'))
|
|
})
|
|
}) as Promise<IResData<T>> & { abort: () => void }
|
|
|
|
promise.abort = () => {
|
|
aborted = true
|
|
task?.abort()
|
|
}
|
|
|
|
return promise
|
|
}
|
|
|
|
// GET
|
|
request.get = <T = any>(url: string, data?: any, option?: UniApp.RequestOptions) => {
|
|
return request<T>({
|
|
method: 'GET',
|
|
url,
|
|
data,
|
|
...option,
|
|
})
|
|
}
|
|
|
|
// PUT
|
|
request.put = <T = any>(url: string, data?: any, option?: UniApp.RequestOptions) => {
|
|
return request<T>({
|
|
method: 'PUT',
|
|
url,
|
|
data,
|
|
...option,
|
|
})
|
|
}
|
|
|
|
// DELETE
|
|
request.delete = <T = any>(url: string, data?: any, option?: UniApp.RequestOptions) => {
|
|
return request<T>({
|
|
method: 'DELETE',
|
|
url,
|
|
data,
|
|
...option,
|
|
})
|
|
}
|
|
|
|
// POST JSON
|
|
request.postJson = <T = any>(url: string, data?: any, option?: UniApp.RequestOptions) => {
|
|
return request<T>({
|
|
method: 'POST',
|
|
url,
|
|
data,
|
|
header: {
|
|
'Content-Type': 'application/json',
|
|
...(option?.header || {}),
|
|
},
|
|
...option,
|
|
})
|
|
}
|
|
|
|
// POST 表单
|
|
request.postForm = <T = any>(url: string, data?: any, option?: UniApp.RequestOptions) => {
|
|
return request<T>({
|
|
method: 'POST',
|
|
url,
|
|
data,
|
|
header: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
...(option?.header || {}),
|
|
},
|
|
...option,
|
|
})
|
|
}
|
|
|
|
export default request
|