上传公寓收藏和公寓附近房源

This commit is contained in:
A1300399510
2024-04-17 18:40:28 +08:00
parent 5a4e6e79cd
commit a1ec98685e
31 changed files with 526 additions and 309 deletions

View File

@@ -90,6 +90,11 @@
<div class="nav-item flexcenter" :class="{ pitch: navTab == item.value }" :aria-label="`${item['name']}-按钮`" v-for="(item, index) in navList" :key="index" @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="handleCollect">
<img v-if="info.iscollect == 1" alt="收藏图标" class="transmit-icon" src="@/assets/img/detail/collectT.png" />
<img v-else alt="收藏图标" class="transmit-icon" src="@/assets/img/detail/collect.png" />
收藏
</div>
<div class="btn-item transmit-btn flexcenter" @click="handleTransmit">
<img alt="转发图标" class="transmit-icon" src="@/assets/img/publicImage/transmit-icon.png" />
转发
@@ -177,7 +182,7 @@
<div class="mileage">{{ specialSchoolDistance.distanceText }}</div>
<img v-if="specialSchoolDistance.toolText == '步行'" class="tool-icon" src="@/assets/img/detail/walk-icon.png" />
<img v-else class="tool-icon" src="@/assets/img/detail/subway-icon.png" />
<div class="tool-time">{{ specialSchoolDistance?.durationText2 }}</div>
<div class="tool-time">{{ specialSchoolDistance?.durationText }}</div>
</div>
<div class="flexcenter">
<img src="@/assets/img/detail/markIcon.svg" class="marker-icon" alt="" />
@@ -335,7 +340,7 @@
</div>
<div class="details-right flexacenter">
<phoneqrcode type="apartment" :qrcode="qrcode"></phoneqrcode>
<groupqrcode></groupqrcode>
<groupqrcode type="apartment"></groupqrcode>
<!-- 同品牌公寓 -->
<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" />
@@ -459,7 +464,7 @@ watch(route, () => {
})
let { uniqid } = router.currentRoute.value.query
let pitchSchool = router.currentRoute.value.school || 0
let pitchSchool = route.query.school || 0
import { copyToClipboard, metersToKilometers, secondsToHoursMinutes } from "@/utils/util.js"
@@ -829,8 +834,6 @@ const distanceSchool = () => {
targetAcademyPitch.value = data[academyPitchIndexTarget]
specialSchoolDistance.value = specialSchoolDistanceTarget
academyPitchIndex.value = academyPitchIndexTarget
console.log("annexSchoolOmit", annexSchoolOmit)
})
}
@@ -862,6 +865,17 @@ const selectIndex = id => {
//显示详情
let showDistance = ref(false)
// 点击收藏
const handleCollect = () => {
api.apartmentCollection({ token }).then(res => {
if (res.code != 200) return
const data = res.data
info.value.iscollect = data.status || 0
ElMessage.success(res.message)
})
}
</script>
<style lang="less" scoped>
@@ -947,7 +961,7 @@ let showDistance = ref(false)
margin-top: -20px;
border-radius: 16px 0 16px 16px;
position: relative;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.118);
// box-shadow: 0 0 10px rgba(0, 0, 0, 0.118);
// .arc {
// position: absolute;
// width: 12px;
@@ -1321,8 +1335,11 @@ let showDistance = ref(false)
font-size: 14px;
padding: 30px;
// margin-bottom: 20px;
border-bottom: 1px solid #ebebeb;
position: relative;
&:not(:last-of-type) {
border-bottom: 1px solid #ebebeb;
}
.type-icon {
position: absolute;
top: 0;
@@ -1497,9 +1514,9 @@ let showDistance = ref(false)
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);
// -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;
@@ -1641,7 +1658,7 @@ let showDistance = ref(false)
height: 60px;
border: 5px solid #fff;
position: relative;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.11764706);
// box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.11764706);
&::after {
content: "";
@@ -1667,9 +1684,9 @@ let showDistance = ref(false)
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);
// -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;
cursor: pointer;

View File

