租房小程序前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

815 lines
28 KiB

<template>
<view class="Locations">
<map style="width: 100%;height: 60vh"
:layer-style='5'
:show-location='true'
:latitude="position.latitude"
:longitude="position.longitude"
:markers="spotGuideMarkers"
:scale="scale"
@markertap="markertap"
id="mapId"
@callouttap="callouttap"
:enable-zoom="true"
:enable-scroll="true"
:enable-rotate="true">
</map>
<!-- 测试按钮 -->
<view class="test-button" @click="testLoadHouseList">
<text>测试加载房源</text>
</view>
<!-- 搜索功能 -->
<view class="search-container">
<view class="se-bgc-white se-pb-20 se-pt-30 se-px-40">
<uv-search @search="onSearch()" placeholder="搜索租房信息" :showAction="false" v-model="keyword"></uv-search>
</view>
<view class="se-pb-10 se-px-40 se-bgc-white">
<uv-drop-down ref="dropDown" sign="dropDown_1" text-active-color="#1EC77A"
:extra-icon="{name:'arrow-down-fill',color:'#666',size:'26rpx'}"
:extra-active-icon="{name:'arrow-up-fill',color:'#1EC77A',size:'26rpx'}" :defaultValue="defaultValue"
:custom-style="{padding: '0rpx 0rpx',borderBottom:'1rpx solid transparent'}" @click="selectMenu">
<uv-drop-down-item name="region" type="2" :label="dropItem('region').label" :value="dropItem('region').value">
</uv-drop-down-item>
<uv-drop-down-item name="rent" type="2" :label="dropItem('rent').label" :value="dropItem('rent').value">
</uv-drop-down-item>
<uv-drop-down-item name="type" type="2" :label="dropItem('type').label" :value="dropItem('type').value">
</uv-drop-down-item>
<uv-drop-down-item name="duration" type="2" :label="dropItem('duration').label" :value="dropItem('duration').value">
</uv-drop-down-item>
</uv-drop-down>
<uv-drop-down-popup sign="dropDown_1" :click-overlay-on-close="true" :currentDropItem="currentDropItem"
@clickItem="clickItem" @popupChange="change"></uv-drop-down-popup>
</view>
</view>
<uv-tabs :list="houseTypeList" :activeStyle="{ color: '#1EC77A', fontWeight: 600 }" lineColor="#1EC77A"
lineHeight="8rpx" lineWidth="50rpx" keyName="title" :current="currentHouseType"
@click="onClickHouseType"></uv-tabs>
<view class="Locations-list">
<!-- 房源列表 -->
<view v-if="list.length > 0">
<view @click="onDetail(item)" class="se-my-10 se-mx-20 se-px-20 se-py-20 se-br-20 se-bgc-white se-flex"
v-for="(item, index) in list" :key="index">
<view class="se-pos se-w-260 se-h-180">
<image v-if="item.iconImage" class="se-a-80 se-pos-lt" :src="item.iconImage" mode=""></image>
<image class="se-w-260 se-h-180 se-br-10" :src="item.images[0]" mode=""></image>
</view>
<view class="se-pl-10 se-w-p-100">
<view class="se-c-black se-fs-28">
{{ item.title }}
</view>
<view class="se-flex se-flex-h-sb se-flex-ai-c se-fs-24 se-mt-10 se-c-66">
<text>{{ item.homeType }}</text>
<text>{{ item.timeGo }}年</text>
</view>
<view class="se-flex se-flex-h-sb se-flex-ai-c se-mt-10">
<template v-if="item.iconTitles.length > 0">
<view class="se-flex">
<view
class="se-display-ib se-c-white se-bgc-orange se-fs-22 se-br-8 se-px-10 se-py-5 se-mr-10"
v-for="(items, indexs) in item.iconTitles" :key="indexs">
{{ items }}
</view>
</view>
</template>
<template v-else>
<view></view>
</template>
<view class="se-c-66 se-flex se-flex-ai-c">
<uv-icon name="eye"></uv-icon>
<text class="se-ml-5 se-fs-18">{{ item.num }}</text>
</view>
</view>
<view class="se-flex se-flex-h-sb se-flex-ai-c se-mt-10">
<text class="se-c-red se-fs-24 se-fw-6 se-toe-1">{{ item.price }}/{{ item.unit }}</text>
<text class="se-c-66 se-fs-22 se-toe-1">{{ item.address }}</text>
</view>
</view>
</view>
</view>
<uv-empty v-else text="没有哦" textSize="30rpx" iconSize="200rpx" icon="list"></uv-empty>
</view>
</view>
</template>
<script>
import { housePageList, houseType, houseArea, houseIconClass, housePrice, houseYear } from "@/common/api.js"
import { getInfo } from "@/common/api.js"
export default {
data() {
return {
scale: 12, //缩放级别
show: true,
tabs: [],
spotGuideIndex: 0, // 当前选中的菜单索引
position: {
latitude: 23.106574,
longitude: 113.324587
},
areaId: null, // 当前选中的区域ID
// 房源列表相关数据
list: [],
classId: null,
pageNo: 1,
pageSize: 10,
houseTypeList: [], // 房源类型列表
currentHouseType: 0, // 当前选中的房源类型索引
userInfo: null, // 用户信息
// 搜索功能相关数据
keyword: "",
// 表示value等于这些值,就属于默认值
defaultValue: ['all', 'all', 'all','all'],
// 筛选结果
result: [],
region:{
label: '区域',
value: 'all',
activeIndex: 0,
color: '#333',
activeColor: '#1EC77A',
child: []
},
rent:{
label: '租金',
value: 'all',
activeIndex: 0,
color: '#333',
activeColor: '#1EC77A',
child: []
},
type: {
label: '类型',
value: 'all',
activeIndex: 0,
color: '#333',
activeColor: '#1EC77A',
child: []
},
duration:{
label: '年限',
value: 'all',
activeIndex: 0,
color: '#333',
activeColor: '#1EC77A',
child: []
},
activeName: 'region',
// 筛选条件
priceId: null,
typeId: null,
yearId: null
}
},
computed: {
spotGuideMarkers() {
let markers = [];
console.log('计算地图标记点,房源列表长度:', this.list.length)
this.list.forEach((item, index) => {
if (item.latitude && item.longitude) {
console.log(`添加标记点 ${index}:`, item.title, item.latitude, item.longitude)
markers.push({
id: index,
latitude: parseFloat(item.latitude),
longitude: parseFloat(item.longitude),
iconPath: '/static/image/tourGuide/2.png',
width: 30,
height: 30,
callout: {
content: item.title || '房源',
color: '#000000',
fontSize: 14,
borderRadius: 5,
bgColor: '#ffffff',
padding: 5,
display: 'BYCLICK'
}
});
}
});
console.log('生成的标记点数量:', markers.length)
return markers;
},
// 搜索功能计算属性
dropItem() {
return (name) => {
const result = {};
const find = this.result.find(item => item.name === name);
if (find) {
result.label = find.label;
result.value = find.value;
} else {
result.label = this[name].label;
result.value = this[name].value;
}
return result;
}
},
// 获取当前下拉筛选项
currentDropItem() {
return this[this.activeName];
}
},
onLoad() {
console.log('页面加载完成')
// 确保在页面加载完成后初始化数据
this.$nextTick(() => {
if (this.list.length === 0) {
this.onHousePageList()
}
})
},
onPageScroll() {
// 滚动后及时更新下拉菜单位置
if (this.$refs.dropDown) {
this.$refs.dropDown.init();
}
},
mounted() {
this.getCurrentLocation()
this.onHouseType() // 获取房源类型
//this.getUserInfo() // 获取用户信息
// 初始化搜索筛选数据
this.initSearchData()
// 延迟加载房源列表,确保用户信息已获取
this.$nextTick(() => {
this.onHousePageList() // 加载房源列表
})
},
onPullDownRefresh() {
let that = this
that.pageNo = 1
that.list = []
that.onHousePageList()
},
onReachBottom() {
let that = this
that.pageNo = that.pageNo + 1
that.onHousePageList()
},
methods: {
getUserInfo(state){
this.$store.commit('getUserInfo', (userInfo) => {
this.userInfo = userInfo
if(userInfo && userInfo.isPay != 1){
uni.showModal({
title: '开通会员可查看租房地图',
content: '开通会员后可查看详细地址和联系方式',
confirmText: '立即开通',
cancelText: '取消',
success : res => {
if(res.confirm){
// 跳转到会员页面
uni.navigateTo({
url: '/pages_subpack/member/index'
})
}
}
})
}
})
},
// 获取当前位置
getCurrentLocation() {
const that = this;
uni.getLocation({
type: 'wgs84',
success: function (res) {
console.log('当前位置的经度:' + res.longitude);
console.log('当前位置的纬度:' + res.latitude);
that.position.latitude = res.latitude;
that.position.longitude = res.longitude;
// 更新地图位置
that.onHousePageList();
},
fail: function (err) {
console.error('获取位置失败:', err);
uni.showToast({
title: '获取位置失败',
icon: 'none'
});
}
});
},
//点击tab栏
clickTabs({ index, name }) {
this.currentArea = index
if (this.areaList[index]) {
this.areaId = this.areaList[index].id
}
this.onHousePageList()
this.$nextTick(() => {
this.selectArea()
})
},
setSpotGuideIndex(index) {
this.spotGuideIndex = index
this.onHousePageList()
},
textToSpeech() {
console.log('textToSpeech');
let self = this
// self.context.src = this.$config.baseUrl + '/info/textToAudio?text=' + "你好"
// self.context.play()
// return
plugin.textToSpeech({
lang: "zh_CN",
tts: true,
content: "景德镇市陶阳里御窑景区位于景德镇的城市中心地带,北起瓷都大桥、昌江大道,南至昌江大桥、西至沿江西路,东至莲社路、胜利路。 自宋以来,景德镇先民“沿河建窑,因窑成市”,渐呈“码头—民窑—老街—里弄—御窑”聚落的历史空间和瓷业肌理,形成了世界建筑史上绝无仅有的老城格局,成就了中国“东方瓷国”的盛誉,陶瓷成为了中国走向世界,世界认识中国的文化符号。这里是景德镇历史上制瓷业的中心、原点和高峰,是“一带一路”海上陶瓷之路的零公里起点,是研究皇家御窑制瓷历史文化和景德镇陶瓷技艺,讲好景德镇故事,传播中国声音的“窗口”和“名片”。",
success: function (res) {
self.context.src = res.filename;
self.context.play()
},
fail: function (res) {
console.log("fail tts", res)
}
})
},
//地图点击事件
markertap(e) {
console.log("markertap===你点击了标记点===", e)
let event = this.list[e.markerId]
if (event) {
this.onDetail(event)
} else {
console.error('未找到对应的房源数据')
uni.showToast({
title: '房源信息获取失败',
icon: 'none'
})
}
},
openLocation(n) {
uni.openLocation({
latitude: n.spotLatitude,
longitude: n.spotLongitude,
})
},
//地图点击事件
callouttap(e) {
console.log('callouttap地图点击事件', e)
let event = this.list[e.markerId]
if (event && event.latitude && event.longitude) {
uni.openLocation({
latitude: event.latitude,
longitude: event.longitude,
})
} else {
console.error('未找到对应的房源位置信息')
uni.showToast({
title: '房源位置信息获取失败',
icon: 'none'
})
}
},
toUrl(item) {
console.log(item);
if (item.categoryId == 0) {
this.$utils.navigateTo(`/pages_order/service/articleDetail?id=${item.id}&type=Inheritance`)
}
},
// 点击按钮将地图中心移动到指定定位点
moveTolocation(latitude, longitude) {
let mapObjs = uni.createMapContext('mapId', this)
mapObjs.moveToLocation(
{
latitude,
longitude
},
{
complete: res => {
console.log('移动完成:', res)
}
})
// this.onRegionChange('',true)
},
// 点击景区,选择最近的一个景点
selectArea() {
let item = this.spotGuide[0]
if (item && item.spotLatitude && item.spotLongitude) {
this.moveTolocation(item.spotLatitude, item.spotLongitude)
}
},
clickAreaDetail(id) {
uni.navigateTo({
url: '/pages_order/service/areaDetail?id=' + id
})
},
// 获取房源类型列表
onHouseType() {
houseType({}).then(response => {
console.info('houseType', response)
this.houseTypeList = response.result
}).catch(error => {
})
},
// 点击房源类型
onClickHouseType(event) {
console.info(event)
let that = this
that.pageNo = 1
that.classId = event.id
that.currentHouseType = event.index
that.list = []
that.onHousePageList()
},
// 获取房源列表
onHousePageList() {
let that = this
let params = {
classId: that.classId,
pageNo: that.pageNo,
pageSize: that.pageSize,
// 搜索和筛选参数
title: that.keyword, // 关键词搜索
areaId: that.areaId, // 区域筛选
priceId: that.priceId, // 租金筛选
typeId: that.typeId, // 类型筛选
yearId: that.yearId // 年限筛选
}
// 如果有位置信息,添加到参数中
if (that.position.latitude && that.position.longitude) {
params.latitude = that.position.latitude
params.longitude = that.position.longitude
}
console.log('请求房源列表参数:', params)
housePageList(params).then((response) => {
console.info("房源列表数据", response.result.records)
if (response.result && response.result.records) {
response.result.records.forEach((items, indexs) => {
if (items.image) {
items.images = items.image.split(',')
} else {
items.images = []
}
if (items.homeImage) {
items.homeImages = items.homeImage.split(',')
} else {
items.homeImages = []
}
if (items.iconTitle) {
items.iconTitles = items.iconTitle.split(',')
} else {
items.iconTitles = []
}
})
that.list = that.list.concat(response.result.records)
// 调试信息:检查有多少房源有位置信息
let markersCount = that.list.filter(item => item.latitude && item.longitude).length
console.log(`房源总数: ${that.list.length}, 有位置信息的房源: ${markersCount}`)
// 如果有房源数据,更新地图中心点
if (that.list.length > 0) {
let firstHouse = that.list.find(item => item.latitude && item.longitude)
if (firstHouse) {
that.position.latitude = firstHouse.latitude
that.position.longitude = firstHouse.longitude
}
// 强制更新地图组件
that.$nextTick(() => {
let mapContext = uni.createMapContext('mapId', that)
if (mapContext) {
mapContext.updateGroundOverlay({
id: 'markers',
'include-points': that.spotGuideMarkers
})
}
})
}
}
}).catch((error) => {
console.error('获取房源列表失败:', error)
uni.showToast({
title: '获取房源列表失败',
icon: 'none'
})
})
},
// 点击房源详情
onDetail(event) {
uni.navigateTo({
url: "/pages_subpack/detail/index?id=" + event.id
})
},
// 搜索功能相关方法
// 初始化搜索筛选数据
initSearchData() {
this.onhouseArea()
this.onhouseIconClass()
this.onhousePrice()
this.onhouseYear()
},
// 处理搜索
onSearch() {
console.info('搜索关键词:', this.keyword)
this.pageNo = 1
this.list = []
this.onHousePageList()
},
// 选择筛选菜单
selectMenu(name) {
this.activeName = name;
},
// 点击筛选项
clickItem(item) {
console.log('选择筛选项:', item);
// 更新对应的筛选值
this[this.activeName].label = item.label;
this[this.activeName].value = item.value;
// 处理筛选逻辑
this.handleFilter(item);
},
// 处理筛选
handleFilter(item) {
console.info('筛选条件变化:', item)
this.pageNo = 1
// 根据筛选类型设置对应的参数
if (this.activeName === 'region') {
this.areaId = item.value === 'all' ? null : item.value
} else if (this.activeName === 'rent') {
this.priceId = item.value === 'all' ? null : item.value
} else if (this.activeName === 'type') {
this.typeId = item.value === 'all' ? null : item.value
} else if (this.activeName === 'duration') {
this.yearId = item.value === 'all' ? null : item.value
}
this.list = []
this.onHousePageList()
},
// 弹窗状态变化
change(e) {
console.log('弹窗打开状态:', e);
},
// 获取区域数据
onhouseArea() {
let that = this
houseArea({}).then(response => {
let arr = [
{
label: '全部区域',
value: 'all'
}
]
response.result.forEach(items => {
let obj = {}
obj.label = items.title;
obj.value = items.id
arr.push(obj)
})
that.region.child = arr
console.info('区域数据', response.result)
}).catch(error => {
})
},
// 获取类型数据
onhouseIconClass() {
let that = this
houseIconClass({}).then(response => {
console.info('类型数据', response.result)
let arr = [
{
label: '全部类型',
value: 'all'
}
]
response.result.forEach(items => {
let obj = {}
obj.label = items.title;
obj.value = items.id
arr.push(obj)
})
that.type.child = arr
}).catch(error => {
})
},
// 获取价格数据
onhousePrice() {
let that = this
housePrice({}).then(response => {
let arr = [
{
label: '全部价格',
value: 'all'
}
]
response.result.forEach(items => {
let obj = {}
obj.label = items.title;
obj.value = items.price
arr.push(obj)
})
that.rent.child = arr
}).catch(error => {
})
},
// 获取年限数据
onhouseYear() {
let that = this
houseYear({}).then(response => {
console.info('年限数据', response.result)
let arr = [
{
label: '全部年限',
value: 'all'
}
]
response.result.forEach(items => {
let obj = {}
obj.label = items.title;
obj.value = items.timeGo
arr.push(obj)
})
that.duration.child = arr
}).catch(error => {
})
},
// 测试加载房源列表
testLoadHouseList() {
console.log('手动触发房源列表加载');
this.pageNo = 1;
this.list = [];
this.onHousePageList();
}
}
}
</script>
<style scoped lang="scss">
.test-button {
position: fixed;
top: 20rpx;
right: 20rpx;
background-color: #1EC77A;
color: white;
padding: 20rpx;
border-radius: 10rpx;
z-index: 999;
font-size: 24rpx;
}
.Locations {
.search-container {
background-color: #fff;
border-bottom: 1rpx solid #f0f0f0;
}
.tabs {
display: flex;
&>view {
flex: 1;
margin: 20rpx 10rpx;
padding: 20rpx 10rpx;
background-color: #e8f7f0;
color: #1EC77A;
border-radius: 40rpx;
font-size: 24rpx;
text-align: center;
}
.act {
background-color: #1EC77A;
color: #fff;
}
}
.Locations-list {
.main {
display: flex;
margin: 20rpx;
.main-image {
width: 150rpx;
height: 150rpx;
border-radius: 20rpx;
}
.info {
margin-left: 20rpx;
.title {
font-size: 30rpx;
font-weight: 900;
}
.tips {
font-size: 24rpx;
color: #999999;
margin-top: 10rpx;
}
}
.controls {
margin-left: auto;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.f {
image {
width: 50rpx;
height: 50rpx;
}
}
}
.btn {
padding: 10rpx;
font-size: 22rpx;
color: #1EC77A;
border: 1rpx solid #1EC77A;
background-color: #e8f7f0;
display: flex;
justify-content: center;
align-items: center;
margin-top: 10rpx;
border-radius: 15rpx;
image {
width: 25rpx;
height: 25rpx;
}
text {
margin: 0 10rpx;
}
}
}
.list {
padding-left: 40rpx;
.main {
align-items: center;
.main-image {
width: 140rpx;
height: 140rpx;
}
.controls {
flex-direction: row;
.f {
margin: 30rpx;
image {
width: 40rpx;
height: 40rpx;
}
}
}
}
}
}
}
</style>