You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
maotu-webtopo/src/components/vue-components/vue-extinguisher-table.vue

306 lines
7.5 KiB
Vue

<template>
<div class="table-container">
<el-card class="card" shadow="hover" :body-style="{ padding: '10px' }">
<h2 class="cardHead">运行信息</h2>
<div class="table-wrapper" v-loading="tableArr.length === 0">
<!-- :span-method="objectSpanMethods" -->
<el-table
:data="tableArr"
style="width: 100%"
:span-method="objectSpanMethods"
class="full-height-table"
>
<el-table-column prop="floorArea" label="所在区域" />
<el-table-column prop="equipmentPlace" label="配置地点" />
<el-table-column prop="equipmentName" label="设备名称" />
<el-table-column prop="equipmentSpecification" label="规格型号" />
<el-table-column prop="equipmentNumber" label="编号" />
<el-table-column prop="vender" label="设备厂家" />
</el-table>
</div>
</el-card>
</div>
</template>
<script lang="ts" setup>
import type { TableColumnCtx } from 'element-plus';
import { computed, onMounted, onUnmounted, ref, watch, reactive } from 'vue';
import emitter from '@/utils/emitter';
import { ro } from 'element-plus/es/locales.mjs';
const props = defineProps({
fontFamily: {
type: String,
default: '黑体'
},
fontSize: {
type: Number,
default: 12
},
testColor: {
type: String,
default: '#ffffff'
},
definitionItemJson: {
type: Object,
default: () => ({})
}
});
// 计算属性——既读取又修改
let computedSize = computed({
// 读取
get() {
return props.fontSize + 'px';
}, // 修改
set(val) {}
});
interface Equipment {
equipmentPlace: string; //设备地点
equipmentName: string; //设备名称
equipmentSpecification: string; //规格
equipmentNumber: string; //编号
vender: string; //厂家
}
interface FloorObj {
floorArea: string; //区域
equipments: Equipment[];
}
let tableArr = ref<any[]>([]);
let spanMap = ref<Map<string, number>>(new Map<string, number>());
//数据初始化
async function dataInit() {
floorData.forEach((floor) => {
floor.equipments.forEach((equipment) => {
tableArr.value.push({
floorArea: floor.floorArea,
equipmentPlace: equipment.equipmentPlace,
equipmentName: equipment.equipmentName,
equipmentSpecification: equipment.equipmentSpecification,
equipmentNumber: equipment.equipmentNumber,
vender: equipment.vender
});
});
if (!spanMap.value.has(floor.floorArea))
spanMap.value.set(floor.floorArea, floor.equipments.length);
});
console.log('spanMap', spanMap.value);
}
// 记录每个楼层已经处理到第几行
let floorStartIndex = ref<Map<string, number>>(new Map<string, number>());
// 合并单元格的逻辑
function objectSpanMethods({ rowIndex, columnIndex }: any) {
if (columnIndex === 0) {
// 只合并第一列"所在区域"
const floorArea = tableArr.value[rowIndex].floorArea;
// 如果是第一次遇到该楼层,记录起始位置
if (!floorStartIndex.value.has(floorArea)) {
floorStartIndex.value.set(floorArea, rowIndex);
}
// 如果是该楼层的第一行,显示并合并
if (floorStartIndex.value.get(floorArea) === rowIndex) {
return [spanMap.value.get(floorArea) || 1, 1];
} else {
// 不是第一行,隐藏
return [0, 0];
}
}
return [1, 1];
}
// 在 onMounted 中
onMounted(async () => {
await dataInit();
});
onUnmounted(() => {
emitter.off('binding-data-update');
});
// 数据源头
const floorData: FloorObj[] = [
{
floorArea: '生产综合楼1楼',
equipments: [
{
equipmentPlace: '蓄电池室',
equipmentName: '干粉灭火器',
equipmentSpecification: 'MFZ4',
equipmentNumber: '1、2号',
vender: '天河消防厂'
},
{
equipmentPlace: '220kV保护室',
equipmentName: '氧化碳灭火器',
equipmentSpecification: 'MFZ4',
equipmentNumber: '1、2号',
vender: '天河消防厂'
},
{
equipmentPlace: '380V配电室',
equipmentName: '干粉灭火器',
equipmentSpecification: 'MFZ4',
equipmentNumber: '1、2号',
vender: '天河消防厂'
},
{
equipmentPlace: '35kV高压室',
equipmentName: '干粉灭火器',
equipmentSpecification: 'MFZ4',
equipmentNumber: '1、2号',
vender: '天河消防厂'
},
{
equipmentPlace: '2号接地变室',
equipmentName: '干粉灭火器',
equipmentSpecification: 'MFZ4',
equipmentNumber: '1、2号',
vender: '天河消防厂'
},
{
equipmentPlace: '110kV电缆室',
equipmentName: '干粉灭火器',
equipmentSpecification: 'MFZ4',
equipmentNumber: '1、2号',
vender: '天河消防厂'
},
{
equipmentPlace: '2号站用变室',
equipmentName: '干粉灭火器',
equipmentSpecification: 'MFZ4',
equipmentNumber: '1、2号',
vender: '天河消防厂'
},
{
equipmentPlace: '生产综合楼1楼走廊',
equipmentName: '干粉灭火器',
equipmentSpecification: 'MFZ4',
equipmentNumber: '1、2号',
vender: '天河消防厂'
}
]
},
{
floorArea: '生产综合楼2楼',
equipments: [
{
equipmentPlace: '110kVGIS室',
equipmentName: '干粉灭火器',
equipmentSpecification: 'MFZ4',
equipmentNumber: '1、2号',
vender: '天河消防厂'
},
{
equipmentPlace: '110kV保护室',
equipmentName: '干粉灭火器',
equipmentSpecification: 'MFZ4',
equipmentNumber: '1、2号',
vender: '天河消防厂'
},
{
equipmentPlace: '主控制室',
equipmentName: '干粉灭火器',
equipmentSpecification: 'MFZ4',
equipmentNumber: '1、2号',
vender: '天河消防厂'
},
{
equipmentPlace: '生产综合楼2楼',
equipmentName: '干粉灭火器',
equipmentSpecification: 'MFZ4',
equipmentNumber: '1、2号',
vender: '天河消防厂'
}
]
}
];
</script>
<style scoped>
.table-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.card {
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
}
.card :deep(.el-card__body) {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
padding: 10px;
}
.table-wrapper {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.full-height-table {
flex: 1;
height: 100%;
}
.full-height-table :deep(.el-table__body-wrapper) {
flex: 1;
overflow-y: auto;
}
.cardHead {
margin: 0 0 15px 0;
padding: 0;
font-size: 16px;
font-weight: bold;
text-align: center;
color: #ffffff;
flex-shrink: 0;
}
.operation-btn {
width: 60px;
min-width: 50px;
padding: 8px 12px;
height: 30px;
}
/* 控制表头文字大小 */
.full-height-table :deep(.el-table__header th) {
font-size: 13px;
font-weight: bold;
}
/* 控制表格内容文字大小 */
.full-height-table :deep(.el-table__body td) {
font-size: v-bind('computedSize');
color: v-bind('props.testColor');
}
/* 控制标签文字大小 */
.full-height-table :deep(.el-tag) {
font-size: v-bind('computedSize'); /* 标签内的文字可以稍小一些 */
}
/* 控制按钮文字大小 */
.full-height-table :deep(.el-button) {
font-size: v-bind('computedSize');
color: v-bind('props.testColor');
}
</style>