mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-06-04 15:19:18 +08:00
fix: 代码块结构改造完成
This commit is contained in:
parent
c4293f17a6
commit
c7a8552d9b
@ -20,8 +20,7 @@ import { EventEmitter } from 'events';
|
||||
|
||||
import { isEmpty } from 'lodash-es';
|
||||
|
||||
import type { EventItemConfig, MComponent, MContainer, MPage } from '@tmagic/schema';
|
||||
import { HookType } from '@tmagic/schema';
|
||||
import { EventItemConfig, HookType, MComponent, MContainer, MPage } from '@tmagic/schema';
|
||||
|
||||
import type App from './App';
|
||||
import type Page from './Page';
|
||||
@ -87,7 +86,7 @@ class Node extends EventEmitter {
|
||||
|
||||
private async runCodeBlock(hook: string) {
|
||||
if (this.data[hook]?.hookType !== HookType.CODE || !this.app.codeDsl || isEmpty(this.app?.codeDsl)) return;
|
||||
for (const item of this.data[hook].data) {
|
||||
for (const item of this.data[hook].hookData) {
|
||||
const { codeId, params = {} } = item;
|
||||
if (this.app.codeDsl[codeId] && typeof this.app?.codeDsl[codeId]?.content === 'function') {
|
||||
await this.app.codeDsl[codeId].content(this, params);
|
||||
|
@ -1,30 +1,26 @@
|
||||
<template>
|
||||
<div class="m-fields-code-select" :key="fieldKey">
|
||||
<TMagicCard shadow="never">
|
||||
<m-form-table
|
||||
:config="tableConfig"
|
||||
:model="model[name]"
|
||||
:name="tableConfig.name"
|
||||
:prop="prop"
|
||||
:size="size"
|
||||
@change="changeHandler"
|
||||
>
|
||||
</m-form-table>
|
||||
</TMagicCard>
|
||||
<div class="m-fields-code-select">
|
||||
<m-form-table
|
||||
:config="tableConfig"
|
||||
:model="model[name]"
|
||||
name="hookData"
|
||||
:prop="prop"
|
||||
:size="size"
|
||||
@change="changeHandler"
|
||||
>
|
||||
</m-form-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="MEditorCodeSelect">
|
||||
import { computed, defineEmits, defineProps, inject, ref } from 'vue';
|
||||
import { map, xor } from 'lodash-es';
|
||||
import { computed, defineEmits, defineProps, inject, watch } from 'vue';
|
||||
import { isEmpty, map } from 'lodash-es';
|
||||
|
||||
import { TMagicCard } from '@tmagic/design';
|
||||
import { FormState, TableConfig } from '@tmagic/form';
|
||||
import { FormItem, TableConfig } from '@tmagic/form';
|
||||
import { HookType } from '@tmagic/schema';
|
||||
|
||||
import type { Services } from '../type';
|
||||
import { CodeSelectOp } from '../type';
|
||||
import { Services } from '../type';
|
||||
const services = inject<Services>('services');
|
||||
const form = inject<FormState>('mForm');
|
||||
const emit = defineEmits(['change']);
|
||||
|
||||
const props = defineProps<{
|
||||
@ -37,7 +33,7 @@ const props = defineProps<{
|
||||
size: 'mini' | 'small' | 'medium';
|
||||
}>();
|
||||
|
||||
const tableConfig = computed(() => {
|
||||
const tableConfig = computed<FormItem>(() => {
|
||||
const defaultConfig = {
|
||||
dropSort: true,
|
||||
items: [
|
||||
@ -57,110 +53,41 @@ const tableConfig = computed(() => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
// {
|
||||
// label: '参数',
|
||||
// name: 'params',
|
||||
// filter: v=>JSON.stringify(v)
|
||||
// },
|
||||
],
|
||||
};
|
||||
return {
|
||||
name: 'data',
|
||||
...defaultConfig,
|
||||
...props.config.tableConfig,
|
||||
};
|
||||
});
|
||||
|
||||
// const selectModel = computed(() => {
|
||||
// console.log("props.model[props.name].data",props.model[props.name].data)
|
||||
// return {
|
||||
// [props.name]: props.model[props.name]?.data?.map((item: { codeId: Id }) => item.codeId) || []
|
||||
// }
|
||||
// });
|
||||
watch(
|
||||
() => props.model[props.name],
|
||||
(value) => {
|
||||
// 兼容旧的数据结构
|
||||
if (isEmpty(value)) {
|
||||
// 空值或者空数组
|
||||
props.model[props.name] = {
|
||||
hookType: HookType.CODE,
|
||||
hookData: [],
|
||||
};
|
||||
} else if (Array.isArray(value) && value.length > 0) {
|
||||
// 兼容旧的数据结构 ['code1','code2']
|
||||
const hookData = value.map((codeId) => ({
|
||||
codeId,
|
||||
}));
|
||||
props.model[props.name] = {
|
||||
hookType: HookType.CODE,
|
||||
hookData,
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
// watch(
|
||||
// () => selectModel.value,
|
||||
// () => {
|
||||
// const selectData
|
||||
// if (isEmpty(selectModel)) return;
|
||||
// const hookData = selectModel.value.map((selectedCodeId: Id) => ({
|
||||
// codeId: selectedCodeId,
|
||||
// }));
|
||||
// console.log('hookData', hookData);
|
||||
// if (isEmpty(hookData)) return;
|
||||
// if (!props.model[props.name]?.data || isEmpty(props.model[props.name]?.data)) {
|
||||
// // 新增hook
|
||||
// props.model[props.name] = {
|
||||
// hookType: HookType.CODE,
|
||||
// data: hookData,
|
||||
// };
|
||||
// } else {
|
||||
// // 新增hook data
|
||||
// props.model[props.name].data = {
|
||||
// ...props.model[props.name].data,
|
||||
// ...hookData,
|
||||
// };
|
||||
// }
|
||||
// console.log('-0-props.model[props.name]--', props.model[props.name]);
|
||||
// },
|
||||
// {
|
||||
// deep: true,
|
||||
// immediate: true,
|
||||
// },
|
||||
// );
|
||||
|
||||
const fieldKey = ref('');
|
||||
const multiple = ref(true);
|
||||
const lastTagSnapshot = ref<string[]>([]);
|
||||
|
||||
// watchEffect(async () => {
|
||||
// if (isEmpty(selectModel)) return;
|
||||
// const combineNames = await Promise.all(
|
||||
// selectModel.value[props.name].map(async (id: string) => {
|
||||
// const { name = '' } = (await services?.codeBlockService.getCodeContentById(id)) || {};
|
||||
// return name;
|
||||
// }),
|
||||
// );
|
||||
// fieldKey.value = combineNames.join('-');
|
||||
// });
|
||||
|
||||
const changeHandler = async (value: any) => {
|
||||
console.log('---value--', value);
|
||||
let codeIds = value;
|
||||
if (typeof value === 'string') {
|
||||
multiple.value = false;
|
||||
codeIds = value ? [value] : [];
|
||||
}
|
||||
await setCombineRelation(codeIds);
|
||||
emit('change', value);
|
||||
const changeHandler = async () => {
|
||||
emit('change', props.model[props.name]);
|
||||
};
|
||||
|
||||
// 同步绑定关系
|
||||
const setCombineRelation = async (codeIds: string[]) => {
|
||||
// 组件id
|
||||
const { id = '' } = services?.editorService.get('node') || {};
|
||||
|
||||
// 兼容单选
|
||||
let opFlag = CodeSelectOp.CHANGE;
|
||||
let diffValues = codeIds;
|
||||
if (multiple.value) {
|
||||
// initValues为表单初始值,当表单内容发生变化时,initValues也会更新,可以理解为上一次表单内容的快照
|
||||
lastTagSnapshot.value = form?.initValues[props.name] || [];
|
||||
opFlag = codeIds.length < lastTagSnapshot.value.length ? CodeSelectOp.DELETE : CodeSelectOp.ADD;
|
||||
diffValues = xor(codeIds, lastTagSnapshot.value) as string[];
|
||||
}
|
||||
// 记录绑定关系
|
||||
await services?.codeBlockService.setCombineRelation(id, diffValues, opFlag, props.prop);
|
||||
};
|
||||
|
||||
// const viewHandler = async () => {
|
||||
// if (props.model[props.name].length === 0) {
|
||||
// tMagicMessage.error('请先绑定代码块');
|
||||
// return;
|
||||
// }
|
||||
// // 记录当前已被绑定的代码块,为查看弹窗的展示内容
|
||||
// await services?.codeBlockService.setCombineIds(props.model[props.name]);
|
||||
// await services?.codeBlockService.setMode(CodeEditorMode.LIST);
|
||||
// services?.codeBlockService.setCodeEditorContent(true, props.model[props.name][0]);
|
||||
// };
|
||||
</script>
|
||||
|
@ -65,7 +65,7 @@ import { CodeBlockContent } from '@tmagic/schema';
|
||||
|
||||
import FunctionEditor from '../../../components/FunctionEditor.vue';
|
||||
import Layout from '../../../components/Layout.vue';
|
||||
import type { CodeDslList, ListState, Services } from '../../../type';
|
||||
import type { CodeDslItem, ListState, Services } from '../../../type';
|
||||
import { CodeEditorMode } from '../../../type';
|
||||
import { serializeConfig } from '../../../utils/editor';
|
||||
|
||||
@ -87,8 +87,6 @@ const editable = computed(() => services?.codeBlockService.getEditStatus());
|
||||
// 当前选中组件绑定的代码块id数组
|
||||
const selectedIds = computed(() => services?.codeBlockService.getCombineIds() || []);
|
||||
|
||||
services?.codeBlockService.getCombineInfo();
|
||||
|
||||
watchEffect(async () => {
|
||||
codeConfig.value = cloneDeep(await services?.codeBlockService.getCodeContentById(id.value)) || null;
|
||||
if (!codeConfig.value) return;
|
||||
@ -108,7 +106,7 @@ watchEffect(async () => {
|
||||
currentTitle.value = state.codeList[0]?.name || '';
|
||||
});
|
||||
|
||||
const selectHandler = (data: CodeDslList) => {
|
||||
const selectHandler = (data: CodeDslItem) => {
|
||||
services?.codeBlockService.setId(data.id);
|
||||
currentTitle.value = data.name;
|
||||
};
|
||||
|
@ -40,7 +40,7 @@
|
||||
effect="dark"
|
||||
content="查看绑定关系"
|
||||
placement="bottom"
|
||||
v-if="state.bindComps[data.id] && state.bindComps[data.id].length > 0"
|
||||
v-if="data.combineInfo && data.combineInfo.length > 0"
|
||||
>
|
||||
<Icon :icon="Link" class="edit-icon" @click.stop="toggleCombineRelation(data)"></Icon>
|
||||
</TMagicTooltip>
|
||||
@ -53,7 +53,7 @@
|
||||
<!-- 展示代码块下绑定的组件 -->
|
||||
<div
|
||||
class="code-comp-map-wrapper"
|
||||
v-if="data.showRelation && state.bindComps[data.id] && state.bindComps[data.id].length > 0"
|
||||
v-if="data.showRelation && data.combineInfo && data.combineInfo.length > 0"
|
||||
>
|
||||
<svg class="arrow-left" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-029747aa="">
|
||||
<path
|
||||
@ -61,23 +61,14 @@
|
||||
d="M609.408 149.376 277.76 489.6a32 32 0 0 0 0 44.672l331.648 340.352a29.12 29.12 0 0 0 41.728 0 30.592 30.592 0 0 0 0-42.752L339.264 511.936l311.872-319.872a30.592 30.592 0 0 0 0-42.688 29.12 29.12 0 0 0-41.728 0z"
|
||||
></path>
|
||||
</svg>
|
||||
<!-- todo 功能暂时隐藏 -->
|
||||
<!-- <TMagicButton
|
||||
v-for="(comp, index) in state.bindComps[data.id]"
|
||||
:key="index"
|
||||
class="code-comp"
|
||||
size="small"
|
||||
:plain="true"
|
||||
>{{ comp.name }}<Icon :icon="Close" class="comp-delete-icon" @click.stop="unbind(comp.id, data.id)"></Icon
|
||||
></TMagicButton> -->
|
||||
<TMagicButton
|
||||
v-for="(comp, index) in state.bindComps[data.id]"
|
||||
v-for="(comp, index) in data.combineInfo"
|
||||
:key="index"
|
||||
class="code-comp"
|
||||
size="small"
|
||||
:plain="true"
|
||||
@click.stop="selectComp(comp.id)"
|
||||
>{{ comp.name }}</TMagicButton
|
||||
@click.stop="selectComp(comp.compId)"
|
||||
>{{ comp.compName }}</TMagicButton
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@ -96,65 +87,65 @@
|
||||
<script lang="ts" setup name="MEditorCodeBlockList">
|
||||
import { computed, inject, reactive, ref, watch } from 'vue';
|
||||
import { Close, Edit, Link, View } from '@element-plus/icons-vue';
|
||||
import { forIn, isEmpty } from 'lodash-es';
|
||||
import { cloneDeep, forIn, isEmpty } from 'lodash-es';
|
||||
|
||||
import { TMagicButton, TMagicInput, tMagicMessage, TMagicTooltip, TMagicTree } from '@tmagic/design';
|
||||
import { CodeBlockContent, Id } from '@tmagic/schema';
|
||||
import StageCore from '@tmagic/stage';
|
||||
|
||||
import Icon from '../../../components/Icon.vue';
|
||||
import type { Services } from '../../../type';
|
||||
import { CodeDeleteErrorType, CodeDslList, CodeEditorMode, ListRelationState } from '../../../type';
|
||||
import type { CodeRelation, Services } from '../../../type';
|
||||
import { CodeDeleteErrorType, CodeDslItem, CodeEditorMode, ListState } from '../../../type';
|
||||
|
||||
import codeBlockEditor from './CodeBlockEditor.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
customError?: (id: string, errorType: CodeDeleteErrorType) => any;
|
||||
customError?: (id: Id, errorType: CodeDeleteErrorType) => any;
|
||||
}>();
|
||||
|
||||
const services = inject<Services>('services');
|
||||
|
||||
// 代码块列表
|
||||
const state = reactive<ListRelationState>({
|
||||
const state = reactive<ListState>({
|
||||
codeList: [],
|
||||
bindComps: {},
|
||||
});
|
||||
|
||||
const editable = computed(() => services?.codeBlockService.getEditStatus());
|
||||
|
||||
// 是否展示代码编辑区
|
||||
const isShowCodeBlockEditor = computed(() => services?.codeBlockService.getCodeEditorShowStatus() || false);
|
||||
// 获取绑定关系
|
||||
const codeCombineInfo = ref<CodeRelation | null>(null);
|
||||
|
||||
// 根据代码块ID获取其绑定的组件信息
|
||||
const getBindCompsByCodeId = (codeId: string) => {
|
||||
const codeCombineInfo = services?.codeBlockService.getCombineInfo();
|
||||
if (!codeCombineInfo) return null;
|
||||
const bindCompsId = Object.keys(codeCombineInfo[codeId]);
|
||||
const compsInfo = bindCompsId.map((compId) => ({
|
||||
id: compId,
|
||||
name: getCompName(compId),
|
||||
const getBindCompsByCodeId = (codeId: Id) => {
|
||||
if (!codeCombineInfo.value || !codeCombineInfo.value[codeId]) return [];
|
||||
const bindCompsId = Object.keys(codeCombineInfo.value[codeId]);
|
||||
return bindCompsId.map((compId) => ({
|
||||
compId,
|
||||
compName: getCompName(compId),
|
||||
}));
|
||||
state.bindComps[codeId] = compsInfo;
|
||||
};
|
||||
|
||||
// 初始化代码块列表
|
||||
const initList = async () => {
|
||||
const codeDsl = (await services?.codeBlockService.getCodeDsl()) || null;
|
||||
if (!codeDsl) return;
|
||||
const codeDsl = cloneDeep(await services?.codeBlockService.getCodeDsl()) || null;
|
||||
codeCombineInfo.value = cloneDeep(services?.codeBlockService.getCombineInfo()) || null;
|
||||
if (!codeDsl || !codeCombineInfo.value) return;
|
||||
state.codeList = [];
|
||||
forIn(codeDsl, (value: CodeBlockContent, codeId: string) => {
|
||||
getBindCompsByCodeId(codeId);
|
||||
forIn(codeDsl, (value: CodeBlockContent, codeId: Id) => {
|
||||
state.codeList.push({
|
||||
id: codeId,
|
||||
name: value.name,
|
||||
codeBlockContent: value,
|
||||
showRelation: true,
|
||||
combineInfo: getBindCompsByCodeId(codeId),
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => services?.codeBlockService.getCodeDsl(),
|
||||
[() => services?.codeBlockService.getCodeDsl(), () => services?.codeBlockService.refreshCombineInfo()],
|
||||
() => {
|
||||
initList();
|
||||
},
|
||||
@ -164,21 +155,6 @@ watch(
|
||||
},
|
||||
);
|
||||
|
||||
// 监听组件名称修改,更新到代码块列表
|
||||
watch(
|
||||
() => services?.editorService.get('node'),
|
||||
(curNode) => {
|
||||
if (!curNode?.id) return;
|
||||
forIn(state.bindComps, (bindCompInfo) => {
|
||||
bindCompInfo.forEach((comp) => {
|
||||
if (comp.id === curNode.id) {
|
||||
comp.name = curNode.name;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// 新增代码块
|
||||
const createCodeBlock = async () => {
|
||||
const { codeBlockService } = services || {};
|
||||
@ -197,14 +173,15 @@ const createCodeBlock = async () => {
|
||||
};
|
||||
|
||||
// 编辑代码块
|
||||
const editCode = async (key: string) => {
|
||||
const editCode = async (key: Id) => {
|
||||
await services?.codeBlockService.setMode(CodeEditorMode.EDITOR);
|
||||
services?.codeBlockService.setCodeEditorContent(true, key);
|
||||
};
|
||||
|
||||
// 删除代码块
|
||||
const deleteCode = (key: string) => {
|
||||
const existBinds = !!(state.bindComps[key]?.length > 0);
|
||||
const deleteCode = (key: Id) => {
|
||||
const currentCode = state.codeList.find((codeItem: CodeDslItem) => codeItem.id === key);
|
||||
const existBinds = !isEmpty(currentCode?.combineInfo);
|
||||
const undeleteableList = services?.codeBlockService.getUndeletableList() || [];
|
||||
if (!existBinds && !undeleteableList.includes(key)) {
|
||||
// 无绑定关系,且不在不可删除列表中
|
||||
@ -221,7 +198,7 @@ const deleteCode = (key: string) => {
|
||||
const filterText = ref('');
|
||||
const tree = ref();
|
||||
|
||||
const filterNode = (value: string, data: CodeDslList): boolean => {
|
||||
const filterNode = (value: string, data: CodeDslItem): boolean => {
|
||||
if (!value) {
|
||||
return true;
|
||||
}
|
||||
@ -233,7 +210,7 @@ const filterTextChangeHandler = (val: string) => {
|
||||
};
|
||||
|
||||
// 展示/隐藏组件绑定关系
|
||||
const toggleCombineRelation = (data: CodeDslList) => {
|
||||
const toggleCombineRelation = (data: CodeDslItem) => {
|
||||
const { id } = data;
|
||||
const currentCode = state.codeList.find((item) => item.id === id);
|
||||
if (!currentCode) return;
|
||||
@ -246,17 +223,6 @@ const getCompName = (compId: Id): string => {
|
||||
return node?.name || String(compId);
|
||||
};
|
||||
|
||||
// todo 功能暂时隐藏
|
||||
// 解除绑定
|
||||
// const unbind = async (compId: Id, codeId: string) => {
|
||||
// const res = await services?.codeBlockService.unbind(compId, codeId, codeHooks);
|
||||
// if (res) {
|
||||
// ElMessage.success('绑定关系解除成功');
|
||||
// } else {
|
||||
// ElMessage.error('绑定关系解除失败');
|
||||
// }
|
||||
// };
|
||||
|
||||
// 选中组件
|
||||
const selectComp = (compId: Id) => {
|
||||
const stage = services?.editorService.get<StageCore | null>('stage');
|
||||
|
@ -23,8 +23,8 @@ import { CodeBlockContent, CodeBlockDSL, HookType, Id, MApp, MNode } from '@tmag
|
||||
|
||||
import editorService from '../services/editor';
|
||||
import type { CodeRelation, CodeState, HookData } from '../type';
|
||||
import { CODE_DRAFT_STORAGE_KEY, CodeEditorMode, CodeSelectOp } from '../type';
|
||||
import { error, info } from '../utils/logger';
|
||||
import { CODE_DRAFT_STORAGE_KEY, CodeEditorMode } from '../type';
|
||||
import { info } from '../utils/logger';
|
||||
|
||||
import BaseService from './BaseService';
|
||||
|
||||
@ -242,84 +242,23 @@ class CodeBlock extends BaseService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置绑定关系
|
||||
* @param {Id} 组件id
|
||||
* @param {string[]} diffCodeIds 代码块id数组
|
||||
* @param {CodeSelectOp} opFlag 操作类型
|
||||
* @param {string} hook 代码块挂载hook名称
|
||||
* 刷新绑定关系
|
||||
* @returns {void}
|
||||
*/
|
||||
public async setCombineRelation(compId: Id, diffCodeIds: string[], opFlag: CodeSelectOp, hook: string) {
|
||||
const combineInfo = this.getCombineInfo();
|
||||
if (!combineInfo) return;
|
||||
if (opFlag === CodeSelectOp.DELETE) {
|
||||
try {
|
||||
diffCodeIds.forEach((codeId) => {
|
||||
const compsContent = combineInfo[codeId];
|
||||
const index = compsContent?.[compId].findIndex((item) => item === hook);
|
||||
if (typeof index !== 'undefined' && index !== -1) {
|
||||
compsContent?.[compId].splice(index, 1);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
error(e);
|
||||
throw new Error('解绑代码块失败');
|
||||
}
|
||||
} else if (opFlag === CodeSelectOp.ADD) {
|
||||
try {
|
||||
diffCodeIds.forEach((codeId) => {
|
||||
const compsContent = combineInfo[codeId];
|
||||
const existHooks = compsContent?.[compId];
|
||||
if (isEmpty(existHooks)) {
|
||||
// comps属性不存在,或者comps为空:新增
|
||||
combineInfo[codeId] = {
|
||||
...(combineInfo[codeId] || {}),
|
||||
[compId]: [hook],
|
||||
};
|
||||
} else {
|
||||
// 往已有的关系中添加hook
|
||||
existHooks?.push(hook);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
error(e);
|
||||
throw new Error('绑定代码块失败');
|
||||
}
|
||||
} else if (opFlag === CodeSelectOp.CHANGE) {
|
||||
// 单选修改
|
||||
forIn(combineInfo, (combineItem, codeId) => {
|
||||
if (codeId === diffCodeIds[0]) {
|
||||
// 增加
|
||||
combineItem = {
|
||||
...(combineItem || {}),
|
||||
[compId]: [hook],
|
||||
};
|
||||
} else if (isEmpty(diffCodeIds) || codeId !== diffCodeIds[0]) {
|
||||
// 清空或者移除之前的选项
|
||||
const compHooks = combineItem?.[compId];
|
||||
// continue
|
||||
if (!compHooks) return true;
|
||||
const index = compHooks.findIndex((hookName) => hookName === hook);
|
||||
if (index !== -1) {
|
||||
compHooks.splice(index, 1);
|
||||
// break
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
console.log('---combineInfo--', combineInfo);
|
||||
console.log('---this.state.relations--', this.state.relations);
|
||||
public refreshCombineInfo(): CodeRelation | null {
|
||||
const root = editorService.get<MApp | null>('root');
|
||||
if (!root) return null;
|
||||
const relations = {};
|
||||
this.recurseMNode(root, relations);
|
||||
this.state.relations = relations;
|
||||
return this.state.relations;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绑定关系
|
||||
* @returns {CodeRelation | null}
|
||||
* @returns {CodeRelation}
|
||||
*/
|
||||
public getCombineInfo(): CodeRelation | null {
|
||||
const root = editorService.get<MApp | null>('root');
|
||||
if (!root) return null;
|
||||
this.recurseMNode(root);
|
||||
public getCombineInfo(): CodeRelation {
|
||||
return this.state.relations;
|
||||
}
|
||||
|
||||
@ -429,17 +368,19 @@ class CodeBlock extends BaseService {
|
||||
|
||||
/**
|
||||
* 递归遍历dsl中挂载了代码块的节点,并更新绑定关系数据
|
||||
* @param {MNode} node 节点信息
|
||||
* @param {MContainer} node 节点信息
|
||||
* @returns void
|
||||
*/
|
||||
private recurseMNode(node: MNode) {
|
||||
private recurseMNode(node: MNode, relations: CodeRelation) {
|
||||
forIn(node, (value, key) => {
|
||||
if (value?.hookType === HookType.CODE && !isEmpty(value?.data)) {
|
||||
value.data.forEach((relationItem: HookData) => {
|
||||
if (!this.state.relations[relationItem.codeId]) {
|
||||
this.state.relations[relationItem.codeId] = {};
|
||||
if (value?.hookType === HookType.CODE && !isEmpty(value.hookData)) {
|
||||
value.hookData.forEach((relationItem: HookData) => {
|
||||
// continue
|
||||
if (!relationItem.codeId) return;
|
||||
if (!relations[relationItem.codeId]) {
|
||||
relations[relationItem.codeId] = {};
|
||||
}
|
||||
const codeItem = this.state.relations[relationItem.codeId];
|
||||
const codeItem = relations[relationItem.codeId];
|
||||
if (isEmpty(codeItem[node.id])) {
|
||||
codeItem[node.id] = [];
|
||||
}
|
||||
@ -449,7 +390,7 @@ class CodeBlock extends BaseService {
|
||||
});
|
||||
if (!isEmpty(node.items)) {
|
||||
node.items.forEach((item: MNode) => {
|
||||
this.recurseMNode(item);
|
||||
this.recurseMNode(item, relations);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
import { reactive, toRaw } from 'vue';
|
||||
import { cloneDeep, mergeWith, uniq } from 'lodash-es';
|
||||
import { cloneDeep, isObject, mergeWith, uniq } from 'lodash-es';
|
||||
|
||||
import type { CodeBlockDSL, Id, MApp, MComponent, MContainer, MNode, MPage } from '@tmagic/schema';
|
||||
import { NodeType } from '@tmagic/schema';
|
||||
@ -459,6 +459,11 @@ class Editor extends BaseService {
|
||||
let newConfig = await this.toggleFixedPosition(toRaw(config), node, this.get<MApp>('root'));
|
||||
|
||||
newConfig = mergeWith(cloneDeep(node), newConfig, (objValue, srcValue) => {
|
||||
if (isObject(srcValue) && Array.isArray(objValue)) {
|
||||
// 原来的配置是数组,新的配置是对象,则直接使用新的值
|
||||
console.log('--srcValue-', srcValue);
|
||||
return srcValue;
|
||||
}
|
||||
if (Array.isArray(srcValue)) {
|
||||
return srcValue;
|
||||
}
|
||||
@ -521,7 +526,7 @@ class Editor extends BaseService {
|
||||
this.pushHistoryState();
|
||||
|
||||
this.emit('update', newNodes);
|
||||
|
||||
codeBlockService.refreshCombineInfo();
|
||||
return Array.isArray(config) ? newNodes : newNodes[0];
|
||||
}
|
||||
|
||||
|
@ -349,7 +349,7 @@ export enum CodeEditorMode {
|
||||
EDITOR = 'editor',
|
||||
}
|
||||
|
||||
export interface CodeDslList {
|
||||
export interface CodeDslItem {
|
||||
/** 代码块id */
|
||||
id: Id;
|
||||
/** 代码块名称 */
|
||||
@ -358,19 +358,20 @@ export interface CodeDslList {
|
||||
codeBlockContent?: CodeBlockContent;
|
||||
/** 是否展示代码绑定关系 */
|
||||
showRelation?: boolean;
|
||||
/** 代码块对应绑定的组件信息 */
|
||||
combineInfo?: CombineInfo[];
|
||||
}
|
||||
|
||||
export interface CombineInfo {
|
||||
/** 组件id */
|
||||
compId: Id;
|
||||
/** 组件名称 */
|
||||
compName: string;
|
||||
}
|
||||
|
||||
export interface ListState {
|
||||
/** 代码块列表 */
|
||||
codeList: CodeDslList[];
|
||||
}
|
||||
|
||||
export interface ListRelationState extends ListState {
|
||||
/** 与代码块绑定的组件信息 */
|
||||
bindComps: {
|
||||
/** 代码块id : 组件信息 */
|
||||
[id: Id]: MNode[];
|
||||
};
|
||||
codeList: CodeDslItem[];
|
||||
}
|
||||
|
||||
export enum CodeDeleteErrorType {
|
||||
@ -380,14 +381,5 @@ export enum CodeDeleteErrorType {
|
||||
BIND = 'bind',
|
||||
}
|
||||
|
||||
export enum CodeSelectOp {
|
||||
/** 增加 */
|
||||
ADD = 'add',
|
||||
/** 删除 */
|
||||
DELETE = 'delete',
|
||||
/** 单选修改 */
|
||||
CHANGE = 'change',
|
||||
}
|
||||
|
||||
// 代码块草稿localStorage key
|
||||
export const CODE_DRAFT_STORAGE_KEY = 'magicCodeDraft';
|
||||
|
@ -226,14 +226,14 @@ export const fillConfig = (config: FormConfig = []) => [
|
||||
{
|
||||
name: 'created',
|
||||
text: 'created',
|
||||
type: 'code-select',
|
||||
labelWidth: '100px',
|
||||
type: 'code-select',
|
||||
},
|
||||
{
|
||||
name: 'mounted',
|
||||
text: 'mounted',
|
||||
type: 'code-select',
|
||||
labelWidth: '100px',
|
||||
type: 'code-select',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -59,7 +59,7 @@ export default {
|
||||
events: [],
|
||||
created: {
|
||||
hookType: 'code',
|
||||
data: [
|
||||
hookData: [
|
||||
{
|
||||
codeId: 'code_5336',
|
||||
params: {
|
||||
@ -74,7 +74,7 @@ export default {
|
||||
},
|
||||
mounted: {
|
||||
hookType: 'code',
|
||||
data: [
|
||||
hookData: [
|
||||
{
|
||||
codeId: 'code_5316',
|
||||
},
|
||||
@ -106,7 +106,7 @@ export default {
|
||||
events: [],
|
||||
created: {
|
||||
hookType: 'code',
|
||||
data: [
|
||||
hookData: [
|
||||
{
|
||||
codeId: 'code_5316',
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user