Files
gterFang/src/views/apartmentDetail.vue
2023-07-26 19:14:37 +08:00

1756 lines
66 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>
<page-top-bar></page-top-bar>
<div class="content wid1200">
<div class="header">
<div class="top flexflex">
<div class="brand-name flexcenter">{{ company.title }}</div>
<div class="brand-abstract">{{ info['propaganda'] }}</div>
</div>
<div class="header-content flexflex">
<img class="arc" src="@/assets/img/publicImage/arc-shadow.png">
<div class="header-left">
<image-watch style="z-index: 1003;" :show="imageShow" :close="cloaseImageShow"
:list="imageList"></image-watch>
<div class="slideshow">
<el-carousel :autoplay="false" indicator-position="none" ref="remarkCaruselUp"
@change="carouselChange">
<el-carousel-item class="flexcenter" v-for="item in allCarouselsData">
<img class="img" :src="item['image'] || item['imageurl']"
@click="cloaseImageShow(allCarouselsData)">
</el-carousel-item>
</el-carousel>
<div class="indicate-type flexacenter" v-if="allCarouselsData.length != 0">
<div class="indicate-item"
:class="{ 'pitch': allCarouselsData[carouselIndex]['type'] == 'lives' }"
v-if="info['lives'] && info['lives'].length != 0" @click="slideshowType('lives')">
直播</div>
<div class="indicate-item"
:class="{ 'pitch': allCarouselsData[carouselIndex]['type'] == 'videos' }"
v-if="info['videos'] && info['videos'].length != 0" @click="slideshowType('videos')">视频
</div>
<div class="indicate-item"
:class="{ 'pitch': allCarouselsData[carouselIndex]['type'] == 'attachment' }"
v-if="info['attachment'] && info['attachment'].length != 0"
@click="slideshowType('attachment')">图片</div>
</div>
<div class="indicate" v-if="allCarouselsData.length != 0">
{{ carouselIndex - carouselsconfig[allCarouselsData[carouselIndex]['type']]['index'] + 1 }}/{{
carouselsconfig[allCarouselsData[carouselIndex]['type']]['amount'] }}</div>
</div>
<div class="slideshow-across flexflex">
<div class="slideshow-btn left flexcenter" @click="handleslideshow('left')">
<img v-if="carouselIndex == 0" class="arrow" src="@/assets/img/publicImage/gray-arrow.svg" />
<img v-else class="arrow rotate180" src="@/assets/img/publicImage/black-arrow.svg" />
</div>
<div ref="slideshowList" class="slideshow-list box no-scrollbar flex1 flexacenter">
<div class="item" :class="{ 'pitch': index == carouselIndex }, `item${index}`"
v-for="(item, index) in allCarouselsData" @click="slideshowItem(index)">
<img class="img" :src="item['thumbnail'] || item['imageurl']" />
<img class="video-icon" v-if="item['type'] != 'attachment'"
src="@/assets/img/publicImage/video-icon.svg">
</div>
</div>
<div class="slideshow-btn flexcenter" @click="handleslideshow('right')">
<img v-if="carouselIndex == allCarouselsData.length - 1" class="arrow rotate180"
src="@/assets/img/publicImage/gray-arrow.svg" />
<img v-else class="arrow" src="@/assets/img/publicImage/black-arrow.svg" />
</div>
</div>
</div>
<div class="header-right flex1">
<div class="tab-box flexflex" v-if="info['tags'] && info['tags'].length != 0">
<div class="tab-item flexcenter" v-for="item in info['tags']">{{ item }}</div>
</div>
<div class="apartment-name" v-if="info['title']">{{ info['title'] }}</div>
<div class="synopsis">{{ info['introduction'] }}</div>
<div class="place flexacenter" v-if="info['address']">
<div class="left flexacenter">
<img class="icon" src="@/assets/img/publicImage/location-icon.png" />
{{ info['address'] }}
</div>
<div class="right flexacenter" @click="handleClickNav('addressEle')">
位置与交通
<img class="icon" src="@/assets/img/publicImage/black-arrow.svg" />
</div>
</div>
<div class="else flexacenter" v-if="withsameapartments">
<div class="left flexacenter">
<img class="icon" src="@/assets/img/apartmentDetail/yellow-diamond.png" />
同品牌其他公寓
</div>
<div class="right flexacenter" @click="handleClickNav('eleseEle')">
<div class="quantity flexcenter">{{ withsameapartments }}</div>
<img class="icon" src="@/assets/img/publicImage/black-arrow.svg" />
</div>
</div>
</div>
</div>
</div>
<div class="operate-box flexacenter">
<div class="nav-box flexacenter">
<div class="nav-item flexcenter" :class="{ 'pitch': navTab == item.value }" v-for="item in navList"
@click="handleClickNav(item.value)">{{ item['value'] == 'roomEle' ? `${item['name']} ${roomList.length}`
: item['name'] }}
</div>
</div>
<div class="btn-box flexacenter">
<div class="btn-item transmit-btn flexcenter" @click="handleTransmit">
<img class="transmit-icon" src="@/assets/img/publicImage/transmit-icon.png" />
转发
<transmit-btn :qrcode="qrcode" :title="info['title']"></transmit-btn>
</div>
<div class="btn-item consult-btn flexcenter" @click="modificationContact">咨询</div>
</div>
</div>
<div class="details-box flexflex">
<div class="details-left flex1" ref="detailsLeft">
<!-- 房间类型 -->
<div class="type-box" v-if="roomList.length != 0" ref="roomEle">
<div class="type-item flexacenter" v-for="(item, index) in roomList">
<img class="type-icon" v-if="item['status'] == 1"
src="@/assets/img/apartmentDetail/apartment-have.svg" />
<img class="type-icon" v-else src="@/assets/img/apartmentDetail/apartment-not.svg" />
<div class="type-left flex1">
<div class="type-name">{{ item['name'] }}</div>
<div class="type-tags flexacenter">
<div class="tags-item flexcenter first" v-if="item.allowance">仅剩{{ item.allowance }}</div>
<div class="tags-item flexcenter" v-for="it in item.tags">{{ it }}</div>
</div>
<div class="media-box flexflex" v-if="item.videos.length != 0 || item.images.length != 0">
<div class="media-btn flexcenter" @click="handleMediaBtn('left', index)"
v-if="item.videos.length + item.images.length > 5">
<img v-if="mediaBtnstate[index] && mediaBtnstate[index] != 0" class="rotate180 arrow"
src="@/assets/img/publicImage/black-arrow.svg" alt="">
<img v-else="mediaBtnstate[index] == 0" class="arrow"
src="@/assets/img/publicImage/gray-arrow.svg" alt="">
</div>
<div class="media-list flexacenter no-scrollbar" :class="`element${index}`">
<div class="media-item flexcenter" v-for="it in item['videos']"
@click="cloaseImageShow([...item['videos'], ...item['images']])">
<img class="media-img" :src="it['thumbnail']">
<img class="media-icon" src="@/assets/img/apartmentDetail/media-icon.svg" />
</div>
<div class="media-item flexcenter" v-for="it in item['images']"
@click="cloaseImageShow([...item['videos'], ...item['images']])">
<img class="media-img" :src="it['thumbnail']">
</div>
</div>
<div class="media-btn flexcenter" @click="handleMediaBtn('right', index)"
v-if="item.videos.length + item.images.length > 5">
<img v-show="mediaBtnstate[index] != 1" class="arrow"
src="@/assets/img/publicImage/black-arrow.svg" alt="">
<img v-show="mediaBtnstate[index] == 1" class="rotate180 arrow"
src="@/assets/img/publicImage/gray-arrow.svg" alt="">
</div>
</div>
</div>
<div class="type-right flexacenter">
<div class="price-box flexflex">
<div class="former" v-if="item['discountprice']">HK$ {{ item['price'] }}/</div>
<div class="new flexacenter">
<div class="unit">HK$</div>
<div class="cost">{{ item['discountprice'] || item['price'] }}</div>
/
</div>
</div>
<div class="consult-btn flexcenter" v-if="item['status'] == 1" @click="modificationContact">咨询
</div>
<div class="full-occupancy flexcenter" v-else>已租满</div>
</div>
</div>
</div>
<!-- 优惠活动 -->
<div class="details-item special-offer" v-if="info['promotionalactivities']" ref="specialEle">
<div class="details-header flexacenter">
<img class="icon" src="@/assets/img/apartmentDetail/special-offer.svg">
优惠活动
</div>
<div class="text" v-html="info['promotionalactivities']"></div>
</div>
<!-- 地址 -->
<div class="details-item location" v-if="info.address" ref="addressEle">
<div class="details-header flexacenter">
<img class="icon" src="@/assets/img/apartmentDetail/location-icon.png">
{{ info.location || '位置' }}
</div>
<view-map :latlng="{ longitude: info['coordinate'][0], latitude: info['coordinate'][1] }"
:name="info['address']"></view-map>
<!-- 交通 -->
<div class="traffic-box" v-if="info['traffic']">
<div class="traffic-title item-title flexcenter">交通</div>
<div class="traffic-content" v-html="info['traffic']"></div>
</div>
</div>
<!-- 房源详情 -->
<div class="details-item special-offer" v-if="info['message']" ref="messageEle">
<div class="details-header flexacenter">
<img class="icon" src="@/assets/img/apartmentDetail/listing-details.png">
房源详情
</div>
<div class="text" v-html="info['message']"></div>
</div>
<!-- 公寓设施 -->
<div class="details-item apartment-facilities" v-if="info['facilities']" ref="facilitiesEle">
<div class="details-header flexacenter">
<img class="icon" src="@/assets/img/apartmentDetail/apartment-facilities.svg">
公寓设施
</div>
<div class="facilities-box">
<div class="facilities-item flexflex" v-for="(item, key) of facilitiesKeyValue">
<div class="facilities-header flexflex">
<div class="item-title">{{ item }}</div>
</div>
<div class="facilities-list flexflex flex1">
<div class="item flexcenter" v-for="it in info['facilities'][key]">
<img class="icon" src="@/assets/img/apartmentDetail/blue-tick.svg" />
{{ it }}
</div>
</div>
</div>
</div>
</div>
<!-- 生活 -->
<div class="details-item life" v-if="info['life']" ref="lifeEle">
<div class="details-header flexacenter">
<img class="icon" src="@/assets/img/apartmentDetail/live.png">
生活
</div>
<div class="text" v-html="info['life']"></div>
</div>
<!-- 品牌介绍 -->
<div class="details-item company" v-if="company" ref="companyEle">
<div class="details-header flexacenter">
<img class="icon" src="@/assets/img/apartmentDetail/live.png">
品牌介绍
</div>
<img class="company-img flexflex" :src="company['imageurl']">
<div class="text" v-html="company['introduction']"></div>
</div>
<div class="details-item hint-box">
<div class="hint-item">
温馨提示房源信息均由公寓方/酒店提供并对其真实性合法性等负责平台不负责甄别和审核具体内容真实性和有效性等请务必仔细核实相关信息谨防上当受骗
</div>
<div class="hint-item"></div>
<div class="hint-item flexacenter">
公寓/酒店/中介房源推广合作请联系<a @click="copy('ad@gter.net')">ad@gter.net</a>
</div>
</div>
</div>
<div class="details-right flexacenter">
<div class="QRcode-box apartment-QRcode flexflex" v-if="true">
<img class="mini-program-title" src="@/assets/img/apartmentDetail/mini-program-title.png">
<div class="QRcode-case flexcenter">
<img class="QRcode-img" :src="qrcode" alt="">
</div>
<div class="apartment-QRcode-hint flexacenter">
<img class="scan-icon" src="@/assets/img/apartmentDetail/scan-icon.png">
手机查看该公寓
</div>
</div>
<div class="QRcode-box group-QRcode flexflex" v-if="true">
<img class="group-title" src="@/assets/img/apartmentDetail/group-title.png">
<div class="QRcode-case flexcenter">
<img class="QRcode-img" :src="wechat['wechatqrcode']" alt="">
</div>
<div class="group-QRcode-hint flexacenter">
<img class="scan-icon" src="@/assets/img/apartmentDetail/scan-icon.png">
入群请添加
<!-- <b>方同学的小助手</b> -->
<b>{{ wechat['nickname'] }}</b>
</div>
</div>
<!-- 同品牌公寓 -->
<div class="same-brand-title flexcenter" v-if="dualBrandList.length != 0" ref="eleseEle">
<img class="same-brand-icon" src="@/assets/img/apartmentDetail/same-brand.png">
同品牌其他公寓
</div>
<div class="same-brand-list" v-if="dualBrandList.length != 0">
<div class="same-brand-item" v-for="item in dualBrandList">
<div class="same-brand-header">
<img class="same-brand-img"
src="https://axure-file.lanhuapp.com/md5__27da7a1a511d30b97b139f58626415e5.svg" />
<div class="apartment-name">{{ item['title'] }}</div>
<div class="apartment-synopsis">{{ item['propaganda'] }}</div>
</div>
<div class="site flexacenter">
<img class="site-icon" src="@/assets/img/publicImage/location-icon.png">
{{ item['address'] }}
</div>
<div class="price-box">
<div class="price-item flexacenter" v-for="it in item['roomlist']">
<div class="room-name">{{ it['name'] }}</div>
<div class="flexacenter">
<div class="unit">HK$</div>
<div class="quantity">{{ it['price'] }}</div>/
</div>
</div>
</div>
<div class="same-brand-quantity flexcenter">
<div class="quantity">{{ item['roomnum'] }}</div>个房型
<img class="same-brand-quantity-icon" src="@/assets/img/publicImage/black-arrow.svg" />
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 添加客服 - 弹窗 -->
<div class="add-customer-mask flexcenter" v-if="contactReservationState">
<div class="add-customer-box flexcenter" :class="{ 'two': customerservicelist.length != 1 }">
<img class="close" @click="modificationContact" src="@/assets/img/publicImage/circle-close.png">
<img class="add-customer-violet" src="@/assets/img/apartmentDetail/add-customer-violet.svg">
<img class="add-customer-violet violet2" src="@/assets/img/apartmentDetail/add-customer-violet2.svg">
<div class="add-customer-interior flexflex">
<img class="add-customer-interior-bj bj2" src="@/assets/img/apartmentDetail/add-customer-map2.svg">
<img class="add-customer-interior-bj bj2"
src="@/assets/img/apartmentDetail/add-customer-interior-bj2.svg" />
<img class="add-customer-interior-bj" src="@/assets/img/apartmentDetail/add-customer-map.svg">
<img class="add-customer-interior-bj" src="@/assets/img/apartmentDetail/add-customer-interior-bj.svg" />
<img class="title" src="@/assets/img/apartmentDetail/add-customer-title.png">
<div class="QR-code-list flexflex">
<div class="QR-code-item" v-for="item in customerservicelist">
<div class="QR-code-box flexcenter">
<div class="top-right-corner"></div>
<div class="bottom-left-corner"></div>
<div class="bottom-right-corner"></div>
<div class="QR-code-chunk flexcenter">
<img class="QR-code-img" :src="item['image']">
</div>
</div>
<div class="name flexcenter">{{ item['title'] }}</div>
<div class="hint flexcenter">微信扫码添加备注寄托</div>
</div>
</div>
</div>
</div>
</div>
<footerpage></footerpage>
</template>
<script setup>
import { ref, onMounted, toRefs, watch, getCurrentInstance, nextTick } from 'vue';
import { ElMessage, valueEquals } from 'element-plus'
import { useStore } from 'vuex';
import pageTopBar from '../components/pageTopBar/pageTopBar.vue';
import footerpage from '@/components/footer/footer.vue'
import viewMap from '@/components/public/viewMap.vue'
import transmitBtn from '@/components/public/transmitBtn.vue'
import imageWatch from '@/components/detail/imageWatch.vue';
import { useRouter } from 'vue-router'
let router = useRouter()
let { uniqid } = router.currentRoute.value.query
import { copyToClipboard } from '@/utils/util.js'
// const uniqid = "aWqSz58aKKvn"
const { proxy } = getCurrentInstance()
const store = useStore();
const { wechat } = toRefs(store.state);
let imageShow = ref(false) // 查看大图弹窗的状态
let imageList = ref([]) // 查看大图弹窗的状态
const cloaseImageShow = (list) => {
if (list) imageList.value = list
imageShow.value = !imageShow.value
}
// allCarouselsData
// 房间类型
let roomList = ref([])
let info = ref({})
let facilitiesKeyValue = { // 设施的键值对
public: "公共",
kitchen: "餐厨",
lavatory: "洗手间",
}
let withsameapartments = ref(0) // 其他公寓数量
let attachment = ref([]) // 轮播图数据
let company = {} // 品牌数据
let token = ""
let qrcode = ref("") // 小程序详情二维码
let allCarouselsData = ref([])
proxy.$get("/tenement/pc/api/apartment/details", { uniqid }).then(res => {
if (res.code != 200) return
let data = res.data
roomList.value = data['roomList']
data['info']['coordinate'] = data['info']['coordinate'].split(',').map(item => {
return +item
})
info.value = data['info']
attachment.value = data['info']['attachment']
withsameapartments.value = data['withsameapartments']
company = data['company']
token = data['token']
qrcode.value = data['qrcode']
handleAllCarouselsData()
nextTick(() => handleNavData())
if (data.withsameapartments > 0) dualBrandData()
})
let carouselsconfig = ref({ lives: {}, videos: {}, attachment: {} })
// 处理 轮播图大图的索引 tab
const handleAllCarouselsData = () => {
let targetInfo = { ...info.value }
let accumulativeTotal = 0 // 累计
for (const key in carouselsconfig.value) {
carouselsconfig.value[key] = {
amount: targetInfo[key].length,
index: accumulativeTotal
}
accumulativeTotal += targetInfo[key].length
}
targetInfo['lives'].forEach(element => {
element['type'] = 'lives'
allCarouselsData.value.push(element)
})
targetInfo['videos'].forEach(element => {
element['type'] = 'videos'
allCarouselsData.value.push(element)
})
let thumbnailList = targetInfo['thumbnailList']
targetInfo['attachment'].forEach((element, index) => {
element = {
imageurl: element,
thumbnail: thumbnailList[index]
}
element['type'] = 'attachment'
allCarouselsData.value.push(element)
})
}
const roomEle = ref(null)
const specialEle = ref(null)
const addressEle = ref(null)
const messageEle = ref(null)
const facilitiesEle = ref(null)
const lifeEle = ref(null)
const companyEle = ref(null)
const eleseEle = ref(null)
let navconfig = [{
name: "房间类型",
value: "roomEle"
}, {
name: "优惠活动",
value: "specialEle"
}, {
name: "位置与交通",
value: "addressEle"
}, {
name: "房源详情",
value: "messageEle"
}, {
name: "公寓设施",
value: "facilitiesEle"
}, {
name: "生活",
value: "lifeEle"
}, {
name: "品牌介绍",
value: "companyEle"
}]
let navList = ref([])
let navTab = ref("roomEle")
// 处理 navList 数据
const handleNavData = () => {
navconfig.forEach(element => {
if (eval(element['value']).value) navList.value.push(element)
})
}
// 处理点击nav 滚动事件
const handleClickNav = value => {
let scrollTop = eval(value).value.offsetTop + 136
if (value != 'eleseEle') navTab.value = value
window.scrollTo({ top: scrollTop, behavior: 'smooth' });
}
let dualBrandList = ref([]) // 同品牌数据
// 同品牌请求数据
const dualBrandData = () => {
proxy.$get("/tenement/pc/api/apartment", { token }).then(res => {
if (res.code != 200) return
let data = res.data
dualBrandList.value = data.data
})
}
// 点击转发的复制链接按钮
const copy = (value) => copyToClipboard(value).then(() => ElMessage.success("复制成功!!!"))
let contactReservationState = ref(false) // 联系预订客服的弹窗状态
let customerservicelist = ref([]) // 联系预订客服的弹窗状态
// 修改 客服 弹窗状态
const modificationContact = () => {
if (customerservicelist.value.length == 0) contactReservationService()
else contactReservationState.value = !contactReservationState.value
}
// 联系预订客服 请求数据
const contactReservationService = () => {
proxy.$get("/tenement/pc/api/apartment/customerservice", {
customerservice: info.value['customerservice'],
token
}).then(res => {
if (res.code != 200) return
let data = res.data
customerservicelist.value = data['customerservicelist']
contactReservationState.value = !contactReservationState.value
})
}
let mediaBtnstate = ref({}) // 0 左边为不能点击 1 右边不能点击 2 是两个都能点击
const handleMediaBtn = (type, index) => {
const element = document.querySelector(`.element${index}`);
if (element) {
let left
if (type == 'left') left = element.scrollLeft - 86
else left = element.scrollLeft + 86
const scrollOptions = {
left,
behavior: 'smooth'
};
element.scrollTo(scrollOptions);
nextTick(() => {
setTimeout(() => {
if (element.scrollLeft == 0) mediaBtnstate.value[index] = 0
else if (element.scrollLeft + 460 == element.scrollWidth) mediaBtnstate.value[index] = 1
else mediaBtnstate.value[index] = 2
}, 150);
})
}
}
let slideshowList = ref(null) // 轮播图小图的节点
let carouselIndex = ref(0) // 轮播图的索引
const remarkCaruselUp = ref(null)
const carouselChange = value => {
carouselIndex.value = value
const element = slideshowList.value
const elementchild = element.querySelector(`.item${value}`);
let left = elementchild.offsetLeft - element.offsetLeft
const scrollOptions = {
left,
behavior: 'smooth'
};
element.scrollTo(scrollOptions);
}
// 顶部轮播图的左右按钮
const handleslideshow = (type) => {
if (type == 'left' && carouselIndex.value != 0) remarkCaruselUp.value.prev()
if (type != 'left' && carouselIndex.value != allCarouselsData.value.length - 1) remarkCaruselUp.value.next()
}
// 直接点击轮播图的小图就行切换
const slideshowItem = index => remarkCaruselUp.value.setActiveItem(index)
// 直接点击大图的 类型
const slideshowType = type => slideshowItem(carouselsconfig.value[type].index)
let detailsLeft = ref(null)
</script>
<style lang="less" scoped>
.content {
margin: -36px auto 0;
position: relative;
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
.header {
margin-bottom: 20px;
.top {
width: 1200px;
height: 65px;
background: -webkit-linear-gradient(356.899508550192deg, rgba(253, 218, 85, 1) 0%, rgba(229, 215, 190, 1) 50%, rgba(203, 254, 191, 1) 100%);
background: -moz-linear-gradient(93.1004914498078deg, rgba(253, 218, 85, 1) 0%, rgba(229, 215, 190, 1) 50%, rgba(203, 254, 191, 1) 100%);
background: linear-gradient(93.1004914498078deg, rgba(253, 218, 85, 1) 0%, rgba(229, 215, 190, 1) 50%, rgba(203, 254, 191, 1) 100%);
border-radius: 16px 16px 0 0;
padding: 0 30px;
.brand-name {
height: 22px;
background-color: rgba(128, 108, 36, 1);
border-radius: 8px;
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
color: #FDDA55;
padding: 0 11px;
margin-top: 12px;
margin-right: 10px;
font-size: 14px;
}
.brand-abstract {
color: #806C24;
font-size: 14px;
padding-top: 13px;
}
}
.header-content {
background-color: #fff;
padding: 25px 30px;
margin-top: -20px;
border-radius: 16px 0 16px 16px;
position: relative;
.arc {
position: absolute;
width: 12px;
height: 12px;
top: -12px;
right: 0;
}
.header-left {
width: 511px;
.slideshow {
position: relative;
margin-bottom: 8px;
/deep/ .el-carousel {
.el-carousel__container {
width: 511px;
height: 340px;
}
.el-carousel__item {
width: 511px;
height: 340px;
display: flex;
align-items: center;
border-radius: 5px;
.img {
width: 100%;
object-fit: cover;
height: 340px;
display: block;
cursor: pointer;
}
.video-icon {}
}
}
.indicate-type {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
height: 24px;
background-color: rgba(255, 255, 255, 1);
border-radius: 36px;
font-size: 16px;
color: #FFFFFF;
.indicate-item {
height: 100%;
padding: 0 11px;
font-size: 14px;
color: #555555;
line-height: 24px;
cursor: pointer;
&.pitch {
border-radius: 36px;
color: #FFFFFF;
background-color: rgba(249, 93, 93, 1);
}
}
}
.indicate {
font-size: 13px;
color: #FFFFFF;
height: 20px;
line-height: 20px;
background-color: rgba(0, 0, 0, 0.494117647058824);
border-radius: 36px;
padding: 0 7px;
position: absolute;
bottom: 10px;
right: 10px;
}
}
.slideshow-across {
width: 511px;
height: 70px;
background-color: rgba(246, 246, 246, 1);
border: 1px solid rgba(235, 235, 235, 1);
border-radius: 4px;
.slideshow-btn {
width: 32px;
height: 100%;
cursor: pointer;
user-select: none;
&.left {
// transform: rotate(180deg);
}
}
.box {
width: 360px;
overflow: auto;
.item {
height: 60px;
margin-right: 6px;
position: relative;
cursor: pointer;
&::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.501960784313725);
}
&.pitch {
&::after {
height: 0;
}
}
.video-icon {
width: 44px;
height: 44px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
// overflow: hidden;
.img {
height: 100%;
border-radius: 6px;
}
}
}
.arrow {
width: 10px;
height: 17px;
}
}
}
.header-right {
margin-left: 59px;
.tab-box {
flex-wrap: wrap;
margin-bottom: 9px;
.tab-item {
height: 24px;
background: -webkit-linear-gradient(145.829772035587deg, rgba(224, 240, 255, 1) 0%, rgba(98, 177, 255, 1) 297%);
background: -moz-linear-gradient(-55.8297720355872deg, rgba(224, 240, 255, 1) 0%, rgba(98, 177, 255, 1) 297%);
background: linear-gradient(-55.8297720355872deg, rgba(224, 240, 255, 1) 0%, rgba(98, 177, 255, 1) 297%);
border-radius: 8px;
font-size: 14px;
color: #447EB3;
line-height: 26px;
padding: 0 7px;
margin-bottom: 12px;
margin-right: 10px;
}
}
.apartment-name {
font-size: 28px;
color: #000000;
line-height: 46px;
margin-bottom: 20px;
}
.synopsis {
font-size: 14px;
color: #7F7F7F;
line-height: 24px;
margin-bottom: 20px;
}
.place,
.else {
height: 63px;
justify-content: space-between;
border-top: 1px solid #ebebeb;
.left {
color: #333333;
font-size: 14px;
.icon {
width: 18px;
height: 18px;
margin-right: 10px;
}
}
.right {
font-size: 14px;
color: #7F7F7F;
line-height: 24px;
cursor: pointer;
.icon {
width: 6px;
height: 10px;
margin-left: 10px;
}
.quantity {
width: 18px;
height: 18px;
border-radius: 50%;
font-size: 13px;
color: #333333;
background-color: #fdda55;
}
}
}
}
}
}
.operate-box {
width: 1200px;
height: 70px;
background-color: rgba(255, 255, 255, 1);
border: 1px solid rgba(235, 235, 235, 1);
border-radius: 16px;
-moz-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.117647058823529);
-webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.117647058823529);
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.117647058823529);
font-size: 14px;
padding: 0 30px;
margin-bottom: 20px;
justify-content: space-between;
position: sticky;
top: 0px;
z-index: 1002;
.nav-box {
.nav-item {
height: 40px;
background-color: rgba(246, 246, 246, 1);
border-radius: 8px;
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-size: 14px;
color: #7F7F7F;
padding: 0 17px;
cursor: pointer;
&.pitch {
background-color: #000;
font-weight: 650;
color: #fff;
}
&:not(:last-of-type) {
margin-right: 10px;
}
}
}
.btn-box {
.btn-item {
width: 100px;
height: 40px;
border-radius: 50px;
cursor: pointer;
&.transmit-btn {
border: 1px solid rgba(235, 235, 235, 1);
color: #333333;
margin-right: 10px;
position: relative;
.transmit-icon {
width: 20px;
height: 20px;
margin-right: 4px;
}
}
&.consult-btn {
background: -webkit-linear-gradient(324.854454500294deg, rgba(98, 177, 255, 1) -11%, rgba(128, 255, 255, 1) 135%);
background: -moz-linear-gradient(125.145545499706deg, rgba(98, 177, 255, 1) -11%, rgba(128, 255, 255, 1) 135%);
background: linear-gradient(125.145545499706deg, rgba(98, 177, 255, 1) -11%, rgba(128, 255, 255, 1) 135%);
font-size: 16px;
color: #FFFFFF;
}
}
}
}
.details-box {
justify-content: space-between;
align-items: flex-start;
.details-left {
.type-box {
.type-item {
width: 876px;
background-color: rgba(255, 255, 255, 1);
border: 1px solid rgba(235, 235, 235, 1);
border-radius: 16px;
-moz-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.117647058823529);
-webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.117647058823529);
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.117647058823529);
font-size: 14px;
padding: 30px;
margin-bottom: 20px;
position: relative;
.type-icon {
position: absolute;
top: 0;
left: 0;
width: 40px;
height: 40px;
transform: rotate(270deg);
}
.type-left {
.type-name {
font-weight: 650;
font-size: 20px;
color: #000000;
margin-bottom: 16px;
}
.type-tags {
margin-bottom: 20px;
.tags-item {
height: 24px;
background-color: rgba(242, 242, 242, 1);
border-radius: 4px;
line-height: 26px;
font-size: 14px;
color: #7F7F7F;
margin-right: 8px;
padding: 0 9px;
&.first {
border: 1px solid rgba(80, 227, 194, 1);
color: #50e3c2;
background-color: #fff;
}
}
}
.media-box {
.media-list {
max-width: 460px;
overflow: auto;
}
.media-item {
position: relative;
margin-right: 10px;
.media-img {
width: 76px;
height: 80px;
border-radius: 10px;
cursor: pointer;
object-fit: cover;
}
.media-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 53px;
height: 53px;
}
}
.media-btn {
height: 80px;
width: 30px;
cursor: pointer;
user-select: none;
.arrow {
width: 10px;
height: 17px;
}
}
}
}
.type-right {
.price-box {
flex-direction: column;
align-items: flex-end;
margin-right: 20px;
.former {
color: #AAAAAA;
font-size: 14px;
text-decoration: line-through;
text-decoration-color: #797979;
margin-bottom: 3px;
}
.new {
.unit {
font-family: 'Arial-Black', 'Arial Black', sans-serif;
font-weight: 900;
color: #000000;
font-size: 16px;
}
.cost {
font-family: 'Arial-Black', 'Arial Black', sans-serif;
font-weight: 900;
font-size: 24px;
color: #F95D5D;
margin: 0 6px;
}
align-items: baseline;
font-size: 14px;
color: #555555;
}
}
.consult-btn {
width: 90px;
height: 40px;
background: -webkit-linear-gradient(321.966692522331deg, rgba(98, 177, 255, 1) -13%, rgba(128, 255, 255, 1) 137%);
background: -moz-linear-gradient(128.033307477669deg, rgba(98, 177, 255, 1) -13%, rgba(128, 255, 255, 1) 137%);
background: linear-gradient(128.033307477669deg, rgba(98, 177, 255, 1) -13%, rgba(128, 255, 255, 1) 137%);
border-radius: 36px;
font-weight: 400;
font-size: 16px;
color: #FFFFFF;
cursor: pointer;
}
.full-occupancy {
width: 90px;
height: 40px;
background-color: rgba(237, 246, 255, 0);
border: 1px solid rgba(215, 215, 215, 1);
border-radius: 36px;
font-weight: 400;
font-size: 16px;
color: #AAAAAA;
}
}
}
}
.item-title {
padding: 0 11px;
height: 26px;
background-color: rgba(51, 51, 51, 1);
border-radius: 8px;
font-size: 14px;
color: #FFFFFF;
line-height: 26px;
display: inline-block;
}
.details-item {
width: 876px;
background-color: rgba(255, 255, 255, 1);
border: 1px solid rgba(235, 235, 235, 1);
border-radius: 16px;
-moz-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.117647058823529);
-webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.117647058823529);
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.117647058823529);
font-size: 14px;
margin-bottom: 20px;
.details-header {
height: 82px;
padding: 0 30px;
border-bottom: 1px solid #ebebeb;
font-size: 16px;
color: #000000;
.icon {
width: 20px;
height: 22px;
margin-right: 4px;
}
}
.text {
font-weight: 400;
font-size: 16px;
color: #555555;
line-height: 30px;
padding: 20px 30px;
white-space: pre-line;
}
.traffic-box {
padding: 0 30px;
.traffic-title {
margin-bottom: 16px;
}
font-weight: 400;
font-size: 16px;
color: #555555;
line-height: 30px;
white-space: pre-line;
padding-bottom: 30px;
}
&.apartment-facilities {
.facilities-box {
padding: 30px;
.facilities-item {
align-items: flex-start;
&:not(:last-of-type) {
margin-bottom: 30px;
}
.facilities-header {
width: 100px;
}
.facilities-list {
flex-wrap: wrap;
.item {
font-size: 16px;
line-height: 26px;
color: #333333;
margin-bottom: 10px;
margin-right: 50px;
.icon {
width: 16px;
height: 16px;
margin-right: 10px;
}
}
}
}
}
}
&.company {
.company-img {
width: 420px;
height: 254px;
margin: 10px auto 0;
}
}
&.hint-box {
color: #7F7F7F;
line-height: 24px;
font-size: 13px;
padding: 30px;
margin-bottom: 100px;
.hint-item {
min-height: 24px;
a {
cursor: pointer;
color: #7F7F7F;
text-decoration: underline;
}
}
}
}
}
.details-right {
width: 304px;
flex-direction: column;
.QRcode-box {
width: 304px;
height: 304px;
background-color: rgba(255, 255, 255, 1);
border: 1px solid rgba(235, 235, 235, 1);
border-radius: 16px;
-moz-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.117647058823529);
-webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.117647058823529);
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.117647058823529);
flex-direction: column;
align-items: center;
margin-bottom: 20px;
.scan-icon {
width: 14px;
height: 14px;
margin-right: 7px;
}
&.apartment-QRcode {
padding: 40px 0;
.mini-program-title {
width: 201px;
height: 24px;
margin-bottom: 28px;
}
.QRcode-case {
width: 120px;
height: 120px;
background-color: rgba(255, 255, 255, 1);
border-radius: 70px;
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.12156862745098);
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.12156862745098);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.12156862745098);
margin-bottom: 33px;
.QRcode-img {
width: 103px;
height: 103px;
border-radius: 70px;
}
}
.apartment-QRcode-hint {
font-size: 14px;
color: #000000;
}
}
&.group-QRcode {
padding: 40px 0;
.group-title {
width: 140px;
height: 26px;
margin-bottom: 26px;
}
.QRcode-case {
width: 120px;
height: 120px;
background-color: rgba(255, 255, 255, 1);
border-radius: 15px;
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.12156862745098);
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.12156862745098);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.12156862745098);
margin-bottom: 28px;
.QRcode-img {
width: 100px;
height: 100px;
}
}
.group-QRcode-hint {
color: #555555;
font-size: 14px;
b {
font-size: 14px;
color: #000;
font-weight: 650;
margin-left: 5px;
}
}
}
}
.same-brand-title {
margin-bottom: 20px;
font-size: 18px;
color: #000000;
background: -webkit-linear-gradient(350.348166533196deg, rgba(253, 218, 85, 1) 0%, rgba(229, 215, 190, 1) 50%, rgba(203, 254, 191, 1) 100%);
background: -moz-linear-gradient(99.6518334668042deg, rgba(253, 218, 85, 1) 0%, rgba(229, 215, 190, 1) 50%, rgba(203, 254, 191, 1) 100%);
background: linear-gradient(99.6518334668042deg, rgba(253, 218, 85, 1) 0%, rgba(229, 215, 190, 1) 50%, rgba(203, 254, 191, 1) 100%);
border-radius: 12px;
width: 304px;
height: 60px;
border: 5px solid #fff;
position: relative;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.11764706);
&::after {
content: "";
position: absolute;
width: 10px;
height: 10px;
background-color: #fff;
transform: rotate(45deg) translateX(-50%);
left: 50%;
bottom: -14px;
z-index: -1;
}
.same-brand-icon {
width: 24px;
height: 24px;
margin-right: 4px;
}
}
.same-brand-list {
.same-brand-item {
width: 304px;
background-color: rgba(255, 255, 255, 1);
border-radius: 17px;
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.156862745098039);
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.156862745098039);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.156862745098039);
padding: 8px 0;
margin-bottom: 20px;
.same-brand-header {
width: 288px;
height: 192px;
overflow: hidden;
border-radius: 17px;
margin: 0 auto 20px;
position: relative;
.same-brand-img {
width: 288px;
height: 192px;
}
.apartment-name {
font-weight: 650;
font-style: normal;
font-size: 16px;
color: #000000;
padding: 0 15px;
height: 32px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(255, 255, 255, 0.7);
padding: 0 15px;
border-radius: 40px;
width: max-content;
line-height: 30px;
}
.apartment-synopsis {
width: 100%;
height: 32px;
line-height: 32px;
background-color: rgba(0, 0, 0, 0.63921568627451);
border-radius: 0 0 10px 10px;
position: absolute;
bottom: 0;
font-size: 13px;
color: #D7D7D7;
padding: 0 10px;
}
}
.site {
margin: 0 20px 20px;
color: #555555;
font-size: 14px;
.site-icon {
width: 18px;
height: 18px;
margin-right: 4px;
}
}
.price-box {
font-size: 14px;
color: #555555;
margin: 0 20px 31px;
.price-item {
justify-content: space-between;
height: 50px;
&:not(:last-of-type) {
border-bottom: 1px solid #ebebeb;
}
}
.room-name {
font-size: 15px;
color: #000000;
}
.unit {
font-family: 'Arial-Black', 'Arial Black', sans-serif;
font-weight: 900;
color: #000000;
font-size: 13px;
}
.quantity {
font-family: 'Arial-Black', 'Arial Black', sans-serif;
font-weight: 900;
font-size: 18px;
color: #F95D5D;
margin: 0 5px;
}
}
.same-brand-quantity {
font-size: 14px;
color: #555555;
margin: 21px auto;
.quantity {
font-weight: 650;
font-size: 14px;
color: #000000;
height: 18px;
background-color: #fddf6d;
border-radius: 9px;
padding: 0 8px;
margin: 0 8px;
}
.same-brand-quantity-icon {
width: 7px;
height: 12px;
margin-left: 8px;
}
}
}
}
}
}
}
.add-customer-mask {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
// background-color: rgba(0, 0, 0, 0.7);
z-index: 1002;
.add-customer-box {
width: 460px;
height: 460px;
background: -webkit-linear-gradient(315deg, rgba(253, 218, 85, 1) 0%, rgba(229, 215, 190, 1) 50%, rgba(203, 254, 191, 1) 100%);
background: -moz-linear-gradient(135deg, rgba(253, 218, 85, 1) 0%, rgba(229, 215, 190, 1) 50%, rgba(203, 254, 191, 1) 100%);
background: linear-gradient(135deg, rgba(253, 218, 85, 1) 0%, rgba(229, 215, 190, 1) 50%, rgba(203, 254, 191, 1) 100%);
border: 1px solid rgba(230, 221, 185, 1);
-moz-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.235294117647059);
-webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.235294117647059);
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.235294117647059);
position: relative;
&.two {
width: 799px;
height: 460px;
.add-customer-violet {
display: none;
&.violet2 {
display: block;
}
}
.add-customer-interior {
width: 700px;
.title {
width: 189px;
height: 31px;
}
.add-customer-interior-bj {
display: none;
&.bj2 {
display: block;
}
}
}
}
.close {
position: absolute;
top: 16px;
right: 16px;
width: 16px;
height: 16px;
cursor: pointer;
}
.add-customer-violet {
position: absolute;
bottom: 0;
left: 0;
top: 0;
right: 0;
width: 421px;
height: 460px;
&.violet2 {
width: 579px;
height: 460px;
display: none;
}
}
.add-customer-interior {
width: 368px;
height: 368px;
position: relative;
z-index: 1;
flex-direction: column;
align-items: center;
padding-top: 35px;
.add-customer-interior-bj {
position: absolute;
top: 0;
left: 0;
z-index: -1;
&.bj2 {
display: none;
}
}
.title {
width: 159px;
height: 26px;
margin-bottom: 35px;
}
.QR-code-list {
.QR-code-item {
&:not(:last-child) {
margin-right: 160px;
}
}
}
.QR-code-box {
margin-bottom: 17px;
padding: 15px;
position: relative;
&::after {
width: 15px;
height: 5px;
}
&::before {
width: 5px;
height: 15px;
}
&::before,
&::after {
content: "";
background-color: rgba(255, 214, 73, 1);
border-radius: 11px;
position: absolute;
top: 0;
left: 0;
}
.top-right-corner {
&::after {
width: 15px;
height: 5px;
}
&::before {
width: 5px;
height: 15px;
}
&::before,
&::after {
content: "";
background-color: rgba(255, 214, 73, 1);
border-radius: 11px;
position: absolute;
top: 0;
right: 0;
}
}
.bottom-left-corner {
&::after {
width: 15px;
height: 5px;
}
&::before {
width: 5px;
height: 15px;
}
&::before,
&::after {
content: "";
background-color: rgba(255, 214, 73, 1);
border-radius: 11px;
position: absolute;
bottom: 0;
left: 0;
}
}
.bottom-right-corner {
&::after {
width: 15px;
height: 5px;
}
&::before {
width: 5px;
height: 15px;
}
&::before,
&::after {
content: "";
background-color: rgba(255, 214, 73, 1);
border-radius: 11px;
position: absolute;
bottom: 0;
right: 0;
}
}
.QR-code-chunk {
width: 130px;
height: 130px;
background-color: rgba(255, 255, 255, 1);
border-radius: 15px;
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.12156862745098);
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.12156862745098);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.12156862745098);
.QR-code-img {
width: 110px;
height: 110px;
}
}
}
.name {
margin-bottom: 6px;
}
.name,
.hint {
color: #555555;
font-size: 14px;
}
}
}
}
</style>