feat(editor, data-source): 支持http数据源请求、响应裁剪配置

This commit is contained in:
roymondchen 2023-10-31 15:29:04 +08:00
parent cb2ff28129
commit f48afa98f2
5 changed files with 146 additions and 44 deletions

View File

@ -126,21 +126,29 @@ export default class HttpDataSource extends DataSource {
public async request(options: Partial<HttpOptions> = {}) { public async request(options: Partial<HttpOptions> = {}) {
this.isLoading = true; this.isLoading = true;
let reqOptions = {
...this.httpOptions,
...options,
};
try { try {
for (const method of this.#beforeRequest) { for (const method of this.#beforeRequest) {
await method({ options, params: {}, dataSource: this, app: this.app }); await method({ options: reqOptions, params: {}, dataSource: this, app: this.app });
}
if (typeof this.schema.beforeRequest === 'function') {
reqOptions = this.schema.beforeRequest(reqOptions, { app: this.app, dataSource: this });
} }
// 注意在编辑器中mockData不会为空至少是默认值不会发起请求 // 注意在编辑器中mockData不会为空至少是默认值不会发起请求
const res = this.mockData let res = this.mockData ? this.mockData : await this.#fetch?.(reqOptions);
? this.mockData
: await this.#fetch?.({
...this.httpOptions,
...options,
});
for (const method of this.#afterRequest) { for (const method of this.#afterRequest) {
await method({ res, options, params: {}, dataSource: this, app: this.app }); await method({ res, options: reqOptions, params: {}, dataSource: this, app: this.app });
}
if (typeof this.schema.afterResponse === 'function') {
res = this.schema.afterResponse(res, { app: this.app, dataSource: this });
} }
if (this.schema.responseOptions?.dataPath) { if (this.schema.responseOptions?.dataPath) {

View File

@ -1,5 +1,7 @@
import type { AppCore, DataSourceSchema, HttpOptions, RequestFunction } from '@tmagic/schema'; import type { AppCore, DataSourceSchema, HttpOptions, RequestFunction } from '@tmagic/schema';
import HttpDataSource from './data-sources/Http';
export interface DataSourceOptions { export interface DataSourceOptions {
schema: DataSourceSchema; schema: DataSourceSchema;
app: AppCore; app: AppCore;
@ -13,6 +15,10 @@ export interface HttpDataSourceSchema extends DataSourceSchema {
dataPath?: string; dataPath?: string;
}; };
autoFetch?: boolean; autoFetch?: boolean;
beforeRequest:
| string
| ((options: HttpOptions, content: { app: AppCore; dataSource: HttpDataSource }) => HttpOptions);
afterResponse: string | ((response: any, content: { app: AppCore; dataSource: HttpDataSource }) => any);
} }
export interface HttpDataSourceOptions extends DataSourceOptions { export interface HttpDataSourceOptions extends DataSourceOptions {

View File

@ -7,7 +7,7 @@ import type { DataSourceSchema } from '@tmagic/schema';
import { guid } from '@tmagic/utils'; import { guid } from '@tmagic/utils';
import type { DatasourceTypeOption } from '@editor/type'; import type { DatasourceTypeOption } from '@editor/type';
import { getFormConfig } from '@editor/utils/data-source'; import { getFormConfig, getFormValue } from '@editor/utils/data-source';
import BaseService from './BaseService'; import BaseService from './BaseService';
@ -50,7 +50,7 @@ class DataSource extends BaseService {
} }
public getFormValue(type = 'base') { public getFormValue(type = 'base') {
return this.get('values')[type]; return getFormValue(type, this.get('values')[type]);
} }
public setFormValue(type: string, value: Partial<DataSourceSchema>) { public setFormValue(type: string, value: Partial<DataSourceSchema>) {

View File

@ -1,4 +1,4 @@
import { FormConfig } from '@tmagic/form'; import { FormConfig, FormState } from '@tmagic/form';
import { DataSchema, DataSourceSchema } from '@tmagic/schema'; import { DataSchema, DataSourceSchema } from '@tmagic/schema';
import BaseFormConfig from './formConfigs/base'; import BaseFormConfig from './formConfigs/base';
@ -8,47 +8,72 @@ const fillConfig = (config: FormConfig): FormConfig => [
...BaseFormConfig(), ...BaseFormConfig(),
...config, ...config,
{ {
type: 'panel', type: 'tab',
title: '数据定义',
items: [ items: [
{ {
name: 'fields', title: '数据定义',
type: 'data-source-fields', items: [
defaultValue: () => [], {
name: 'fields',
type: 'data-source-fields',
defaultValue: () => [],
},
],
}, },
],
},
{
type: 'panel',
title: '方法定义',
items: [
{ {
name: 'methods', title: '方法定义',
type: 'data-source-methods', items: [
defaultValue: () => [], {
name: 'methods',
type: 'data-source-methods',
defaultValue: () => [],
},
],
}, },
],
},
{
type: 'panel',
title: '事件配置',
display: false,
items: [
{ {
name: 'events', title: '事件配置',
src: 'datasource', display: false,
type: 'event-select', items: [
{
name: 'events',
src: 'datasource',
type: 'event-select',
},
],
}, },
],
},
{
type: 'panel',
title: 'mock数据',
items: [
{ {
name: 'mocks', title: 'mock数据',
type: 'data-source-mocks', items: [
defaultValue: () => [], {
name: 'mocks',
type: 'data-source-mocks',
defaultValue: () => [],
},
],
},
{
title: '请求参数裁剪',
display: (formState: FormState, { model }: any) => model.type === 'http',
items: [
{
name: 'beforeRequest',
type: 'vs-code',
parse: true,
height: '600px',
},
],
},
{
title: '响应数据裁剪',
display: (formState: FormState, { model }: any) => model.type === 'http',
items: [
{
name: 'afterResponse',
type: 'vs-code',
parse: true,
height: '600px',
},
],
}, },
], ],
}, },
@ -65,6 +90,64 @@ export const getFormConfig = (type: string, configs: Record<string, FormConfig>)
} }
}; };
export const getFormValue = (type: string, values: Partial<DataSourceSchema>): Partial<DataSourceSchema> => {
if (type !== 'http') {
return values;
}
return {
beforeRequest: `(options, context) => {
/**
*
*
* options: HttpOptions
*
* interface HttpOptions {
* // 请求链接
* url: string;
* // query参数
* params?: Record<string, string>;
* // body数据
* data?: Record<string, any>;
* // 请求头
* headers?: Record<string, string>;
* // 请求方法 GET/POST
* method?: Method;
* }
*
* context
*
* interface Content {
* app: AppCore;
* dataSource: HttpDataSource;
* }
*
* return: HttpOptions
*/
// 此处的返回值会作为这个接口的入参
return options;
}`,
afterResponse: `(response, context) => {
/**
*
* context
*
* interface Content {
* app: AppCore;
* dataSource: HttpDataSource;
* }
*
*/
// 此处的返回值会作为这个接口的返回值
return response;
}`,
...values,
};
};
export const getDisplayField = (dataSources: DataSourceSchema[], key: string) => { export const getDisplayField = (dataSources: DataSourceSchema[], key: string) => {
const displayState: { value: string; type: 'var' | 'text' }[] = []; const displayState: { value: string; type: 'var' | 'text' }[] = [];

View File

@ -18,10 +18,15 @@
export type Method = 'get' | 'GET' | 'delete' | 'DELETE' | 'post' | 'POST' | 'put' | 'PUT'; export type Method = 'get' | 'GET' | 'delete' | 'DELETE' | 'post' | 'POST' | 'put' | 'PUT';
export interface HttpOptions { export interface HttpOptions {
/** 请求链接 */
url: string; url: string;
/** query参数 */
params?: Record<string, string>; params?: Record<string, string>;
/** body数据 */
data?: Record<string, any>; data?: Record<string, any>;
/** 请求头 */
headers?: Record<string, string>; headers?: Record<string, string>;
/** 请求方法 GET/POST */
method?: Method; method?: Method;
[key: string]: any; [key: string]: any;
} }