<template>
|
<view class="index-page">
|
<image class="top-gradient-bg" src="/static/image/bg_home@2x.png" mode="aspectFill"></image>
|
<view class="top-hero">
|
<view :style="{ height: statusbarHeight + 'px' }"></view>
|
<view class="hero-bar" :style="{ height: navHeight + 'px' }">
|
<view class="location-chip" @click="chooseLocation">
|
<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" @click="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" @click="jumpBannerDetail(item)">
|
<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" @click="jumpOrderList(3)">
|
<image class="service-image" src="/static/image/home_ic_qujian@2x.png" mode="aspectFit"></image>
|
</view>
|
</view>
|
|
<view class="notice-card" v-if="ingOrder && ingOrder.orderId" @click="jumpOrderDetail(ingOrder.orderId)">
|
<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">{{ingOrder.statusDesc || ''}}</text>
|
<text class="notice-text">{{ingOrder.tip || ''}}</text>
|
</view>
|
</view>
|
|
<view class="section-head">
|
<text class="section-title">推荐寄存点</text>
|
<text class="section-more" @click="jumpJC">查看更多</text>
|
</view>
|
|
<view class="recommend-list">
|
<template v-if="pointList.length > 0">
|
<view v-for="(item, index) in pointList" :key="index" class="point-card" @click="goShopDetails(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>
|
</template>
|
<template v-else>
|
<view class="no-data">
|
<image src="/static/image/default_nodata_white@2x.png" mode="widthFix"></image>
|
</view>
|
</template>
|
</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>
|
<auth-login :show="showLogin" @close="showLogin = false"></auth-login>
|
<custom-tabbar></custom-tabbar>
|
</view>
|
</template>
|
|
<script>
|
import { mapState } from 'vuex'
|
import amapFile from '@/utils/amap-wx.130.js'
|
import CustomTabbar from '@/components/custom-tabbar/custom-tabbar.vue'
|
|
export default {
|
components: {
|
CustomTabbar
|
},
|
computed: {
|
...mapState(['navHeight', 'statusbarHeight', 'address', 'latitude', 'cityId', 'longitude', 'token']),
|
currentAddress() {
|
return this.address && this.address !== '定位中' ? this.address : '获取定位'
|
}
|
},
|
data() {
|
return {
|
bannerList: [],
|
pointList: [],
|
ingOrder: null,
|
showLogin: false,
|
pendingNavigate: null
|
}
|
},
|
async onLoad() {
|
await this.$onLaunched
|
await this.getBannerList()
|
if (this.cityId && this.latitude && this.longitude) {
|
await this.getNearbyShopList()
|
}
|
},
|
onShow() {
|
this.ingOrder =null
|
this.getIngorder()
|
},
|
watch: {
|
token(newToken) {
|
if (newToken && this.pendingNavigate) {
|
const fn = this.pendingNavigate
|
this.pendingNavigate = null
|
this.showLogin = false
|
fn()
|
}
|
}
|
},
|
methods: {
|
jumpBannerDetail(item) {
|
if(!item.content || item.content =='' || item.type==0){
|
return
|
}
|
if (item.type == 1) {
|
uni.navigateTo({
|
url: '/shop/pages/article-details/article-details?id=' + item.id
|
})
|
} else if(item.type == 2) {
|
uni.navigateTo({
|
url: '/shop/pages/webview/webview?url=' + item.content
|
})
|
}
|
},
|
jumpOrderDetail(id){
|
uni.navigateTo({
|
url:'/pages/delivery-order-detail/delivery-order-detail?userType=0&id='+id
|
})
|
},
|
async getIngorder(){
|
var that =this
|
let res = await that.$u.api.getActiveOrderTip()
|
if (res && res.code === 200) {
|
this.ingOrder = res.data
|
}
|
},
|
jumpOrderList(status){
|
if (!this.token) {
|
this.pendingNavigate = () => this.jumpOrderList(status)
|
this.showLogin = true
|
return
|
}
|
uni.setStorageSync("orderStatus",status)
|
uni.switchTab({
|
url: '/pages/itinerary/itinerary'
|
})
|
},
|
jumpxiadan() {
|
if (!this.token) {
|
this.pendingNavigate = () => this.jumpxiadan()
|
this.showLogin = true
|
return
|
}
|
if (!this.cityId) return uni.showToast({
|
title: '当前城市暂未开通',
|
icon: 'none'
|
})
|
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() {
|
const res = await this.$u.api.getNearbyShopList({
|
capacity: 5,
|
page: 1,
|
model: {
|
latitude: this.latitude,
|
longitude: this.longitude,
|
cityId: this.cityId,
|
sortType: 1
|
}
|
})
|
if (res.code === 200) {
|
this.pointList = res.data.records || []
|
}
|
},
|
jumpJC() {
|
if (!this.cityId) return uni.showToast({
|
title: '当前城市暂未开通',
|
icon: 'none'
|
})
|
uni.navigateTo({
|
url: '/pages/storage-point/storage-point'
|
})
|
},
|
handleLocation() {
|
var that = this;
|
uni.openSetting({
|
success: (res) => {
|
if (res.authSetting['scope.userLocation']) {
|
that.positioning()
|
}
|
}
|
});
|
},
|
chooseLocation() {
|
var that = this;
|
uni.chooseLocation({
|
type: 'gcj02',
|
success: async function(addr) {
|
console.log(addr, '==================uniapp选择位置成功');
|
if (addr.errMsg === 'chooseLocation:ok' && addr.latitude) {
|
const locParam = { latitude: addr.latitude, longitude: addr.longitude };
|
var myAmapFun = new amapFile.AMapWX({ key: that.$gaodeMapKey });
|
myAmapFun.getRegeo({
|
location: addr.longitude + ',' + addr.latitude,
|
success: async function(data) {
|
console.log(data, '==================选择地址逆解析');
|
let info = data[0];
|
locParam.province = info.province;
|
locParam.city = (info.regeocodeData.addressComponent.city && typeof info.regeocodeData.addressComponent.city === 'string')
|
? info.regeocodeData.addressComponent.city
|
: info.regeocodeData.addressComponent.province;
|
var ta = addr.name || '地址获取失败';
|
locParam.address = ta
|
const resCity = await that.$u.api.getCityByName({ cityName: locParam.city })
|
if (resCity.code === 200 && resCity.data) {
|
locParam.cityId = resCity.data.id
|
that.$store.commit('setPosition', locParam)
|
that.pointList = []
|
that.getNearbyShopList()
|
} else {
|
that.$store.commit('setPosition', locParam)
|
that.$store.commit('clearCityId')
|
that.pointList = []
|
}
|
},
|
fail: function(err) {
|
console.error('获取位置失败===========', err);
|
that.$store.commit('setPosition', locParam)
|
that.pointList = []
|
that.getNearbyShopList()
|
}
|
});
|
}
|
},
|
fail: function(err) {
|
console.error('选择位置失败===========', err);
|
}
|
});
|
},
|
// 定位
|
positioning() {
|
var that = this;
|
uni.getLocation({
|
type: 'gcj02',
|
highAccuracyExpireTime: 3000,
|
isHighAccuracy: true,
|
success: function (addr) {
|
const locParam = { latitude: addr.latitude, longitude: addr.longitude };
|
var myAmapFun = new amapFile.AMapWX({ key: 'f2e6c0bfcac14c27b4f0d6d0d5b9d7d' });
|
myAmapFun.getRegeo({
|
location: addr.longitude + ',' + addr.latitude,
|
success: async function(data) {
|
console.log(data, '==================获取地址');
|
let info = data[0];
|
locParam.province = info.province;
|
locParam.city = info.city;
|
locParam.area = info.district;
|
locParam.street = info.street;
|
var ta = info.name || '地址获取失败';
|
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()
|
}
|
});
|
}
|
});
|
},
|
goShopDetails(item){
|
uni.navigateTo({
|
url: '/pages/storage-point-detail/storage-point-detail?id='+item.id
|
})
|
},
|
goStoragePage() {
|
if (!this.cityId) return uni.showToast({
|
title: '当前城市暂未开通',
|
icon: 'none'
|
})
|
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;
|
}
|
|
.no-data {
|
width: 100%;
|
margin-top: 80rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
image {
|
width: 320rpx;
|
height: 320rpx;
|
}
|
}
|
|
.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>
|