request.ts 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. import dayjs from 'dayjs'
  6. import { APP_VERSION, WX_VERSION } from "./api";
  7. import { getTimezone, getTimezoneId, getTimezoneName } from "@/utils/tools";
  8. import showAlert from "@/components/basic/Alert";
  9. const utc = require('dayjs/plugin/utc')
  10. const timezone = require('dayjs/plugin/timezone')
  11. dayjs.extend(utc)
  12. dayjs.extend(timezone)
  13. interface RequestParam {
  14. url: string;
  15. method: 'POST' | 'GET' | 'DELETE' | 'PUT';
  16. data?: Record<string, any>;
  17. showAlert?: boolean;
  18. }
  19. interface Resp {
  20. statusCode?: number;
  21. header?: any;
  22. data?: any;
  23. errMsg?: string;
  24. };
  25. async function getStorage(key: string) {
  26. try {
  27. const res = await Taro.getStorage({ key });
  28. return res.data;
  29. } catch {
  30. return '';
  31. }
  32. }
  33. //X-Language:语言,X-Device-Id:设备唯一码,X-Platform:小程序/android/ios,X-Location:地区,X-Device:登录设备
  34. // header['X-Language'] = ''
  35. // header['X-Device-Id'] = ''
  36. // header['X-Platform'] = ''
  37. // header['X-Location'] = ''
  38. // header['X-Device'] = ''
  39. // header['X-Time-Zone-Id'] = Intl.DateTimeFormat().resolvedOptions().timeZone
  40. // header['Authorization'] = 'Bearer ' + wx.getStorageSync('token');
  41. // header['Authorization'] = 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJhY2NvdW50Iiwic3ViIjoiMmQ5OWNlYzI0ZDFlMzE0Y2U1MjhlODM4MWMzYzk0MzgiLCJpc3MiOiJDT0RFUEFBUy5DT00iLCJuaWNrbmFtZSI6IueOi-a4nSIsInR5cCI6IkJlYXJlciIsInNlc3Npb25fc3RhdGUiOiIyN2RjNmU4ZDdjMWU1MTVmNDQwNzVjZTFlODk2ZmUzNCIsImV4cCI6MTcxNjY0Mzk5MSwiaWF0IjoxNjg1MDIxNTkxfQ.fmFj0OVNRzjLkdebSyGJyk8EScPJFpDiz0L25W35zoA'
  42. export async function request<T>(param: RequestParam): Promise<T> {
  43. const kTimeout = 8000;
  44. const kRetryCount = 2;
  45. let retryCount = 0;
  46. function performRequest(resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) {
  47. // if (process.env.TARO_ENV == 'rn' && Taro.getSystemInfoSync().platform != 'ios') {
  48. // return;
  49. // }
  50. const { url, method, data } = param;
  51. console.log(url)
  52. var requestTask: any = null;
  53. let header: any = {};
  54. const token = global.token ? global.token : ''; //await getStorage('token')
  55. var timeZoneFormatted = getTimezone()
  56. var timeZoneName = getTimezoneName()
  57. // var timeZoneLocation = Intl.DateTimeFormat().resolvedOptions().timeZone
  58. header['content-type'] = 'application/json'
  59. header['X-Timezone'] = encodeURIComponent(JSON.stringify({
  60. id: getTimezoneId(),
  61. name: timeZoneName ? timeZoneName : '',
  62. gmt: timeZoneFormatted
  63. }))
  64. header['X-Platform'] = Taro.getSystemInfoSync().platform == 'ios' ? 'IOS' : 'ANDROID'; //IOS ANDROID
  65. header['X-Lang'] = process.env.TARO_ENV == 'rn' ? 'en' : 'zh' //zh en
  66. header['X-Client-Type'] = process.env.TARO_ENV == 'rn' ? 'APP' : 'WX_APP' //WX_APP APP
  67. header['X-Client-Version'] = process.env.TARO_ENV == 'rn' ? APP_VERSION : WX_VERSION
  68. header['X-Day'] = dayjs().format('YYYYMMDD')
  69. header['X-Timestamp'] = new Date().getTime()
  70. if (token.length > 0) {
  71. header['Authorization'] = `Bearer ${token}`;
  72. // header['Authorization'] = 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJhY2NvdW50Iiwic3ViIjoiZTQ3M2RlZDI4YzgwNzY3ZDZiOTBkYzAzMDg5YzRhYzEiLCJpc3MiOiJmYXN0Iiwibmlja25hbWUiOiLmtYvor5UiLCJ0eXAiOiJCZWFyZXIiLCJzZXNzaW9uX3N0YXRlIjoiNDE1NTZkODNiM2QyODRmYzNhODY1NmI3YzdhOTBjODQiLCJleHAiOjIwMzM3ODU4MTcsImlhdCI6MTcxODI1MzAxN30.JBbFZhmckizGqblsFFB3ee3u_CivwTR8w-0VoUcph2w';
  73. // header['Authorization'] = 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJhY2NvdW50Iiwic3ViIjoiMjZkOGE1YTg0MDMyYmExN2Q4NDk3MTlkNTljNGY1NzgiLCJpc3MiOiJmYXN0Iiwibmlja25hbWUiOiJCSyIsInR5cCI6IkJlYXJlciIsInNlc3Npb25fc3RhdGUiOiI1ZDU2NTkzYmNjNWFmNzM0OWNlZTMwZjlkNGYzMWIyMCIsImV4cCI6MTc0ODE3MDg5NSwiaWF0IjoxNzE2NjM0ODk1fQ.uaRm2vSNCX8fkFS63Oe-WNWIDHG_cRM-nQ5EGyUMaBg';
  74. }
  75. const timer = setTimeout(() => {
  76. requestTask && requestTask.abort();
  77. console.log('timeout');
  78. if (retryCount < kRetryCount) {
  79. // Retry the request
  80. console.log(`Retrying request (${retryCount + 1}/2)...`);
  81. retryCount++;
  82. performRequest(resolve, reject);
  83. return;
  84. }
  85. if (process.env.TARO_ENV == 'rn' && (param.data as any).showAlert) {
  86. showAlert({
  87. title: 'error',
  88. content: global.language == 'en' ? 'Posting failed. Please check your network.' : '操作失败,请检查网络',
  89. showCancel: false
  90. })
  91. } else {
  92. if (global.language == 'en') {
  93. ToastUtil.getInstance().showToast(method == 'GET' ?
  94. 'Network connection failed. Please check your network.' :
  95. 'Posting failed. Please check your network.');
  96. }
  97. else {
  98. ToastUtil.getInstance().showToast(method == 'GET' ? '网络连接失败,请检查网络' : '操作失败,请检查网络');
  99. }
  100. }
  101. reject('timeout');
  102. }, kTimeout);
  103. requestTask = Taro.request({
  104. url: url,
  105. method: method,
  106. header: header,
  107. timeout: kTimeout,
  108. data: data || {},
  109. success: (response: Resp | { [key: string]: any }) => {
  110. clearTimeout(timer);
  111. const { statusCode, data } = response;
  112. if (statusCode != 200) {
  113. console.log(response)
  114. }
  115. if (statusCode >= 200 && statusCode < 300) {
  116. //正常数据返回
  117. var resp = {} as T;
  118. if (response.data) {
  119. resp = response.data as T;
  120. }
  121. resolve(resp);
  122. } else if (statusCode == 401) {
  123. // global.postBtnUpdateStatus('idle')
  124. //未登录或挤下线处理
  125. if (process.env.TARO_ENV == 'weapp') {
  126. Taro.stopPullDownRefresh()
  127. }
  128. else if (process.env.TARO_ENV == 'rn') {
  129. if (url.indexOf('login/password') != -1) {
  130. reject(data);
  131. return;
  132. }
  133. }
  134. if (global.dispatch) {
  135. global.dispatch(logoutSuccess());
  136. }
  137. } else if (statusCode == 500 && response.data.error_code == 'WX_STEP_PARSE_FAIL') {
  138. //单独对计步第一次请求失败处理
  139. resolve(response.data);
  140. } else {
  141. //通用错误处理
  142. if (statusCode == 502) {
  143. if (process.env.TARO_ENV == 'rn' && (param.data as any).showAlert) {
  144. showAlert({
  145. title: 'error',
  146. content: global.language == 'en' ? 'Server is busy now. Please try again later.' : '服务器正忙, 请您稍后再试。',
  147. showCancel: false
  148. })
  149. }
  150. else {
  151. Taro.showToast({
  152. icon: 'none',
  153. title: global.language == 'en' ? 'Server is busy now. Please try again later.' : '服务器正忙, 请您稍后再试。',
  154. });
  155. }
  156. }
  157. else {
  158. if (process.env.TARO_ENV == 'rn' && (param.data as any).showAlert) {
  159. showAlert({
  160. title: 'error',
  161. content: data.error_message,
  162. showCancel: false
  163. })
  164. }
  165. else {
  166. Taro.showToast({
  167. icon: 'none',
  168. title: data.error_message,
  169. });
  170. }
  171. }
  172. reject(data);
  173. }
  174. },
  175. fail: err => {
  176. if ((err as any).statusCode >= 200 && (err as any).statusCode < 300) {
  177. clearTimeout(timer);
  178. resolve()
  179. return;
  180. }
  181. // global.postBtnUpdateStatus('idle')
  182. // console.log('oppsu');
  183. // clearTimeout(timer);
  184. // reject(err);
  185. },
  186. });
  187. }
  188. return new Promise<T>((resolve, reject) => {
  189. performRequest(resolve, reject);
  190. });
  191. }