| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- <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: () => ({
- ruleReductionAmount: '0',
- ruleMinSpendAmount: '0',
- }),
- },
- 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 = props.coupon.relatedType
- if (coupon.value?.relatedName && coupon.value?.relatedName !== 'null') {
- const relatedName = getLastPartAfterSlash(props.coupon.relatedName)
- if (relatedType === '2') {
- 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/coupon3.png')" mode="aspectFit" />
- <view class="coupon-content-container">
- <view class="coupon-content">
- <view class="coupon-amount">
- <view class="coupon-amount-count">
- <view class="coupon-amount-count-icon">
- ¥
- </view>
- <view class="coupon-amount-count-number">
- {{ coupon?.ruleReductionAmount }}
- </view>
- </view>
- <view class="coupon-amount-text">
- 满{{ coupon?.ruleMinSpendAmount }}元可用
- </view>
- </view>
- <view class="coupon-info">
- <view class="coupon-info-category">
- {{ category }}
- </view>
- <view class="flex flex-row flex-nowrap text-[24rpx] text-[#666]">
- <view>使用规则:</view>
- <view class="text-blue" @tap="isExpand = !isExpand">{{ isExpand ? '收起' : '展开' }}</view>
- </view>
- <view class="coupon-info-time">
- <template v-if="coupon.validityType === '2'">
- <view>{{ deadline }}</view>
- </template>
- <template v-else-if="coupon.validityType === '1'">
- <!-- <view>使用日期</view> -->
- <view>{{ deadline }}</view>
- </template>
- <template v-else>
- <view>{{ deadline }}</view>
- </template>
- </view>
- </view>
- </view>
- <view class="discount-btn">
- <button class="coupon-btn-container" @click="handleShareCoupon">
- <view>立即</view>
- <view>发券</view>
- </button>
- <template v-if="!enableCustomShare">
- <ShortLinkModal v-model:show-modal="showShareModal" :coupon-id="couponTemplateId"
- :share-link="couponShareLink" :scroll-view-id="scrollViewId" :share-hooks="shareHooks"
- @close="handleCloseShareModal" />
- </template>
- </view>
- </view>
- <view :class="['coupon-express-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>
- </view>
- </template>
- <style lang="scss" scoped>
- .discount-coupon {
- // width: 670rpx;
- width: 100%;
- max-width: 800rpx;
- min-height: 200rpx;
- position: relative;
- overflow: hidden;
- .coupon-bg {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- width: 100%;
- height: 200rpx;
- z-index: 1;
- object-fit: cover;
- }
- .coupon-content-container {
- // position: absolute;
- width: 100%;
- height: 200rpx;
- display: flex;
- flex-direction: row;
- flex-wrap: nowrap;
- .coupon-content {
- height: 161.5rpx;
- width: calc(100% - 27.68%);
- padding-top: 18rpx;
- padding-left: 20rpx;
- padding-bottom: 20rpx;
- display: flex;
- flex-direction: row;
- gap: 3rpx;
- z-index: 2;
- .coupon-amount {
- height: 100%;
- width: 32%;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- .coupon-amount-count {
- display: flex;
- flex-direction: row;
- flex-wrap: nowrap;
- align-items: baseline;
- .coupon-amount-count-icon {
- font-weight: 500;
- font-size: 27rpx;
- color: #f83003;
- }
- .coupon-amount-count-number {
- font-weight: 500;
- font-size: 70rpx;
- color: #f83003;
- clear: both;
- }
- }
- .coupon-amount-text {
- font-weight: 400;
- font-size: 24rpx;
- color: #f3513b;
- }
- }
- .coupon-info {
- height: 100%;
- width: 68%;
- display: flex;
- flex-direction: column;
- justify-content: space-evenly;
- padding-left: 18rpx;
- .coupon-info-category {
- font-weight: bold;
- font-size: 28rpx;
- color: #333333;
- }
- .coupon-info-time {
- // padding-top: 14rpx;
- display: flex;
- flex-direction: column;
- gap: 5rpx;
- font-weight: 400;
- font-size: 22rpx;
- color: #888888;
- }
- }
- }
- .discount-btn {
- z-index: 2;
- height: 100%;
- width: 27.68%;
- display: flex;
- justify-content: center;
- align-items: center;
- .coupon-btn-container {
- width: 115rpx;
- height: 115rpx;
- transform: translateX(7rpx);
- padding: 17rpx 20rpx 18rpx 20rpx;
- background-color: transparent;
- border: none;
- font-weight: 500;
- font-size: 28rpx;
- color: #ffffff;
- line-height: 41rpx;
- &::after {
- border: none;
- position: unset;
- height: inherit;
- }
- }
- }
- }
- .coupon-express-info {
- margin-top: -15rpx;
- padding: 20rpx 30rpx;
- padding-top: 35rpx;
- width: calc(100% - 82rpx);
- border-left: 11rpx solid #ff792f;
- border-right: 11rpx solid #ff2c43;
- // border-bottom: 11rpx solid transparent;
- // border-image-slice: 1;
- // border-image: linear-gradient(to right, #ff792f, #ff2c43);
- position: relative;
- background-color: #f9f9f9;
- border-bottom-left-radius: 21rpx;
- border-bottom-right-radius: 21rpx;
- overflow: hidden;
- transition: all 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
- &::after {
- content: '';
- position: absolute;
- left: 0;
- bottom: 0;
- width: 100%;
- height: 11rpx; // 底部边框宽度
- background: linear-gradient(to right, #ff792f, #ff2c43);
- z-index: 0;
- // 处理圆角
- border-bottom-left-radius: 21rpx;
- border-bottom-right-radius: 21rpx;
- }
- .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-express-info.collapsed {
- opacity: 0;
- max-height: 0;
- padding-top: 0;
- padding-bottom: 0;
- border-top-width: 0;
- border-bottom-width: 0;
- }
- /* 展开状态 */
- .coupon-express-info.expanded {
- opacity: 1;
- max-height: 500rpx;
- /* 设置一个足够大的值以容纳所有内容 */
- }
- }
- </style>
|