feat(editor,core,schema): 组件高级配置支持配置数据源方法

This commit is contained in:
roymondchen 2024-02-28 14:33:57 +08:00
parent 0d471a96ed
commit 074d76456b
4 changed files with 90 additions and 20 deletions

View File

@ -18,10 +18,17 @@
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { isEmpty } from 'lodash-es'; import { DataSource } from '@tmagic/data-source';
import type {
import type { DeprecatedEventConfig, EventConfig, MComponent, MContainer, MPage, MPageFragment } from '@tmagic/schema'; AppCore,
import { HookType } from '@tmagic/schema'; DeprecatedEventConfig,
EventConfig,
MComponent,
MContainer,
MPage,
MPageFragment,
} from '@tmagic/schema';
import { HookCodeType, HookType } from '@tmagic/schema';
import type App from './App'; import type App from './App';
import type Page from './Page'; import type Page from './Page';
@ -78,7 +85,7 @@ class Node extends EventEmitter {
}); });
this.instance = instance; this.instance = instance;
await this.runCodeBlock('created'); await this.runHookCode('created');
}); });
this.once('mounted', async (instance: any) => { this.once('mounted', async (instance: any) => {
@ -90,24 +97,51 @@ class Node extends EventEmitter {
this.app.compActionHandler(eventConfig.eventConfig, eventConfig.fromCpt, eventConfig.args); this.app.compActionHandler(eventConfig.eventConfig, eventConfig.fromCpt, eventConfig.args);
} }
await this.runCodeBlock('mounted'); await this.runHookCode('mounted');
}); });
} }
private async runCodeBlock(hook: string) { private async runHookCode(hook: string) {
if (typeof this.data[hook] === 'function') { if (typeof this.data[hook] === 'function') {
// 兼容旧的数据格式 // 兼容旧的数据格式
await this.data[hook](this); await this.data[hook](this);
return; return;
} }
if (this.data[hook]?.hookType !== HookType.CODE || isEmpty(this.app.codeDsl)) return;
for (const item of this.data[hook].hookData) {
const { codeId, params = {} } = item;
const functionContent = this.app.codeDsl?.[codeId]?.content; const hookData = this.data[hook] as {
/** 钩子类型 */
hookType: HookType;
hookData: {
/** 函数类型 */
codeType?: HookCodeType;
/** 函数id, 代码块为string, 数据源为[数据源id, 方法名称] */
codeId: string | [string, string];
/** 参数配置 */
params: Record<string, any>;
}[];
};
if (typeof functionContent === 'function') { if (hookData?.hookType !== HookType.CODE) return;
await functionContent({ app: this.app, params });
for (const item of hookData.hookData) {
const { codeType = HookCodeType.CODE, codeId, params = {} } = item;
let functionContent: ((...args: any[]) => any) | string | undefined;
const functionParams: { app: AppCore; params: Record<string, any>; dataSource?: DataSource } = {
app: this.app,
params,
};
if (codeType === HookCodeType.CODE && typeof codeId === 'string' && this.app.codeDsl?.[codeId]) {
functionContent = this.app.codeDsl[codeId].content;
} else if (codeType === HookCodeType.DATA_SOURCE_METHOD && Array.isArray(codeId) && codeId.length > 1) {
const dataSource = this.app.dataSourceManager?.get(codeId[0]);
functionContent = dataSource?.methods.find((method) => method.name === codeId[1])?.content;
functionParams.dataSource = dataSource;
}
if (functionContent && typeof functionContent === 'function') {
await functionContent(functionParams);
} }
} }
} }

View File

@ -12,7 +12,8 @@ import { isEmpty } from 'lodash-es';
import { TMagicCard } from '@tmagic/design'; import { TMagicCard } from '@tmagic/design';
import type { FieldProps } from '@tmagic/form'; import type { FieldProps } from '@tmagic/form';
import { HookType } from '@tmagic/schema'; import { FormState } from '@tmagic/form';
import { HookCodeType, HookType } from '@tmagic/schema';
import type { Services } from '@editor/type'; import type { Services } from '@editor/type';
@ -38,13 +39,40 @@ const codeConfig = computed(() => ({
name: 'hookData', name: 'hookData',
enableToggleMode: false, enableToggleMode: false,
expandAll: true, expandAll: true,
titleKey: 'codeId', title: (mForm: FormState, { model, index }: any) => {
if (model.codeType === HookCodeType.DATA_SOURCE_METHOD) {
if (Array.isArray(model.codeId)) {
const ds = services?.dataSourceService.getDataSourceById(model.codeId[0]);
return `${ds?.title} / ${model.codeId[1]}`;
}
return Array.isArray(model.codeId) ? model.codeId.join('/') : index;
}
return model.codeId || index;
},
items: [ items: [
{ {
type: 'code-select-col', type: 'row',
name: 'codeId', items: [
labelWidth: 0, {
disabled: () => !services?.codeBlockService.getEditStatus(), type: 'select',
name: 'codeType',
span: 8,
options: [
{ value: HookCodeType.CODE, text: '代码块' },
{ value: HookCodeType.DATA_SOURCE_METHOD, text: '数据源方法' },
],
defaultValue: 'code',
},
{
type: (mForm: FormState, { model }: any) =>
model.codeType === HookCodeType.DATA_SOURCE_METHOD ? 'data-source-method-select' : 'code-select-col',
name: 'codeId',
span: 16,
labelWidth: 0,
disabled: () => !services?.codeBlockService.getEditStatus(),
},
],
}, },
], ],
})); }));

View File

@ -17,6 +17,7 @@
<CodeParams <CodeParams
v-if="paramsConfig.length" v-if="paramsConfig.length"
name="params" name="params"
:key="model[name]"
:model="model" :model="model"
:size="size" :size="size"
:params-config="paramsConfig" :params-config="paramsConfig"
@ -33,7 +34,7 @@
</div> </div>
</template> </template>
<script lang="ts" setup name=""> <script lang="ts" setup>
import { computed, inject, ref, watch } from 'vue'; import { computed, inject, ref, watch } from 'vue';
import { Edit, View } from '@element-plus/icons-vue'; import { Edit, View } from '@element-plus/icons-vue';
import { isEmpty, map } from 'lodash-es'; import { isEmpty, map } from 'lodash-es';

View File

@ -205,6 +205,13 @@ export enum HookType {
CODE = 'code', CODE = 'code',
} }
export enum HookCodeType {
/** 代码块 */
CODE = 'code',
/** 数据源方法 */
DATA_SOURCE_METHOD = 'data-source-method',
}
export interface DataSchema { export interface DataSchema {
type?: 'null' | 'boolean' | 'object' | 'array' | 'number' | 'string' | 'any'; type?: 'null' | 'boolean' | 'object' | 'array' | 'number' | 'string' | 'any';
/** 键名 */ /** 键名 */