RequestModules.ts 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /**
  2. * 这里写的是业务相关的:
  3. * * 请求数据处理函数。
  4. * * 自定义请求模块。
  5. * * 自定义错误报告处理函数。
  6. */
  7. import { appendGetUrlParams, appendPostParams, checkIfStringAllEnglish, isNullOrEmpty } from "@/common/request/utils/Utils";
  8. import AppCofig, { isDev } from "../common/config/AppCofig";
  9. import RequestApiConfig from "../common/request/core/RequestApiConfig";
  10. import { RequestApiError, RequestApiResult, type RequestApiErrorType } from "../common/request/core/RequestApiResult";
  11. import { RequestCoreInstance, RequestOptions } from "../common/request/core/RequestCore";
  12. import { defaultResponseDataGetErrorInfo, defaultResponseDataHandlerCatch } from "../common/request/core/RequestHandler";
  13. import type { DataModel, NewDataModel } from "@imengyu/js-request-transform";
  14. import type { KeyValue } from "@/common/utils/CommonUtils";
  15. import { useAuthStore } from "@/store/auth";
  16. import ApiCofig from "@/common/config/ApiCofig";
  17. import uniappImplementer, { Response } from "@/common/request/implementer/Uniapp";
  18. /**
  19. * 不报告错误的 code
  20. */
  21. const notReportErrorCode = [401] as number[];
  22. const notReportMessages = [
  23. /请授权绑定手机号/g,
  24. ] as RegExp[];
  25. function matchNotReportMessage(str: string) {
  26. for (let i = 0; i < notReportMessages.length; i++) {
  27. if (notReportMessages[i].test(str))
  28. return true;
  29. }
  30. return false;
  31. }
  32. //请求拦截器
  33. function requestInceptor(url: string, req: RequestOptions) {
  34. //获取store中的token,追加到头;
  35. const autoStore = useAuthStore();
  36. if (isNullOrEmpty((req.header as KeyValue).token as string)) {
  37. req.header['token'] = autoStore.token;
  38. req.header['__token__'] = autoStore.token;
  39. }
  40. if (req.method == 'GET') {
  41. //追加GET参数
  42. url = appendGetUrlParams(url, 'main_body_id', ApiCofig.mainBodyId);
  43. } else {
  44. req.data = appendPostParams(req.data,'main_body_id', ApiCofig.mainBodyId);
  45. }
  46. return { newUrl: url, newReq: req };
  47. }
  48. //响应数据处理函数
  49. function responseDataHandler<T extends DataModel>(response: Response, req: RequestOptions, resultModelClass: NewDataModel|undefined, instance: RequestCoreInstance<T>, apiName: string | undefined): Promise<RequestApiResult<T>> {
  50. return new Promise<RequestApiResult<T>>((resolve, reject) => {
  51. const method = req.method || 'GET';
  52. response.json().then((json) => {
  53. if (response.ok) {
  54. if (!json) {
  55. reject(new RequestApiError(
  56. 'businessError',
  57. '后端未返回数据',
  58. '',
  59. response.status,
  60. null,
  61. null,
  62. req,
  63. apiName,
  64. response.url
  65. ));
  66. return;
  67. }
  68. //code == 0 错误
  69. if (json.code === 0) {
  70. handleError();
  71. return;
  72. }
  73. //处理后端的数据
  74. let message = '未知错误';
  75. let data = {} as any;
  76. //后端返回格式不统一,所以在这里处理格式
  77. if (typeof json.data === 'object') {
  78. data = json.data;
  79. message = json.data?.msg || response.statusText;
  80. }
  81. else {
  82. //否则返回上层对象
  83. data = json;
  84. message = json.msg || response.statusText;
  85. }
  86. resolve(new RequestApiResult(
  87. resultModelClass ?? instance.config.modelClassCreator,
  88. json?.code || response.status,
  89. message,
  90. data,
  91. json
  92. ));
  93. }
  94. else {
  95. handleError();
  96. }
  97. function handleError() {
  98. let errType : RequestApiErrorType = 'unknow';
  99. let errString = '';
  100. let errCodeStr = '';
  101. if (typeof json.message === 'string')
  102. errString = json.message;
  103. if (typeof json.msg === 'string')
  104. errString += json.msg;
  105. if (checkIfStringAllEnglish(errString))
  106. errString = '服务器返回:' + errString;
  107. //错误处理
  108. if (errString) {
  109. //如果后端有返回错误信息,则收集错误信息并返回
  110. errType = 'businessError';
  111. if (typeof json.data === 'object' && json.data?.errmsg) {
  112. errString += '\n' + json.data.errmsg;
  113. }
  114. if (typeof json.errors === 'object') {
  115. for (const key in json.errors) {
  116. if (Object.prototype.hasOwnProperty.call(json.errors, key)) {
  117. errString += '\n' + json.errors[key];
  118. }
  119. }
  120. }
  121. } else {
  122. const res = defaultResponseDataGetErrorInfo(response, json);
  123. errType = res.errType;
  124. errString = res.errString;
  125. errCodeStr = res.errCodeStr;
  126. }
  127. reject(new RequestApiError(
  128. errType,
  129. errString,
  130. errCodeStr,
  131. response.status,
  132. null,
  133. null,
  134. req,
  135. apiName,
  136. response.url
  137. ));
  138. }
  139. }).catch((err) => {
  140. //错误统一处理
  141. defaultResponseDataHandlerCatch(method, req, response, null, err, apiName, response.url, reject, instance);
  142. });
  143. });
  144. }
  145. //错误报告处理
  146. function responseErrReoprtInceptor<T extends DataModel>(instance: RequestCoreInstance<T>, response: RequestApiError) {
  147. return (
  148. (response.errorType !== 'businessError' && response.errorType !== 'networkError') ||
  149. notReportErrorCode.indexOf(response.code) >= 0 ||
  150. matchNotReportMessage(response.errorMessage) === true
  151. );
  152. }
  153. //错误报告处理
  154. export function reportError<T extends DataModel>(instance: RequestCoreInstance<T>, response: RequestApiError | Error) {
  155. if (isDev) {
  156. if (response instanceof RequestApiError) {
  157. uni.showModal({
  158. title: `请求错误 ${response.apiName} : ${response.errorMessage}`,
  159. content: response.toString() +
  160. '\r\n请求接口:' + response.apiName +
  161. '\r\n请求地址:' + response.apiUrl +
  162. '\r\n请求参数:' + JSON.stringify(response.rawRequest) +
  163. '\r\n返回参数:' + JSON.stringify(response.rawData) +
  164. '\r\n状态码:' + response.code +
  165. '\r\n信息:' + response.errorCodeMessage,
  166. type: 'error',
  167. showCancel: false,
  168. });
  169. } else {
  170. uni.showModal({
  171. title: '错误报告 代码错误',
  172. content: response?.stack || ('' + response),
  173. type: 'error',
  174. showCancel: false,
  175. });
  176. }
  177. } else {
  178. let errMsg = '';
  179. if (response instanceof RequestApiError)
  180. errMsg = response.errorMessage + '。';
  181. errMsg += '服务出现了异常,请稍后重试或联系客服。';
  182. errMsg += '版本:' + AppCofig.version;
  183. uni.showModal({
  184. title: '抱歉',
  185. content: errMsg,
  186. showCancel: false,
  187. });
  188. }
  189. }
  190. /**
  191. * App服务请求模块
  192. */
  193. export class AppServerRequestModule<T extends DataModel> extends RequestCoreInstance<T> {
  194. constructor() {
  195. super(uniappImplementer);
  196. this.config.baseUrl = RequestApiConfig.getConfig().BaseUrl;
  197. this.config.errCodes = []; //
  198. this.config.requestInceptor = requestInceptor;
  199. this.config.responseDataHandler = responseDataHandler;
  200. this.config.responseErrReoprtInceptor = responseErrReoprtInceptor;
  201. this.config.reportError = reportError;
  202. }
  203. }