From 4c26e78e188f6913854d1eaeea93431f38dfa643 Mon Sep 17 00:00:00 2001 From: zhf <1204297681@qq.com> Date: Tue, 2 Sep 2025 20:28:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E7=A9=BA=E7=99=BD=E5=8D=A0=E4=BD=8D=E9=A2=84=E7=BD=AE=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 + .../index-blank-placeholder.controller.ts | 87 ++++++++++++++++++ .../index-blank-placeholder.provider.ts | 28 ++++++ .../index-blank-placeholder.scss | 14 +++ .../index-blank-placeholder.state.ts | 10 ++ .../index-blank-placeholder.tsx | 91 +++++++++++++++++++ .../index-blank-placeholder/index.ts | 21 +++++ src/panel-component/index.ts | 2 + 8 files changed, 257 insertions(+) create mode 100644 src/panel-component/index-blank-placeholder/index-blank-placeholder.controller.ts create mode 100644 src/panel-component/index-blank-placeholder/index-blank-placeholder.provider.ts create mode 100644 src/panel-component/index-blank-placeholder/index-blank-placeholder.scss create mode 100644 src/panel-component/index-blank-placeholder/index-blank-placeholder.state.ts create mode 100644 src/panel-component/index-blank-placeholder/index-blank-placeholder.tsx create mode 100644 src/panel-component/index-blank-placeholder/index.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index ad19a6f0..75f19236 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ ## [Unreleased] +### Added + +- 新增首页空白占位预置组件 + ## [0.7.41-alpha.12] - 2025-09-02 ### Added diff --git a/src/panel-component/index-blank-placeholder/index-blank-placeholder.controller.ts b/src/panel-component/index-blank-placeholder/index-blank-placeholder.controller.ts new file mode 100644 index 00000000..f24b5f2b --- /dev/null +++ b/src/panel-component/index-blank-placeholder/index-blank-placeholder.controller.ts @@ -0,0 +1,87 @@ +import { AppMenuController, PanelItemController } from '@ibiz-template/runtime'; +import { IPanelContainer } from '@ibiz/model-core'; +import { IndexBlankPlaceholderState } from './index-blank-placeholder.state'; +import { NavPosIndexController } from '../nav-pos-index'; + +/** + * 首页空白占位控制器 + * + * @export + * @class IndexBlankPlaceholderController + * @extends {PanelItemController} + */ +export class IndexBlankPlaceholderController extends PanelItemController { + declare state: IndexBlankPlaceholderState; + + protected createState(): IndexBlankPlaceholderState { + return new IndexBlankPlaceholderState(this.parent?.state); + } + + /** + * @description 当前视图路由层级 + * @exposedoc + * @readonly + * @type {(number | undefined)} + * @memberof IndexBlankPlaceholderController + */ + get routeDepth(): number | undefined { + return this.panel.view.modal.routeDepth; + } + + /** + * @description 应用菜单 + * @exposedoc + * @readonly + * @type {(AppMenuController | undefined)} + * @memberof IndexBlankPlaceholderController + */ + get appmenu(): AppMenuController | undefined { + return this.panel.getController('appmenu') as AppMenuController; + } + + /** + * @description 首页导航栏 + * @exposedoc + * @readonly + * @type {(NavPosIndexController | undefined)} + * @memberof IndexBlankPlaceholderController + */ + get navPos(): NavPosIndexController | undefined { + return this.panel.panelItems.nav_pos_index as NavPosIndexController; + } + + /** + * 初始化 + * + * @protected + * @return {*} {Promise} + * @memberof IndexBlankPlaceholderController + */ + protected async onInit(): Promise { + await super.onInit(); + this.state.keepAlive = true; + // 默认不显示防止闪烁 + this.state.visible = false; + // 如果应用菜单有默认打开的路由视图则默认不显示 + this.panel.evt.on('onMounted', async () => { + if (this.navPos) this.navPos.state.keepAlive = true; + const appViewId = this.appmenu?.getDefaultOpenView(); + if (appViewId) { + const appView = await ibiz.hub.config.view.get(appViewId!); + const { openMode = 'INDEXVIEWTAB' } = appView; + this.state.visible = !openMode.startsWith('INDEXVIEWTAB'); + } + }); + } + + /** + * @description 设置显示状态 + * @exposedoc + * @param {boolean} state + * @memberof IndexBlankPlaceholderController + */ + setVisible(state: boolean): void { + this.state.visible = state; + if (this.navPos) this.navPos.state.visible = !state; + } +} diff --git a/src/panel-component/index-blank-placeholder/index-blank-placeholder.provider.ts b/src/panel-component/index-blank-placeholder/index-blank-placeholder.provider.ts new file mode 100644 index 00000000..9c568185 --- /dev/null +++ b/src/panel-component/index-blank-placeholder/index-blank-placeholder.provider.ts @@ -0,0 +1,28 @@ +import { + IPanelItemProvider, + PanelController, + PanelItemController, +} from '@ibiz-template/runtime'; +import { IPanelContainer } from '@ibiz/model-core'; +import { IndexBlankPlaceholderController } from './index-blank-placeholder.controller'; + +/** + * 首页空白占位适配器 + * + * @export + * @class IndexBlankPlaceholderProvider + * @implements {IPanelItemProvider} + */ +export class IndexBlankPlaceholderProvider implements IPanelItemProvider { + component: string = 'IBizIndexBlankPlaceholder'; + + async createController( + panelItem: IPanelContainer, + panel: PanelController, + parent: PanelItemController | undefined, + ): Promise { + const c = new IndexBlankPlaceholderController(panelItem, panel, parent); + await c.init(); + return c; + } +} diff --git a/src/panel-component/index-blank-placeholder/index-blank-placeholder.scss b/src/panel-component/index-blank-placeholder/index-blank-placeholder.scss new file mode 100644 index 00000000..d13b1611 --- /dev/null +++ b/src/panel-component/index-blank-placeholder/index-blank-placeholder.scss @@ -0,0 +1,14 @@ +// 默认样式 +@include b(index-blank-placeholder) { + width: 100%; + height: 100%; + + > .#{bem('row')} { + height: 100%; + overflow: hidden auto; + } + + @include when(hidden) { + display: none; + } +} diff --git a/src/panel-component/index-blank-placeholder/index-blank-placeholder.state.ts b/src/panel-component/index-blank-placeholder/index-blank-placeholder.state.ts new file mode 100644 index 00000000..a73a9a33 --- /dev/null +++ b/src/panel-component/index-blank-placeholder/index-blank-placeholder.state.ts @@ -0,0 +1,10 @@ +import { PanelItemState } from '@ibiz-template/runtime'; + +/** + * 首页空白占位状态 + * + * @export + * @class IndexBlankPlaceholderState + * @extends {PanelItemState} + */ +export class IndexBlankPlaceholderState extends PanelItemState {} diff --git a/src/panel-component/index-blank-placeholder/index-blank-placeholder.tsx b/src/panel-component/index-blank-placeholder/index-blank-placeholder.tsx new file mode 100644 index 00000000..f1e1db76 --- /dev/null +++ b/src/panel-component/index-blank-placeholder/index-blank-placeholder.tsx @@ -0,0 +1,91 @@ +import { IPanelContainer } from '@ibiz/model-core'; +import { onRouteChange, useNamespace } from '@ibiz-template/vue3-util'; +import { computed, defineComponent, PropType, VNode } from 'vue'; +import { IndexBlankPlaceholderController } from './index-blank-placeholder.controller'; +import './index-blank-placeholder.scss'; + +/** + * 空白占位 + * @primary + * @description 首页空白占位组件,当菜单未进行导航时,首页显示此容器内的内容。 + */ +export const IndexBlankPlaceholder = defineComponent({ + name: 'IBizIndexBlankPlaceholder', + props: { + /** + * @description 空白占位模型数据 + */ + modelData: { + type: Object as PropType, + required: true, + }, + /** + * @description 空白占位控制器 + */ + controller: { + type: Object as PropType, + required: true, + }, + }, + setup(props) { + const c = props.controller; + const ns = useNamespace('index-blank-placeholder'); + const { id } = props.modelData; + + // 类名控制 + const classArr = computed(() => { + let result: Array = [ns.b(), ns.m(id)]; + result = [ + ...result, + ...props.controller.containerClass, + ns.is('hidden', !props.controller.state.visible), + ]; + return result; + }); + + if (c.routeDepth) { + onRouteChange(args => { + // 如果有2级视图则不显示 + c.setVisible(!args.currentKey); + }, c.routeDepth + 1); + } + + return { ns, classArr }; + }, + render() { + // 内容区默认插槽处理,封装app-col + const defaultSlots: VNode[] = this.$slots.default?.() || []; + const content = ( + + {defaultSlots.map(slot => { + const props = slot.props as IData; + if (!props || !props.controller) { + return slot; + } + + return ( + + {slot} + + ); + })} + + ); + return ( +
{ + this.controller.onClick(); + }} + > + {this.controller.model.cssStyle ? ( + + ) : null} + {content} +
+ ); + }, +}); diff --git a/src/panel-component/index-blank-placeholder/index.ts b/src/panel-component/index-blank-placeholder/index.ts new file mode 100644 index 00000000..59f9a829 --- /dev/null +++ b/src/panel-component/index-blank-placeholder/index.ts @@ -0,0 +1,21 @@ +import { App } from 'vue'; +import { registerPanelItemProvider } from '@ibiz-template/runtime'; +import { withInstall } from '@ibiz-template/vue3-util'; +import { IndexBlankPlaceholder } from './index-blank-placeholder'; +import { IndexBlankPlaceholderProvider } from './index-blank-placeholder.provider'; +import { IndexBlankPlaceholderController } from './index-blank-placeholder.controller'; + +export { IndexBlankPlaceholderController }; + +export const IBizIndexBlankPlaceholder = withInstall( + IndexBlankPlaceholder, + function (v: App) { + v.component(IndexBlankPlaceholder.name!, IndexBlankPlaceholder); + registerPanelItemProvider( + 'CONTAINER_INDEX_BLANK_PLACEHOLDER', + () => new IndexBlankPlaceholderProvider(), + ); + }, +); + +export default IBizIndexBlankPlaceholder; diff --git a/src/panel-component/index.ts b/src/panel-component/index.ts index 6dd90fca..01593247 100644 --- a/src/panel-component/index.ts +++ b/src/panel-component/index.ts @@ -31,6 +31,7 @@ import IBizMobAsyncAction from './async-action'; import IBizPanelButtonList from './panel-button-list'; import IBizAuthSso from './auth-sso'; import IBizPanelAppTitle from './panel-app-title'; +import IBizIndexBlankPlaceholder from './index-blank-placeholder'; export const IBizPanelComponents = { install: (v: App): void => { @@ -64,6 +65,7 @@ export const IBizPanelComponents = { v.use(IBizAuthSso); v.use(IBizAuthWxmpQrcode); v.use(IBizPanelAppTitle); + v.use(IBizIndexBlankPlaceholder); }, }; -- Gitee