index.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import { isDev, ignoreTokens, config } from "@/config";
  2. import { locale, t } from "../locale";
  3. import { isNull, isObject, parse, storage } from "../utils";
  4. import { useStore } from "../store";
  5. // 请求参数类型定义
  6. export type RequestOptions = {
  7. url: string; // 请求地址
  8. method?: RequestMethod; // 请求方法
  9. data?: any; // 请求体数据
  10. params?: any; // URL参数
  11. header?: any; // 请求头
  12. timeout?: number; // 超时时间
  13. withCredentials?: boolean; // 是否携带凭证
  14. firstIpv4?: boolean; // 是否优先使用IPv4
  15. enableChunked?: boolean; // 是否启用分块传输
  16. };
  17. // 响应数据类型定义
  18. export type Response<R = any> = {
  19. code: number;
  20. message: string;
  21. data?: R;
  22. };
  23. // 请求队列(用于等待token刷新后继续请求)
  24. let requests: ((token: string) => void)[] = [];
  25. // 标记token是否正在刷新
  26. let isRefreshing = false;
  27. // 判断当前url是否忽略token校验
  28. const isIgnoreToken = (url: string) => {
  29. return ignoreTokens.some((e) => {
  30. const pattern = e.replace(/\*/g, ".*");
  31. return new RegExp(pattern).test(url);
  32. });
  33. };
  34. /**
  35. * 通用请求方法
  36. * @param options 请求参数
  37. * @returns Promise<T>
  38. */
  39. export function request<R = any>(options: RequestOptions): Promise<Response<R>> {
  40. let { url, method = "GET", data = {}, header = {}, timeout = 60000 } = options;
  41. const { user } = useStore();
  42. // 开发环境下打印请求信息
  43. if (isDev) {
  44. console.log(`[${method}] ${url}`);
  45. }
  46. // 拼接基础url
  47. if (!url.startsWith("http")) {
  48. url = config.baseUrl + url;
  49. }
  50. // 获取当前token
  51. let Authorization: string | null = user.token;
  52. console.log(Authorization);
  53. return new Promise((resolve, reject) => {
  54. // 发起请求的实际函数
  55. const next = () => {
  56. console.log(222);
  57. uni.request({
  58. url,
  59. method,
  60. data,
  61. header: {
  62. Authorization,
  63. language: locale.value,
  64. ...(header as UTSJSONObject)
  65. },
  66. timeout,
  67. success(res) {
  68. console.log(res);
  69. // 401 无权限
  70. if (res.statusCode == 401) {
  71. user.logout();
  72. reject({ message: t("无权限") } as Response);
  73. }
  74. // 502 服务异常
  75. else if (res.statusCode == 502) {
  76. reject({
  77. message: t("服务异常")
  78. } as Response);
  79. }
  80. // 404 未找到
  81. else if (res.statusCode == 404) {
  82. return reject({
  83. message: `[404] ${url}`
  84. } as Response);
  85. }
  86. // 200 正常响应
  87. else if (res.statusCode == 0 || res.statusCode == 200) {
  88. if (res.data == null) {
  89. resolve(null);
  90. } else if (!isObject(res.data as any)) {
  91. resolve(res.data);
  92. } else {
  93. // 解析响应数据
  94. const { code, message, data } = parse<Response>(
  95. res.data ?? { code: 0 }
  96. )!;
  97. switch (code) {
  98. case 1000:
  99. resolve(data);
  100. break;
  101. default:
  102. reject({ message, code } as Response);
  103. break;
  104. }
  105. }
  106. } else {
  107. reject({ message: t("服务异常") } as Response);
  108. }
  109. },
  110. // 网络请求失败
  111. fail(err) {
  112. reject({ message: err.errMsg } as Response);
  113. }
  114. });
  115. };
  116. console.log(2222);
  117. next();
  118. // 非刷新token接口才进行token有效性校验
  119. if (!options.url.includes("/refreshToken")) {
  120. if (!isNull(Authorization)) {
  121. // 判断token是否过期
  122. // if (storage.isExpired("token")) {
  123. // // 判断refreshToken是否过期
  124. // if (storage.isExpired("refreshToken")) {
  125. // // 刷新token也过期,直接退出登录
  126. // user.logout();
  127. // return;
  128. // }
  129. // // 如果当前没有在刷新token,则发起刷新
  130. // if (!isRefreshing) {
  131. // isRefreshing = true;
  132. // user.refreshToken()
  133. // .then((token) => {
  134. // // 刷新成功后,执行队列中的请求
  135. // requests.forEach((cb) => cb(token));
  136. // requests = [];
  137. // isRefreshing = false;
  138. // })
  139. // .catch((err) => {
  140. // reject(err);
  141. // user.logout();
  142. // });
  143. // }
  144. // // 将当前请求加入队列,等待token刷新后再执行
  145. // new Promise((resolve) => {
  146. // requests.push((token: string) => {
  147. // // 重新设置token
  148. // Authorization = token;
  149. // next();
  150. // resolve(true);
  151. // });
  152. // });
  153. // // 此处return,等待token刷新
  154. // return;
  155. // }
  156. }
  157. }
  158. // token有效,直接发起请求
  159. // next();
  160. });
  161. }
  162. export function useGet<R = any, T = any>(url: string, params?: T, config?: RequestOptions): Promise<Response<R>> {
  163. const options: RequestOptions = {
  164. url,
  165. params,
  166. method: 'GET',
  167. ...config,
  168. }
  169. return request<R>(options)
  170. }
  171. export function usePost<R = any, T = any>(url: string, data?: T, config?: RequestOptions): Promise<Response<R>> {
  172. const options: RequestOptions = {
  173. url,
  174. data,
  175. method: 'POST',
  176. ...config,
  177. }
  178. return request<R>(options)
  179. }
  180. export function usePut<R = any, T = any>(url: string, data?: T, config?: RequestOptions): Promise<Response<R>> {
  181. const options: RequestOptions = {
  182. url,
  183. data,
  184. method: 'PUT',
  185. ...config,
  186. }
  187. return request<R>(options)
  188. }
  189. export function useDelete<R = any, T = any>(url: string, data?: T, config?: RequestOptions): Promise<Response<R>> {
  190. const options: RequestOptions = {
  191. url,
  192. data,
  193. method: 'DELETE',
  194. ...config,
  195. }
  196. return request<R>(options)
  197. }