refactor: 粘贴schema时只对展示类型重复组件ID重新生成

This commit is contained in:
zhangtao07 2024-07-10 16:36:17 +08:00
parent f83a7aa280
commit a9fe012b66
3 changed files with 65 additions and 7 deletions

View File

@ -9,7 +9,7 @@ export default class CodeEditorPanel extends React.Component<PanelProps> {
setTimeout(() => {
this.props.manager.patchSchema(true);
// 检测是否整体粘贴组件,如果是的话强制替换ID避免样式bug
// 检测是否整体粘贴组件,如果是的话对指定类型组件存在重复ID的重新生成
if (
e?.languageId === 'json' &&
e.range?.startColumn === 1 &&
@ -17,7 +17,7 @@ export default class CodeEditorPanel extends React.Component<PanelProps> {
e.range?.endColumn === 2 &&
e.range?.endLineNumber > 1
) {
this.props.manager.reGenerateCurrentNodeID();
this.props.manager.reGenerateNodeDuplicateID(['布局容器', '展示']);
}
}, 500);
}

View File

@ -9,7 +9,7 @@ import debounce from 'lodash/debounce';
import findIndex from 'lodash/findIndex';
import omit from 'lodash/omit';
import {openContextMenus, toast, alert, DataScope, DataSchema} from 'amis';
import {getRenderers, RenderOptions, mapTree, isEmpty} from 'amis-core';
import {getRenderers, RenderOptions, JSONTraverse} from 'amis-core';
import {
PluginInterface,
BasicPanelItem,
@ -57,7 +57,8 @@ import {
JSONPipeOut,
scrollToActive,
JSONPipeIn,
JSONGetById
generateNodeId,
JSONGetNodesById
} from './util';
import {hackIn, makeSchemaFormRender, makeWrapper} from './component/factory';
import {env} from './env';
@ -1565,14 +1566,56 @@ export class EditorManager {
}
/**
* id
* id
*/
reGenerateCurrentNodeID() {
reGenerateNodeDuplicateID(types: Array<string> = []) {
const node = this.store.getNodeById(this.store.activeId);
if (!node) {
return;
}
this.replaceChild(node.id, reGenerateID(node.schema));
let schema = node.schema;
let changed = false;
// 支持按照类型过滤某类型组件
let tags = node.info?.plugin?.tags || [];
if (!Array.isArray(tags)) {
tags = [tags];
}
if (types.length && !tags.some(tag => types.includes(tag))) {
return;
}
// 记录组件新旧ID映射关系方便当前组件内事件动作替换
let idRefs: {[propKey: string]: string} = {};
// 如果有多个重复组件则重新生成ID
JSONTraverse(schema, (value: any, key: string, host: any) => {
const isNodeIdFormat =
typeof value === 'string' && value.indexOf('u:') === 0;
if (key === 'id' && isNodeIdFormat && host) {
let sameNodes = JSONGetNodesById(this.store.schema, value, 'id');
if (sameNodes && sameNodes.length > 1) {
let newId = generateNodeId();
idRefs[value] = newId;
host[key] = newId;
changed = true;
}
}
return value;
});
if (changed) {
// 替换当前组件内事件动作里面可能的ID
JSONTraverse(schema, (value: any, key: string, host: any) => {
const isNodeIdFormat =
typeof value === 'string' && value.indexOf('u:') === 0;
if (key === 'componentId' && isNodeIdFormat && idRefs[value]) {
host.componentId = idRefs[value];
}
return value;
});
this.replaceChild(node.id, schema);
}
}
/**

View File

@ -322,6 +322,21 @@ export function JSONGetById(json: any, id: string, idKey?: string): any {
return JSONGetByPath(json, paths);
}
export function JSONGetNodesById(
json: any,
id: string,
idKey: string = '$$id'
): Array<any> {
let result: Array<any> = [];
JSONTraverse(json, (value: any, key: string, host: any) => {
if (key === idKey && value == id) {
result.push(host);
}
});
return result;
}
export function JSONGetParentById(
json: any,
id: string,