261 lines
6.4 KiB
Vue
261 lines
6.4 KiB
Vue
<!-- 切换房号页面 -->
|
||
<template>
|
||
<s-layout title="切换房号">
|
||
<view class="switch-house-page">
|
||
<!-- 小区名称 -->
|
||
<view class="section-label">小区名称</view>
|
||
<picker
|
||
mode="selector"
|
||
:range="state.communityList"
|
||
range-key="name"
|
||
:value="state.communityIndex"
|
||
@change="onCommunityChange"
|
||
>
|
||
<view class="card community-card">
|
||
<text class="community-name">{{ state.currentCommunity }}</text>
|
||
<!-- 下拉箭头 SVG -->
|
||
<svg class="arrow-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M6 9L12 15L18 9" stroke="#999999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||
</svg>
|
||
</view>
|
||
</picker>
|
||
|
||
<!-- 房号 -->
|
||
<view class="section-label">房号</view>
|
||
<scroll-view class="house-scroll" scroll-y :style="{ height: scrollHeight + 'px' }">
|
||
<view class="card house-card">
|
||
<view
|
||
v-for="(item, index) in state.houseList"
|
||
:key="index"
|
||
class="house-item"
|
||
:class="{ active: state.selectedHouseId === item.id }"
|
||
@tap="selectHouse(item)"
|
||
>
|
||
<!-- 单选按钮 -->
|
||
<radio
|
||
class="house-radio"
|
||
:checked="state.selectedHouseId === item.id"
|
||
color="#FF7B54"
|
||
/>
|
||
<text class="house-name">{{ item.name }}</text>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<!-- 底部去认证 -->
|
||
<view class="bottom-link-wrapper">
|
||
<text class="auth-link" @tap="goAddHouse">房屋不存在,去认证</text>
|
||
</view>
|
||
</view>
|
||
</s-layout>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { reactive, ref } from 'vue';
|
||
import { onLoad } from '@dcloudio/uni-app';
|
||
import MemberHouseApi from '@/sheep/api/community/memberHouse';
|
||
import sheep from '@/sheep';
|
||
|
||
// scroll-view 动态高度
|
||
const scrollHeight = ref(0);
|
||
|
||
// 页面状态
|
||
const state = reactive({
|
||
// 小区房屋树(原始数据)
|
||
communityTree: [],
|
||
// 小区列表(用于picker)
|
||
communityList: [],
|
||
// 当前选中的小区索引
|
||
communityIndex: 0,
|
||
// 当前小区名称
|
||
currentCommunity: '',
|
||
// 房号列表
|
||
houseList: [],
|
||
// 当前选中房号ID(对应 memberHouseId)
|
||
selectedHouseId: '',
|
||
});
|
||
|
||
// 获取小区房屋树
|
||
const fetchCommunityTree = async () => {
|
||
const { code, data } = await MemberHouseApi.getCommunityTree();
|
||
if (code === 0 && data && data.length > 0) {
|
||
state.communityTree = data;
|
||
state.communityList = data.map((item) => ({
|
||
id: item.communityId,
|
||
name: item.communityName,
|
||
}));
|
||
// 默认选中第一个小区
|
||
state.communityIndex = 0;
|
||
state.currentCommunity = data[0].communityName;
|
||
updateHouseListByIndex(0);
|
||
}
|
||
};
|
||
|
||
// 根据小区索引更新房屋列表
|
||
const updateHouseListByIndex = (index) => {
|
||
const community = state.communityTree[index];
|
||
if (!community) return;
|
||
const houses = community.houses || [];
|
||
state.houseList = houses.map((item) => ({
|
||
id: String(item.memberHouseId),
|
||
name: item.fullAddress || `${item.buildingNo}${item.unitNo}${item.roomNo}`,
|
||
// 保留原始字段,切换接口需要
|
||
memberHouseId: item.memberHouseId,
|
||
houseId: item.houseId,
|
||
communityId: community.communityId,
|
||
}));
|
||
// 默认选中第一个房屋
|
||
state.selectedHouseId = state.houseList[0]?.id || '';
|
||
};
|
||
|
||
onLoad(() => {
|
||
// 计算 scroll-view 可用高度(屏幕高度 - 状态栏 - 导航栏 - 小区区域高度 - 底部链接高度 - 安全区)
|
||
const sys = uni.getSystemInfoSync();
|
||
const safeBottom = sys.safeAreaInsets?.bottom || 0;
|
||
// 估算:状态栏+导航栏约 88px,小区区域约 140px,底部链接约 60px
|
||
scrollHeight.value = sys.windowHeight - 88 - 140 - 60 - safeBottom;
|
||
fetchCommunityTree();
|
||
});
|
||
|
||
// 选择房号并切换
|
||
const selectHouse = async (item) => {
|
||
state.selectedHouseId = item.id;
|
||
const switchRes = await MemberHouseApi.switchHouse({
|
||
memberHouseId: item.memberHouseId,
|
||
houseId: item.houseId,
|
||
communityId: item.communityId,
|
||
});
|
||
if (switchRes.code === 0) {
|
||
// 切换成功后刷新用户信息
|
||
await sheep.$store('user').getInfo();
|
||
uni.showToast({ title: '已切换至 ' + item.name, icon: 'none' });
|
||
}
|
||
};
|
||
|
||
// 切换小区
|
||
const onCommunityChange = (e) => {
|
||
const index = e.detail.value;
|
||
state.communityIndex = index;
|
||
state.currentCommunity = state.communityList[index].name;
|
||
updateHouseListByIndex(index);
|
||
};
|
||
|
||
// 去认证房屋
|
||
const goAddHouse = () => {
|
||
uni.navigateTo({
|
||
url: '/pages/index/check-page',
|
||
});
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
/* 页面容器 */
|
||
.switch-house-page {
|
||
height: 100%;
|
||
background-color: #F5F5F5;
|
||
padding: 24rpx 0 calc(40rpx + env(safe-area-inset-bottom));
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* 房号滚动区域 */
|
||
.house-scroll {
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 区块标签 */
|
||
.section-label {
|
||
font-size: 28rpx;
|
||
font-weight: 400;
|
||
color: #666666;
|
||
margin: 24rpx 38rpx 16rpx;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
/* 白色卡片通用样式 */
|
||
.card {
|
||
background-color: #FFFFFF;
|
||
border-radius: 24rpx;
|
||
margin: 0 38rpx;
|
||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
|
||
}
|
||
|
||
/* 小区选择卡片 */
|
||
.community-card {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 30rpx 32rpx;
|
||
|
||
.community-name {
|
||
font-size: 30rpx;
|
||
font-weight: 500;
|
||
color: #333333;
|
||
}
|
||
|
||
.arrow-icon {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
}
|
||
|
||
/* 房号卡片 */
|
||
.house-card {
|
||
padding: 8rpx 32rpx;
|
||
|
||
.house-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 28rpx 0;
|
||
border-bottom: 1rpx solid #F0F0F0;
|
||
transition: background-color 0.2s;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
&:active {
|
||
opacity: 0.7;
|
||
}
|
||
|
||
.house-radio {
|
||
margin-right: 20rpx;
|
||
flex-shrink: 0;
|
||
transform: scale(0.85);
|
||
}
|
||
|
||
.house-name {
|
||
font-size: 30rpx;
|
||
font-weight: 400;
|
||
color: #333333;
|
||
}
|
||
|
||
&.active .house-name {
|
||
color: #FF7B54;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 底部认证链接 */
|
||
.bottom-link-wrapper {
|
||
display: flex;
|
||
justify-content: center;
|
||
margin-top: auto;
|
||
padding: 40rpx 0 calc(40rpx + env(safe-area-inset-bottom));
|
||
|
||
.auth-link {
|
||
font-size: 28rpx;
|
||
font-weight: 400;
|
||
color: #FF7B54;
|
||
text-decoration: underline;
|
||
line-height: 1.4;
|
||
|
||
&:active {
|
||
opacity: 0.7;
|
||
}
|
||
}
|
||
}
|
||
</style>
|