This commit is contained in:
2025-11-14 11:39:33 +08:00
parent 6e5d892992
commit 1ba633ba45
7143 changed files with 922330 additions and 0 deletions

124
pages/detail/addHouse.vue Normal file
View File

@@ -0,0 +1,124 @@
<template>
<view>
<view class="wrap">
<view class="u-tabs-box">
<u-tabs-swiper ref="tabs" :list="tabList" :current="current" @change="change" :is-scroll="false" swiperWidth="750" bar-width="120"></u-tabs-swiper>
</view>
<swiper class="swiper-box" :current="swiperCurrent" @transition="transition" @animationfinish="animationfinish">
<swiper-item class="swiper-item">
<add-all-house :model="model"></add-all-house>
</swiper-item>
<swiper-item class="swiper-item">
<add-sub-house :model="model"></add-sub-house>
</swiper-item>
</swiper>
</view>
</view>
</template>
<script>
import addAllHouse from '@/components/zy/addAllHouse.vue'
import addSubHouse from '@/components/zy/addSubHouse.vue'
export default {
components: {
addAllHouse,addSubHouse
},
data() {
return {
tabList: [{name: '整租'},{name: '合租'}],
current: 0,
swiperCurrent: 0,
tabsHeight: 0,
// 房源对象
model: null,
};
},
onLoad: function (option) {
this.model = JSON.parse(option.room)
},
methods: {
// tab栏切换
change(index) {
this.swiperCurrent = index;
},
transition({ detail: { dx } }) {
this.$refs.tabs.setDx(dx);
},
animationfinish({ detail: { current } }) {
this.$refs.tabs.setFinishCurrent(current);
this.swiperCurrent = current;
this.current = current;
this.model.type = current;
}
}
};
</script>
<style>
page{
background-color: #FFFFFF;
}
</style>
<style lang="scss" scoped>
.tabSwiper {
width: 710rpx;
background-color: #ffffff;
margin: 20rpx auto;
border-radius: 20rpx;
box-sizing: border-box;
padding: 20rpx;
font-size: 28rpx;
.top {
display: flex;
justify-content: space-between;
.left {
display: flex;
align-items: center;
.title {
margin: 0 10rpx;
font-size: 32rpx;
font-weight: bold;
}
}
.right {
color: $u-tips-color;
}
}
.item {
display: flex;
margin: 20rpx 0 0;
.left {
margin-right: 20rpx;
image {
width: 200rpx;
height: 200rpx;
border-radius: 10rpx;
}
}
.content {
.title {
font-size: 28rpx;
line-height: 50rpx;
}
}
.right {
margin-left: 10rpx;
padding-top: 20rpx;
text-align: right;
}
}
}
.wrap {
display: flex;
flex-direction: column;
height: calc(100vh - var(--window-top));
width: 100%;
}
.swiper-box {
flex: 1;
}
.swiper-item {
height: 100%;
}
</style>

View File

