diff --git a/src/components/BuildingTable/core/builders/table-builder.js b/src/components/BuildingTable/core/builders/table-builder.js index 60770eb..3645a1e 100644 --- a/src/components/BuildingTable/core/builders/table-builder.js +++ b/src/components/BuildingTable/core/builders/table-builder.js @@ -4,9 +4,14 @@ import BaseBuilder from "./base-builder"; * Table布局楼盘表逻辑幢构建器 */ export default class TableBuilder extends BaseBuilder { + spanData = { // 跨楼层数据 + indexes: {}, + layers: {} + } + // 构建房屋(楼层倒序排列) buildHouses(layerInfo, unitInfo) { - const houses = this.data.houses + const houses = this.data.houses || [] const { layerList, layerMap } = layerInfo const { unitList, unitMap } = unitInfo // 1、生成房屋数据结构: houseList->Array,layer->Array,unit->Array @@ -19,7 +24,7 @@ export default class TableBuilder extends BaseBuilder { }) }) // 2、填充房屋 - for (const house of houses) { + for (let house of houses) { const { unitName, minAtLayer, layerCount, columnCount } = house // 跨层的房屋需要将起始楼层上移(layerCount),因为表格colspan是从上往下的,楼层却是从下往上 const layerIndex = house._layerIndex = layerMap[minAtLayer].index - layerCount + 1 @@ -31,21 +36,74 @@ export default class TableBuilder extends BaseBuilder { const index = layerMap[layer].index houseList[index][unitIndex]._houseCount += columnCount }) + // 构造跨层数据 + if (layerCount > 1) { + const indexKey = `${layerIndex}&${unitIndex}` + const layerKey = `${minAtLayer}&${unitIndex}` + const indexes = this.spanData.indexes[indexKey] || (this.spanData.indexes[indexKey] = new Set()); + indexes.add(layerKey) + this.spanData.layers[layerKey] = this.spanData.layers[layerKey] || [] + } } - // 3、单元填充平衡,并排列房屋在单元中的位置 - for (const layer of houseList) { + // 3、单元填充平衡 + for (let layer of houseList) { layer.forEach((unit, unitIndex) => { + // 填充跨层数据 + unit.forEach(house => { + const { minAtLayer, _unitIndex } = house + const layerKey = `${minAtLayer}&${_unitIndex}` + this.spanData.layers[layerKey] && this.spanData.layers[layerKey].push(house) + }) // 计算需要填充的空白房屋(null)的数量,并填充 const remain = unitList[unitIndex].columnCount - unit._houseCount if (remain > 0) { unit.push(...new Array(remain).fill(null)) } - // 单元内房屋排序,增加列索引信息 - unit.sort((m, n) => this.compareHouse(m, n)) - unit.forEach((house, index) => (house && (house._columnIndex = index))) delete unit._houseCount }) } + // 4、单元排序 + Object.values(this.spanData.layers).forEach(houses => { + // 跨层原始层房屋排序 + houses.sort((m, n) => this.compareHouse(m, n)) + }) + houseList.forEach((layer, layerIndex) => { + layer.forEach((unit, unitIndex) => { + const indexKey = `${layerIndex}&${unitIndex}` + if (this.spanData.indexes[indexKey]) { + this.sortSpanHouse(unit) + } else { + unit.sort((m, n) => this.compareHouse(m, n)) + } + unit.forEach((house, index) => house && (house._columnIndex = index)); + }) + }) return houseList } + + // 跨行房屋排序 + sortSpanHouse(unit) { + const spanHouses = new Array(unit.length).fill(undefined) + // 1、排列跨层房屋位置,与在原始层位置保持一致 + unit.forEach(house => { + if (house && house.layerCount > 1) { + const layerKey = `${house.minAtLayer}&${house._unitIndex}` + const spanIndex = this.spanData.layers[layerKey].indexOf(house) + spanHouses[spanIndex] = house + } + }) + // 2、排列非跨层房屋位置,排除跨层房屋后按顺序排放 + const normalHouses = unit + .filter(m => !m || m.layerCount == 1) + .sort((m, n) => this.compareHouse(m, n)) + let normalIndex = 0 + spanHouses.forEach((house, index) => { + if (house === undefined) { + unit[index] = normalHouses[normalIndex] + normalIndex++ + } else { + unit[index] = spanHouses[index] + } + }) + } } \ No newline at end of file diff --git a/src/components/BuildingTable/renders/table/HouseTableRender.vue b/src/components/BuildingTable/renders/table/HouseTableRender.vue index ff348f6..35e9526 100644 --- a/src/components/BuildingTable/renders/table/HouseTableRender.vue +++ b/src/components/BuildingTable/renders/table/HouseTableRender.vue @@ -50,17 +50,12 @@ export default { }, }, updated() { - this.doLayout(); + this.setLayout(); }, mounted() { - this.doLayout(); + this.setLayout(); }, methods: { - // 重新布局 - doLayout() { - this.setLayout(); - this.setEmptyFloorsHeight(); - }, // 设置楼盘表内容区域布局参数和空楼层高度 setLayout() { const hasGutter = this.tableWidth >= this.$el.clientWidth @@ -70,15 +65,22 @@ export default { hasGutter, scrollLeft, }); - this.setEmptyFloorsHeight(); + this.setFloorsHeight(); }, - // 设置空楼层高度(空楼层没有单元格支撑高度,需要从其他行高度设置) - setEmptyFloorsHeight() { - const emptyRow = this.$el.querySelector("tbody>tr[data-empty]"); - const firstRow = this.$el.querySelector("tbody>tr:not([data-empty])"); - if (emptyRow && firstRow) { - emptyRow.style.height = `${firstRow.clientHeight}px`; - } + // 设置楼层高度(空楼层、跨行楼层没有单元格支撑高度,需要从其他行高度设置) + setFloorsHeight() { + const heights = Array.from(this.$el.querySelectorAll("tbody>tr")).map( + (m) => m.clientHeight + ); + if (heights.length == 0) return; + // 计算出最大层高,将小于最大层高的楼层设为最大层高 + const maxHeight = Math.max.apply(null, heights); + heights.forEach((h, index) => { + if (h != maxHeight) { + const row = this.$el.querySelector(`tbody>:nth-child(${index + 1})`); + row && (row.style.height = `${maxHeight}px`); + } + }); }, // 同步楼盘表内容区域滚动参数 handleScroll(e) { diff --git a/src/components/BuildingTable/style/house.scss b/src/components/BuildingTable/style/house.scss index 080ae30..9ea54b0 100644 --- a/src/components/BuildingTable/style/house.scss +++ b/src/components/BuildingTable/style/house.scss @@ -113,6 +113,12 @@ table-layout: fixed; } + .house-cell__block { + display: flex; + flex-direction: column; + justify-content: flex-end; + } + .building-td__floor, .building-td__house { background-color: $background-color; diff --git a/src/views/BuildingTableDemo.vue b/src/views/BuildingTableDemo.vue index 4bc4f52..02e7e54 100644 --- a/src/views/BuildingTableDemo.vue +++ b/src/views/BuildingTableDemo.vue @@ -68,10 +68,10 @@ export default { // 创建测试数据 let data = this.createTestData(); // 测试跨多层 - // data.logicBuilds[0].houses[0].columnCount = 2; - // data.logicBuilds[0].houses[0].layerCount = 2; - // const house = data.logicBuilds[0].houses.find(m=>m.houseName === '403') - // house.layerCount = 2 + data.logicBuilds[0].houses[0].columnCount = 2; + data.logicBuilds[0].houses[0].layerCount = 2; + const house = data.logicBuilds[0].houses.find(m=>m.houseName === '403') + house.layerCount = 2 // const house1 = data.logicBuilds[0].houses.find(m=>m.houseName === '502') // house1.columnCount = 2