From 8c6829198f56e4a16dff033ef5cdc54d0b443dfd Mon Sep 17 00:00:00 2001 From: Shine-zwj <1917095344@qq.com> Date: Wed, 31 May 2023 19:14:47 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=E6=95=B0=E6=8D=AE=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E6=A0=B7=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/control/data-view/data-view.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/control/data-view/data-view.scss b/src/control/data-view/data-view.scss index 9c762a6b..d7447457 100644 --- a/src/control/data-view/data-view.scss +++ b/src/control/data-view/data-view.scss @@ -11,7 +11,8 @@ $control-dataview: ( margin: getCssVar('control-dataview', 'margin'); padding: getCssVar('control-dataview', 'padding'); - + cursor: pointer; + &:hover { border-color: getCssVar('control-dataview', 'hover-bg-color'); } -- Gitee From 23189be17af93b4b9f134abb79361d94447087bb Mon Sep 17 00:00:00 2001 From: Shine-zwj <1917095344@qq.com> Date: Wed, 31 May 2023 19:16:01 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E6=A0=91?= =?UTF-8?q?=E9=83=A8=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/control/tree/tree.controller.ts | 1 + src/control/tree/tree.tsx | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/control/tree/tree.controller.ts b/src/control/tree/tree.controller.ts index ccc9e0ef..10dfa7b1 100644 --- a/src/control/tree/tree.controller.ts +++ b/src/control/tree/tree.controller.ts @@ -63,6 +63,7 @@ export class TreeController console.log(isInitialLoad); const datas = (await this.loadNodes(undefined)) || []; + await this.afterLoad(datas); this.state.isLoaded = true; await this.evt.emit('onLoadSuccess', { isInitialLoad: true, diff --git a/src/control/tree/tree.tsx b/src/control/tree/tree.tsx index 2461ab54..5658ab71 100644 --- a/src/control/tree/tree.tsx +++ b/src/control/tree/tree.tsx @@ -11,6 +11,24 @@ export const TreeControl = defineComponent({ modelData: { type: Object as PropType, required: true }, context: { type: Object as PropType, required: true }, params: { type: Object as PropType, default: () => ({}) }, + /** + * 部件行数据默认激活模式 + * - 0 不激活 + * - 1 单击激活 + * - 2 双击激活(默认值) + * + * @type {(number | 0 | 1 | 2)} + */ + mdctrlActiveMode: { type: Number, default: 2 }, + + /** + * 是否为单选 + * - true 单选 + * - false 多选 + * + * @type {(Boolean)} + */ + singleSelect: { type: Boolean, default: true }, }, setup() { const c = useControlController((...args) => new TreeController(...args)); -- Gitee From 15c7e2dc95c6def52474e2388e364b0ca336d494 Mon Sep 17 00:00:00 2001 From: Shine-zwj <1917095344@qq.com> Date: Wed, 31 May 2023 19:17:15 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E5=AF=BC?= =?UTF-8?q?=E8=88=AA=E5=8D=A0=E4=BD=8D=E7=BC=93=E5=AD=98=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nav-pos/nav-pos.controller.ts | 90 ++++++++----------- src/panel-component/nav-pos/nav-pos.tsx | 16 ++-- 2 files changed, 47 insertions(+), 59 deletions(-) diff --git a/src/panel-component/nav-pos/nav-pos.controller.ts b/src/panel-component/nav-pos/nav-pos.controller.ts index 15c0db5b..d2863a2f 100644 --- a/src/panel-component/nav-pos/nav-pos.controller.ts +++ b/src/panel-component/nav-pos/nav-pos.controller.ts @@ -28,6 +28,14 @@ export class NavPosController extends PanelItemController { */ viewModals: { [key: string]: IModal } = {}; + /** + * 当前导航视图 + * + * @type {NavViewMsg} + * @memberof NavPosController + */ + curNavViewMsg!: NavViewMsg; + /** * 创建导航占位状态对象 * @@ -51,58 +59,12 @@ export class NavPosController extends PanelItemController { } /** - * 路由变化 + * 路由改变 * - * @param {{ - * currentKey: string; - * fullPath: string; - * }} { - * currentKey, - * fullPath, - * } - * @return {*} * @memberof NavPosController */ - onRouteChange({ - currentKey, - fullPath, - }: { - currentKey: string; - fullPath: string; - }) { - // 比监控视图层级低的路由跳转不做处理。 - this.state.currentKey = currentKey; - if (currentKey === '') { - return; - } - - // *维护缓存 - if (!this.state.cacheKeys.includes(currentKey)) { - // 缓存里没有的,加入缓存 - this.state.cacheKeys.push(currentKey); - - // 维护每个视图的modal - if (this.routeDepth) { - this.viewModals[currentKey] = new Modal({ - mode: this.routeDepth ? ViewMode.ROUTE : ViewMode.EMBED, - routeDepth: this.routeDepth ? this.routeDepth + 1 : undefined, - dismiss: () => { - // 执行对应key的dismiss方法 - this.dismiss(currentKey); - }, - }); - } - } - - // *维护导航视图信息 - if (this.state.navViewMsgs[currentKey]) { - this.state.navViewMsgs[currentKey].fullPath = fullPath; - } else { - this.state.navViewMsgs[currentKey] = { - key: currentKey, - fullPath, - }; - } + onRouteChange() { + this.setNavViewMsg(this.curNavViewMsg); } /** @@ -132,18 +94,38 @@ export class NavPosController extends PanelItemController { * @memberof NavPosController */ openView(navViewMsg: NavViewMsg) { - // 路由打开 - if (this.routeDepth) { + if (this.state.cacheKeys.includes(navViewMsg.key)) { + this.state.currentKey = navViewMsg.key; + } else if (this.routeDepth) { + this.curNavViewMsg = navViewMsg; + this.viewModals[navViewMsg.key] = new Modal({ + mode: this.routeDepth ? ViewMode.ROUTE : ViewMode.EMBED, + routeDepth: this.routeDepth ? this.routeDepth + 1 : undefined, + dismiss: () => { + // 执行对应key的dismiss方法 + this.dismiss(navViewMsg.key); + }, + }); const tempContext = Object.assign(navViewMsg.context!.clone(), { toRouteDepth: this.routeDepth + 1, }); ibiz.openView.root(navViewMsg.viewModel!, tempContext, navViewMsg.params); - } else if (!this.state.cacheKeys.includes(navViewMsg.key)) { + return; + } + this.setNavViewMsg(navViewMsg); + } + + /** + * 设置导航视图信息 + * + * @param {NavViewMsg} navViewMsg + * @memberof NavPosController + */ + setNavViewMsg(navViewMsg: NavViewMsg) { + if (!this.state.cacheKeys.includes(navViewMsg.key)) { this.state.cacheKeys.push(navViewMsg.key); this.state.navViewMsgs[navViewMsg.key] = navViewMsg; this.state.currentKey = navViewMsg.key; - } else { - this.state.currentKey = navViewMsg.key; } } } diff --git a/src/panel-component/nav-pos/nav-pos.tsx b/src/panel-component/nav-pos/nav-pos.tsx index aee5e0ec..74f48e5f 100644 --- a/src/panel-component/nav-pos/nav-pos.tsx +++ b/src/panel-component/nav-pos/nav-pos.tsx @@ -1,8 +1,9 @@ -import { defineComponent, h, PropType, resolveComponent } from 'vue'; -import { onRouteChange, useNamespace } from '@ibiz-template/vue3-util'; +import { defineComponent, h, PropType, resolveComponent, watch } from 'vue'; +import { useNamespace } from '@ibiz-template/vue3-util'; import { IPanelRawItem } from '@ibiz/model-core'; import { NavPosController } from './nav-pos.controller'; import { EventBase } from '@ibiz-template/runtime'; +import { useRoute } from 'vue-router'; import './nav-pos.scss'; export const NavPos = defineComponent({ @@ -25,9 +26,14 @@ export const NavPos = defineComponent({ }; if (c.routeDepth) { - onRouteChange(args => { - c.onRouteChange(args); - }, c.routeDepth + 1); + const route = useRoute(); + watch( + () => route?.path, + () => { + c.onRouteChange(); + }, + { immediate: true }, + ); } return { ns, c, onViewCreated }; }, -- Gitee From 6f19a028f0d5c9cd44f4f1a6b9a3f5b1c20d7e92 Mon Sep 17 00:00:00 2001 From: Shine-zwj <1917095344@qq.com> Date: Wed, 31 May 2023 19:20:28 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E5=AF=BC?= =?UTF-8?q?=E8=88=AA=E9=83=A8=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/control/exp-bar/exp-bar.controller.ts | 2 +- src/control/exp-bar/index.ts | 4 ++ src/control/exp-bar/tree-exp-bar/index.ts | 21 ++++++ .../tree-exp-bar/tree-exp-bar.controller.ts | 70 +++++++++++++++++++ .../tree-exp-bar/tree-exp-bar.provider.ts | 12 ++++ .../exp-bar/tree-exp-bar/tree-exp-bar.scss | 0 .../exp-bar/tree-exp-bar/tree-exp-bar.tsx | 44 ++++++++++++ src/control/index.ts | 4 +- .../tab-exp-panel/tab-exp-panel.controller.ts | 18 +++-- src/index.ts | 2 + src/view-engine/index.ts | 6 ++ src/view-engine/tree-exp-view.engine.ts | 65 +++++++++++++++++ 12 files changed, 234 insertions(+), 14 deletions(-) create mode 100644 src/control/exp-bar/index.ts create mode 100644 src/control/exp-bar/tree-exp-bar/index.ts create mode 100644 src/control/exp-bar/tree-exp-bar/tree-exp-bar.controller.ts create mode 100644 src/control/exp-bar/tree-exp-bar/tree-exp-bar.provider.ts create mode 100644 src/control/exp-bar/tree-exp-bar/tree-exp-bar.scss create mode 100644 src/control/exp-bar/tree-exp-bar/tree-exp-bar.tsx create mode 100644 src/view-engine/tree-exp-view.engine.ts diff --git a/src/control/exp-bar/exp-bar.controller.ts b/src/control/exp-bar/exp-bar.controller.ts index 43818524..b5b38f8f 100644 --- a/src/control/exp-bar/exp-bar.controller.ts +++ b/src/control/exp-bar/exp-bar.controller.ts @@ -298,7 +298,7 @@ export class ExpBarControlController< const viewModel = await this.calcViewModel(); const { context, params } = this.prepareParams(this.XDataModel, data); this.navPos?.openView({ - key: viewModel.codeName!.toLowerCase(), + key: data[0].srfkey, context, params, viewModel, diff --git a/src/control/exp-bar/index.ts b/src/control/exp-bar/index.ts new file mode 100644 index 00000000..5e449869 --- /dev/null +++ b/src/control/exp-bar/index.ts @@ -0,0 +1,4 @@ +export * from './tree-exp-bar'; +export * from './list-exp-bar'; +export * from './grid-exp-bar'; +export * from './data-view-exp-bar'; diff --git a/src/control/exp-bar/tree-exp-bar/index.ts b/src/control/exp-bar/tree-exp-bar/index.ts new file mode 100644 index 00000000..54243731 --- /dev/null +++ b/src/control/exp-bar/tree-exp-bar/index.ts @@ -0,0 +1,21 @@ +import { registerControlProvider, ControlType } from '@ibiz-template/runtime'; +import { withInstall } from '@ibiz-template/vue3-util'; +import { App } from 'vue'; +import { TreeExpBarControl } from './tree-exp-bar'; +import { TreeExpBarProvider } from './tree-exp-bar.provider'; + +export * from './tree-exp-bar.provider'; +export * from './tree-exp-bar.controller'; + +export const IBizTreeExpBarControl = withInstall( + TreeExpBarControl, + function (v: App) { + v.component(TreeExpBarControl.name, TreeExpBarControl); + registerControlProvider( + ControlType.TREE_EXP_BAR, + () => new TreeExpBarProvider(), + ); + }, +); + +export default IBizTreeExpBarControl; diff --git a/src/control/exp-bar/tree-exp-bar/tree-exp-bar.controller.ts b/src/control/exp-bar/tree-exp-bar/tree-exp-bar.controller.ts new file mode 100644 index 00000000..7eb5c402 --- /dev/null +++ b/src/control/exp-bar/tree-exp-bar/tree-exp-bar.controller.ts @@ -0,0 +1,70 @@ +import { + ITreeExpBarController, + ITreeExpBarEvent, + ITreeExpBarState, + TreeDataSetNodeData, +} from '@ibiz-template/runtime'; +import { IDETree, IDETreeNode, ITreeExpBar } from '@ibiz/model-core'; +import { ExpBarControlController } from '../exp-bar.controller'; + +/** + * 树导航栏控制器 + * + * @export + * @class TreeExpBarController + * @extends {ExpBarControlController} + * @implements {ITreeExpBarController} + */ +export class TreeExpBarController + extends ExpBarControlController< + ITreeExpBar, + ITreeExpBarState, + ITreeExpBarEvent + > + implements ITreeExpBarController +{ + /** + * 获取指定节点模型 + * + * @param {string} nodeId + * @return {*} {(IDETreeNode | undefined)} + * @memberof TreeExpBarController + */ + getNodeModel(nodeId: string): IDETreeNode | undefined { + const { detreeNodes } = this.XDataModel as IDETree; + let nodeModel: IDETreeNode | undefined; + if (detreeNodes) { + detreeNodes.forEach(node => { + if (node.id === nodeId) { + nodeModel = node; + } + }); + } + return nodeModel; + } + + /** + * 打开导航占位视图 + * + * @param {TreeDataSetNodeData[]} data + * @memberof TreeExpBarController + */ + async openNavPosView(data: TreeDataSetNodeData[]) { + if (data[0]) { + const item = data[0]; + const nodeModel = this.getNodeModel(item.nodeId); + if (nodeModel && nodeModel.navAppViewId) { + const viewModel = await ibiz.hub.getAppView(nodeModel.navAppViewId); + const { context, params } = this.prepareParams(nodeModel, [ + item.deData ? item.deData : item, + ]); + this.navPos?.openView({ + key: item.srfkey as string, + context, + params, + viewModel, + }); + } + } + } +} diff --git a/src/control/exp-bar/tree-exp-bar/tree-exp-bar.provider.ts b/src/control/exp-bar/tree-exp-bar/tree-exp-bar.provider.ts new file mode 100644 index 00000000..8adbe99d --- /dev/null +++ b/src/control/exp-bar/tree-exp-bar/tree-exp-bar.provider.ts @@ -0,0 +1,12 @@ +import { IControlProvider } from '@ibiz-template/runtime'; + +/** + * 树导航栏适配器 + * + * @export + * @class TreeExpBarProvider + * @implements {IControlProvider} + */ +export class TreeExpBarProvider implements IControlProvider { + component: string = 'IBizTreeExpBarControl'; +} diff --git a/src/control/exp-bar/tree-exp-bar/tree-exp-bar.scss b/src/control/exp-bar/tree-exp-bar/tree-exp-bar.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/control/exp-bar/tree-exp-bar/tree-exp-bar.tsx b/src/control/exp-bar/tree-exp-bar/tree-exp-bar.tsx new file mode 100644 index 00000000..4c329f35 --- /dev/null +++ b/src/control/exp-bar/tree-exp-bar/tree-exp-bar.tsx @@ -0,0 +1,44 @@ +import { useControlController, useNamespace } from '@ibiz-template/vue3-util'; +import { defineComponent, PropType } from 'vue'; +import { ITreeExpBar } from '@ibiz/model-core'; +import { TreeExpBarController } from './tree-exp-bar.controller'; +import IBizTreeControl from '../../tree'; +import './tree-exp-bar.scss'; + +export const TreeExpBarControl = defineComponent({ + name: 'IBizTreeExpBarControl', + props: { + modelData: { type: Object as PropType, required: true }, + context: { type: Object as PropType, required: true }, + params: { type: Object as PropType, default: () => ({}) }, + srfnav: { type: String, required: false }, + }, + setup() { + const c = useControlController( + (...args) => new TreeExpBarController(...args), + ); + const ns = useNamespace(`control-${c.model.controlType!.toLowerCase()}`); + + return { + c, + ns, + }; + }, + render() { + const { state, XDataModel, params, context } = this.c; + const { isCreated } = state; + return ( + + {isCreated && XDataModel && ( + + )} + + ); + }, +}); diff --git a/src/control/index.ts b/src/control/index.ts index 6f91f295..55c0faec 100644 --- a/src/control/index.ts +++ b/src/control/index.ts @@ -9,6 +9,4 @@ export * from './data-view'; export * from './tree'; export * from './pickup-view-panel'; export * from './tab-exp-panel'; -export * from './exp-bar/list-exp-bar'; -export * from './exp-bar/grid-exp-bar'; -export * from './exp-bar/data-view-exp-bar'; +export * from './exp-bar'; 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 eaca131b..04ba6f85 100644 --- a/src/control/tab-exp-panel/tab-exp-panel.controller.ts +++ b/src/control/tab-exp-panel/tab-exp-panel.controller.ts @@ -99,7 +99,7 @@ export class TabExpPanelController const { activeName } = this.state; const viewPanel = this.model.controls!.find(tab => tab.id === activeName); if (viewPanel) { - this.setNavPosParams(viewPanel); + this.openNavPosParams(viewPanel); } } @@ -141,18 +141,16 @@ export class TabExpPanelController * @param {IParams} params * @memberof TabExpPanelController */ - async setNavPosParams(tabViewPanel: IDETabViewPanel) { + async openNavPosParams(tabViewPanel: IDETabViewPanel) { const viewModel = await ibiz.hub.getAppView( tabViewPanel.embeddedAppDEViewId!, ); const { context, params } = this.prepareParams(tabViewPanel); - if (this.navPos) { - this.navPos.openView({ - key: viewModel.codeName!.toLowerCase(), - context, - params, - viewModel, - }); - } + this.navPos?.openView({ + key: tabViewPanel.codeName!.toLowerCase(), + context, + params, + viewModel, + }); } } diff --git a/src/index.ts b/src/index.ts index 5bbd5ce9..6d111645 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,6 +18,7 @@ import { IBizListExpBarControl, IBizGridExpBarControl, IBizDataViewExpBarControl, + IBizTreeExpBarControl, } from './control'; import IBizEditor from './editor'; import { IBizView } from './view'; @@ -51,6 +52,7 @@ export default { v.use(IBizEditFormControl); v.use(IBizCaptionBarControl); v.use(IBizTabExpPanelControl); + v.use(IBizTreeExpBarControl); // 编辑器 v.use(IBizEditor); }, diff --git a/src/view-engine/index.ts b/src/view-engine/index.ts index ffcad48b..d0790e06 100644 --- a/src/view-engine/index.ts +++ b/src/view-engine/index.ts @@ -14,12 +14,14 @@ import { TabExpViewEngine } from './tab-exp-view.engine'; import { GridExpViewEngine } from './grid-exp-view.engine'; import { ListExpViewEngine } from './list-exp-view.engine'; import { DataViewExpViewEngine } from './data-view-exp-view.engine'; +import { TreeExpViewEngine } from './tree-exp-view.engine'; export * from './grid-view.engine'; export * from './index-view.engine'; export * from './data-view.engine'; export * from './opt-view.engine'; export * from './tab-exp-view.engine'; +export * from './tree-exp-view.engine'; export const IBizViewEngine = { install: (_v: App) => { @@ -83,5 +85,9 @@ export const IBizViewEngine = { 'VIEW_DataViewExpView', (c: IViewController) => new DataViewExpViewEngine(c), ); + ibiz.engine.register( + 'VIEW_TreeExpView', + (c: IViewController) => new TreeExpViewEngine(c), + ); }, }; diff --git a/src/view-engine/tree-exp-view.engine.ts b/src/view-engine/tree-exp-view.engine.ts new file mode 100644 index 00000000..dd83c024 --- /dev/null +++ b/src/view-engine/tree-exp-view.engine.ts @@ -0,0 +1,65 @@ +import { + ViewController, + ITreeExpViewEvent, + ITreeExpViewState, + ViewEngineBase, + ITreeExpBarController, +} from '@ibiz-template/runtime'; +import { IAppDETreeExplorerView } from '@ibiz/model-core'; + +export class TreeExpViewEngine extends ViewEngineBase { + /** + * 树导航视图控制器 + * + * @protected + * @type {ViewController< + * IAppDETreeExplorerView, + * ITreeExpViewState, + * ITreeExpViewEvent + * >} + * @memberof TreeExpViewEngine + */ + protected declare view: ViewController< + IAppDETreeExplorerView, + ITreeExpViewState, + ITreeExpViewEvent + >; + + /** + * 树导航栏 + * + * @readonly + * @memberof TreeExpViewEngine + */ + get treeExpBar() { + return this.view.getController('treeexpbar') as ITreeExpBarController; + } + + /** + * created生命周期 + * + * @memberof TreeExpViewEngine + */ + async doCreated() { + super.doCreated(); + if (!this.view.slotProps.treeexpbar) { + this.view.slotProps.treeexpbar = {}; + } + this.view.slotProps.treeexpbar.srfnav = this.view.state.srfnav; + } + + /** + * mounted生命周期 + * + * @return {*} {Promise} + * @memberof TreeExpViewEngine + */ + async doMounted(): Promise { + await super.doMounted(); + const { model } = this.view; + // 默认加载 + if (model.loadDefault) { + this.treeExpBar.load(); + } + } +} -- Gitee