@@ -0,0 +1,314 @@
<template>
<view class="asset-detail">
<!-- 顶部导航栏 -->
<customNavbar
title="不动资产详情"
></customNavbar>
<!-- 顶部信息块 -->
<view class="top-block u-flex u-row-between u-p-20">
<!-- 左侧轮播图 -->
<view class="left-swiper">
<u-swiper
:list="asset.images"
height="220"
border-radius="12"
autoplay
interval="3000"
></u-swiper>
</view>
<!-- 右侧信息块 -->
<view class="right-info u-flex u-flex-col u-justify-between">
<view>
<view class="asset-name">{{ asset.name }}</view>
<view class="asset-community">所属小区{{ asset.community }}</view>
<view class="asset-rent">租金<text class="price">¥{{ formatMoney(asset.rent) }}/</text></view>
</view>
<view class="btn-group">
<u-button
size="mini"
type="primary"
icon="map"
@click="viewVR"
>
查看VR图
</u-button>
</view>
</view>
</view>
<view class="content">
<!-- 基本信息 -->
<mycard title="资产信息">
<view class="info-list">
<u-cell-group>
<u-cell-item title="资产编号" :value="asset.code" :arrow="false"/>
<u-cell-item title="资产类别" :value="asset.category" :arrow="false"/>
<u-cell-item title="资产面积" :value="asset.area + '㎡'" :arrow="false"/>
<u-cell-item title="资产价值" :value="'¥' + formatMoney(asset.value)" :arrow="false"/>
<u-cell-item title="权属单位" :value="asset.owner" :arrow="false"/>
</u-cell-group>
</view>
</mycard>
<!-- 位置信息 -->
<mycard title="位置信息" >
<view class="map-section">
<u-cell-group>
<u-cell-item title="地址" :value="asset.address" :arrow="false"/>
</u-cell-group>
<map
:latitude="asset.lat"
:longitude="asset.lng"
:markers="markers"
style="width: 100%; height: 300rpx; border-radius: 12rpx; margin-top: 20rpx;"
></map>
</view>
</mycard>
<!-- 备注信息 -->
<mycard title="备注信息">
<view class="remark">
{{ asset.remark || '暂无备注信息' }}
</view>
</mycard>
</view>
<!-- 预约弹窗 -->
<u-popup v-model="showReserve" mode="bottom" border-radius="20">
<view class="popup-content">
<text class="popup-title">预约看房</text>
<u-input v-model="reserveName" placeholder="请输入姓名" />
<u-input v-model="reservePhone" placeholder="请输入电话" />
<u-button type="primary" @click="submitReserve">提交预约</u-button>
</view>
</u-popup>
<!-- 底部导航栏 -->
<assetBottomBar :phone="asset.contact" @reserve="showReserve = true" />
</view>
</template>
<script>
import mycard from '../../components/card/mycard.vue';
import assetBottomBar from '../../components/bottom/assetBottomBar.vue';
export default {
components:{
mycard,
assetBottomBar
},
data() {
return {
// 控制预约弹窗显示
showReserve: false,
// 预约表单数据
reserveName: '',
reservePhone: '',
assetId: null,
asset: {
name: '',
community: '',
code: '',
category: '',
area: '',
value: '',
rent: '',
owner: '',
address: '',
lat: 0,
lng: 0,
images: [],
remark: '',
isFavorite: false,
},
markers: [],
};
},
onLoad(options) {
this.assetId = options.id || 'A001';
this.loadAssetDetail();
},
methods: {
// 模拟接口请求
loadAssetDetail() {
setTimeout(() => {
console.log("fork数据")
this.asset = {
name: '广州市中心写字楼A栋',
community: '天河国际商务区',
code: 'GDZC2025001',
category: '商业用房',
area: 1250.5,
value: 28000000,
rent: 88000,
owner: '广州市国资委',
address: '广州市天河区体育西路88号',
lat: 23.135,
lng: 113.327,
images: [
'https://cdn.uviewui.com/uview/swiper/swiper1.png',
'https://cdn.uviewui.com/uview/swiper/swiper2.png',
],
remark: '该资产目前用于办公出租,维护状态良好。',
isFavorite: false,
};
this.markers = [
{
id: 1,
latitude: this.asset.lat,
longitude: this.asset.lng,
title: this.asset.name,
},
];
}, 300);
},
formatMoney(num) {
return Number(num).toLocaleString();
},
toggleFavorite() {
this.asset.isFavorite = !this.asset.isFavorite;
uni.showToast({
title: this.asset.isFavorite ? '已收藏' : '取消收藏',
icon: 'success',
});
},
contactManager() {
uni.makePhoneCall({
phoneNumber: '400-123-4567',
});
},
viewVR() {
uni.showToast({
title: '打开卫星图...',
icon: 'none',
});
// 可扩展:跳转到 VR 页面或调用地图 API
},
submitReserve (){
console.log('提交预约看房申请')
this.showReserve = false;
}
},
};
</script>
<style lang="scss" scoped>
.asset-detail {
background-color: #f7f8fa;
min-height: 100vh;
padding-bottom: 120rpx;
padding-top: 175rpx; /* 给导航栏留空间 */
.top-block {
background-color: #fff;
border-radius: 16rpx;
margin: 20rpx;
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.05);
.left-swiper {
width: 45%;
}
.right-info {
width: 50%;
padding-left: 20rpx;
.asset-name {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.asset-community {
font-size: 26rpx;
color: #666;
margin-bottom: 10rpx;
}
.asset-rent {
font-size: 26rpx;
color: #444;
.price {
color: #e54d42;
font-weight: bold;
margin-left: 4rpx;
}
}
.btn-group {
margin-top: 20rpx;
align-self: flex-start;
}
}
}
.content {
padding: 20rpx;
background-color: #f5f6fa;
min-height: 100vh;
padding-bottom: 140rpx; /* 避免内容被遮住 */
.info-list {
padding: 10rpx 20rpx;
background-color: #ffffff;
border-radius: 12rpx;
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.05);
}
.map-section {
padding: 10rpx 20rpx 20rpx;
background-color: #ffffff;
border-radius: 12rpx;
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
map {
width: 100%;
height: 320rpx;
border-radius: 12rpx;
margin-top: 20rpx;
overflow: hidden;
}
}
.remark {
padding: 20rpx;
font-size: 28rpx;
color: #555;
line-height: 1.6;
background-color: #ffffff;
border-radius: 12rpx;
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.05);
}
}
}
.popup-content {
padding: 40rpx 30rpx;
background-color: #fff;
border-radius: 20rpx 20rpx 0 0;
}
.popup-title {
display: block;
font-size: 32rpx;
font-weight: bold;
color: #333;
text-align: center;
margin-bottom: 30rpx;
}
.u-input {
margin-bottom: 20rpx;
}
.u-button {
margin-top: 20rpx;
border-radius: 50rpx;
}
</style>

View File

