Browse Source

pms 保养计划 选择设备 列表垂直滚动

zhangcl 2 weeks ago
parent
commit
15ecd3c571
1 changed files with 220 additions and 37 deletions
  1. 220 37
      src/views/pms/maintenance/MainPlanDeviceList.vue

+ 220 - 37
src/views/pms/maintenance/MainPlanDeviceList.vue

@@ -1,7 +1,9 @@
 <template>
   <Dialog v-model="dialogVisible" :title="t('deviceList.selectDevice')"
-          style="width: 1100px; max-height: 800px"  @close="handleClose" :close-on-click-modal="false">
-    <ContentWrap>
+          :style="{ width: dialogWidth }"
+          :body-style="{ height: '100%' }"
+          class="device-select-dialog"  @close="handleClose" :close-on-click-modal="false">
+    <ContentWrap class="dialog-top">
       <el-form
         class="-mb-15px"
         :model="queryParams"
@@ -36,43 +38,48 @@
         </el-form-item>
       </el-form>
     </ContentWrap>
-    <ContentWrap>
-      <el-table
-        v-loading="loading"
-        :data="list"
-        :stripe="true"
-        ref="tableRef"
-        :show-overflow-tooltip="true"
-        @row-click="handleRowClick"
-      >
-        <el-table-column width="70" :label="t('workOrderMaterial.select')">
-          <template #default="{ row }">
-            <el-checkbox
-              :model-value="selectedRows.some(item => item.id === row.id)"
-              @click.stop="toggleRow(row)"
-              class="no-label-radio"
-            />
-          </template>
-        </el-table-column>
-        <el-table-column :label="t('chooseMaintain.deviceCode')" align="center" prop="deviceCode" />
-        <el-table-column :label="t('deviceList.deviceName')" align="center" prop="deviceName" />
-        <el-table-column :label="t('faultForm.deptId')" align="center" prop="deptId" v-if="false"/>
-        <el-table-column :label="t('iotDevice.dept')" align="center" prop="deptName" />
-        <el-table-column :label="t('iotDevice.status')" align="center" prop="deviceStatus">
-          <template #default="scope">
-            <dict-tag :type="DICT_TYPE.PMS_DEVICE_STATUS" :value="scope.row.deviceStatus" />
-          </template>
-        </el-table-column>
-        <el-table-column
-          :label="t('deviceList.createTime')"
-          align="center"
-          prop="createTime"
-          width="180"
-          :formatter="dateFormatter"
-        />
-      </el-table>
+    <ContentWrap class="table-container">
+      <div class="table-wrapper">
+        <el-table
+          v-loading="loading"
+          :data="list"
+          :stripe="true"
+          ref="tableRef"
+          :show-overflow-tooltip="true"
+          @row-click="handleRowClick"
+          :max-height="effectiveTableHeight"
+        >
+          <el-table-column width="70" :label="t('workOrderMaterial.select')">
+            <template #default="{ row }">
+              <el-checkbox
+                :model-value="selectedRows.some(item => item.id === row.id)"
+                @click.stop="toggleRow(row)"
+                class="no-label-radio"
+              />
+            </template>
+          </el-table-column>
+          <el-table-column :label="t('chooseMaintain.deviceCode')" align="center" prop="deviceCode" />
+          <el-table-column :label="t('deviceList.deviceName')" align="center" prop="deviceName" />
+          <el-table-column :label="t('faultForm.deptId')" align="center" prop="deptId" v-if="false"/>
+          <el-table-column :label="t('iotDevice.dept')" align="center" prop="deptName" />
+          <el-table-column :label="t('iotDevice.status')" align="center" prop="deviceStatus">
+            <template #default="scope">
+              <dict-tag :type="DICT_TYPE.PMS_DEVICE_STATUS" :value="scope.row.deviceStatus" />
+            </template>
+          </el-table-column>
+          <el-table-column
+            :label="t('deviceList.createTime')"
+            align="center"
+            prop="createTime"
+            width="180"
+            :formatter="dateFormatter"
+          />
+        </el-table>
+      </div>
+
       <!-- 分页 -->
       <Pagination
+        v-if="showPagination"
         :total="total"
         v-model:page="queryParams.pageNo"
         v-model:limit="queryParams.pageSize"
@@ -115,6 +122,14 @@ const queryParams = reactive({
   code: undefined
 })
 
