Selaa lähdekoodia

Merge remote-tracking branch 'origin/master'

lipenghui 3 viikkoa sitten
vanhempi
commit
958be47153

+ 380 - 60
src/views/pms/iotmainworkorder/DeviceAlarmBomList.vue

@@ -1,48 +1,85 @@
 <template>
   <Dialog v-model="dialogVisible"
           :title="t('monitor.details')"
-          style="width: 1500px"
+          :width="dialogWidth"
           class="fixed-height-dialog"
           @close="handleClose" >
-      <ContentWrap>
+    <ContentWrap>
+
+      <!-- 添加设备信息展示区域 -->
+      <div v-if="deviceInfo" class="device-info-card">
+        <div class="info-item">
+          <span class="info-label">{{ t('iotDevice.code') }}:</span>
+          <span class="info-value">{{ deviceInfo.deviceCode }}</span>
+        </div>
+        <div class="info-item">
+          <span class="info-label">{{ t('iotDevice.name') }}:</span>
+          <span class="info-value">{{ deviceInfo.deviceName }}</span>
+        </div>
+      </div>
+
+      <div class="table-container">
         <!-- 添加表格容器并设置滚动 -->
         <el-table
           v-loading="loading"
           :data="paginatedList"
           :stripe="true"
           :show-overflow-tooltip="true"
-          style="width: 100%"
+          style="width: auto"
           height="100%"
           class="scrollable-table"
+          ref="tableRef"
         >
-          <el-table-column :label="t('iotDevice.code')" align="center" prop="deviceCode" />
-          <el-table-column :label="t('iotDevice.name')" align="center" prop="deviceName" />
-          <el-table-column :label="t('operationFillForm.sumTime')" align="center" prop="totalRunTime" >
+          <el-table-column :label="t('iotDevice.code')" align="center" prop="deviceCode"
+                           :width="columnWidths.deviceCode" v-if="false"/>
+          <el-table-column :label="t('iotDevice.name')" align="center" prop="deviceName"
+                           :width="columnWidths.deviceName" v-if="false"/>
+          <el-table-column :label="t('mainPlan.MaintItems')" align="center" prop="name"
+                           :width="columnWidths.name"/>
+
+          <el-table-column :label="t('operationFillForm.sumTime')" align="center" prop="totalRunTime"
+                           :width="columnWidths.totalRunTime">
             <template #default="{ row }">
               {{ row.totalRunTime ?? row.tempTotalRunTime }}
             </template>
           </el-table-column>
-          <el-table-column :label="t('operationFillForm.sumKil')" align="center" prop="totalMileage" >
+          <el-table-column :label="t('operationFillForm.sumKil')" align="center" prop="totalMileage"
+                           :width="columnWidths.totalMileage">
             <template #default="{ row }">
               {{ row.totalMileage ?? row.tempTotalMileage }}
             </template>
           </el-table-column>
