Bläddra i källkod

fix(sampleListDialog): 修复样品列表弹窗的样式和功能问题(优化其高度问题)

xieyong 4 dagar sedan
förälder
incheckning
7eee6896e7
1 ändrade filer med 58 tillägg och 11 borttagningar
  1. 58 11
      src/views/inspectionWork/components/sampleListDialog.vue

+ 58 - 11
src/views/inspectionWork/components/sampleListDialog.vue

@@ -43,6 +43,13 @@
               :item-size="64"
               key-field="__vsKey"
               :buffer="200"
+              :style="{
+                height:
+                  Math.min(
+                    (props.row.qualitySampleTemplateList || []).length * 64,
+                    400
+                  ) + 'px'
+              }"
               v-if="(props.row.qualitySampleTemplateList || []).length"
             >
               <template #default="{ item }">
@@ -311,12 +318,55 @@
         scrollBound: false, // 滚动监听是否已绑定
         resizeObserver: null, // 监听 dialog body 大小变化
         isFullscreen: false, // 当前是否处于全屏
-        DEFAULT_TABLE_HEIGHT: 560, // 默认(非全屏)表格高度
-        tableHeight: 560, // 当前表格高度(全屏时由 recomputeTableHeight 重算)
+        DEFAULT_TABLE_HEIGHT: 560, // 默认(非全屏)表格最大高度
+        MAX_TABLE_HEIGHT: 560, // 硬上限:非全屏和全屏都受此限制
+        _fullscreenTableHeight: 560, // 全屏时由 recomputeTableHeight 重算(dialog body 高度)
         PRELOAD_COUNT: 3 // 预加载样品数(打开弹框时立即加载,滚动时永驻内存不卸载)
       };
     },
-    computed: {},
+    computed: {
+      // 表格高度:
+      //   - 非全屏:取"内容自然高度"和默认上限的较小者
+      //   - 全屏:取 dialog body 高度(recomputeTableHeight 重算)
+      //   - 两种情况都受 MAX_TABLE_HEIGHT 硬上限约束(避免 dialog body 很高时表格过大)
+      tableHeight() {
+        const cap = Math.min(
+          this.isFullscreen
+            ? this._fullscreenTableHeight
+            : this.DEFAULT_TABLE_HEIGHT,
+          this.MAX_TABLE_HEIGHT
+        );
+        // 最小 200,避免空数据/异常情况下表格太矮
+        return Math.max(200, Math.min(cap, this.naturalContentHeight));
+      },
+      // 估算 tableData 实际占的高度(el-table 的 :height 需要精确数字)
+      // 注意:内层 RecycleScroller 现在是动态高度(按模板数自适应,封顶 400),
+      // 这里要保持一致,否则估算会比实际大、表格会撑到 cap 而不是收缩
+      naturalContentHeight() {
+        const TABLE_HEADER = 44;       // el-table 表头
+        const MAIN_ROW = 48;            // 主行
+        const EXPAND_HEADER = 40;       // virtual-table-header(包含 padding)
+        const EXPAND_WRAPPER_PAD = 20;  // virtual-expand-wrapper 的上下 padding
+        const EXPAND_EMPTY = 56;        // "暂无检测项" 占位(padding 20 + 文本)
+        const SCROLLER_MAX = 400;       // RecycleScroller 高度封顶
+        const SCROLLER_ITEM = 64;       // 单个模板行高度
+
+        let h = TABLE_HEADER;
+        for (const row of this.tableData) {
+          h += MAIN_ROW;
+          const key = row.sampleCode || row.__rowKey;
+          const expanded = this.expandedKeys.includes(key);
+          if (expanded) {
+            const tplLen = (row.qualitySampleTemplateList || []).length;
+            h += EXPAND_HEADER + EXPAND_WRAPPER_PAD;
+            h += tplLen > 0
+              ? Math.min(tplLen * SCROLLER_ITEM, SCROLLER_MAX)
+              : EXPAND_EMPTY;
+          }
+        }
+        return h;
+      }
+    },
 
     created() {},
     beforeDestroy() {
@@ -370,7 +420,6 @@
           this.bindScrollListener();
           // 重置全屏状态并重新计算表格高度(防止上次打开残留全屏)
           this.isFullscreen = false;
-          this.tableHeight = this.DEFAULT_TABLE_HEIGHT;
           this.observeBodyResize();
         });
       },
@@ -417,14 +466,12 @@
         });
       },
 
-      // 重新计算表格高度:全屏时填满 dialog body,非全屏回到默认值
+      // 重新计算表格高度:仅全屏时需要——把 dialog body 高度写进 _fullscreenTableHeight;
+      // 非全屏由 computed tableHeight 直接用 DEFAULT_TABLE_HEIGHT,无需重算
       recomputeTableHeight() {
+        if (!this.isFullscreen) return;
         const tableEl = this.$refs.mainTable && this.$refs.mainTable.$el;
         if (!tableEl) return;
-        if (!this.isFullscreen) {
-          this.tableHeight = this.DEFAULT_TABLE_HEIGHT;
-          return;
-        }
         // 全屏:沿 DOM 找到 .el-dialog,再取 .el-dialog__body 的内容区高度
         // (不用 .ele-modal-wrap 这个 class——实际类名是 ele-modal-wrap-fullscreen)
         const dialog = tableEl.closest('.el-dialog');
@@ -434,7 +481,7 @@
         const style = getComputedStyle(body);
         const padTop = parseFloat(style.paddingTop) || 0;
         const padBottom = parseFloat(style.paddingBottom) || 0;
-        this.tableHeight = body.clientHeight - padTop - padBottom;
+        this._fullscreenTableHeight = body.clientHeight - padTop - padBottom;
       },
 
       // 监听 dialog body 尺寸变化(拖拽 / resize / 全屏切换都会触发)
@@ -720,7 +767,7 @@
   }
 
   .virtual-scroller {
-    height: 400px;
+    /* 高度由 :style 动态控制(按模板数量自适应,封顶 400) */
     border: 1px solid #ebeef5;
     border-top: none;
     background: #fff;