@@ -0,0 +1,245 @@
<template>
<view class="contract-detail-page">
<customNavbar title="我的合同"></customNavbar>
<!-- 顶部信息 -->
<view class="header">
<image class="cover" :src="contract.coverUrl" mode="aspectFill" />
<view class="info">
<text class="name">{{ contract.assetName }}</text>
<text class="room">{{ contract.assetRoom || '—' }}</text>
</view>
</view>
<!-- 合同基本信息 -->
<view class="section">
<view class="section-title">合同基本信息</view>
<view class="info-item" v-for="(item, index) in baseInfo" :key="index" @click="handleClick(item)">
<text class="label">{{ item.label }}</text>
<view class="value-box">
<text class="value">{{ item.value }}</text>
<u-icon v-if="item.hasArrow" name="arrow-right" size="30" color="#ccc" />
</view>
</view>
</view>
<!-- 费用信息 -->
<view class="section">
<view class="section-title">费用信息</view>
<view class="info-item" v-for="(item, index) in feeInfo" :key="index" @click="handleClick(item)">
<text class="label">{{ item.label }}</text>
<view class="value-box">
<text class="value">{{ item.value }}</text>
<u-icon v-if="item.hasArrow" name="arrow-right" size="30" color="#ccc" />
</view>
</view>
</view>
<!-- 签约主体信息 -->
<view class="section">
<view class="section-title">签约主体信息</view>
<view class="info-item" v-for="(item, index) in signerInfo" :key="index">
<text class="label">{{ item.label }}</text>
<text class="value">{{ item.value }}</text>
</view>
</view>
<!-- 底部操作栏 -->
<view v-if="contract.status === '待签署'" class="bottom-bar">
<u-button
type="primary"
shape="circle"
class="sign-btn"
@click="goSign"
>
去签署
</u-button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
contract: {
id: 'c123',
coverUrl: '/static/img/index/swiper/swiper3.jpg',
assetName: '深圳南山中心写字楼租赁合同',
assetRoom: 'B栋1203',
status: '待签署', // 可选:待签署 / 已签署 / 已过期
signStatus: '未签署',
startDate: '2025-01-01',
endDate: '2026-01-01',
payMethod: '按月支付',
payTime: '每月5日',
electronicId: 'e1001',
deposit: '¥5000',
rent: '¥8500/月',
electricity: '¥1.2/度',
water: '¥5/吨',
property: '¥300/月',
userId: 'u777',
signer: '张三',
idCard: '440301199001011234',
phone: '13800138000',
idValidDate: '2035-01-01',
},
};
},
computed: {
baseInfo() {
return [
{ label: '合同状态', value: this.contract.status },
{ label: '签约状态', value: this.contract.signStatus },
{ label: '合同生效期', value: `${this.contract.startDate}${this.contract.endDate}` },
{ label: '付款方式', value: this.contract.payMethod },
{ label: '付款时间', value: this.contract.payTime },
{ label: '电子合同', value: '', hasArrow: true, id: this.contract.electronicId },
];
},
feeInfo() {
return [
{ label: '押金/保证金', value: this.contract.deposit },
{ label: '租金', value: this.contract.rent },
{ label: '电费', value: this.contract.electricity },
{ label: '水费', value: this.contract.water },
{ label: '物业/增值服务', value: this.contract.property },
{ label: '我的账单', value: '', hasArrow: true, id: this.contract.id },
];
},
signerInfo() {
return [
{ label: '签约人', value: this.contract.signer },
{ label: '身份证号', value: this.contract.idCard },
{ label: '手机号', value: this.contract.phone },
{ label: '证件有效期', value: this.contract.idValidDate },
];
},
},
methods: {
handleClick(item) {
if (item.label === '电子合同') {
uni.navigateTo({
url: `/pages/contract/contractFile?id=${item.id}`,
});
} else if (item.label === '我的账单') {
uni.navigateTo({
url: `/pages/bill/billList?userId=${this.contract.userId}&contractId=${item.id}`,
});
}
},
goSign() {
uni.navigateTo({
url: `/pages/contract/signContract?id=${this.contract.id}`,
});
},
},
};
</script>
<style lang="scss" scoped>
.contract-detail-page {
background: #f7f8fa;
min-height: 100vh;
padding-top: 175rpx; /* 给导航栏留空间 */
padding-bottom: 120rpx; /* 预留底部操作栏空间 */
}
/* 顶部封面信息 */
.header {
display: flex;
background: #fff;
padding: 24rpx;
border-radius: 12rpx;
margin: 20rpx;
.cover {
width: 180rpx;
height: 180rpx;
border-radius: 12rpx;
margin-right: 20rpx;
}
.info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
.name {
font-size: 30rpx;
font-weight: bold;
color: #333;
margin-bottom: 12rpx;
}
.room {
font-size: 26rpx;
color: #666;
}
}
}
/* 信息区域 */
.section {
background: #fff;
border-radius: 12rpx;
margin: 20rpx;
padding: 20rpx 24rpx;
.section-title {
font-weight: bold;
font-size: 28rpx;
margin-bottom: 12rpx;
color: #333;
}
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.label {
font-size: 26rpx;
color: #666;
}
.value-box {
display: flex;
align-items: center;
.value {
font-size: 26rpx;
color: #333;
}
u-icon {
margin-left: 10rpx;
}
}
}
}
/* 底部固定操作栏 */
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: #fff;
padding: 35rpx;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.06);
z-index: 99;
.sign-btn {
width: 100%;
height: 88rpx;
}
}
</style>

574
pages/detail/detail.vue Normal file
View File

