|
@@ -69,35 +69,56 @@
|
|
|
</ContentWrap>
|
|
|
|
|
|
<!-- 列表 -->
|
|
|
- <ContentWrap>
|
|
|
- <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
|
|
- <el-table-column :label="t('iotDevice.serial')" width="70" align="center">
|
|
|
+ <ContentWrap ref="tableContainerRef" class="table-wrap">
|
|
|
+ <el-table v-loading="loading" :data="list" :stripe="true" style="width: 100%" ref="tableRef">
|
|
|
+ <el-table-column :label="t('iotDevice.serial')" align="center" :width="columnWidths.serial">
|
|
|
<template #default="scope">
|
|
|
{{ scope.$index + 1 }}
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<!--
|
|
|
<el-table-column label="工单号" align="center" prop="orderNumber" /> -->
|
|
|
- <el-table-column :label="t('bomList.name')" align="center" prop="name" />
|
|
|
- <el-table-column :label="t('bomList.status')" align="center" prop="result" >
|
|
|
+ <el-table-column :label="t('bomList.name')" align="left" prop="name" :width="columnWidths.name"/>
|
|
|
+ <el-table-column :label="t('bomList.status')" align="center" prop="result" :width="columnWidths.result">
|
|
|
<template #default="scope">
|
|
|
<dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT" :value="scope.row.result" />
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column :label="t('bomList.serviceDue')" align="center">
|
|
|
+ <el-table-column :label="t('bomList.serviceDue')" align="center" :width="columnWidths.serviceDue">
|
|
|
<template #default="scope">
|
|
|
<span :class="getDistanceClass(scope.row.mainDistance)">
|
|
|
{{ scope.row.mainDistance }}
|
|
|
</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column :label="t('bomList.type')" align="center" prop="type" >
|
|
|
+ <el-table-column :label="t('bomList.type')" align="center" prop="type" :width="columnWidths.type">
|
|
|
<template #default="scope">
|
|
|
<dict-tag :type="DICT_TYPE.PMS_MAIN_WORK_ORDER_TYPE" :value="scope.row.type" />
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column :label="t('iotMaintain.PersonInCharge')" align="center" prop="responsiblePersonName" />
|
|
|
- <el-table-column :label="t('iotMaintain.operation')" align="center" min-width="120px">
|
|
|
+ <el-table-column :label="t('iotMaintain.PersonInCharge')" align="center"
|
|
|
+ prop="responsiblePersonName" :width="columnWidths.responsiblePersonName"/>
|
|
|
+ <el-table-column
|
|
|
+ :label="t('dict.createTime')"
|
|
|
+ align="center"
|
|
|
+ prop="createTime"
|
|
|
+ :formatter="dateFormatter"
|
|
|
+ :width="columnWidths.createTime"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ :label="t('dict.fillTime')"
|
|
|
+ align="center"
|
|
|
+ prop="updateTime"
|
|
|
+ :width="columnWidths.updateTime"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ <span v-if="scope.row.result == 2">
|
|
|
+ {{ formatCellDate(scope.row.updateTime) }}
|
|
|
+ </span>
|
|
|
+ <span v-else></span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column :label="t('iotMaintain.operation')" align="center" :width="columnWidths.operation">
|
|
|
<template #default="scope">
|
|
|
<el-button
|
|
|
link
|
|
@@ -155,7 +176,10 @@ defineOptions({ name: 'IotMainWorkOrder' })
|
|
|
|
|
|
const message = useMessage() // 消息弹窗
|
|
|
const { t } = useI18n() // 国际化
|
|
|
+const tableRef = ref() // 表格引用
|
|
|
|
|
|
+// 表格容器引用 用于获取容器宽度
|
|
|
+const tableContainerRef = ref()
|
|
|
const loading = ref(true) // 列表的加载中
|
|
|
const list = ref<IotMainWorkOrderVO[]>([]) // 列表的数据
|
|
|
const total = ref(0) // 列表的总页数
|
|
@@ -186,6 +210,141 @@ const queryParams = reactive({
|
|
|
const queryFormRef = ref() // 搜索的表单
|
|
|
const exportLoading = ref(false) // 导出的加载中
|
|
|
|
|
|
+// 列宽度配置
|
|
|
+const columnWidths = ref({
|
|
|
+ serial: '80px',
|
|
|
+ name: '1',
|
|
|
+ result: '120px',
|
|
|
+ serviceDue: '150px',
|
|
|
+ type: '120px',
|
|
|
+ responsiblePersonName: '150px',
|
|
|
+ createTime: '180px',
|
|
|
+ updateTime: '180px',
|
|
|
+ operation: '180px'
|
|
|
+})
|
|
|
+
|
|
|
+// 计算文本宽度
|
|
|
+const getTextWidth = (text: string, fontSize = 14) => {
|
|
|
+ const span = document.createElement('span');
|
|
|
+ span.style.visibility = 'hidden';
|
|
|
+ span.style.position = 'absolute';
|
|
|
+ span.style.whiteSpace = 'nowrap';
|
|
|
+ span.style.fontSize = `${fontSize}px`;
|
|
|
+ span.style.fontFamily = 'inherit';
|
|
|
+ span.innerText = text;
|
|
|
+
|
|
|
+ document.body.appendChild(span);
|
|
|
+ const width = span.offsetWidth;
|
|
|
+ document.body.removeChild(span);
|
|
|
+
|
|
|
+ return width;
|
|
|
+};
|
|
|
+
|
|
|
+// 计算列宽度
|
|
|
+const calculateColumnWidths = () => {
|
|
|
+ const MIN_WIDTH = 80; // 最小列宽
|
|
|
+ const PADDING = 25; // 列内边距
|
|
|
+ const FIXED_COLUMN_PADDING = 15; // 固定列额外内边距
|
|
|
+
|
|
|
+ // 可伸缩列的key(这里设置为名称列)
|
|
|
+ const FLEXIBLE_COLUMN = 'name';
|
|
|
+
|
|
|
+ // 需要自适应的列配置
|
|
|
+ const autoColumns = [
|
|
|
+ { key: 'serial', label: t('iotDevice.serial'), getValue: (row, index) => `${index + 1}` },
|
|
|
+ { key: 'name', label: t('bomList.name'), getValue: (row) => row.name },
|
|
|
+ {
|
|
|
+ key: 'result',
|
|
|
+ label: t('bomList.status'),
|
|
|
+ getValue: (row) => {
|
|
|
+ const dict = getStrDictOptions(DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT)
|
|
|
+ .find(d => d.value === row.result);
|
|
|
+ return dict ? dict.label : '';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { key: 'serviceDue', label: t('bomList.serviceDue'), getValue: (row) => row.mainDistance || '' },
|
|
|
+ {
|
|
|
+ key: 'type',
|
|
|
+ label: t('bomList.type'),
|
|
|
+ getValue: (row) => {
|
|
|
+ const dict = getStrDictOptions(DICT_TYPE.PMS_MAIN_WORK_ORDER_TYPE)
|
|
|
+ .find(d => d.value === row.type);
|
|
|
+ return dict ? dict.label : '';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { key: 'responsiblePersonName', label: t('iotMaintain.PersonInCharge'), getValue: (row) => row.responsiblePersonName },
|
|
|
+ { key: 'createTime', label: t('dict.createTime'), getValue: (row) => dateFormatter(null, null, row.createTime) },
|
|
|
+ {
|
|
|
+ key: 'updateTime',
|
|
|
+ label: t('dict.fillTime'),
|
|
|
+ getValue: (row) => row.result == 2 ? formatCellDate(row.updateTime) : ''
|
|
|
+ },
|
|
|
+ { key: 'operation', label: t('iotMaintain.operation'), fixedWidth: 180 } // 操作列固定宽度
|
|
|
+ ];
|
|
|
+
|
|
|
+ const newWidths: Record<string, string> = {};
|
|
|
+
|
|
|
+ let totalFixedWidth = 0; // 所有固定宽度列的总和 用于计算剩余空间
|
|
|
+
|
|
|
+ // 先计算所有非伸缩列的宽度
|
|
|
+ autoColumns.forEach(col => {
|
|
|
+ if (col.fixedWidth) {
|
|
|
+ newWidths[col.key] = `${col.fixedWidth}px`;
|
|
|
+ if (col.key !== FLEXIBLE_COLUMN) {
|
|
|
+ totalFixedWidth += col.fixedWidth;
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 跳过伸缩列
|
|
|
+ if (col.key === FLEXIBLE_COLUMN) return;
|
|
|
+
|
|
|
+ const headerText = col.label;
|
|
|
+ const headerWidth = getTextWidth(headerText) * 1.2;
|
|
|
+
|
|
|
+ // 计算内容最大宽度
|
|
|
+ let contentMaxWidth = 0;
|
|
|
+ list.value.forEach((row, index) => {
|
|
|
+ const text = col.getValue ? String(col.getValue(row, index)) : String(row[col.key] || '');
|
|
|
+ const textWidth = getTextWidth(text);
|
|
|
+ if (textWidth > contentMaxWidth) contentMaxWidth = textWidth;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 取最大值并添加内边距
|
|
|
+ const finalWidth = Math.max(headerWidth, contentMaxWidth, MIN_WIDTH) + PADDING;
|
|
|
+ newWidths[col.key] = `${finalWidth}px`;
|
|
|
+ totalFixedWidth += finalWidth;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 计算伸缩列所需的宽度
|
|
|
+ if (tableContainerRef.value?.$el) {
|
|
|
+ const containerWidth = tableContainerRef.value.$el.clientWidth;
|
|
|
+ // 计算剩余空间:容器宽度 - 所有固定列宽度 - 滚动条宽度(17px)
|
|
|
+ const remainingWidth = containerWidth - totalFixedWidth - 17;
|
|
|
+
|
|
|
+ if (remainingWidth > MIN_WIDTH) {
|
|
|
+ // 将剩余宽度分配给伸缩列
|
|
|
+ newWidths[FLEXIBLE_COLUMN] = `${Math.max(remainingWidth, MIN_WIDTH)}px`;
|
|
|
+ } else {
|
|
|
+ // 空间不足时使用内容宽度
|
|
|
+ const headerText = t('bomList.name');
|
|
|
+ const headerWidth = getTextWidth(headerText) * 1.2;
|
|
|
+ newWidths[FLEXIBLE_COLUMN] = `${Math.max(headerWidth, MIN_WIDTH) + PADDING}px`;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 默认处理
|
|
|
+ newWidths[FLEXIBLE_COLUMN] = '200px';
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新列宽度
|
|
|
+ columnWidths.value = newWidths;
|
|
|
+
|
|
|
+ // 重新布局表格
|
|
|
+ nextTick(() => {
|
|
|
+ tableRef.value?.doLayout();
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
/** 查询列表 */
|
|
|
const getList = async () => {
|
|
|
loading.value = true
|
|
@@ -193,11 +352,23 @@ const getList = async () => {
|
|
|
const data = await IotMainWorkOrderApi.sortedMainWorkOrderPage(queryParams)
|
|
|
list.value = data.list
|
|
|
total.value = data.total
|
|
|
+
|
|
|
+ // 数据加载后计算列宽
|
|
|
+ nextTick(() => {
|
|
|
+ calculateColumnWidths()
|
|
|
+ window.dispatchEvent(new Event('resize'))
|
|
|
+ })
|
|
|
} finally {
|
|
|
loading.value = false
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// 日期格式化辅助函数
|
|
|
+const formatCellDate = (dateString: string | null) => {
|
|
|
+ if (!dateString) return '';
|
|
|
+ return dateFormatter(null, null, dateString);
|
|
|
+}
|
|
|
+
|
|
|
/** 搜索按钮操作 */
|
|
|
const handleQuery = () => {
|
|
|
queryParams.pageNo = 1
|
|
@@ -291,7 +462,18 @@ const handleExport = async () => {
|
|
|
/** 初始化 **/
|
|
|
onMounted(() => {
|
|
|
getList()
|
|
|
+ window.addEventListener('resize', calculateColumnWidths);
|
|
|
})
|
|
|
+
|
|
|
+onUnmounted(() => {
|
|
|
+ window.removeEventListener('resize', calculateColumnWidths);
|
|
|
+})
|
|
|
+
|
|
|
+// 监听列表数据变化重新计算列宽
|
|
|
+watch(list, () => {
|
|
|
+ nextTick(calculateColumnWidths)
|
|
|
+}, { deep: true })
|
|
|
+
|
|
|
</script>
|
|
|
<style scoped>
|
|
|
/* 正数样式 - 淡绿色 */
|
|
@@ -311,4 +493,47 @@ onMounted(() => {
|
|
|
border-radius: 4px;
|
|
|
display: inline-block;
|
|
|
}
|
|
|
+
|
|
|
+.table-wrap {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+/* 确保所有内容不换行 */
|
|
|
+:deep(.el-table) {
|
|
|
+ width: auto !important;
|
|
|
+}
|
|
|
+
|
|
|
+/* 表头和单元格内容不换行 */
|
|
|
+:deep(.el-table__header .el-table__cell .cell),
|
|
|
+:deep(.el-table__body .el-table__cell .cell) {
|
|
|
+ white-space: nowrap !important;
|
|
|
+ overflow: visible !important;
|
|
|
+ text-overflow: clip !important;
|
|
|
+}
|
|
|
+
|
|
|
+/* 防止表头内容换行 */
|
|
|
+:deep(.el-table__header-wrapper) .el-table__cell > .cell {
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+
|
|
|
+/* 确保表格行不换行 */
|
|
|
+:deep(.el-table__row) {
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+
|
|
|
+/* 表头特别处理 */
|
|
|
+:deep(.el-table__header) {
|
|
|
+ .cell {
|
|
|
+ display: inline-block;
|
|
|
+ white-space: nowrap;
|
|
|
+ width: auto !important;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 表格使用100%宽度 */
|
|
|
+:deep(.el-table__inner-wrapper) {
|
|
|
+ width: 100% !important;
|
|
|
+}
|
|
|
</style>
|