Files
cashier_wx/components/coupon-modal.vue
2025-09-26 10:55:45 +08:00

319 lines
7.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 首页优惠券弹窗 -->
<template>
<up-popup :show="show" bgColor="transparent">
<view class="container">
<view class="content">
<image class="bg" src="https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/4/6520f3cfae594480aa2e612ff4ad121c.png" mode="widthFix"></image>
<view class="swiper-wrap">
<swiper class="swiper" @change="swiperChange">
<swiper-item class="swiper-item" v-for="(item, index) in couponList" :key="index">
<view class="item" v-for="val in item" :key="val.id">
<image
class="item-bg"
src="https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/4/105b29907c274f9e84e14b9ddb867356.png"
mode="aspectFill"
></image>
<view class="info-wrap">
<view class="info">
<view class="name name1" v-if="val.couponType == 1">
<text class="t1">{{ val.discountAmount }}</text>
<text class="t2">{{ val.fullAmount }}可用</text>
</view>
<view class="name name2" v-if="val.couponType == 2">
<text class="t1">商品兑换{{ val.discountNum }}</text>
<text class="t2">{{ val.fullAmount }}可用</text>
</view>
<view class="name name2" v-if="val.couponType == 3">
<text class="t1">{{ val.discountRate }}折券</text>
<text class="t2">{{ val.fullAmount }}可用</text>
</view>
<view class="name name2" v-if="val.couponType == 4">
<text class="t1">第二件半价券</text>
<text class="t2">{{ val.fullAmount }}可用</text>
</view>
<view class="name name2" v-if="val.couponType == 6">
<text class="t1">买一送一券</text>
<text class="t2">{{ val.fullAmount }}可用</text>
</view>
<view class="title">
{{ val.title }}
</view>
<view class="time">
<view class="row">
<text class="t">
有效期至{{ dayjs(item.validStartTime || new Date()).format('YYYY.M.D') }} -
{{ dayjs(item.validEndTime || new Date()).format('YYYY.M.D') }}
</text>
</view>
</view>
</view>
<view class="lq-btn">
<view class="lb" @click="getHandle">
<text class="t">立即</text>
<text class="t">领取</text>
</view>
</view>
</view>
</view>
</swiper-item>
</swiper>
<view class="dot-wrap">
<view class="page-btn">
<up-icon name="arrow-left" :color="swiperIndex == 0 ? '#fa746a' : '#f6171b'" size="16"></up-icon>
</view>
<view class="page-wrap">
<text class="t" :class="{ active: swiperIndex == index }" v-for="(item, index) in couponList.length" :key="index">{{ item }}</text>
</view>
<view class="page-btn">
<up-icon name="arrow-right" :color="swiperIndex == couponList.length - 1 ? '#fa746a' : '#f6171b'" size="16"></up-icon>
</view>
</view>
</view>
<view class="btn-wrap" @click="getHandle">
<image class="btn-img" src="https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/4/a7ea3211baf84cc8b77171d4f88c7f9e.png" mode="widthFix"></image>
<text class="t">全部领取{{ couponCount }}</text>
</view>
<view class="close" @click="getHandle">
<up-icon name="close-circle" size="34" color="#fff"></up-icon>
</view>
</view>
</view>
</up-popup>
</template>
<script setup>
import _ from 'lodash';
import dayjs from 'dayjs';
import { onMounted, ref } from 'vue';
import { getCouponPopup, receivePopUp } from '@/common/api/member.js';
const couponCount = ref(0);
const swiperIndex = ref(0);
const couponList = ref([]);
const show = ref(false);
const props = defineProps({
getMode: {
type: String,
default: 'eat'
}
});
// 轮播图滑动
function swiperChange(e) {
swiperIndex.value = e.detail.current;
}
// 优惠券弹窗
async function getCouponPopupAjax() {
try {
const res = await getCouponPopup({ getMode: props.getMode });
if (res.length) {
show.value = true;
couponCount.value = res.length;
couponList.value = _.chunk(res, 3);
}
} catch (error) {
console.log(error);
}
}
// 领取
async function getHandle() {
try {
uni.showLoading({
title: '领取中...',
mask: true
});
const res = await receivePopUp({
getMode: props.getMode
});
show.value = false;
uni.showToast({
title: '已领取,请在我的优惠券中查看',
icon: 'none'
});
} catch (err) {
console.log(err);
}
uni.hideLoading();
}
onMounted(() => {
getCouponPopupAjax();
});
</script>
<style scoped lang="scss">
.container {
width: 100vw;
height: 100vh;
position: relative;
display: flex;
align-items: center;
justify-content: center;
padding-top: 10vh;
.content {
width: 94vw;
position: relative;
padding-left: 24upx;
.close {
position: absolute;
left: 50%;
bottom: -100upx;
transform: translateX(-50%);
}
.bg {
width: 100%;
height: 100%;
}
.swiper-wrap {
width: 64%;
height: 70%;
position: absolute;
left: 18%;
top: 96upx;
.swiper {
width: 100%;
height: 90%;
background-color: #fff;
.swiper-item {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: repeat(3, 1fr);
grid-column-gap: 0;
grid-row-gap: 12upx;
.item {
background-color: #e20410;
border-radius: 12upx;
padding: 12upx;
position: relative;
.item-bg {
width: 100%;
height: 100%;
}
.info-wrap {
width: 100%;
height: 100%;
padding: 20upx;
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: center;
.info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 8upx;
.name {
font-size: 32upx;
font-weight: bold;
color: #fff;
.t1 {
font-size: 32upx;
font-weight: bold;
color: #fff;
margin-right: 8upx;
}
.t2 {
font-size: 20upx;
color: #fff;
}
}
.title {
font-size: 28upx;
color: #fff;
font-weight: bold;
}
.time {
display: flex;
.row {
height: 30upx;
padding: 0 8upx;
background-color: #fff;
border-radius: 8upx;
display: flex;
align-items: center;
.t {
font-size: 10px;
color: #c50914;
}
}
}
}
.lq-btn {
.lb {
$size: 80upx;
width: $size;
height: $size;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 50%;
background-color: #fe413d;
.t {
color: #fff;
font-size: 20upx;
font-weight: bold;
}
}
}
}
}
}
}
.dot-wrap {
width: 100%;
height: 10%;
display: flex;
align-items: center;
justify-content: center;
gap: 20upx;
.page-wrap {
display: flex;
align-items: center;
gap: 20upx;
&.disabled {
.t {
color: #fa746a;
}
}
.t {
font-size: 28upx;
color: #fa746a;
&.active {
color: #f6171b;
font-weight: bold;
}
}
}
}
}
.btn-wrap {
width: 60%;
position: absolute;
left: 20%;
bottom: 38upx;
.btn-img {
width: 100%;
}
.t {
font-size: 42upx;
font-weight: bold;
color: #b43a14;
position: absolute;
top: 44%;
left: 54%;
white-space: nowrap;
transform: translate(-50%, -50%);
}
}
}
}
</style>