@@ -6,58 +6,54 @@
<breadcrumb :data="housingInfo['data']" :operation="setOperation"></breadcrumb>
<div class="dis-f jus-bet" style="margin-top: -15px;">
<div class="info-box">
<div style="position: absolute; top: 0; left: 0;">
<el-affix :offset="0" @change="changeTitleType" z-index="1002" style="width: 1200px;">
<div class="top-bar-box dis-f jus-x" v-if="titleType">
<div class="top-bar dis-f al-item jus-bet">
<div class="dis-f al-item">
<img src="../assets/img/detail/authenticationHousing.png" class="authentication-housing" v-if="pageType == 1 && housingInfo['data'] && housingInfo['data'].info.verified" alt="" />
<img src="../assets/homeImage/intermediaryTabImg.png" class="intermediary-logo" style="margin-right: 10px;" v-if="pageType == 2 && housingInfo['data'] && housingInfo['data'].isintermediary == 1" alt="" />
<div class="line" v-if="(housingInfo['data'] && housingInfo['data'].info.verified) || (pageType == 2 && housingInfo['data'] && housingInfo['data'].isintermediary == 1)"></div>
<span class="need-houing-type" v-if="pageType == 3">预算</span>
<span class="unit">HK$</span>
<span class="rent" v-if="!Array.isArray(housingInfo['data'] && housingInfo['data'].info.rent)">{{ housingInfo["data"] && housingInfo["data"].info.rent }}</span>
<span class="rent" v-if="Array.isArray(housingInfo['data'] && housingInfo['data'].info.rent)">
{{ housingInfo["data"] && housingInfo["data"].info.rent[0] }}<span class="rent" v-if="housingInfo['data'] && housingInfo['data'].info.rent[1]" style="margin: 0;">~</span><span class="rent" style="margin: 0;" v-if="housingInfo['data'] && housingInfo['data'].info.rent[1]">{{ housingInfo["data"] && housingInfo["data"].info.rent[1] }}</span>
<div class="top-bar-box dis-f jus-x">
<div class="top-bar dis-f al-item jus-bet">
<div class="dis-f al-item">
<img src="../assets/img/detail/authenticationHousing.png" class="authentication-housing" v-if="pageType == 1 && housingInfo['data'] && housingInfo['data'].info.verified" alt="" />
<img src="../assets/homeImage/intermediaryTabImg.png" class="intermediary-logo" style="margin-right: 10px;" v-if="pageType == 2 && housingInfo['data'] && housingInfo['data'].isintermediary == 1" alt="" />
<div class="line" v-if="(housingInfo['data'] && housingInfo['data'].info.verified) || (pageType == 2 && housingInfo['data'] && housingInfo['data'].isintermediary == 1)"></div>
<span class="need-houing-type" v-if="pageType == 3">预算</span>
<span class="unit">HK$</span>
<span class="rent" v-if="!Array.isArray(housingInfo['data'] && housingInfo['data'].info.rent)">{{ housingInfo["data"] && housingInfo["data"].info.rent }}</span>
<span class="rent" v-if="Array.isArray(housingInfo['data'] && housingInfo['data'].info.rent)">
{{ housingInfo["data"] && housingInfo["data"].info.rent[0] }}<span class="rent" v-if="housingInfo['data'] && housingInfo['data'].info.rent[1]" style="margin: 0;">~</span><span class="rent" style="margin: 0;" v-if="housingInfo['data'] && housingInfo['data'].info.rent[1]">{{ housingInfo["data"] && housingInfo["data"].info.rent[1] }}</span>
</span>
<span>/{{ housingInfo["data"] && housingInfo["data"].info.rentalperiod }}</span>
<div class="line"></div>
<div class="dis-f al-item">
{{ indexData["data"] && indexData["data"]["config"] && indexData["data"]["config"]["type"][housingInfo["data"] && housingInfo["data"].info.type.substring(0, 1)] }}
<img src="../assets/img/detail/arrowIcon.svg" class="icon" alt="" />
{{ indexData["data"] && indexData["data"]["config"] && indexData["data"]["config"]["type"][housingInfo["data"] && housingInfo["data"].info.type] }}
</div>
</div>
<div class="dis-f al-item">
<div class="tool-btn dis-f al-item jus-x">
<div class="dis-f al-item fav-btn" @click="setOperation">
<div class="pos-r" style="width: 20px; height: 20px;">
<img src="../assets/img/detail/collect.png" v-show="housingInfo['data'] && !housingInfo['data'].isfav" class="fav-img fav-img-t" alt="" />
<img src="../assets/img/detail/collectT.png" v-show="housingInfo['data'] && !housingInfo['data'].isfav" class="fav-img fav-img-f" alt="" />
</div>
<img src="../assets/img/detail/collectT.png" v-show="housingInfo['data'] && housingInfo['data'].isfav" class="tool-icon" alt="" />
<span style="margin-left: 5px;">
{{ housingInfo["data"] && housingInfo["data"].isfav ? housingInfo["data"] && housingInfo["data"]["info"].count_fav : "收藏" }}
</span>
<span>/{{ housingInfo["data"] && housingInfo["data"].info.rentalperiod }}</span>
<div class="line"></div>
<div class="dis-f al-item">
{{ indexData["data"] && indexData["data"]["config"] && indexData["data"]["config"]["type"][housingInfo["data"] && housingInfo["data"].info.type.substring(0, 1)] }}
<img src="../assets/img/detail/arrowIcon.svg" class="icon" alt="" />
{{ indexData["data"] && indexData["data"]["config"] && indexData["data"]["config"]["type"][housingInfo["data"] && housingInfo["data"].info.type] }}
</div>
</div>
<div class="line" style="margin: 0 20px;"></div>
<div class="dis-f al-item">
<div class="tool-btn dis-f al-item jus-x">
<div class="dis-f al-item fav-btn" @click="setOperation">
<div class="pos-r" style="width: 20px; height: 20px;">
<img src="../assets/img/detail/collect.png" v-show="housingInfo['data'] && !housingInfo['data'].isfav" class="fav-img fav-img-t" alt="" />
<img src="../assets/img/detail/collectT.png" v-show="housingInfo['data'] && !housingInfo['data'].isfav" class="fav-img fav-img-f" alt="" />
</div>
<img src="../assets/img/detail/collectT.png" v-show="housingInfo['data'] && housingInfo['data'].isfav" class="tool-icon" alt="" />
<span style="margin-left: 5px;">
{{ housingInfo["data"] && housingInfo["data"].isfav ? housingInfo["data"] && housingInfo["data"]["info"].count_fav : "收藏" }}
</span>
</div>
<div class="line" style="margin: 0 20px;"></div>
<div class="dis-f al-item">
<img src="../assets/img/detail/forward.png" class="tool-icon" alt="" />
<span>
转发
</span>
<transmit-btn v-if="housingInfo.data" :concatType="concatType" :qrcode="housingInfo.data['qrcode']" :title="housingInfo.data.info['subject']" type="housingTop"></transmit-btn>
</div>
</div>
<div class="concat-btn-box" :class="{ 'concat-btn-show': concatType }">
<div class="contact-btn top-contact-btn" style="margin: 0 0 0 10px;" @click="getConcatData">
联系方式
</div>
</div>
<img src="../assets/img/detail/forward.png" class="tool-icon" alt="" />
<span>
转发
</span>
<transmit-btn v-if="housingInfo.data" :concatType="concatType" :qrcode="housingInfo.data['qrcode']" :title="housingInfo.data.info['subject']" type="housingTop"></transmit-btn>
</div>
</div>
<div class="concat-btn-box" :class="{ 'concat-btn-show': concatType }">
<div class="contact-btn top-contact-btn" style="margin: 0 0 0 10px;" @click="getConcatData">
联系方式
</div>
</div>
</div>
</el-affix>
</div>
</div>
<div class="detail-price-box dis-f" style="align-items: end;">
<span class="need-houing-type" v-if="pageType == 3">预算</span>
@@ -983,7 +979,7 @@ let setNavigation = () => {
path: pageType.value === 2 ? "/intermediaryHousing" : pageType.value === 3 ? "/needHousing" : "/personHousing",
title: pageType.value === 2 ? "中介房源" : pageType.value === 3 ? "求房源" : "个人房源",
}
housingInfo["data"]["info"].location = housingInfo["data"]["info"].location + ''
housingInfo["data"]["info"].location = housingInfo["data"]["info"].location + ""
store.state.routeList["thirdIndex"] = {
path: `${store.state.routeList["secondaryIndex"].path}`,
query: {
@@ -1251,7 +1247,7 @@ onBeforeUnmount(() => {
const distanceSchool = () => {
api.detailsDistance({
uniqid: uniqid.value,
istype: 1
istype: 1,
}).then(res => {
const data = res.data
if (res.code != 200) return
@@ -1330,7 +1326,6 @@ const selectIndex = id => {
// showDistance.value = true
}
</script>
<style scoped lang="less">
img {
@@ -1828,7 +1823,11 @@ img {
}
.top-bar-box {
position: fixed;
width: 100%;
left: 0;
bottom: 0;
z-index: 1002;
.line {
width: 1px;
@@ -2945,7 +2944,6 @@ img {
top: 20px;
right: 20px;
cursor: pointer;
}
}

View File

@@ -107,7 +107,7 @@ const getData = () => {
requestLoading = true
proxy
.$get("/tenement/pc/api/apartment", {
.$post("/tenement/pc/api/apartment", {
limit: 10,
page,
...pitchValue.value,
@@ -232,7 +232,7 @@ const handlecollect = uniqid => {
api.apartmentCollection({ token }).then(res => {
if (res.code != 200) return
const data = res.data
console.log("data", data)
// console.log("data", data)
list.value[targetIndex]["iscollect"] = data.status
ElMessage.success(res.message)
})

View File

@@ -4,102 +4,130 @@
<div class="info-box flexacenter">
<div class="info-left flexacenter flex1">
<a href="https://bbs.gter.net/account.php?a=avatar" target="_blank">
<img class="info-user-icon"
:src="user['avatar'] || store.state.user['avatar'] || require('@/assets/img/publicImage/defaultAvatar.png')">
<img class="info-user-icon" :src="user['avatar'] || store.state.user['avatar'] || require('@/assets/img/publicImage/defaultAvatar.png')" />
</a>
<div class="info-user-box">
<div class="info-user-top flexacenter">
<a href="https://bbs.gter.net/account.php?a=info" target="_blank" class="info-user-username">{{
user['nickname'] }}</a>
<a href="https://bbs.gter.net/account.php?a=info" target="_blank" class="info-user-username">{{ user["nickname"] }}</a>
<a href="https://bbs.gter.net/account.php?a=info" target="_blank">
<img class="info-user-edit" src="@/assets/img/publicImage/edit-pen.png">
<img class="info-user-edit" src="@/assets/img/publicImage/edit-pen.png" />
</a>
<img class="info-user-certifying" v-if="user.intermediary == 1"
src="@/assets/img/publicImage/certifying-agent.png">
<img class="info-user-certifying" v-if="user.intermediary == 1" src="@/assets/img/publicImage/certifying-agent.png" />
<div class="info-user-validity" v-if="validityidentity">有效期至{{ validityidentity }}</div>
</div>
<div class="info-user-bottom flexacenter">UID{{ user['uid'] }}</div>
<div class="info-user-bottom flexacenter">UID{{ user["uid"] }}</div>
</div>
</div>
<div class="info-right flexacenter">
<div class="operate-item message flexcenter" @click="systematicState = true; newmessagenum = 0">
<div class="operate-item message flexcenter" @click="handleOpenMessage">
<div class="operate-item-shell flexcenter">
<div class="newmessagenum flexcenter" v-if="newmessagenum > 0">{{ newmessagenum }}</div>
<img class="operate-icon" src="@/assets/img/publicImage/message-icon.svg">
<img class="operate-icon" src="@/assets/img/publicImage/message-icon.svg" />
</div>
<div class="operate-text">消息提醒</div>
</div>
<img class="" src="@/assets/img/publicImage/cut-off-rule.svg">
<img class="" src="@/assets/img/publicImage/cut-off-rule.svg" />
<div class="operate-item flexcenter add">
<div class="operate-item-shell flexcenter">
<img class="operate-icon" src="@/assets/img/publicImage/add-icon.svg">
<img class="operate-icon" src="@/assets/img/publicImage/add-icon.svg" />
</div>
<div class="operate-text">发布房源</div>
<choosing-identity></choosing-identity>
</div>
<template v-if="user['uid'] && user.identity != 0">
<img class="" src="@/assets/img/publicImage/cut-off-rule.svg">
<img class="" src="@/assets/img/publicImage/cut-off-rule.svg" />
<div class="operate-item flexcenter identity">
<div class="operate-item-shell flexcenter"
:class="{ 'intermediary': user.identity == 1, 'personage': user.identity == -1 }">
<img class="operate-icon" src="@/assets/img/publicImage/intermediary-icon.png">
<div class="operate-item-shell flexcenter" :class="{ 'intermediary': user.identity == 1, 'personage': user.identity == -1 }">
<img class="operate-icon" src="@/assets/img/publicImage/intermediary-icon.png" />
</div>
<div class="operate-text">{{ identityObj[user.identity || -1] }}</div>
<div v-if="user.identity == 1" class="btn-qrcode">
<authentication-info :type="2" style="height: 217px ;"></authentication-info>
<!-- <img class="bj" src="@/assets/img/publicImage/mediation-authentication-bj.jpg">
<img class="QR-code" src="https://app.gter.net/tenement/pc/api/qrcode?type=middlemanAuth"> -->
<authentication-info :type="2" style="height: 217px;"></authentication-info>
</div>
<div v-else class="btn-qrcode">
<authentication-info :type="1" style="height: 217px ;"></authentication-info>
<!-- <img class="bj" src="@/assets/img/publicImage/housing-certification-bj.jpg">
<img class="QR-code" src="https://app.gter.net/tenement/pc/api/qrcode?type=propertyAuth"> -->
<authentication-info :type="1" style="height: 217px;"></authentication-info>
</div>
</div>
<!-- <el-popover placement="right-end" :width="360" trigger="hover" :show-arrow="false"
popper-style="background: transparent;padding:0;box-shadow: none;border: none;">
<img v-if="user.identity == 1" style="width: 360px;"
src="@/assets/img/publicImage/mediation-authentication-code.svg">
<img v-else style="width: 360px;" src="@/assets/img/publicImage/housing-certification-code.svg">
</el-popover> -->
</template>
</div>
</div>
<div class="tab-box flexacenter">
<div class="tab-item flexcenter" :class="{ 'pitch': tabState == 'fav' }" @click="cutTab('fav')">我的收藏</div>
<div class="tab-item flexcenter" :class="{ 'pitch': tabState == 'publish' }" @click="cutTab('publish')">我的发布
</div>
<div class="tab-item flexcenter" :class="{ 'pitch': tabState == 'publish' }" @click="cutTab('publish')">我的发布</div>
</div>
</div>
<div class="quantity wid1200" v-if="tabState == 'fav'">共收藏 <b>{{ count['fav'] }}</b> 个房源</div>
<div class="quantity wid1200 flexacenter" v-else> <b>{{ count['publish'] }}</b> 房源上架 {{ stat['listing'] }} <div
class="longString">|</div> 草稿 {{ stat['draft']
}} <div class="longString">|</div> 下架 {{ stat['offshelf'] }}</div>
<div class="quantity wid1200" v-if="tabState == 'fav'">
共收藏 <b>{{ count["fav"] }}</b> 房源
</div>
<div class="quantity wid1200 flexacenter" v-else>
<b>{{ count["publish"] }}</b> 条房源上架 {{ stat["listing"] }}
<div class="longString">|</div>
草稿 {{ stat["draft"] }}
<div class="longString">|</div>
下架 {{ stat["offshelf"] }}
</div>
<div class="list wid1200 flexflex" v-show="tabState == 'fav'" ref="gridContainer">
<div class="item" v-for="(item, index) in favData['list']" :key="item.id">
<public-list-item :item="item" :index="index" @cancelCollection="cancelCollection"></public-list-item>
<div class="item" v-for="(item, index) in favData['list']" :key="item.id" @click="goApartmentDetail(item)">
<div v-if="item.collectiontype == 'apartment'" class="apartment-item">
<div class="apartment-header flexflex">
<img class="apartment-header-img" :src="item.image || item.imageurl" />
<div class="apartment-header-content flexflex flex1">
<div class="apartment-header-title">{{ item.title }}</div>
<div class="apartment-header-tips">{{ item.propaganda }}</div>
<div class="apartment-header-types flex">
<div v-for="(it, i) in item.othertags" :key="i" class="apartment-header-types-item flexcenter">{{ it }}</div>
</div>
</div>
</div>
<div class="apartment-type-box flexflex flex1">
<div class="apartment-type-list flexflex flex1">
<div class="apartment-type-list-item flexacenter" v-for="(it, index) in item.roomlist" :key="index">
<div class="apartment-type-list-item-name flex1">{{ it.name }}</div>
<div class="apartment-type-list-item-price flexacenter">
<div class="unit">HK$</div>
<div class="value">{{ it.price }}</div>
/
</div>
</div>
</div>
<div class="apartment-type-total flexcenter">
<div class="apartment-type-total-value flexcenter">{{ item.roomnum }}</div>
个房型
<img class="apartment-type-arrow" src="@/assets/img/publicImage/black-arrow.svg" />
</div>
</div>
<div class="apartment-bottom flexacenter">
<div class="apartment-bottom-location flexacenter flex1">
<img class="apartment-bottom-icon" src="@/assets/img/publicImage/location-icon.png" />
{{ item.address }}
</div>
<div class="apartment-bottom-btn flexacenter" @click.stop="cancelCollection(item)">
<img class="apartment-bottom-btn-icon" src="@/assets/img/publicImage/black-circle-cross.svg" />
取消收藏
</div>
</div>
</div>
<public-list-item v-else :item="item" :index="index" @cancelCollection="cancelCollection"></public-list-item>
</div>
</div>
<div class="list wid1200 flexflex" v-show="tabState == 'publish'" ref="gridContainerpublish">
<div class="item" v-for="(item, index) in publishData['list']" :key="item.id">
<public-list-item :item="item" :index="index" @cancelCollection="cancelCollection" :ispublish="true"
@goUp="goUp" @undercarriage="undercarriage" @handleDelete="handleDelete"></public-list-item>
<public-list-item :item="item" :index="index" @cancelCollection="cancelCollection" :ispublish="true" @goUp="goUp" @undercarriage="undercarriage" @handleDelete="handleDelete"></public-list-item>
</div>
</div>
<div class="empty-box flexcenter wid1200"
v-if="(tabState == 'fav' && favData['list'].length == 0) || (tabState == 'publish' && publishData['list'].length == 0)">
<div class="empty-box flexcenter wid1200" v-if="(tabState == 'fav' && favData['list'].length == 0) || (tabState == 'publish' && publishData['list'].length == 0)">
<empty-duck></empty-duck>
</div>
<div class="bottom-tps"
v-if="(tabState == 'fav' && favData['list'].length != 0 && favData['page'] == 0) || (tabState == 'publish' && publishData['list'].length != 0 && publishData['page'] == 0)">
- 到底了 -</div>
<div class="bottom-tps" v-if="(tabState == 'fav' && favData['list'].length != 0 && favData['page'] == 0) || (tabState == 'publish' && publishData['list'].length != 0 && publishData['page'] == 0)">
- 到底了 -
</div>
<!-- 有疑问 -->
<have-questions></have-questions>
@@ -113,253 +141,276 @@
</template>
<script setup>
import pageTopBar from '../components/pageTopBar/pageTopBar.vue';
import systematicNotificationPop from '@/components/user/systematic-notification-pop.vue'
import haveQuestions from '@/components/public/have-questions.vue'
import pageFooter from '@/components/footer/footer.vue'
import publicListItem from '@/components/public/public-list-item.vue'
import emptyDuck from '@/components/public/empty-duck.vue'
import choosingIdentity from '@/components/edit/choosingIdentity.vue'
import backToTop from '@/components/public/backToTop.vue'
import authenticationInfo from '@/components/seachModule/authenticationInfo.vue';
import pageTopBar from "../components/pageTopBar/pageTopBar.vue"
import systematicNotificationPop from "@/components/user/systematic-notification-pop.vue"
import haveQuestions from "@/components/public/have-questions.vue"
import pageFooter from "@/components/footer/footer.vue"
import publicListItem from "@/components/public/public-list-item.vue"
import emptyDuck from "@/components/public/empty-duck.vue"
import choosingIdentity from "@/components/edit/choosingIdentity.vue"
import backToTop from "@/components/public/backToTop.vue"
import authenticationInfo from "@/components/seachModule/authenticationInfo.vue"
import { ref, reactive, onMounted, onUnmounted, getCurrentInstance, nextTick, pushScopeId } from 'vue'
import { useRoute, useRouter } from 'vue-router';
import { ref, reactive, onMounted, onUnmounted, getCurrentInstance, nextTick, pushScopeId } from "vue"
import { useRoute, useRouter } from "vue-router"
import { ElLoading, ElMessage } from 'element-plus'
import Masonry from 'masonry-layout';
import store from '@/store/index';
import { ElLoading, ElMessage } from "element-plus"
import Masonry from "masonry-layout"
import store from "@/store/index"
const { proxy } = getCurrentInstance()
const route = useRoute();
const route = useRoute()
let router = useRouter()
const gridContainer = ref(null);
const gridContainerpublish = ref(null);
const gridContainer = ref(null)
const gridContainerpublish = ref(null)
let masonryInstance = null
let masonryInstancepublish = null
onMounted(() => {
masonryInstance = new Masonry(gridContainer.value, {
itemSelector: '.item',
gutter: 20
});
itemSelector: ".item",
gutter: 20,
})
masonryInstancepublish = new Masonry(gridContainerpublish.value, {
itemSelector: '.item',
gutter: 20
});
itemSelector: ".item",
gutter: 20,
})
init()
window.addEventListener('scroll', handleScroll);
window.addEventListener("scroll", handleScroll)
})
let systematicState = ref(false) // 系统通知
let user = ref({})
let count = ref({}) // 发布和收藏的数量
let newmessagenum = ref(0)
let validityidentity = ref('')
let tabState = ref('publish') // fav publish
let validityidentity = ref("")
let tabState = ref("publish") // fav publish
const identityObj = {
1: "中介认证",
"-1": "房源认证"
"-1": "房源认证",
}
// 打开消息提醒 并且 删除未读消息数
const handleOpenMessage = () => {
systematicState.value = true
newmessagenum.value = 0
}
const init = () => {
proxy.$post("/tenement/pc/api/user").then(res => {
if (res.code != 200) return
let data = res.data
proxy
.$post("/tenement/pc/api/user")
.then(res => {
if (res.code != 200) return
let data = res.data
if (!route.query['tab']) {
if (data.count['publish'] > 0) tabState.value = 'publish'
else if (data.count['fav'] == 0) tabState.value = 'publish'
else tabState.value = 'fav'
} else tabState.value = route.query['tab']
if (!route.query["tab"]) {
if (data.count["publish"] > 0) tabState.value = "publish"
else if (data.count["fav"] == 0) tabState.value = "publish"
else tabState.value = "fav"
} else tabState.value = route.query["tab"]
if (tabState.value == 'publish') getPublishData()
else getFavData()
// if (tabState.value == 'publish') getPublishData()
// else getFavData()
tabState.value = "fav"
getFavData()
user.value = data.user
count.value = data.count
newmessagenum.value = data.newmessagenum
store.state.user['messagenum'] = data.newmessagenum
user.value = data.user
count.value = data.count
newmessagenum.value = data.newmessagenum
store.state.user["messagenum"] = data.newmessagenum
validityidentity.value = data.validityidentity
}).finally(() => { })
validityidentity.value = data.validityidentity
})
.finally(() => {})
}
let loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
visible: false
});
text: "Loading",
background: "rgba(0, 0, 0, 0.7)",
visible: false,
})
let publishData = ref({
page: 1,
list: []
list: [],
})
let stat = ref({}) // 我的发布的详细数量
// 获取发布数据
const getPublishData = () => {
if (publishData.value['page'] == 0 || loading['visible'].value) return
if (publishData.value["page"] == 0 || loading["visible"].value) return
loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
text: "Loading",
background: "rgba(0, 0, 0, 0.7)",
})
proxy.$post("/tenement/pc/api/user/publishList", {
page: publishData.value['page']
}).then(res => {
if (res.code != 200) return
let data = res.data
// data.data[0]['verifiedstatus'] = 1
stat.value = data['stat']
publishData.value['page'] = data['page'] * data['limit'] >= data['count'] ? 0 : data['page'] + 1
publishData.value['list'] = publishData.value['list'].concat(data['data'] || [])
nextTick(() => {
masonryInstancepublish.reloadItems();
masonryInstancepublish.layout();
proxy
.$post("/tenement/pc/api/user/publishList", {
page: publishData.value["page"],
})
.then(res => {
if (res.code != 200) return
let data = res.data
// data.data[0]['verifiedstatus'] = 1
stat.value = data["stat"]
publishData.value["page"] = data["page"] * data["limit"] >= data["count"] ? 0 : data["page"] + 1
publishData.value["list"] = publishData.value["list"].concat(data["data"] || [])
nextTick(() => {
masonryInstancepublish.reloadItems()
masonryInstancepublish.layout()
loading.close()
})
})
.finally(() => {
loading.close()
})
}).finally(() => {
loading.close()
})
}
let favData = ref({
page: 1,
list: []
list: [],
})
// 获取收藏数据
const getFavData = () => {
if (favData.value['page'] == 0 || loading['visible'].value) return
if (favData.value["page"] == 0 || loading["visible"].value) return
loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
text: "Loading",
background: "rgba(0, 0, 0, 0.7)",
})
proxy.$post("/tenement/pc/api/user/favList", {
page: favData.value['page'],
}).then(res => {
if (res.code != 200) return
let data = res.data
favData.value['page'] = data['page'] * data['limit'] >= data['count'] ? 0 : data['page'] + 1
favData.value['list'] = favData.value['list'].concat(data['data'] || [])
favData.value['limit'] = data['limit']
nextTick(() => {
masonryInstance.reloadItems();
masonryInstance.layout();
proxy
// .$post("/tenement/pc/api/user/favList", {
.$post("/tenement/pc/api/user/collectionList", {
page: favData.value["page"],
})
.then(res => {
if (res.code != 200) return
let data = res.data
favData.value["page"] = data["page"] * data["limit"] >= data["count"] ? 0 : data["page"] + 1
favData.value["list"] = favData.value["list"].concat(data["data"] || [])
favData.value["limit"] = data["limit"]
nextTick(() => {
masonryInstance.reloadItems()
masonryInstance.layout()
loading.close()
})
})
.finally(() => {
loading.close()
})
}).finally(() => {
loading.close()
})
}
// 切换 tab
const cutTab = (value) => {
// 切换 tab
const cutTab = value => {
tabState.value = value
if (tabState.value == 'publish' && publishData.value['list'].length == 0) getPublishData()
else if (tabState.value == 'fav' && favData.value['list'].length == 0) getFavData()
if (tabState.value == "publish" && publishData.value["list"].length == 0) getPublishData()
else if (tabState.value == "fav" && favData.value["list"].length == 0) getFavData()
}
// 取消收藏
let cancelCollection = data => {
proxy.$post("/tenement/pc/api/user/operation", {
token: data['token']
}).then(res => {
if (res.code != 200) return
favData.value.list.splice(data['index'], 1)
count.value['fav']--
if (favData.value.list.length == 0 && favData.value['page'] != 0) {
favData.value['page'] = 1
getFavData()
} else refillData(data['index'])
nextTick(() => {
masonryInstance.reloadItems();
masonryInstance.layout();
loading.close()
let url = '/tenement/pc/api/user/operation'
if (data['collectiontype'] == 'apartment') url = '/tenement/pc/api/user/apartmentCollection'
proxy
.$post(url, {
token: data["token"],
})
.then(res => {
if (res.code != 200) return
favData.value.list.splice(data["index"], 1)
count.value["fav"]--
if (favData.value.list.length == 0 && favData.value["page"] != 0) {
favData.value["page"] = 1
getFavData()
} else refillData(data["index"])
nextTick(() => {
masonryInstance.reloadItems()
masonryInstance.layout()
loading.close()
})
})
})
}
// 取消输出后重新补充一条数据
const refillData = index => {
if (favData.value['page'] == 0 || loading['visible'].value) return
const page = favData.value['page'] - 1
proxy.$post("/tenement/pc/api/user/favList", {
page,
limit: favData.value['limit']
}).then(res => {
if (res.code != 200) return
let data = res.data['data'] || []
favData.value['list'].push(data[data.length - 1])
nextTick(() => {
masonryInstance.reloadItems();
masonryInstance.layout();
if (favData.value["page"] == 0 || loading["visible"].value) return
const page = favData.value["page"] - 1
proxy
.$post("/tenement/pc/api/user/favList", {
page,
limit: favData.value["limit"],
})
.then(res => {
if (res.code != 200) return
let data = res.data["data"] || []
favData.value["list"].push(data[data.length - 1])
nextTick(() => {
masonryInstance.reloadItems()
masonryInstance.layout()
})
})
})
}
// 点击下架都修改状态
const undercarriage = (index, status) => {
stat.value['listing']--
stat.value['offshelf']++
publishData.value['list'][index].status = status
stat.value["listing"]--
stat.value["offshelf"]++
publishData.value["list"][index].status = status
nextTick(() => {
masonryInstance.reloadItems();
masonryInstance.layout();
masonryInstance.reloadItems()
masonryInstance.layout()
})
}
// 点击顶上去后改 数据 状态
const goUp = index => publishData.value['list'][index].isding = 1
const goUp = index => (publishData.value["list"][index].isding = 1)
// 点击删除
const handleDelete = (index, status) => {
if (status == 0) stat.value['draft']--
else if (status == 1) stat.value['listing']--
else stat.value['offshelf']--
count.value['publish']--
publishData.value['list'].splice(index, 1)
if (status == 0) stat.value["draft"]--
else if (status == 1) stat.value["listing"]--
else stat.value["offshelf"]--
count.value["publish"]--
publishData.value["list"].splice(index, 1)
nextTick(() => {
masonryInstancepublish.reloadItems();
masonryInstancepublish.layout();
masonryInstancepublish.reloadItems()
masonryInstancepublish.layout()
loading.close()
})
}
// 监听滚动到底部
const handleScroll = () => {
if (!user.value['uid']) return
const scrollHeight = document.documentElement.scrollHeight;
const clientHeight = document.documentElement.clientHeight;
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (!user.value["uid"]) return
const scrollHeight = document.documentElement.scrollHeight
const clientHeight = document.documentElement.clientHeight
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
if (scrollTop + clientHeight >= scrollHeight - 350) {
if (tabState.value == 'publish') getPublishData()
if (tabState.value == "publish") getPublishData()
else getFavData()
}
};
}
// 跳转公寓详情页
const goApartmentDetail = item => router.push(`/apartmentDetail?uniqid=${item.uniqid}`)
onUnmounted(() => {
window.removeEventListener('scroll', handleScroll);
});
window.removeEventListener("scroll", handleScroll)
})
</script>
<style lang="less" scoped>
* {
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
}
.user-box {
@@ -414,18 +465,16 @@ onUnmounted(() => {
color: #aaa;
font-size: 13px;
}
}
.info-user-bottom {
height: 24px;
color: #7F7F7F;
color: #7f7f7f;
}
}
}
.info-right {
.operate-item:hover .btn-qrcode {
display: block;
}
@@ -444,7 +493,6 @@ onUnmounted(() => {
}
&.message {
.operate-item-shell {
position: relative;
background-color: rgba(80, 227, 194, 1);
@@ -467,7 +515,7 @@ onUnmounted(() => {
height: 16px;
font-size: 13px;
background: #f95d5d;
color: #FFFFFF;
color: #ffffff;
border-radius: 50%;
}
}
@@ -516,7 +564,6 @@ onUnmounted(() => {
height: 24px;
}
}
}
}
@@ -541,11 +588,11 @@ onUnmounted(() => {
&.pitch {
background-color: rgba(98, 177, 255, 1);
border-radius: 8px;
font-family: 'PingFangSC-Semibold', 'PingFang SC Semibold', 'PingFang SC', sans-serif;
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
font-weight: 650;
font-style: normal;
font-size: 18px;
color: #FFFFFF;
color: #ffffff;
position: relative;
&::after {
@@ -554,9 +601,8 @@ onUnmounted(() => {
bottom: -5px;
width: 14px;
height: 8px;
background-image: url('@/assets/img/publicImage/green-arrow-below.svg');
background-image: url("@/assets/img/publicImage/green-arrow-below.svg");
}
}
}
}
@@ -575,7 +621,7 @@ onUnmounted(() => {
.longString {
font-weight: 400;
color: #D7D7D7;
color: #d7d7d7;
margin: 0 4px;
}
}
@@ -591,7 +637,7 @@ onUnmounted(() => {
}
.empty-box {
background-color: #FFFFFF;
background-color: #ffffff;
height: 500px;
margin: 0 auto;
justify-content: center;
@@ -632,4 +678,155 @@ onUnmounted(() => {
transform: translateX(-50%);
}
}
.apartment-item {
width: 590px;
height: 360px;
padding: 20px;
background-color: rgba(255, 255, 255, 1);
border-radius: 16px;
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
margin-bottom: 20px;
.apartment-header {
margin-bottom: 20px;
.apartment-header-img {
width: 209px;
height: 140px;
border-radius: 15px;
margin-right: 20px;
}
.apartment-header-content {
flex-direction: column;
.apartment-header-title {
font-weight: 650;
font-size: 20px;
color: #000000;
margin-bottom: 10px;
}
.apartment-header-tips {
color: #aaaaaa;
font-size: 14px;
margin-bottom: 20px;
}
.apartment-header-types {
height: 76px;
overflow: hidden;
.apartment-header-types-item {
display: inline-flex;
height: 28px;
padding: 0 12px;
background-color: rgba(224, 240, 255, 1);
border-radius: 5px;
color: #447eb3;
font-size: 13px;
margin-right: 10px;
margin-bottom: 10px;
}
}
}
}
.apartment-type-box {
width: 550px;
background-color: rgba(246, 246, 246, 1);
border-radius: 12px;
.apartment-type-list {
flex-direction: column;
border-right: 1px solid #ebebeb;
.apartment-type-list-item {
padding: 0 10px;
height: 54px;
&:not(:last-of-type) {
border-bottom: 1px solid #ebebeb;
}
.apartment-type-list-item-name {
font-size: 15px;
color: #000000;
}
.apartment-type-list-item-price {
.unit {
font-family: "Arial-Black", "Arial Black", sans-serif;
font-weight: 900;
color: #000000;
font-size: 14px;
margin-right: 5px;
}
.value {
font-family: "Arial-Black", "Arial Black", sans-serif;
font-weight: 900;
font-size: 20px;
color: #f95d5d;
margin-right: 5px;
}
font-size: 14px;
color: #555555;
}
}
}
.apartment-type-total {
font-size: 14px;
color: #555555;
width: 191px;
.apartment-type-total-value {
font-weight: 650;
font-size: 14px;
color: #000000;
line-height: 18px;
background-color: #fddf6d;
border-radius: 9px;
padding: 0 8px;
margin: 0 8px;
}
.apartment-type-arrow {
width: 7px;
height: 12px;
margin-left: 8px;
}
}
}
.apartment-bottom {
height: 58px;
.apartment-bottom-location {
font-size: 15px;
color: #555555;
.apartment-bottom-icon {
width: 18px;
height: 18px;
margin-right: 5px;
}
}
.apartment-bottom-btn {
color: #333333;
font-size: 14px;
height: 58px;
&:hover .apartment-bottom-btn-icon {
transform: rotate(360deg);
}
.apartment-bottom-btn-icon {
width: 16px;
height: 16px;
margin-right: 3px;
transition: all 1s;
}
}
}
}
</style>