距离院校新样式

This commit is contained in:
A1300399510
2024-04-12 16:34:08 +08:00
parent 085317f790
commit 03bcc9fe9b
19 changed files with 393 additions and 82 deletions

View File

@@ -221,7 +221,7 @@
<div class="title-box">
所在楼层
</div>
<span class="text"> {{ housingInfo["data"] && housingInfo["data"].info.floor }}&nbsp </span>
<span class="text"> {{ housingInfo["data"] && housingInfo["data"].info.floor }}&nbsp; </span>
<span class="text" style="margin-left: 0;" v-if="housingInfo['data'] && housingInfo['data'].info.elevator && housingInfo['data'].info.elevator != -1">
<span style="color: #d7d7d7;">|</span>
@@ -306,32 +306,71 @@
</div>
</div>
</div>
<!-- -->
<div class="dis-f jus-x pos-r" v-if="distanceList[0] && distanceList[0].name && pageType != 3 && distanceList.length > 1">
<!-- <div class="distance-info-box pos-r" :class="{ 'show-distance-info-box': showDistance }" :style="{ 'height': showDistance ? `${70 + 42 + 82 * distanceList.length - 1}px` : '0px' }"> -->
<div class="distance-info-box pos-r show-distance-info-box" style="height: 611px;">
<div class="distance-info-box pos-r" :class="{ 'show-distance-info-box': showDistance }" :style="{ height: showDistance ? `${50 * annexSchoolList.length + 70}px` : '0px' }">
<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>
<el-scrollbar v-if="distanceList.length > 0" height="541px">
<div class="distance-info-data dis-f">
<div class="distance-info-left">
<div class="distance-info-left-item flexcenter pitch" v-for="(item, index) in 15" :key="index">中大</div>
</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 v-if="distanceList.length > 0" :style="{ height: 50 * annexSchoolList.length + 'px' }">
<div class="distance-info-right flex1">
<div class="distance-header-box flexacenter">
<div class="distance-header-icon flexcenter">
<img src="@/assets/img/detail/home.png" alt="" class="distance-header-img" />
<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>
<!-- <div class="dis-f al-item school-info" v-for="(item, index) in distanceList" :key="index" :class="{ 'mg-t-50': index > 0 }">
</el-scrollbar>
<!-- <div class="dis-f al-item school-info" v-for="(item, index) in distanceList" :key="index" :class="{ 'mg-t-50': index > 0 }">
<div class="icon-box dis-f al-item jus-x" :class="{ 'home-icon': item && item.address }">
<div class="line" v-show="index > 0"></div>
<img src="../assets/img/detail/school.png" class="icon" v-show="item && !item.address" alt="" />
@@ -345,31 +384,37 @@
</div>
</div>
</div> -->
</div>
</el-scrollbar>
</div>
<!-- </el-scrollbar> -->
</div>
<div class="distance-box dis-f jus-bet">
<div class="dis-f al-item" style="position: relative;" @click="setShowDistance">
<div class="dis-f al-item s-w-100" style="position: absolute;">
<div class="line-school-box dis-f al-item s-w-100" style="justify-content: space-around;">
<div v-for="(item, i) in distanceList" class="box-text" :key="item && item.id" v-show="i < 6 && item.id">
<!-- <div :class="{ 'far-s': item && item.recently_distance > 4 }" v-if="item && !item.address" class="text-c"> -->
<!-- <div :class="{ 'far-s': item && item.recently_distance > 4 }" v-if="item && !item.address" class="text-c">
{{ item && item.recently_distance }}km
</div> -->
<div class="distance-item-value flexacenter">
<div class="mileage">1.1km</div>
<img class="tool-icon" src="@/assets/img/detail/walk-icon.png" />
<!-- <img class="tool-icon" src="@/assets/img/detail/subway-icon.png" /> -->
<div class="tool-time">21min</div>
<div class="box-text" 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" />
<!-- subway-icon -->
<div class="tool-time">{{ specialSchoolDistance.durationText }}</div>
</div>
<div class="dis-f jus-x" v-if="item && !item.address">
<div class="dis-f jus-x">
<img src="../assets/img/detail/markIcon.svg" class="marker-icon" alt="" />
<!-- <img src="../assets/img/detail/markIcon.svg" v-if="item && item.recently_distance <= 4" class="marker-icon" alt="" /> -->
<!-- <img src="../assets/img/detail/markIconNot.svg" v-if="item && item.recently_distance > 4" class="marker-icon" alt="" /> -->
</div>
<!-- <div :class="{ 'far-s': item && item.recently_distance > 4 }" class="text-c" v-if="item && !item.address">{{ item && item.alias }}</div> -->
<div class="text-c" v-if="item && !item.address">{{ item && item.alias }}</div>
<div class="text-c">{{ specialSchoolDistance.alias }}</div>
</div>
<div v-for="(item, i) in annexSchoolOmit" class="box-text" :key="i">
<div class="distance-item-value flexacenter">
<div class="mileage">{{ item.distanceText }}</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].durationText2 }}</div>
</div>
<div class="dis-f jus-x">
<img src="../assets/img/detail/markIcon.svg" class="marker-icon" alt="" />
</div>
<div class="text-c">{{ item.alias }}</div>
</div>
</div>
</div>
@@ -534,7 +579,7 @@
<div>
<div class="body-maxWidth" v-show="recommendListData.length > 0">
<div ref="gridContainer" style="margin-top: 15px; display: flex; flex-wrap: wrap; margin-bottom: 50px; width: 876px;">
<indexWaterfallBox v-for="(items, i) in recommendListData" :data="items" :key="items.id"> </indexWaterfallBox>
<indexWaterfallBox v-for="items in recommendListData" :data="items" :key="items.id"> </indexWaterfallBox>
</div>
</div>
<div class="body-maxWidth" v-if="publisherList.length > 0">
@@ -808,7 +853,6 @@ let moveImageList = type => {
if (type === "right" && imgScrollBottom()) return
if ((type === "left" && imgListTab.value === 0) || (imgListTab.value === imageLIstLeft.value.length - 1 && type === "right")) return
type === "left" ? imgListTab.value-- : imgListTab.value++
// console.log(imageLIstLeft.value[imgListTab.value])
setOffsetWidth(imageLIstLeft.value[imgListTab.value], type)
}
//设置滚动
@@ -845,7 +889,6 @@ let setImageWidth = num => {
clientWidth.value = imageList.value.clientWidth
scrollWidth.value = imageList.value.scrollWidth
}
// console.log(imageLIstLeft.value)
}
//学校地址数据
@@ -994,7 +1037,6 @@ let getHousingInfo = () => {
uniqid: uniqid.value,
uid: store.state.user.uid,
}).then(res => {
// console.log(res)
if (res.code === 200) {
const data = res.data
housingInfo["data"] = res.data
@@ -1032,7 +1074,6 @@ let setOperation = () => {
api.operation({
token: housingInfo["data"].token,
}).then(res => {
// console.log(res)
if (res.code === 200) {
housingInfo["data"].info.count_fav = res.data.count
housingInfo["data"].isfav = res.data.status
@@ -1119,7 +1160,6 @@ let recommendList = () => {
pagevalue: pagevalue.value,
token: housingInfo["data"].token,
}).then(res => {
// console.log(res)
if (res.code === 200) {
if (res.data.data && res.data.data.length >= 30) {
loadMore.value = true
@@ -1160,7 +1200,6 @@ let getPublisherList = () => {
limit: 30,
token: housingInfo["data"].token,
}).then(res => {
// console.log(res)
if (res.code === 200) {
if (res.data.length >= 30) {
loadMore.value = true
@@ -1184,21 +1223,25 @@ let masonryInstance = null
let router = useRouter()
let route = useRoute()
let pitchSchool = "" // 筛选页面带过来的 学校ID
watch(route, () => {
let { id } = router.currentRoute.value.query
uniqid.value = id
pitchSchool = route.query["school"] || ""
pageType.value = housingInfo["data"]["info"].intermediary === 1 ? 2 : housingInfo["data"]["info"].intermediary === 6 ? 3 : 1 //1个人 2中介 3求房源
publisherList.value = []
recommendListData.value = []
getHousingInfo()
// distanceSchool()
distanceSchool()
})
onMounted(() => {
let { id } = router.currentRoute.value.query
uniqid.value = id
pitchSchool = route.query["school"] || ""
getHousingInfo()
// distanceSchool()
distanceSchool()
masonryInstance = new Masonry(gridContainer.value, {
itemSelector: ".item",
gutter: 10,
@@ -1218,9 +1261,101 @@ const distanceSchool = () => {
api.detailsDistance({
uniqid: uniqid.value,
}).then(res => {
console.log("res", 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
})
}
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 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 {
@@ -2536,7 +2671,7 @@ img {
top: 130px;
z-index: 666;
width: 100%;
max-height: 610px;
// max-height: 610px;
transition: all 0.2s linear;
overflow: hidden;
@@ -2832,23 +2967,30 @@ img {
width: 70px;
flex-direction: column;
border-right: 1px solid #ebebeb;
box-sizing: content-box;
.distance-info-left-item {
width: 69px;
width: 100%;
height: 50px;
box-sizing: content-box;
font-size: 16px;
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%);
}
}
}
.distance-info-right {
padding: 30px 40px;
.distance-header-box {
color: #333333;
font-weight: 650;
font-size: 20px;
margin-bottom: 30px;
justify-content: space-between;
.distance-header-icon {
width: 36px;
height: 36px;
@@ -2861,6 +3003,162 @@ img {
height: 24px;
}
}
.distance-header-hint {
color: #a09e9e;
font-size: 15px;
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: 18px;
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: 20px;
height: 20px;
margin-right: 6px;
}
.academy-school-item-time {
color: #000;
font-weight: 650;
font-size: 18px;
}
.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: 15px;
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: 15px;
margin-bottom: 20px;
}
}
}

View File

@@ -6,7 +6,7 @@
<div class="dis-f jus-x al-item">
<div class="body-maxWidth mg-t-35">
<div v-show="dataList.data && dataList.data.length > 0" ref="list">
<biserialItem v-for="(item, i) in pageList" :key="i" :item="item"></biserialItem>
<biserialItem v-for="(item, i) in pageList" :key="i" :item="item" :school="school"></biserialItem>
</div>
<div class="dis-f jus-x no-list-box al-item" v-show="dataList.data && dataList.data.length === 0">
<noList hint-text-two="建议放宽筛选条件"></noList>
@@ -15,7 +15,7 @@
<!-- 其他附近房源 -->
<div v-if="moreList.length != 0" class="other-nearby-listings-box flexcenter">没有找到更多房源为您推荐其他附近房源</div>
<div style="width: 1200px;" ref="moreShowList">
<biserialItem v-for="(item, i) in moreList" :key="i" :item="item"></biserialItem>
<biserialItem v-for="(item, i) in moreList" :key="i" :item="item" :school="school"></biserialItem>
</div>
</div>
</div>
@@ -58,6 +58,9 @@ let loading = ref(true)
let loadingText = ref(" 下拉加载更多 ")
provide("count", dataCount)
let school = ref("") // 单独提前 选中的学校id 需要 在跳转页面中使用
//轮播
// let bannerList = reactive({ data: [] })
// let banner = () => {
@@ -92,6 +95,8 @@ let getDataList = data => {
...data,
}
school.value = postData["school"] || ""
moreList.value = []
window.removeEventListener("scroll", getMoreScroll, true)

View File

@@ -6,7 +6,7 @@
<div class="dis-f jus-x al-item">
<div class="body-maxWidth mg-t-35">
<div v-show="dataList.data && dataList.data.length > 0" style="width: 1200px;" ref="list">
<biserialItem v-for="(item, i) in pageList" :key="i" :item="item"></biserialItem>
<biserialItem v-for="(item, i) in pageList" :key="i" :item="item" :school="school"></biserialItem>
</div>
<div class="dis-f jus-x no-list-box al-item" v-show="dataList.data && dataList.data.length === 0">
<noList hint-text-two="建议放宽筛选条件"></noList>
@@ -15,7 +15,7 @@
<!-- 其他附近房源 -->
<div v-if="moreList.length != 0" class="other-nearby-listings-box flexcenter">没有找到更多房源为您推荐其他附近房源</div>
<div style="width: 1200px;" ref="moreShowList">
<biserialItem v-for="(item, i) in moreList" :key="i" :item="item"></biserialItem>
<biserialItem v-for="(item, i) in moreList" :key="i" :item="item" :school="school"></biserialItem>
</div>
</div>
</div>
@@ -61,6 +61,8 @@ let pageList = ref([])
let seachSelectData = reactive({ data: {} })
let loading = ref(true)
let loadingText = ref(" 下拉加载更多 ")
let school = ref("") // 单独提前 选中的学校id 需要 在跳转页面中使用
provide("count", dataCount)
const { proxy } = getCurrentInstance()
@@ -77,16 +79,6 @@ let setSeachSelectData = (data, noMask = false) => {
getDataList(seachSelectData.data)
}
//轮播
// let bannerList = reactive({ data: [] })
// let banner = () => {
// api.banner().then(res => {
// if (res.code === 200) {
// bannerList.data = res.data
// }
// })
// }
//获取搜索数据
let getDataList = data => {
loadingText.value = " 加载中..... "
@@ -97,6 +89,8 @@ let getDataList = data => {
intermediary: 0,
...data,
}
school.value = postData["school"] || ""
if (!postData["orderby"]) postData["orderby"] = "default"
moreList.value = []