318 lines
8.5 KiB
Vue
318 lines
8.5 KiB
Vue
<template>
|
|
<view class="container">
|
|
<!-- 搜索区域 -->
|
|
<view class="search-container">
|
|
<view class="search-input-wrapper">
|
|
<uni-icons class="search-icon" type="search" size="20" color="#999"></uni-icons>
|
|
<input class="search-input" placeholder="请输入关键字进行搜索" placeholder-class="placeholder" v-model="searchText"
|
|
@input="handleSearchInput" />
|
|
<view v-if="searchText" class="clear-icon" @tap="clearSearch">
|
|
<uni-icons type="clear" size="18" color="#999"></uni-icons>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 小区列表 -->
|
|
<scroll-view class="community-list" scroll-y>
|
|
<view v-for="item in displayedCommunities" :key="item.id" class="community-item"
|
|
@tap="selectCommunity(item)" :class="{active: selectedItem?.id === item.id}">
|
|
<view class="community-item-left">
|
|
<image src="https://wuye.ckdzkj.com/images/imgs/community.png" style="width: 48rpx;height: 48rpx;"></image>
|
|
<view class="community-info">
|
|
<text class="community-name">{{ item.villageName }}</text>
|
|
</view>
|
|
</view>
|
|
<view v-if="selectedItem && selectedItem.id === item.id" class="selected-icon">
|
|
<image src="https://wuye.ckdzkj.com/images/imgs/check.png" style="width: 48rpx;height: 48rpx;"></image>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 空状态 -->
|
|
<view v-if="displayedCommunities.length === 0 && !isLoading" class="empty-state">
|
|
<uni-icons type="info" size="60" color="#ccc"></uni-icons>
|
|
<text class="empty-text">暂无小区数据</text>
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<!-- 确认按钮 -->
|
|
<view class="confirm-area">
|
|
<button class="confirm-btn" :disabled="!selectedItem" :class="{ 'disabled-btn': !selectedItem }"
|
|
@tap="handleConfirm">
|
|
确认
|
|
</button>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from 'vue'
|
|
import {onLoad} from '@dcloudio/uni-app'
|
|
import { getVillageList,switchVillage} from '../../api/api.js'
|
|
|
|
// 响应式数据
|
|
const searchText = ref('')
|
|
const selectedItem = ref(null)
|
|
const displayedCommunities = ref([])
|
|
const isLoading = ref(false)
|
|
const isConfirming = ref(false)
|
|
let searchTimeout = null
|
|
const defaultVillageId = ref('')
|
|
|
|
// 调用接口获取小区列表
|
|
const fetchVillageList = async (villageName = '') => {
|
|
isLoading.value = true
|
|
try {
|
|
const res = await getVillageList({ villageName })
|
|
if (res.code === 200) {
|
|
displayedCommunities.value = res.data
|
|
|
|
// 如果当前选中项不在新的列表中(搜索过滤掉了),则清空选中状态
|
|
if (selectedItem.value) {
|
|
const stillExists = displayedCommunities.value.find(
|
|
item => String(item.id) === String(selectedItem.value.id)
|
|
)
|
|
if (!stillExists) {
|
|
selectedItem.value = null
|
|
}
|
|
}
|
|
|
|
// 自动选中传入的默认小区(仅在默认小区存在于列表时)
|
|
if (defaultVillageId.value) {
|
|
const found = displayedCommunities.value.find(
|
|
item => String(item.id) === String(defaultVillageId.value)
|
|
)
|
|
if (found) {
|
|
selectedItem.value = found
|
|
}
|
|
}
|
|
} else {
|
|
uni.showToast({ title: res.msg || '获取数据失败', icon: 'none' })
|
|
}
|
|
} catch (err) {
|
|
uni.showToast({ title: '网络错误', icon: 'none' })
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
// 接收传入的参数,并初始加载小区列表
|
|
onLoad((options) => {
|
|
if (options?.villageId) {
|
|
defaultVillageId.value = options.villageId
|
|
}
|
|
// 在 onLoad 中调用初始加载,确保 defaultVillageId 已设置
|
|
fetchVillageList()
|
|
})
|
|
|
|
// 处理搜索输入(防抖)
|
|
const handleSearchInput = () => {
|
|
if (searchTimeout) clearTimeout(searchTimeout)
|
|
searchTimeout = setTimeout(() => {
|
|
fetchVillageList(searchText.value.trim())
|
|
}, 300)
|
|
}
|
|
|
|
// 清空搜索
|
|
const clearSearch = () => {
|
|
searchText.value = ''
|
|
fetchVillageList('')
|
|
}
|
|
|
|
// 选择小区
|
|
const selectCommunity = (item) => {
|
|
selectedItem.value = item
|
|
}
|
|
|
|
// 确认选择
|
|
const handleConfirm = () => {
|
|
// 防重复点击
|
|
if (isConfirming.value) return
|
|
if (!selectedItem.value) {
|
|
uni.showToast({ title: '请先选择小区', icon: 'none', duration: 2000 })
|
|
return
|
|
}
|
|
isConfirming.value = true
|
|
uni.showLoading({ title: '切换中...', mask: true })
|
|
switchVillage({ villageId: selectedItem.value.id }).then((res) =>{
|
|
if(res.code === 200){
|
|
uni.showToast({ title: '切换成功', icon: 'success', duration: 1500 })
|
|
uni.hideLoading()
|
|
uni.$emit('confirm', selectedItem.value)
|
|
setTimeout(() => {
|
|
uni.navigateBack()
|
|
}, 1500)
|
|
}else{
|
|
isConfirming.value = false
|
|
uni.hideLoading()
|
|
uni.showToast({ title: res.msg || '切换失败', icon: 'none' })
|
|
}
|
|
}).catch((err)=>{
|
|
isConfirming.value = false
|
|
uni.hideLoading()
|
|
uni.showToast({title:err.msg || '网络异常',icon:'none'})
|
|
})
|
|
|
|
|
|
// uni.showModal({
|
|
// title: '确认选择',
|
|
// content: `您已选择: ${selectedItem.value.villageName}`,
|
|
// success: (res) => {
|
|
// if (res.confirm) {
|
|
// uni.showToast({ title: '选择成功', icon: 'success', duration: 1500 })
|
|
// uni.$emit('confirm', selectedItem.value)
|
|
// setTimeout(() => {
|
|
// uni.navigateBack()
|
|
// }, 1500)
|
|
// }
|
|
// }
|
|
// })
|
|
}
|
|
|
|
</script>
|
|
|
|
<style scoped>
|
|
.container {
|
|
min-height: 100vh;
|
|
background-color: #f5f5f5;
|
|
display: flex;
|
|
flex-direction: column;
|
|
padding: 0rpx 40rpx;
|
|
}
|
|
|
|
.search-container {
|
|
padding: 20rpx 30rpx;
|
|
background-color: #ffffff;
|
|
display: flex;
|
|
align-items: center;
|
|
z-index: 10;
|
|
position: sticky;
|
|
top: 0;
|
|
}
|
|
|
|
.search-input-wrapper {
|
|
flex: 1;
|
|
background-color: #f3f3f3;
|
|
border-radius: 10rpx;
|
|
padding: 8rpx 20rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
height: 80rpx;
|
|
}
|
|
|
|
.search-icon {
|
|
margin-right: 15rpx;
|
|
}
|
|
|
|
.search-input {
|
|
flex: 1;
|
|
height: 100%;
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
}
|
|
|
|
.placeholder {
|
|
color: #999;
|
|
font-size: 28rpx;
|
|
text-align: center;
|
|
}
|
|
|
|
.clear-icon {
|
|
padding: 10rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.community-list {
|
|
flex: 1;
|
|
margin-top: 20rpx;
|
|
margin-bottom: 180rpx;
|
|
}
|
|
|
|
.community-item {
|
|
background-color: #fff;
|
|
padding: 30rpx;
|
|
margin-bottom: 20rpx;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
transition: all 0.25s ease;
|
|
border: 1px solid transparent;
|
|
border-radius: 12rpx;
|
|
}
|
|
|
|
.community-item.active {
|
|
background-color: #F5FAFF;
|
|
border: 1px solid #2F77FD;
|
|
}
|
|
|
|
.community-item-left {
|
|
display: flex;
|
|
align-items: center;
|
|
flex: 1;
|
|
}
|
|
|
|
.community-info {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
}
|
|
|
|
.community-name {
|
|
font-size: 32rpx;
|
|
color: #222;
|
|
font-weight: 500;
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.selected-icon {
|
|
margin-left: 20rpx;
|
|
}
|
|
|
|
.empty-state {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 100rpx 0;
|
|
}
|
|
|
|
.empty-text {
|
|
font-size: 32rpx;
|
|
color: #999;
|
|
margin-top: 20rpx;
|
|
}
|
|
|
|
.confirm-area {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
padding: 20rpx 30rpx 40rpx;
|
|
background-color: #fff;
|
|
box-shadow: 0 -2rpx 20rpx rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
.confirm-btn {
|
|
background-color: #4D5DFA;
|
|
color: #fff;
|
|
height: 80rpx;
|
|
line-height: 80rpx;
|
|
border-radius: 8rpx;
|
|
font-size: 28rpx;
|
|
width: 100%;
|
|
margin: 0;
|
|
}
|
|
|
|
.disabled-btn {
|
|
background-color: #ccc;
|
|
color: #fff;
|
|
}
|
|
|
|
@media (min-width: 768px) {
|
|
.container {
|
|
max-width: 500px;
|
|
margin: 0 auto;
|
|
}
|
|
}
|
|
</style>
|