RequestModules.ts 7.8 KB

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