From 7cf58a4d2fff6b9cba9029d4d43ba9744dbef864 Mon Sep 17 00:00:00 2001
From: Ben Lin <maobin001@msn.com>
Date: 星期四, 18 七月 2024 15:49:03 +0800
Subject: [PATCH] 工单更新

---
 src/components/Table/src/hooks/useTableScroll.ts |  318 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 232 insertions(+), 86 deletions(-)

diff --git a/src/components/Table/src/hooks/useTableScroll.ts b/src/components/Table/src/hooks/useTableScroll.ts
index 3777d6e..10313e9 100644
--- a/src/components/Table/src/hooks/useTableScroll.ts
+++ b/src/components/Table/src/hooks/useTableScroll.ts
@@ -1,10 +1,19 @@
 import type { BasicTableProps, TableRowSelection, BasicColumn } from '../types/table';
 import { Ref, ComputedRef, ref, computed, unref, nextTick, watch } from 'vue';
-import { getViewportOffset } from '/@/utils/domUtils';
-import { isBoolean } from '/@/utils/is';
+import { getViewportOffset } from '@/utils/domUtils';
+import { isBoolean } from '@/utils/is';
 import { useWindowSizeFn, onMountedOrActivated } from '@vben/hooks';
-import { useModalContext } from '/@/components/Modal';
-import { useDebounceFn } from '@vueuse/core';
+import { useModalContext } from '@/components/Modal';
+import { useDebounceFn, promiseTimeout } from '@vueuse/core';
+
+import {
+  footerHeight as layoutFooterHeight,
+  layoutMultipleHeadePlaceholderTime,
+} from '@/settings/designSetting';
+
+import { useRootSetting } from '@/hooks/setting/useRootSetting';
+
+const { getShowFooter, getFullContent } = useRootSetting();
 
 export function useTableScroll(
   propsRef: ComputedRef<BasicTableProps>,
@@ -27,8 +36,20 @@
   });
 
   watch(
-    () => [unref(getCanResize), unref(getDataSourceRef)?.length],
+    () => [unref(getCanResize), unref(getDataSourceRef)?.length, unref(getShowFooter)],
     () => {
+      debounceRedoHeight();
+    },
+    {
+      flush: 'post',
+    },
+  );
+
+  watch(
+    () => [unref(getFullContent)],
+    async () => {
+      // 绛夊緟鍔ㄧ敾缁撴潫鍚�200姣
+      await promiseTimeout(layoutMultipleHeadePlaceholderTime * 1000 + 200);
       debounceRedoHeight();
     },
     {
@@ -53,22 +74,13 @@
   let footerEl: HTMLElement | null;
   let bodyEl: HTMLElement | null;
 
-  async function calcTableHeight() {
-    const { resizeHeightOffset, pagination, maxHeight, isCanResizeParent, useSearchForm } =
-      unref(propsRef);
-    const tableData = unref(getDataSourceRef);
+  /**
+   * table wrapper padding 鐨勯珮搴�
+   * @description 鏉ヨ嚜浜� .vben-basic-table .ant-table-wrapper
+   */
+  const tableWrapperPadding = 6;
 
-    const table = unref(tableElRef);
-    if (!table) return;
-
-    const tableEl: Element = table.$el;
-    if (!tableEl) return;
-
-    if (!bodyEl) {
-      bodyEl = tableEl.querySelector('.ant-table-body');
-      if (!bodyEl) return;
-    }
-
+  function handleScrollBar(bodyEl: HTMLElement, tableEl: Element) {
     const hasScrollBarY = bodyEl.scrollHeight > bodyEl.clientHeight;
     const hasScrollBarX = bodyEl.scrollWidth > bodyEl.clientWidth;
 
@@ -85,6 +97,180 @@
     } else {
       !tableEl.classList.contains('hide-scrollbar-x') && tableEl.classList.add('hide-scrollbar-x');
     }
+  }
+
+  /**
+   * 璁$畻鍒嗛〉鍣ㄩ珮搴�
+   * @param tableEl table element
+   * @returns number
+   */
+  function caclPaginationHeight(tableEl: Element): number {
+    const { pagination } = unref(propsRef);
+
+    let paginationHeight = 0;
+    if (!isBoolean(pagination)) {
+      // 浠� Dom 鑾峰彇
+      if (!paginationEl) {
+        paginationEl = tableEl.querySelector('.ant-pagination') as HTMLElement;
+      }
+      if (paginationEl) {
+        // 鍒嗛〉 margin-top
+        const paginationElMarginTop =
+          parseInt(getComputedStyle(paginationEl)?.marginTop) || 10 + 24;
+        // 鍒嗛〉楂樺害
+        const offsetHeight = paginationEl.offsetHeight;
+        paginationHeight = offsetHeight + paginationElMarginTop;
+      } else {
+        // 鎵句笉鍒板垎椤电粍浠讹紝缂虹渷缁欎簣榛樿鍒嗛〉 margin-top + 楂樺害
+        paginationHeight = 10 + 24;
+      }
+    } else {
+      // 涓嶆樉绀哄垎椤碉紝pagination 涓� false 鐨勬椂鍊�
+      paginationHeight = 0;
+    }
+    return paginationHeight;
+  }
+
+  function caclFooterHeight(tableEl: Element): number {
+    const { pagination } = unref(propsRef);
+    let footerHeight = 0;
+    if (!isBoolean(pagination)) {
+      if (!footerEl) {
+        footerEl = tableEl.querySelector('.ant-table-footer') as HTMLElement;
+      } else {
+        const offsetHeight = footerEl.offsetHeight;
+        footerHeight += offsetHeight || 0;
+      }
+    }
+    return footerHeight;
+  }
+
+  function calcHeaderHeight(headEl: Element): number {
+    let headerHeight = 0;
+    if (headEl) {
+      headerHeight = (headEl as HTMLElement).offsetHeight;
+    }
+    return headerHeight;
+  }
+
+  /**
+   * 璁$畻浠庤〃澶翠竴鐩村埌body搴曢儴鐨勬�婚珮搴�
+   * @param tableEl table element
+   * @param headEl table 椤靛ご element
+   * @returns number
+   */
+  function calcBottomAndPaddingHeight(tableEl: Element, headEl: Element) {
+    const { isCanResizeParent } = unref(propsRef);
+    let bottomIncludeBody = 0;
+    if (unref(wrapRef) && isCanResizeParent) {
+      // 缁ф壙鐖跺厓绱犻珮搴�
+      const wrapHeight = unref(wrapRef)?.offsetHeight ?? 0;
+
+      let formHeight = unref(formRef)?.$el.offsetHeight ?? 0;
+      if (formHeight) {
+        // 鏉ヨ嚜浜� .vben-basic-table-form-container .ant-form 浠ュ強 .vben-basic-table-form-container
+        formHeight += 16 + 16 * 2;
+      }
+
+      bottomIncludeBody = wrapHeight - tableWrapperPadding - formHeight;
+    } else {
+      // 缂虹渷 wrapRef 鎯呭喌涓�
+      bottomIncludeBody = getViewportOffset(headEl).bottomIncludeBody;
+    }
+
+    return bottomIncludeBody;
+  }
+
+  /**
+   * 璁$畻 table 鍦� modal 鍐� modal 鎵�鍗犵敤鐨勯珮搴�
+   * @param tableEl table element
+   * @returns number
+   */
+  function calcModalHeight(tableEl: Element) {
+    // 鎵句竴涓� table 鏄惁鍦� modal 鍐咃紝鑾峰緱 modal銆亀rap銆乫ooter锛屽苟鑰冭檻 fullscreen 鐨勬儏鍐�
+    let modalEl: Nullable<HTMLElement> = null;
+    let modalWrapEl: Nullable<HTMLElement> = null;
+    let modalFooterEl: Nullable<HTMLElement> = null;
+    let modalElIterator: HTMLElement = tableEl.parentElement!;
+    let modalIsFullscreen = false;
+    while (modalElIterator !== document.body) {
+      if (!modalElIterator) break;
+      if (modalElIterator.classList.contains('ant-modal')) {
+        modalEl = modalElIterator;
+        modalWrapEl = modalEl.parentElement;
+        modalFooterEl = modalElIterator.querySelector('.ant-modal-content>.ant-modal-footer');
+        modalIsFullscreen = modalWrapEl?.classList.contains('fullscreen-modal') ?? false;
+        break;
+      }
+      modalElIterator = modalElIterator.parentElement!;
+    }
+
+    if (modalEl) {
+      // table 鍦� modal 鍐�
+
+      // modal top
+      const { top: modalTop = 0 } = modalEl ? getViewportOffset(modalEl) : {};
+
+      // 鏉ヨ嚜浜� .ant-modal锛岄潪鍏ㄥ睆涓� 24锛屽叏灞忎负 0
+      const modalBottom = modalIsFullscreen ? 0 : 24;
+
+      //  modal footer 楂樺害
+      const modalFooterHeight = modalFooterEl?.offsetHeight ?? 0;
+
+      // modal footer 杈硅窛锛屾潵鑷簬 .ant-modal .ant-modal-footer
+      const modalFooterMarginTop = modalFooterEl
+        ? modalIsFullscreen
+          ? 0
+          : parseInt(getComputedStyle(modalFooterEl).marginTop)
+        : 0;
+
+      // 鏉ヨ嚜浜� .ant-modal .ant-modal-body > .scrollbar
+      const modalScrollBarHeight = 14;
+
+      return (
+        (modalTop > modalBottom ? modalTop : modalBottom) +
+        modalFooterHeight +
+        modalFooterMarginTop +
+        modalScrollBarHeight
+      );
+    }
+
+    // table 涓嶄綇 modal 鍐�
+    return 0;
+  }
+
+  /**
+   * 鏍规嵁鏍峰紡杩斿洖涓�浜涢棿璺濋珮搴�
+   * @returns number
+   */
+  function getMarginPaddingHeight() {
+    const { isCanResizeParent } = unref(propsRef);
+
+    if (unref(wrapRef) && isCanResizeParent) {
+      // 缁ф壙鐖跺厓绱犻珮搴�
+      return tableWrapperPadding;
+    }
+    return (
+      tableWrapperPadding + 16 // 鏉ヨ嚜浜� .vben-basic-table-form-container 鎴栨槸 .p-4
+    );
+  }
+
+  async function calcTableHeight() {
+    const { resizeHeightOffset, maxHeight } = unref(propsRef);
+    const tableData = unref(getDataSourceRef);
+
+    const table = unref(tableElRef);
+    if (!table) return;
+
+    const tableEl: Element = table.$el;
+    if (!tableEl) return;
+
+    if (!bodyEl) {
+      bodyEl = tableEl.querySelector('.ant-table-body');
+      if (!bodyEl) return;
+    }
+
+    handleScrollBar(bodyEl, tableEl);
 
     bodyEl!.style.height = 'unset';
 
@@ -97,74 +283,32 @@
 
     if (!headEl) return;
 
-    // Table height from bottom height-custom offset
-    let paddingHeight = 32;
-    // Pager height
-    let paginationHeight = 2;
-    if (!isBoolean(pagination)) {
-      paginationEl = tableEl.querySelector('.ant-pagination') as HTMLElement;
-      if (paginationEl) {
-        const offsetHeight = paginationEl.offsetHeight;
-        paginationHeight += offsetHeight || 0;
-      } else {
-        // TODO First fix 24
-        paginationHeight += 24;
-      }
-    } else {
-      paginationHeight = -8;
-    }
+    const paginationHeight = caclPaginationHeight(tableEl);
+    const footerHeight = caclFooterHeight(tableEl);
+    const headerHeight = calcHeaderHeight(headEl);
+    const bottomIncludeBody = calcBottomAndPaddingHeight(tableEl, headEl);
 
-    let footerHeight = 0;
-    if (!isBoolean(pagination)) {
-      if (!footerEl) {
-        footerEl = tableEl.querySelector('.ant-table-footer') as HTMLElement;
-      } else {
-        const offsetHeight = footerEl.offsetHeight;
-        footerHeight += offsetHeight || 0;
-      }
-    }
+    const modalHeight = calcModalHeight(tableEl);
 
-    let headerHeight = 0;
-    if (headEl) {
-      headerHeight = (headEl as HTMLElement).offsetHeight;
-    }
+    const marginPaddingHeight = getMarginPaddingHeight();
 
-    let bottomIncludeBody = 0;
-    if (unref(wrapRef) && isCanResizeParent) {
-      const tablePadding = 12;
-      const formMargin = 16;
-      let paginationMargin = 10;
-      const wrapHeight = unref(wrapRef)?.offsetHeight ?? 0;
-
-      let formHeight = unref(formRef)?.$el.offsetHeight ?? 0;
-      if (formHeight) {
-        formHeight += formMargin;
-      }
-      if (isBoolean(pagination) && !pagination) {
-        paginationMargin = 0;
-      }
-      if (isBoolean(useSearchForm) && !useSearchForm) {
-        paddingHeight = 0;
-      }
-
-      const headerCellHeight =
-        (tableEl.querySelector('.ant-table-title') as HTMLElement)?.offsetHeight ?? 0;
-
-      console.log(wrapHeight - formHeight - headerCellHeight - tablePadding - paginationMargin);
-      bottomIncludeBody =
-        wrapHeight - formHeight - headerCellHeight - tablePadding - paginationMargin;
-    } else {
-      // Table height from bottom
-      bottomIncludeBody = getViewportOffset(headEl).bottomIncludeBody;
-    }
-
-    let height =
+    // Math.floor 瀹佹効灏�1px锛屼篃涓嶆孩鍑�
+    let height = Math.floor(
       bottomIncludeBody -
-      (resizeHeightOffset || 0) -
-      paddingHeight -
-      paginationHeight -
-      footerHeight -
-      headerHeight;
+        (resizeHeightOffset || 0) -
+        paginationHeight -
+        footerHeight -
+        headerHeight -
+        // 寮圭獥锛堝鏋滄湁锛夌浉鍏抽珮搴�
+        modalHeight -
+        // 椤甸潰 footer 楂樺害锛堥潪寮圭獥鐨勬椂鍊欙級
+        (getShowFooter.value && modalHeight <= 0 ? layoutFooterHeight : 0) -
+        // 鏍峰紡闂磋窛楂樺害
+        marginPaddingHeight -
+        // 棰勭暀闈炴暣鏁伴珮搴︽孩鍑猴紙濡傚疄闄呴珮搴︿负100.5锛宱ffsetHeight 鐨勫�间负101锛�
+        1,
+    );
+
     height = (height > maxHeight! ? (maxHeight as number) : height) ?? height;
     setHeight(height);
 
@@ -191,7 +335,9 @@
     columns.forEach((item) => {
       width += Number.parseFloat(item.width as string) || 0;
     });
-    const unsetWidthColumns = columns.filter((item) => !Reflect.has(item, 'width'));
+    const unsetWidthColumns = columns.filter(
+      (item) => !Reflect.has(item, 'width') && item.ifShow !== false,
+    );
 
     const len = unsetWidthColumns.length;
     if (len !== 0) {
@@ -211,7 +357,7 @@
       y: canResize ? tableHeight : null,
       scrollToFirstRowOnChange: false,
       ...scroll,
-    };
+    } as BasicTableProps['scroll'];
   });
 
   return { getScrollRef, redoHeight };

--
Gitblit v1.9.3