BaseAppServerRequestModule.ts 8.0 KB

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