REFACTOR:礼品功能重构

This commit is contained in:
LinCyJang
2025-10-24 01:31:50 +08:00
parent 705d64d238
commit d1bbea6e9b
8 changed files with 986 additions and 58 deletions
@@ -0,0 +1,213 @@
<template>
<u-popup :show="show" @close="close" mode="center" round="16" closeable>
<view class="gift-address-form">
<view class="form-title">填写您的信息</view>
<view class="form-content">
<view class="form-item">
<text class="label">姓名</text>
<input
type="text"
v-model="form.realName"
placeholder="请填写姓名"
class="input"
/>
</view>
<view class="form-item">
<text class="label">联系电话</text>
<input
type="number"
v-model="form.phone"
placeholder="请填写联系电话"
maxlength="11"
class="input"
/>
</view>
<view class="form-item">
<text class="label">入住时间</text>
<view class="date-picker" @click="showDatePicker = true">
<text v-if="form.checkInDate && form.checkOutDate">
{{ form.checkInDate }} {{ form.checkOutDate }}
</text>
<text v-else class="placeholder">请选择入住时间</text>
<text class="calendar-icon"></text>
</view>
</view>
</view>
<date-range-picker
v-model="dateRange"
:show="showDatePicker"
:travelGroupProductId="mid"
:minBookingDays="minBookingDays"
@update:show="showDatePicker = false"
@input="handleDateRangeChange"
/>
<view class="form-footer">
<button class="submit-btn" @click="submitForm">点击确定</button>
</view>
</view>
</u-popup>
</template>
<script>
import DateRangePicker from '@/components/DateRangePicker/DateRangePicker.vue'
export default {
name: 'GiftAddressForm',
components: {
DateRangePicker
},
props: {
show: {
type: Boolean,
default: false
},
unavailableDates: {
type: Array,
default: () => []
},
mid: {
type: String,
default: ''
},
minBookingDays: {
type: Number,
default: 0
}
},
data() {
return {
form: {
realName: '',
phone: '',
checkInDate: '',
checkOutDate: ''
},
showDatePicker: false,
dateRange: [null, null]
}
},
methods: {
close() {
this.$emit('close')
this.showDatePicker = false
},
handleDateRangeChange(dates) {
if (dates && dates.length === 2) {
[this.form.checkInDate, this.form.checkOutDate] = dates
}
},
submitForm() {
if (!this.form.realName) {
uni.showToast({
title: '请填写姓名',
icon: 'none'
})
return
}
if (!this.form.phone || !/^1\d{10}$/.test(this.form.phone)) {
uni.showToast({
title: '请填写正确的手机号',
icon: 'none'
})
return
}
if (!this.form.checkInDate || !this.form.checkOutDate) {
uni.showToast({
title: '请选择入住时间',
icon: 'none'
})
return
}
this.$emit('submit', this.form)
this.close()
}
}
}
</script>
<style lang="scss" scoped>
.gift-address-form {
width: 650rpx;
background: #FFFFFF;
border-radius: 32rpx;
padding: 40rpx;
box-sizing: border-box;
.form-title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 40rpx;
}
.form-content {
.form-item {
margin-bottom: 30rpx;
.label {
font-size: 28rpx;
color: #333333;
margin-bottom: 16rpx;
display: block;
}
.input {
width: 100%;
height: 80rpx;
background: #F8F8F8;
border-radius: 12rpx;
padding: 0 24rpx;
font-size: 28rpx;
}
.date-picker {
height: 80rpx;
background: #F8F8F8;
border-radius: 12rpx;
padding: 0 24rpx;
display: flex;
align-items: center;
justify-content: space-between;
.placeholder {
color: #999999;
font-size: 28rpx;
}
.calendar-icon {
font-size: 32rpx;
}
}
}
}
.form-footer {
margin-top: 40rpx;
.submit-btn {
width: 100%;
height: 88rpx;
background: #C52733;
border-radius: 44rpx;
color: #FFFFFF;
font-size: 32rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
}
</style>]]>
+108 -46
View File
@@ -6,7 +6,10 @@
top: card.productImageY*2 + 'rpx',
left: card.productImageX*2 + 'rpx'
}">
<image class="pro-image" :src="card.giftProducts[0].productImage" mode="aspectFit|aspectFill|widthFix" lazy-load="false" @error="" @load="">
<image v-if="!isTravelGroup" class="pro-image" :src="card.giftProducts[0].productImage" mode="aspectFit|aspectFill|widthFix" lazy-load="false">
</image>
<image v-if="isTravelGroup" class="pro-image" :src="card.image" mode="aspectFit|aspectFill|widthFix" lazy-load="false">
</image>
</view>
@@ -18,36 +21,49 @@
</view>
</view>
<view class="blind-box" v-if="card.isBlind">
<u-icon :name="webUrl + '/orderIcon/礼物.png'" size="30" ></u-icon>
<text class="v12-font-30 v12-dark-text v12-font-bold v12-ml-2">您收到一份来自朋友的神秘礼物</text>
</view>
<view class="btn-wrap">
<button v-if="!isReceive && myGift.isCurrentUser !== 1" class="share-btn v12-white-text v12-primary" @click="setAddress(0)">
填写地址并收下
</button>
<button v-if="card.canTransfer !== 0 && !isReceive && myGift.isCurrentUser !== 1" open-type="share" class="share-btn v12-white v12-primary-text v12-d-flex" >
点击转赠给好友
<u-icon :name="webUrl + '/icon/share.png'" ></u-icon>
</button>
</view>
<view v-if="myGift.isCurrentUser === 1 && !card.isBlind" @click="toOrder" style="z-index: 10; display: flex;flex-direction: column;align-items: center;">
<view class="address-btn v12-white-text v12-primary">
您已领取礼包
<view v-if="!isTravelGroup">
<view class="blind-box" v-if="card.isBlind">
<u-icon :name="webUrl + '/orderIcon/礼物.png'" size="30" ></u-icon>
<text class="v12-font-30 v12-dark-text v12-font-bold v12-ml-2">您收到一份来自朋友的神秘礼物</text>
</view>
<view class="info-btn v12-text-center v12-font-32 v12-mt-3">查看礼包详情>></view>
</view>
<view v-if="myGift.isCurrentUser === 1 && card.isBlind" style="z-index: 10; display: flex;flex-direction: column;align-items: center;">
<view style="width: fit-content;" class="address-btn v12-white-text v12-primary" @click="toOrder">
您已领取礼包去看看>>
<view class="btn-wrap">
<button v-if="!isReceive && myGift.isCurrentUser !== 1" class="share-btn v12-white-text v12-primary" @click="setAddress(0)">
填写地址并收下
</button>
<button v-if="card.canTransfer !== 0 && !isReceive && myGift.isCurrentUser !== 1" open-type="share" class="share-btn v12-white v12-primary-text v12-d-flex" >
点击转赠给好友
<u-icon :name="webUrl + '/icon/share.png'" ></u-icon>
</button>
</view>
<view class="info-btn v12-text-center v12-font-32 v12-mt-3" @click.stop="searchGift">我也要送礼</view>
<view v-if="myGift.isCurrentUser === 1 && !card.isBlind" @click="toOrder" style="z-index: 10; display: flex;flex-direction: column;align-items: center;">
<view class="address-btn v12-white-text v12-primary">
您已领取礼包
</view>
<view class="info-btn v12-text-center v12-font-32 v12-mt-3">查看礼包详情>></view>
</view>
<view v-if="myGift.isCurrentUser === 1 && card.isBlind" style="z-index: 10; display: flex;flex-direction: column;align-items: center;">
<view style="width: fit-content;" class="address-btn v12-white-text v12-primary" @click="toOrder">
您已领取礼包去看看>>
</view>
<view class="info-btn v12-text-center v12-font-32 v12-mt-3" @click.stop="searchGift">我也要送礼</view>
</view>
<view v-if="isReceive && myGift.isCurrentUser !== 1" @click="toHome" style="z-index: 10; display: flex;flex-direction: column;align-items: center;">
<view class="address-btn v12-white-text v12-primary">
礼包已被领取
</view>
<view class="info-btn v12-text-center v12-font-32 v12-mt-3" style="z-index: 10">去商城看看>></view>
</view>
</view>
<view v-if="isReceive && myGift.isCurrentUser !== 1" @click="toHome" style="z-index: 10; display: flex;flex-direction: column;align-items: center;">
<view class="address-btn v12-white-text v12-primary">
礼包已被领取
<view v-if="isTravelGroup">
<view class="btn-wrap">
<button class="share-btn v12-white-text v12-primary" @click="setShowAddressForm(true)">
填写地址并收下
</button>
<button open-type="share" class="share-btn v12-white v12-primary-text v12-d-flex" >
点击转赠给好友
<u-icon :name="webUrl + '/icon/share.png'" ></u-icon>
</button>
</view>
<view class="info-btn v12-text-center v12-font-32 v12-mt-3" style="z-index: 10">去商城看看>></view>
</view>
<view class="tips">
<view class="tip-text v12-mr-1" @click="showTips">
@@ -56,26 +72,35 @@
</view>
</view>
<giftTips ref="giftTips" :richText="giftNotice"></giftTips>
<AddressDialog ref="addressDialog" @save="getReceive"></AddressDialog>
<AddressList ref="AddressList" :addressList="address" @save="getReceive"></AddressList>
<GiftAddressForm
ref="giftAddressForm"
:show="showAddressForm"
:unavailableDates="unavailableDates"
:mid="card.travelGroupProduct.id"
:minBookingDays="card.travelGroupProduct.minBookingDays"
@close="closeAddressForm"
@submit="handleAddressSubmit"
/>
</view>
</template>
<script>
import { getGiftCardSendNotice, getGiftCardReceive } from '@/api/gift'
import { getGiftCardSendNotice, getGiftCardReceive, receiveSojoumGroupBuyGift } from '@/api/gift'
import cookie from "@/utils/store/cookie";
import { getAddressList } from '@/api/user'
import giftTips from './giftTips.vue'
import AddressDialog from './AddressDialog.vue'
import AddressList from './AddressList.vue'
import GiftAddressForm from './GiftAddressForm.vue'
export default {
name: 'GiftCard',
components: {
giftTips,
AddressDialog,
AddressList
GiftAddressForm
},
props: {
isTravelGroup: {
type: Boolean,
default: false
},
// 组件属性
card: {
type: Object,
@@ -91,8 +116,9 @@ export default {
webUrl: this.$VUE_APP_RESOURCES_URL,
// 组件数据
giftNotice: '',
address: [],
order: ''
order: '',
showAddressForm: false,
unavailableDates: ['2025-08-13', '2025-08-14', '2025-08-15', '2025-08-16', '2025-08-17', '2025-08-18', '2025-08-19', '2025-08-20', '2025-08-21', '2025-08-22', '2025-08-23']
}
},
computed: {
@@ -128,6 +154,9 @@ export default {
}
},
methods: {
setShowAddressForm(show) {
this.showAddressForm = true
},
searchGift() {
this.$yrouter.push('/pages/shop/GoodsList/index?s=' +'送礼' )
},
@@ -167,16 +196,49 @@ export default {
}).finally(() => {
})
},
setAddress(flag) {
getAddressList().then(res => {
if (res.data.length === 0) {
this.$refs.addressDialog.open()
} else {
this.address = res.data
if(flag) return
this.$refs.AddressList.open()
}
})
setAddress() {
this.showAddressForm = true;
},
closeAddressForm() {
this.showAddressForm = false;
},
handleAddressSubmit(formData) {
console.log(formData);
uni.showLoading({
title: '领取中...',
mask: true
});
// code string 礼品卡code
// realName string 真实姓名
// phone string 手机号码
// orderStartDate string 起始日期(yyyy-MM-dd
// orderEndDate string 结束日期(yyyy-MM-dd
// 调用领取礼包API
receiveSojoumGroupBuyGift({
code: this.card.code,
realName: formData.realName,
phone: formData.phone,
orderStartDate: formData.checkInDate,
orderEndDate: formData.checkOutDate
}).then(res => {
this.showAddressForm = false;
this.order = res.data.orderId;
this.$emit('receive', this.card.code);
uni.showToast({
title: '领取成功',
icon: 'success'
});
}).catch(() => {
uni.showToast({
title: '领取失败,请重试',
icon: 'none'
});
}).finally(() => {
uni.hideLoading();
});
},
async showTips() {
// 获取发礼提示