公寓详情加收藏和附近学校
This commit is contained in:
parent
3f2f641be0
commit
5a4e6e79cd
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="item flexflex" @click="goapArtmentDetails">
|
||||
<div class="collect-box flexcenter" @click.stop="handleCollect1(item)" v-if="false">
|
||||
<div class="collect-box flexcenter" @click.stop="handleCollect1(item.uniqid)">
|
||||
<img v-if="item.iscollect == 0" class="collect-icon" style="width: 30px; height: 30px;" src="@/assets/img/apartmentDetail/collecting-shadows.svg" />
|
||||
<img v-else class="collect-icon" src="@/assets/img/apartmentDetail/collecting-yellow-shadows.svg" />
|
||||
</div>
|
||||
@ -48,12 +48,16 @@ const props = defineProps({
|
||||
|
||||
const emit = defineEmits(["handlecollect"])
|
||||
|
||||
const goapArtmentDetails = () => redirectToExternalWebsite(`/apartmentDetail?uniqid=${props["item"].uniqid}`)
|
||||
const goapArtmentDetails = () => {
|
||||
let url = `/apartmentDetail?uniqid=${props["item"].uniqid}`
|
||||
if (props.pitchValue['school']) url += `&school=${props.pitchValue['school']}`
|
||||
|
||||
redirectToExternalWebsite(url)
|
||||
}
|
||||
|
||||
// 点击收藏后传过父组件
|
||||
const handleCollect1 = item => {
|
||||
emit("handlecollect", item)
|
||||
}
|
||||
const handleCollect1 = uniqid => emit("handlecollect", uniqid)
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
@ -128,7 +128,7 @@ const showPop = () => {
|
||||
width: 816px;
|
||||
height: 180px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 40px;
|
||||
// margin-bottom: 40px;
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
@ -42,6 +42,9 @@ export default{
|
||||
},
|
||||
detailsDistance:(params={})=>{//详情页 - 距离学校距离
|
||||
return axios.get('/tenement/pc/api/details/distance',params)
|
||||
},
|
||||
apartmentCollection:(params={})=>{// 公寓列表 - 收藏
|
||||
return axios.get('/tenement/pc/api/user/apartmentCollection',params)
|
||||
}
|
||||
|
||||
}
|
@ -21,7 +21,7 @@ axios.interceptors.request.use(
|
||||
if (config.url != "/tenement/pc/api/user/operation" && !noMask) showFullScreenLoading()
|
||||
// 开发时登录用的,可以直接替换小程序的 authorization
|
||||
// if (process.env.NODE_ENV == "development") config['headers']['authorization'] = "x2mmnl9grt51bpplj2k6ioiuummzhnw3"
|
||||
if (process.env.NODE_ENV == "development") config["headers"]["authorization"] = "gifqtoiomgb2efu7tcr16kcgs2"
|
||||
if (process.env.NODE_ENV == "development") config["headers"]["authorization"] = "mx25rp0q99x3sis8hidugttty80c5qum"
|
||||
|
||||
// 当 noMask == true 和 confing.method == 'get' 时,删除 config.params['noMask']
|
||||
if (noMask && config.method == "get") delete config.params["noMask"]
|
||||
|
@ -1,51 +1,80 @@
|
||||
|
||||
|
||||
function setSeoTitle(title) {
|
||||
document.title = '港校租房-' + title
|
||||
document.title = "港校租房-" + title
|
||||
}
|
||||
|
||||
// 跳转 url
|
||||
function redirectToExternalWebsite(url) {
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.target = '_blank';
|
||||
link.click();
|
||||
const link = document.createElement("a")
|
||||
link.href = url
|
||||
link.target = "_blank"
|
||||
link.click()
|
||||
}
|
||||
|
||||
// 跳转登录
|
||||
function goTologin() {
|
||||
let url = encodeURIComponent(location.href);
|
||||
redirectToExternalWebsite(`https://passport.gter.net/?referer=${url}`);
|
||||
let url = encodeURIComponent(location.href)
|
||||
redirectToExternalWebsite(`https://passport.gter.net/?referer=${url}`)
|
||||
}
|
||||
|
||||
// 复制方法
|
||||
function copyToClipboard(text) {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const textareaEle = document.createElement("textarea");
|
||||
document.body.appendChild(textareaEle);
|
||||
const textareaEle = document.createElement("textarea")
|
||||
document.body.appendChild(textareaEle)
|
||||
// 2. 将需要复制的文本传入输入框, 并调用 select 方法, 选中输入框中文本
|
||||
textareaEle.value = text;
|
||||
textareaEle.select();
|
||||
textareaEle.readOnly = 'readOnly';
|
||||
textareaEle.value = text
|
||||
textareaEle.select()
|
||||
textareaEle.readOnly = "readOnly"
|
||||
// 3. 调用复制选中文本的方法
|
||||
document.execCommand('copy');
|
||||
document.execCommand("copy")
|
||||
// 4. 销毁输入框
|
||||
document.body.removeChild(textareaEle);
|
||||
document.body.removeChild(textareaEle)
|
||||
resolve()
|
||||
// navigator.clipboard.writeText(text).then(() => {
|
||||
// resolve()
|
||||
// }).catch((err) => {
|
||||
// reject()
|
||||
// });
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 转换 秒数
|
||||
function secondsToHoursMinutes(seconds, type) {
|
||||
// 计算小时数
|
||||
const hours = Math.floor(seconds / 3600)
|
||||
// 计算剩余的秒数
|
||||
const remainingSecondsAfterHours = seconds % 3600
|
||||
// 计算分钟数
|
||||
const minutes = Math.floor(remainingSecondsAfterHours / 60)
|
||||
// 计算剩余的秒数
|
||||
const remainingSeconds = remainingSecondsAfterHours % 60
|
||||
|
||||
let text = ""
|
||||
if (type == "chinese") {
|
||||
if (hours != 0) text += hours + "小时"
|
||||
if (minutes != 0) text += minutes + "分钟"
|
||||
if (remainingSeconds != 0 && minutes == 0) text += remainingSeconds + "秒"
|
||||
} else {
|
||||
if (hours != 0) text += hours + "h"
|
||||
if (minutes != 0) text += minutes + "min"
|
||||
if (remainingSeconds != 0 && minutes == 0) text += remainingSeconds + "s"
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
// 转换 米数
|
||||
function metersToKilometers(input, type) {
|
||||
let text = ""
|
||||
if (input >= 1000) text = (input / 1000).toFixed(1) + (type == "chinese" ? "公里" : "km")
|
||||
else text = input + (type == "chinese" ? "米" : "m")
|
||||
return text
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
setSeoTitle,
|
||||
redirectToExternalWebsite,
|
||||
goTologin,
|
||||
copyToClipboard,
|
||||
}
|
||||
secondsToHoursMinutes,
|
||||
metersToKilometers,
|
||||
}
|
||||
|
@ -26,11 +26,11 @@
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
<div class="indicate-type flexacenter" v-if="indicateTypeState()">
|
||||
<div class="indicate-item" :class="{pitch: allCarouselsData[carouselIndex]['type'] == 'lives'}" v-if="info['lives'] && info['lives'].length != 0" @click="slideshowType('lives')">
|
||||
<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 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>
|
||||
@ -87,7 +87,7 @@
|
||||
<div class="operate-box-bj flexcenter">
|
||||
<div class="operate-box flexacenter" aria-label="详情的导航栏">
|
||||
<div class="nav-box flexacenter">
|
||||
<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 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="handleTransmit">
|
||||
@ -102,7 +102,7 @@
|
||||
<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-box" v-if="roomList.length !== 0" ref="roomEle">
|
||||
<div class="type-item flexacenter" v-for="(item, index) in roomList" :key="index">
|
||||
<!-- <img class="type-icon" alt="房间类型-角图片" 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" /> -->
|
||||
@ -166,7 +166,106 @@
|
||||
<img class="icon" src="@/assets/img/apartmentDetail/location-icon.png" />
|
||||
{{ info.location || "位置" }}
|
||||
</div>
|
||||
<view-map :latlng="{latitude: info['coordinate'][0], longitude: info['coordinate'][1]}" :name="info['address']"></view-map>
|
||||
<view-map :latlng="{ latitude: info['coordinate'][0], longitude: info['coordinate'][1] }" :name="info['address']"></view-map>
|
||||
|
||||
<el-popover :width="814" trigger="click" popper-style="padding: 0" :show-arrow="false" v-model:visible="showDistance">
|
||||
<template #reference>
|
||||
<div class="annex-school-box flexacenter">
|
||||
<div class="annex-left flex1 flexacenter">
|
||||
<div class="annex-school-item flexflex flex1" @click="selectIndex()" v-if="specialSchoolDistance">
|
||||
<div class="distance-item-value special flexacenter">
|
||||
<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>
|
||||
<div class="flexcenter">
|
||||
<img src="@/assets/img/detail/markIcon.svg" class="marker-icon" alt="" />
|
||||
</div>
|
||||
<div class="alias-text flexcenter">{{ specialSchoolDistance.alias || "都大" }}</div>
|
||||
</div>
|
||||
|
||||
<div class="annex-school-item flexflex flex1" v-for="(item, index) in annexSchoolOmit" :key="index" @click="selectIndex(item.id)">
|
||||
<div class="distance-item-value flexacenter">
|
||||
<div class="mileage">{{ item.distanceText || "2.0km" }}</div>
|
||||
<img v-if="!item.list[0].publictransport" 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">{{ item.list[0]?.publictransport?.durationText2 || item.list[0]?.durationText2 || "41min" }}</div>
|
||||
<!-- <div class="tool-time">{{ "41min" }}</div> -->
|
||||
</div>
|
||||
<div class="flexcenter">
|
||||
<img src="@/assets/img/detail/markIcon.svg" class="marker-icon" alt="" />
|
||||
</div>
|
||||
<div class="alias-text flexcenter">{{ item.alias || "都大" }}</div>
|
||||
</div>
|
||||
<div class="line-img"></div>
|
||||
</div>
|
||||
<div class="annex-btn flexcenter">
|
||||
<img class="annex-btn-bj" src="@/assets/img/detail/infoBtnBg.svg" />
|
||||
更多
|
||||
<img class="annex-btn-icon" src="@/assets/img/detail/arrowIcon.svg" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="distance-info-box pos-r" :style="{ height: `${50 * annexSchoolList.length + 70}px` }">
|
||||
<div class="title-box dis-f al-item jus-x">
|
||||
房源
|
||||
<img class="distance-arrow" src="@/assets/img/detail/arrow-circle-blue.svg" />
|
||||
院校
|
||||
<img src="../assets/img/detail/close.png" class="close-icon" @click="showDistance = false" alt="" />
|
||||
</div>
|
||||
<div class="distance-info-data dis-f">
|
||||
<div class="distance-info-left">
|
||||
<div class="distance-info-left-item flexcenter" :class="{ 'pitch': index == academyPitchIndex }" v-for="(item, index) in annexSchoolList" :key="index" @click="selectAcademyIndex(index)">{{ item.alias }}</div>
|
||||
</div>
|
||||
<el-scrollbar :style="{ height: 50 * annexSchoolList.length + 'px' }">
|
||||
<div class="distance-info-right flex1">
|
||||
<div class="distance-header-box flexacenter">
|
||||
<div class="flexacenter">
|
||||
<div class="distance-header-icon flexcenter">
|
||||
<img src="@/assets/img/detail/home.png" alt="" class="distance-header-img" />
|
||||
</div>
|
||||
{{ targetAcademyPitch.school }}
|
||||
</div>
|
||||
<div class="distance-header-hint">本数据来自高德地图,仅供参考。</div>
|
||||
</div>
|
||||
|
||||
<div class="academy-school-item" v-for="(item, index) in targetAcademyPitch.list" :key="index">
|
||||
<div class="academy-school-item-header flexacenter">
|
||||
<div class="academy-school-item-left flexacenter">
|
||||
<div class="academy-school-item-name">{{ item.title }}</div>
|
||||
<div class="academy-school-item-number">{{ item.distanceText || "1km" }}</div>
|
||||
</div>
|
||||
<div class="academy-school-item-right flexacenter">
|
||||
<img v-if="item.publictransport" class="academy-school-item-icon" src="@/assets/img/detail/subway-icon.png" mode="widthFix" />
|
||||
<img v-else class="academy-school-item-icon" src="@/assets/img/detail/walk-icon.png" mode="widthFix" />
|
||||
<div class="academy-school-item-time">{{ item?.publictransport?.durationText || item.durationText || "1分钟" }}</div>
|
||||
</div>
|
||||
<img class="arrow-green" mode="widthFix" src="@/assets/img/detail/arrow-green.svg" />
|
||||
</div>
|
||||
<div class="academy-school-item-journey" v-if="item.publictransport">
|
||||
<div class="journey-item flexacenter" v-for="(item, index) in item.publictransport.segments" :key="index">
|
||||
<div class="circle"></div>
|
||||
<!-- 步行 骑行 -->
|
||||
<div v-if="item.type == 'walking'" class="journey-value flex1">步行{{ item.distanceText }}</div>
|
||||
<!-- 地铁 -->
|
||||
<div v-else-if="item.type == 'bus' && item.bustype == '地铁线路'" class="journey-value flex1 subway flexacenter">
|
||||
<div class="subway-name flexcenter">{{ item.name }}</div>
|
||||
<div class="flex1" style="white-space: nowrap;">{{ item.via_num }}站·{{ item.durationText }}</div>
|
||||
</div>
|
||||
<!-- 公交 -->
|
||||
<div v-else-if="item.type == 'bus' && item.bustype == '普通公交线路'" class="journey-value flex1 bus flexacenter">
|
||||
<div class="bus-name flexcenter">{{ item.name }}</div>
|
||||
<div class="flex1" style="white-space: nowrap;">{{ item.via_num }}站·{{ item.durationText }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
|
||||
<!-- 交通 -->
|
||||
<div class="traffic-box" v-if="info['traffic']">
|
||||
@ -281,7 +380,7 @@
|
||||
|
||||
<!-- 添加客服 - 弹窗 -->
|
||||
<div class="add-customer-mask flexcenter" v-if="contactReservationState">
|
||||
<div class="add-customer-box flexcenter" :class="{two: customerservicelist.length != 1}">
|
||||
<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" />
|
||||
@ -316,9 +415,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref, onMounted, onUnmounted, toRefs, watch, getCurrentInstance, nextTick} from "vue"
|
||||
import {ElMessage, valueEquals} from "element-plus"
|
||||
import {useStore} from "vuex"
|
||||
import { ref, onMounted, onUnmounted, 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"
|
||||
@ -328,17 +427,19 @@ import backToTop from "@/components/public/backToTop.vue"
|
||||
import imageWatch from "@/components/detail/imageWatch.vue"
|
||||
import phoneqrcode from "@/components/public/phoneQRcode.vue"
|
||||
import groupqrcode from "@/components/public/group-QRcode.vue"
|
||||
import api from "@/utils/api"
|
||||
|
||||
import {useRouter, useRoute} from "vue-router"
|
||||
import { useRouter, useRoute } from "vue-router"
|
||||
let router = useRouter()
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
watch(route, () => {
|
||||
uniqid = router.currentRoute.value.query["uniqid"]
|
||||
pitchSchool = router.currentRoute.value.query["school"] || ""
|
||||
info.value = {}
|
||||
roomList.value = []
|
||||
carouselsconfig.value = {lives: {}, videos: {}, attachment: {}}
|
||||
carouselsconfig.value = { lives: {}, videos: {}, attachment: {} }
|
||||
navList.value = []
|
||||
navTab.value = "roomEle"
|
||||
dualBrandList.value = []
|
||||
@ -353,15 +454,16 @@ watch(route, () => {
|
||||
carouselIndex.value = 0
|
||||
allCarouselsData.value = []
|
||||
// mediaBtnstate.value = {}
|
||||
|
||||
init()
|
||||
distanceSchool()
|
||||
})
|
||||
|
||||
let {uniqid} = router.currentRoute.value.query
|
||||
let { uniqid } = router.currentRoute.value.query
|
||||
let pitchSchool = router.currentRoute.value.school || 0
|
||||
|
||||
import {copyToClipboard} from "@/utils/util.js"
|
||||
import { copyToClipboard, metersToKilometers, secondsToHoursMinutes } from "@/utils/util.js"
|
||||
|
||||
const {proxy} = getCurrentInstance()
|
||||
const { proxy } = getCurrentInstance()
|
||||
const store = useStore()
|
||||
|
||||
let imageShow = ref(false) // 查看大图弹窗的状态
|
||||
@ -399,10 +501,11 @@ let allCarouselsData = ref([])
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
distanceSchool()
|
||||
})
|
||||
|
||||
const init = () => {
|
||||
proxy.$get("/tenement/pc/api/apartment/details", {uniqid}).then(res => {
|
||||
proxy.$get("/tenement/pc/api/apartment/details", { uniqid }).then(res => {
|
||||
if (res.code != 200) {
|
||||
ElMessage.error(res["message"])
|
||||
return
|
||||
@ -431,8 +534,8 @@ const init = () => {
|
||||
qrcode.value = data["qrcode"]
|
||||
|
||||
handleAllCarouselsData()
|
||||
|
||||
document.title = data?.info?.title || '港校租房-品牌公寓详情'
|
||||
|
||||
document.title = data?.info?.title || "港校租房-品牌公寓详情"
|
||||
|
||||
nextTick(() => handleNavData())
|
||||
|
||||
@ -440,11 +543,11 @@ const init = () => {
|
||||
})
|
||||
}
|
||||
|
||||
let carouselsconfig = ref({lives: {}, videos: {}, attachment: {}})
|
||||
let carouselsconfig = ref({ lives: {}, videos: {}, attachment: {} })
|
||||
|
||||
// 处理 轮播图大图的索引 tab
|
||||
const handleAllCarouselsData = () => {
|
||||
let targetInfo = {...info.value}
|
||||
let targetInfo = { ...info.value }
|
||||
|
||||
let accumulativeTotal = 0 // 累计
|
||||
for (const key in carouselsconfig.value) {
|
||||
@ -530,13 +633,13 @@ const handleNavData = () => {
|
||||
// 处理点击nav 滚动事件
|
||||
const handleClickNav = value => {
|
||||
let scrollTop = eval(value).value.offsetTop + 136
|
||||
window.scrollTo({top: scrollTop, behavior: "smooth"})
|
||||
window.scrollTo({ top: scrollTop, behavior: "smooth" })
|
||||
}
|
||||
|
||||
let dualBrandList = ref([]) // 同品牌数据
|
||||
// 同品牌请求数据
|
||||
const dualBrandData = () => {
|
||||
proxy.$get("/tenement/pc/api/apartment", {token}).then(res => {
|
||||
proxy.$get("/tenement/pc/api/apartment", { token }).then(res => {
|
||||
if (res.code != 200) return
|
||||
let data = res.data
|
||||
dualBrandList.value = data.data
|
||||
@ -670,6 +773,95 @@ const indicateTypeState = () => {
|
||||
|
||||
// 公共跳转
|
||||
const publicJump = path => router.push(path)
|
||||
|
||||
// 获取 距离学校距离
|
||||
const distanceSchool = () => {
|
||||
api.detailsDistance({
|
||||
uniqid,
|
||||
istype: 2,
|
||||
}).then(res => {
|
||||
const data = res.data
|
||||
if (res.code != 200) return
|
||||
|
||||
let specialSchoolDistanceTarget = null
|
||||
let academyPitchIndexTarget = 0
|
||||
const school = pitchSchool || ""
|
||||
let annexSchoolOmitTarget = []
|
||||
data.forEach((element, index) => {
|
||||
element["distanceText"] = metersToKilometers(element.distance)
|
||||
element.list.forEach(ele => {
|
||||
ele["durationText"] = secondsToHoursMinutes(ele.duration, "chinese")
|
||||
ele["durationText2"] = secondsToHoursMinutes(ele.duration)
|
||||
ele["distanceText"] = metersToKilometers(ele.distance)
|
||||
if (Object.prototype.toString.call(ele.publictransport) === "[object Object]") {
|
||||
ele.publictransport["durationText"] = secondsToHoursMinutes(ele?.publictransport?.duration || 0, "chinese")
|
||||
ele.publictransport["durationText2"] = secondsToHoursMinutes(ele?.publictransport?.duration || 0)
|
||||
const segments = ele.publictransport["segments"]
|
||||
if (Array.isArray(segments)) {
|
||||
segments.forEach(e => {
|
||||
e["via_num"] = 1 + Math.floor(e.via_num)
|
||||
e["durationText"] = secondsToHoursMinutes(e.duration)
|
||||
e["distanceText"] = metersToKilometers(e.distance, "chinese")
|
||||
})
|
||||
}
|
||||
} else ele.publictransport = null
|
||||
})
|
||||
|
||||
if (school == element.id) {
|
||||
academyPitchIndexTarget = index
|
||||
const obj = element.list[0] || {}
|
||||
let toolText = "步行"
|
||||
if (Object.prototype.toString.call(obj.publictransport) === "[object Object]") toolText = "公交地铁"
|
||||
specialSchoolDistanceTarget = {
|
||||
alias: element.alias,
|
||||
distanceText: obj["distanceText"],
|
||||
durationText: obj.publictransport?.durationText2 || obj["durationText2"],
|
||||
toolText,
|
||||
}
|
||||
} else annexSchoolOmitTarget.push(element)
|
||||
})
|
||||
|
||||
if (specialSchoolDistanceTarget) annexSchoolOmitTarget = annexSchoolOmitTarget.slice(0, 4)
|
||||
else annexSchoolOmitTarget = annexSchoolOmitTarget.slice(0, 5)
|
||||
|
||||
annexSchoolOmit.value = annexSchoolOmitTarget
|
||||
annexSchoolList.value = data
|
||||
targetAcademyPitch.value = data[academyPitchIndexTarget]
|
||||
specialSchoolDistance.value = specialSchoolDistanceTarget
|
||||
academyPitchIndex.value = academyPitchIndexTarget
|
||||
|
||||
console.log("annexSchoolOmit", annexSchoolOmit)
|
||||
})
|
||||
}
|
||||
|
||||
let annexSchoolOmit = ref([]) // 附近院校 前面 7个 或者 6个的
|
||||
let annexSchoolList = ref([]) // 附近院校数据
|
||||
let academyPitchIndex = ref(0) // 附近学校距离选中院校 下标
|
||||
let targetAcademyPitch = ref({}) // 附近学校距离选中院校 数据
|
||||
let specialSchoolDistance = ref(null) // 特殊的 用户带有school参数 则需要特殊显示 学校距离
|
||||
|
||||
// 选择附近学校距离的学校下标
|
||||
const selectAcademyIndex = index => {
|
||||
academyPitchIndex.value = index || 0
|
||||
targetAcademyPitch.value = annexSchoolList.value[academyPitchIndex.value]
|
||||
}
|
||||
|
||||
// 选择附近学校距离的学校下标
|
||||
const selectIndex = id => {
|
||||
if (!id) id = pitchSchool
|
||||
const data = annexSchoolOmit.value || []
|
||||
data.forEach((element, index) => {
|
||||
if (element.id == id) {
|
||||
academyPitchIndex.value = index || 0
|
||||
targetAcademyPitch.value = annexSchoolList.value[academyPitchIndex.value]
|
||||
}
|
||||
})
|
||||
|
||||
// showDistance.value = true
|
||||
}
|
||||
|
||||
//显示详情
|
||||
let showDistance = ref(false)
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@ -1353,6 +1545,7 @@ const publicJump = path => router.push(path)
|
||||
}
|
||||
|
||||
.traffic-box {
|
||||
margin-top: 40px;
|
||||
padding: 0 30px;
|
||||
|
||||
.traffic-title {
|
||||
@ -1844,6 +2037,26 @@ a:-webkit-any-link {
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.dis-f {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.jus-x {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.jus-sp {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.al-item {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.pos-r {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.message-info {
|
||||
background: #000000;
|
||||
border-color: #000000;
|
||||
@ -1857,4 +2070,327 @@ a:-webkit-any-link {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.annex-school-box {
|
||||
margin: 20px 30px 0;
|
||||
cursor: pointer;
|
||||
|
||||
.annex-left {
|
||||
width: 100%;
|
||||
height: 101px;
|
||||
border: 1px solid #f2f2f2;
|
||||
border-radius: 12px 0 0 12px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
.annex-school-item {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.distance-item-value {
|
||||
height: 24px;
|
||||
padding: 0 8px;
|
||||
background-color: rgba(246, 246, 246, 1);
|
||||
border-radius: 29px;
|
||||
width: fit-content;
|
||||
|
||||
&.special {
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0.8) -14%, rgba(80, 227, 194, 0.8) 100%);
|
||||
}
|
||||
|
||||
.mileage {
|
||||
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
|
||||
font-weight: 650;
|
||||
font-size: 14px;
|
||||
color: #000000;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.tool-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.tool-time {
|
||||
font-size: 13px;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.marker-icon {
|
||||
margin: 9px 0 12px;
|
||||
}
|
||||
|
||||
.line-img {
|
||||
height: 2px;
|
||||
width: 724px;
|
||||
background-image: linear-gradient(to right, #d7d7d7 0%, #d7d7d7 50%, transparent 0%);
|
||||
background-size: 4px 2px;
|
||||
background-repeat: repeat-x;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
.annex-btn {
|
||||
width: 90px;
|
||||
height: 101px;
|
||||
font-size: 14px;
|
||||
color: #000000;
|
||||
border-radius: 0 12px 12px 0;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
.annex-btn-bj {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.annex-btn-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.distance-info-box {
|
||||
.title-box {
|
||||
font-weight: 650;
|
||||
font-size: 20px;
|
||||
color: #000000;
|
||||
|
||||
height: 70px;
|
||||
border-bottom: 1px solid #ebebeb;
|
||||
border-radius: 16px 16px 0 0;
|
||||
|
||||
.distance-arrow {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin: 0 28px;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.distance-info-data {
|
||||
.distance-info-left {
|
||||
width: 70px;
|
||||
flex-direction: column;
|
||||
border-right: 1px solid #ebebeb;
|
||||
box-sizing: content-box;
|
||||
|
||||
.distance-info-left-item {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
font-size: 14px;
|
||||
color: #555555;
|
||||
cursor: pointer;
|
||||
&.pitch {
|
||||
font-weight: 650;
|
||||
color: #000000;
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0.8) -14%, rgba(80, 227, 194, 0.8) 100%);
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
border-radius: 0 0 0 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.distance-info-right {
|
||||
padding: 30px 40px;
|
||||
.distance-header-box {
|
||||
color: #333333;
|
||||
font-weight: 650;
|
||||
font-size: 16px;
|
||||
margin-bottom: 30px;
|
||||
justify-content: space-between;
|
||||
.distance-header-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-color: #fddf6d;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
|
||||
.distance-header-img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.distance-header-hint {
|
||||
color: #a09e9e;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.academy-school-item {
|
||||
background-color: rgba(246, 246, 246, 1);
|
||||
border-radius: 12px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.academy-school-item-header {
|
||||
font-size: 16px;
|
||||
width: 670px;
|
||||
height: 65px;
|
||||
justify-content: space-between;
|
||||
padding-left: 22px;
|
||||
padding-right: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.academy-school-item-header .arrow-green {
|
||||
width: 7px;
|
||||
height: 12px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.academy-school-item-name {
|
||||
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
|
||||
font-weight: 650;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.academy-school-item-number {
|
||||
color: rgb(51, 51, 51);
|
||||
margin-left: 4px;
|
||||
font-weight: 400;
|
||||
font-family: "ArialMT", "Arial", sans-serif;
|
||||
}
|
||||
|
||||
.academy-school-item-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.academy-school-item-time {
|
||||
color: #000;
|
||||
font-weight: 650;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.academy-school-item-journey {
|
||||
border-top: 1px solid #ebebeb;
|
||||
padding-top: 22px;
|
||||
padding-left: 22px;
|
||||
padding-bottom: 30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.journey-item {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.journey-item:not(:last-of-type) {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.academy-school-item-journey::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 26.4px;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
display: block;
|
||||
background-image: linear-gradient(to bottom, #aaaaaa 50%, transparent 50%);
|
||||
background-size: 1px 4px; /* 控制虚线的宽度和间距 */
|
||||
}
|
||||
|
||||
.journey-item:first-of-type::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: -22px;
|
||||
left: 0;
|
||||
width: 9px;
|
||||
height: calc(50% + 22px);
|
||||
background-color: rgba(246, 246, 246, 1);
|
||||
}
|
||||
|
||||
.journey-item:last-of-type::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: -30px;
|
||||
left: 0;
|
||||
width: 9px;
|
||||
height: calc(50% + 30px);
|
||||
background-color: rgba(246, 246, 246, 1);
|
||||
}
|
||||
|
||||
.journey-item .circle {
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border-radius: 50%;
|
||||
background-color: #f6f6f6;
|
||||
border: 1px solid #797979;
|
||||
box-sizing: border-box;
|
||||
margin-right: 20px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.journey-item .journey-value {
|
||||
color: #333;
|
||||
font-size: 13px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.journey-item .journey-value.subway {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
.journey-item .journey-value.subway .subway-name {
|
||||
padding: 3.5px 11px;
|
||||
background-color: rgba(51, 51, 51, 1);
|
||||
border-radius: 10px;
|
||||
color: #fff;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.journey-item .journey-value.bus {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
.journey-item .journey-value.bus .bus-name {
|
||||
padding: 3.5px 11px;
|
||||
background-color: rgba(80, 227, 194, 0);
|
||||
box-sizing: border-box;
|
||||
border: 1px solid rgba(51, 51, 51, 1);
|
||||
border-radius: 10px;
|
||||
margin-right: 10px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.academy-school-hint {
|
||||
color: #a09e9e;
|
||||
font-size: 13px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-popper.is-light {
|
||||
border-radius: 10px !important;
|
||||
}
|
||||
</style>
|
||||
|
@ -295,7 +295,7 @@
|
||||
<span class="title">{{ location && location[housingInfo["data"] && housingInfo["data"]["info"].location.substring(0, 1)] }} > {{ location && location[housingInfo["data"] && housingInfo["data"]["info"].location] }}</span>
|
||||
</div>
|
||||
<div class="dis-f jus-x" style="margin-top: 15px;" v-if="housingInfo['data'] && housingInfo['data'].info.latitude">
|
||||
<div>
|
||||
<div style="margin-bottom: 20px;">
|
||||
<mapInfo
|
||||
:latlng="{
|
||||
longitude: housingInfo['data'].info.longitude * 1,
|
||||
@ -356,7 +356,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- <div class="distance-info-box pos-r" :class="{ 'show-distance-info-box': showDistance }" :style="{ height: showDistance ? `${50 * annexSchoolList.length + 70}px` : '0px' }"> -->
|
||||
<div class="distance-info-box pos-r" :style="{ height: `${50 * annexSchoolList.length + 70}px` }">
|
||||
<div class="title-box dis-f al-item jus-x">
|
||||
房源
|
||||
@ -368,7 +367,7 @@
|
||||
<div class="distance-info-left">
|
||||
<div class="distance-info-left-item flexcenter" :class="{ 'pitch': index == academyPitchIndex }" v-for="(item, index) in annexSchoolList" :key="index" @click="selectAcademyIndex(index)">{{ item.alias }}</div>
|
||||
</div>
|
||||
<el-scrollbar v-if="distanceList.length > 0" :style="{ height: 50 * annexSchoolList.length + 'px' }">
|
||||
<el-scrollbar :style="{ height: 50 * annexSchoolList.length + 'px' }">
|
||||
<div class="distance-info-right flex1">
|
||||
<div class="distance-header-box flexacenter">
|
||||
<div class="flexacenter">
|
||||
@ -804,6 +803,8 @@ import report from "@/components/public/report.vue"
|
||||
|
||||
import store from "@/store"
|
||||
|
||||
import { metersToKilometers, secondsToHoursMinutes } from "@/utils/util.js"
|
||||
|
||||
//页面类型
|
||||
let pageType = ref("")
|
||||
|
||||
@ -1250,6 +1251,7 @@ onBeforeUnmount(() => {
|
||||
const distanceSchool = () => {
|
||||
api.detailsDistance({
|
||||
uniqid: uniqid.value,
|
||||
istype: 1
|
||||
}).then(res => {
|
||||
const data = res.data
|
||||
if (res.code != 200) return
|
||||
@ -1329,37 +1331,6 @@ const selectIndex = id => {
|
||||
// showDistance.value = true
|
||||
}
|
||||
|
||||
// 转换 秒数
|
||||
const secondsToHoursMinutes = (seconds, type) => {
|
||||
// 计算小时数
|
||||
const hours = Math.floor(seconds / 3600)
|
||||
// 计算剩余的秒数
|
||||
const remainingSecondsAfterHours = seconds % 3600
|
||||
// 计算分钟数
|
||||
const minutes = Math.floor(remainingSecondsAfterHours / 60)
|
||||
// 计算剩余的秒数
|
||||
const remainingSeconds = remainingSecondsAfterHours % 60
|
||||
|
||||
let text = ""
|
||||
if (type == "chinese") {
|
||||
if (hours != 0) text += hours + "小时"
|
||||
if (minutes != 0) text += minutes + "分钟"
|
||||
if (remainingSeconds != 0 && minutes == 0) text += remainingSeconds + "秒"
|
||||
} else {
|
||||
if (hours != 0) text += hours + "h"
|
||||
if (minutes != 0) text += minutes + "min"
|
||||
if (remainingSeconds != 0 && minutes == 0) text += remainingSeconds + "s"
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
// 转换 米数
|
||||
const metersToKilometers = (input, type) => {
|
||||
let text = ""
|
||||
if (input >= 1000) text = (input / 1000).toFixed(1) + (type == "chinese" ? "公里" : "km")
|
||||
else text = input + (type == "chinese" ? "米" : "m")
|
||||
return text
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
img {
|
||||
@ -2787,7 +2758,7 @@ img {
|
||||
border-style: solid;
|
||||
border-color: rgba(242, 242, 242, 1);
|
||||
border-radius: 12px;
|
||||
margin-top: 20px;
|
||||
// margin-top: 20px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
/* ::-webkit-scrollbar {
|
||||
@ -2996,6 +2967,10 @@ img {
|
||||
color: #000000;
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0.8) -14%, rgba(80, 227, 194, 0.8) 100%);
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
border-radius: 0 0 0 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@ import { useRoute, useRouter } from "vue-router"
|
||||
import backToTop from "@/components/public/backToTop.vue"
|
||||
import store from "../../store/index"
|
||||
import api from "../../utils/api"
|
||||
import { ElMessage } from "element-plus"
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
@ -214,13 +215,27 @@ const getMoreScroll = () => {
|
||||
}
|
||||
|
||||
// 处理列表的点击收藏
|
||||
const handlecollect = item => {
|
||||
console.log("item", item)
|
||||
const targetData = JSON.parse(JSON.stringify(list.value))
|
||||
console.log("targetData", targetData);
|
||||
targetData.forEach(element => {
|
||||
console.log();
|
||||
});
|
||||
const handlecollect = uniqid => {
|
||||
console.log("uniqid", uniqid)
|
||||
let targetData = {}
|
||||
let targetIndex = 0
|
||||
let token = ""
|
||||
|
||||
list.value.forEach((element, index) => {
|
||||
if (element.uniqid == uniqid) {
|
||||
targetData = element
|
||||
targetIndex = index
|
||||
token = element.token || ""
|
||||
}
|
||||
})
|
||||
|
||||
api.apartmentCollection({ token }).then(res => {
|
||||
if (res.code != 200) return
|
||||
const data = res.data
|
||||
console.log("data", data)
|
||||
list.value[targetIndex]["iscollect"] = data.status
|
||||
ElMessage.success(res.message)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
Loading…
x
Reference in New Issue
Block a user