diff --git a/src/control/index.ts b/src/control/index.ts
index 53176b356a4331be7dc2a599bfcce571f6655b20..f5ee577136bf1445de761695f060a44bcad31a5a 100644
--- a/src/control/index.ts
+++ b/src/control/index.ts
@@ -16,3 +16,4 @@ export * from './dashboard';
export * from './chart';
export * from './calendar';
export * from './wizard-panel';
+export * from './tree-exp-bar';
diff --git a/src/control/toolbar/popper-toolbar/popper-toolbar.scss b/src/control/toolbar/popper-toolbar/popper-toolbar.scss
index ced87cd49b531376ab7f7148c5a34e9dca46c6e0..af24de842add4678b3c2c4d57393fb964da63119 100644
--- a/src/control/toolbar/popper-toolbar/popper-toolbar.scss
+++ b/src/control/toolbar/popper-toolbar/popper-toolbar.scss
@@ -32,6 +32,6 @@
}
}
.van-button {
- min-width: var(--van-back-top-size);
+ min-width: rem(44px);
}
}
\ No newline at end of file
diff --git a/src/control/tree-exp-bar/index.ts b/src/control/tree-exp-bar/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..08d57ebb88a88a7486a08c910aed56a04de4a1a6
--- /dev/null
+++ b/src/control/tree-exp-bar/index.ts
@@ -0,0 +1,18 @@
+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 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/tree-exp-bar/render-util.tsx b/src/control/tree-exp-bar/render-util.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..fc72e171a8c89b2ac2b1c0f7e374aa396ba65f8b
--- /dev/null
+++ b/src/control/tree-exp-bar/render-util.tsx
@@ -0,0 +1,121 @@
+import { Namespace } from '@ibiz-template/core';
+import { IExpBarControlController } from '@ibiz-template/runtime';
+import { debounce } from 'lodash-es';
+import { VNode, h, resolveComponent } from 'vue';
+import { useRoute } from 'vue-router';
+import {
+ onRouteChange,
+ route2routePath,
+ useNamespace,
+} from '@ibiz-template/vue3-util';
+// import './render-util.scss';
+
+/**
+ * 导航栏绘制工具(标题,快速搜索)
+ * @author lxm
+ * @date 2023-08-02 08:06:38
+ * @export
+ * @param {ExpBarControlController} c
+ * @param {Namespace} ns
+ * @return {*} {({ renderTitle: () => VNode | null; renderSearchBar: () => VNode | null })}
+ */
+export function useExpBarRender(
+ c: IExpBarControlController,
+ ns: Namespace,
+): { renderTitle: () => VNode | null; renderSearchBar: () => VNode | null } {
+ const expBarNs = useNamespace('exp-bar');
+
+ const debounceSearch = debounce(() => {
+ c.load();
+ }, 500);
+
+ const onInput = (value: string): void => {
+ c.state.query = value;
+ debounceSearch();
+ };
+
+ const renderTitle = (): VNode | null => {
+ const { model } = c;
+ if (!model.showTitleBar) {
+ return null;
+ }
+ let title = model.title;
+ if (model.titleLanguageRes) {
+ title = ibiz.i18n.t(model.titleLanguageRes.lanResTag!, model.title);
+ }
+ return (
+
+ {model.sysImage && (
+
+ )}
+ {title && {title}}
+
+ );
+ };
+
+ const renderSearchBar = (): VNode | null => {
+ const { model } = c;
+ if (!model.enableSearch) {
+ return null;
+ }
+
+ const modelData = c.view.model.viewLayoutPanel?.controls?.find(
+ item => item.id === 'searchbar',
+ );
+ if (modelData) {
+ const ctrlProps = {
+ context: c.context,
+ params: c.params,
+ };
+ const comp = resolveComponent('IBizControlShell');
+ return h(comp, {
+ modelData,
+ ...ctrlProps,
+ });
+ }
+
+ return (
+
+ {{
+ prefix: (): VNode => {
+ return ;
+ },
+ }}
+
+ );
+ };
+
+ return { renderTitle, renderSearchBar };
+}
+
+/**
+ * 监听路由变更,当自身所处的路由变更时触发导航栏控制器onRouterChange
+ * @author lxm
+ * @date 2023-09-14 10:02:41
+ * @export
+ * @param {IExpBarControlController} c
+ */
+export function useWatchRouteChange(c: IExpBarControlController): void {
+ const depth = c.view.modal.routeDepth;
+ if (depth) {
+ const route = useRoute();
+ let selfKey: string | undefined;
+ onRouteChange(({ currentKey, fullPath }) => {
+ if (!selfKey) {
+ selfKey = currentKey;
+ } else if (selfKey === currentKey) {
+ const routePath = route2routePath(route);
+ const { srfnav } = routePath.pathNodes[depth! - 1];
+ c.onRouterChange({ srfnav: srfnav || '', path: fullPath });
+ }
+ }, depth);
+ }
+}
diff --git a/src/control/tree-exp-bar/tree-exp-bar.provider.ts b/src/control/tree-exp-bar/tree-exp-bar.provider.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8adbe99d599f2c5a58eb468dfaeeba7aef3807ed
--- /dev/null
+++ b/src/control/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/tree-exp-bar/tree-exp-bar.scss b/src/control/tree-exp-bar/tree-exp-bar.scss
new file mode 100644
index 0000000000000000000000000000000000000000..59b1a7089ba01983a2ce458d37b49e570efbebda
--- /dev/null
+++ b/src/control/tree-exp-bar/tree-exp-bar.scss
@@ -0,0 +1,8 @@
+@include b('control-treeexpbar'){
+ .vs-tree-inner{
+ width: 100%;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ }
+}
\ No newline at end of file
diff --git a/src/control/tree-exp-bar/tree-exp-bar.tsx b/src/control/tree-exp-bar/tree-exp-bar.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..f216217db28f47f5a16e8a1d3b8a434633e947a6
--- /dev/null
+++ b/src/control/tree-exp-bar/tree-exp-bar.tsx
@@ -0,0 +1,73 @@
+import { PropType, VNode, computed, defineComponent } from 'vue';
+import { ITreeExpBar } from '@ibiz/model-core';
+import { IControlProvider, TreeExpBarController } from '@ibiz-template/runtime';
+import { useControlController, useNamespace } from '@ibiz-template/vue3-util';
+import { useExpBarRender, useWatchRouteChange } from './render-util';
+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: () => ({}) },
+ provider: { type: Object as PropType },
+ srfnav: { type: String, required: false },
+ noNeedNavView: { type: Boolean, required: false },
+ loadDefault: { type: Boolean, default: true },
+ },
+ setup() {
+ const c = useControlController(
+ (...args) => new TreeExpBarController(...args),
+ );
+ const ns = useNamespace(`control-${c.model.controlType!.toLowerCase()}`);
+
+ const { renderTitle, renderSearchBar } = useExpBarRender(c, ns);
+ useWatchRouteChange(c);
+
+ const navigational = computed(() => {
+ return (
+ c.view.model.viewType &&
+ !['DEMOBMPICKUPVIEW', 'DEMOBPICKUPVIEW'].includes(c.view.model.viewType)
+ );
+ });
+
+ return {
+ c,
+ ns,
+ navigational,
+ renderTitle,
+ renderSearchBar,
+ };
+ },
+ render() {
+ const { state, XDataModel } = this.c;
+ const { isCreated } = state;
+
+ const slots: IData = {
+ captionbar: this.renderTitle,
+ searchbar: this.renderSearchBar,
+ };
+ if (isCreated) {
+ if (XDataModel) {
+ const key = this.c.controlPanel ? XDataModel.name! : 'default';
+ // 树自己绘制,要传递额外的参数
+ slots[key] = (): VNode => {
+ return (
+
+ );
+ };
+ }
+ }
+ return {slots};
+ },
+});
diff --git a/src/ibiz-vue3.ts b/src/ibiz-vue3.ts
index 50732eb8bf066c99499eca1f5302b3cfddddba5a..4593890050ccac9587d81be4bd141b01a7bfd0b5 100644
--- a/src/ibiz-vue3.ts
+++ b/src/ibiz-vue3.ts
@@ -28,6 +28,7 @@ import {
IBizWizardPanelControl,
IBizAppMenuIconViewControl,
IBizAppMenuListViewControl,
+ IBizTreeExpBarControl,
} from './control';
import { iBizI18n } from './locale';
import IBizPanelComponents from './panel-component';
@@ -77,6 +78,7 @@ export default {
v.use(IBizChartControl);
v.use(IBizCalendarControl);
v.use(IBizWizardPanelControl);
+ v.use(IBizTreeExpBarControl);
// 编辑器
v.use(IBizEditor);
},
diff --git a/src/util/fullscreen/fullscreen-util.ts b/src/util/fullscreen/fullscreen-util.ts
index 437c03d76d7f7393e2a1f39a9bfd092e35645a0c..6c058509418b9b9fb9eebe51bf47ff4e9bd3afe5 100644
--- a/src/util/fullscreen/fullscreen-util.ts
+++ b/src/util/fullscreen/fullscreen-util.ts
@@ -1,10 +1,8 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
-import { VNode, createApp, h } from 'vue';
-// import { defaultNamespace } from '@ibiz-template/core/out/utils/namespace/namespace';
+import { createApp } from 'vue';
import { IBizFullscreenHeader } from '../../common/fullscreen-header/fullscreen-header';
-// import { defaultNamespace } from '@ibiz-template/core/out/utils/namespace/namespace';
/**
* 全屏全局工具类
diff --git a/src/view-engine/index.ts b/src/view-engine/index.ts
index 0732b2155f293cf9117703c4e65db70f2e0881b6..1853e9c820fbb15edd74968f09079125cc797e79 100644
--- a/src/view-engine/index.ts
+++ b/src/view-engine/index.ts
@@ -1,4 +1,8 @@
-import { IViewController, IMobViewController } from '@ibiz-template/runtime';
+import {
+ IViewController,
+ IMobViewController,
+ ITreeExpBarController,
+} from '@ibiz-template/runtime';
import { IndexViewEngine } from './index-view.engine';
import { MobEditViewEngine } from './mob-edit-view.engine';
import { MobEditView3Engine } from './mob-edit-view3.engine';
@@ -21,9 +25,15 @@ import { MobOptViewEngine } from './mob-opt-view.engine';
import { MobChartViewEngine } from './mob-chart-view.engine';
import { MobCalendarViewEngine } from './mob-calendar-view.engine';
import { MobWizardViewEngine } from './mob-wizard-view-engine';
+import { MobTreeExpViewEngine } from './mob-tree-exp-view.engine';
export const IBizViewEngine = {
install: (): void => {
+ ibiz.engine.register(
+ 'VIEW_MobTreeExpView',
+ (c: IMobViewController) => new MobTreeExpViewEngine(c),
+ );
+
ibiz.engine.register(
`VIEW_APPINDEXVIEW`,
(c: IViewController) => new IndexViewEngine(c),
diff --git a/src/view-engine/mob-tree-exp-view.engine.ts b/src/view-engine/mob-tree-exp-view.engine.ts
new file mode 100644
index 0000000000000000000000000000000000000000..daa7a6830c89aae90ad5d5430dc077cffddee633
--- /dev/null
+++ b/src/view-engine/mob-tree-exp-view.engine.ts
@@ -0,0 +1,60 @@
+import {
+ ViewController,
+ ITreeExpViewEvent,
+ ITreeExpViewState,
+ ITreeController,
+ ViewEngineBase,
+ IExpBarControlController,
+} from '@ibiz-template/runtime';
+import { IAppDETreeExplorerView } from '@ibiz/model-core';
+
+export class MobTreeExpViewEngine extends ViewEngineBase {
+ /**
+ * 树导航视图控制器
+ */
+ protected declare view: ViewController<
+ IAppDETreeExplorerView,
+ ITreeExpViewState,
+ ITreeExpViewEvent
+ >;
+
+ get expBar(): IExpBarControlController {
+ return this.view.getController(this.expBarName) as IExpBarControlController;
+ }
+
+ /**
+ * 树导航栏部件名称
+ *
+ * @author lxm
+ * @date 2023-08-31 03:43:02
+ * @readonly
+ * @type {string}
+ */
+ get expBarName(): string {
+ return 'treeexpbar';
+ }
+
+ /**
+ * 树部件控制器
+ *
+ * @readonly
+ * @memberof TreeExpViewEngine
+ */
+ get tree(): ITreeController {
+ return this.expBar.xDataController as ITreeController;
+ }
+
+ async onCreated(): Promise {
+ await super.onCreated();
+ const { childNames } = this.view;
+ childNames.push('treeexppanel');
+ if (!this.view.slotProps.treeexppanel) {
+ this.view.slotProps.treeexppanel = {};
+ }
+ }
+
+ async onMounted(): Promise {
+ await super.onMounted();
+ await this.loadEntityData();
+ }
+}