ソースを参照

feat: 重构红包弹窗功能并调整展示逻辑

- 将红包弹窗从搜索页移至搜索结果页,改为动态触发
- 红包弹窗组件改为 ref 调用方式,支持传入优惠券数据动态展示
- 搜索结果接口返回优惠券信息时自动弹出红包弹窗
- 调整搜索页底部内边距,移除搜索页红包浮动按钮
- 修正推荐商品加入购物车的 sourceFrom 参数值
ylong 2 週間 前
コミット
9588712273

+ 142 - 143
pages-sell/components/packet-dialog/index.vue

@@ -5,13 +5,14 @@
 			<view class="dialog-body">
 				<image src="/pages-sell/static/search/packet-dialog.png" class="dialog-bg" mode="widthFix"></image>
 				<view class="content-overlay">
-					<text class="dialog-title">惊喜红包!</text>
+					<text class="dialog-title">{{ detail.couponName }}</text>
 					<view class="amount-wrapper">
-						<text class="amount-num">15</text>
+						<text class="amount-num">{{ detail.faceMoney }}</text>
 						<text class="amount-unit">元</text>
 					</view>
 					<view class="condition-box">
-						<text>满0.01可用 24小时有效</text>
+						<text v-if="detail.thresholdMoney == 0">无门槛可用</text>
+						<text v-else>满{{ detail.thresholdMoney }}可用 24小时有效</text>
 					</view>
 					<view class="btn-accept" @click="close">
 						<text>开心收下</text>
@@ -26,172 +27,170 @@
 </template>
 
 <script>
