Feat:抽奖2.0(部分接口未调通)

This commit is contained in:
LinCyJang
2026-04-27 08:47:33 +08:00
parent 0202f14073
commit d3602c010e
11 changed files with 2718 additions and 29 deletions
+67 -2
View File
@@ -346,10 +346,34 @@
<!-- v9 老用户弹窗 -->
<u-popup
v-if="isOldUserPopupShow"
v-if="drawEntranceConfig.homePosterEnable"
mode="center"
bgColor="transparent"
:show="isOldUser && oldUserPopup.image && lotteryCanDraw"
:show="isDrawPosterVisible"
>
<view class="popup-old-user flex flex-col ai-center">
<image
:src="drawEntranceConfig.homePosterImage"
class="main"
mode="scaleToFill"
@click="tapDrawPoster()"
/>
<view
class="icon-box flex jc-center ai-center"
@click="closeDrawPoster()"
>
<image
:src="webUrl+'/20230608112219219303.png'"
mode="scaleToFill"
/>
</view>
</view>
</u-popup>
<u-popup
v-if="canShowOldPoster"
mode="center"
bgColor="transparent"
:show="isOldUser"
>
<view class="popup-old-user flex flex-col ai-center">
<image
@@ -431,6 +455,8 @@ export default {
return {
isFirstLoad: true,
isOldUserPopupShow: 0,
isDrawPosterVisible: false,
canShowOldPoster: false,
webUrl: this.$VUE_APP_RESOURCES_URL,
// 状态栏高度
statusBarHeight: 20,
@@ -458,6 +484,8 @@ export default {
// 老用户弹窗
isOldUser: true,
oldUserPopup: {},
// 首页抽奖弹窗入口
drawEntranceConfig: {},
// 民宿专题轮播
contentHomestay: [],
// 新品推荐
@@ -1492,6 +1520,7 @@ export default {
_this.bastLeftList = []
_this.bastRightList = []
_this.lotteryCanDraw = data.lotteryCanDraw || false
_this.initPosterPopupState(data)
if (data.bastList) {
for (let i = 0; i < data.bastList.length; i++) {
if (i % 2 === 0) {
@@ -1544,6 +1573,7 @@ export default {
this.$set(this, 'isOldUserPopupShow', data.isOldUserPopupShow || 0)
this.indexVideo = data.indexVideo ? data.indexVideo.videoUrl : ''
this.lotteryCanDraw = data.lotteryCanDraw || false
this.initPosterPopupState(data)
if (data.bastList) {
const newBastLeftList = []
const newBastRightList = []
@@ -1606,6 +1636,41 @@ export default {
changeOldPopup(state) {
this.isOldUser = state
},
initPosterPopupState(data = {}) {
const drawEntranceConfig = data.drawEntranceConfig || {}
this.$set(this, 'drawEntranceConfig', drawEntranceConfig)
const hasDrawPoster = Number(drawEntranceConfig.homePosterEnable) === 1
this.canShowOldPoster = Boolean(
(data.isOldUserPopupShow || 0) &&
data.oldUserPopup &&
data.oldUserPopup.image &&
(data.lotteryCanDraw || false)
)
this.isDrawPosterVisible = hasDrawPoster
this.isOldUser = !hasDrawPoster && this.canShowOldPoster
},
showNextPoster() {
if (!this.isDrawPosterVisible && this.canShowOldPoster) {
this.isOldUser = true
}
},
closeDrawPoster() {
this.isDrawPosterVisible = false
this.showNextPoster()
},
goDrawLotteryPage() {
const config = this.drawEntranceConfig || {}
const linkType = Number(config.homePosterLinkType) || 1
const activityId = Number(config.homePosterAreaId) || 0
uni.navigateTo({
url: `/pkg-video/views/county-lottery?linkType=${linkType}&activityId=${4}`
})
},
tapDrawPoster() {
this.isDrawPosterVisible = false
this.goDrawLotteryPage()
this.showNextPoster()
},
// 民宿专题
goHomeStay(item) {
if (item.type === 1) {
+333 -20
View File
@@ -309,6 +309,38 @@
@close="pwdPopClose"
@finish="pwdPopFinish"
/>
<view v-if="drawTicketPopup.show" class="draw-ticket-mask" @touchmove.stop.prevent>
<view class="draw-ticket-popup">
<view class="draw-ticket-close" @click="closeDrawTicketPopup">×</view>
<view class="draw-ticket-icon">
<view class="ticket-icon-box">
<view class="ticket-icon-check"></view>
</view>
</view>
<view class="draw-ticket-title">支付成功</view>
<view class="ticket-card-container">
<view class="ticket-badge">
<text>恭喜获得抽奖码</text>
<view class="ticket-badge-arrow"></view>
</view>
<view class="ticket-card">
<view class="ticket-card-subtitle">
<text class="ticket-card-subtitle-text">您的专属抽奖码</text>
</view>
<view class="ticket-card-code-box">
<text class="ticket-card-code">{{ drawTicketPopup.ticketCode }}</text>
</view>
<view class="ticket-card-time" v-if="drawTicketPopup.drawTime">开奖时间{{ drawTicketPopup.drawTime }}</view>
</view>
</view>
<view class="draw-ticket-actions">
<view class="action-btn home-btn" @click="goHomeFromPopup">返回首页</view>
<view class="action-btn primary" @click="goTicketsFromPopup">查看我的抽奖码</view>
</view>
</view>
</view>
</view>
</template>
@@ -328,6 +360,7 @@ import {isNullOrEmpty, isWeixin} from "@/utils"
import blPaymentPasswordInput from '@/components/blPaymentPasswordInput.vue'
import uniPopup from '@/components/uni-popup/uni-popup.vue'
import CouponsPopup from "@/components/CouponsPopup.vue"
import { getDrawTicketByOrder } from '@/api/lottery'
import { pageListenMixins } from '@/mixins/pageListenMixins'
const NAME = "OrderSubmission"
@@ -395,7 +428,13 @@ export default {
pageKeyId: Object.freeze('orderConfirm'),
total: 0,
couponTitle: '',
hasCoupon: false
hasCoupon: false,
drawTicketPopup: {
show: false,
orderId: '',
ticketCode: '',
drawTime: ''
}
}
},
computed: mapGetters(["userInfo", "storeItems"]),
@@ -707,6 +746,7 @@ export default {
createOrder(this.orderGroupInfo.orderKey, params).then(res => {
uni.hideLoading()
const data = res.data
const orderId = data && data.result ? data.result.orderId : ''
switch (data.status) {
case "ORDER_EXIST":
case "EXTEND_ORDER":
@@ -718,7 +758,7 @@ export default {
this.$yrouter.replace({
path: "/pages/order/OrderDetails/index",
query: {
id: data.result.orderId
id: orderId
}
})
break;
@@ -743,21 +783,23 @@ export default {
icon: "none",
duration: 2000
})
if (this.orderGroupInfo.cartInfo && this.orderGroupInfo.cartInfo.length === 1) {
this.$yrouter.replace({
path: "/pages/order/OrderDetails/index",
query: {
id: data.result.orderId
}
})
} else {
this.$yrouter.replace({
path: "/pages/order/MyOrder/index",
query: {
type: 2
}
})
}
this.afterPaySuccess(orderId, () => {
if (this.orderGroupInfo.cartInfo && this.orderGroupInfo.cartInfo.length === 1) {
this.$yrouter.replace({
path: "/pages/order/OrderDetails/index",
query: {
id: orderId
}
})
} else {
this.$yrouter.replace({
path: "/pages/order/MyOrder/index",
query: {
type: 2
}
})
}
})
break;
case "WECHAT_H5_PAY":
// H5支付
@@ -770,7 +812,16 @@ export default {
break;
case "WECHAT_PAY":
// 小程序支付
weappPay(data.result.jsConfig).finally(() => {
weappPay(data.result.jsConfig).then(() => {
this.afterPaySuccess(orderId, () => {
this.$yrouter.replace({
path: "/pages/order/MyOrder/index",
query: {
type: 1
}
})
})
}).catch(() => {
this.$yrouter.replace({
path: "/pages/order/MyOrder/index",
query: {
@@ -781,13 +832,22 @@ export default {
break;
case "WECHAT_APP_PAY":
// APP支付
weappPay(data.result.jsConfig).finally(() => {
weappPay(data.result.jsConfig).then(() => {
this.afterPaySuccess(orderId, () => {
this.$yrouter.replace({
path: "/pages/order/MyOrder/index",
query: {
type: 1
}
})
})
}).catch(() => {
this.$yrouter.replace({
path: "/pages/order/MyOrder/index",
query: {
type: 1
}
});
})
})
break;
}
@@ -830,6 +890,50 @@ export default {
this.computedPrice(1)
// this.couponId = uni.getStorageSync('couponId') || 0
// this.couponTitle = item.couponTitle
},
async afterPaySuccess(orderId, fallback) {
if (!orderId) {
fallback && fallback()
return
}
try {
const res = await getDrawTicketByOrder(orderId)
const result = (res && res.data) || {}
const hasTicket = Number(result.hasTicket || 0) === 1
const howPopup = Number(result.howPopup || 0) === 1
if (hasTicket && howPopup) {
this.drawTicketPopup = {
show: true,
orderId: orderId,
ticketCode: result.ticketCode || '',
drawTime: result.drawTime || ''
}
return
}
} catch (e) {
}
fallback && fallback()
},
closeDrawTicketPopup() {
this.drawTicketPopup.show = false
this.$yrouter.replace({
path: "/pages/order/MyOrder/index",
query: {
type: 1
}
})
},
goHomeFromPopup() {
this.drawTicketPopup.show = false
uni.switchTab({
url: '/pages/home/index'
})
},
goTicketsFromPopup() {
this.drawTicketPopup.show = false
uni.navigateTo({
url: '/pkg-video/views/county-my-tickets'
})
}
}
};
@@ -1007,4 +1111,213 @@ export default {
padding: 20rpx 0 0 0;
color: #999;
}
.draw-ticket-mask {
position: fixed;
inset: 0;
z-index: 1000;
background: rgba(0, 0, 0, 0.45);
display: flex;
align-items: center;
justify-content: center;
padding: 24rpx;
box-sizing: border-box;
}
.draw-ticket-popup {
width: 100%;
max-width: 640rpx;
background: #fff;
border-radius: 40rpx;
padding: 50rpx 40rpx 60rpx;
position: relative;
box-sizing: border-box;
}
.draw-ticket-close {
position: absolute;
top: 30rpx;
right: 30rpx;
width: 60rpx;
height: 60rpx;
border: 4rpx solid #111;
border-radius: 50%;
font-size: 50rpx;
color: #111;
line-height: 52rpx;
text-align: center;
font-weight: 500;
z-index: 10;
}
.draw-ticket-icon {
display: flex;
justify-content: center;
margin-top: 20rpx;
}
.ticket-icon-box {
width: 90rpx;
height: 70rpx;
border: 6rpx solid #111;
border-radius: 10rpx;
position: relative;
box-sizing: border-box;
}
.ticket-icon-box::before {
content: '';
position: absolute;
top: -16rpx;
left: 14rpx;
width: 50rpx;
height: 12rpx;
border-top: 6rpx solid #111;
border-left: 6rpx solid #111;
border-right: 6rpx solid #111;
border-radius: 6rpx 6rpx 0 0;
background: #fff;
}
.ticket-icon-check {
width: 36rpx;
height: 18rpx;
border-left: 6rpx solid #c23326;
border-bottom: 6rpx solid #c23326;
transform: rotate(-45deg);
position: absolute;
left: 20rpx;
top: 14rpx;
}
.draw-ticket-title {
font-size: 56rpx;
color: #222;
font-weight: 800;
text-align: center;
margin-top: 24rpx;
letter-spacing: 2rpx;
}
.ticket-card-container {
margin-top: 50rpx;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
}
.ticket-badge {
background-color: #fff9eb;
border: 6rpx solid #111;
border-radius: 40rpx;
padding: 12rpx 40rpx;
font-size: 46rpx;
font-weight: 800;
color: #222;
position: relative;
z-index: 2;
margin-bottom: -36rpx;
letter-spacing: 2rpx;
}
.ticket-badge-arrow {
position: absolute;
bottom: -22rpx;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 22rpx solid transparent;
border-right: 22rpx solid transparent;
border-top: 22rpx solid #111;
}
.ticket-badge-arrow::after {
content: '';
position: absolute;
top: -26rpx;
left: -16rpx;
border-left: 16rpx solid transparent;
border-right: 16rpx solid transparent;
border-top: 16rpx solid #fff9eb;
}
.ticket-card {
width: 100%;
background: #c23326;
border-radius: 36rpx;
padding: 70rpx 36rpx 40rpx;
box-sizing: border-box;
text-align: center;
position: relative;
}
.ticket-card-subtitle {
display: flex;
justify-content: center;
}
.ticket-card-subtitle-text {
color: #fff;
font-size: 34rpx;
font-weight: 700;
border: 2rpx solid #fff;
border-radius: 40rpx;
padding: 8rpx 50rpx;
letter-spacing: 4rpx;
}
.ticket-card-code-box {
background: #fff;
border-radius: 20rpx;
margin-top: 36rpx;
padding: 36rpx 0;
}
.ticket-card-code {
color: #c23326;
font-size: 72rpx;
font-weight: 800;
letter-spacing: 8rpx;
}
.ticket-card-time {
color: #fff;
font-size: 30rpx;
margin-top: 36rpx;
letter-spacing: 1rpx;
}
.draw-ticket-actions {
margin-top: 60rpx;
display: flex;
justify-content: space-between;
align-items: center;
gap: 20rpx;
}
.action-btn {
flex: 1;
height: 86rpx;
border-radius: 44rpx;
font-size: 32rpx;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
white-space: nowrap;
}
.action-btn.home-btn {
color: #c23326;
border: 2rpx solid #c23326;
background: #fff;
}
.action-btn.primary {
color: #fff;
background: #c23326;
}
</style>
+34
View File
@@ -215,6 +215,13 @@
</view>
</view>
</view>
<view
v-if="drawConfig.myTicketImageEnable === 1 && drawConfig.myTicketImage"
class="my-ticket-entry"
@click="goMyTicketList"
>
<image :src="drawConfig.myTicketImage" mode="widthFix" class="img" />
</view>
<!-- 我的服务开始 -->
<view class="myService" style="margin-top: 30rpx !important;">
<view class="title acea-row row-middle">
@@ -301,6 +308,7 @@ import {
noticeList,
getUserCenterBanner
} from "@/api/user"
import { getDrawConfig } from '@/api/lottery'
import {isWeixin} from "@/utils"
import cookie from "@/utils/store/cookie"
import { pageListenMixins } from '@/mixins/pageListenMixins'
@@ -389,6 +397,10 @@ export default {
],
bannerBgUrl: '',
userCenterBannerUrl: '',
drawConfig: {
myTicketImage: '',
myTicketImageEnable: 0
},
pageKeyId: Object.freeze('userIndex'),
nowrap: true,
// 是否已登录
@@ -403,6 +415,7 @@ export default {
},
onShow() {
uni.$emit('updateUnreadMessageCount')
this.getDrawConfigReq()
if (this.$store.getters.token) {
this.isNoLogin = false
uni.showLoading({
@@ -429,6 +442,19 @@ export default {
},
methods: {
...mapMutations(['updateAuthorizationPage']),
getDrawConfigReq() {
getDrawConfig().then(res => {
if (res && res.data) {
this.drawConfig = {
myTicketImage: res.data.myTicketImage || '',
myTicketImageEnable: Number(res.data.myTicketImageEnable) || 0
}
}
}).catch(() => {})
},
goMyTicketList() {
this.linkTo('/pkg-video/views/county-my-tickets')
},
// 新增方法:计算文本像素长度
getTextWidth() {
this.$nextTick(() => {
@@ -681,6 +707,14 @@ export default {
}
.my-wrapper {
padding: 30upx;
.my-ticket-entry {
margin-top: 30rpx;
.img {
width: 100%;
border-radius: 24rpx;
display: block;
}
}
&.wrapper {
padding: 0 0 30rpx 0 !important;
}