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-xq-test/vue-synthesize-table.vue

334 lines
7.1 KiB
Vue

1 month ago
<template>
<div>
<!-- :span-method="objectSpanMethod" -->
<el-table
:data="tableData"
border
:span-method="objectSpanMethod"
style="width: 100%; margin-top: 20px"
max-height="530"
>
<!-- 楼层信息列 -->
<el-table-column prop="floorName" label="楼层" />
<el-table-column type="index" label="ID" />
<!-- 设备信息列 -->
<el-table-column prop="name" label="设备名称" />
<el-table-column prop="id" label="设备ID" />
<!-- 设备状态列 -->
<el-table-column label="设备状态">
<template #default="{ row }">
<el-tag :type="row.eState === 0 ? 'success' : 'warning'">
{{ row.eState === 0 ? '正常' : '故障' }}
</el-tag>
</template>
</el-table-column>
<!-- 当前状态列 -->
<el-table-column label="当前状态">
<template #default="{ row }">
<el-tag v-if="row.currentState === 0" type="success"></el-tag>
<el-tag v-else-if="row.currentState === 1" type="info">停止</el-tag>
<el-tag v-else type="error">报警</el-tag>
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column label="操作">
<template #default="{ row }">
<el-button type="primary" class="operation-btn" v-if="row.operation"> </el-button>
<el-button type="primary" class="operation-btn" v-else> </el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script lang="ts" setup>
import type { TableColumnCtx } from 'element-plus';
import { computed } from 'vue';
interface User {
id: string;
name: string;
amount1: string;
amount2: string;
amount3: number;
}
interface Equipment {
id: string; //设备ID
address?: string; //设备地址
name: string; //设备名称
eState: number; //设备状态 0正常 1故障
currentState: number; //当前状态 0运行 1停止 2报警
operation: boolean; //操作 true屏蔽 false取消屏蔽
}
interface FloorObj {
floorName: string; //地址
equipments: Equipment[];
}
const floorData: FloorObj[] = [
{
floorName: '安全工器具室',
equipments: [
{
id: '10010',
name: '1号感烟探头',
eState: 0,
currentState: 0,
operation: true
},
{
id: '10011',
name: '2号感烟探头',
eState: 0,
currentState: 0,
operation: true
}
]
},
{
floorName: '蓄电池室',
equipments: [
{
id: '10012',
name: '3号感烟探头',
eState: 1,
currentState: 1,
operation: false
},
{
id: '10013',
name: '4号感烟探头',
eState: 0,
currentState: 0,
operation: true
}
]
},
{
floorName: '220kV保护室',
equipments: [
{
id: '10014',
name: '5号感烟探头',
eState: 0,
currentState: 2,
operation: false
},
{
id: '10015',
name: '6号感烟探头',
eState: 1,
currentState: 1,
operation: true
}
]
},
{
floorName: '380kV配电室',
equipments: [
{
id: '10016',
name: '7号感烟探头',
eState: 0,
currentState: 0,
operation: false
},
{
id: '10017',
name: '8号感烟探头',
eState: 0,
currentState: 2,
operation: true
}
]
},
{
floorName: '35kV高压室',
equipments: [
{
id: '10018',
name: '9号感烟探头',
eState: 1,
currentState: 1,
operation: false
},
{
id: '10019',
name: '10号感烟探头',
eState: 0,
currentState: 0,
operation: true
}
]
},
{
floorName: '2号接地变室',
equipments: [
{
id: '10020',
name: '11号感烟探头',
eState: 0,
currentState: 2,
operation: false
},
{
id: '10021',
name: '12号感烟探头',
eState: 1,
currentState: 1,
operation: true
}
]
},
{
floorName: '110kV电缆室',
equipments: [
{
id: '10022',
name: '13号感烟探头',
eState: 0,
currentState: 0,
operation: false
},
{
id: '10023',
name: '14号感烟探头',
eState: 0,
currentState: 0,
operation: true
}
]
},
{
floorName: '2号站用变室',
equipments: [
{
id: '10024',
name: '15号感烟探头',
eState: 0,
currentState: 0,
operation: false
},
{
id: '10025',
name: '16号感烟探头',
eState: 0,
currentState: 0,
operation: true
}
]
},
{
floorName: '生产综合楼1楼走廊',
equipments: [
{
id: '10026',
name: '17号感烟探头',
eState: 0,
currentState: 0,
operation: false
},
{
id: '10027',
name: '18号感烟探头',
eState: 0,
currentState: 0,
operation: true
},
{
id: '10028',
name: '1号声光报警器',
eState: 0,
currentState: 0,
operation: false
},
{
id: '10029',
name: '2号声光报警器',
eState: 0,
currentState: 0,
operation: true
},
{
id: '10030',
name: '1号手报',
eState: 0,
currentState: 0,
operation: false
},
{
id: '10031',
name: '2号手报',
eState: 0,
currentState: 0,
operation: true
}
]
}
];
interface SpanMethodProps {
row: any;
column: TableColumnCtx<User>;
rowIndex: number;
columnIndex: number;
}
const objectSpanMethod = ({ row, columnIndex }: SpanMethodProps) => {
if (columnIndex === 0) {
// 查找当前行对应的楼层数据
const floor = floorData.find((f) => f.floorName === row.floorName);
if (floor) {
// 找到该楼层下第一个设备的索引
const firstEquipmentIndex = floor.equipments.findIndex((e) => e.id === row.id);
if (firstEquipmentIndex === 0) {
// 如果是第一个设备,合并该楼层的所有行
return {
rowspan: floor.equipments.length,
colspan: 1
};
} else {
// 如果不是第一个设备,不显示(被合并)
return {
rowspan: 0,
colspan: 0
};
}
}
}
// 其他列不合并
return {
rowspan: 1,
colspan: 1
};
};
// 将嵌套数据展开为表格数据
const tableData = computed(() => {
return floorData.flatMap((floor) =>
floor.equipments.map((equipment) => ({
...equipment,
floorName: floor.floorName, // 添加楼层信息到每行
// 如果有设备地址就显示,没有就显示楼层作为地址
address: equipment.address || floor.floorName
}))
);
});
</script>
<style scoped>
.operation-btn {
width: 70px;
min-width: 70px;
padding: 8px 12px;
}
</style>