+// 新增响应式变量
+const dialogWidth = ref('1100px');
+const tableMinHeight = ref(400); // 初始最小高度
+const effectiveTableHeight = ref<number | null>(null); // 单一高度变量
+const tableDynamicHeight = ref('auto'); // 新增动态高度变量
+const dialogTopRef = ref<HTMLElement | null>(null);
+const showPagination = ref(false); // 控制分页显示
+
 // 点击整行选中
 const handleRowClick = (row) => {
   toggleRow(row)
@@ -124,10 +139,30 @@ const open = async () => {
   // 重置为初始参数(保留分页设置)
   Object.assign(queryParams, initialQueryParams)
   queryFormRef.value?.resetFields()
+
+  // 初始隐藏分页组件
+  showPagination.value = false;
+
   await getList()
+
+  // 动态计算宽度
+  await nextTick();
+  const viewportWidth = window.innerWidth;
+  if (viewportWidth < 1200) {
+    // 小屏幕自适应
+    dialogWidth.value = Math.min(1100, viewportWidth - 40) + 'px';
+  } else {
+    // 大屏幕保持固定
+    dialogWidth.value = '1100px';
+  }
+  // 确保计算高度的DOM已渲染
+  await nextTick();
+  calculateTableHeight();
 }
+
 defineExpose({ open })
 const { wsCache } = useCache()
+
 const getList = async () => {
   loading.value = true
   try {
@@ -136,11 +171,55 @@ const getList = async () => {
     const data = await IotDeviceApi.getIotDevicePage(queryParams)
     list.value = data.list
     total.value = data.total
+
+    // 只有在需要时才显示分页
+    showPagination.value = total.value > queryParams.pageSize;
+    // 数据加载完成后重新计算高度
+    await nextTick();
+    calculateTableHeight();
   } finally {
     loading.value = false
   }
 }
 
+// 计算表格最大高度
+const calculateTableHeight = () => {
+  nextTick(() => {
+    try {
+      // 获取对话框实际可用空间
+      const dialogBody = document.querySelector('.el-dialog__body');
+      if (!dialogBody || !dialogTopRef.value) return;
+
+      const dialogBodyRect = dialogBody.getBoundingClientRect();
+
+      // 计算可用高度 = 对话框body高度 - 顶部表单高度 - 内边距
+      const dialogPadding = 20; // 上下内边距
+      const topHeight = dialogTopRef.value.offsetHeight;
+      const availableHeight = dialogBodyRect.height - topHeight - dialogPadding;
+
+      // 保证最小高度
+      let calculatedHeight = Math.max(availableHeight, tableMinHeight.value);
+
+      // 根据记录数量计算所需高度(考虑表头和行高)
+      const headerHeight = 40; // 表头高度估算
+      const rowHeight = 48; // 行高估算(增加8px用于行间分割线)
+      const totalRowsHeight = headerHeight + (list.value.length * rowHeight);
+
+      // 如果所需高度小于可用高度,则按实际高度显示
+      if (totalRowsHeight < availableHeight) {
+        calculatedHeight = totalRowsHeight;
+      }
+
+      // 确保高度合理
+      effectiveTableHeight.value = Math.max(calculatedHeight, 300);
+    } catch (e) {
+      console.error("高度计算错误:", e);
+      // 设置回退高度
+      effectiveTableHeight.value = 500;
+    }
+  });
+};
+
 const initialQueryParams = {
   pageNo: 1,
   pageSize: 10,
@@ -209,8 +288,103 @@ const resetQuery = () => {
   queryFormRef.value?.resetFields()
   handleQuery()
 }
+
+// 监听列表变化动态调整高度
+watch(list, () => {
+  calculateTableHeight();
+});
+
+// 监听窗口大小变化
+onMounted(() => {
+  window.addEventListener('resize', calculateTableHeight);
+});
+
+onUnmounted(() => {
+  window.removeEventListener('resize', calculateTableHeight);
+});
+
 </script>
 <style lang="scss" scoped>
+
+/* 新增样式 */
+.device-select-dialog {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+
+  // 增强弹窗高度利用
+  ::v-deep(.el-dialog) {
+    max-height: 85vh;
+    display: flex;
+    flex-direction: column;
+
+    .el-dialog__header {
+      padding: 15px 20px;
+    }
+
+    .el-dialog__body {
+      display: flex;
+      flex-direction: column;
+      flex: 1;
+      padding: 15px;
+      overflow: hidden;
+    }
+  }
+}
+
+/* 列宽度保证 - 防止挤压 */
+.el-table {
+  ::v-deep(.el-table__cell) {
+    min-width: 80px;
+
+    &:first-child {
+      min-width: 60px;
+    }
+
+    &:nth-child(2),
+    &:nth-child(3) {
+      min-width: 120px;
+    }
+  }
+
+  // 行高增加,提升可读性
+  ::v-deep(.el-table__row) {
+    height: 40px;
+  }
+}
+
+.dialog-top {
+  flex-shrink: 0;
+  margin-bottom: 15px;
+
+  .el-form {
+    padding: 5px 0; // 减少表单内边距
+  }
+}
+
+.table-container {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  min-height: 0;
+  max-height: 100%;
+
+  .table-wrapper {
+    overflow: visible !important;
+    .el-table {
+      // 表格自带的滚动机制
+      ::v-deep(.el-table__body-wrapper) {
+        overflow-y: auto !important;
+      }
+    }
+  }
+}
+
+.table-wrapper {
+  flex: 1;
+  overflow-y: auto; /* 内部滚动 */
+}
+
 .no-label-radio .el-radio__label {
   display: none;
 }
@@ -237,4 +411,13 @@ const resetQuery = () => {
   background-color: #c2dca8;
   border-color: #c2dca8;
 }
+
+// 分页样式优化 - 弹性位置
+.pagination-container {
+  margin-top: auto; // 将分页推到底部
+  padding: 15px 0 5px;
+  background: white; // 防止内容重叠
+  z-index: 10;
+}
+
 </style>