Files
property-resident-side/property-uniapp-project/pageSubPack/my/bindHouse.vue
2026-07-30 15:35:02 +08:00

427 lines
8.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="contentStyle" style="">
<view class="status-bar"></view>
<uni-nav-bar title="绑定房屋" left-icon="left" @clickLeft="goBack" :border="false" backgroundColor="transparent">
</uni-nav-bar>
<!-- 表单区域 -->
<scroll-view class="page" scroll-y="true">
<!-- 搜索框 -->
<view class="search-box">
<input class="search-input" v-model="searchKey" placeholder="请输入名称"
placeholder-class="input-placeholder" @input="onSearch" />
<uni-icons type="search" size="20" color="#999" />
</view>
<!-- 房屋列表 -->
<scroll-view class="list-container" scroll>
<view v-if="filteredList.length === 0" class="empty-state">
<uni-icons type="info" size="60" color="#ccc"></uni-icons>
<text class="empty-text">
{{ '暂无数据'}}
</text>
</view>
<view class="house-card" v-for="(item, index) in filteredList" :key="index"
@click="selectHouse(item,index)" :class="{ checked: selectedIndex === index }">
<!-- 小区名称 -->
<view class="community-name">
<text class="title-line"></text>
<text class="title-text">{{ item.villageName }}</text>
</view>
<!-- 选中对勾 -->
<view class="check-icon" :class="{ checked: selectedIndex === index }"></view>
<!-- 房屋信息 -->
<view class="info-row">
<text class="info-label">房间号</text>
<text class="info-value">{{ item.roomNo }}</text>
</view>
<view class="info-row">
<text class="info-label">业主</text>
<text class="info-value">{{ item.owner }}</text>
</view>
<view class="info-row">
<text class="info-label">房屋状态</text>
<text class="info-value status-text" :style="{ color: statusColor[item.status] }">
{{ item.status }}
</text>
</view>
</view>
</scroll-view>
</scroll-view>
<!-- 底部确定绑定按钮 -->
<view class="bottom-btn">
<button class="confirm-btn" @click="confirmBind">确定绑定</button>
</view>
</view>
</template>
<script setup>
import {
ref,
onMounted,
computed
} from 'vue'
import {
onReachBottom,
onPullDownRefresh,
onLoad
} from '@dcloudio/uni-app'
import {
getVillageList
} from '/pageSubPack/api/apiSub.js'
/* 设定状态栏默认高度 */
const statusBarHeight = 20
const searchKey = ref("")
const selectedId = ref('')
const selectedName = ref('')
const selectedIndex = ref(-1)
/* 搜索状态 */
const onSearch = () => {
// 实时过滤computed 自动处理
}
onLoad(() => {
getList()
})
/* 房屋状态颜色映射 */
const statusColor = {
自住: "#409EFF",
闲置: "#67C23A",
租赁: "#E6A23C",
其他: "#909399",
}
/* 模拟房屋数据 */
const communityList = ref([{
id: 1,
villageName: "北境碧桂园小区(别墅)",
roomNo: "2号楼2层",
owner: "张三",
status: "自住",
},
{
id: 1,
villageName: "北境碧桂园小区(别墅)",
roomNo: "2号楼1层",
owner: "张三",
status: "闲置",
},
])
/* 过滤后的列表(搜索功能) */
const filteredList = computed(() => {
selectedIndex.value = -1
if (!searchKey.value.trim()) {
return communityList.value
}
return communityList.value.filter(item =>
item.villageName.includes(searchKey.value.trim())
)
})
/* 选择房屋 */
const selectHouse = (item, index) => {
selectedIndex.value = index
selectedId.value = item.id
selectedName.value = item.villageName + item.roomNo
}
/* 确定绑定 */
const confirmBind = () => {
if (selectedIndex.value === -1) {
return uni.showToast({
title: "请先选择房屋",
icon: "none",
})
}
uni.showModal({
title: "确认选择",
content: `确定绑定 ${selectedName.value} 吗?`,
success: (res) => {
if (res.confirm) {
uni.showLoading({
title: '绑定中...',
mask: true
})
setTimeout(() => {
uni.showToast({
title: '绑定成功',
icon: 'success'
})
}, 1000)
setTimeout(() => {
// 提交成功后跳转列表页
uni.hideLoading()
uni.setStorageSync('bindHouseId', selectedId.value)
uni.setStorageSync('bindHouseName', selectedName.value)
uni.setStorageSync('checkType', '停车场')
uni.removeStorageSync('paringLotId')
uni.removeStorageSync('paringLotName')
uni.removeStorageSync('parkingSpaceId')
uni.removeStorageSync('parkingSpaceName')
goNext()
}, 2500)
}
},
})
}
const getList = async () => {
try {
const res = await getVillageList({
})
console.log(res);
const data = res
communityList.value = data.data || []
} catch (err) {
uni.showToast({
title: '加载失败',
icon: 'none'
})
console.error('列表接口报错:', err)
} finally {
}
}
const goNext = () => {
uni.navigateTo({
url: '/pageSubPack/my/selectParingLot',
success: res => {},
fail: () => {},
complete: () => {}
})
}
const goBack = () => {
uni.navigateTo({
url: '/pageSubPack/my/addParkingSpace',
success: res => {},
fail: () => {},
complete: () => {}
})
}
</script>
<style lang="scss">
page {
background: #f9f9f9;
overflow: hidden;
}
</style>
<style scoped>
.contentStyle {
display: flex;
flex-direction: column;
height: 100vh;
}
.page {
flex: 1;
overflow-y: auto;
padding: 0px 40rpx;
box-sizing: border-box;
}
/* 底部按钮 */
.bottom-btn {
padding: 20rpx 30rpx 40rpx;
}
/* 通用输入框样式 */
.input-item {
font-size: 30rpx;
color: #333;
}
.input-placeholder {
color: #999;
font-size: 30rpx;
}
/* 确定按钮 */
.submit-btn {
width: 100%;
height: 88rpx;
line-height: 88rpx;
background-color: #1677ff;
color: #fff;
font-size: 32rpx;
border-radius: 8rpx;
border: none;
margin-top: 20rpx;
}
/* 搜索框 */
.search-box {
display: flex;
align-items: center;
background-color: #F3F3F3;
border-radius: 20rpx;
margin: 0px 0px 20rpx 0rpx;
padding: 0 30rpx;
height: 70rpx;
}
.search-input {
flex: 1;
height: 100%;
font-size: 30rpx;
border: none;
background: transparent;
}
.input-placeholder {
color: #999;
font-size: 30rpx;
}
.search-icon {
font-size: 36rpx;
color: #999;
}
/* 列表容器 */
.list-container {}
/* 空状态 */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
color: #ccc;
}
.empty-text {
font-size: 32rpx;
color: #999;
margin-top: 20rpx;
margin-bottom: 10rpx;
}
/* 房屋卡片 */
.house-card {
border: 1rpx solid #e5e5e5;
border-radius: 12rpx;
padding: 20rpx;
margin-bottom: 30rpx;
position: relative;
background-color: #fff;
}
.house-card.checked {
background: #f4f7ff;
border-color: #1677ff;
}
.community-name {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 20rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #f0f0f0;
display: flex;
align-items: center;
}
.title-line {
width: 8rpx;
height: 36rpx;
background-color: #007AFF;
margin-right: 12rpx;
border-radius: 4rpx;
}
.title-text {
font-size: 32rpx;
font-weight: bold;
color: #333333;
}
.info-row {
display: flex;
align-items: center;
margin-bottom: 16rpx;
}
.info-label {
width: 160rpx;
font-size: 28rpx;
color: #000;
}
.info-value {
font-size: 28rpx;
color: #333;
}
.status-text {
font-weight: 500;
}
/* 选中对勾 */
.check-icon {
position: absolute;
right: 20rpx;
top: 46rpx;
transform: translateY(-50%);
width: 52rpx;
height: 52rpx;
border-radius: 50%;
border: 2rpx solid #ccc;
}
.check-icon::after {
content: "✓";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
font-size: 30rpx;
font-weight: bold;
}
/* 选中状态:蓝色背景 */
.check-icon.checked {
background-color: #1677ff;
border-color: #1677ff;
}
.confirm-btn {
width: 100%;
height: 96rpx;
line-height: 96rpx;
background-color: #1677ff;
color: #fff;
font-size: 36rpx;
border-radius: 12rpx;
border: none;
}
.status-bar {
width: 100vw;
height: 46px;
}
</style>