RequestModules.ts 6.8 KB

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