|
|
@@ -0,0 +1,377 @@
|
|
|
+<script lang="ts" setup>
|
|
|
+import { computed, ref } from 'vue'
|
|
|
+import ShortLinkModal from '@/components/ShortLinkModal.vue'
|
|
|
+import { getLastPartAfterSlash } from '@/utils/couponClassFormat'
|
|
|
+import { getImageUrl } from '@/utils/imageUtil'
|
|
|
+import { useCouponShare } from '../hooks/useCouponShare'
|
|
|
+import { getPlatformSource } from '@/utils/platformSource'
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ coupon: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({
|
|
|
+ ruleDiscountRate: '0',
|
|
|
+ ruleMinSpendAmount: '0',
|
|
|
+ relatedName: '',
|
|
|
+ ruleDiscountCapAmount: '0',
|
|
|
+ validityType: '1',
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ scrollViewId: {
|
|
|
+ type: String,
|
|
|
+ default: '',
|
|
|
+ },
|
|
|
+ enableCustomShare: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ }
|
|
|
+})
|
|
|
+const emit = defineEmits(['shareClick'])
|
|
|
+const coupon = computed(() => props.coupon)
|
|
|
+const couponTemplateId = computed(() => coupon.value.templateId || '')
|
|
|
+const deadline = computed(() => {
|
|
|
+ const type = props.coupon.validityType
|
|
|
+ if (type === '2') {
|
|
|
+ return `自领取之日起${props.coupon.validDays}日内使用`
|
|
|
+ }
|
|
|
+ else if (type === '1') {
|
|
|
+ return `限${props.coupon.validStartTime}到${props.coupon.validEndTime}日内使用`
|
|
|
+ }
|
|
|
+ return '长期有效'
|
|
|
+})
|
|
|
+const category = computed(() => {
|
|
|
+ const relatedType = coupon.value.relatedType
|
|
|
+ if (coupon.value?.relatedName && coupon.value?.relatedName !== 'null') {
|
|
|
+ let relatedName = coupon.value.relatedName
|
|
|
+ if (relatedType === '2') {
|
|
|
+ relatedName = getLastPartAfterSlash(coupon.value.relatedName)
|
|
|
+ return `限${relatedName}分类商品使用`
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return `限${relatedName}商品使用`
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return '不限商品分类'
|
|
|
+})
|
|
|
+
|
|
|
+// 分享弹窗相关 - 使用v-model控制弹窗显示
|
|
|
+const showShareModal = ref(false)
|
|
|
+const couponShareLink = ref('')
|
|
|
+const isExpand = ref(false);
|
|
|
+
|
|
|
+const { shareCoupon, ...shareHooks } = useCouponShare()
|
|
|
+
|
|
|
+// 调用分享弹窗
|
|
|
+async function handleShareCoupon() {
|
|
|
+ // 确保有优惠券数据
|
|
|
+ if (coupon.value.templateId) {
|
|
|
+ // uni.showLoading({
|
|
|
+ // title: '获取分享链接中...',
|
|
|
+ // mask: true,
|
|
|
+ // })
|
|
|
+ try {
|
|
|
+ const shareLink = await shareCoupon(couponTemplateId.value)
|
|
|
+ if (shareLink) {
|
|
|
+ couponShareLink.value = shareLink
|
|
|
+ showShareModal.value = true
|
|
|
+ if (props.enableCustomShare) {
|
|
|
+ emit('shareClick', couponShareLink.value, shareHooks)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finally {
|
|
|
+ // uni.hideLoading()
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 关闭分享弹窗
|
|
|
+function handleCloseShareModal() {
|
|
|
+ console.log('分享弹窗已关闭')
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <view class="discount-coupon">
|
|
|
+ <image class="coupon-bg" :src="getImageUrl('@img/index/coupon4.png')" mode="aspectFill" />
|
|
|
+ <view class="discount-coupon-content">
|
|
|
+ <view class="discount-coupon-info-container">
|
|
|
+ <view class="discount-coupon-info-content">
|
|
|
+ <view class="discount-coupon-info-price">
|
|
|
+ <text class="discount-coupon-info-number">
|
|
|
+ {{ coupon?.ruleReductionAmount }}
|
|
|
+ </text>
|
|
|
+ <view class="discount-coupon-info-unit">
|
|
|
+ ¥
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="discount-coupon-info-desc">
|
|
|
+ <view class="desc-text">
|
|
|
+ 满{{ coupon.ruleMinSpendAmount }}元可用
|
|
|
+ </view>
|
|
|
+ <view class="desc-type" @tap="isExpand = !isExpand">
|
|
|
+ {{ category }}
|
|
|
+ <up-icon v-if="isExpand" name="arrow-up-fill" />
|
|
|
+ <up-icon v-else name="arrow-down-fill" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="discount-coupon-info-time">
|
|
|
+ {{ deadline }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="discount-btn-container">
|
|
|
+ <view class="btn-bg">
|
|
|
+ <button class="discount-btn" @click="handleShareCoupon">
|
|
|
+ <view>立即</view>
|
|
|
+ <view>发券</view>
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <!-- <up-transition :show="isExpand" mode="fade-down" duration="300"> -->
|
|
|
+ <view :class="['coupon-info', isExpand ? 'expanded' : 'collapsed']">
|
|
|
+ <view class="info-content">
|
|
|
+ <view class="info-item">
|
|
|
+ <view class="item-title">券类型:</view>
|
|
|
+ <view class="item-content">{{ coupon.type === '2' ? '折扣券' : '满减券' }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="info-item">
|
|
|
+ <view class="item-title">限定地区:</view>
|
|
|
+ <view class="item-content">
|
|
|
+ {{ coupon?.locality && coupon?.locality !== 'null' ?
|
|
|
+ `仅可在${coupon?.locality}地区的商户使用` : '不限地区' }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="info-item">
|
|
|
+ <view class="item-title">限定商户:</view>
|
|
|
+ <view class="item-content">
|
|
|
+ {{ coupon?.storeName && coupon?.storeName !== 'null' ?
|
|
|
+ `仅限${coupon?.storeName}商户使用` : '不限商户' }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="info-item">
|
|
|
+ <view class="item-title">限定商品:</view>
|
|
|
+ <view class="item-content">{{ category }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="info-item">
|
|
|
+ <view class="item-title">限定平台:</view>
|
|
|
+ <view class="item-content">{{ getPlatformSource(coupon?.platformSource) }}</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <!-- </up-transition> -->
|
|
|
+ <template v-if="!enableCustomShare">
|
|
|
+ <ShortLinkModal v-model:show-modal="showShareModal" :coupon-id="couponTemplateId" :share-hooks="shareHooks"
|
|
|
+ :share-link="couponShareLink" :scroll-view-id="scrollViewId" @close="handleCloseShareModal" />
|
|
|
+ </template>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.discount-coupon {
|
|
|
+ width: 100%;
|
|
|
+ max-width: 800rpx;
|
|
|
+ min-height: 209rpx;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .coupon-bg {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 209rpx;
|
|
|
+ object-fit: cover;
|
|
|
+ z-index: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .discount-coupon-content {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ height: 209rpx;
|
|
|
+ // padding: 14rpx 0 17rpx 12rpx;
|
|
|
+
|
|
|
+ .discount-coupon-info-container {
|
|
|
+ width: 73.47%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ padding: 14rpx 0 17rpx 12rpx;
|
|
|
+ z-index: 1;
|
|
|
+
|
|
|
+ .discount-coupon-info-content {
|
|
|
+ width: 100%;
|
|
|
+ height: 78.09%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ // justify-content: center;
|
|
|
+ gap: 20rpx;
|
|
|
+
|
|
|
+ .discount-coupon-info-price {
|
|
|
+ width: 199rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ align-items: flex-end;
|
|
|
+ padding-bottom: 22rpx;
|
|
|
+ justify-content: center;
|
|
|
+ padding-left: 10rpx;
|
|
|
+ gap: 5rpx;
|
|
|
+
|
|
|
+ .discount-coupon-info-number {
|
|
|
+ height: 132rpx;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 80rpx;
|
|
|
+ color: #f8204b;
|
|
|
+ line-height: 168rpx;
|
|
|
+ letter-spacing: -8rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .discount-coupon-info-unit {
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 27rpx;
|
|
|
+ color: #f8204b;
|
|
|
+ line-height: 56rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .discount-coupon-info-desc {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 13rpx;
|
|
|
+
|
|
|
+ .desc-text {
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .desc-type {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #333333;
|
|
|
+ line-height: 30rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .discount-coupon-info-time {
|
|
|
+ padding-top: 16rpx;
|
|
|
+ padding-bottom: 8rpx;
|
|
|
+ flex: 1;
|
|
|
+ width: 100%;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 18rpx;
|
|
|
+ color: #666666;
|
|
|
+ line-height: 18rpx;
|
|
|
+ padding-left: 1rem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .discount-btn-container {
|
|
|
+ height: 100%;
|
|
|
+ width: 26.53%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .btn-bg {
|
|
|
+ width: 125rpx;
|
|
|
+ height: 125rpx;
|
|
|
+ transform: translate(10%, 0);
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ z-index: 2;
|
|
|
+
|
|
|
+ .discount-btn {
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 10rpx;
|
|
|
+ padding: 0;
|
|
|
+ background-color: transparent;
|
|
|
+ border: none;
|
|
|
+ line-height: 28rpx;
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ border: none;
|
|
|
+ position: unset;
|
|
|
+ height: inherit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .coupon-info {
|
|
|
+ padding: 20rpx 30rpx;
|
|
|
+ width: calc(100% - 82rpx);
|
|
|
+ border-left: 11rpx solid #ffd8d3;
|
|
|
+ border-right: 11rpx solid #ffd8d3;
|
|
|
+ border-bottom: 11rpx solid #ffd8d3;
|
|
|
+ background-color: #fefefe;
|
|
|
+ border-bottom-left-radius: 11rpx;
|
|
|
+ border-bottom-right-radius: 11rpx;
|
|
|
+ overflow: hidden;
|
|
|
+ transition: all 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
|
+ box-shadow: 1rpx 1rpx 10rpx #fff9f4;
|
|
|
+
|
|
|
+ .info-content {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: flex-start;
|
|
|
+ gap: 20rpx;
|
|
|
+
|
|
|
+ .info-item {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-start;
|
|
|
+ gap: 10rpx;
|
|
|
+ color: #666;
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 26rpx;
|
|
|
+
|
|
|
+ .item-title {
|
|
|
+ flex: 1;
|
|
|
+ width: 160rpx;
|
|
|
+ font-weight: bolder;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 收起状态 */
|
|
|
+ .coupon-info.collapsed {
|
|
|
+ opacity: 0;
|
|
|
+ max-height: 0;
|
|
|
+ padding-top: 0;
|
|
|
+ padding-bottom: 0;
|
|
|
+ border-top-width: 0;
|
|
|
+ border-bottom-width: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 展开状态 */
|
|
|
+ .coupon-info.expanded {
|
|
|
+ opacity: 1;
|
|
|
+ max-height: 500rpx;
|
|
|
+ /* 设置一个足够大的值以容纳所有内容 */
|
|
|
+ padding-top: 20rpx;
|
|
|
+ padding-bottom: 20rpx;
|
|
|
+ border-top-width: 11rpx;
|
|
|
+ border-bottom-width: 11rpx;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|