feat(editor): codeBlockService暴露一些方法支持hook,默认设置代码块到dsl的method字段

This commit is contained in:
parisma 2022-09-13 15:32:12 +08:00 committed by jia000
parent 25d9de10e2
commit 5b220a0e06
8 changed files with 122 additions and 53 deletions

View File

@ -41,16 +41,16 @@ const props = defineProps<{
size: string; size: string;
}>(); }>();
const changeHandler = (value: any) => { const changeHandler = async (value: any) => {
// //
const { id = '' } = services?.editorService.get('node') || {}; const { id = '' } = services?.editorService.get('node') || {};
services?.codeBlockService.setCompRelation(id, value); await services?.codeBlockService.setCompRelation(id, value);
emit('change', value); emit('change', value);
}; };
const viewHandler = () => { const viewHandler = async () => {
services?.codeBlockService.setMode(EditorMode.LIST); await services?.codeBlockService.setMode(EditorMode.LIST);
services?.codeBlockService.setCombineIds(props.model[props.name]); await services?.codeBlockService.setCombineIds(props.model[props.name]);
services?.codeBlockService.setCodeEditorContent(true, props.model[props.name][0]); services?.codeBlockService.setCodeEditorContent(true, props.model[props.name][0]);
}; };
</script> </script>

View File

