request.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /**
  2. * HTTP请求工具类
  3. * 封装uni.request,统一处理请求和响应
  4. */
  5. import { API_CONFIG } from './config';
  6. import { getToken, handleUnauthorized } from './auth';
  7. /**
  8. * 请求配置接口
  9. */
  10. interface RequestConfig {
  11. url: string;
  12. method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
  13. data?: any;
  14. header?: any;
  15. timeout?: number;
  16. /** 是否跳过添加token,用于免登录接口 */
  17. skipAuth?: boolean;
  18. }
  19. /**
  20. * 响应数据接口
  21. */
  22. interface ResponseData<T = any> {
  23. code: number;
  24. message: string;
  25. data?: T;
  26. }
  27. /**
  28. * 发起HTTP请求
  29. * @param config 请求配置
  30. * @returns Promise<响应数据>
  31. */
  32. export const request = <T = any>(config: RequestConfig): Promise<T> => {
  33. return new Promise((resolve, reject) => {
  34. const { url, method = 'GET', data, header = {}, timeout = API_CONFIG.timeout, skipAuth = false } = config;
  35. // 构建完整URL
  36. let fullUrl = url.startsWith('http') ? url : `${API_CONFIG.baseUrl}${url}`;
  37. // 添加token到请求头(skipAuth为true时跳过)
  38. if (!skipAuth) {
  39. const token = getToken();
  40. if (token) {
  41. header['accessToken'] = token;
  42. if (API_CONFIG.enableLog) {
  43. console.log('[请求拦截] 添加token到请求头:', token.substring(0, 8) + '...');
  44. }
  45. } else {
  46. if (API_CONFIG.enableLog) {
  47. console.warn('[请求拦截] 未找到token,请求将不携带token');
  48. }
  49. }
  50. }
  51. // 添加Content-Type
  52. if (!header['Content-Type']) {
  53. header['Content-Type'] = 'application/json';
  54. }
  55. // 打印请求日志
  56. if (API_CONFIG.enableLog) {
  57. console.log(`[请求] ${method} ${fullUrl}`, data);
  58. }
  59. // 发起请求
  60. uni.request({
  61. url: fullUrl,
  62. method,
  63. data,
  64. header,
  65. timeout,
  66. success: (res: any) => {
  67. // 打印响应日志
  68. if (API_CONFIG.enableLog) {
  69. console.log(`[响应] ${method} ${fullUrl}`, res.data);
  70. }
  71. const responseData = res.data as ResponseData<T>;
  72. // 处理HTTP状态码
  73. if (res.statusCode !== 200) {
  74. const errorMsg = `请求失败: HTTP ${res.statusCode}`;
  75. uni.showToast({
  76. title: errorMsg,
  77. icon: 'none'
  78. });
  79. reject(new Error(errorMsg));
  80. return;
  81. }
  82. // 处理业务状态码
  83. if (responseData.code === 200 || responseData.code === 0) {
  84. // 成功
  85. if (API_CONFIG.enableLog) {
  86. console.log('[响应处理] 业务成功,返回data:', responseData.data);
  87. }
  88. resolve(responseData.data as T);
  89. } else if (responseData.code === 401) {
  90. // 未登录或token过期 -> 全局未授权处理(清除登录信息并跳转登录页)
  91. handleUnauthorized();
  92. reject(new Error(responseData.message || '未登录'));
  93. } else {
  94. // 业务错误
  95. const errorMsg = responseData.message || '操作失败';
  96. uni.showToast({
  97. title: errorMsg,
  98. icon: 'none'
  99. });
  100. reject(new Error(errorMsg));
  101. }
  102. },
  103. fail: (err: any) => {
  104. // 网络错误
  105. console.error(`[请求失败] ${method} ${fullUrl}`, err);
  106. let errorMsg = '网络请求失败';
  107. if (err.errMsg) {
  108. if (err.errMsg.includes('timeout')) {
  109. errorMsg = '请求超时,请检查网络';
  110. } else if (err.errMsg.includes('fail')) {
  111. errorMsg = '网络连接失败,请检查网络';
  112. }
  113. }
  114. uni.showToast({
  115. title: errorMsg,
  116. icon: 'none'
  117. });
  118. reject(new Error(errorMsg));
  119. }
  120. });
  121. });
  122. };
  123. /**
  124. * GET请求
  125. */
  126. export const get = <T = any>(url: string, data?: any, options?: { skipAuth?: boolean }): Promise<T> => {
  127. return request<T>({ url, method: 'GET', data, ...options });
  128. };
  129. /**
  130. * POST请求
  131. */
  132. export const post = <T = any>(url: string, data?: any): Promise<T> => {
  133. return request<T>({ url, method: 'POST', data });
  134. };
  135. /**
  136. * PUT请求
  137. */
  138. export const put = <T = any>(url: string, data?: any): Promise<T> => {
  139. return request<T>({ url, method: 'PUT', data });
  140. };
  141. /**
  142. * DELETE请求
  143. */
  144. export const del = <T = any>(url: string, data?: any): Promise<T> => {
  145. return request<T>({ url, method: 'DELETE', data });
  146. };