427 lines
10 KiB
Vue
427 lines
10 KiB
Vue
<script>
|
|
import {getProvince, getProvinceGoods, getProvinceList} from "@/api/product";
|
|
|
|
export default {
|
|
name: "landMark",
|
|
data() {
|
|
return {
|
|
webUrl: this.$VUE_APP_RESOURCES_URL,
|
|
keyword: '',
|
|
page: 1,
|
|
navList: [],
|
|
navIndex: 0,
|
|
mapData: null,
|
|
mapLocations: [],
|
|
goods: [],
|
|
directionClass: ['', 'up', 'right', 'down', 'left'],
|
|
}
|
|
},
|
|
computed: {
|
|
topBoxBgColor() {
|
|
return this.navList.length > 0 ? this.navList[this.navIndex]['backgroundColor'] : '#FFFFFF';
|
|
},
|
|
viewBoxBgColor() {
|
|
return this.mapData?.backgroundColor || '#FFFFFF';
|
|
},
|
|
scale() {
|
|
return 718 / (this.mapData?.mapImageWidth || 1);
|
|
}
|
|
},
|
|
onLoad() {
|
|
this.getNavList();
|
|
},
|
|
onReachBottom() {
|
|
this.page++;
|
|
this.fetchGoods();
|
|
},
|
|
methods: {
|
|
getNavList() {
|
|
getProvinceList().then(({data}) => {
|
|
this.navList = data;
|
|
this.changeNav(this.navIndex);
|
|
});
|
|
},
|
|
|
|
search() {
|
|
this.page = 1;
|
|
this.fetchGoods();
|
|
},
|
|
|
|
changeNav(index) {
|
|
this.navIndex = index;
|
|
this.page = 1;
|
|
this.getMap();
|
|
this.fetchGoods();
|
|
},
|
|
|
|
getMap() {
|
|
const id = this.navList[this.navIndex]['id']
|
|
getProvince(id).then(({data}) => {
|
|
this.mapData = data;
|
|
this.mapLocations = data.mapLocations;
|
|
this.calcPosition();
|
|
});
|
|
},
|
|
|
|
// 计算位置
|
|
calcPosition() {
|
|
this.mapLocations?.forEach(item => {
|
|
item.gx = item.x * this.scale;
|
|
item.gy = item.y * this.scale;
|
|
})
|
|
},
|
|
|
|
fetchGoods() {
|
|
const id = this.navList[this.navIndex]['id']
|
|
getProvinceGoods(id, this.keyword, this.page).then(({data}) => {
|
|
if (this.page === 1) this.goods = [];
|
|
for (let i = 0; i < data.length; i++) {
|
|
this.goods.push(data[i]);
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<view class="pkg-product-land-mark" v-if="mapData">
|
|
<view class="top-box" :style="{'backgroundColor':topBoxBgColor}">
|
|
<view class="view-box">
|
|
<view class="search-box flex ai-center">
|
|
<input type="text" v-model="keyword" placeholder="搜索商品" placeholder-style="color:#999"
|
|
@confirm="search()"/>
|
|
<image :src="webUrl+'/20231223183627184005.png'" mode="scaleToFill" style="width:30rpx;height:30rpx"/>
|
|
</view>
|
|
|
|
<view class="map-box">
|
|
<image class="img-map" :src="mapData.mapImage" mode="widthFix"/>
|
|
|
|
<view class="item" :style="{'left':item.gx+'rpx','top':item.gy+'rpx'}" v-for="item in mapLocations" @click="$global.navToGoods(item.productId)">
|
|
<view class="round">
|
|
<view class="line" :class="'line-'+directionClass[item.labelDirection]"></view>
|
|
</view>
|
|
<view class="label flex ai-end" :class="'label-'+directionClass[item.labelDirection]">
|
|
<image class="cover flex-0" :src="item.mapImage" mode="scaleToFill" v-if="item.labelDirection===4"/>
|
|
<view class="title flex ai-center">{{ item.mapTitle }}</view>
|
|
<image class="cover flex-0" :src="item.mapImage" mode="scaleToFill" v-if="item.labelDirection!==4"/>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="nav flex">
|
|
<view class="flex flex-0 ai-center" :class="{'active': navIndex===index}" v-for="(item,index) in navList"
|
|
:key="index" @click="changeNav(index)">{{ item.provinceName }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="main-box" v-if="mapData.recommended.storeImage"
|
|
@click="$global.navToGoods(mapData.recommended.productId)">
|
|
<image class="bg-main" :src="mapData.recommended.storeImage" mode="scaleToFill"/>
|
|
<view class="box-mask flex flex-col jc-end">
|
|
<view class="one-t bold">{{ mapData.recommended.title }}</view>
|
|
<view class="more-t">{{ mapData.recommended.description }}</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="list-box flex flex-wrap">
|
|
<view class="item" v-for="item in goods" :key="item.id" @click="$global.navToGoods(item.productId)">
|
|
<image :src="item.storeImage" mode="scaleToFill"/>
|
|
<view class="content flex flex-col jc-between">
|
|
<view class="more-t bold">{{ item.title }}</view>
|
|
<view class="flex jc-between ai-center">
|
|
<text class="price">¥{{ item.price }}</text>
|
|
<image class="btn" :src="webUrl+'/20231114151028082368.png'" mode="scaleToFill"/>
|
|
<!-- <view class="btn flex jc-center ai-center">立即购买</view>-->
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<image class="img-nodata" :src="webUrl+'/20231023131208675588.png'" mode="scaleToFill"
|
|
v-if="goods.length===0"/>
|
|
</view>
|
|
</template>
|
|
|
|
<style scoped lang="less">
|
|
.pkg-product-land-mark {
|
|
background: #F7F3ED;
|
|
|
|
image {
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.top-box {
|
|
padding: 32rpx 0 20rpx;
|
|
|
|
.view-box {
|
|
position: relative;
|
|
margin: 0 16rpx;
|
|
border-radius: 40rpx;
|
|
overflow: hidden;
|
|
|
|
.search-box {
|
|
position: absolute;
|
|
top: 20rpx;
|
|
left: 34rpx;
|
|
width: 650rpx;
|
|
height: 64rpx;
|
|
padding: 0 32rpx;
|
|
box-sizing: border-box;
|
|
border-radius: 32rpx;
|
|
background: #FFFFFF;
|
|
z-index: 10;
|
|
|
|
input {
|
|
width: 100%;
|
|
height: 100%;
|
|
line-height: 64rpx;
|
|
font-size: 28rpx;
|
|
}
|
|
}
|
|
|
|
.map-box {
|
|
position: relative;
|
|
width: 718rpx;
|
|
|
|
.img-map {
|
|
width: 718rpx;
|
|
height: auto;
|
|
}
|
|
|
|
.item {
|
|
position: absolute;
|
|
|
|
.round {
|
|
width: 8rpx;
|
|
height: 8rpx;
|
|
border-radius: 50%;
|
|
box-shadow: 0 0 0 8rpx rgba(225, 38, 65, .4);;
|
|
background: #E12641;
|
|
}
|
|
|
|
.line {
|
|
position: relative;
|
|
border: 2rpx solid #E12641;
|
|
}
|
|
|
|
.line-up {
|
|
left: 50%;
|
|
transform: translate(-50%, -100%);
|
|
width: 0;
|
|
height: 30rpx;
|
|
}
|
|
|
|
.line-right {
|
|
top: 50%;
|
|
transform: translate(0, -50%);
|
|
width: 30rpx;
|
|
height: 0;
|
|
}
|
|
|
|
.line-down {
|
|
left: 50%;
|
|
transform: translate(-50%, 0);
|
|
width: 0;
|
|
height: 30rpx;
|
|
}
|
|
|
|
.line-left {
|
|
top: 50%;
|
|
transform: translate(-100%, -50%);
|
|
width: 30rpx;
|
|
height: 0;
|
|
}
|
|
|
|
.label {
|
|
position: relative;
|
|
|
|
.cover {
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
box-sizing: border-box;
|
|
border: 6rpx solid #E12641;
|
|
border-radius: 50%;
|
|
z-index: 20;
|
|
}
|
|
|
|
.title {
|
|
height: 32rpx;
|
|
box-sizing: border-box;
|
|
margin-bottom: 10rpx;
|
|
padding: 0 16rpx;
|
|
background: #E12641;
|
|
color: #FFFFFF;
|
|
font-size: 22rpx;
|
|
line-height: 32rpx;
|
|
white-space: nowrap;
|
|
z-index: 10;
|
|
}
|
|
}
|
|
|
|
.label-up {
|
|
top: -80rpx;
|
|
left: -50%;
|
|
|
|
.title {
|
|
margin-right: -9rpx;
|
|
border-radius: 20rpx 0 0 20rpx;
|
|
}
|
|
}
|
|
|
|
.label-right {
|
|
top: -40rpx;
|
|
left: 32rpx;
|
|
|
|
.title {
|
|
margin-right: -9rpx;
|
|
border-radius: 20rpx 0 0 20rpx;
|
|
}
|
|
}
|
|
|
|
.label-down {
|
|
left: -50%;
|
|
|
|
.title {
|
|
margin-right: -9rpx;
|
|
border-radius: 20rpx 0 0 20rpx;
|
|
}
|
|
}
|
|
|
|
.label-left {
|
|
left: -100%;
|
|
transform: translate(-30rpx, -40rpx);
|
|
|
|
.title {
|
|
margin-left: -9rpx;
|
|
border-radius: 0 20rpx 20rpx 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.nav {
|
|
padding: 30rpx 20rpx 0;
|
|
overflow-x: scroll;
|
|
|
|
view {
|
|
height: 52rpx;
|
|
box-sizing: border-box;
|
|
padding: 0 18rpx;
|
|
border: 4rpx solid transparent;
|
|
color: #FFFFFF;
|
|
font-size: 32rpx;
|
|
}
|
|
|
|
.active {
|
|
border-color: #FFFFFF;
|
|
border-radius: 26rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.main-box {
|
|
position: relative;
|
|
width: 718rpx;
|
|
height: 360rpx;
|
|
margin: 24rpx 16rpx;
|
|
border-radius: 16rpx;
|
|
overflow: hidden;
|
|
|
|
.bg-main {
|
|
width: 718rpx;
|
|
height: 360rpx;
|
|
}
|
|
|
|
.box-mask {
|
|
position: absolute;
|
|
left: 0;
|
|
bottom: 0;
|
|
width: 100%;
|
|
height: 200rpx;
|
|
box-sizing: border-box;
|
|
padding: 20rpx 16rpx 16rpx;
|
|
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000000 100%);
|
|
color: #FFFFFF;
|
|
|
|
.one-t {
|
|
margin-bottom: 16rpx;
|
|
font-size: 46rpx;
|
|
line-height: 52rpx;
|
|
}
|
|
|
|
.more-t {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
padding-top: 10rpx;
|
|
border-top: 1rpx solid #FFFFFF;
|
|
font-size: 28rpx;
|
|
line-height: 32rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.list-box {
|
|
margin-top: 24rpx;
|
|
padding: 0 16rpx 34rpx;
|
|
|
|
.item {
|
|
width: 234rpx;
|
|
height: 380rpx;
|
|
margin-right: 8rpx;
|
|
margin-bottom: 24rpx;
|
|
border-radius: 12rpx;
|
|
background: #FFFFFF;
|
|
overflow: hidden;
|
|
|
|
image {
|
|
width: 234rpx;
|
|
height: 234rpx;
|
|
}
|
|
|
|
.content {
|
|
height: 122rpx;
|
|
margin: 6rpx 6rpx 18rpx;
|
|
|
|
.more-t {
|
|
font-size: 28rpx;
|
|
line-height: 36rpx;
|
|
color: #333333;
|
|
}
|
|
|
|
.price {
|
|
font-size: 28rpx;
|
|
line-height: 36rpx;
|
|
color: #DC1616;
|
|
}
|
|
|
|
.btn {
|
|
width: 118rpx;
|
|
height: 42rpx;
|
|
//background: linear-gradient(180deg, #EFEDC7 0%, #EAC94B 100%);
|
|
//border-radius: 4rpx;
|
|
//color: #764A00;
|
|
//font-size: 24rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.item:nth-child(3n) {
|
|
margin-right: 0;
|
|
}
|
|
}
|
|
|
|
.img-nodata {
|
|
position: relative;
|
|
top: 0;
|
|
left: 50%;
|
|
transform: translate(-50%, 0);
|
|
width: 352rpx;
|
|
height: 338rpx;
|
|
margin-bottom: 60rpx;
|
|
}
|
|
}
|
|
</style> |