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