diff --git a/CHANGELOG.md b/CHANGELOG.md index 94634b5e6cf1bbe93cf5ba3a056716f4abafdec3..dfd0fedd148cf127a63a4a49732c237fce2bafa5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,13 @@ ## [Unreleased] +### Added + +- 新增移动端全局全屏打开工具 + ### Fixed - + +- 修复图表宽高变化时未自适应的问题 - 修复门户控件界面行为组未绘制的问题 - 修复登录页标签标题异常 diff --git a/src/common/fullscreen-header/fullscreen-header.scss b/src/common/fullscreen-header/fullscreen-header.scss new file mode 100644 index 0000000000000000000000000000000000000000..aee3fdae11c076e104144c5e4a5108f95d0d53a4 --- /dev/null +++ b/src/common/fullscreen-header/fullscreen-header.scss @@ -0,0 +1,17 @@ +@include b('fullscreen-header'){ + height: getCssVar(spacing,extra,loose); + display: flex; + justify-content: center; + align-items: center; + overflow: hidden; + position: relative; + @include e('close'){ + position: absolute; + right: getCssVar(spacing,extra,tight); + font-size: getCssVar(font-size,header-3); + height: 100%; + display: flex; + align-items: center; + } + +} \ No newline at end of file diff --git a/src/common/fullscreen-header/fullscreen-header.tsx b/src/common/fullscreen-header/fullscreen-header.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c139c18deb83d3aae257e927f80f87ed138c65db --- /dev/null +++ b/src/common/fullscreen-header/fullscreen-header.tsx @@ -0,0 +1,29 @@ +import { useNamespace } from '@ibiz-template/vue3-util'; +import { defineComponent } from 'vue'; +import './fullscreen-header.scss'; + +export const IBizFullscreenHeader = defineComponent({ + name: 'IBizFullscreenHeader', + props: { + title: { + type: String, + }, + }, + setup() { + const ns = useNamespace('fullscreen-header'); + const onClose = () => { + ibiz.fullscreenUtil.closeElementFullscreen(); + }; + return { ns, onClose }; + }, + render() { + return ( +
+ {this.title} + + + +
+ ); + }, +}); diff --git a/src/common/index.ts b/src/common/index.ts index e18c23fa96fdf418b62a4955f261d8bed20f7b3f..e4d2448e103519dcd307a18de33cb936403e52f1 100644 --- a/src/common/index.ts +++ b/src/common/index.ts @@ -16,6 +16,7 @@ import { IBizRawItem } from './rawitem/rawitem'; import { IBizRow } from './row/row'; import { IBizPresetViewBack } from './preset-view-back/preset-view-back'; import { IBizPresetViewHeader } from './preset-view-header/preset-view-header'; +import { IBizFullscreenHeader } from './fullscreen-header/fullscreen-header'; export * from './col/col'; export * from './row/row'; @@ -38,6 +39,7 @@ export const IBizCommonComponents = { v.component(IBizPresetViewBack.name, IBizPresetViewBack); v.component(IBizPresetViewHeader.name, IBizPresetViewHeader); v.component(IBizCodeList.name, IBizCodeList); + v.component(IBizFullscreenHeader.name, IBizFullscreenHeader); }, }; diff --git a/src/control/chart/chart.tsx b/src/control/chart/chart.tsx index 7f0181b88a7715edee70f129ed200a9898f0c33c..8fcdf985f4afce54cc963c98e775b09f29a453fc 100644 --- a/src/control/chart/chart.tsx +++ b/src/control/chart/chart.tsx @@ -1,5 +1,11 @@ import { useControlController, useNamespace } from '@ibiz-template/vue3-util'; -import { defineComponent, onMounted, PropType, ref } from 'vue'; +import { + defineComponent, + onBeforeUnmount, + onMounted, + PropType, + ref, +} from 'vue'; import { IDEChart } from '@ibiz/model-core'; import { init } from 'echarts'; import './chart.scss'; @@ -20,9 +26,23 @@ const ChartControl = defineComponent({ const ns = useNamespace(`control-${c.model.controlType!.toLowerCase()}`); const chartRef = ref(); + // 容器大小变化监听器 + let resizeObserver: ResizeObserver; + onMounted(() => { const chart = init(chartRef.value); c.initChart(chart); + + if (chartRef.value && ResizeObserver) { + resizeObserver = new ResizeObserver(() => { + c.resizeChart(); + }); + resizeObserver.observe(chartRef.value); + } + }); + + onBeforeUnmount(() => { + resizeObserver?.disconnect(); }); return { diff --git a/src/mob-app/main.ts b/src/mob-app/main.ts index e47765f194154fc96be58829e868b8fb57536378..1cffdfafdc554623fa9f35ad0a7122ec5a468a53 100644 --- a/src/mob-app/main.ts +++ b/src/mob-app/main.ts @@ -24,6 +24,7 @@ import { NotificationUtil, OpenViewUtil, OverlayController, + FullscreenUtil, } from '../util'; export async function runApp(plugins?: Plugin[]): Promise { @@ -83,6 +84,7 @@ export async function runApp(plugins?: Plugin[]): Promise { ibiz.loading = new LoadingUtil(); ibiz.overlay = new OverlayController(); ibiz.platform = getPlatformProvider(); + ibiz.fullscreenUtil = new FullscreenUtil(); await ibiz.i18n.init(); diff --git a/src/util/fullscreen/fullscreen-util.ts b/src/util/fullscreen/fullscreen-util.ts new file mode 100644 index 0000000000000000000000000000000000000000..437c03d76d7f7393e2a1f39a9bfd092e35645a0c --- /dev/null +++ b/src/util/fullscreen/fullscreen-util.ts @@ -0,0 +1,82 @@ +/* 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 { IBizFullscreenHeader } from '../../common/fullscreen-header/fullscreen-header'; +// import { defaultNamespace } from '@ibiz-template/core/out/utils/namespace/namespace'; + +/** + * 全屏全局工具类 + * + * @export + * @class FullscreenUtil + */ +export class FullscreenUtil { + /** + * Creates an instance of FullscreenUtil. + * @memberof FullscreenUtil + */ + constructor() {} + + /** + *是否全屏状态 + * + * @readonly + * @memberof FullscreenUtil + */ + get isFullScreen() { + return !!document.fullscreenElement; + } + + /** + * 全屏样式 + * @author fzh + * @date 2024-07-15 19:39:40 + */ + public FullscreenClass: string = 'full-screen-class'; + + /** + * 指定元素全屏 + * @author fzh + * @date 2024-07-09 19:39:40 + */ + public openElementFullscreen(div: HTMLDivElement, data?: IParams): void { + if (data?.class) { + this.FullscreenClass = data.class; + } + if (!document.fullscreenElement && div) { + if (this.FullscreenClass) { + div.classList.add(this.FullscreenClass); + } + + // 通过传递参数决定是否绘制标题和关闭按钮 + if (data?.showClose || data?.srftitle) { + const content = document.createElement('div'); + content.id = 'fullscreen'; + const app = createApp(IBizFullscreenHeader, { + title: data?.srftitle, + }); + app.mount(content); + //直接操作传进来的元素 + div.insertBefore(content, div.children[0]); + } + div.requestFullscreen(); + } + } + + /** + * 页面退出全屏 + * @author fzh + * @date 2024-07-09 19:39:40 + */ + public closeElementFullscreen(): void { + // 退出前移除全屏元素的全屏样式 + document.fullscreenElement?.classList.remove(this.FullscreenClass); + const close = document.fullscreenElement?.querySelector('#fullscreen'); + if (close) { + close.remove(); + } + document.exitFullscreen(); + } +} diff --git a/src/util/index.ts b/src/util/index.ts index c813241e40d432996f775bd7d2b7320b6ce2a163..5b6160309d4358403d28219ac4a7fb4914bbdd39 100644 --- a/src/util/index.ts +++ b/src/util/index.ts @@ -8,4 +8,5 @@ export { loadingDirective } from './directive/loading'; export { ConfirmUtil } from './confirm-util/confirm-util'; export { AppUtil } from './app-util/app-util'; export { usePagination } from './pagination/use-pagination'; +export { FullscreenUtil } from './fullscreen/fullscreen-util'; export * from './store';