mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-03-17 19:23:27 +00:00
chore(editor): 画布拖动组件位置更新dsl添加changeRecordes
This commit is contained in:
parent
5f57d620da
commit
10c36c1980
@ -8,7 +8,7 @@ import editorService from '@editor/services/editor';
|
|||||||
import uiService from '@editor/services/ui';
|
import uiService from '@editor/services/ui';
|
||||||
import type { StageOptions } from '@editor/type';
|
import type { StageOptions } from '@editor/type';
|
||||||
import { H_GUIDE_LINE_STORAGE_KEY, UI_SELECT_MODE_EVENT_NAME, V_GUIDE_LINE_STORAGE_KEY } from '@editor/utils/const';
|
import { H_GUIDE_LINE_STORAGE_KEY, UI_SELECT_MODE_EVENT_NAME, V_GUIDE_LINE_STORAGE_KEY } from '@editor/utils/const';
|
||||||
import { getGuideLineFromCache } from '@editor/utils/editor';
|
import { buildChangeRecords, getGuideLineFromCache } from '@editor/utils/editor';
|
||||||
|
|
||||||
const root = computed(() => editorService.get('root'));
|
const root = computed(() => editorService.get('root'));
|
||||||
const page = computed(() => editorService.get('page'));
|
const page = computed(() => editorService.get('page'));
|
||||||
@ -94,7 +94,15 @@ export const useStage = (stageOptions: StageOptions) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
editorService.update(ev.data.map((data) => ({ id: getIdFromEl()(data.el) || '', style: data.style })));
|
// 为每个元素单独更新,确保 changeRecords 与对应的元素关联
|
||||||
|
ev.data.forEach((data) => {
|
||||||
|
const id = getIdFromEl()(data.el);
|
||||||
|
if (!id) return;
|
||||||
|
|
||||||
|
const { style = {} } = data;
|
||||||
|
|
||||||
|
editorService.update({ id, style }, { changeRecords: buildChangeRecords(style, 'style') });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
stage.on('sort', (ev: SortEventData) => {
|
stage.on('sort', (ev: SortEventData) => {
|
||||||
|
|||||||
@ -411,3 +411,28 @@ export const isIncludeDataSource = (node: MNode, oldNode: MNode) => {
|
|||||||
|
|
||||||
return isIncludeDataSource;
|
return isIncludeDataSource;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const buildChangeRecords = (value: any, basePath: string) => {
|
||||||
|
const changeRecords: { propPath: string; value: any }[] = [];
|
||||||
|
|
||||||
|
// 递归构建 changeRecords
|
||||||
|
const buildChangeRecords = (obj: any, basePath: string) => {
|
||||||
|
Object.entries(obj).forEach(([key, value]) => {
|
||||||
|
if (value !== undefined) {
|
||||||
|
const currentPath = basePath ? `${basePath}.${key}` : key;
|
||||||
|
|
||||||
|
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
||||||
|
// 递归处理嵌套对象
|
||||||
|
buildChangeRecords(value, currentPath);
|
||||||
|
} else {
|
||||||
|
// 处理基础类型值
|
||||||
|
changeRecords.push({ propPath: currentPath, value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
buildChangeRecords(value, basePath);
|
||||||
|
|
||||||
|
return changeRecords;
|
||||||
|
};
|
||||||
|
|||||||
@ -154,3 +154,154 @@ describe('moveItemsInContainer', () => {
|
|||||||
expect(container.items[2].id).toBe(3);
|
expect(container.items[2].id).toBe(3);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('buildChangeRecords', () => {
|
||||||
|
test('基础类型值', () => {
|
||||||
|
const value = {
|
||||||
|
name: 'test',
|
||||||
|
age: 25,
|
||||||
|
active: true,
|
||||||
|
};
|
||||||
|
const result = editor.buildChangeRecords(value, '');
|
||||||
|
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ propPath: 'name', value: 'test' },
|
||||||
|
{ propPath: 'age', value: 25 },
|
||||||
|
{ propPath: 'active', value: true },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('嵌套对象', () => {
|
||||||
|
const value = {
|
||||||
|
user: {
|
||||||
|
name: 'John',
|
||||||
|
profile: {
|
||||||
|
age: 30,
|
||||||
|
city: 'Beijing',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
theme: 'dark',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = editor.buildChangeRecords(value, '');
|
||||||
|
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ propPath: 'user.name', value: 'John' },
|
||||||
|
{ propPath: 'user.profile.age', value: 30 },
|
||||||
|
{ propPath: 'user.profile.city', value: 'Beijing' },
|
||||||
|
{ propPath: 'settings.theme', value: 'dark' },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('带有basePath', () => {
|
||||||
|
const value = {
|
||||||
|
style: {
|
||||||
|
width: 100,
|
||||||
|
height: 200,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = editor.buildChangeRecords(value, 'node');
|
||||||
|
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ propPath: 'node.style.width', value: 100 },
|
||||||
|
{ propPath: 'node.style.height', value: 200 },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('包含数组', () => {
|
||||||
|
const value = {
|
||||||
|
items: [1, 2, 3],
|
||||||
|
config: {
|
||||||
|
list: ['a', 'b'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = editor.buildChangeRecords(value, '');
|
||||||
|
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ propPath: 'items', value: [1, 2, 3] },
|
||||||
|
{ propPath: 'config.list', value: ['a', 'b'] },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('包含null值', () => {
|
||||||
|
const value = {
|
||||||
|
data: null,
|
||||||
|
info: {
|
||||||
|
value: null,
|
||||||
|
name: 'test',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = editor.buildChangeRecords(value, '');
|
||||||
|
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ propPath: 'data', value: null },
|
||||||
|
{ propPath: 'info.value', value: null },
|
||||||
|
{ propPath: 'info.name', value: 'test' },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('跳过undefined值', () => {
|
||||||
|
const value = {
|
||||||
|
name: 'test',
|
||||||
|
age: undefined,
|
||||||
|
info: {
|
||||||
|
city: 'Beijing',
|
||||||
|
country: undefined,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = editor.buildChangeRecords(value, '');
|
||||||
|
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ propPath: 'name', value: 'test' },
|
||||||
|
{ propPath: 'info.city', value: 'Beijing' },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('空对象', () => {
|
||||||
|
const value = {};
|
||||||
|
const result = editor.buildChangeRecords(value, '');
|
||||||
|
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('深层嵌套', () => {
|
||||||
|
const value = {
|
||||||
|
level1: {
|
||||||
|
level2: {
|
||||||
|
level3: {
|
||||||
|
level4: {
|
||||||
|
value: 'deep',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = editor.buildChangeRecords(value, 'root');
|
||||||
|
|
||||||
|
expect(result).toEqual([{ propPath: 'root.level1.level2.level3.level4.value', value: 'deep' }]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('混合类型', () => {
|
||||||
|
const value = {
|
||||||
|
string: 'text',
|
||||||
|
number: 42,
|
||||||
|
boolean: false,
|
||||||
|
array: [1, 2],
|
||||||
|
object: {
|
||||||
|
nested: 'value',
|
||||||
|
},
|
||||||
|
nullValue: null,
|
||||||
|
};
|
||||||
|
const result = editor.buildChangeRecords(value, 'mixed');
|
||||||
|
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ propPath: 'mixed.string', value: 'text' },
|
||||||
|
{ propPath: 'mixed.number', value: 42 },
|
||||||
|
{ propPath: 'mixed.boolean', value: false },
|
||||||
|
{ propPath: 'mixed.array', value: [1, 2] },
|
||||||
|
{ propPath: 'mixed.object.nested', value: 'value' },
|
||||||
|
{ propPath: 'mixed.nullValue', value: null },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user