浏览代码

pms 填报保养工单 选择物料 样式调整 列宽度自适应

zhangcl 3 周之前
父节点
当前提交
8d9fed5831
共有 1 个文件被更改,包括 156 次插入16 次删除
  1. 156 16
      src/views/pms/iotmainworkorder/WorkOrderMaterial.vue

+ 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>