mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-06-22 01:39:31 +08:00
feat(editor): codeBlockService暴露一些方法支持hook,默认设置代码块到dsl的method字段
This commit is contained in:
parent
25d9de10e2
commit
5b220a0e06
@ -41,16 +41,16 @@ const props = defineProps<{
|
||||
size: string;
|
||||
}>();
|
||||
|
||||
const changeHandler = (value: any) => {
|
||||
const changeHandler = async (value: any) => {
|
||||
// 记录组件与代码块的绑定关系
|
||||
const { id = '' } = services?.editorService.get('node') || {};
|
||||
services?.codeBlockService.setCompRelation(id, value);
|
||||
await services?.codeBlockService.setCompRelation(id, value);
|
||||
emit('change', value);
|
||||
};
|
||||
|
||||
const viewHandler = () => {
|
||||
services?.codeBlockService.setMode(EditorMode.LIST);
|
||||
services?.codeBlockService.setCombineIds(props.model[props.name]);
|
||||
const viewHandler = async () => {
|
||||
await services?.codeBlockService.setMode(EditorMode.LIST);
|
||||
await services?.codeBlockService.setCombineIds(props.model[props.name]);
|
||||
services?.codeBlockService.setCodeEditorContent(true, props.model[props.name][0]);
|
||||
};
|
||||
</script>
|
||||
|
@ -58,7 +58,7 @@ import { computed, inject, ref, watchEffect } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
|
||||
import type { CodeBlockContent, Services } from '../../../type';
|
||||
import type { CodeBlockContent, CodeBlockDSL, Services } from '../../../type';
|
||||
import { EditorMode } from '../../../type';
|
||||
|
||||
const services = inject<Services>('services');
|
||||
@ -66,6 +66,8 @@ const services = inject<Services>('services');
|
||||
const codeEditor = ref<any | null>(null);
|
||||
// 编辑器当前需展示的代码块内容
|
||||
const codeConfig = ref<CodeBlockContent | null>(null);
|
||||
// select选择的内容(CodeBlockDSL)
|
||||
const selectedValue = ref<CodeBlockDSL | null>(null);
|
||||
|
||||
// 是否展示代码编辑区
|
||||
const isShowCodeBlockEditor = computed(() => codeConfig.value && services?.codeBlockService.getCodeEditorShowStatus());
|
||||
@ -74,15 +76,17 @@ const id = computed(() => services?.codeBlockService.getId() || '');
|
||||
const editable = computed(() => services?.codeBlockService.getEditStatus());
|
||||
// 当前选中组件绑定的代码块id数组
|
||||
const selectedIds = computed(() => services?.codeBlockService.getCombineIds() || []);
|
||||
// select选择的内容(CodeBlockDSL)
|
||||
const selectedValue = computed(() => services?.codeBlockService.getCodeDslByIds(selectedIds.value));
|
||||
|
||||
watchEffect(() => {
|
||||
codeConfig.value = services?.codeBlockService.getCodeContentById(id.value) ?? null;
|
||||
watchEffect(async () => {
|
||||
codeConfig.value = (await services?.codeBlockService.getCodeContentById(id.value)) ?? null;
|
||||
});
|
||||
|
||||
watchEffect(async () => {
|
||||
selectedValue.value = (await services?.codeBlockService.getCodeDslByIds(selectedIds.value)) || null;
|
||||
});
|
||||
|
||||
// 保存代码
|
||||
const saveCode = () => {
|
||||
const saveCode = async () => {
|
||||
if (!codeEditor.value || !codeConfig.value || !editable.value) return;
|
||||
|
||||
try {
|
||||
@ -95,7 +99,7 @@ const saveCode = () => {
|
||||
return;
|
||||
}
|
||||
// 存入dsl
|
||||
services?.codeBlockService.setCodeDslById(id.value, {
|
||||
await services?.codeBlockService.setCodeDslById(id.value, {
|
||||
name: codeConfig.value.name,
|
||||
content: codeConfig.value.content,
|
||||
});
|
||||
@ -103,9 +107,9 @@ const saveCode = () => {
|
||||
};
|
||||
|
||||
// 保存并关闭
|
||||
const saveAndClose = () => {
|
||||
saveCode();
|
||||
services?.codeBlockService.setCodeEditorShowStatus(false);
|
||||
const saveAndClose = async () => {
|
||||
await saveCode();
|
||||
await services?.codeBlockService.setCodeEditorShowStatus(false);
|
||||
};
|
||||
|
||||
const menuSelectHandler = (item: any) => {
|
||||
|
@ -35,24 +35,28 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, inject } from 'vue';
|
||||
import { computed, inject, ref, watchEffect } from 'vue';
|
||||
import { Close, Edit } from '@element-plus/icons-vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { flattenDeep, isEmpty, values } from 'lodash-es';
|
||||
|
||||
import type { CodeBlockContent, Services } from '../../../type';
|
||||
import { EditorMode } from '../../../type';
|
||||
import { CodeBlockDSL, EditorMode } from '../../../type';
|
||||
|
||||
import codeBlockEditor from './CodeBlockEditor.vue';
|
||||
|
||||
const services = inject<Services>('services');
|
||||
|
||||
// 代码块列表
|
||||
const codeList = computed(() => services?.codeBlockService.getCodeDsl());
|
||||
const codeList = ref<CodeBlockDSL | null>(null);
|
||||
|
||||
const editable = computed(() => services?.codeBlockService.getEditStatus());
|
||||
|
||||
watchEffect(async () => {
|
||||
codeList.value = (await services?.codeBlockService.getCodeDsl()) || null;
|
||||
});
|
||||
|
||||
// 新增代码块
|
||||
const createCodeBlock = () => {
|
||||
const createCodeBlock = async () => {
|
||||
const { codeBlockService } = services || {};
|
||||
if (!codeBlockService) {
|
||||
ElMessage.error('新增代码块失败');
|
||||
@ -62,15 +66,15 @@ const createCodeBlock = () => {
|
||||
name: '代码块',
|
||||
content: `() => {\n // place your code here\n}`,
|
||||
};
|
||||
codeBlockService.setMode(EditorMode.EDITOR);
|
||||
const id = codeBlockService.getUniqueId();
|
||||
codeBlockService.setCodeDslById(id, codeConfig);
|
||||
await codeBlockService.setMode(EditorMode.EDITOR);
|
||||
const id = await codeBlockService.getUniqueId();
|
||||
await codeBlockService.setCodeDslById(id, codeConfig);
|
||||
codeBlockService.setCodeEditorContent(true, id);
|
||||
};
|
||||
|
||||
// 编辑代码块
|
||||
const editCode = (key: string) => {
|
||||
services?.codeBlockService.setMode(EditorMode.EDITOR);
|
||||
const editCode = async (key: string) => {
|
||||
await services?.codeBlockService.setMode(EditorMode.EDITOR);
|
||||
services?.codeBlockService.setCodeEditorContent(true, key);
|
||||
};
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
import { reactive } from 'vue';
|
||||
import { keys, omit, pick } from 'lodash-es';
|
||||
|
||||
import editorService from '../services/editor';
|
||||
import type { CodeBlockContent, CodeBlockDSL, CodeState, CompRelation } from '../type';
|
||||
import { EditorMode } from '../type';
|
||||
import { info } from '../utils/logger';
|
||||
@ -38,7 +39,21 @@ class CodeBlock extends BaseService {
|
||||
});
|
||||
|
||||
constructor() {
|
||||
super([]);
|
||||
super([
|
||||
'setCodeDsl',
|
||||
'getCodeDsl',
|
||||
'getCodeContentById',
|
||||
'getCodeDslByIds',
|
||||
'getCurrentDsl',
|
||||
'setCodeDslById',
|
||||
'setCodeEditorShowStatus',
|
||||
'setEditStatus',
|
||||
'setMode',
|
||||
'setCombineIds',
|
||||
'setCompRelation',
|
||||
'setUndeleteableList',
|
||||
'deleteCodeDslByIds',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,17 +61,21 @@ class CodeBlock extends BaseService {
|
||||
* @param {CodeBlockDSL} codeDsl 代码DSL
|
||||
* @returns {void}
|
||||
*/
|
||||
public setCodeDsl(codeDsl: CodeBlockDSL): void {
|
||||
public async setCodeDsl(codeDsl: CodeBlockDSL): Promise<void> {
|
||||
this.state.codeDsl = codeDsl;
|
||||
await editorService.setCodeDsl(this.state.codeDsl);
|
||||
info('[code-block]:code-dsl-change', this.state.codeDsl);
|
||||
this.emit('code-dsl-change', this.state.codeDsl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取活动的代码块dsl数据源
|
||||
* 获取活动的代码块dsl数据源(默认从dsl中的method字段读取)
|
||||
* @returns {CodeBlockDSL | null}
|
||||
*/
|
||||
public getCodeDsl(): CodeBlockDSL | null {
|
||||
public async getCodeDsl(): Promise<CodeBlockDSL | null> {
|
||||
if (!this.state.codeDsl) {
|
||||
this.state.codeDsl = await editorService.getCodeDsl();
|
||||
}
|
||||
return this.state.codeDsl;
|
||||
}
|
||||
|
||||
@ -65,9 +84,9 @@ class CodeBlock extends BaseService {
|
||||
* @param {string} id 代码块id
|
||||
* @returns {CodeBlockContent | null}
|
||||
*/
|
||||
public getCodeContentById(id: string): CodeBlockContent | null {
|
||||
public async getCodeContentById(id: string): Promise<CodeBlockContent | null> {
|
||||
if (!id) return null;
|
||||
const totalCodeDsl = this.getCodeDsl();
|
||||
const totalCodeDsl = await this.getCodeDsl();
|
||||
if (!totalCodeDsl) return null;
|
||||
return totalCodeDsl[id] ?? null;
|
||||
}
|
||||
@ -78,13 +97,13 @@ class CodeBlock extends BaseService {
|
||||
* @param {CodeBlockContent} codeConfig 代码块内容配置信息
|
||||
* @returns {void}
|
||||
*/
|
||||
public setCodeDslById(id: string, codeConfig: CodeBlockContent): void {
|
||||
let codeDsl = this.getCodeDsl();
|
||||
public async setCodeDslById(id: string, codeConfig: CodeBlockContent): Promise<void> {
|
||||
let codeDsl = await this.getCodeDsl();
|
||||
codeDsl = {
|
||||
...codeDsl,
|
||||
[id]: codeConfig,
|
||||
};
|
||||
this.setCodeDsl(codeDsl);
|
||||
await this.setCodeDsl(codeDsl);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,8 +111,8 @@ class CodeBlock extends BaseService {
|
||||
* @param {string[]} ids 代码块id数组
|
||||
* @returns {CodeBlockDSL}
|
||||
*/
|
||||
public getCodeDslByIds(ids: string[]): CodeBlockDSL {
|
||||
const codeDsl = this.getCodeDsl();
|
||||
public async getCodeDslByIds(ids: string[]): Promise<CodeBlockDSL> {
|
||||
const codeDsl = await this.getCodeDsl();
|
||||
return pick(codeDsl, ids) as CodeBlockDSL;
|
||||
}
|
||||
|
||||
@ -102,7 +121,7 @@ class CodeBlock extends BaseService {
|
||||
* @param {boolean} status 是否展示代码编辑面板
|
||||
* @returns {void}
|
||||
*/
|
||||
public setCodeEditorShowStatus(status: boolean): void {
|
||||
public async setCodeEditorShowStatus(status: boolean): Promise<void> {
|
||||
this.state.isShowCodeEditor = status;
|
||||
}
|
||||
|
||||
@ -130,8 +149,8 @@ class CodeBlock extends BaseService {
|
||||
* 获取当前选中的代码块内容
|
||||
* @returns {CodeBlockContent | null}
|
||||
*/
|
||||
public getCurrentDsl() {
|
||||
return this.getCodeContentById(this.state.id);
|
||||
public async getCurrentDsl() {
|
||||
return await this.getCodeContentById(this.state.id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,7 +166,7 @@ class CodeBlock extends BaseService {
|
||||
* @param {boolean} 是否可编辑
|
||||
* @returns {void}
|
||||
*/
|
||||
public setEditStatus(status: boolean): void {
|
||||
public async setEditStatus(status: boolean): Promise<void> {
|
||||
this.state.editable = status;
|
||||
}
|
||||
|
||||
@ -182,7 +201,7 @@ class CodeBlock extends BaseService {
|
||||
* @param {EditorMode} mode 模式
|
||||
* @returns {void}
|
||||
*/
|
||||
public setMode(mode: EditorMode): void {
|
||||
public async setMode(mode: EditorMode): Promise<void> {
|
||||
this.state.mode = mode;
|
||||
}
|
||||
|
||||
@ -191,7 +210,7 @@ class CodeBlock extends BaseService {
|
||||
* @param {string[]} ids 代码块id数组
|
||||
* @returns {void}
|
||||
*/
|
||||
public setCombineIds(ids: string[]): void {
|
||||
public async setCombineIds(ids: string[]): Promise<void> {
|
||||
this.state.combineIds = ids;
|
||||
}
|
||||
|
||||
@ -209,7 +228,7 @@ class CodeBlock extends BaseService {
|
||||
* @param {string[]} codeIds 代码块id数组
|
||||
* @returns {void}
|
||||
*/
|
||||
public setCompRelation(compId: number | string, codeIds: string[]) {
|
||||
public async setCompRelation(compId: number | string, codeIds: string[]) {
|
||||
if (!compId) return;
|
||||
this.state.compRelation = {
|
||||
[compId]: codeIds,
|
||||
@ -237,7 +256,7 @@ class CodeBlock extends BaseService {
|
||||
* @param {string[]} codeIds 代码块id数组
|
||||
* @returns {void}
|
||||
*/
|
||||
public setUndeleteableList(codeIds: string[]): void {
|
||||
public async setUndeleteableList(codeIds: string[]): Promise<void> {
|
||||
this.state.undeletableList = codeIds;
|
||||
}
|
||||
|
||||
@ -246,10 +265,10 @@ class CodeBlock extends BaseService {
|
||||
* @param {string[]} codeIds 需要删除的代码块id数组
|
||||
* @returns {CodeBlockDSL} 删除后的code dsl
|
||||
*/
|
||||
public deleteCodeDslByIds(codeIds: string[]): CodeBlockDSL {
|
||||
const currentDsl = this.getCodeDsl();
|
||||
public async deleteCodeDslByIds(codeIds: string[]): Promise<CodeBlockDSL> {
|
||||
const currentDsl = await this.getCodeDsl();
|
||||
const newDsl = omit(currentDsl, codeIds);
|
||||
this.setCodeDsl(newDsl);
|
||||
await this.setCodeDsl(newDsl);
|
||||
return newDsl;
|
||||
}
|
||||
|
||||
@ -257,13 +276,13 @@ class CodeBlock extends BaseService {
|
||||
* 生成代码块唯一id
|
||||
* @returns {string} 代码块唯一id
|
||||
*/
|
||||
public getUniqueId(): string {
|
||||
public async getUniqueId(): Promise<string> {
|
||||
const newId = (Date.now().toString(36) + Math.random().toString(36).substring(2)).padEnd(19, '0');
|
||||
// 判断是否重复
|
||||
const dsl = this.getCodeDsl();
|
||||
const dsl = await this.getCodeDsl();
|
||||
const existedIds = keys(dsl);
|
||||
if (!existedIds.includes(newId)) return newId;
|
||||
return this.getUniqueId();
|
||||
return await this.getUniqueId();
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
|
@ -19,7 +19,7 @@
|
||||
import { reactive, toRaw } from 'vue';
|
||||
import { cloneDeep, mergeWith, uniq } from 'lodash-es';
|
||||
|
||||
import type { Id, MApp, MComponent, MContainer, MNode, MPage } from '@tmagic/schema';
|
||||
import type { CodeBlockDSL, Id, MApp, MComponent, MContainer, MNode, MPage } from '@tmagic/schema';
|
||||
import { NodeType } from '@tmagic/schema';
|
||||
import StageCore from '@tmagic/stage';
|
||||
import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils';
|
||||
@ -80,6 +80,8 @@ class Editor extends BaseService {
|
||||
'undo',
|
||||
'redo',
|
||||
'highlight',
|
||||
'getCodeDsl',
|
||||
'setCodeDsl',
|
||||
],
|
||||
// 需要注意循环依赖问题,如果函数间有相互调用的话,不能设置为串行调用
|
||||
['select', 'update', 'moveLayer'],
|
||||
@ -760,6 +762,26 @@ class Editor extends BaseService {
|
||||
this.get<Map<Id, Id>>('modifiedNodeIds').clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从dsl中的method字段读取活动的代码块
|
||||
* @returns {CodeBlockDSL | null}
|
||||
*/
|
||||
public async getCodeDsl(): Promise<CodeBlockDSL | null> {
|
||||
const root = this.get<MApp | null>('root');
|
||||
if (!root) return null;
|
||||
return root.method || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置代码块到dsl的method字段
|
||||
* @param {CodeBlockDSL} codeDsl 代码DSL
|
||||
* @returns {void}
|
||||
*/
|
||||
public async setCodeDsl(codeDsl: CodeBlockDSL): Promise<void> {
|
||||
if (!this.state.root) return;
|
||||
this.state.root.method = codeDsl;
|
||||
}
|
||||
|
||||
private addModifiedNodeId(id: Id) {
|
||||
if (!this.isHistoryStateChange) {
|
||||
this.get<Map<Id, Id>>('modifiedNodeIds').set(id, id);
|
||||
|
@ -233,8 +233,8 @@ export const fillConfig = (config: FormConfig = []) => [
|
||||
labelWidth: '100px',
|
||||
selectConfig: {
|
||||
multiple: true,
|
||||
options: () => {
|
||||
const codeDsl = codeBlockService.getCodeDsl();
|
||||
options: async () => {
|
||||
const codeDsl = await codeBlockService.getCodeDsl();
|
||||
if (codeDsl) {
|
||||
return map(codeDsl, (value, key) => ({
|
||||
text: `${value.name}(${key})`,
|
||||
|
@ -68,8 +68,20 @@ export interface MApp extends MComponent {
|
||||
type: NodeType.ROOT;
|
||||
/** */
|
||||
items: MPage[];
|
||||
/** 代码块 */
|
||||
method: CodeBlockDSL;
|
||||
}
|
||||
|
||||
export interface CodeBlockDSL {
|
||||
[id: string]: CodeBlockContent;
|
||||
}
|
||||
|
||||
export interface CodeBlockContent {
|
||||
/** 代码块名称 */
|
||||
name: string;
|
||||
/** 代码块内容 */
|
||||
content: string;
|
||||
}
|
||||
export interface PastePosition {
|
||||
left?: number;
|
||||
top?: number;
|
||||
|
@ -20,6 +20,14 @@ export default {
|
||||
id: '75f0extui9d7yksklx27hff8xg',
|
||||
name: 'test',
|
||||
type: 'app',
|
||||
method: {
|
||||
l7znj1q24wilb357ay6: {
|
||||
name: 'getData',
|
||||
content: () => {
|
||||
console.log('this is getData function');
|
||||
},
|
||||
},
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'page',
|
||||
|
Loading…
x
Reference in New Issue
Block a user