195 lines
4.3 KiB
Vue
195 lines
4.3 KiB
Vue
<template>
|
|
<up-overlay :show="show">
|
|
<view class="box" v-if="SelData">
|
|
<view class="bg-fff u-p-30 item">
|
|
<view class="u-flex coverImg">
|
|
<up-image
|
|
width="204rpx"
|
|
height="228rpx"
|
|
radius="6"
|
|
:src="SelData.goods.coverImg"
|
|
></up-image>
|
|
<view class="limitDiscount" v-if="showLimitDiscount(SelData.goods)"
|
|
>限时折扣</view
|
|
>
|
|
</view>
|
|
|
|
<view class="u-flex-1 u-p-l-36">
|
|
<view class="u-flex u-col-center justify-between u-m-t-10">
|
|
<view class="u-line-1 font-16 color-333 font-bold u-p-r-16">{{
|
|
SelData.title
|
|
}}</view>
|
|
<up-icon
|
|
size="20"
|
|
name="close-circle"
|
|
color="#666"
|
|
@click="close"
|
|
></up-icon>
|
|
</view>
|
|
<view class="color-333 font-14 u-m-t-32 u-line-1">{{
|
|
SelData.guideDetail
|
|
}}</view>
|
|
<view class="u-flex justify-between u-m-t-30">
|
|
<view class="price"
|
|
>¥
|
|
<GoodsPrice
|
|
:limitDiscount="cartStore.limitTimeDiscount"
|
|
:cart="SelData.goods"
|
|
:shopUserInfo="shopUserInfo"
|
|
:shopInfo="shopInfo"
|
|
></GoodsPrice
|
|
></view>
|
|
<view class="buy" @click="buy">立即下单</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</up-overlay>
|
|
</template>
|
|
<script setup>
|
|
import * as orderUtils from "@/utils/order-utils.js";
|
|
import GoodsPrice from "@/components/goods-price.vue";
|
|
import * as suggestApi from "@/common/api/market/suggest.js";
|
|
import { ref, onMounted, inject, watch } from "vue";
|
|
const cartStore = inject("cartStore");
|
|
const shopUserInfo = inject("shopUserInfo");
|
|
const shopInfo = inject("shopInfo");
|
|
|
|
function showLimitDiscount(item) {
|
|
if (!cartStore.limitTimeDiscount) {
|
|
return false;
|
|
}
|
|
return orderUtils.canUseLimitTimeDiscount(
|
|
item,
|
|
cartStore.limitTimeDiscount,
|
|
shopInfo,
|
|
shopUserInfo.value,
|
|
"id"
|
|
);
|
|
}
|
|
|
|
|
|
const show = ref(false);
|
|
|
|
let timer = null;
|
|
|
|
function taskEnd() {
|
|
clearInterval(timer);
|
|
show.value = false;
|
|
}
|
|
function statTime() {
|
|
clearInterval(timer);
|
|
timer = setTimeout(() => {
|
|
const item = list.value[nowIndex.value];
|
|
if (item) {
|
|
SelData.value = item;
|
|
show.value = true;
|
|
} else {
|
|
taskEnd();
|
|
}
|
|
}, suggestTime.value * 1000);
|
|
}
|
|
|
|
const list = ref([]);
|
|
const SelData = ref(null);
|
|
const nowIndex = ref(0);
|
|
function close() {
|
|
suggestTime.value = 30;
|
|
taskEnd();
|
|
nowIndex.value += 1;
|
|
if (nowIndex.value == list.value.length) {
|
|
return;
|
|
}
|
|
statTime();
|
|
}
|
|
const suggestTime = ref(100);
|
|
|
|
const emits = defineEmits(["onBuyClick"]);
|
|
function buy() {
|
|
emits("onBuyClick", SelData.value.goods);
|
|
}
|
|
onMounted(() => {
|
|
suggestApi
|
|
.getGoods({
|
|
shopId: uni.cache.get("shopId"),
|
|
})
|
|
.then((res) => {
|
|
if (res) {
|
|
suggestTime.value = res.suggestTime;
|
|
list.value = (res.list || [])
|
|
.map((v) => {
|
|
return {
|
|
...v,
|
|
goods: cartStore.returnGoods(v.foods),
|
|
};
|
|
})
|
|
.filter((v) => v.goods);
|
|
startWatch();
|
|
}
|
|
});
|
|
});
|
|
|
|
function startWatch() {
|
|
watch(
|
|
() => cartStore.isEmpty,
|
|
(newval) => {
|
|
if (newval && list.value.length) {
|
|
statTime();
|
|
} else {
|
|
clearInterval(timer);
|
|
nowIndex.value = 0;
|
|
show.value = false;
|
|
}
|
|
},
|
|
{
|
|
immediate: true,
|
|
}
|
|
);
|
|
}
|
|
</script>
|
|
<style scoped lang="scss">
|
|
.box {
|
|
position: fixed;
|
|
z-index: 100;
|
|
left: 30rpx;
|
|
right: 30rpx;
|
|
bottom: calc(var(--safe-area-inset-bottom) + 0px);
|
|
.item {
|
|
padding: 32rpx 28rpx;
|
|
border-radius: 16rpx;
|
|
background: #fff;
|
|
box-shadow: 0 0 20rpx rgba(0, 0, 0, 0.05);
|
|
display: flex;
|
|
}
|
|
.price {
|
|
font-size: 40rpx;
|
|
color: #333;
|
|
}
|
|
.buy {
|
|
padding: 4rpx 28rpx;
|
|
border-radius: 36rpx;
|
|
background: #e8ad7b;
|
|
color: #ffffff;
|
|
font-size: 28rpx;
|
|
line-height: 48rpx;
|
|
}
|
|
}
|
|
.coverImg{
|
|
position: relative;
|
|
}
|
|
.limitDiscount {
|
|
background-color: #cc5617;
|
|
padding: 2rpx 10rpx;
|
|
white-space: nowrap;
|
|
text-align: center;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
font-weight: 400;
|
|
font-size: 24rpx;
|
|
color: #ffffff;
|
|
border-radius: 20rpx 0rpx 20rpx 0rpx;
|
|
z-index: 9;
|
|
color: #fff;
|
|
}
|
|
</style> |