385 lines
8.1 KiB
Vue
385 lines
8.1 KiB
Vue
<template>
|
|
<view class="floor-selector">
|
|
<!-- 楼层选择 -->
|
|
<view class="floor-section">
|
|
<text class="section-label">楼层:</text>
|
|
<view class="floor-buttons">
|
|
<view
|
|
v-for="floor in floors"
|
|
:key="floor.id"
|
|
:class="{ active: selectedFloor && selectedFloor.id === floor.id }"
|
|
class="floor-btn"
|
|
@click="selectFloor(floor)"
|
|
>
|
|
{{ floor.label }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 分隔线 -->
|
|
<view class="divider"></view>
|
|
|
|
<view class="content-section">
|
|
<!-- 区域选择 -->
|
|
<view class="area-section">
|
|
<view
|
|
v-for="area in areas"
|
|
:key="area.id"
|
|
:class="{ active: selectedArea && selectedArea.id === area.id }"
|
|
class="area-btn"
|
|
@click="selectArea(area)"
|
|
>
|
|
{{ area.label }}
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 分隔线 -->
|
|
<view class="vertical-divider"></view>
|
|
|
|
<!-- 单元选择 -->
|
|
<view class="unit-section">
|
|
<view class="unit-grid">
|
|
<view
|
|
v-for="unit in units"
|
|
:key="unit.id"
|
|
:class="{ active: selectedUnit && selectedUnit.id === unit.id }"
|
|
class="unit-btn"
|
|
@click="selectUnit(unit)"
|
|
>
|
|
{{ unit.label }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { getMemorialTree } from "@/api/memorial/index.js";
|
|
|
|
export default {
|
|
name: "FloorSelector",
|
|
props: {
|
|
// 默认选中的楼层ID
|
|
defaultFloorId: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
// 默认选中的区域ID
|
|
defaultAreaId: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
// 默认选中的单元ID
|
|
defaultUnitId: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
treeData: [],
|
|
selectedFloor: null,
|
|
selectedArea: null,
|
|
selectedUnit: null,
|
|
loading: false,
|
|
};
|
|
},
|
|
computed: {
|
|
// 楼层列表
|
|
floors() {
|
|
if (!this.treeData.length) return [];
|
|
const memorial = this.treeData[0];
|
|
return memorial && memorial.children ? memorial.children : [];
|
|
},
|
|
// 当前选中楼层的区域列表
|
|
areas() {
|
|
if (!this.selectedFloor) return [];
|
|
return this.selectedFloor.children ? this.selectedFloor.children : [];
|
|
},
|
|
// 当前选中区域的单元列表
|
|
units() {
|
|
if (!this.selectedArea) return [];
|
|
return this.selectedArea.children ? this.selectedArea.children : [];
|
|
},
|
|
},
|
|
watch: {
|
|
// 监听选中变化,向父组件发送事件
|
|
selectedUnit: {
|
|
handler(newUnit) {
|
|
this.$emit("selection-change", {
|
|
floor: this.selectedFloor,
|
|
area: this.selectedArea,
|
|
unit: newUnit,
|
|
});
|
|
},
|
|
deep: true,
|
|
},
|
|
},
|
|
mounted() {
|
|
this.loadTreeData();
|
|
},
|
|
methods: {
|
|
// 加载树形数据
|
|
async loadTreeData() {
|
|
this.loading = true;
|
|
try {
|
|
const response = await getMemorialTree();
|
|
console.log("楼层树形数据:", response);
|
|
|
|
if (response && response.code === 200) {
|
|
this.treeData = response.data || [];
|
|
|
|
// 设置默认选中项
|
|
this.setDefaultSelection();
|
|
} else {
|
|
console.error("获取楼层数据失败:", response);
|
|
uni.showToast({
|
|
title: "获取楼层数据失败",
|
|
icon: "none",
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error("加载楼层数据失败:", error);
|
|
uni.showToast({
|
|
title: "网络异常,请稍后重试",
|
|
icon: "none",
|
|
});
|
|
} finally {
|
|
this.loading = false;
|
|
}
|
|
},
|
|
|
|
// 设置默认选中项
|
|
setDefaultSelection() {
|
|
// 设置默认楼层
|
|
if (this.defaultFloorId) {
|
|
const floor = this.floors.find((f) => f.id === this.defaultFloorId);
|
|
if (floor) {
|
|
this.selectFloor(floor);
|
|
}
|
|
} else if (this.floors.length > 0) {
|
|
// 默认选中第一个楼层
|
|
this.selectFloor(this.floors[0]);
|
|
}
|
|
|
|
// 设置默认区域
|
|
if (this.defaultAreaId && this.selectedFloor) {
|
|
const area = this.areas.find((a) => a.id === this.defaultAreaId);
|
|
if (area) {
|
|
this.selectArea(area);
|
|
}
|
|
} else if (this.areas.length > 0) {
|
|
// 默认选中第一个区域
|
|
this.selectArea(this.areas[0]);
|
|
}
|
|
|
|
// 设置默认单元
|
|
if (this.defaultUnitId && this.selectedArea) {
|
|
const unit = this.units.find((u) => u.id === this.defaultUnitId);
|
|
if (unit) {
|
|
this.selectUnit(unit);
|
|
}
|
|
} else if (this.units.length > 0) {
|
|
// 默认选中第一个单元
|
|
this.selectUnit(this.units[0]);
|
|
}
|
|
},
|
|
|
|
// 选择楼层
|
|
selectFloor(floor) {
|
|
this.selectedFloor = floor;
|
|
this.selectedArea = null;
|
|
this.selectedUnit = null;
|
|
|
|
// 自动选中第一个区域
|
|
if (this.areas.length > 0) {
|
|
this.selectArea(this.areas[0]);
|
|
}
|
|
},
|
|
|
|
// 选择区域
|
|
selectArea(area) {
|
|
this.selectedArea = area;
|
|
this.selectedUnit = null;
|
|
|
|
// 自动选中第一个单元
|
|
if (this.units.length > 0) {
|
|
this.selectUnit(this.units[0]);
|
|
}
|
|
},
|
|
|
|
// 选择单元
|
|
selectUnit(unit) {
|
|
this.selectedUnit = unit;
|
|
},
|
|
|
|
// 获取当前选中信息
|
|
getCurrentSelection() {
|
|
return {
|
|
floor: this.selectedFloor,
|
|
area: this.selectedArea,
|
|
unit: this.selectedUnit,
|
|
};
|
|
},
|
|
|
|
// 重置选择
|
|
resetSelection() {
|
|
this.selectedFloor = null;
|
|
this.selectedArea = null;
|
|
this.selectedUnit = null;
|
|
this.setDefaultSelection();
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.floor-selector {
|
|
padding: 42rpx 44rpx 30rpx 44rpx;
|
|
width: 750rpx;
|
|
background-color: #fffbf5;
|
|
border-radius: 38rpx;
|
|
box-sizing: border-box;
|
|
margin-top: 14rpx;
|
|
}
|
|
|
|
.floor-section {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 26rpx;
|
|
//border:1rpx solid #613613;
|
|
}
|
|
|
|
.section-label {
|
|
margin-right: 10rpx;
|
|
width: 96rpx;
|
|
height: 44rpx;
|
|
font-weight: 400;
|
|
font-size: 32rpx;
|
|
color: #3d3d3d;
|
|
line-height: 44rpx;
|
|
text-align: left;
|
|
}
|
|
|
|
.floor-buttons {
|
|
display: flex;
|
|
gap: 20rpx;
|
|
}
|
|
|
|
.floor-btn {
|
|
padding: 8rpx 49rpx;
|
|
color: #a24242;
|
|
border-radius: 8rpx;
|
|
font-size: 28rpx;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
width: 134rpx;
|
|
//height: 52rpx;
|
|
|
|
background: #fff1dd;
|
|
border: 1rpx solid #a24242;
|
|
|
|
&.active {
|
|
background-color: #a24242;
|
|
color: #fff1dd;
|
|
}
|
|
}
|
|
|
|
.divider {
|
|
height: 1rpx;
|
|
background: repeating-linear-gradient(
|
|
to right,
|
|
#a24242 0,
|
|
#a24242 8rpx,
|
|
transparent 8rpx,
|
|
transparent 16rpx
|
|
);
|
|
margin: 26rpx 0 0 0;
|
|
}
|
|
|
|
.content-section {
|
|
display: flex;
|
|
height: calc(100% - 120rpx);
|
|
}
|
|
|
|
.area-section {
|
|
margin-top: 30rpx;
|
|
width: 180rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16rpx;
|
|
|
|
//border: 1rpx solid #f414fb;
|
|
}
|
|
|
|
.area-btn {
|
|
padding: 8rpx 40rpx;
|
|
color: #a24242;
|
|
border-radius: 8rpx;
|
|
font-size: 28rpx;
|
|
text-align: center;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
box-sizing: border-box;
|
|
width: 134rpx;
|
|
//height: 52rpx;
|
|
|
|
background: #fff1dd;
|
|
border: 1rpx solid #a24242;
|
|
|
|
&.active {
|
|
background-color: #a24242;
|
|
color: #fff1dd;
|
|
}
|
|
}
|
|
|
|
.vertical-divider {
|
|
width: 1rpx;
|
|
background: repeating-linear-gradient(
|
|
to bottom,
|
|
#a24242 0,
|
|
#a24242 8rpx,
|
|
transparent 8rpx,
|
|
transparent 16rpx
|
|
);
|
|
margin: 0 48rpx 0 0;
|
|
}
|
|
|
|
.unit-section {
|
|
//border: 1rpx solid #f47fef;
|
|
flex: 1;
|
|
margin-top: 64rpx;
|
|
}
|
|
|
|
.unit-grid {
|
|
//border: 1rpx solid #f47fef;
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 16rpx;
|
|
}
|
|
|
|
.unit-btn {
|
|
padding: 8rpx 12rpx;
|
|
color: #a24242;
|
|
border-radius: 8rpx;
|
|
font-size: 28rpx;
|
|
text-align: center;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 134rpx;
|
|
|
|
background: #fff1dd;
|
|
border: 1rpx solid #a24242;
|
|
|
|
&.active {
|
|
background-color: #a24242;
|
|
color: #fff1dd;
|
|
border-color: #a24242;
|
|
}
|
|
}
|
|
</style>
|