diff --git a/packages/er-design/src/views/er-design-view/er-design-view.engine.ts b/packages/er-design/src/views/er-design-view/er-design-view.engine.ts index d39852d72587c558d303c2a397f2b2cd2759005f..15b3c95cf071e761baf193036288528df5767f15 100644 --- a/packages/er-design/src/views/er-design-view/er-design-view.engine.ts +++ b/packages/er-design/src/views/er-design-view/er-design-view.engine.ts @@ -1,15 +1,24 @@ import { EditFormService, IDataEntity, + IPanelItemCoopPosController, SysUIActionTag, ViewEngineBase, + ViewMode, + calcDeCodeNameById, convertNavData, getControl, } from '@ibiz-template/runtime'; import { IDEEditForm } from '@ibiz/model-core'; -import { RuntimeModelError } from '@ibiz-template/core'; +import { + IHttpResponse, + IMarkOpenData, + IPortalMessage, + RuntimeModelError, +} from '@ibiz-template/core'; import { NavPosController } from '@ibiz-template/vue3-util'; import { ERDesignViewController } from './er-design-view.controller'; +import { ERDesignContentController } from '../../panel-items/er_design_content/er-design-content.controller'; /** * ER 设计视图引擎 @@ -72,6 +81,30 @@ export class ERDesignViewEngine extends ViewEngineBase { */ protected service!: EditFormService; + /** + * 协同消息占位控制器 + * + * @readonly + * @type {(IPanelItemCoopPosController | undefined)} + * @memberof ERDesignViewEngine + */ + get coopPos(): IPanelItemCoopPosController | undefined { + return this.view.layoutPanel?.panelItems + .coop_pos as IPanelItemCoopPosController; + } + + /** + * 设计区 + * + * @readonly + * @type {(ERDesignContentController | undefined)} + * @memberof ERDesignViewEngine + */ + get erDesignContent(): ERDesignContentController | undefined { + return this.view.layoutPanel?.panelItems + .er_design_content as ERDesignContentController; + } + /** * 视图初始化 * @@ -111,6 +144,28 @@ export class ERDesignViewEngine extends ViewEngineBase { await this.load(); } + /** + * 监听实体数据变更 + * + * @protected + * @param {IPortalMessage} msg + * @memberof ERDesignViewEngine + */ + protected onDEDataChange(msg: IPortalMessage): void { + // 右侧引用视图名集合 + const refViewNames = this.view.model.viewLayoutPanel!.appViewRefs?.map( + ref => ref.refAppViewId?.split('.')[1], + ); + const viewName = msg.triggerKey?.split('@')[0]; + // 如果引用视图的数据发生变更 + if (refViewNames?.includes(viewName?.toLowerCase())) { + const deName = calcDeCodeNameById(this.form.appDataEntityId!); + const srfkey = this.view.state.data.srfkey; + // 发送更新通知 + ibiz.markOpenData.action(deName, srfkey, 'UPDATE'); + } + } + /** * 视图挂载 * @@ -127,11 +182,90 @@ export class ERDesignViewEngine extends ViewEngineBase { ); this.navPos = this.view.layoutPanel!.panelItems.nav_pos as NavPosController; this.activeRoot(); + this.initMarkOpenData(); this.view.evt.emit('onViewInfoChange', { dataInfo: this.view.state.data.srfmajortext || '', }); } + /** + * 初始化标记打开数据相关逻辑 + * + * @return {*} {void} + * @memberof ERDesignViewEngine + */ + async initMarkOpenData(): Promise { + // 非路由的编辑视图不需要触发(防止多个界面同时操作一条数据,消息重复) + if ( + ![ViewMode.ROUTE, ViewMode.ROUTE_MODAL].includes(this.view.modal.mode) || + !this.coopPos + ) { + return; + } + // 初始化协同编辑占位消息模式 - 显示操作人员 + this.coopPos.initMessageModes(['DISPLAYOPPERSON']); + + this.onDEDataChange = this.onDEDataChange.bind(this); + ibiz.mc.command.change.on(this.onDEDataChange); + + const deName = calcDeCodeNameById(this.form.appDataEntityId!); + const srfkey = this.view.state.data.srfkey; + + const callback = (data: IMarkOpenData): void => { + this.coopPos?.updateMessage({ + data, + }); + }; + + // 发送查看通知 + const result = (await ibiz.markOpenData.action( + deName, + srfkey, + 'VIEW', + )) as IHttpResponse; + + if (result.ok && result.data.length > 0) { + result.data.forEach(item => { + if (item.data) { + this.coopPos?.updateMessage({ + data: item.data, + }); + } + }); + } + + // 监听消息 + ibiz.markOpenData.subscribe(deName, srfkey, callback); + + // 销毁监听 + this.view.evt.on('onDestroyed', () => { + ibiz.mc.command.change.off(this.onDEDataChange); + ibiz.markOpenData.unsubscribe(deName, srfkey, callback); + }); + + // 发送关闭通知 + this.view.evt.on('onCloseView', () => { + ibiz.markOpenData.action(deName, srfkey, 'CLOSE'); + }); + + // 设计区值变更发送更新通知 + this.erDesignContent?.x6.evt.onAll(eventName => { + if ( + [ + 'onNodeCreated', + 'onNodeUpdated', + 'onNodeRemoved', + 'onLinkCreated', + 'onLinkUpdated', + 'onLinkRemoved', + 'onVerticesChange', + ].includes(eventName) + ) { + ibiz.markOpenData.action(deName, srfkey, 'UPDATE'); + } + }); + } + /** * 选中数据 * diff --git a/packages/er-design/src/x6/controller/x6-controller/x6-controller.event.ts b/packages/er-design/src/x6/controller/x6-controller/x6-controller.event.ts index c6f8873380798b0d7cb120264519f1c487f9499f..cafbf2ebdd159904c7094d60571e97e3b38a2772 100644 --- a/packages/er-design/src/x6/controller/x6-controller/x6-controller.event.ts +++ b/packages/er-design/src/x6/controller/x6-controller/x6-controller.event.ts @@ -14,6 +14,10 @@ export interface X6ControllerEvent extends IComponentEvent { event: EventBase; emitArgs: IData; }; + onNodeUpdated: { + event: EventBase; + emitArgs: IData; + }; onNodeRemoved: { event: EventBase; emitArgs: X6NodeData; @@ -22,6 +26,10 @@ export interface X6ControllerEvent extends IComponentEvent { event: EventBase; emitArgs: IData; }; + onLinkUpdated: { + event: EventBase; + emitArgs: IData; + }; onLinkRemoved: { event: EventBase; emitArgs: IData; diff --git a/packages/er-design/src/x6/controller/x6-node-controller/x6-node-controller.ts b/packages/er-design/src/x6/controller/x6-node-controller/x6-node-controller.ts index 84bb2e67e8aad4b49f32731ba13216ecc4432517..c23c1f6daba80fb9f4741dc73224b23b53267861 100644 --- a/packages/er-design/src/x6/controller/x6-node-controller/x6-node-controller.ts +++ b/packages/er-design/src/x6/controller/x6-node-controller/x6-node-controller.ts @@ -281,6 +281,7 @@ export class X6NodeController extends X6CellController { ); if (result) { node.position(result.leftPos, result.topPos); + this.x6.evt.emit('onNodeUpdated', nodeData); } }