@@ -0,0 +1,574 @@
<template>
<view class="u-margin-left-20 u-margin-right-20">
<u-navbar :is-back="true" title="房源" :border-bottom="false"
back-text="返回" :custom-back="goHome" ></u-navbar>
<view>
<u-swiper :list="swiperlist" :height="750" mode="number" effect3d effect3d-previous-margin="20" :interval="5000" @click="clickImg"></u-swiper>
</view>
<view class="item u-margin-top-5">
<view class="item-title">{{room.type == '整租' ? room.houseNum + room.houseHall + room.toiletNum : room.roomType}}</view>
<view class="item-price">¥{{room.price}}/</view>
</view>
<view class="item" style="display: flex;align-items: center;flex-wrap: wrap;">
<view v-for="(item,index) in tagList" :key="index"
style="background-color: #f5f5f5;color: #606266;margin-right: 15rpx;
margin-top: 15rpx;padding: 0 10rpx;height: 60rpx;line-height: 60rpx;">
{{item.title}}
</view>
</view>
<!-- 小程序通讯 -->
<button type="default" open-type="contact" class="clearBtn">
<u-cell-group>
<u-cell-item title="服务费另计" value="在线咨询"></u-cell-item>
</u-cell-group>
</button>
<view v-if="room.introduce">
<u-gap height="10" bg-color="#f8f8f8"></u-gap>
<u-card title="房源介绍" :border="false" :head-border-bottom="false" padding="0" title-size="38">
<view class="u-padding-top-45 item" slot="body">
{{room.introduce}}
</view>
</u-card>
</view>
<u-gap height="1" bg-color="#f8f8f8"></u-gap>
<view style="position: relative;">
<u-card title="小区介绍" :border="false" :head-border-bottom="false" padding="0" title-size="38">
<view class="u-padding-top-45" slot="body">
<view class="u-flex" style="justify-content: space-between;">
<view class="item">
<view>建筑年份{{village.year}}</view>
<view>建筑类型{{village.type}}</view>
<view>绿化率{{village.green}}%</view>
</view>
<image src="https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg" mode="widthFix"
style="width: 250rpx;height: 200rpx;"></image>
</view>
</view>
</u-card>
</view>
<u-gap height="1" bg-color="#f8f8f8"></u-gap>
<view style="position: relative;">
<u-card :title="room.villageName" :border="false" :head-border-bottom="false" padding="0" title-size="38">
<view class="u-padding-top-45" slot="body">
<map :latitude="latitude" :longitude="longitude">
<cover-view style='width:100%;height:100%;' @click="clickMap"></cover-view>
</map>
<view
@click="clickMap"
style="margin-top: 30rpx;padding-left: 10rpx;height:80rpx;
line-height: 80rpx;background-color: #fdfdfd;border-radius: 6px;
display: flex;justify-content: space-between;
padding-right: 10rpx;color: #909399;
">
<view>
<u-icon name="map" color="#909399" size="30"></u-icon>
<text style="margin-left: 8rpx;">
房源直线距离约 {{distance}} km
</text>
</view>
<view>
<text style="margin-right: 3rpx;">
导航
</text>
<u-icon name="arrow-right" color="#909399" size="30"></u-icon>
</view>
</view>
<view style="margin-top: 20rpx;margin-left: 10rpx;font-size: 10px;
color: #909399">
*数据仅供参考请以实际看房为准
</view>
</view>
</u-card>
</view>
<u-gap height="1" bg-color="#f8f8f8"></u-gap>
<view style="position: relative;">
<u-card title="服务介绍" :border="false" :head-border-bottom="false" padding="0" title-size="38">
<view class="u-padding-top-35" slot="body">
<u-cell-group :border="false">
<u-cell-item icon="heart" title="承诺-四大租住承诺,安心有保障" :arrow="false" hover-class="none" :border-bottom="false"></u-cell-item>
<u-cell-item icon="level" title="品质-两类品质保障,入住更无忧" :arrow="false" hover-class="none" :border-bottom="false"></u-cell-item>
<u-cell-item icon="star" title="服务-两项日常服务,生活超便捷" :arrow="false" hover-class="none" :border-bottom="false"></u-cell-item>
<u-cell-item icon="rmb" title="付款-多种付款方式,支付更灵活" :arrow="false" hover-class="none" :border-bottom="false"></u-cell-item>
</u-cell-group>
</view>
</u-card>
</view>
<u-gap height="1" bg-color="#f8f8f8"></u-gap>
<view style="position: relative;">
<u-card title="房源评价" :border="false" :head-border-bottom="false" padding="0" title-size="38">
<view class="u-padding-top-50 u-padding-bottom-50" slot="body">
<u-cell-group :border="false">
{{evaluate}}
<text style="float: right;color: #909399;font-size: 13px;">{{credt}}</text>
</u-cell-group>
</view>
<view slot="foot" style="padding-top: 30rpx;float: right;">
<u-icon name="chat-fill"></u-icon>
<text @click="moreEval" style="text-align: center;font-size: 12px;margin-left: 5rpx;">更多评价{{evalsize}}</text>
</view>
</u-card>
</view>
<u-gap height="10" bg-color="#f8f8f8"></u-gap>
<view style="position: relative;padding-bottom: 50rpx;">
<u-card title="经纪人" :border="false" :head-border-bottom="false" padding="0" title-size="38">
<view class="u-padding-top-45" slot="body">
<view class="u-flex">
<view class="u-m-r-20">
<u-avatar :src="room.agentAvatar" size="80"></u-avatar>
</view>
<view class="u-flex-1">
<view class="u-font-16 u-p-b-40">{{room.agentName}}</view>
<!-- <view class="u-font-12 u-p-b-10">{{user.agentPhone}}</view> -->
</view>
</view>
<view class="arrow-right" @click="clickItem">
<view class="phone">
<u-icon name="phone" class="u-p-l-10" color="#d1d1d1"
size="40"
></u-icon>
</view>
</view>
</view>
</u-card>
<view class="item">
<u-divider>开源字节为您服务</u-divider>
</view>
</view>
<view class="navigation">
<view class="left">
<button type="default" open-type="contact" class="clearBtn"
style="font-size: 14px;color: #6a6a6a;">
<view class="item">
<u-icon name="server-fill" :size="40"></u-icon>
<view class="text">客服</view>
</view>
</button>
<view class="item" @click="heartHouse">
<u-icon name="heart" :size="40" v-if="!room.heart"></u-icon>
<u-icon name="heart-fill" color="#ff9900" :size="40" v-if="room.heart"></u-icon>
<view class="text">收藏</view>
</view>
<button type="default" open-type="share" class="clearBtn"
style="font-size: 14px;color: #6a6a6a;">
<view class="item">
<u-icon name="zhuanfa" :size="40"></u-icon>
<view class="text">分享</view>
</view>
</button>
</view>
<view class="right" @click="clickItem">
<view class="btn">联系经纪人</view>
</view>
</view>
</view>
</template>
<script>
import config from "@/common/config.js" // 全局配置文件
export default {
data() {
return {
room: {
villageName:'',
houseNum:'',
houseHall:'',
toiletNum:'',
roomType:'',
direction:'',
price:'',
introduce:'',
heart:false,
},
village: {
year:'',
type:'',
green:'',
},
swiperlist: [],
tagList: [],
//评价列表
evaluList:[],
user: {},
longitude: 120.14,
latitude: 30.35,
distance:0,
//自己的评论
ownevalu:'',
houseId:null,
evalsize:0,
havem:false,
evaluate:'',
credt:''
}
},
onLoad: function (option) {
let houseId = option.houseId //上个页面传递的参数。
this.houseId =houseId
// 渲染当前房源信息
this.findHouseById(houseId);
// // 在页面中定义激励视频广告
// let videoAd = null
// // 在页面onLoad回调事件中创建激励视频广告实例
// if (wx.createRewardedVideoAd) {
// videoAd = wx.createRewardedVideoAd({
// adUnitId: 'adunit-8cd5789a01a51891'
// })
// videoAd.onLoad(() => {
// console.log('激励视频 成功加载广告')
// })
// videoAd.onError((err) => {})
// videoAd.onClose((res) => {
// console.log('激励视频 成功关闭广告')
// })
// }
// // 用户触发广告后,显示激励视频广告
// if (videoAd) {
// videoAd.show().catch(() => {
// // 失败重试
// videoAd.load()
// .then(() => videoAd.show())
// .catch(err => {
// console.log('激励视频 广告显示失败')
// })
// })
// }
},
methods: {
heartHouse(){
// 判断是否有userId
let lifeData = uni.getStorageSync('lifeData');
let vuex_user = lifeData.vuex_user
if(!vuex_user){
// 没有userId 则跳转到登录
return uni.reLaunch({
url:'../login/login'
})
}
// 收藏
let url = "api/houseApi/saveHeart";
this.$u.post(url, {
heart: this.room.heart,
houseId: this.room.id,
userId: vuex_user.user.userId,
}).then(result => {
this.room.heart = !this.room.heart
this.$mytip.toast(result.msg)
});
},
goHome(){
uni.reLaunch({
url:'../index/index'
})
},
clickItem() {
//拨打固定电话
uni.makePhoneCall({
phoneNumber: this.room.agentPhone,
});
},
findHouseById(houseId){
let url = "api/houseApi/findHouseById";
this.$u.get(url, {
id: houseId
}).then(result => {
let room = result.data
if(room.type == 0){
room.type = '整租'
}else if(room.type == 1){
room.type = '合租'
}
if(room.roomType == 1){
room.roomType = '主卧'
}else if(room.roomType == 2){
room.roomType = '次卧'
}else{
room.roomType = '未知'
}
if(this.$u.test.isEmpty(room.houseNum)){
room.houseNum = ''
}
if(this.$u.test.isEmpty(room.houseHall)){
room.houseHall = ''
}
if(this.$u.test.isEmpty(room.toiletNum)){
room.toiletNum = ''
}
if(this.$u.test.isEmpty(room.floor)){
room.floor = ''
}else{
room.floor = room.floor + '层'
}
this.swiperlist = room.imageList.map(val=>{
let imgUrl = val.imgUrl
if(!imgUrl.includes(config.staticUrl)){
imgUrl = config.staticUrl+val.imgUrl
}else{
imgUrl = val.imgUrl
}
return {
title: val.imageName,
image: imgUrl
}
})
this.tagList = room.featureList.map(val=>{
return {
title: val.feature,
}
})
if(!room.agentAvatar.includes(config.staticUrl)){
room.agentAvatar = config.staticUrl+room.agentAvatar
}
this.user = room.user
this.village = room.village
this.room = room
// 判断是否收藏
this.selectHouseHeart(houseId);
//查询房源评价
this.selectHouseEvals(houseId);
// 分享自定义标题与图片
let shareTitle = ''
if(room.type == '整租'){
shareTitle = this.village.name + " " + this.room.houseNum + this.room.houseHall + this.room.toiletNum + " " + this.room.decoration+ " ¥" + this.room.price+"/月"
}else{
shareTitle = this.village.name + " " + room.roomType + " " + this.room.decoration+ " ¥" + this.room.price+"/月"
}
this.$u.mpShare = {
title: shareTitle, // 默认为小程序名称,可自定义
// 支持PNG及JPG默认为当前页面的截图
imageUrl: this.room.faceUrl,
}
// 添加到浏览历史
let houseHistory = uni.getStorageSync('houseHistory')
if(!houseHistory){
houseHistory = []
}
// 如果超过20个了则删除最后一个
if(houseHistory.length >= 20){
houseHistory.pop()
}
houseHistory.push(this.room)
// 数据去重
const keyArr = [];
houseHistory.forEach((element,index) => {
keyArr.push(element.code); // 通过code来判断
});
const newArr = [];
const newKey = new Set(keyArr); // key去重
newKey.forEach(item =>{
const index = keyArr.findIndex(item2 => item2 === item);
newArr.push(houseHistory[index]);
})
uni.setStorageSync('houseHistory',newArr)
// 经纬度
this.longitude = room.longitude
this.latitude = room.latitude
// 计算距离
let lat1 = 39.909
let lng1 = 116.39742
let lat2 = this.latitude
let lng2 = this.longitude
uni.getLocation({
type: 'gcj02',
success: res=> {
lat1 = res.latitude
lng1 = res.longitude
this.distance = this.getDistance(lat1,lng1 ,lat2 , lng2);
}
})
});
},
selectHouseHeart(houseId){
// 判断是否有userId
let lifeData = uni.getStorageSync('lifeData');
let vuex_user = lifeData.vuex_user
if(vuex_user){
let url = "api/houseApi/selectHouseHeart";
this.$u.get(url, {
houseId: houseId,
userId: vuex_user.user.userId,
}).then(result => {
this.room.heart = result.data
});
}
},
selectHouseEvals(houseId){
let url = "api/houseApi/selectHouseEvals";
this.$u.get(url, {
houseId: houseId,
pageNum: 1,
pageSize: 1
}).then(result => {
if(result.total >0){
this.evaluate = result.rows[0].evaluate;
if(this.evaluate.length>30){
this.evaluate = this.evaluate .substring(0, 30)+"......";
}
this.credt=result.rows[0].createTime;
this.havem=true;
this.evalsize = result.total;
}
});
},
moreEval() {
this.$u.route({
url: '/pages/detail/evalList',
params: {
houseId: this.houseId
}
})
},
clickImg(index){
let imgArr = this.swiperlist.map(val=>{
return val.image
})
console.log(imgArr);
// 预览图片
uni.previewImage({
current: index,
urls: imgArr
});
},
clickMap(e){
uni.openLocation({
longitude: Number(this.longitude),
latitude: Number(this.latitude),
name: this.room.villageName,
address: this.room.address
})
},
getDistance(lat1, lng1, lat2, lng2) {
lat1 = lat1 || 0;
lng1 = lng1 || 0;
lat2 = lat2 || 0;
lng2 = lng2 || 0;
var rad1 = lat1 * Math.PI / 180.0;
var rad2 = lat2 * Math.PI / 180.0;
var a = rad1 - rad2;
var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
var r = 6378137;
var distance = r * 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(rad1) * Math.cos(rad2) * Math.pow(Math.sin(b / 2), 2)));
return (distance/1000).toFixed(2);
}
}
}
</script>
<style>
/* page不能写带scope的style标签中否则无效 */
page {
background-color: rgb(255, 255, 255);
}
</style>
<style lang="scss" scoped>
map {
width: 100%;
height: 350rpx;
}
.item{
padding: 25rpx;
line-height: 80rpx;
margin-top: -30rpx;
}
.item-title {
font-size: 42rpx;
color: $u-main-color;
font-weight: bold;
}
.item-price {
font-weight: normal;
font-size: 45rpx;
color: $u-type-warning;
}
.item-desc {
font-weight: normal;
font-size: 36rpx;
color: $u-tips-color;
}
.arrow-right{
position: absolute;
top: 80rpx;
right: 28rpx;
font-weight: normal;
font-size: 28rpx;
color: $u-tips-color;
.phone{
width: 90rpx;height:90rpx;
border-radius: 100%;
box-shadow: 0px 1px 20px 0px rgba(0,0,0,0.1);
display: flex;
justify-content: center;
align-items: center;
}
}
.wayClass{
color: #606266;
padding: 30rpx;
line-height: 50rpx;
}
.clearBtn{
margin:0;
padding: 0;
line-height: 1;
background-color: #FFFFFF;
}
.clearBtn::after{
position: unset !important;
border: unset;
}
.navigation {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 0rpx 15rpx;
background-color: #ffffff;
box-shadow:0 -1px 1px 0 rgba(0, 0, 0, 0.05);
z-index: 9999;
.left {
display: flex;
justify-content: center;
align-items: center;
margin-top: 38rpx;
font-size: 14px;
color: #6a6a6a;
.item {
display: flex;
.text{
margin-left: 4rpx;
}
}
}
.right {
display: flex;
font-size: 28rpx;
align-items: center;
.btn {
line-height: 66rpx;
margin-left: 30rpx;
padding: 5rpx 50rpx;
color: #ffffff;
border-radius: 36rpx;
background-color: #2979ff;
}
}
}
</style>