-          <el-table-column :label="t('mainPlan.MaintItems')" align="center" prop="name" />
-
-          <template v-if="showTimeColumns">
-            <el-table-column :label="t('mainPlan.lastMaintenanceOperationTime')" align="center" prop="lastRunningTime" />
-            <el-table-column :label="t('mainPlan.RunTimeCycle')" align="center" prop="nextRunningTime" />
-            <el-table-column :label="t('mainPlan.nextMaintTime')" align="center" prop="timePeriod" />
-          </template>
-
-          <template v-if="showMileageColumns">
-            <el-table-column :label="t('mainPlan.lastMaintenanceMileage')" align="center" prop="lastRunningKilometers" />
-            <el-table-column :label="t('mainPlan.operatingMileageCycle')" align="center" prop="nextRunningKilometers" />
-            <el-table-column :label="t('mainPlan.nextMaintKil')" align="center" prop="kilometerCycle" />
-          </template>
-
-          <template v-if="showNaturalDateColumns">
-            <el-table-column :label="t('mainPlan.lastMaintenanceOperationTime')" align="center" prop="lastNaturalDate"  width="220">
+
+          <!-- 时间分组列 -->
+          <el-table-column v-if="showTimeColumns" label="保养时长"
+                           align="center"
+                           :width="columnWidths.timeGroup">
+            <el-table-column :label="t('mainPlan.lastMaintenanceOperationTime')" align="center" prop="lastRunningTime"
+                             :width="columnWidths.lastRunningTime"/>
+            <el-table-column :label="t('mainPlan.RunTimeCycle')" align="center" prop="nextRunningTime"
+                             :width="columnWidths.nextRunningTime"/>
+            <el-table-column :label="t('mainPlan.nextMaintTime')" align="center" prop="timePeriod"
+                             :width="columnWidths.timePeriod"/>
+          </el-table-column>
+
+          <!-- 里程分组列 -->
+          <el-table-column v-if="showMileageColumns" label="保养里程"
+                           align="center"
+                           :width="columnWidths.mileageGroup">
+            <el-table-column :label="t('mainPlan.lastMaintenanceMileage')" align="center" prop="lastRunningKilometers"
+                             :width="columnWidths.lastRunningKilometers"/>
+            <el-table-column :label="t('mainPlan.operatingMileageCycle')" align="center" prop="nextRunningKilometers"
+                             :width="columnWidths.nextRunningKilometers"/>
+            <el-table-column :label="t('mainPlan.nextMaintKil')" align="center" prop="kilometerCycle"
+                             :width="columnWidths.kilometerCycle"/>
+          </el-table-column>
+
+          <!-- 日期分组列 -->
+          <el-table-column v-if="showNaturalDateColumns" label="保养日期"
+                           align="center"
+                           :width="columnWidths.dateGroup">
+            <el-table-column :label="t('mainPlan.lastMaintenanceOperationTime')" align="center" prop="lastNaturalDate"
+                             :width="columnWidths.lastNaturalDate">
               <template #default="scope">
                 <el-date-picker
                   v-model="scope.row.lastNaturalDate"
@@ -50,22 +87,25 @@
                   placeholder="选择日期"
                   format="YYYY-MM-DD"
                   value-format="YYYY-MM-DD"
-                  style="width: 60%"
+                  style="width: 100%"
                   :disabled="true"
                 />
               </template>
             </el-table-column>
-            <el-table-column :label="t('mainPlan.NaturalDailyCycle')" align="center" prop="nextNaturalDate" />
-            <el-table-column :label="t('mainPlan.nextMaintDate')" align="center" prop="naturalDatePeriod" />
-          </template>
+            <el-table-column :label="t('mainPlan.NaturalDailyCycle')" align="center" prop="nextNaturalDate"
+                             :width="columnWidths.nextNaturalDate"/>
+            <el-table-column :label="t('mainPlan.nextMaintDate')" align="center" prop="naturalDatePeriod"
+                             :width="columnWidths.naturalDatePeriod"/>
+          </el-table-column>
         </el-table>
-        <Pagination
-          :total="total"
-          v-model:page="queryParams.pageNo"
-          v-model:limit="queryParams.pageSize"
-          @pagination="handlePagination"
-        />
-      </ContentWrap>
+      </div>
+      <Pagination
+        :total="total"
+        v-model:page="queryParams.pageNo"
+        v-model:limit="queryParams.pageSize"
+        @pagination="handlePagination"
+      />
+    </ContentWrap>
   </Dialog>
 </template>
 
@@ -82,6 +122,12 @@ const loading = ref(true) // 列表的加载中
 const queryFormRef = ref() // 搜索的表单
 const list = ref<IotMaintenanceBomVO[]>([]) // 列表的数据
 const total = ref(0) // 列表的总页数
