Files
RentWeAppFront/pages-assets/assets/assetsDetail.vue
2026-01-30 09:01:38 +08:00

554 lines
13 KiB
Vue
Raw Permalink 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="asset-detail">
<!-- 顶部导航栏 -->
<customNavbar title="资产详情" ref="navbar" :is-transparent="navbarStyle.isTransparent"
:bg-color="navbarStyle.bgColor" :text-color="navbarStyle.textColor" :opacity="navbarStyle.opacity"
:extra-icons="navbarStyle.extraIcons" :show-home="false" />
<!-- 图片展示区 -->
<view class="image-section" :style="{ paddingTop: navTotalHeight + 'px' }">
<Carousel :list="swiperList" boxHeight="740rpx" :vrIcon="staticHost + '/public/static/icon/vr.png'"
vrViewPage="/pages-biz/vr/vr" :vr-list="vrList" />
</view>
<!-- 资产基本信息 -->
<view class="container">
<view class="basic-info">
<view class="info-header">
<view class="category-tag">{{ asset.type || '未知' }}</view>
<view class="asset-name">{{ asset.name || '未知'}}</view>
</view>
<view class=" featureArea feature-list">
<view class="feature-tag" v-for="(item, index) in asset.features" :key="index"
:style="{ color: getRandomColor().color,backgroundColor: getRandomColor().bg}">
{{ item }}
</view>
</view>
<view class="stress-info">
<view class="stress-item">
<view class="stress-value">{{ asset.rent || '未知'}}/</view>
<view class="stress-label">租金</view>
</view>
<view class="stress-item">
<view class="stress-value">{{ asset.layout || '未知'}}</view>
<view class="stress-label">户型</view>
</view>
<view class="stress-item">
<view class="stress-value">{{ asset.area || '未知'}}</view>
<view class="stress-label">面积</view>
</view>
</view>
</view>
<!-- 资产信息表格 -->
<view class="asset-info-table">
<view class="table-title">资产信息</view>
<view class="table-content">
<view class="table-row">
<view class="row-item">
<view class="item-label">朝向</view>
<view class="item-value">{{ asset.orientation || '未知'}}</view>
</view>
<view class="row-item">
<view class="item-label">电梯</view>
<view class="item-value">{{ asset.hasLift|| '未知' }}</view>
</view>
</view>
<view class="table-row">
<view class="row-item">
<view class="item-label">单元</view>
<view class="item-value">{{ asset.unitNo || '未知'}}</view>
</view>
<view class="row-item">
<view class="item-label">楼层</view>
<view class="item-value">{{ asset.floorNo || '暂无' }}</view>
</view>
</view>
<view class="table-row">
<view class="row-item full-width">
<view class="item-label">门牌号</view>
<view class="item-value">{{ asset.roomNo || '未知'}}</view>
</view>
</view>
<view class="table-row">
<view class="row-item full-width">
<view class="item-label">资产描述</view>
<view class="item-value">{{asset.remark || '未知'}}</view>
</view>
</view>
<view class="table-row">
<view class="row-item full-width">
<view class="item-label">商圈</view>
<view class="item-value">{{ asset.bizZone || '暂无'}}</view>
</view>
</view>
<view class="table-row">
<view class="row-item full-width">
<view class="item-label">地址</view>
<view class="item-value">{{ asset.address || '未知'}}</view>
</view>
</view>
</view>
</view>
</view>
<!-- 地图位置 -->
<view class="map-container">
<map :latitude="asset.lat||'0'" :longitude="asset.lng|| '0'" :markers="markers"
style="width: 92%; height: 300rpx;"></map>
</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 v-if="asset.status === '闲置中'" :assetId="assetId" :phone="managerPhone"
@reserve="showReserve = true" btn-title="预约看资产" shareBtnTitle="分享资产"
page-path="/pages-assets/assets/detail/assetsDetail" minicode-api="/pages-assets/assets/detail/assetsDetail"
btnColor="#FF2F31" :query="assetId" />
</view>
</template>
<script>
import assetBottomBar from '../../components/bottom/assetBottomBar.vue';
import CarouselVue from '../../components/Carousel/Carousel.vue';
export default {
components: {
assetBottomBar,
CarouselVue
},
data() {
return {
// 控制预约弹窗显示
showReserve: false,
navTotalHeight: 0,
// 预约表单数据
reserveName: '',
reservePhone: '',
assetId: null,
// 直接使用静态数据
asset: null,
managerPhone: null,
// 根据静态数据初始化标记
vrList: [],
markers: [],
background: {
backgroundColor: '#ffffff',
// 渐变色
// backgroundImage: 'linear-gradient(-90deg, #F9DED9 0%, #F8DFC0 99%);'
},
// 导航栏样式控制
navbarStyle: {
isTransparent: true,
bgColor: '#ffffff',
textColor: '#000000',
opacity: 1,
extraIcons: ['ellipsis'] // 右侧额外图标
},
// 滚动距离
scrollTop: 0,
tagColors: [{
color: '#ffffff',
bg: '#FF2F31'
}]
};
},
onLoad(options) {
this.assetId = options.assetsNo;
// 静态数据初始化
this.loadAssetDetail();
this.recordView();
},
mounted() {
const navbar = this.$refs.navbar;
const navHeight = navbar.navContentHeight; // 直接拿子组件 data
this.navTotalHeight = navHeight; // 加上额外间距
},
onPageScroll(e) {
this.scrollTop = e.scrollTop;
// 计算导航栏透明度和样式
this.updateNavbarStyle(e.scrollTop);
},
computed: {
staticHost() {
return this.$config.staticUrl
},
swiperList() {
let list = [];
if (this.asset && this.asset.vrImgs && this.asset.vrImgs.length > 0) {
this.asset.vrImgs.forEach(img => {
list.push({
src: this.$config.staticUrl + img,
mediaType: 'vr',
bizType: 'vr'
})
})
}
if (this.asset && this.asset.detailImgs && this.asset.detailImgs.length > 0) {
this.asset.detailImgs.forEach(img => {
list.push({
src: this.$config.staticUrl + img,
mediaType: 'image',
bizType: '详细图片'
})
})
}
return list;
}
},
methods: {
// 根据滚动距离更新导航栏样式
updateNavbarStyle(scrollTop) {
// 定义滚动阈值,超过此值导航栏变为不透明
const threshold = 200;
// 计算透明度
let opacity = scrollTop / threshold;
opacity = Math.min(opacity, 1);
opacity = Math.max(opacity, 0);
// 更新导航栏样式
// this.navbarStyle.opacity = opacity;
// if (opacity > 0.5) {
// this.navbarStyle.isTransparent = false;
// } else {
// this.navbarStyle.isTransparent = true;
// }
},
getRandomColor() {
const index = Math.floor(Math.random() * this.tagColors.length)
return this.tagColors[index]
},
// 模拟接口请求
loadAssetDetail() {
let url = `/assets/detail?id=${this.assetId}`
this.$u.get(url).then(result => {
const data = result.data
console.log(data)
this.asset = {
name: data.assetsName,
bizZone: data.bizZone,
code: data.assetsNo,
type: data.assetsType,
area: data.footPrint,
rent: data.rentFee,
address: data.assetsAddress,
hasLift: data.hasLift,
lat: data.latitude,
lng: data.longitude,
unitNo: data.unitNo,
roomNo: data.roomNo,
floorNo: data.floorNo,
description: data.assetsDesc,
detailImgs: data.detailImgs,
layout: data.layout, //户型
orientation: data.orientation, //朝向
vrImgs: data.vrImgs,
remark: data.assetsDesc,
status: data.assetsStatus,
features: ['家电齐全']
};
this.managerPhone = data.managerPhone
this.markers = [{
id: 1,
latitude: this.asset.lat,
longitude: this.asset.lng,
title: this.asset.name,
}, ];
}).catch(err => {
console.log("获取资产信息失败:", err)
})
},
formatMoney(num) {
return Number(num).toLocaleString();
},
toggleFavorite() {
this.asset.isFavorite = !this.asset.isFavorite;
uni.showToast({
title: this.asset.isFavorite ? '已收藏' : '取消收藏',
icon: 'success',
});
},
validatePhoneNumber(phone) {
const regex = /^1[3-9]\d{9}$/;
return regex.test(phone);
},
submitReserve() {
console.log('提交预约看房申请')
// 身份证校验
if (!this.validatePhoneNumber(this.reservePhone)) {
uni.showToast({
title: '手机号格式不正确',
icon: 'none'
});
return;
}
let url = '/reservate/submit'
this.$u.post(url, {
reserveName: this.reserveName,
assetsNo: this.assetId,
assetsName: this.asset.name,
phone: this.reservePhone
}, {
WT: this.$getToken()
}).then(res => {
if (res.flag) {
this.$mytip.toast('提交预约成功成功')
} else {
this.$mytip.toast('预约提交失败,请重试')
}
})
this.showReserve = false;
},
recordView(assetId) {
let token = this.$getToken()
if (token) {
let url = "/potential/add";
this.$u.get(url, {
assetId: this.assetId
}, {
'WT': this.$getToken()
}).then(obj => {
}).catch(err => {
console.log("记录客户浏览记录失败", err)
})
}
},
},
};
</script>
<style lang="scss" scoped>
.asset-detail {
background-color: #f7f8fa;
min-height: 100vh;
padding-bottom: 400rpx;
padding-top: 0;
/* 不再需要固定的顶部内边距,由动态计算的 navTotalHeight 控制 */
}
/* 图片展示区 */
.image-section {
width: 100%;
background-color: #000;
}
.image-section image {
width: 100%;
height: 740rpx;
}
/* 基本信息区 */
.container {
width: 100%;
border-radius: 40rpx 40rpx 0rpx 0rpx;
background-color: #ffffff;
margin-top: -50rpx;
position: relative;
}
.basic-info {
padding: 20rpx 30rpx;
padding-top: 50rpx;
}
.stress-info {
display: flex;
height: 150rpx;
background-color: #fff;
}
.stress-item {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center; // 垂直居中
align-items: center; // 水平居中
position: relative;
}
/* 分隔线:不是最后一个才显示 */
.stress-item:not(:last-child)::after {
content: '';
position: absolute;
right: 0;
top: 25%;
width: 1px;
height: 50%;
background-color: #eee;
}
/* 上面的 value */
.stress-value {
font-size: 40rpx;
font-weight: 600;
color: #FF2F31;
line-height: 1.2;
}
/* 下面的 label */
.stress-label {
margin-top: 8rpx;
font-size: 24rpx;
color: #999;
}
.info-header {
display: flex;
align-items: center;
margin-bottom: 10rpx;
}
.category-tag {
background-color: #FCF2F3;
color: #E9353C;
font-size: 24rpx;
padding: 5rpx 15rpx;
border-radius: 4rpx;
margin-right: 15rpx;
}
.asset-name {
font-size: 32rpx;
font-weight: bold;
color: #333;
flex: 1;
}
.feature-list {
display: flex;
flex-wrap: wrap;
gap: 12rpx;
}
.feature-tag {
padding: 6rpx 16rpx;
font-size: 28rpx;
border-radius: 10rpx;
line-height: 1.4;
}
.featureArea{
margin-top: 30rpx;
margin-bottom: 10rpx;
display: flex;
align-items: center;
}
.address-info {
font-size: 26rpx;
color: #666;
margin-bottom: 10rpx;
display: flex;
align-items: center;
}
.label {
color: #999;
margin-right: 10rpx;
}
/* 地图容器 */
.map-container {
width: 100%;
height: 168px;
padding: 20rpx;
overflow: hidden;
display: flex;
justify-content: center;
background-color: white;
border-radius: 20rpx;
}
/* 资产信息表格 */
.asset-info-table {
padding: 20rpx 30rpx;
margin-bottom: 20rpx;
padding-bottom: 100rpx;
}
.table-title {
font-size: 33rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
}
.table-content {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.table-row {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
}
.row-item {
flex: 1;
min-width: 45%;
display: flex;
flex-direction: column;
gap: 5rpx;
}
.row-item.full-width {
min-width: 100%;
}
.item-label {
font-size: 26rpx;
color: #999;
}
.item-value {
font-size: 30rpx;
color: #333;
font-weight: 500;
}
/* 预约弹窗 */
.popup-content {
padding: 40rpx 30rpx;
background-color: #fff;
border-radius: 20rpx 20rpx 0 0;
&::v-deep .u-btn {
background: #ff3b30;
}
}
.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>