@ -58,7 +58,7 @@ import { computed, inject, ref, watchEffect } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { isEmpty } from 'lodash-es'; import { isEmpty } from 'lodash-es';
import type { CodeBlockContent, Services } from '../../../type'; import type { CodeBlockContent, CodeBlockDSL, Services } from '../../../type';
import { EditorMode } from '../../../type'; import { EditorMode } from '../../../type';
const services = inject<Services>('services'); const services = inject<Services>('services');
@ -66,6 +66,8 @@ const services = inject<Services>('services');
const codeEditor = ref<any | null>(null); const codeEditor = ref<any | null>(null);
// //
const codeConfig = ref<CodeBlockContent | null>(null); const codeConfig = ref<CodeBlockContent | null>(null);
// select(CodeBlockDSL)
const selectedValue = ref<CodeBlockDSL | null>(null);
// //
const isShowCodeBlockEditor = computed(() => codeConfig.value && services?.codeBlockService.getCodeEditorShowStatus()); const isShowCodeBlockEditor = computed(() => codeConfig.value && services?.codeBlockService.getCodeEditorShowStatus());
@ -74,15 +76,17 @@ const id = computed(() => services?.codeBlockService.getId() || '');
const editable = computed(() => services?.codeBlockService.getEditStatus()); const editable = computed(() => services?.codeBlockService.getEditStatus());
// id // id
const selectedIds = computed(() => services?.codeBlockService.getCombineIds() || []); const selectedIds = computed(() => services?.codeBlockService.getCombineIds() || []);
// select(CodeBlockDSL)
const selectedValue = computed(() => services?.codeBlockService.getCodeDslByIds(selectedIds.value));
watchEffect(() => { watchEffect(async () => {
codeConfig.value = services?.codeBlockService.getCodeContentById(id.value) ?? null; 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; if (!codeEditor.value || !codeConfig.value || !editable.value) return;
try { try {
@ -95,7 +99,7 @@ const saveCode = () => {
return; return;
} }
// dsl // dsl
services?.codeBlockService.setCodeDslById(id.value, { await services?.codeBlockService.setCodeDslById(id.value, {
name: codeConfig.value.name, name: codeConfig.value.name,
content: codeConfig.value.content, content: codeConfig.value.content,
}); });
@ -103,9 +107,9 @@ const saveCode = () => {
}; };
// //
const saveAndClose = () => { const saveAndClose = async () => {
saveCode(); await saveCode();
services?.codeBlockService.setCodeEditorShowStatus(false); await services?.codeBlockService.setCodeEditorShowStatus(false);
}; };
const menuSelectHandler = (item: any) => { const menuSelectHandler = (item: any) => {

View File

@ -35,24 +35,28 @@
</template> </template>
<script lang="ts" setup> <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 { Close, Edit } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { flattenDeep, isEmpty, values } from 'lodash-es'; import { flattenDeep, isEmpty, values } from 'lodash-es';
import type { CodeBlockContent, Services } from '../../../type'; import type { CodeBlockContent, Services } from '../../../type';
import { EditorMode } from '../../../type'; import { CodeBlockDSL, EditorMode } from '../../../type';
import codeBlockEditor from './CodeBlockEditor.vue'; import codeBlockEditor from './CodeBlockEditor.vue';
const services = inject<Services>('services'); const services = inject<Services>('services');
// //
const codeList = computed(() => services?.codeBlockService.getCodeDsl()); const codeList = ref<CodeBlockDSL | null>(null);
const editable = computed(() => services?.codeBlockService.getEditStatus()); const editable = computed(() => services?.codeBlockService.getEditStatus());
watchEffect(async () => {
codeList.value = (await services?.codeBlockService.getCodeDsl()) || null;
});
// //
const createCodeBlock = () => { const createCodeBlock = async () => {
const { codeBlockService } = services || {}; const { codeBlockService } = services || {};
if (!codeBlockService) { if (!codeBlockService) {
ElMessage.error('新增代码块失败'); ElMessage.error('新增代码块失败');
@ -62,15 +66,15 @@ const createCodeBlock = () => {
name: '代码块', name: '代码块',
content: `() => {\n // place your code here\n}`, content: `() => {\n // place your code here\n}`,
}; };
codeBlockService.setMode(EditorMode.EDITOR); await codeBlockService.setMode(EditorMode.EDITOR);
const id = codeBlockService.getUniqueId(); const id = await codeBlockService.getUniqueId();
codeBlockService.setCodeDslById(id, codeConfig); await codeBlockService.setCodeDslById(id, codeConfig);
codeBlockService.setCodeEditorContent(true, id); codeBlockService.setCodeEditorContent(true, id);
}; };
// //
const editCode = (key: string) => { const editCode = async (key: string) => {
services?.codeBlockService.setMode(EditorMode.EDITOR); await services?.codeBlockService.setMode(EditorMode.EDITOR);
services?.codeBlockService.setCodeEditorContent(true, key); services?.codeBlockService.setCodeEditorContent(true, key);
}; };

View File

@ -19,6 +19,7 @@
import { reactive } from 'vue'; import { reactive } from 'vue';
import { keys, omit, pick } from 'lodash-es'; import { keys, omit, pick } from 'lodash-es';
import editorService from '../services/editor';
import type { CodeBlockContent, CodeBlockDSL, CodeState, CompRelation } from '../type'; import type { CodeBlockContent, CodeBlockDSL, CodeState, CompRelation } from '../type';
import { EditorMode } from '../type'; import { EditorMode } from '../type';
import { info } from '../utils/logger'; import { info } from '../utils/logger';
@ -38,7 +39,21 @@ class CodeBlock extends BaseService {
}); });
constructor() { 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 * @param {CodeBlockDSL} codeDsl DSL
* @returns {void} * @returns {void}
*/ */
public setCodeDsl(codeDsl: CodeBlockDSL): void { public async setCodeDsl(codeDsl: CodeBlockDSL): Promise<void> {
this.state.codeDsl = codeDsl; this.state.codeDsl = codeDsl;
await editorService.setCodeDsl(this.state.codeDsl);
info('[code-block]:code-dsl-change', this.state.codeDsl); info('[code-block]:code-dsl-change', this.state.codeDsl);
this.emit('code-dsl-change', this.state.codeDsl); this.emit('code-dsl-change', this.state.codeDsl);
} }
/** /**
* dsl数据源 * dsl数据源dsl中的method字段读取
* @returns {CodeBlockDSL | null} * @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; return this.state.codeDsl;
} }
@ -65,9 +84,9 @@ class CodeBlock extends BaseService {
* @param {string} id id * @param {string} id id
* @returns {CodeBlockContent | null} * @returns {CodeBlockContent | null}
*/ */
public getCodeContentById(id: string): CodeBlockContent | null { public async getCodeContentById(id: string): Promise<CodeBlockContent | null> {
if (!id) return null; if (!id) return null;
const totalCodeDsl = this.getCodeDsl(); const totalCodeDsl = await this.getCodeDsl();
if (!totalCodeDsl) return null; if (!totalCodeDsl) return null;
return totalCodeDsl[id] ?? null; return totalCodeDsl[id] ?? null;
} }
@ -78,13 +97,13 @@ class CodeBlock extends BaseService {
* @param {CodeBlockContent} codeConfig * @param {CodeBlockContent} codeConfig
* @returns {void} * @returns {void}
*/ */
public setCodeDslById(id: string, codeConfig: CodeBlockContent): void { public async setCodeDslById(id: string, codeConfig: CodeBlockContent): Promise<void> {
let codeDsl = this.getCodeDsl(); let codeDsl = await this.getCodeDsl();
codeDsl = { codeDsl = {
...codeDsl, ...codeDsl,
[id]: codeConfig, [id]: codeConfig,
}; };
this.setCodeDsl(codeDsl); await this.setCodeDsl(codeDsl);
} }
/** /**
@ -92,8 +111,8 @@ class CodeBlock extends BaseService {
* @param {string[]} ids id数组 * @param {string[]} ids id数组
* @returns {CodeBlockDSL} * @returns {CodeBlockDSL}
*/ */
public getCodeDslByIds(ids: string[]): CodeBlockDSL { public async getCodeDslByIds(ids: string[]): Promise<CodeBlockDSL> {
const codeDsl = this.getCodeDsl(); const codeDsl = await this.getCodeDsl();
return pick(codeDsl, ids) as CodeBlockDSL; return pick(codeDsl, ids) as CodeBlockDSL;
} }
@ -102,7 +121,7 @@ class CodeBlock extends BaseService {
* @param {boolean} status * @param {boolean} status
* @returns {void} * @returns {void}
*/ */
public setCodeEditorShowStatus(status: boolean): void { public async setCodeEditorShowStatus(status: boolean): Promise<void> {
this.state.isShowCodeEditor = status; this.state.isShowCodeEditor = status;
} }
@ -130,8 +149,8 @@ class CodeBlock extends BaseService {
* *
* @returns {CodeBlockContent | null} * @returns {CodeBlockContent | null}
*/ */
public getCurrentDsl() { public async getCurrentDsl() {
return this.getCodeContentById(this.state.id); return await this.getCodeContentById(this.state.id);
} }
/** /**
@ -147,7 +166,7 @@ class CodeBlock extends BaseService {
* @param {boolean} * @param {boolean}
* @returns {void} * @returns {void}
*/ */
public setEditStatus(status: boolean): void { public async setEditStatus(status: boolean): Promise<void> {
this.state.editable = status; this.state.editable = status;
} }
@ -182,7 +201,7 @@ class CodeBlock extends BaseService {
* @param {EditorMode} mode * @param {EditorMode} mode
* @returns {void} * @returns {void}
*/ */
public setMode(mode: EditorMode): void { public async setMode(mode: EditorMode): Promise<void> {
this.state.mode = mode; this.state.mode = mode;
} }
@ -191,7 +210,7 @@ class CodeBlock extends BaseService {
* @param {string[]} ids id数组 * @param {string[]} ids id数组
* @returns {void} * @returns {void}
*/ */
public setCombineIds(ids: string[]): void { public async setCombineIds(ids: string[]): Promise<void> {
this.state.combineIds = ids; this.state.combineIds = ids;
} }
@ -209,7 +228,7 @@ class CodeBlock extends BaseService {
* @param {string[]} codeIds id数组 * @param {string[]} codeIds id数组
* @returns {void} * @returns {void}
*/ */
public setCompRelation(compId: number | string, codeIds: string[]) { public async setCompRelation(compId: number | string, codeIds: string[]) {
if (!compId) return; if (!compId) return;
this.state.compRelation = { this.state.compRelation = {
[compId]: codeIds, [compId]: codeIds,
@ -237,7 +256,7 @@ class CodeBlock extends BaseService {
* @param {string[]} codeIds id数组 * @param {string[]} codeIds id数组
* @returns {void} * @returns {void}
*/ */
public setUndeleteableList(codeIds: string[]): void { public async setUndeleteableList(codeIds: string[]): Promise<void> {
this.state.undeletableList = codeIds; this.state.undeletableList = codeIds;
} }
@ -246,10 +265,10 @@ class CodeBlock extends BaseService {
* @param {string[]} codeIds id数组 * @param {string[]} codeIds id数组
* @returns {CodeBlockDSL} code dsl * @returns {CodeBlockDSL} code dsl
*/ */
public deleteCodeDslByIds(codeIds: string[]): CodeBlockDSL { public async deleteCodeDslByIds(codeIds: string[]): Promise<CodeBlockDSL> {
const currentDsl = this.getCodeDsl(); const currentDsl = await this.getCodeDsl();
const newDsl = omit(currentDsl, codeIds); const newDsl = omit(currentDsl, codeIds);
this.setCodeDsl(newDsl); await this.setCodeDsl(newDsl);
return newDsl; return newDsl;
} }
@ -257,13 +276,13 @@ class CodeBlock extends BaseService {
* id * id
* @returns {string} 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 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); const existedIds = keys(dsl);
if (!existedIds.includes(newId)) return newId; if (!existedIds.includes(newId)) return newId;
return this.getUniqueId(); return await this.getUniqueId();
} }
public destroy() { public destroy() {

View File

@ -19,7 +19,7 @@
import { reactive, toRaw } from 'vue'; import { reactive, toRaw } from 'vue';
import { cloneDeep, mergeWith, uniq } from 'lodash-es'; 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 { NodeType } from '@tmagic/schema';
import StageCore from '@tmagic/stage'; import StageCore from '@tmagic/stage';
import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils'; import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils';
@ -80,6 +80,8 @@ class Editor extends BaseService {
'undo', 'undo',
'redo', 'redo',
'highlight', 'highlight',
'getCodeDsl',
'setCodeDsl',
], ],
// 需要注意循环依赖问题,如果函数间有相互调用的话,不能设置为串行调用 // 需要注意循环依赖问题,如果函数间有相互调用的话,不能设置为串行调用
['select', 'update', 'moveLayer'], ['select', 'update', 'moveLayer'],
@ -760,6 +762,26 @@ class Editor extends BaseService {
this.get<Map<Id, Id>>('modifiedNodeIds').clear(); 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) { private addModifiedNodeId(id: Id) {
if (!this.isHistoryStateChange) { if (!this.isHistoryStateChange) {
this.get<Map<Id, Id>>('modifiedNodeIds').set(id, id); this.get<Map<Id, Id>>('modifiedNodeIds').set(id, id);

View File

@ -233,8 +233,8 @@ export const fillConfig = (config: FormConfig = []) => [
labelWidth: '100px', labelWidth: '100px',
selectConfig: { selectConfig: {
multiple: true, multiple: true,
options: () => { options: async () => {
const codeDsl = codeBlockService.getCodeDsl(); const codeDsl = await codeBlockService.getCodeDsl();
if (codeDsl) { if (codeDsl) {
return map(codeDsl, (value, key) => ({ return map(codeDsl, (value, key) => ({
text: `${value.name}${key}`, text: `${value.name}${key}`,

View File

@ -68,8 +68,20 @@ export interface MApp extends MComponent {
type: NodeType.ROOT; type: NodeType.ROOT;
/** */ /** */
items: MPage[]; items: MPage[];
/** 代码块 */
method: CodeBlockDSL;
} }
export interface CodeBlockDSL {
[id: string]: CodeBlockContent;
}
export interface CodeBlockContent {
/** 代码块名称 */
name: string;
/** 代码块内容 */
content: string;
}
export interface PastePosition { export interface PastePosition {
left?: number; left?: number;
top?: number; top?: number;

View File

@ -20,6 +20,14 @@ export default {
id: '75f0extui9d7yksklx27hff8xg', id: '75f0extui9d7yksklx27hff8xg',
name: 'test', name: 'test',
type: 'app', type: 'app',
method: {
l7znj1q24wilb357ay6: {
name: 'getData',
content: () => {
console.log('this is getData function');
},
},
},
items: [ items: [
{ {
type: 'page', type: 'page',