diff --git a/src/control/dashboard/portlet/portlet-part/portlet-part.controller.ts b/src/control/dashboard/portlet/portlet-part/portlet-part.controller.ts index ceaec9e509384e9a8efd777ea151250efaf24638..09c1bd242b42b02075f6f6a487115b2ad293918b 100644 --- a/src/control/dashboard/portlet/portlet-part/portlet-part.controller.ts +++ b/src/control/dashboard/portlet/portlet-part/portlet-part.controller.ts @@ -1,6 +1,8 @@ import { ButtonContainerState, + calcDynaClass, calcLayoutHeightWidth, + ControlVO, IDashboardController, IPortletContainerController, IPortletController, @@ -8,6 +10,7 @@ import { UIActionUtil, } from '@ibiz-template/runtime'; import { IDBPortletPart, IUIActionGroupDetail } from '@ibiz/model-core'; +import { useNamespace } from '@ibiz-template/vue3-util'; import { PortletPartState } from './portlet-part.state'; /** @@ -74,6 +77,17 @@ export class PortletPartController return this.dashboard.params; } + /** + * 获取容器类名集合 + * @author lxm + * @date 2023-08-02 06:06:12 + * @readonly + * @type {string[]} + */ + get containerClass(): string[] { + return [...this.state.class.container, ...this.state.class.containerDyna]; + } + /** * Creates an instance of PortletPartController. * @author lxm @@ -106,7 +120,7 @@ export class PortletPartController protected async onInit(): Promise { // 初始化布局参数 - const { layoutPos, sysCss, portletType } = this.model; + const { layoutPos, portletType, sysCss } = this.model; // 初始化高宽 if (layoutPos) { @@ -116,12 +130,14 @@ export class PortletPartController } // 给col添加各自类型的类名 - this.state.layout.extraClass = `ibiz-portlet-col__${portletType!.toLowerCase()} `; - if (sysCss) { - this.state.layout.extraClass = sysCss.cssName!; + const ns = useNamespace('portlet-col'); + this.state.layout.extraClass.push(ns.m(portletType!.toLowerCase())); + + if (sysCss?.cssName) { + this.state.class.container.push(sysCss.cssName); } - this.initActionStates(); + await this.initActionStates(); } /** @@ -138,10 +154,11 @@ export class PortletPartController /** * 初始化标题右侧界面行为按钮的状态 * - * @author lxm - * @date 2022-09-07 21:09:43 + * @author chitanda + * @date 2023-08-02 17:08:04 + * @return {*} {Promise} */ - async initActionStates() { + async initActionStates(): Promise { // 操作列按钮状态控制 const { uiactionGroup } = this.model; if (!uiactionGroup?.uiactionGroupDetails?.length) { @@ -161,6 +178,20 @@ export class PortletPartController }); await containerState.update(); this.state.actionGroupState = containerState; + + // 实体门户视图监听视图数据变更,刷新界面行为组的状态。 + const { appDataEntityId } = this.dashboard.view.model; + if (appDataEntityId) { + this.dashboard.view.evt.on('onDataChange', event => { + let data = event.data[0]; + if (data && data instanceof ControlVO) { + data = data.getOrigin(); + } + if (data) { + this.state.actionGroupState!.update(data, appDataEntityId); + } + }); + } } /** @@ -186,4 +217,37 @@ export class PortletPartController event, }); } + + /** + * 表单数据变更通知(由表单控制器调用) + * + * @author lxm + * @date 2022-09-20 18:09:56 + * @param {string[]} names + */ + async dataChangeNotify(data: IData): Promise { + // 计算界面行为组状态 + if (this.state.actionGroupState) { + const { appDataEntityId } = this.dashboard.view.model; + this.state.actionGroupState.update(data, appDataEntityId); + } + + // 计算动态样式表 + this.calcDynaClass(data); + } + + /** + * 计算动态样式表 + * @author lxm + * @date 2023-08-02 06:15:08 + * @param {IData} data + */ + protected calcDynaClass(data: IData): void { + if (this.model.dynaClass) { + const dynaClass = calcDynaClass(this.model.dynaClass, data); + if (dynaClass.length) { + this.state.class.containerDyna = dynaClass; + } + } + } } diff --git a/src/control/dashboard/portlet/portlet-part/portlet-part.state.ts b/src/control/dashboard/portlet/portlet-part/portlet-part.state.ts index b24a0161f94b50fa0e51149fbbe9e6fae7e8b673..4ee67df33edd88617a2480974ee03c8d3b078bbc 100644 --- a/src/control/dashboard/portlet/portlet-part/portlet-part.state.ts +++ b/src/control/dashboard/portlet/portlet-part/portlet-part.state.ts @@ -1,6 +1,7 @@ import { IButtonContainerState, ILayoutState, + IPortletClass, IPortletState, } from '@ibiz-template/runtime'; @@ -19,10 +20,15 @@ export class PortletPartState implements IPortletState { width: '', height: '', extraStyle: {}, - extraClass: '', + extraClass: [], contentStyle: {}, }; + class: IPortletClass = { + container: [], + containerDyna: [], + }; + /** * 界面行为组状态 * diff --git a/src/control/data-view/data-view.controller.ts b/src/control/data-view/data-view.controller.ts index 574fdce1ca4d5de4fe7dd08884c6f59091300e54..514143c342398ca65e51fb5adeb58ae00f21ce03 100644 --- a/src/control/data-view/data-view.controller.ts +++ b/src/control/data-view/data-view.controller.ts @@ -7,7 +7,7 @@ import { ButtonContainerState, UIActionButtonState, UIActionUtil, - IDataViewControlGroupState, + IMDControlGroupState, CodeListItem, MDCtrlLoadParams, } from '@ibiz-template/runtime'; @@ -202,7 +202,7 @@ export class DataViewControlController children.push(item); childrenMap.set(item[groupAppDEFieldId], children); }); - const groups: IDataViewControlGroupState[] = []; + const groups: IMDControlGroupState[] = []; childrenMap.forEach((value: IData[], key: string) => { groups.push({ caption: key, @@ -222,7 +222,7 @@ export class DataViewControlController const { groupAppDEFieldId, groupCodeListId } = this.model; if (groupAppDEFieldId && groupCodeListId) { const { items } = this.state; - const groups: IDataViewControlGroupState[] = []; + const groups: IMDControlGroupState[] = []; const app = ibiz.hub.getApp(this.context.srfappid); const codeList = await app.codeList.get( groupCodeListId, diff --git a/src/control/drtab/drtab.controller.ts b/src/control/drtab/drtab.controller.ts index 748ca86f76e8fbdeefc3c3d068cbaa33eba33c6e..70ab5e0f6cc289bc072d707ff76021acf45bb83b 100644 --- a/src/control/drtab/drtab.controller.ts +++ b/src/control/drtab/drtab.controller.ts @@ -7,12 +7,12 @@ import { calcNavParams, IEditView3State, calcDeCodeNameById, + IEditFormController, } from '@ibiz-template/runtime'; import { getNestedRoutePath } from '@ibiz-template/vue3-util'; import { IDEDRCtrlItem, IDEDRTab } from '@ibiz/model-core'; import { Router } from 'vue-router'; import { NavPosController } from '../../panel-component'; -import { ViewLayoutPanelController } from '../panel'; /** * 数据关系栏控制器 @@ -27,23 +27,23 @@ export class DRTabController implements IDRTabController { /** - * 视图布局面板 + * 导航占位控制器 * * @readonly * @memberof DRTabController */ - get layoutPanel() { - return this.view.getController('layoutpanel') as ViewLayoutPanelController; + get navPos() { + return this.layoutPanel?.panelItems.nav_pos as NavPosController; } /** - * 导航占位控制器 + * 表单部件 * * @readonly * @memberof DRTabController */ - get navPos() { - return this.layoutPanel?.panelItems.nav_pos as NavPosController; + get form() { + return this.view.getController('form') as IEditFormController; } /** @@ -90,6 +90,16 @@ export class DRTabController } } + /** + * 获取数据 + * + * @return {*} {IData[]} + * @memberof DRTabController + */ + getData(): IData[] { + return this.form?.getData() || [{}]; + } + /** * 初始化state的属性 * diff --git a/src/control/form/form-detail/form-detail/form-detail.controller.ts b/src/control/form/form-detail/form-detail/form-detail.controller.ts index c869c8d3e603cf7444e534ca508eec287572b39f..9622e7600b93f510d936e78dfbf7da7ccb4d5aa6 100644 --- a/src/control/form/form-detail/form-detail/form-detail.controller.ts +++ b/src/control/form/form-detail/form-detail/form-detail.controller.ts @@ -5,8 +5,10 @@ import { verifyFormGroupLogic, IFormDetailController, IFormDetailContainerController, + calcDynaClass, } from '@ibiz-template/runtime'; import { IDEFormDetail } from '@ibiz/model-core'; +import { useNamespace } from '@ibiz-template/vue3-util'; import { FormController } from '../../form/form.controller'; import { FormDetailState } from './form-detail.state'; @@ -56,10 +58,32 @@ export class FormDetailController * @date 2022-09-01 22:09:48 * @readonly */ - get data() { + get data(): IData { return this.form.data; } + /** + * 获取容器类名集合 + * @author lxm + * @date 2023-08-02 06:06:12 + * @readonly + * @type {string[]} + */ + get containerClass(): string[] { + return [...this.state.class.container, ...this.state.class.containerDyna]; + } + + /** + * 获取标题类名集合 + * @author lxm + * @date 2023-08-02 06:16:48 + * @readonly + * @type {string[]} + */ + get labelClass(): string[] { + return [...this.state.class.label, ...this.state.class.labelDyna]; + } + /** * Creates an instance of FormDetailController. * @author lxm @@ -92,7 +116,7 @@ export class FormDetailController this.state.showMoreMode = this.model.showMoreMode!; // 初始化布局参数 - const { layoutPos, sysCss, detailType } = this.model; + const { layoutPos, detailType, sysCss, labelSysCss } = this.model; // 初始化高宽 if (layoutPos) { @@ -102,9 +126,15 @@ export class FormDetailController } // 给col添加各自类型的类名 - this.state.layout.extraClass = `ibiz-form-col__${detailType!.toLowerCase()} `; - if (sysCss) { - this.state.layout.extraClass = sysCss.cssName!; + const ns = useNamespace('panel-col'); + this.state.layout.extraClass.push(ns.m(detailType!.toLowerCase())); + + if (sysCss?.cssName) { + this.state.class.container.push(sysCss.cssName); + } + + if (labelSysCss?.cssName) { + this.state.class.label.push(labelSysCss.cssName); } } @@ -130,6 +160,9 @@ export class FormDetailController async dataChangeNotify(names: string[]): Promise { // 计算动态控制逻辑 this.calcDynamicLogic(names); + + // 计算动态样式表 + this.calcDynaClass(this.data); } /** @@ -141,6 +174,9 @@ export class FormDetailController async formStateNotify(state: FormNotifyState): Promise { // 计算动态控制逻辑 this.calcDynamicLogic([], state); + + // 计算动态样式表 + this.calcDynaClass(this.data); } /** @@ -199,4 +235,25 @@ export class FormDetailController // 在界面数据发生变更时,会调用此方法。 // 可外部覆盖实例的此方法,实现自定义的数据更新逻辑。 } + + /** + * 计算动态样式表 + * @author lxm + * @date 2023-08-02 06:15:08 + * @param {IData} data + */ + protected calcDynaClass(data: IData): void { + if (this.model.dynaClass) { + const dynaClass = calcDynaClass(this.model.dynaClass, data); + if (dynaClass.length) { + this.state.class.containerDyna = dynaClass; + } + } + if (this.model.labelDynaClass) { + const dynaClass = calcDynaClass(this.model.labelDynaClass, data); + if (dynaClass.length) { + this.state.class.labelDyna = dynaClass; + } + } + } } diff --git a/src/control/form/form-detail/form-detail/form-detail.state.ts b/src/control/form/form-detail/form-detail/form-detail.state.ts index 31b3601104e6823442a6f4d40720664762400d4b..35eac1cce883dfaf512b6bba4d96902239779b5d 100644 --- a/src/control/form/form-detail/form-detail/form-detail.state.ts +++ b/src/control/form/form-detail/form-detail/form-detail.state.ts @@ -1,5 +1,6 @@ /* eslint-disable no-setter-return */ import { + IFormDetailClass, IFormDetailContainerState, IFormDetailState, ILayoutState, @@ -24,10 +25,17 @@ export class FormDetailState implements IFormDetailState { width: '', height: '', extraStyle: {}, - extraClass: '', + extraClass: [], contentStyle: {}, }; + class: IFormDetailClass = { + container: [], + containerDyna: [], + label: [], + labelDyna: [], + }; + /** * 是否必填 * diff --git a/src/control/panel/panel/panel-item.controller.ts b/src/control/panel/panel/panel-item.controller.ts index 6fecd152aa723bb3f5ebcb960050f791ae852bb1..83ac773607e1a8b6643f42c91dca8c4e17eaf865 100644 --- a/src/control/panel/panel/panel-item.controller.ts +++ b/src/control/panel/panel/panel-item.controller.ts @@ -4,8 +4,12 @@ import { PanelNotifyState, verifyPanelGroupLogic, IPanelItemController, + IPanelController, + IPanelDataContainerController, + calcDynaClass, } from '@ibiz-template/runtime'; import { IPanelItem } from '@ibiz/model-core'; +import { useNamespace } from '@ibiz-template/vue3-util'; import { PanelItemState } from './panel-item.state'; import { PanelController } from './panel.controller'; @@ -21,6 +25,50 @@ export class PanelItemController */ state: PanelItemState; + /** + * 数据父容器 + * @author lxm + * @date 2023-07-15 11:35:18 + * @readonly + * @type {(IPanelController | IPanelDataContainerController)} + */ + get dataParent(): IPanelController | IPanelDataContainerController { + return this.findDataParent(this); + } + + /** + * 父容器数据对象数据 + * @author lxm + * @date 2023-07-15 01:33:58 + * @readonly + * @type {IData} + */ + get data(): IData { + return this.dataParent.data; + } + + /** + * 获取容器类名集合 + * @author lxm + * @date 2023-08-02 06:06:12 + * @readonly + * @type {string[]} + */ + get containerClass(): string[] { + return [...this.state.class.container, ...this.state.class.containerDyna]; + } + + /** + * 获取标题类名集合 + * @author lxm + * @date 2023-08-02 06:16:48 + * @readonly + * @type {string[]} + */ + get labelClass(): string[] { + return [...this.state.class.label, ...this.state.class.labelDyna]; + } + /** * Creates an instance of PanelItemController. * @author lxm @@ -50,7 +98,7 @@ export class PanelItemController protected async onInit(): Promise { // 初始化布局参数 - const { layoutPos, sysCss, itemType } = this.model; + const { layoutPos, itemType, sysCss, labelSysCss } = this.model; // 初始化高宽 if (layoutPos) { @@ -60,9 +108,15 @@ export class PanelItemController } // 给col添加各自类型的类名 - this.state.layout.extraClass = `ibiz-panel-col__${itemType!.toLowerCase()} `; + const ns = useNamespace('panel-col'); + this.state.layout.extraClass.push(ns.m(itemType!.toLowerCase())); + if (sysCss?.cssName) { - this.state.layout.extraClass = sysCss.cssName; + this.state.class.container.push(sysCss.cssName); + } + + if (labelSysCss?.cssName) { + this.state.class.label.push(labelSysCss.cssName); } } @@ -88,6 +142,9 @@ export class PanelItemController dataChangeNotify(names: string[]): void { // 计算动态控制逻辑 this.calcDynamicLogic(names); + + // 计算动态样式表 + this.calcDynaClass(this.data); } /** @@ -99,6 +156,9 @@ export class PanelItemController panelStateNotify(_state: PanelNotifyState): void { // 计算动态控制逻辑 this.calcDynamicLogic([], true); + + // 计算动态样式表 + this.calcDynaClass(this.data); } /** @@ -146,4 +206,45 @@ export class PanelItemController } }); } + + /** + * 找到指定成员的数据父容器 + * @author lxm + * @date 2023-07-15 11:26:49 + * @param {IPanelItemController} panel + * @return {*} {(IPanelController | IPanelDataContainerController)} + */ + findDataParent( + panel: IPanelItemController, + ): IPanelController | IPanelDataContainerController { + const parent = panel.parent; + if (!parent) { + return panel.panel; + } + if (parent.isDataContainer) { + return parent as IPanelDataContainerController; + } + return this.findDataParent(parent); + } + + /** + * 计算动态样式表 + * @author lxm + * @date 2023-08-02 06:15:08 + * @param {IData} data + */ + protected calcDynaClass(data: IData): void { + if (this.model.dynaClass) { + const dynaClass = calcDynaClass(this.model.dynaClass, data); + if (dynaClass.length) { + this.state.class.containerDyna = dynaClass; + } + } + if (this.model.labelDynaClass) { + const dynaClass = calcDynaClass(this.model.labelDynaClass, data); + if (dynaClass.length) { + this.state.class.labelDyna = dynaClass; + } + } + } } diff --git a/src/control/panel/panel/panel-item.state.ts b/src/control/panel/panel/panel-item.state.ts index b06f8577be563c5fe85125010d18c92ebe2910d7..0178fa29d10899969d8a6abba25e38b694fb9118 100644 --- a/src/control/panel/panel/panel-item.state.ts +++ b/src/control/panel/panel/panel-item.state.ts @@ -1,4 +1,8 @@ -import { ILayoutState, IPanelItemState } from '@ibiz-template/runtime'; +import { + ILayoutState, + IPanelItemClass, + IPanelItemState, +} from '@ibiz-template/runtime'; /** * 面板成员状态 @@ -19,10 +23,17 @@ export class PanelItemState implements IPanelItemState { width: '', height: '', extraStyle: {}, - extraClass: '', + extraClass: [], contentStyle: {}, }; + class: IPanelItemClass = { + container: [], + containerDyna: [], + label: [], + labelDyna: [], + }; + /** * 是否必填 * diff --git a/src/control/panel/view-layout-panel/view-layout-panel.controller.ts b/src/control/panel/view-layout-panel/view-layout-panel.controller.ts index 378433843aabd5b0f5a8300cb730bb3ee5f4765d..c8466853f166425e85842c009b7c63188920ff0f 100644 --- a/src/control/panel/view-layout-panel/view-layout-panel.controller.ts +++ b/src/control/panel/view-layout-panel/view-layout-panel.controller.ts @@ -1,9 +1,7 @@ import { - EventBase, IViewLayoutPanelController, IViewLayoutPanelEvent, IViewLayoutPanelState, - ViewLogicDispatcher, } from '@ibiz-template/runtime'; import { IPanelContainer, @@ -29,57 +27,9 @@ export class ViewLayoutPanelController > implements IViewLayoutPanelController { - /** - * 视图逻辑的事件调度分发器 - * @author lxm - * @date 2023-03-23 08:15:02 - * @type {ViewLogicDispatcher} - */ - logicDispatcher!: ViewLogicDispatcher; - - /** - * 视图打开方式(默认路由) - * @author lxm - * @date 2023-03-28 08:08:49 - * @readonly - */ - get viewMode() { - return this.ctx.view.modal.mode; - } - protected async onCreated(): Promise { this.preprocessModel(); await super.onCreated(); - const { appViewLogics } = this.model; - this.logicDispatcher = new ViewLogicDispatcher( - this.context, - this.params, - this.view, - ); - if (appViewLogics?.length) { - await this.logicDispatcher.init(appViewLogics); - } - - // 监听视图事件 - this.ctx.view.evt.onAll((_name, event) => { - return this.logicDispatcher.view.fire(event); - }); - } - - async onDestroyed(): Promise { - await super.onDestroyed(); - this.logicDispatcher.destroy(); - } - - /** - * 监听所有部件的事件 - * @author lxm - * @date 2023-03-28 07:53:38 - * @param {EventBase} event - * @return {*} {Promise} - */ - onCtrlEvent(event: EventBase): Promise { - return this.logicDispatcher.ctrl.fire(event); } /** @@ -102,6 +52,12 @@ export class ViewLayoutPanelController children.push(item); } }); + // 过滤深层的子成员 + children.forEach(item => { + if (item.itemType === 'CONTAINER') { + this.preprocessModel(item); + } + }); return children; }; diff --git a/src/control/tab-exp-panel/tab-exp-panel.controller.ts b/src/control/tab-exp-panel/tab-exp-panel.controller.ts index 41f860e088ace6b4a70d1ec6e528fb9e1968cc59..ad2294dc0f1b2b54ca675274e27e004eb1386fc1 100644 --- a/src/control/tab-exp-panel/tab-exp-panel.controller.ts +++ b/src/control/tab-exp-panel/tab-exp-panel.controller.ts @@ -9,7 +9,7 @@ import { } from '@ibiz-template/runtime'; import { IDER1N, IDETabViewPanel, ITabExpPanel } from '@ibiz/model-core'; import { NavPosController } from '../../panel-component'; -import { ViewLayoutPanelController } from '../panel'; + import { NavViewMsg } from '../../panel-component/nav-pos/nav-pos.state'; /** @@ -24,14 +24,6 @@ export class TabExpPanelController extends ControlController implements ITabExpPanelController { - /** - * 布局面板控制器 - * - * @type {ViewLayoutPanelController} - * @memberof TabExpPanelController - */ - layoutPanel!: ViewLayoutPanelController; - /** * 导航占位控制器 * @@ -40,7 +32,7 @@ export class TabExpPanelController * @memberof TabExpPanelController */ get navPos(): NavPosController | undefined { - return this.layoutPanel.panelItems.nav_pos as NavPosController; + return this.view.layoutPanel?.panelItems.nav_pos as NavPosController; } /** @@ -64,9 +56,8 @@ export class TabExpPanelController */ async onCreated(): Promise { await super.onCreated(); - this.layoutPanel = this.view.getController( - 'layoutpanel', - ) as ViewLayoutPanelController; + this.layoutPanel = this.view.layoutPanel!; + this.initTabPages(); } @@ -82,6 +73,7 @@ export class TabExpPanelController tabPages.push({ caption: panel.caption!, tabTag: panel.id!, + class: panel.sysCss ? [panel.sysCss.cssName!] : [], }); }); this.state.tabPages = tabPages; diff --git a/src/control/tree/tree.controller.ts b/src/control/tree/tree.controller.ts index fbdfb1fdd0845b84db1df62852b1319e0f4f6ed1..a6977d1e782661b9606bfe20515a4f719d008dd0 100644 --- a/src/control/tree/tree.controller.ts +++ b/src/control/tree/tree.controller.ts @@ -1,4 +1,5 @@ /* eslint-disable no-param-reassign */ +import { recursiveIterate } from '@ibiz-template/core'; import { MDControlController, ITreeEvent, @@ -8,8 +9,17 @@ import { TreeStaticNodeData, getRootNode, MDCtrlLoadParams, + UIActionUtil, + UIActionButtonState, + ButtonContainerState, } from '@ibiz-template/runtime'; -import { IDETree } from '@ibiz/model-core'; +import { + IDEContextMenu, + IDETBUIActionItem, + IDEToolbarItem, + IDETree, + IDETreeNode, +} from '@ibiz/model-core'; import { TreeService } from './tree.service'; /** @@ -35,13 +45,22 @@ export class TreeController undefined, { leaf: false }, ); + this.state.expandedKeys = []; this.state.size = 0; + this.state.contextMenus = {}; } protected async onCreated(): Promise { await super.onCreated(); this.service = new TreeService(this.model); await this.service.init(this.context); + + // 初始化上下文菜单状态 + this.model.detreeNodes!.forEach(node => { + if (node.decontextMenu?.detoolbarItems?.length) { + this.initContextMenuState(node.decontextMenu); + } + }); } /** @@ -50,15 +69,21 @@ export class TreeController * @author lxm * @date 2022-08-19 14:08:50 */ - async load(args?: MDCtrlLoadParams): Promise { - const isInitialLoad = args?.isInitialLoad === true; - const datas = (await this.loadNodes(undefined)) || []; - // await this.afterLoad(datas); + async load(args: MDCtrlLoadParams = {}): Promise { + const isInitialLoad = args.isInitialLoad === true; + const isLoadMore = args.isLoadMore === true; + const nodes = await this.loadNodes(); + await this.afterLoad(args, nodes); this.state.isLoaded = true; + if (isLoadMore) { + this.state.items.push(...nodes); + } else { + this.state.items = nodes; + } await this.evt.emit('onLoadSuccess', { isInitialLoad, }); - return datas; + return nodes; } /** @@ -68,9 +93,7 @@ export class TreeController * @returns {*} * @memberof TreeController */ - async loadNodes( - parentNode: ITreeNodeData | undefined, - ): Promise { + async loadNodes(parentNode?: ITreeNodeData): Promise { const params = await this.getFetchParams(); const hasQuery = !!params.query; @@ -81,9 +104,9 @@ export class TreeController // 请求服务获取子节点数据 await this.startLoading(); - let datas; + let nodes; try { - datas = + nodes = (await this.service.fetchChildNodes(parentNode, { context: this.context.clone(), params, @@ -92,8 +115,8 @@ export class TreeController } finally { await this.endLoading(); } - parentNode.children = datas; - return datas; + parentNode.children = nodes; + return nodes; } /** @@ -105,17 +128,136 @@ export class TreeController */ async onTreeNodeClick(nodeData: ITreeNodeData): Promise { // 单选时,单击才会触发选中逻辑 - // 选中相关处理 - const { selectedData } = this.state; - // 选中里没有则添加,有则删除 - const filterArr = selectedData.filter(item => item.id !== nodeData.id); - if (filterArr.length === selectedData.length) { - this.setSelection( - this.state.singleSelect ? [nodeData] : selectedData.concat([nodeData]), - ); + if (this.state.singleSelect) { + // 选中相关处理 + const { selectedData } = this.state; + // 选中里没有则添加,有则删除 + const filterArr = selectedData.filter(item => item.id !== nodeData.id); + if (filterArr.length === selectedData.length) { + this.setSelection( + this.state.singleSelect + ? [nodeData] + : selectedData.concat([nodeData]), + ); + } else { + this.setSelection(filterArr); + } + } + + // 激活事件 + if (this.state.mdctrlActiveMode === 1) { + await this.setActive(nodeData); + } + } + + /** + * 树节点双击事件 + * @author lxm + * @date 2023-05-29 10:01:36 + * @param {ITreeNodeData} nodeData + * @return {*} {Promise} + */ + async onDbTreeNodeClick(nodeData: ITreeNodeData): Promise { + if (this.state.mdctrlActiveMode === 2) { + await this.setActive(nodeData); + } + } + + setSelection(selection: IData[]): void { + // todo 当自己点选中时,父节点选不选中,如果选中需要在这边优化 + super.setSelection(selection); + } + + /** + * 设置展开节点 + * + * @author zk + * @date 2023-07-10 08:07:29 + * @param {string[]} nodeKeys + * @param {boolean} [isReplace=false] + * @memberof TreeController + */ + setExpandedKeys(nodeKeys: string[], isReplace: boolean = false): void { + if (isReplace) { + this.state.expandedKeys = nodeKeys; } else { - this.setSelection(filterArr); + this.state.expandedKeys.push(...nodeKeys); } - await this.setActive(nodeData); + } + + /** + * 获取节点模型 + * @author lxm + * @date 2023-07-27 10:47:58 + * @param {string} id + * @return {*} {(IDETreeNode | undefined)} + */ + getNodeModel(id: string): IDETreeNode | undefined { + return this.model.detreeNodes?.find(item => item.id === id); + } + + /** + * 执行界面行为 + * @author lxm + * @date 2023-07-27 05:31:36 + * @param {string} uiActionId + * @param {ITreeNodeData} nodeData + * @param {MouseEvent} event + * @return {*} {Promise} + */ + async doUIAction( + uiActionId: string, + nodeData: ITreeNodeData, + event: MouseEvent, + ): Promise { + const eventArgs = this.getEventArgs(); + if (nodeData.context) { + eventArgs.context = Object.assign( + eventArgs.context.clone(), + nodeData.context, + ); + } + if (nodeData.params) { + eventArgs.params = { ...eventArgs.params, ...nodeData.params }; + } + await UIActionUtil.execAndResolved(uiActionId!, { + ...eventArgs, + data: [nodeData.deData || nodeData], + event, + }); + } + + /** + * 初始化上下文菜单状态 + * @author lxm + * @date 2023-08-01 04:53:32 + * @protected + * @param {IDEContextMenu} contextMenu + */ + protected initContextMenuState(contextMenu: IDEContextMenu) { + if (this.state.contextMenus[contextMenu.id!]) { + // 已创建过得就不重复创建了。 + return; + } + const menuState = new ButtonContainerState(); + // 初始化工具栏状态控制对象 + recursiveIterate( + contextMenu, + (item: IDEToolbarItem) => { + if (item.itemType === 'DEUIACTION') { + const uiItem = item as IDETBUIActionItem; + const buttonState = new UIActionButtonState( + uiItem.id!, + this.context.srfappid!, + uiItem.uiactionId!, + ); + + menuState.addState(uiItem.id!, buttonState); + } + }, + { childrenFields: ['detoolbarItems'] }, + ); + this.state.contextMenus[contextMenu.id!] = menuState; + this.state.contextMenus[contextMenu.id!].update(); } } diff --git a/src/editor/rate/ibiz-rate/ibiz-rate.tsx b/src/editor/rate/ibiz-rate/ibiz-rate.tsx index 328dc28b87e047ce26731ba5f8f69e3ad06da850..7bc7494019e67f36690f57cf390908ea6fbe452c 100644 --- a/src/editor/rate/ibiz-rate/ibiz-rate.tsx +++ b/src/editor/rate/ibiz-rate/ibiz-rate.tsx @@ -5,6 +5,7 @@ import { useFocusAndBlur, useNamespace, } from '@ibiz-template/vue3-util'; +import { toNumber } from 'lodash-es'; import { RateEditorController } from '../rate-editor.controller'; export const IBizRate = defineComponent({ @@ -24,7 +25,7 @@ export const IBizRate = defineComponent({ let max = 5; if (editorModel.editorParams) { if (editorModel.editorParams.maxvalue) { - max = c.handleStringToNumber(editorModel.editorParams.maxvalue); + max = toNumber(editorModel.editorParams.maxvalue); } } diff --git a/src/editor/slider/ibiz-slider/ibiz-slider.tsx b/src/editor/slider/ibiz-slider/ibiz-slider.tsx index c00f1718cc3122a08e451a012456914a79ee8f3f..f0c99ff22102ca2549ab7a17886256247bb3dbd7 100644 --- a/src/editor/slider/ibiz-slider/ibiz-slider.tsx +++ b/src/editor/slider/ibiz-slider/ibiz-slider.tsx @@ -5,6 +5,7 @@ import { useFocusAndBlur, useNamespace, } from '@ibiz-template/vue3-util'; +import { toNumber } from 'lodash-es'; import { SliderEditorController } from '../slider-editor.controller'; import './ibiz-slider.scss'; @@ -27,16 +28,16 @@ export const IBizSlider = defineComponent({ let range = false; if (editorModel.editorParams) { if (editorModel.editorParams.stepvalue) { - step = c.handleStringToNumber(editorModel.editorParams.stepvalue); + step = toNumber(editorModel.editorParams.stepvalue); } if (editorModel.editorParams.maxvalue) { - max = c.handleStringToNumber(editorModel.editorParams.maxvalue); + max = toNumber(editorModel.editorParams.maxvalue); } if (editorModel.editorParams.minvalue) { - min = c.handleStringToNumber(editorModel.editorParams.minvalue); + min = toNumber(editorModel.editorParams.minvalue); } if (editorModel.editorParams.range) { - range = c.handleStringToBoolean(editorModel.editorParams.range); + range = c.toBoolean(editorModel.editorParams.range); } } diff --git a/src/editor/stepper/ibiz-stepper/ibiz-stepper.tsx b/src/editor/stepper/ibiz-stepper/ibiz-stepper.tsx index 059d8ecd9b20c96b158be15aca6afb5834d528e2..d6496d3888955ebcbb2b630aad5e6d07cd88468e 100644 --- a/src/editor/stepper/ibiz-stepper/ibiz-stepper.tsx +++ b/src/editor/stepper/ibiz-stepper/ibiz-stepper.tsx @@ -4,6 +4,7 @@ import { getStepperProps, useNamespace, } from '@ibiz-template/vue3-util'; +import { toNumber } from 'lodash-es'; import { StepperEditorController } from '../stepper-editor.controller'; export const IBizStepper = defineComponent({ @@ -29,16 +30,16 @@ export const IBizStepper = defineComponent({ let min = -Infinity; if (editorModel.editorParams) { if (editorModel.editorParams.stepvalue) { - step = c.handleStringToNumber(editorModel.editorParams.stepvalue); + step = toNumber(editorModel.editorParams.stepvalue); } if (editorModel.editorParams.precision) { - precision = c.handleStringToNumber(editorModel.editorParams.precision); + precision = toNumber(editorModel.editorParams.precision); } if (editorModel.editorParams.maxvalue) { - max = c.handleStringToNumber(editorModel.editorParams.maxvalue); + max = toNumber(editorModel.editorParams.maxvalue); } if (editorModel.editorParams.minvalue) { - min = c.handleStringToNumber(editorModel.editorParams.minvalue); + min = toNumber(editorModel.editorParams.minvalue); } } diff --git a/src/view-engine/mob-edit-view.engine.ts b/src/view-engine/mob-edit-view.engine.ts index f12473cdb245fe16ca22be894058aa3c833e7ff5..0a17a17562d386bd4b54faeaa5a0a9212145e0d0 100644 --- a/src/view-engine/mob-edit-view.engine.ts +++ b/src/view-engine/mob-edit-view.engine.ts @@ -35,7 +35,7 @@ export class MobEditViewEngine extends ViewEngineBase { const { childNames, modal } = this.view; childNames.push('form'); - modal.hooks.beforeDismiss.tapPromise(async context => { + modal.hooks.shouldDismiss.tapPromise(async context => { if (this.form.state.modified) { const isAllow = await ibiz.modal.confirm({ title: '关闭提醒',