From 7c86e933e1763eba54b978687513cdbd111b25cb Mon Sep 17 00:00:00 2001 From: jianglinjun Date: Wed, 16 Oct 2024 19:04:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=AB=AF=E6=A0=91=E5=AF=BC=E8=88=AA=E8=A7=86=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/control/index.ts | 1 + .../popper-toolbar/popper-toolbar.scss | 2 +- src/control/tree-exp-bar/index.ts | 18 +++ src/control/tree-exp-bar/render-util.tsx | 121 ++++++++++++++++++ .../tree-exp-bar/tree-exp-bar.provider.ts | 12 ++ src/control/tree-exp-bar/tree-exp-bar.scss | 8 ++ src/control/tree-exp-bar/tree-exp-bar.tsx | 73 +++++++++++ src/ibiz-vue3.ts | 2 + src/util/fullscreen/fullscreen-util.ts | 4 +- src/view-engine/index.ts | 12 +- src/view-engine/mob-tree-exp-view.engine.ts | 60 +++++++++ 11 files changed, 308 insertions(+), 5 deletions(-) create mode 100644 src/control/tree-exp-bar/index.ts create mode 100644 src/control/tree-exp-bar/render-util.tsx create mode 100644 src/control/tree-exp-bar/tree-exp-bar.provider.ts create mode 100644 src/control/tree-exp-bar/tree-exp-bar.scss create mode 100644 src/control/tree-exp-bar/tree-exp-bar.tsx create mode 100644 src/view-engine/mob-tree-exp-view.engine.ts diff --git a/src/control/index.ts b/src/control/index.ts index 53176b35..f5ee5771 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 ced87cd4..af24de84 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 00000000..08d57ebb --- /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 00000000..fc72e171 --- /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 00000000..8adbe99d --- /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 00000000..59b1a708 --- /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 00000000..f216217d --- /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 50732eb8..45938900 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 437c03d7..6c058509 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 0732b215..1853e9c8 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 00000000..daa7a683 --- /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(); + } +} -- Gitee