request.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import { logoutSuccess } from "@/store/user";
  2. import ToastUtil from "@/utils/toast_utils";
  3. import Taro from "@tarojs/taro";
  4. import { useDispatch } from "react-redux";
  5. interface RequestParam {
  6. url: string;
  7. method: 'POST' | 'GET' | 'DELETE' | 'PUT';
  8. data?: Record<string, any>;
  9. showAlert?: boolean;
  10. }
  11. interface Resp {
  12. statusCode?: number;
  13. header?: any;
  14. data?: any;
  15. errMsg?: string;
  16. };
  17. async function getStorage(key: string) {
  18. try {
  19. const res = await Taro.getStorage({ key });
  20. return res.data;
  21. } catch {
  22. return '';
  23. }
  24. }
  25. //X-Language:语言,X-Device-Id:设备唯一码,X-Platform:小程序/android/ios,X-Location:地区,X-Device:登录设备
  26. // header['X-Language'] = ''
  27. // header['X-Device-Id'] = ''
  28. // header['X-Platform'] = ''
  29. // header['X-Location'] = ''
  30. // header['X-Device'] = ''
  31. // header['X-Time-Zone-Id'] = Intl.DateTimeFormat().resolvedOptions().timeZone
  32. // header['Authorization'] = 'Bearer ' + wx.getStorageSync('token');
  33. // header['Authorization'] = 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJhY2NvdW50Iiwic3ViIjoiMmQ5OWNlYzI0ZDFlMzE0Y2U1MjhlODM4MWMzYzk0MzgiLCJpc3MiOiJDT0RFUEFBUy5DT00iLCJuaWNrbmFtZSI6IueOi-a4nSIsInR5cCI6IkJlYXJlciIsInNlc3Npb25fc3RhdGUiOiIyN2RjNmU4ZDdjMWU1MTVmNDQwNzVjZTFlODk2ZmUzNCIsImV4cCI6MTcxNjY0Mzk5MSwiaWF0IjoxNjg1MDIxNTkxfQ.fmFj0OVNRzjLkdebSyGJyk8EScPJFpDiz0L25W35zoA'
  34. export async function request<T>(param: RequestParam): Promise<T> {
  35. const kTimeout = 8000;
  36. const kRetryCount = 2;
  37. let retryCount = 0;
  38. function performRequest(resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) {
  39. const { url, method, data } = param;
  40. var requestTask: any = null;
  41. let header: any = {};
  42. const token = global.token ? global.token : ''; //await getStorage('token')
  43. var split = new Date().toString().split(' ');
  44. var timeZoneFormatted = split[split.length - 2];
  45. header['content-type'] = 'application/json'
  46. header['X-Time-Zone'] = timeZoneFormatted; //new Date().getTimezoneOffset() / 60
  47. header['X-Platform'] = Taro.getSystemInfoSync().platform=='ios'?'IOS':'ANDROID'; //IOS ANDROID
  48. header['X-Lang'] = process.env.TARO_ENV=='rn'?'en':'zh' //zh en
  49. header['X-Client-Type'] = 'WX_APP' //WX_APP APP
  50. header['X-Client_Version'] = '1.0'
  51. if (token.length > 0) {
  52. header['Authorization'] = `Bearer ${token}`;
  53. }
  54. const timer = setTimeout(() => {
  55. requestTask && requestTask.abort();
  56. console.log('timeout');
  57. if (retryCount < kRetryCount) {
  58. // Retry the request
  59. console.log(`Retrying request (${retryCount + 1}/2)...`);
  60. retryCount++;
  61. performRequest(resolve, reject);
  62. return;
  63. }
  64. if (global.language=='en'){
  65. ToastUtil.getInstance().showToast(method == 'GET' ?
  66. 'Network connection failed. Please check your network.' :
  67. 'Posting failed. Please check your network.');
  68. }
  69. else {
  70. ToastUtil.getInstance().showToast(method == 'GET' ? '网络连接失败,请检查网络' : '操作失败,请检查网络');
  71. }
  72. reject('timeout');
  73. }, kTimeout);
  74. requestTask = Taro.request({
  75. url: url,
  76. method: method,
  77. header: header,
  78. // timeout: kTimeout,
  79. data: data || {},
  80. success: (response: Resp | { [key: string]: any }) => {
  81. clearTimeout(timer);
  82. const { statusCode, data } = response;
  83. if (statusCode != 200) {
  84. console.log(response)
  85. }
  86. if (statusCode >= 200 && statusCode < 300) {
  87. //正常数据返回
  88. var resp = {} as T;
  89. if (response.data) {
  90. resp = response.data as T;
  91. }
  92. resolve(resp);
  93. } else if (statusCode == 401) {
  94. // global.postBtnUpdateStatus('idle')
  95. //未登录或挤下线处理
  96. if (process.env.TARO_ENV=='weapp'){
  97. Taro.stopPullDownRefresh()
  98. }
  99. else if (process.env.TARO_ENV=='rn'){
  100. if (url.indexOf('login/password')!=-1){
  101. reject(data);
  102. return;
  103. }
  104. }
  105. global.dispatch(logoutSuccess());
  106. } else if (statusCode == 500 && response.data.error_code == 'WX_STEP_PARSE_FAIL') {
  107. //单独对计步第一次请求失败处理
  108. resolve(response.data);
  109. } else {
  110. //通用错误处理
  111. Taro.showToast({
  112. icon: 'none',
  113. title: data.error_message,
  114. });
  115. reject(data);
  116. }
  117. },
  118. fail: err => {
  119. if ((err as any).statusCode >= 200 && (err as any).statusCode < 300){
  120. clearTimeout(timer);
  121. resolve()
  122. return;
  123. }
  124. // global.postBtnUpdateStatus('idle')
  125. // console.log('oppsu');
  126. // clearTimeout(timer);
  127. // reject(err);
  128. },
  129. });
  130. }
  131. return new Promise<T>((resolve, reject) => {
  132. performRequest(resolve, reject);
  133. });
  134. }