-export default {
-	name: 'PacketDialog',
-	props: {
-		value: {
-			type: Boolean,
-			default: false
-		}
-	},
-	data() {
-		return {
-			visible: false
-		}
-	},
-	watch: {
-		value: {
-			handler(val) {
-				this.visible = val;
-			},
-			immediate: true
+	export default {
+		name: 'PacketDialog',
+		props: {
+			value: {
+				type: Boolean,
+				default: false
+			}
 		},
-		visible(val) {
-			this.$emit('input', val);
-		}
-	},
-	methods: {
-		close() {
-			this.visible = false;
+		data() {
+			return {
+				visible: false,
+				detail: {
+					couponName: '',
+					faceMoney: 0,
+					thresholdMoney: 0,
+				}
+			}
+		},
+		methods: {
+			open(data) {
+				this.visible = true;
+				this.detail = data;
+			},
+			close() {
+				this.visible = false;
+			}
 		}
 	}
-}
 </script>
 
 <style lang="scss" scoped>
-.custom-popup {
-	position: fixed;
-	top: 0;
-	left: 0;
-	right: 0;
-	bottom: 0;
-	z-index: 999;
-	display: flex;
-	align-items: center;
-	justify-content: center;
-	transition: all 0.3s ease-in-out;
-
-	.popup-mask {
-		position: absolute;
+	.custom-popup {
+		position: fixed;
 		top: 0;
 		left: 0;
-		width: 100%;
-		height: 100%;
-		background: #000000;
-		opacity: 0.7;
-	}
-}
-
-.packet-dialog-container {
-	position: relative;
-	display: flex;
-	flex-direction: column;
-	align-items: center;
-	z-index: 1000;
-	
-	.dialog-body {
-		position: relative;
-		width: 640rpx;
-		// height is determined by image aspect ratio
-		
-		.dialog-bg {
-			width: 100%;
-			display: block;
-		}
-		
-		.content-overlay {
+		right: 0;
+		bottom: 0;
+		z-index: 999;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		transition: all 0.3s ease-in-out;
+
+		.popup-mask {
 			position: absolute;
 			top: 0;
 			left: 0;
 			width: 100%;
 			height: 100%;
-			display: flex;
-			flex-direction: column;
-			align-items: center;
-			justify-content: center;
-			padding-top: 120rpx;
-			padding-left: 50rpx;
-			
-			.dialog-title {
-				font-size: 38rpx;
-				font-weight: bold;
-				color: #B31700;
-				margin-bottom: 20rpx;
-				padding-top: 50rpx;
+			background: #000000;
+			opacity: 0.7;
+		}
+	}
+
+	.packet-dialog-container {
+		position: relative;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		z-index: 1000;
+
+		.dialog-body {
+			position: relative;
+			width: 640rpx;
+			// height is determined by image aspect ratio
+
+			.dialog-bg {
+				width: 100%;
+				display: block;
 			}
-			
-			.amount-wrapper {
+
+			.content-overlay {
+				position: absolute;
+				top: 0;
+				left: 0;
+				width: 100%;
+				height: 100%;
 				display: flex;
-				align-items: baseline;
+				flex-direction: column;
+				align-items: center;
 				justify-content: center;
-				margin-bottom: 20rpx;
-				
-				.amount-num {
-					font-family: Arial;
+				padding-top: 120rpx;
+				padding-left: 50rpx;
+
+				.dialog-title {
+					font-size: 38rpx;
 					font-weight: bold;
-					font-size: 80rpx;
 					color: #B31700;
-					background: linear-gradient(214deg, rgba(179,23,0,0.69) 0%, rgba(255,132,0,0.69) 100%);
-					-webkit-background-clip: text;
-					-webkit-text-fill-color: transparent;
+					margin-bottom: 20rpx;
+					padding-top: 50rpx;
 				}
-				
-				.amount-unit {
-					color: #B31700;
-					font-size: 38rpx;
-					font-weight: bold;
-					margin-left: 4rpx;
+
+				.amount-wrapper {
+					display: flex;
+					align-items: baseline;
+					justify-content: center;
+					margin-bottom: 20rpx;
+
+					.amount-num {
+						font-family: Arial;
+						font-weight: bold;
+						font-size: 80rpx;
+						color: #B31700;
+						background: linear-gradient(214deg, rgba(179, 23, 0, 0.69) 0%, rgba(255, 132, 0, 0.69) 100%);
+						-webkit-background-clip: text;
+						-webkit-text-fill-color: transparent;
+					}
+
+					.amount-unit {
+						color: #B31700;
+						font-size: 38rpx;
+						font-weight: bold;
+						margin-left: 4rpx;
+					}
 				}
-			}
-			
-			.condition-box {
-				padding: 4rpx 20rpx;
-				border-radius: 8rpx;
-				
-				text {
-					font-size: 24rpx;
-					color: #B31700;
+
+				.condition-box {
+					padding: 4rpx 20rpx;
+					border-radius: 8rpx;
+
+					text {
+						font-size: 24rpx;
+						color: #B31700;
+					}
+				}
+
+				.btn-accept {
+					width: 300rpx;
+					height: 96rpx;
+					background: linear-gradient(180deg, #FFF5D6 0%, #FFDFA8 100%);
+					border-radius: 48rpx;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+					box-shadow: 0 4rpx 10rpx rgba(179, 23, 0, 0.3);
+					margin-top: 20rpx; // Adjust positioning
+
+					text {
+						color: #B31700;
+						font-size: 32rpx;
+						font-weight: bold;
+					}
 				}
 			}
-			
-			.btn-accept {
-				width: 300rpx;
-				height: 96rpx;
-				background: linear-gradient(180deg, #FFF5D6 0%, #FFDFA8 100%);
-				border-radius: 48rpx;
+		}
+
+		.close-area {
+			position: absolute;
+			top: 0rpx;
+			right: 0;
+
+			.close-icon-custom {
+				width: 60rpx;
+				height: 60rpx;
+				border: 2rpx solid #fff;
+				border-radius: 50%;
+				color: #fff;
+				font-size: 50rpx;
+				line-height: 54rpx;
 				display: flex;
 				align-items: center;
 				justify-content: center;
-				box-shadow: 0 4rpx 10rpx rgba(179, 23, 0, 0.3);
-				margin-top: 20rpx; // Adjust positioning
-				
-				text {
-					color: #B31700;
-					font-size: 32rpx;
-					font-weight: bold;
-				}
+				padding-bottom: 6rpx; // Visual adjustment for 'x'
 			}
 		}
 	}
-	
-	.close-area {
-		position: absolute;
-		top: 0rpx;
-		right: 0;
-		
-		.close-icon-custom {
-			width: 60rpx;
-			height: 60rpx;
-			border: 2rpx solid #fff;
-			border-radius: 50%;
-			color: #fff;
-			font-size: 50rpx;
-			line-height: 54rpx;
-			display: flex;
-			align-items: center;
-			justify-content: center;
-			padding-bottom: 6rpx; // Visual adjustment for 'x'
-		}
-	}
-}
 </style>

+ 1 - 1
pages-sell/components/recommend-item/index.vue

@@ -77,7 +77,7 @@ export default {
 		handleAddToCart() {
 			// Open the popup using ref
 			// 加入购物车时,传递 sourceFrom 参数为 2
-			this.$refs.popup.open(this.item, 2);
+			this.$refs.popup.open(this.item, 1);
 		},
 		onPopupConfirm(data) {
 			// Emit the confirmed data

+ 65 - 1
pages-sell/pages/search-result.vue

@@ -79,6 +79,19 @@
                 </view>
             </view>
         </u-popup>
+
+        <!-- Red Packet Float -->
+        <!-- <view class="red-packet-float" @click="openPacket">
+            <view class="time-badge">
+                <text>剩</text>
+                <u-count-down :timestamp="timestamp" separator="colon" color="#DF1407" bg-color="transparent"
+                    font-size="18" separator-size="18" separator-color="#DF1407"></u-count-down>
+            </view>
+            <image src="/pages-sell/static/search/icon-red-packet.png" class="packet-img" mode="aspectFit"></image>
+        </view> -->
+
+        <!-- Surprise Packet Dialog -->
+        <PacketDialog ref="packetDialog"></PacketDialog>
     </view>
 </template>
 
@@ -86,12 +99,14 @@
     import RecommendItem from '../components/recommend-item/index.vue';
     import HotRecommendItem from '../components/hot-recommend-item/index.vue';
     import Navbar from '@/components/navbar/navbar.vue';
+    import PacketDialog from '@/pages-sell/components/packet-dialog/index.vue';
 
     export default {
         components: {
             RecommendItem,
             HotRecommendItem,
             Navbar,
+            PacketDialog
         },
         data() {
             return {
@@ -109,7 +124,8 @@
                 tempMinPrice: '',
                 tempMaxPrice: '',
                 minPrice: '',
-                maxPrice: ''
+                maxPrice: '',
+                timestamp: 86400, // 24 hours countdown
             }
         },
         onPullDownRefresh() {
@@ -163,6 +179,14 @@
                     } else {
                         this.loadStatus = 'loadmore';
                     }
+
+                    if(res.data.couponName){
+                        this.openPacket({
+                            couponName: res.data.couponName,
+                            faceMoney: res.data.faceMoney,
+                            thresholdMoney: res.data.thresholdMoney,
+                        });
+                    }
                 }).catch(() => {
                     uni.stopPullDownRefresh();
                     this.loadStatus = 'loadmore';
@@ -232,6 +256,12 @@
                     title: '已加入购物车',
                     icon: 'success'
                 });
+            },
+            openPacket(data) {
+                this.$refs.packetDialog.open(data);
+            },
+            closePacket() {
+                this.$refs.packetDialog.close();
             }
         }
     }
@@ -417,4 +447,38 @@
             }
         }
     }
+
+    .red-packet-float {
+        position: fixed;
+        bottom: 200rpx;
+        right: 40rpx;
+        z-index: 100;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+
+        .time-badge {
+            background: #FFE173;
+            color: #DF1407;
+            font-size: 18rpx;
+            padding: 4rpx 10rpx;
+            border-radius: 10rpx;
+            position: absolute;
+            top: -40rpx;
+            right: -20rpx;
+            white-space: nowrap;
+            z-index: 2;
+            display: flex;
+            align-items: center;
+
+            text {
+                margin-right: 4rpx;
+            }
+        }
+
+        .packet-img {
+            width: 100rpx;
+            height: 120rpx;
+        }
+    }
 </style>

+ 1 - 58
pages-sell/pages/search.vue

@@ -52,30 +52,15 @@
                 </view>
             </view>
         </view>
-
-        <!-- Red Packet Float -->
-        <view class="red-packet-float" @click="openPacket">
-            <view class="time-badge">
-                <text>剩</text>
-                <u-count-down :timestamp="timestamp" separator="colon" color="#DF1407" bg-color="transparent"
-                    font-size="18" separator-size="18" separator-color="#DF1407"></u-count-down>
-            </view>
-            <image src="/pages-sell/static/search/icon-red-packet.png" class="packet-img" mode="aspectFit"></image>
-        </view>
-
-        <!-- Surprise Packet Dialog -->
-        <PacketDialog v-model="showPacketDialog"></PacketDialog>
     </view>
 </template>
 
 <script>
     import Navbar from '@/components/navbar/navbar.vue';
-    import PacketDialog from '@/pages-sell/components/packet-dialog/index.vue';
 
     export default {
         components: {
             Navbar,
-            PacketDialog
         },
         data() {
             return {
@@ -83,8 +68,6 @@
                 historyList: [],
                 hotVisible: true,
                 hotList: [],
-                timestamp: 86400, // 24 hours countdown
-                showPacketDialog: false
             }
         },
         onShow() {
@@ -142,12 +125,6 @@
             },
             toggleHot() {
                 this.hotVisible = !this.hotVisible;
-            },
-            openPacket() {
-                this.showPacketDialog = true;
-            },
-            closePacket() {
-                this.showPacketDialog = false;
             }
         }
     }
@@ -204,7 +181,7 @@
     }
 
     .section {
-        padding: 30rpx;
+        padding: 0 30rpx 30rpx;
 
         .section-header {
             display: flex;
@@ -272,38 +249,4 @@
             }
         }
     }
-
-    .red-packet-float {
-        position: fixed;
-        bottom: 200rpx;
-        right: 40rpx;
-        z-index: 100;
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-
-        .time-badge {
-            background: #FFE173;
-            color: #DF1407;
-            font-size: 18rpx;
-            padding: 4rpx 10rpx;
-            border-radius: 10rpx;
-            position: absolute;
-            top: -40rpx;
-            right: -20rpx;
-            white-space: nowrap;
-            z-index: 2;
-            display: flex;
-            align-items: center;
-
-            text {
-                margin-right: 4rpx;
-            }
-        }
-
-        .packet-img {
-            width: 100rpx;
-            height: 120rpx;
-        }
-    }
 </style>