From e1380841823e55131922c742e483379563d7bd03 Mon Sep 17 00:00:00 2001 From: hisoka0728 <1399952343@qq.com> Date: Wed, 24 Jul 2024 18:16:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B7=A6=E4=BE=A7=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=8F=82=E6=95=B0=E9=85=8D=E7=BD=AE=E8=A1=8C?= =?UTF-8?q?=E4=B8=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../provider/x6-node.service.provider.ts | 10 + .../x6-panel-item-stencil.controller.ts | 282 ++++++++++++++++-- .../plugins/logic-design/custom-node/index.ts | 2 + .../custom-node/material-add-node.ts | 62 ++++ .../logic-design/custom-node/material-node.ts | 16 +- .../src/plugins/logic-design/index.scss | 15 + .../src/plugins/logic-design/node.ts | 9 + 7 files changed, 363 insertions(+), 33 deletions(-) create mode 100644 packages/antv-x6-design/src/plugins/logic-design/custom-node/material-add-node.ts diff --git a/packages/antv-x6-design/src/interface/provider/x6-node.service.provider.ts b/packages/antv-x6-design/src/interface/provider/x6-node.service.provider.ts index 995f4f37..73501b32 100644 --- a/packages/antv-x6-design/src/interface/provider/x6-node.service.provider.ts +++ b/packages/antv-x6-design/src/interface/provider/x6-node.service.provider.ts @@ -45,6 +45,16 @@ export interface X6NodeServiceProvider extends X6CellServiceProvider { */ createMaterialCell(codeItem: CodeListItem): Node.Metadata; + /** + * 创建节点素材实例 + * + * @author zhanghengfeng + * @date 2024-02-19 16:02:58 + * @param {CodeListItem} codeItem + * @return {*} {Node.Metadata} + */ + createMaterialAddCell(codeItem: CodeListItem): Node.Metadata; + /** * 过滤节点 * diff --git a/packages/antv-x6-design/src/panel-items/x6-panel-item-stencil/x6-panel-item-stencil.controller.ts b/packages/antv-x6-design/src/panel-items/x6-panel-item-stencil/x6-panel-item-stencil.controller.ts index 0cab818b..f4230a10 100644 --- a/packages/antv-x6-design/src/panel-items/x6-panel-item-stencil/x6-panel-item-stencil.controller.ts +++ b/packages/antv-x6-design/src/panel-items/x6-panel-item-stencil/x6-panel-item-stencil.controller.ts @@ -2,6 +2,7 @@ import { CodeListItem, PanelItemController, ScriptFactory, + UIActionUtil, } from '@ibiz-template/runtime'; import { IPanelField, ICodeListEditor, IAppCodeList } from '@ibiz/model-core'; import { Stencil } from '@antv/x6-plugin-stencil'; @@ -47,6 +48,224 @@ export class X6PanelItemStencilController extends PanelItemController Array.isArray(item.children) && item.children.length, + ); + } + codeListItems.forEach(item => { + if (Array.isArray(item.children)) { + item.children.forEach(child => { + if (typeof child.data === 'string') { + child.data = ScriptFactory.execSingleLine(child.data) as IData; + } + }); + } + }); + Object.keys(action).forEach((key: string) => { + const item = codeListItems.find( + i => (i.id as string).toLowerCase() === key.toLowerCase(), + ); + if (item) { + Object.assign(item, { action: action[key] }); + if (item.children) { + item.children.forEach(i => { + Object.assign(i, { action: action[key] }); + }); + } + } + }); + return codeListItems; + } + + /** + * 挂载 stencil 节点 + * + * @author fangZhiHao + * @date 2024-07-24 09:07:35 + * @param {CodeListItem[]} codeListItems + */ + public mountNodes(codeListItems: CodeListItem[]) { + codeListItems.forEach((item, index) => { + if (item.children) { + const nodes = item.children.map(codeItem => { + const node = this.x6.g.createNode( + this.provider.createMaterialCell(codeItem), + ); + return node; + }); + if (codeListItems[index]) { + const add = (codeListItems[index] as IData)?.action; + if (add?.ADD_ACTION) { + const addNode = this.x6.g.createNode( + this.provider.createMaterialAddCell({ + action: add, + data: { + psdelogicnodename: 'add', + memo: '新增', + logicnodetype: 'add', + param1: 'add', + }, + id: 'add', + sysImage: { + appId: 'metaflow__dataflowdesign', + rawContent: + '', + }, + text: '新增', + value: 'add', + } as CodeListItem), + ); + nodes.push(addNode); + } + } + this.s!.load(nodes, item.id!); + } + }); + } + + /** + * 清空分组 + * + * @author fangZhiHao + * @date 2024-07-24 09:07:59 + * @param {CodeListItem[]} codeListItems + */ + public calcGroups(codeListItems: CodeListItem[]) { + this.s?.options.groups?.forEach(item => { + this.s?.removeGroup(item.name); + }); + codeListItems.forEach(item => { + this.s?.addGroup({ + name: item.id!, + title: item.text, + graphHeight: 0, + collapsable: true, + collapsed: item.userData === 'contract', + }); + }); + } + + /** + * 设置事件 + * + * @author fangZhiHao + * @date 2024-07-24 18:07:17 + * @param {IData} action + * @param {CodeListItem[]} codeListItems + */ + setEevnt(action: IData, codeListItems: CodeListItem[]) { + setTimeout(() => { + const remove = document.querySelectorAll( + '.ibiz-material-node-delete-icon', + ); + remove.forEach((el: IData) => { + el.addEventListener( + 'mousedown', + async (event: MouseEvent) => { + const cl = el.classList?.[1]; + let uiActionId = ''; + if (cl) { + uiActionId = `${ + action[cl.toLocaleUpperCase()] && + action[cl.toLocaleUpperCase()].REMOVE_ACTION + }@psdelogic`; + } else { + return; + } + event.preventDefault(); + event.stopPropagation(); + // "add_resource@psdelogic" + await UIActionUtil.execAndResolved( + uiActionId, + { + context: this.panel.context, + params: { + panelDataParent: this.dataParent.model.id!, + ...this.panel.params, + }, + data: [this.data], + view: this.panel.view, + event, + noWaitRoute: true, + }, + this.model.appId, + ); + const { appCodeListId } = this.model.editor as ICodeListEditor; + if (appCodeListId) { + codeListItems = await this.calcCodeList(appCodeListId, action); + this.mountNodes(codeListItems); + } + this.setEevnt(action, codeListItems); + }, + { captrue: true, passive: false }, + ); + }); + const add = document.querySelectorAll('.ibiz-material-node-add-icon'); + add.forEach((el: IData) => { + el.addEventListener( + 'mousedown', + async (event: MouseEvent) => { + const cl = el.classList?.[1]; + let uiActionId = ''; + if (cl) { + uiActionId = `${ + action[cl.toLocaleUpperCase()] && + action[cl.toLocaleUpperCase()].ADD_ACTION + }@psdelogic`; + } else { + return; + } + event.preventDefault(); + event.stopPropagation(); + // "add_resource@psdelogic" + await UIActionUtil.execAndResolved( + uiActionId, + { + context: this.panel.context, + params: { + panelDataParent: this.dataParent.model.id!, + ...this.panel.params, + }, + data: [this.data], + view: this.panel.view, + event, + noWaitRoute: true, + }, + this.model.appId, + ); + const { appCodeListId } = this.model.editor as ICodeListEditor; + if (appCodeListId) { + codeListItems = await this.calcCodeList(appCodeListId, action); + this.mountNodes(codeListItems); + } + this.setEevnt(action, codeListItems); + }, + { captrue: true, passive: false }, + ); + }); + }, 4000); + } + async initStencil( container: HTMLDivElement, count: number = 0, @@ -66,32 +285,40 @@ export class X6PanelItemStencilController extends PanelItemController { + const firstUnderscoreIndex = key.indexOf('_'); + if (firstUnderscoreIndex !== -1) { + const part1 = key + .substring(0, firstUnderscoreIndex) + .toLocaleUpperCase(); + const part2 = key.substring(firstUnderscoreIndex + 1); + if (action[part1]) { + action[part1][part2] = editorParams[key]; + } else { + action[part1] = { + [part2]: editorParams[key], + id: part1, + }; + } + } + }); + if (editorParams.SHOWHEADER) { + Object.assign(action, { + showHeader: JSON.parse(editorParams.SHOWHEADER), + }); + } + } if (appCodeListId) { + // 加载代码表 并计算界面行为 const app = await ibiz.hub.getApp(this.model.appId); codeList = app.codeList.getCodeList(appCodeListId)!; - const codeItems = await app.codeList.get( - appCodeListId, - this.panel.context, - this.panel.params, - ); - codeListItems = codeItems.filter( - item => Array.isArray(item.children) && item.children.length, - ); - codeListItems.forEach(item => { - if (Array.isArray(item.children)) { - item.children.forEach(child => { - if (typeof child.data === 'string') { - child.data = ScriptFactory.execSingleLine( - child.data, - ) as IData; - } - }); - } - }); + codeListItems = await this.calcCodeList(appCodeListId, action); } } if (!codeList) { @@ -138,17 +365,8 @@ export class X6PanelItemStencilController extends PanelItemController { - if (item.children) { - const nodes = item.children.map(codeItem => { - const node = this.x6.g.createNode( - this.provider.createMaterialCell(codeItem), - ); - return node; - }); - this.s!.load(nodes, item.id!); - } - }); + this.mountNodes(codeListItems); + this.setEevnt(action, codeListItems); } else { throw new Error('X6PanelItemStencil: 初始化容器为空 not found'); } diff --git a/packages/antv-x6-design/src/plugins/logic-design/custom-node/index.ts b/packages/antv-x6-design/src/plugins/logic-design/custom-node/index.ts index 4111f9a7..814d2b59 100644 --- a/packages/antv-x6-design/src/plugins/logic-design/custom-node/index.ts +++ b/packages/antv-x6-design/src/plugins/logic-design/custom-node/index.ts @@ -1,6 +1,7 @@ import { Graph } from '@antv/x6'; import { LogicNode } from './logic-node'; import { MaterialNode } from './material-node'; +import { MaterialAddNode } from './material-add-node'; /** * 安装自定义节点 @@ -12,4 +13,5 @@ import { MaterialNode } from './material-node'; export function installCustomNode(): void { Graph.registerNode('logic-node', LogicNode, true); Graph.registerNode('material-node', MaterialNode, true); + Graph.registerNode('material-add-node', MaterialAddNode, true); } diff --git a/packages/antv-x6-design/src/plugins/logic-design/custom-node/material-add-node.ts b/packages/antv-x6-design/src/plugins/logic-design/custom-node/material-add-node.ts new file mode 100644 index 00000000..0d38a2f4 --- /dev/null +++ b/packages/antv-x6-design/src/plugins/logic-design/custom-node/material-add-node.ts @@ -0,0 +1,62 @@ +import { Node, Shape } from '@antv/x6'; +import { Namespace } from '@ibiz-template/core'; +/** + * 素材区节点呈现 + * + * @author chitanda + * @date 2023-11-24 14:11:41 + * @export + * @class MaterialNode + * @extends {Shape.Edge} + */ +export class MaterialAddNode extends Shape.Rect { + constructor(metadata: Node.Metadata = {}) { + const ns = new Namespace('material-node'); + super({ + width: 98, + height: 80, + markup: [ + { + tagName: 'foreignObject', + selector: 'foreignObject', + className: [ + ns.b('add-icon'), + metadata.data.action && metadata.data.action.id, + ], + children: [ + { + ns: 'http://www.w3.org/1999/xhtml', + tagName: 'div', + className: ns.b('container'), + attrs: { + title: metadata.label || '', + }, + children: [ + { + tagName: 'div', + className: ns.b('icon'), + selector: 'icon', + }, + { + tagName: 'div', + className: ns.b('text'), + textContent: metadata.label || '', + }, + ], + }, + ], + }, + ], + attrs: { + foreignObject: { + width: 98, + height: 80, + }, + icon: { + html: metadata.icon || '', + }, + }, + ...metadata, + }); + } +} diff --git a/packages/antv-x6-design/src/plugins/logic-design/custom-node/material-node.ts b/packages/antv-x6-design/src/plugins/logic-design/custom-node/material-node.ts index e1dcb81e..3644c063 100644 --- a/packages/antv-x6-design/src/plugins/logic-design/custom-node/material-node.ts +++ b/packages/antv-x6-design/src/plugins/logic-design/custom-node/material-node.ts @@ -1,6 +1,5 @@ import { Node, Shape } from '@antv/x6'; import { Namespace } from '@ibiz-template/core'; - /** * 素材区节点呈现 * @@ -34,6 +33,14 @@ export class MaterialNode extends Shape.Rect { className: ns.b('icon'), selector: 'icon', }, + { + tagName: 'div', + className: [ + ns.b('delete-icon'), + metadata.data?.action && metadata.data.action.id, + ], + selector: 'deleteIcon', + }, { tagName: 'div', className: ns.b('text'), @@ -52,6 +59,13 @@ export class MaterialNode extends Shape.Rect { icon: { html: metadata.icon || '', }, + deleteIcon: { + html: + // eslint-disable-next-line dot-notation + metadata.data.action && metadata.data.action.REMOVE_ACTION + ? `` + : '', + }, }, ...metadata, }); diff --git a/packages/antv-x6-design/src/plugins/logic-design/index.scss b/packages/antv-x6-design/src/plugins/logic-design/index.scss index 8ed8ec68..9d6069a9 100644 --- a/packages/antv-x6-design/src/plugins/logic-design/index.scss +++ b/packages/antv-x6-design/src/plugins/logic-design/index.scss @@ -9,6 +9,12 @@ color: #303133; text-overflow: ellipsis; white-space: nowrap; + + &:hover { + .#{bem(material-node-delete-icon)}{ + display: block; + } + } } @include b(material-node-icon) { @@ -22,6 +28,15 @@ } } +@include b(material-node-delete-icon) { + position: absolute; + top: 4px; + right: 6px; + z-index: 10; + display: none; + cursor: pointer; +} + @include b(material-node-text) { display: -webkit-box; flex: 1 0 0; diff --git a/packages/antv-x6-design/src/plugins/logic-design/node.ts b/packages/antv-x6-design/src/plugins/logic-design/node.ts index a1a0b912..9b0c95dd 100644 --- a/packages/antv-x6-design/src/plugins/logic-design/node.ts +++ b/packages/antv-x6-design/src/plugins/logic-design/node.ts @@ -181,6 +181,15 @@ export class NodeProviderImpl }; } + createMaterialAddCell(codeItem: CodeListItem): Node.Metadata { + return { + shape: 'material-add-node', + label: codeItem.text, + data: codeItem, + icon: this.getIcon(codeItem), + }; + } + validateNode(node: Node, options: Dnd.ValidateNodeOptions): boolean { const data = node.data; if (!data) { -- Gitee