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(option: UniApp.RequestOptions): Promise> & { abort: () => void } { let task: UniApp.RequestTask | undefined let aborted = false const promise = new Promise>((resolve, reject) => { // 判断是否是登录请求 const isLogin = option.url?.includes('login') const readDbJson = new Promise>((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), 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 = { ...(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 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> & { abort: () => void } promise.abort = () => { aborted = true task?.abort() } return promise } // GET request.get = (url: string, data?: any, option?: UniApp.RequestOptions) => { return request({ method: 'GET', url, data, ...option, }) } // PUT request.put = (url: string, data?: any, option?: UniApp.RequestOptions) => { return request({ method: 'PUT', url, data, ...option, }) } // DELETE request.delete = (url: string, data?: any, option?: UniApp.RequestOptions) => { return request({ method: 'DELETE', url, data, ...option, }) } // POST JSON request.postJson = (url: string, data?: any, option?: UniApp.RequestOptions) => { return request({ method: 'POST', url, data, header: { 'Content-Type': 'application/json', ...(option?.header || {}), }, ...option, }) } // POST 表单 request.postForm = (url: string, data?: any, option?: UniApp.RequestOptions) => { return request({ method: 'POST', url, data, header: { 'Content-Type': 'application/x-www-form-urlencoded', ...(option?.header || {}), }, ...option, }) } export default request