+
+const dialogWidth = '1500px';
+
+const tableRef = ref(null)    // 表格实例引用
+const columnWidths = ref({}) // 存储列宽的对象
+
 const queryParams = reactive({
   pageNo: 1,
   pageSize: 10,
@@ -96,6 +142,64 @@ const props = defineProps({
 
 const selectedRow = ref(null)
 
+const getTextWidth = (str: string) => {
+  if (!str) return 0;
+  if (widthCache.has(str)) return widthCache.get(str)!;
+
+  const span = document.createElement('span');
+  span.style.visibility = 'hidden';
+  span.style.position = 'absolute';
+  span.style.whiteSpace = 'nowrap';
+  span.style.font = '14px Microsoft YaHei';
+  span.textContent = str;
+
+  document.body.appendChild(span);
+  const width = span.offsetWidth;
+  document.body.removeChild(span);
+
+  widthCache.set(str, width);
+  return width;
+};
+
+// 添加列宽计算函数
+const widthCache = new Map<string, number>();
+
+const flexColumnWidth = (label: string, prop: keyof IotMaintenanceBomVO) => {
+  // 确保有数据时才计算
+  if (!paginatedList.value.length) return "auto";
+  // 基础内边距30px
+  const basePadding = 20;
+  const labelWidth = getActualWidth(label) + basePadding; // 文本宽度 + 内边距
+  // 计算内容最大宽度
+  let maxContentWidth = 0;
+  // 获取该列所有内容的宽度
+  for (const row of paginatedList.value) {
+    let value = "";
+
+    // 特殊列处理
+    if (prop === "totalRunTime") {
+      value = (row.totalRunTime ?? row.tempTotalRunTime)?.toString() || "";
+    } else if (prop === "totalMileage") {
+      value = (row.totalMileage ?? row.tempTotalMileage)?.toString() || "";
+    } else {
+      value = row[prop]?.toString() || "";
+    }
+
+    // 数值格式化
+    if (value && !isNaN(Number(value))) {
+      value = Number(value).toLocaleString();
+    }
+
+    const contentWidth = getActualWidth(value) + basePadding;
+    if (contentWidth > maxContentWidth) {
+      maxContentWidth = contentWidth;
+    }
+  }
+
+  // 返回较大值加上安全边距
+  return Math.max(labelWidth, maxContentWidth, 120) + "px";
+};
+
 // 处理单选逻辑
 const selectRow = (row) => {
   selectedRow.value = selectedRow.value?.id === row.id ? null : row
@@ -108,6 +212,67 @@ const handlePagination = () => {
   console.log("分页变化,当前页:", queryParams.pageNo);
 };
 
+// 改进的宽度计算函数
+const getActualWidth = (text: string) => {
+  if (!text) return 0;
+
+  // 更精准的字符宽度计算
+  const chineseChars = (text.match(/[\u4e00-\u9fa5]/g) || []).length;
+  const otherChars = text.length - chineseChars;
+
+  // 中文16px,英文9px
+  return chineseChars * 16 + otherChars * 9;
+};
+
+// 设置列宽
+const setColumnWidths = () => {
+  const widths: Record<string, string> = {};
+
+  // 固定列
+  // widths.deviceCode = flexColumnWidth(t('iotDevice.code'), 'deviceCode');
+  // widths.deviceName = flexColumnWidth(t('iotDevice.name'), 'deviceName');
+  widths.totalRunTime = flexColumnWidth(t('operationFillForm.sumTime'), 'totalRunTime');
+  widths.totalMileage = flexColumnWidth(t('operationFillForm.sumKil'), 'totalMileage');
+  widths.name = flexColumnWidth(t('mainPlan.MaintItems'), 'name');
+
+  // 动态列
+  if (showTimeColumns.value) {
+    widths.lastRunningTime = flexColumnWidth(t('mainPlan.lastMaintenanceOperationTime'), 'lastRunningTime');
+    widths.nextRunningTime = flexColumnWidth(t('mainPlan.RunTimeCycle'), 'nextRunningTime');
+    widths.timePeriod = flexColumnWidth(t('mainPlan.nextMaintTime'), 'timePeriod');
+    // 分组列宽度 = 子列宽度之和 + 边框补偿
+    widths.timeGroup = `${[
+      parseFloat(widths.lastRunningTime),
+      parseFloat(widths.nextRunningTime),
+      parseFloat(widths.timePeriod)
+    ].reduce((sum, w) => sum + w, 0) + 2}px`;
+  }
+
+  if (showMileageColumns.value) {
+    widths.lastRunningKilometers = flexColumnWidth(t('mainPlan.lastMaintenanceMileage'), 'lastRunningKilometers');
+    widths.nextRunningKilometers = flexColumnWidth(t('mainPlan.operatingMileageCycle'), 'nextRunningKilometers');
+    widths.kilometerCycle = flexColumnWidth(t('mainPlan.nextMaintKil'), 'kilometerCycle');
+    widths.mileageGroup = `${[
+      parseFloat(widths.lastRunningKilometers),
+      parseFloat(widths.nextRunningKilometers),
+      parseFloat(widths.kilometerCycle)
+    ].reduce((sum, w) => sum + w, 0) + 2}px`;
+  }
+
+  if (showNaturalDateColumns.value) {
+    widths.lastNaturalDate = flexColumnWidth(t('mainPlan.lastMaintenanceOperationTime'), 'lastNaturalDate'); // 固定日期选择器的宽度
+    widths.nextNaturalDate = flexColumnWidth(t('mainPlan.NaturalDailyCycle'), 'nextNaturalDate');
+    widths.naturalDatePeriod = flexColumnWidth(t('mainPlan.nextMaintDate'), 'naturalDatePeriod');
+    widths.dateGroup = `${[
+      parseFloat(widths.lastNaturalDate),
+      parseFloat(widths.nextNaturalDate),
+      parseFloat(widths.naturalDatePeriod)
+    ].reduce((sum, w) => sum + w, 0) + 2}px`;
+  }
+
+  columnWidths.value = widths;
+};
+
 // 分页计算属性
 const paginatedList = computed(() => {
   const start = (queryParams.pageNo - 1) * queryParams.pageSize;
@@ -137,7 +302,7 @@ const getWorkOrderList = async () => {
   loading.value = true
   try {
     const data = await IotMainWorkOrderBomApi.getWorkOrderBOMs(queryParams)
-    // 格式化日期字段 - 新增代码
+    // 格式化日期字段
     data.forEach(item => {
       if (item.lastNaturalDate) {
         // 将时间戳转换为 YYYY-MM-DD 格式
@@ -161,10 +326,11 @@ const getWorkOrderList = async () => {
 }
 
 const getPlanList = async () => {
+  widthCache.clear();
   loading.value = true
   try {
     const data = await IotMaintenanceBomApi.getMainPlanBOMs(queryParams)
-    // 格式化日期字段 - 新增代码
+    // 格式化日期字段
     data.forEach(item => {
       if (item.lastNaturalDate) {
         // 将时间戳转换为 YYYY-MM-DD 格式
@@ -184,9 +350,22 @@ const getPlanList = async () => {
     total.value = data.length
   } finally {
     loading.value = false
+    nextTick(setColumnWidths); // 数据加载后计算列宽
   }
 }
 
+// 添加设备信息计算属性
+const deviceInfo = computed(() => {
+  if (list.value.length > 0) {
+    const firstRecord = list.value[0];
+    return {
+      deviceCode: firstRecord.deviceCode,
+      deviceName: firstRecord.deviceName
+    };
+  }
+  return null;
+});
+
 const handleClose = () => {
   // 重置状态避免多个弹窗出现
   dialogVisible.value = false
@@ -235,17 +414,17 @@ const calculateNextNaturalDate = (item: IotMaintenanceBomVO): string => {
   return dayjs(item.lastNaturalDate).add(item.nextNaturalDate, 'day').format('YYYY-MM-DD')
 }
 
-// 新增计算属性:控制时间相关列的显示
+// 计算属性:控制时间相关列的显示
 const showTimeColumns = computed(() => {
   return paginatedList.value.some(item => item.runningTimeRule === 0);
 });
 
-// 新增计算属性:控制里程相关列的显示
+// 计算属性:控制里程相关列的显示
 const showMileageColumns = computed(() => {
   return paginatedList.value.some(item => item.mileageRule === 0);
 });
 
-// 新增计算属性:自然日期相关列的显示
+// 计算属性:自然日期相关列的显示
 const showNaturalDateColumns = computed(() => {
   return paginatedList.value.some(item => item.naturalDateRule === 0);
 });
@@ -265,41 +444,182 @@ const resetQuery = () => {
   handleQuery()
 }
 
+// 监听分页数据变化,重新设置列宽
+watch(paginatedList, () => {
+  nextTick(() => {
+    setColumnWidths();
+  });
+});
+
+// 监听动态列的变化
+watch([showTimeColumns, showMileageColumns, showNaturalDateColumns], () => {
+  nextTick(setColumnWidths);
+});
+
 </script>
 
 <style lang="scss" scoped>
-/* 新版CSS解决方案 */
-.fixed-height-dialog :deep(.el-dialog) {
-  width: 1500px !important; /* 合并原内联样式 */
-  height: 800px !important; /* 关键:固定高度 */
+
+/* 设备信息卡片样式 */
+.device-info-card {
   display: flex;
-  flex-direction: column;
+  flex-wrap: wrap;
+  gap: 24px; /* 项间距 */
+  margin-bottom: 16px;
+  padding: 16px;
+  background-color: #f8f9fa;
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+
+  .info-item {
+    display: flex;
+    align-items: center;
+
+    .info-label {
+      font-weight: 600;
+      color: #606266;
+      margin-right: 8px;
+      white-space: nowrap;
+    }
+
+    .info-value {
+      font-weight: 500;
+      color: #303133;
+      padding: 4px 12px;
+      background: #ffffff;
+      border-radius: 4px;
+      border: 1px solid #ebeef5;
+      min-width: 200px;
+    }
+  }
+}
+
+/* 分组表头样式 */
+:deep(.el-table .el-table__header .el-table-column--group) {
+  background-color: #f5f7fa;
+  font-weight: bold;
+
+  > .cell {
+    font-weight: bold;
+    color: #303133;
+  }
+
+  background-color: #f0f7ff;
+  border: 1px solid #409eff !important;
+  box-shadow: 0 2px 4px rgba(64, 158, 255, 0.2);
+
+  > .cell {
+    font-weight: 700;
+    color: #1d63dc;
+  }
 }
 
-.fixed-height-dialog :deep(.el-dialog__header) {
-  padding: 20px;
-  flex-shrink: 0; /* 防止标题栏压缩 */
+/* 加深所有单元格边框 */
+:deep(.el-table__header th) {
+  border: 1px solid #c0c4cc !important;
 }
 
-.fixed-height-dialog :deep(.el-dialog__body) {
+/* 分组内部单元格特殊样式 */
+:deep(.el-table-column--group .el-table__cell) {
+  border-top: 1px dashed #a0cfff !important;
+}
+
+/* 分组间垂直线 */
+:deep(.el-table-column--group) {
+  position: relative;
+
+  &::after {
+    content: "";
+    position: absolute;
+    right: -1px;
+    top: 0;
+    bottom: 0;
+    width: 2px;
+    background: linear-gradient(to bottom, #409eff, #79bbff);
+  }
+}
+
+/* 新版CSS解决方案 */
+.fixed-height-dialog {
+  :deep(.el-dialog) {
+    width: 1500px !important; /* 固定宽度 */
+    height: 85vh !important; /* 使用视口高度 */
+    display: flex;
+    flex-direction: column;
+    margin-top: 5vh !important; /* 垂直居中 */
+  }
+
+  /* 添加媒体查询,确保在小屏幕上也能完整显示 */
+  @media (max-width: 1500px) {
+    :deep(.el-dialog) {
+      width: 95% !important;
+      max-width: 1500px; /* 仍然限制最大宽度 */
+    }
+  }
+
+  :deep(.el-dialog__header) {
+    padding: 20px;
+    flex-shrink: 0;
+  }
+
+  :deep(.el-dialog__body) {
+    flex: 1;
+    padding: 10px 20px;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden; /* 防止内容溢出 */
+  }
+}
+
+/* 表格容器 */
+.table-container {
   flex: 1;
-  overflow: hidden; /* 隐藏外层滚动 */
-  padding: 10px 20px; /* 适当内边距 */
+  overflow: auto;
+  position: relative;
+
+  .scrollable-table {
+    width: 100%; /* 自适应宽度 */
+
+    :deep(.el-table__header) {
+      th {
+        white-space: nowrap !important; /* 强制表头不换行 */
+        text-overflow: ellipsis;
+        overflow: hidden;
+        padding: 8px 0; /* 增加内边距 */
+      }
+    }
+
+    :deep(.el-table__body) {
+      td {
+        white-space: nowrap !important; /* 强制内容不换行 */
+        text-overflow: ellipsis;
+        overflow: hidden;
+        padding: 8px 0; /* 增加内边距 */
+      }
+    }
+
+    :deep(.el-table__body-wrapper) {
+      overflow-x: hidden !important; /* 隐藏X轴滚动条 */
+    }
+  }
 }
 
-/* 表格滚动核心 */
-.scrollable-table {
-  height: 100% !important;
+/* 分页样式 */
+.pagination-footer {
+  margin-top: 15px;
+  flex-shrink: 0;
+}
 
-  :deep(.el-table__body-wrapper) {
-    overflow-y: auto !important;
-    max-height: calc(100% - 40px); /* 扣除表头高度 */
+/* 响应式处理 - 确保在小屏幕上布局合理 */
+@media (max-width: 1500px) {
+  .fixed-height-dialog :deep(.el-dialog) {
+    width: 95% !important;
+    max-width: 98vw;
   }
 
-  :deep(.el-table__header-wrapper) {
-    position: sticky;
-    top: 0;
-    z-index: 10;
+  .table-container {
+    overflow-x: auto;
   }
 }
+
 </style>

+ 156 - 16
src/views/pms/iotmainworkorder/WorkOrderMaterial.vue

@@ -1,5 +1,9 @@
 <template>
-  <Dialog v-model="dialogVisible" title="选择物料" style="width: 1200px; min-height: 400px">
+  <Dialog v-model="dialogVisible" title="选择物料" style="width: 1400px; min-height: 400px">
+
+    <div ref="measureSpan"
+         style="position:absolute;left:-9999px;top:-9999px;visibility:hidden;white-space:nowrap;padding:0 15px;font:14px Arial, PingFang SC, Microsoft YaHei, sans-serif;">
+    </div>
 
     <!-- 设备分类和BOM节点信息显示 -->
     <div style="margin: 0 0px 15px; background: #f5f7fa; padding: 12px 20px; border-radius: 4px;">
@@ -123,7 +127,7 @@
         :data="list"
         :stripe="true"
         ref="tableRef"
-        :show-overflow-tooltip="true"
+        class="adaptive-table"
         @row-click="handleRowClick"
         :row-class-name="rowClassName"
       >
@@ -152,8 +156,7 @@
           :label="t('workOrderMaterial.factory')"
           align="center"
           prop="factory"
-          :show-overflow-tooltip="true"
-          class="!w-100px"
+          :width="flexColumnWidth('factory', t('workOrderMaterial.factory'))"
         />
         <el-table-column
           :label="t('workOrderMaterial.costCenter')"
@@ -166,8 +169,7 @@
           :label="t('workOrderMaterial.costCenter')"
           align="center"
           prop="costCenter"
-          :show-overflow-tooltip="true"
-          class="!w-100px"
+          :width="flexColumnWidth('costCenter', t('workOrderMaterial.costCenter'))"
         />
         <el-table-column
           :label="t('workOrderMaterial.storageLocation')"
@@ -180,27 +182,23 @@
           :label="t('workOrderMaterial.storageLocation')"
           align="center"
           prop="projectDepartment"
-          :show-overflow-tooltip="true"
-          class="!w-100px"
+          :width="flexColumnWidth('projectDepartment', t('workOrderMaterial.storageLocation'))"
         />
         <el-table-column
           :label="t('workOrderMaterial.materialCode')"
           align="center"
           prop="materialCode"
-          :show-overflow-tooltip="true"
-          class="!w-100px"
+          :width="flexColumnWidth('materialCode', t('workOrderMaterial.materialCode'))"
         />
         <el-table-column
           :label="t('workOrderMaterial.materialName')"
           align="center"
           prop="materialName"
-          :show-overflow-tooltip="true"
+          :class-name="'material-name-cell'"
+          :width="materialNameWidth"
         />
-        <el-table-column :label="t('workOrderMaterial.unit')" align="center" prop="unit" />
-        <el-table-column :label="t('workOrderMaterial.unitPrice')" align="center" prop="unitPrice" />
-        <el-table-column :label="t('workOrderMaterial.total')" align="center" prop="totalInventoryQuantity" />
-        <el-table-column :label="t('workOrderMaterial.source')" align="center" prop="materialSource" />
-        <el-table-column :label="t('workOrderMaterial.ConsumptionQuantity')" align="center" prop="quantity">
+        <el-table-column :label="t('workOrderMaterial.ConsumptionQuantity')" align="center" prop="quantity"
+                         :width="flexColumnWidth('quantity', t('workOrderMaterial.ConsumptionQuantity'), 20)">
           <template #default="scope">
             <el-input
               type="number"
@@ -212,6 +210,15 @@
             />
           </template>
         </el-table-column>
+        <el-table-column :label="t('workOrderMaterial.unit')" align="center" prop="unit"
+                         :width="flexColumnWidth('unit', t('workOrderMaterial.unit'))"/>
+        <el-table-column :label="t('workOrderMaterial.unitPrice')" align="center" prop="unitPrice"
+                         :width="flexColumnWidth('unitPrice', t('workOrderMaterial.unitPrice'))"/>
+        <el-table-column :label="t('workOrderMaterial.total')" align="center" prop="totalInventoryQuantity"
+                         :width="flexColumnWidth('totalInventoryQuantity', t('workOrderMaterial.total'))"/>
+        <el-table-column :label="t('workOrderMaterial.source')" align="center" prop="materialSource"
+                         :width="flexColumnWidth('materialSource', t('workOrderMaterial.source'))"/>
+
       </el-table>
       <!-- 分页 -->
       <Pagination
@@ -252,8 +259,15 @@ const queryFormRef = ref() // 搜索的表单
 const list = ref<WorkOrderBomMaterialApi.IotMainWorkOrderBomMaterialVO[]>([]) // 列表的数据
 const total = ref(0) // 列表的总页数
 const tableRef = ref()
+const tableContainer = ref<HTMLElement | null>(null) // 表格容器引用
 const selectedRows = ref<WorkOrderBomMaterialApi.IotMainWorkOrderBomMaterialVO[]>([]) // 多选数据(存储所有选中行的数组)
 
+// 物料名称列宽度(作为基准列)
+const materialNameWidth = ref<number | string>(0)
+
+// 测量容器引用
+const measureSpan = ref<HTMLDivElement | null>(null)
+
 const showMaterialArea = ref(false) // 控制A区域显示状态
 const deviceBomMaterials = ref<any[]>([]) // 存储绑定物料数据
 
@@ -356,6 +370,85 @@ const open = async (deptId: number, bomNodeId: number, row: any, type: string) =
 
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 
+// 文本宽度测量
+const getTextWidth = (text: string) => {
+  if (!measureSpan.value) return 0
+  measureSpan.value.innerText = text
+  return measureSpan.value.offsetWidth
+}
+
+// 列宽计算方法
+const flexColumnWidth = (prop: string, label: string, extra: number = 0) => {
+  if (!list.value || list.value.length === 0) {
+    return getTextWidth(label) + extra
+  }
+
+  const contentList = list.value.map(item => {
+    const value = item[prop]
+    if (value == null) return ' '
+    return typeof value === 'number' ? value.toString() : value
+  })
+
+  contentList.push(label)
+  const maxWidth = Math.max(...contentList.map(text => getTextWidth(text)))
+  return Math.min(maxWidth + extra, 400)
+}
+
+// 计算所有列的总宽度(物料名称列除外)
+const calculateTotalColumnWidth = () => {
+  const columns = [
+    // 复选框列(固定60px)
+    60,
+    // 工厂列
+    flexColumnWidth('factory', t('workOrderMaterial.factory')),
+    // 成本中心列
+    flexColumnWidth('costCenter', t('workOrderMaterial.costCenter')),
+    // 库存地点列
+    flexColumnWidth('projectDepartment', t('workOrderMaterial.storageLocation')),
+    // 物料编码列
+    flexColumnWidth('materialCode', t('workOrderMaterial.materialCode')),
+    // 消耗数量列
+    flexColumnWidth('quantity', t('workOrderMaterial.ConsumptionQuantity'), 20),
+    // 单位列
+    flexColumnWidth('unit', t('workOrderMaterial.unit')),
+    // 单价列
+    flexColumnWidth('unitPrice', t('workOrderMaterial.unitPrice')),
+    // 总库存数量列
+    flexColumnWidth('totalInventoryQuantity', t('workOrderMaterial.total')),
+    // 来源列
+    flexColumnWidth('materialSource', t('workOrderMaterial.source'))
+  ]
+
+  return columns.reduce((total, width) => total + width, 0)
+}
+
+// 调整物料名称列宽度(作为基准列)
+const adjustMaterialNameWidth = () => {
+  nextTick(() => {
+    if (!tableContainer.value) return
+
+    // 获取表格容器的宽度
+    const containerWidth = tableContainer.value.$el.clientWidth
+
+    // 计算所有列的总宽度(物料名称列除外)
+    const totalWidth = calculateTotalColumnWidth()
+
+    // 计算可用空间(预留20px用于边框和滚动条)
+    const availableSpace = containerWidth - totalWidth - 20
+
+    if (availableSpace > 0) {
+      // 如果空间足够,分配剩余空间给物料名称列
+      materialNameWidth.value = Math.max(
+        flexColumnWidth('materialName', t('workOrderMaterial.materialName')),
+        availableSpace
+      )
+    } else {
+      // 如果空间不足,按内容自适应
+      materialNameWidth.value = flexColumnWidth('materialName', t('workOrderMaterial.materialName'))
+    }
+  })
+}
+
 const getList = async () => {
   loading.value = true
   try {
@@ -366,6 +459,10 @@ const getList = async () => {
     total.value = data.total
   } finally {
     loading.value = false
+    // 数据加载完成后调整基准列宽度
+    nextTick(() => {
+      adjustMaterialNameWidth()
+    })
   }
 }
 
@@ -496,6 +593,22 @@ const resetQuery = () => {
   Object.assign(queryParams, defaultQueryParams)
   handleQuery()
 }
+
+// 窗口大小改变时重新计算列宽
+const handleResize = () => {
+  adjustMaterialNameWidth()
+}
+
+onMounted(() => {
+  // 添加窗口大小变化监听器
+  window.addEventListener('resize', handleResize)
+})
+
+onUnmounted(() => {
+  // 移除窗口大小变化监听器
+  window.removeEventListener('resize', handleResize)
+})
+
 </script>
 <style lang="scss" scoped>
 .no-label-radio .el-radio__label {
@@ -532,4 +645,31 @@ const resetQuery = () => {
 :deep(.el-table .bg-blue-5) {
   background-color: #3fa5de !important; /* Element Plus 绿色背景 */
 }
+
+// 表格自适应样式
+:deep(.adaptive-table) {
+  width: 100%;
+
+  .el-table__cell {
+    .cell {
+      white-space: nowrap; /* 禁止换行 */
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+  }
+  // 确保基准列使用可用空间
+  .material-name-cell .cell {
+    display: block;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    max-width: 100%;
+  }
+
+}
+
+// 移除溢出提示(防止省略号)
+:deep(.el-tooltip) {
+  overflow: visible !important;
+}
+
 </style>