132
pages/detail/evalList.vue Normal file
View File

@@ -0,0 +1,132 @@
<template>
<view >
<view class="text">
<text style="font-size: 15px;margin-left: 20rpx;">全部评价({{total}})
<text style="float: right;margin-right: 20rpx;font-weight: bold;" @click="inputDialogToggle" >添加评价</text>
</text>
</view>
<view class="text" v-for="(item,index) in listData" :key="index" style="padding: 0 20rpx;margin-top: 6rpx;">
<view><text>{{ item.evaluate }}</text></view>
<view style="text-align: right;color: #909399;font-size: 13px;"><text>{{ item.createTime }}</text></view>
</view>
<view>
<!-- 输入框示例 -->
<uni-popup ref="inputDialog" type="dialog">
<uni-popup-dialog ref="inputClose" mode="input" title="评价房源" value=""
@confirm="submitEval">
<textarea placeholder="请输入评价" v-model="ownevalu" ></textarea>
</uni-popup-dialog>
</uni-popup>
</uni-popup>
</view>
</view>
</template>
<script>
export default {
data() {
return {
houseId:null,
listData: [],
pageNum: 1,
pageSize: 20,
scrollTop: 0,
reload: false,
loadStatus: 'loadmore',
status: 'more',
total:0,
ownevalu:'',
userId:null
};
},
onLoad(option) {
this.houseId = option.houseId; //上个页面传递的参数。
this.getList();
},
onPageScroll(e) {
this.scrollTop = e.scrollTop;
},
onReachBottom() {
this.loadStatus = 'loading';
// 获取数据
this.getList()
},
// 下拉刷新
onPullDownRefresh() {
this.pageNum = 1
this.$refs.uWaterfall.clear();
// 获取数据
this.getList();
// 关闭刷新
uni.stopPullDownRefresh();
},
methods: {
getList() {
let url = "/api/houseApi/selectHouseEvals";
let defaultData = {
houseId:this.houseId,
pageNum: this.pageNum,
pageSize: this.pageSize
}
this.$u.get(url, {...defaultData}).then(result => {
console.log(result);
const data = result.rows;
this.total= result.total;
if(this.pageNum>0 && data.length < this.pageSize){
this.loadStatus = 'nomore';
}else{
++ this.pageNum
this.loadStatus = 'loadmore';
}
this.listData = data;
});
},
inputDialogToggle() {
// 判断是否有userId
let lifeData = uni.getStorageSync('lifeData');
let vuex_user = lifeData.vuex_user
if(!vuex_user){
// 没有userId 则跳转到登录
return uni.reLaunch({
url:'../login/login'
})
}
this.userId=vuex_user.userId;
this.$refs.inputDialog.open();
//判断是否有评价权限
// let url = "api/houseApi/checkAuthEvals";
// this.$u.get(url, {
// houseId: this.houseId,
// userId:this.userId
// }).then(result => {
// if(result.code === 200 && result.data.length>0){
// this.$refs.inputDialog.open();
// }else{
// this.$mytip.toast("只有租客才能进行评论!");
// }
// });
},
submitEval(){
let url = "api/houseApi/saveHouseEvals";
this.$u.get(url, {
houseId: this.houseId,
evalu: this.ownevalu,
userId:this.userId
}).then(result => {
this.$mytip.toast('评价成功')
this.$refs.inputDialog.close()
this.getList();
});
}
}
};
</script>
<style>
.text {
background-color: #fff;
line-height: 80rpx;
}
</style>

