<template>
|
<view class="index-page">
|
<view class="top-gradient-bg" :style="{ backgroundImage: 'url(' + backgroundImage + ')' }"></view>
|
<view class="top-hero">
|
<view :style="{ height: statusbarHeight + 'px' }"></view>
|
<view class="hero-bar" :style="{ height: navHeight + 'px' }">
|
<view class="location-chip" @tap="handleLocation">
|
<image src="/static/icon/home1_ic_location@2x.png" mode="aspectFit"></image>
|
<text>{{ currentAddress }}</text>
|
<u-icon name="arrow-right" size="14" color="#ffffff"></u-icon>
|
</view>
|
</view>
|
|
<view class="search-box" @tap="goStoragePage">
|
<image src="/static/icon/home_ic_search@2x.png" mode="aspectFit"></image>
|
<text class="search-text">搜索寄存点名称或地址</text>
|
</view>
|
|
<view class="banner-card hero-banner">
|
<swiper class="banner-swiper" :indicator-dots="true" :autoplay="true" :interval="3000" :duration="500" :circular="true" :indicator-color="'rgba(255, 255, 255, 0.5)'" :indicator-active-color="'#ffffff'">
|
<swiper-item v-for="(item, index) in bannerList" :key="index">
|
<image class="banner-image" :src="item.imgurlFull" mode="aspectFill"></image>
|
</swiper-item>
|
</swiper>
|
</view>
|
</view>
|
|
<view class="page-body">
|
<view class="service-grid">
|
<view class="service-card deposit-card" @click="jumpxiadan">
|
<image class="service-image" src="/static/image/home_ic_jicun@2x.png" mode="aspectFit"></image>
|
</view>
|
<view class="service-card retrieve-card">
|
<image class="service-image" src="/static/image/home_ic_qujian@2x.png" mode="aspectFit"></image>
|
</view>
|
</view>
|
|
<view class="notice-card">
|
<view class="notice-icon-wrap">
|
<image src="/static/icon/home_ic_daizhifu@2x.png" mode="aspectFit"></image>
|
</view>
|
<view class="notice-copy">
|
<text class="notice-title">待支付</text>
|
<text class="notice-text">请在 10 分钟内完成支付,超时订单将自动取消</text>
|
</view>
|
</view>
|
|
<view class="section-head">
|
<text class="section-title">推荐寄存点</text>
|
<text class="section-more" @click="jumpJC">查看更多</text>
|
</view>
|
|
<view class="recommend-list">
|
<view v-for="(item, index) in pointList" :key="index" class="point-card" @click="goStoragePage(item)">
|
<view class="point-thumb">
|
<image class="point-thumb-image" :src="item.coverImg" mode="widthFix"></image>
|
</view>
|
<view class="point-main">
|
<view class="point-head">
|
<text class="point-name">{{ item.name }}</text>
|
<text class="point-distance">{{ item.distanceText }}</text>
|
</view>
|
<view class="point-address">
|
<image src="/static/icon/home_ic_location3@2x.png" mode="aspectFit"></image>
|
<text>{{ item.address }}</text>
|
</view>
|
<text class="point-time">{{ item.shopHours }}</text>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<view class="location-toast" v-if="!latitude">
|
<view class="toast-copy">
|
<text class="toast-title">未授权定位</text>
|
<text class="toast-text">我们无法获得您当前位置信息为您推荐附近寄存点</text>
|
</view>
|
<view class="toast-btn" @click="handleLocation">开启定位</view>
|
</view>
|
</view>
|
</template>
|
|
<script>
|
import { mapState } from 'vuex'
|
|
export default {
|
computed: {
|
...mapState(['navHeight', 'statusbarHeight', 'address', 'latitude', 'cityId', 'longitude']),
|
currentAddress() {
|
return this.address && this.address !== '定位中' ? this.address : '获取定位'
|
}
|
},
|
data() {
|
return {
|
backgroundImage: require('@/static/image/bg_home@2x.png'),
|
bannerList: [],
|
pointList: [],
|
page: 1,
|
isRequest: true
|
}
|
},
|
async onLoad() {
|
await this.$onLaunched
|
await this.getBannerList()
|
await this.getNearbyShopList()
|
},
|
onReachBottom() {
|
this.getNearbyShopList()
|
},
|
methods: {
|
jumpxiadan() {
|
uni.navigateTo({
|
url: '/pages/luggage-storage/luggage-storage'
|
})
|
},
|
async getBannerList() {
|
const res = await this.$u.api.getBannerList({ position: 0 })
|
if (res.code === 200) {
|
this.bannerList = res.data || []
|
}
|
},
|
async getNearbyShopList() {
|
if (!this.isRequest) return;
|
const res = await this.$u.api.getNearbyShopList({
|
capacity: 10,
|
page: this.page,
|
model: {
|
latitude: this.latitude,
|
longitude: this.longitude,
|
cityId: this.cityId,
|
sortType: 1
|
}
|
})
|
if (res.code === 200) {
|
this.pointList = res.data.records || []
|
this.page++
|
if (res.data.total <= this.pointList.length) {
|
this.isRequest = false
|
}
|
}
|
},
|
jumpJC() {
|
uni.navigateTo({
|
url: '/pages/storage-point/storage-point'
|
})
|
},
|
handleLocation() {
|
var that = this;
|
uni.openSetting({
|
success: (res) => {
|
if (res.authSetting['scope.userLocation']) {
|
that.positioning()
|
}
|
}
|
});
|
},
|
// 定位
|
positioning() {
|
var that = this;
|
uni.getLocation({
|
type: 'gcj02',
|
highAccuracyExpireTime: 3000,
|
isHighAccuracy: true,
|
success: function (addr) {
|
const locParam = { latitude: addr.latitude, longitude: addr.longitude };
|
const qqmapsdk = new QQMapWX({
|
key: 'WE3BZ-HN6WS-ONDOH-62QCV-MNL6F-5NFNE'
|
});
|
qqmapsdk.reverseGeocoder({
|
locParam,
|
success: async function(res) {
|
console.log(res, '==================获取地址');
|
let info = res.result;
|
locParam.province = info.address_component.province;
|
locParam.city = info.address_component.city;
|
locParam.area = info.address_component.district;
|
locParam.street = info.address_component.street;
|
var ta = info.address || '地址获取失败' ;
|
if(info.formatted_addresses && info.formatted_addresses.recommend){
|
ta =info.formatted_addresses.recommend
|
}
|
locParam.address = ta
|
const resCity = await that.$u.api.getCityByName({ cityName: locParam.city })
|
if (resCity.code === 200) {
|
locParam.cityId = resCity.data.id
|
}
|
that.$store.commit('setPosition',locParam)
|
that.$isResolve()
|
},
|
fail: (err) => {
|
that.$isResolve()
|
}
|
});
|
}
|
});
|
},
|
goStoragePage() {
|
uni.navigateTo({
|
url: '/pages/storage-point/storage-point'
|
})
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.index-page {
|
position: relative;
|
padding-bottom: 30rpx;
|
}
|
|
.top-gradient-bg {
|
position: absolute;
|
left: 0;
|
top: 0;
|
width: 100%;
|
height: 420rpx;
|
background-repeat: no-repeat;
|
background-size: 100% 100%;
|
z-index: 0;
|
}
|
|
.top-hero {
|
position: relative;
|
z-index: 1;
|
padding: 0 30rpx 0 30rpx;
|
box-sizing: border-box;
|
}
|
|
.hero-banner {
|
margin-top: 30rpx;
|
}
|
|
.hero-bar {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
|
.location-chip {
|
display: flex;
|
align-items: center;
|
gap: 6rpx;
|
max-width: 360rpx;
|
image {
|
flex-shrink: 0;
|
width: 36rpx;
|
height: 36rpx;
|
margin-right: 8rpx;
|
}
|
text {
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
font-weight: 500;
|
font-size: 32rpx;
|
color: #FFFFFF;
|
}
|
}
|
|
.search-box {
|
height: 72rpx;
|
margin-top: 10rpx;
|
padding: 0 22rpx;
|
border-radius: 16rpx;
|
background: #ffffff;
|
display: flex;
|
align-items: center;
|
gap: 14rpx;
|
image {
|
width: 28rpx;
|
height: 28rpx;
|
}
|
}
|
|
.search-text {
|
font-size: 26rpx;
|
color: #b6bcc8;
|
}
|
|
.page-body {
|
position: relative;
|
z-index: 1;
|
padding: 18rpx 22rpx 0;
|
}
|
|
.banner-card {
|
position: relative;
|
height: 320rpx;
|
padding: 0;
|
border-radius: 20rpx;
|
overflow: hidden;
|
box-sizing: border-box;
|
}
|
|
.banner-swiper {
|
height: 100%;
|
}
|
|
.banner-swiper ::deep .uni-swiper-dot {
|
width: 30rpx;
|
height: 6rpx;
|
border-radius: 3rpx;
|
}
|
|
.banner-swiper ::deep .uni-swiper-dot-active {
|
background-color: #ffffff;
|
}
|
|
.banner-swiper swiper-item {
|
height: 100%;
|
}
|
|
.banner-image {
|
width: 100%;
|
height: 100%;
|
}
|
|
.service-grid {
|
display: grid;
|
grid-template-columns: repeat(2, 1fr);
|
gap: 18rpx;
|
margin-top: 18rpx;
|
}
|
|
.service-card {
|
width: 334rpx;
|
height: 176rpx;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
box-sizing: border-box;
|
}
|
|
.service-image {
|
width: 334rpx;
|
height: 176rpx;
|
}
|
|
.notice-card {
|
display: flex;
|
align-items: center;
|
margin-top: 30rpx;
|
padding: 30rpx;
|
box-sizing: border-box;
|
border-radius: 18rpx;
|
background: linear-gradient(135deg, #25a2f5 0%, #1eaef4 100%);
|
overflow: hidden;
|
}
|
|
.notice-icon-wrap {
|
flex-shrink: 0;
|
width: 76rpx;
|
height: 76rpx;
|
border-radius: 38rpx;
|
background: rgba(255, 255, 255, 0.14);
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.notice-icon {
|
width: 38rpx;
|
height: 38rpx;
|
}
|
|
.notice-copy {
|
margin-left: 18rpx;
|
min-width: 0;
|
}
|
|
.notice-title {
|
display: block;
|
font-weight: bold;
|
font-size: 30rpx;
|
color: #FFFFFF;
|
}
|
|
.notice-text {
|
display: block;
|
margin-top: 6rpx;
|
font-weight: 400;
|
font-size: 24rpx;
|
color: rgba(255,255,255,0.85);
|
}
|
|
.section-head {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
margin-top: 40rpx;
|
}
|
|
.section-title {
|
font-size: 36rpx;
|
font-weight: 700;
|
color: #202020;
|
}
|
|
.section-more {
|
font-size: 24rpx;
|
color: #a4acb8;
|
}
|
|
.section-more::after {
|
content: ' >';
|
}
|
|
.recommend-list {
|
margin-top: 32rpx;
|
}
|
|
.point-card {
|
display: flex;
|
gap: 18rpx;
|
padding: 24rpx;
|
margin-bottom: 20rpx;
|
border-radius: 18rpx;
|
background: #f4f7fc;
|
}
|
|
.point-thumb {
|
position: relative;
|
flex-shrink: 0;
|
width: 132rpx;
|
height: 104rpx;
|
border-radius: 12rpx;
|
overflow: hidden;
|
}
|
|
.point-thumb-image {
|
width: 100%;
|
height: 100%;
|
}
|
|
.point-main {
|
flex: 1;
|
min-width: 0;
|
}
|
|
.point-head {
|
display: flex;
|
align-items: flex-start;
|
justify-content: space-between;
|
gap: 10rpx;
|
}
|
|
.point-name {
|
flex: 1;
|
font-size: 32rpx;
|
font-weight: 600;
|
line-height: 1.35;
|
color: #222222;
|
}
|
|
.point-distance {
|
flex-shrink: 0;
|
font-size: 24rpx;
|
color: #a6aebb;
|
}
|
|
.point-address {
|
display: flex;
|
align-items: center;
|
gap: 6rpx;
|
margin-top: 8rpx;
|
font-size: 24rpx;
|
color: #8f97a4;
|
image {
|
width: 20rpx;
|
height: 20rpx;
|
}
|
}
|
|
.point-time {
|
display: block;
|
margin-top: 10rpx;
|
font-size: 24rpx;
|
color: #9aa2ae;
|
}
|
|
.location-toast {
|
position: fixed;
|
left: 20rpx;
|
right: 20rpx;
|
bottom: 8rpx;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 18rpx 20rpx;
|
border-radius: 12rpx;
|
background: rgba(42, 42, 42, 0.88);
|
z-index: 30;
|
}
|
|
.toast-copy {
|
min-width: 0;
|
padding-right: 16rpx;
|
}
|
|
.toast-title {
|
display: block;
|
font-size: 28rpx;
|
font-weight: 600;
|
color: #ffffff;
|
}
|
|
.toast-text {
|
display: block;
|
margin-top: 6rpx;
|
font-size: 22rpx;
|
line-height: 1.4;
|
color: rgba(255, 255, 255, 0.76);
|
}
|
|
.toast-btn {
|
flex-shrink: 0;
|
height: 54rpx;
|
line-height: 54rpx;
|
padding: 0 20rpx;
|
border-radius: 27rpx;
|
background: linear-gradient(135deg, #18b2ff 0%, #0b95ff 100%);
|
font-size: 24rpx;
|
font-weight: 600;
|
color: #ffffff;
|
}
|
</style>
|