purchase-let/multipleShop/index/index.vue

349 lines
7.7 KiB
Vue

<template>
<view class="multiple">
<view class="multiple-search">
<u-search v-model="queryParams.name" :animation="true" :showAction="false" bgColor="#f6f6f6"
placeholder="请输入门店"></u-search>
<view class="multiple-search-txt" @click.native="handleSearch">搜索</view>
</view>
<view class="multiple-card">
<scroll-view :scroll-y="true" style="height:100%;" @scrolltolower="onReachBottom">
<view class="multiple-card-wrap" style="padding-top: 12rpx;">
<block v-for="(item,indx) in shopList" :key="indx">
<view class="multiple-card-item" :class="{active:currShop == item.id}"
@click="onChooseShop(item)">
<view class="multiple-card-item-left">
<view class="multiple-card-item-left-title">{{item.name}}</view>
<view class="multiple-card-item-left-tag">
<text class="yellow" v-if="item.is_store == 1">可自提</text>
<text class="green" v-if="item.is_send == 1">可配送</text>
</view>
<view class="multiple-card-item-left-info">
<u-image src="../../multipleShop/images/location_small.webp" width="24rpx"
height="24rpx" />
<text>{{item.detailed_address || '-'}}</text>
</view>
<view class="multiple-card-item-left-info">
<u-image src="../../multipleShop/images/time.webp" width="24rpx" height="24rpx" />
<text
v-if="item.day_start && item.day_end">{{item.day_start + '-' + item.day_end}}</text>
<text v-else>9:00-18:00</text>
</view>
</view>
<view class="multiple-card-item-right">
<view class="multiple-card-item-right-distance">距离{{parseDistance(item.distance)}}
</view>
<view class="multiple-card-item-right-icon">
<view style="margin-right: 30rpx;" @click.stop="onPhoneCall(item.phone)">
<u-image src="../../multipleShop/images/phone.webp" width="48rpx"
height="48rpx" />
</view>
<view @click.stop="onNavgation(item)">
<u-image src="../../multipleShop/images/location.webp" width="48rpx"
height="48rpx" />
</view>
</view>
</view>
</view>
</block>
</view>
<up-loadmore :status="status" iconColor="#b3b3b3" color="#b3b3b3" />
</scroll-view>
</view>
</view>
</template>
<script setup>
import {
reactive,
ref,
} from "vue";
import {
shopListApi
} from "@/api/multipleShop.js";
import {
onLoad,
onShow
} from "@dcloudio/uni-app";
const currShop = ref(''); // 选择门店
const shopList = ref([]); // 门店列表
const status = ref(''); // 滚动状态
// 查询参数
const queryParams = reactive({
longitude: '',
latitude: '',
phone: '',
name: '',
page_no: 1,
page_size: 6
})
// 初始化
onLoad(() => {
// 获取定位
getLocation();
});
// 门店选择
const onChooseShop = (item) => {
currShop.value = item.id;
uni.setStorageSync('STORE_INFO', JSON.stringify(item))
setTimeout(() => {
uni.reLaunch({
url: '/pages/index/index?id=' + item.id,
fail(err) {
console.log(err);
}
})
}, 300)
}
// 触底刷新
const onReachBottom = () => {
getShopList();
}
// 搜索
const handleSearch = () => {
shopList.value = [];
queryParams.page_no = 1;
status.value = '';
getShopList();
}
// 获取门店
const getShopList = () => {
if (status.value == 'nomore') return;
if (status.value == 'loading') return;
status.value == 'loading';
shopListApi(queryParams).then(res => {
let len = res.data.lists;
status.value = queryParams.page_size > len.length ? 'nomore' : 'loadmore';
shopList.value = shopList.value.concat(res.data.lists);
if (status.value == 'loadmore') queryParams.page_no += 1;
})
}
// 门店距离处理
const parseDistance = (e) => {
if (!e) return '-';
if (e > 1) {
return (e.toFixed(1)) + 'km';
} else {
return (e * 1000).toFixed(0) + 'm';
}
}
// 拨打门店电话
const onPhoneCall = (phone) => {
if (!phone) return;
uni.makePhoneCall({
phoneNumber: phone
})
}
// 导航
const onNavgation = (item) => {
uni.openLocation({
latitude: Number(item.latitude),
longitude: Number(item.longitude),
})
}
// 获取定位
const getLocation = () => {
let location = uni.getStorageSync('location');
if (location) {
let [lng, lat] = location.split(',');
queryParams.longitude = lng;
queryParams.latitude = lat;
// 加载店铺列表
getShopList();
} else {
uni.getLocation({
type: "gcj02",
success(res) {
queryParams.latitude = res.latitude;
queryParams.longitude = res.longitude;
// 加载店铺列表
getShopList();
// 避免下次再获取
uni.setStorageSync('location', `${res.longitude},${res.latitude}`)
}
})
}
}
</script>
<style lang="scss">
page {
background: #FAFAFA;
}
.multiple {
padding-bottom: 30rpx;
.multiple-search {
position: sticky;
top: 0;
z-index: 10;
display: flex;
height: 90rpx;
background-color: #fff;
padding: 0 24rpx;
box-sizing: border-box;
.multiple-search-txt {
position: absolute;
right: 28rpx;
top: 50%;
z-index: 11;
transform: translateY(-50%);
width: 110rpx;
height: 52rpx;
line-height: 52rpx;
text-align: center;
background: #FFFFFF;
border-radius: 30rpx 30rpx 30rpx 30rpx;
font-size: 28rpx;
color: #20B128;
}
}
.multiple-card {
height: calc(100vh - 90rpx);
padding-bottom: 12rpx;
.u-loadmore {
padding-bottom: 40rpx;
}
.multiple-card-item {
display: flex;
background: #FFFFFF;
border-radius: 16rpx;
margin: 0 24rpx 20rpx;
padding: 30rpx 0 42rpx 30rpx;
overflow: hidden;
.multiple-card-item-left {
width: 70%;
border-right: 2rpx solid #F1F1F1;
.multiple-card-item-left-title {
margin-bottom: 14rpx;
font-weight: bold;
font-size: 28rpx;
color: #444444;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.multiple-card-item-left-tag {
display: flex;
flex-wrap: wrap;
align-items: center;
margin-bottom: 16rpx;
text {
width: 90rpx;
height: 42rpx;
line-height: 42rpx;
text-align: center;
border-radius: 8rpx;
font-size: 24rpx;
margin-right: 16rpx;
padding: 4rpx 10rpx;
}
.yellow {
background-color: #FFF8F1;
color: #FFB76D;
}
.green {
color: #20B128;
background-color: #F2FFF3;
}
}
.multiple-card-item-left-info {
display: flex;
padding-right: 10rpx;
&:nth-child(1) {
margin-bottom: 16rpx;
}
text {
font-weight: 400;
font-size: 24rpx;
color: #777777;
margin-left: 4rpx;
}
}
}
.multiple-card-item-right {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 30%;
flex-shrink: 0;
.multiple-card-item-right-distance {
margin-bottom: 20rpx;
font-size: 22rpx;
color: #777777;
}
.multiple-card-item-right-icon {
display: flex;
align-items: center;
}
}
}
.active {
position: relative;
border: 2rpx solid #20B128;
&::after {
content: "";
display: block;
position: absolute;
right: -34rpx;
bottom: -8rpx;
width: 0;
height: 0;
border-left: 50rpx solid transparent;
border-right: 50rpx solid transparent;
border-bottom: 50rpx solid #20B128;
transform: rotate(135deg);
}
&::before {
content: "";
display: block;
position: absolute;
right: 10rpx;
bottom: 4rpx;
color: #fff;
z-index: 11;
font-weight: bold;
}
}
}
}
</style>