318
pages/detail/preHouse.vue Normal file
View File

@@ -0,0 +1,318 @@
<template>
<view class="">
<!-- #ifndef MP-WEIXIN -->
<u-image width="100%" height="350rpx" :src="src"></u-image>
<!-- #endif -->
<view class="wrap">
<u-form :model="model" :rules="rules" ref="uForm" :errorType="errorType">
<u-form-item :label-position="labelPosition" label="小区名称" prop="villageName" label-width="180"
left-icon="map" :leftIconStyle="{color:'#d5d5d5'}">
<u-input :border="border" type="select" :select-open="selectShow" v-model="model.villageName" placeholder="请选择小区(必选)" @click="selectShow = true"></u-input>
</u-form-item>
<u-form-item :label-position="labelPosition" label="详细地址" prop="address" label-width="180"
left-icon="file-text" :leftIconStyle="{color:'#d5d5d5'}" right-icon="map"
:rightIconStyle="{color:'#d5d5d5'}">
<u-input :border="border" placeholder="请在地图选择详细地址" v-model="model.address" type="text" disabled
@click="chooseAddress"></u-input>
</u-form-item>
<u-form-item :label-position="labelPosition" label="房牌号" prop="houseNo" label-width="180"
left-icon="home" :leftIconStyle="{color:'#d5d5d5'}">
<u-input :border="border" placeholder="请输入门牌号(必填)" v-model="model.houseNo" type="text"></u-input>
</u-form-item>
<u-form-item :label-position="labelPosition" label="装修" prop="decoration" label-width="180" left-icon="eye" :leftIconStyle="{color:'#d5d5d5'}">
<u-input :border="border" type="select" placeholder="请选择装修(必选)":select-open="decorationShow" v-model="model.decoration" @click="decorationShow = true"></u-input>
</u-form-item>
<u-form-item :label-position="labelPosition" label="房东姓名" prop="ownerName" label-width="180"
left-icon="account" :leftIconStyle="{color:'#d5d5d5'}">
<u-input :border="border" placeholder="请输入房东姓名(必填)" v-model="model.ownerName" type="text"></u-input>
</u-form-item>
<u-form-item :label-position="labelPosition" label="房东电话" prop="owerPhone" label-width="180"
left-icon="phone" :leftIconStyle="{color:'#d5d5d5'}">
<u-input :border="border" placeholder="请输入房东电话(必填)" v-model="model.owerPhone" type="number" maxlength="11"></u-input>
</u-form-item>
<u-form-item label-width="180" :label-position="labelPosition" label="付款方式" prop="payType"
left-icon="rmb-circle" :leftIconStyle="{color:'#d5d5d5'}">
<u-input :border="border" type="select" :select-open="actionSheetShow" v-model="model.payType" placeholder="请选择付款方式(必选)" @click="actionSheetShow = true"></u-input>
</u-form-item>
</u-form>
<!-- 流量主-腾讯视频广告 -->
<ad unit-id="adunit-c6cdd74f48eed506" ad-type="video" ad-theme="white"></ad>
<u-select mode="single-column" :list="selectList" v-model="selectShow" @confirm="selectConfirm"></u-select>
<u-select mode="single-column" :list="decorationList" v-model="decorationShow" @confirm="decorationConfirm"></u-select>
<u-action-sheet :list="actionSheetList" v-model="actionSheetShow" @click="actionSheetCallback"></u-action-sheet>
</view>
<view class="bottom-btn">
<u-button type="primary" @click="submit">下一步</u-button>
</view>
</view>
</template>
<script>
export default {
data() {
let that = this;
return {
src: 'http://img.sccnn.com/bimg/340/02027.jpg',
actionSheetShow: false,
model: {
type: 0,
houseType: '',
roomLabel: '',
villageName: '',
villageId: '',
address: '',
houseNo: '',
//装修
decoration:'',
//房东
ownerName:'',
//房东电话
owerPhone:'',
payType:'',
createName: uni.getStorageSync('lifeData').vuex_user.userName,
publishId: uni.getStorageSync('lifeData').vuex_user.userId,
state: 0,
longitude: 0,
latitude: 0,
},
selectList: [],
decorationList: [
{
label: '简装',
value: '简装'
},
{
label: '中装',
value: '中装'
},
{
label: '精装修',
value: '精装修'
},
{
label: '豪装',
value: '豪装'
}
],
actionSheetList: [
{
text: '月付'
},
{
text: '季付'
},
{
text: '半年付'
},
{
text: '年付'
}
],
rules: {
villageName: [
{
required: true,
message: '请选择小区',
trigger: ['change','blur'],
}
],
address: [
{
required: true,
message: '请输入详细地址',
trigger: ['change','blur'],
}
],
houseNo: [
{
required: true,
message: '请输入门牌号',
trigger: ['change','blur'],
}
],
decoration: [
{
required: true,
message: '请选择装修',
trigger: ['change','blur'],
}
],
ownerName: [
{
required: true,
message: '请输入房东姓名',
trigger: ['change','blur'],
}
],
owerPhone: [
{
required: true,
message: '请输入房东电话',
trigger: ['change','blur'],
}
],
payType: [
{
required: true,
message: '请选择付款方式',
trigger: ['change','blur'],
}
],
},
border: false,
check: false,
selectShow: false,
decorationShow: false,
labelPosition: 'left',
errorType: ['toast'],
};
},
onLoad(option) {
let houseId = option.houseId //上个页面传递的参数。
if(houseId){
// 渲染当前房源信息
this.findHouseById(houseId);
}
this.findVillageList()
// 定位经纬度
uni.getLocation({
type: 'gcj02',
// 当指定 high 时期望精度值为100m当指定 best 时期望精度值为20m
accuracy:'best',
// 开启高精度定位
isHighAccuracy:true,
success: (res) => {
this.longitude=res.longitude
this.latitude= res.latitude
}
});
uni.$on('changeAddressConfig', (address,lon,lat) => {
// 获取数据
this.changeAddressConfig(address,lon,lat);
})
},
onUnload() {
// 移除监听事件
uni.$off('changeAddressConfig');
},
onReady() {
this.$refs.uForm.setRules(this.rules);
},
methods: {
changeAddressConfig(address,lon,lat){
this.model.address = address
this.model.longitude= lon
this.model.latitude= lat
},
submit() {
this.$refs.uForm.validate(valid => {
if (valid) {
if(!this.$u.test.mobile(this.model.owerPhone)){
return this.$mytip.toast('房东电话请输入手机号码')
}
return this.$u.route({
url: '/pages/detail/addHouse',
params: {
room: JSON.stringify(this.model)
}
})
} else {
console.log('验证失败');
}
});
},
selectConfirm(e) {
e.map((val, index) => {
this.model.villageName = val.label;
this.model.villageId = val.value
})
},
decorationConfirm(e) {
e.map((val, index) => {
this.model.decoration = val.label;
})
},
labelPositionChange(index) {
this.labelPosition = index == 0 ? 'left' : 'top';
},
// 点击actionSheet回调
actionSheetCallback(index) {
uni.hideKeyboard();
this.model.payType = this.actionSheetList[index].text;
},
findVillageList() {
let url = "/api/houseApi/findVillageList";
this.$u.get(url,{
city:uni.getStorageSync('lifeData').vuex_city,
orderByColumn: 'name',
isAsc: 'desc'
}).then(result => {
const data = result.rows
for (let i = 0; i < data.length; i++) {
// 先转成字符串再转成对象,避免数组对象引用导致数据混乱
let item = data[i]
this.selectList.push({
label: item.name,
value: item.id
})
}
return data
});
},
findHouseById(houseId){
let url = "api/houseApi/findHouseById";
this.$u.get(url, {
id: houseId
}).then(result => {
let room = result.data
this.model = room
let houseType = this.model.houseNum + this.model.houseHall + this.model.toiletNum
if(houseType == 0){
houseType = ''
}
this.model.houseType = houseType
if(this.model.roomType == 1){
this.model.roomLabel = '主卧'
}else if(this.model.roomType == 2){
this.model.roomLabel = '次卧'
}
});
},
chooseAddress() {
this.$u.route({
url: '/pages/chooseAddress/index'
})
},
}
};
</script>
<style>
page{
background-color: #FFFFFF;
}
</style>
<style scoped lang="scss">
.wrap {
padding: 30rpx;
}
/* #ifdef MP-WEIXIN */
.bottom-btn {
position: fixed;
bottom: 8rpx;
width: 100%;
padding: 30rpx;
border-top: 1rpx solid #eee;
background-color: #FFFFFF;
}
/* #endif */
/* #ifndef MP-WEIXIN */
.bottom-btn {
padding: 0 30rpx 30rpx 30rpx;
background-color: #FFFFFF;
}
/* #endif */
</style>