|
@@ -1,10 +1,12 @@
|
|
|
import RequestApiConfig from './RequestApiConfig';
|
|
|
import { DataModel, type NewDataModel } from '@imengyu/js-request-transform';
|
|
|
-import { isNullOrEmpty, stringHashCode } from '../utils/Utils';
|
|
|
+import { stringHashCode } from '../utils/Utils';
|
|
|
import { RequestApiError, RequestApiResult } from './RequestApiResult';
|
|
|
import { defaultResponseDataHandler, defaultResponseErrorHandler } from './RequestHandler';
|
|
|
import type { HeaderType, QueryParams, TypeSaveable } from '../utils/AllType';
|
|
|
import type { KeyValue } from '@imengyu/js-request-transform/dist/DataUtils';
|
|
|
+import type { RequestImplementer } from './RequestImplementer';
|
|
|
+import { FormData, type Response } from '../implementer/Uniapp';
|
|
|
|
|
|
/**
|
|
|
* API 请求核心
|
|
@@ -83,7 +85,7 @@ export interface RequestCacheConfig {
|
|
|
cacheEnable: boolean,
|
|
|
}
|
|
|
|
|
|
-interface CacheStorage {
|
|
|
+export interface RequestCacheStorage {
|
|
|
time: number,
|
|
|
data: TypeSaveable
|
|
|
}
|
|
@@ -92,7 +94,7 @@ export class RequestOptions {
|
|
|
/**
|
|
|
* 请求的参数
|
|
|
*/
|
|
|
- data?: string | object | ArrayBuffer;
|
|
|
+ data?: string | object | ArrayBuffer | FormData;
|
|
|
/**
|
|
|
* 设置请求的 header,header 中不能设置 Referer。
|
|
|
*/
|
|
@@ -127,62 +129,15 @@ export class RequestOptions {
|
|
|
*/
|
|
|
firstIpv4?: boolean;
|
|
|
}
|
|
|
-export class Response {
|
|
|
- public constructor(url: string, data: unknown, options: {
|
|
|
- headers: Record<string, unknown>,
|
|
|
- status: number,
|
|
|
- }, errMsg: string) {
|
|
|
- this.errMsg = errMsg;
|
|
|
- this.data = data;
|
|
|
- this.url = url;
|
|
|
- this.status = options.status;
|
|
|
- this.headers = options.headers;
|
|
|
- this.ok = options.status >= 200 && options.status <= 399;
|
|
|
- this.statusText = `Status: ${options.status}`;
|
|
|
- }
|
|
|
-
|
|
|
- headers: Record<string, unknown>;
|
|
|
- ok: boolean;
|
|
|
- status: number;
|
|
|
- statusText: string;
|
|
|
- errMsg: string;
|
|
|
- url: string;
|
|
|
- data: unknown;
|
|
|
-
|
|
|
- json() : Promise<any> {
|
|
|
- return new Promise<any>((resolve, reject) => {
|
|
|
- if (typeof this.data === 'undefined' || isNullOrEmpty(this.data)) {
|
|
|
- resolve({});
|
|
|
- return;
|
|
|
- }
|
|
|
- if (typeof this.data === 'object') {
|
|
|
- resolve(this.data);
|
|
|
- return;
|
|
|
- }
|
|
|
- let data = null;
|
|
|
-
|
|
|
- if (typeof this.data === 'string') {
|
|
|
- try {
|
|
|
- data = JSON.parse(this.data);
|
|
|
- } catch(e) {
|
|
|
- console.log('json error: ' + e, this.data);
|
|
|
-
|
|
|
- reject(e);
|
|
|
- }
|
|
|
- } else {
|
|
|
- data = this.data;
|
|
|
- }
|
|
|
-
|
|
|
- resolve(data);
|
|
|
- })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* API 请求核心实例类,本类是对 fetch 的封装,提供了基本的请求功能。
|
|
|
*/
|
|
|
export class RequestCoreInstance<T extends DataModel> {
|
|
|
|
|
|
+ constructor(implementer: RequestImplementer) {
|
|
|
+ this.implementer = implementer;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 当前请求实例的请求配置项
|
|
|
*/
|
|
@@ -197,6 +152,11 @@ export class RequestCoreInstance<T extends DataModel> {
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
+ * 请求实现类
|
|
|
+ */
|
|
|
+ implementer: RequestImplementer;
|
|
|
+
|
|
|
+ /**
|
|
|
* 检查是否需要报告错误
|
|
|
*/
|
|
|
checkShouldReportError(err: RequestApiError) {
|
|
@@ -286,9 +246,7 @@ export class RequestCoreInstance<T extends DataModel> {
|
|
|
if (cacheTime > 0) {
|
|
|
requestHash = "RequestCache" + stringHashCode(url + req.method);
|
|
|
//获取数据
|
|
|
- const c = localStorage.getItem(requestHash);
|
|
|
- if (c) {
|
|
|
- const cacheData = JSON.parse(c) as CacheStorage;
|
|
|
+ this.implementer.getCache(requestHash).then((cacheData) => {
|
|
|
if (!cacheData) {
|
|
|
callback(cacheTime, requestHash, null);
|
|
|
return;
|
|
@@ -299,10 +257,11 @@ export class RequestCoreInstance<T extends DataModel> {
|
|
|
return;
|
|
|
}
|
|
|
callback(cacheTime, requestHash, null);
|
|
|
- }
|
|
|
- } else {
|
|
|
+ }).catch(() => {
|
|
|
+ callback(cacheTime, requestHash, null);
|
|
|
+ });
|
|
|
+ } else
|
|
|
callback(cacheTime, requestHash, null);
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -323,6 +282,11 @@ export class RequestCoreInstance<T extends DataModel> {
|
|
|
url = newUrl;
|
|
|
req = newReq;
|
|
|
}
|
|
|
+ if (req.data instanceof FormData) {
|
|
|
+ req.header['Content-Type'] = 'multipart/form-data';
|
|
|
+ } else if (typeof req.data === 'object' || req.data === undefined) {
|
|
|
+ req.header['Content-Type'] = 'application/json';
|
|
|
+ }
|
|
|
|
|
|
if (RequestApiConfig.getConfig().EnableApiRequestLog)
|
|
|
console.log(`[API Debugger] Q > ${apiName} [${req.method || 'GET'}] ` + url, req.data);
|
|
@@ -342,10 +306,10 @@ export class RequestCoreInstance<T extends DataModel> {
|
|
|
this.requestAndResponse(url, req, apiName, modelClassCreator, (result) => {
|
|
|
//保存缓存
|
|
|
if (cacheTime > 0) {
|
|
|
- localStorage.setItem(cacheKey, JSON.stringify({
|
|
|
+ this.implementer.setCache(cacheKey, {
|
|
|
time: new Date().getTime() + cacheTime,
|
|
|
data: result as unknown as TypeSaveable,
|
|
|
- } as CacheStorage));
|
|
|
+ });
|
|
|
}
|
|
|
}).then((d) => {
|
|
|
resolve(d);
|
|
@@ -356,49 +320,11 @@ export class RequestCoreInstance<T extends DataModel> {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- /*private startRequest(url: string, init?: RequestOptions, timeout = 10000): Promise<Response> {
|
|
|
- // 创建 AbortController 实例
|
|
|
- const controller = new AbortController();
|
|
|
- const { signal } = controller;
|
|
|
-
|
|
|
- // 设置超时逻辑
|
|
|
- const timeoutId = setTimeout(() => {
|
|
|
- controller.abort(); // 超时后取消请求
|
|
|
- }, timeout);
|
|
|
-
|
|
|
- // 发起 fetch 请求
|
|
|
- const response = fetch(url, { ...init, signal });
|
|
|
-
|
|
|
- // 请求完成后清除超时
|
|
|
- response.finally(() => clearTimeout(timeoutId));
|
|
|
- return response
|
|
|
- }*/
|
|
|
-
|
|
|
- private startUniappRequest(url: string, init?: RequestOptions, timeout = 10000): Promise<Response> {
|
|
|
- return new Promise<Response>((resolve, reject) => {
|
|
|
- uni.request({
|
|
|
- url: url,
|
|
|
- timeout: timeout,
|
|
|
- ...init,
|
|
|
- success(res) {
|
|
|
- const response = new Response(url, res.data, {
|
|
|
- headers: res.header,
|
|
|
- status: res.statusCode,
|
|
|
- }, 'success');
|
|
|
- resolve(response);
|
|
|
- },
|
|
|
- fail(res) {
|
|
|
- reject(res);
|
|
|
- },
|
|
|
- })
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
//发送请求并且处理
|
|
|
private requestAndResponse(url: string, req: RequestOptions, apiName: string, resultModelClass: NewDataModel|undefined, saveCache?: (result: unknown) => void) {
|
|
|
return new Promise<RequestApiResult<T>>((resolve, reject) => {
|
|
|
//发起请求
|
|
|
- this.startUniappRequest(url, req, this.config.timeout).then((res) => {
|
|
|
+ this.implementer.doRequest(url, req, this.config.timeout).then((res) => {
|
|
|
//响应拦截
|
|
|
if (this.config.responseInceptor)
|
|
|
res = this.config.responseInceptor(res);
|
|
@@ -447,7 +373,7 @@ export class RequestCoreInstance<T extends DataModel> {
|
|
|
* @param querys 请求URL参数
|
|
|
* @param cache 缓存参数
|
|
|
*/
|
|
|
- post(url: string, data: KeyValue, apiName: string, querys?: QueryParams, modelClassCreator?: NewDataModel, cache?: RequestCacheConfig, headers?: KeyValue) {
|
|
|
+ post(url: string, data: KeyValue|FormData, apiName: string, querys?: QueryParams, modelClassCreator?: NewDataModel, cache?: RequestCacheConfig, headers?: KeyValue) {
|
|
|
return this.request(this.makeUrl(url, querys), { method: 'POST', data, header: headers }, apiName, modelClassCreator, cache);
|
|
|
}
|
|
|
/**
|