Browse Source

feat: 添加降价活动规则弹窗和下拉刷新功能

- 新增降价活动规则弹窗组件及API接口
- 为购物车和销售页面添加下拉刷新功能
- 修复图片显示模式和文本溢出样式
- 启用页面下拉刷新配置
- 恢复商品分享二维码功能
ylong 2 tuần trước cách đây
mục cha
commit
590b632e6d

+ 3 - 0
api/modules/mall.js

@@ -149,6 +149,9 @@ export const useMallApi = (Vue, vm) => {
         // 删除我的足迹
         clearLookLogAjax: (idList) => vm.$u.post('/token/shop/user/clearLookLog', idList),
 
+        // 降价活动规则详情
+        getActivityReduceRuleAjax: () => vm.$u.get('/token/shop/getActivityReduceRule'),
+
          // 获取商品分享二维码
         getIsbnQrcodeAjax: (isbn) => vm.$u.http.get('/token/shop/order/getIsbnQrcode', { isbn }),
 	}

+ 6 - 6
pages-sell/components/detail/share-popup.vue

@@ -62,12 +62,12 @@ export default {
 		open() {
 			this.show = true;
 			this.userInfo = uni.getStorageSync('userInfo') || {};
-			// this.$u.api.getIsbnQrcodeAjax(this.product.isbn).then(res => {
-			// 	if (res.code == 200) {
-			// 		console.log(res);
-			// 		this.qrcodeUrl = res.data;
-			// 	}
-			// });
+			this.$u.api.getIsbnQrcodeAjax(this.product.isbn).then(res => {
+				if (res.code == 200) {
+					console.log(res);
+					this.qrcodeUrl = res.data;
+				}
+			});
 		},
 		close() {
 			this.show = false;

+ 79 - 0
pages-sell/components/reduce-rule-popup/index.vue

@@ -0,0 +1,79 @@
+<template>
+    <common-dialog ref="dialog" title="活动规则" confirmText="确定" :showCancel="false" @confirm="onConfirm" width="640rpx">
+        <view class="rule-content">
+            <view class="rule-item">1.活动时间:{{ ruleData.startTime || '暂无' }}至{{ ruleData.endTime || '暂无' }}。</view>
+            <view class="rule-item">2.助力降价机制:用户成功分享并邀请 1 位好友完成助力,即可享受对应图书的降价优惠,最高可0元购书!</view>
+            <view class="rule-item">3.助力有效期:用户发起助力后,需在{{ ruleData.inviteExpireHour || 24 }}小时内完成好友助力,超时未完成则本次助力失效,可重新发起邀请,有效期以助力成功时间为准。</view>
+            <view class="rule-item">4.助力上限说明:单用户单订单单本图书仅可降价 {{ ruleData.reduceTimesPerIsbn || 1 }} 次,达到次数上限后无法继续通过助力获得优惠;每个用户 ID 每日最多可参与助力 {{ ruleData.assistTimesEveryDay || 1 }} 次,同一好友仅可为同一用户的同一订单助力 1 次,重复助力无效。</view>
+            <view class="rule-item">5.若用户存在恶意刷助力、虚假账号、作弊等违规行为,平台有权直接取消其活动资格、收回已获得的降价优惠,并限制其后续参与平台活动的权限。</view>
+        </view>
+    </common-dialog>
+</template>
+
+<script>
+import commonDialog from '@/components/common-dialog.vue'
+
+export default {
+    components: {
+        commonDialog
+    },
+    data() {
+        return {
+            ruleData: {}
+        }
+    },
+    methods: {
+        open() {
+            this.fetchRuleData();
+            this.$refs.dialog.openPopup();
+        },
+        fetchRuleData() {
+            this.$u.api.getActivityReduceRuleAjax().then(res => {
+                if (res.code === 200) {
+                    // 处理日期格式,只取年月日
+                    let data = res.data || {};
+                    if (data.startTime) {
+                        data.startTime = this.formatDate(data.startTime);
+                    }
+                    if (data.endTime) {
+                        data.endTime = this.formatDate(data.endTime);
+                    }
+                    this.ruleData = data;
+                }
+            })
+        },
+        formatDate(dateStr) {
+            // 将类似 2025-03-25T00:00:00 转换为 2025年3月25日
+            if (!dateStr) return '';
+            let date = new Date(dateStr);
+            if (isNaN(date.getTime())) {
+                // 处理可能带有空格的格式 2025-03-25 00:00:00
+                date = new Date(dateStr.replace(/-/g, '/'));
+            }
+            if (isNaN(date.getTime())) return dateStr;
+            return `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日`;
+        },
+        onConfirm() {
+            // 点击确定,弹窗自动关闭
+            this.$emit('confirm');
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.rule-content {
+    text-align: left;
+    font-size: 26rpx;
+    color: #333333;
+    line-height: 44rpx;
+    max-height: 60vh;
+    overflow-y: auto;
+    padding-bottom: 20rpx;
+
+    .rule-item {
+        margin-bottom: 20rpx;
+        text-align: justify;
+    }
+}
+</style>

+ 14 - 0
pages-sell/components/sell-container/index.vue

@@ -576,6 +576,13 @@ export default {
 
 			.text-orange-light {
 				color: #DB832D;
+				display: inline-block;
+				width: 90%;
+				//超出部分省略号显示
+				overflow: hidden;
+				white-space: nowrap;
+				text-overflow: ellipsis;
+				max-width: 200rpx;
 			}
 
 			.text-green {
@@ -584,6 +591,13 @@ export default {
 
 			.text-green-light {
 				color: #1F8049;
+				display: inline-block;
+				width: 90%;
+				//超出部分省略号显示
+				overflow: hidden;
+				white-space: nowrap;
+				text-overflow: ellipsis;
+				max-width: 200rpx;
 			}
 		}
 

+ 10 - 5
pages-sell/pages/detail.vue

@@ -18,7 +18,7 @@
         <view class="content-scroll">
             <!-- Book Cover Area -->
             <view class="cover-area">
-                <image class="book-cover" :src="product.cover" mode="aspectFill"></image>
+                <image class="book-cover" :src="product.cover" mode="heightFix"></image>
                 <view class="share-btn" @click="openSharePopup">
                     <image src="/pages-sell/static/goods/icon-share.png" class="share-icon"></image>
                     <text>分享</text>
@@ -34,7 +34,7 @@
             </view>
 
             <!-- Service Info -->
-            <ServiceCard @click="showServicePopup" :bookInfo="product"></ServiceCard>
+            <ServiceCard @click="showReduceRulePopup" :bookInfo="product"></ServiceCard>
 
             <!-- Customer Service Float -->
             <FloatingDrag :width="120" :height="120" :initial-position="servicePosition"
@@ -79,6 +79,9 @@
 
         <!-- Share Popup -->
         <SharePopup ref="sharePopup" :product="product"></SharePopup>
+
+        <!-- Reduce Rule Popup -->
+        <ReduceRulePopup ref="reduceRulePopup"></ReduceRulePopup>
     </view>
 </template>
 
@@ -91,6 +94,7 @@
     import FooterBar from '../components/detail/footer-bar.vue'
     import FloatingDrag from "@/components/floating-drag.vue";
     import SharePopup from '../components/detail/share-popup.vue';
+    import ReduceRulePopup from '../components/reduce-rule-popup/index.vue';
 
     export default {
         components: {
@@ -101,7 +105,8 @@
             ProductContent,
             FooterBar,
             FloatingDrag,
-            SharePopup
+            SharePopup,
+            ReduceRulePopup
         },
         data() {
             return {
@@ -218,8 +223,8 @@
                     uni.hideLoading();
                 });
             },
-            showServicePopup() {
-                // Placeholder for service popup
+            showReduceRulePopup() {
+                this.$refs.reduceRulePopup.open();
             },
             onBookClick(book) {
                 console.log('Book clicked:', book);

+ 2 - 1
pages-sell/pages/recommend.vue

@@ -9,7 +9,7 @@
 
 		<!-- Header Content -->
 		<view class="header-content">
-			<image class="header-image" :src="imageUrl" mode="aspectFill"></image>
+			<image class="header-image" :src="imageUrl" mode="widthFix"></image>
 			<view class="header-desc">
 				<view class="title-row">
 					<text class="title-text">{{ showName }}</text>
@@ -192,6 +192,7 @@ export default {
                 align-items: center;
                 justify-content: center;
                 border: none;
+				height: 50rpx;
                 
                 &::after {
                     border: none;

+ 2 - 0
pages.json

@@ -9,6 +9,7 @@
                 "navigationBarTitleText": "书嗨",
                 "navigationBarTextStyle": "white",
                 "navigationStyle": "custom",
+                "enablePullDownRefresh": true,
                 "usingComponents": {
                     "sell-container": "/pages-sell/components/sell-container/index"
                 },
@@ -59,6 +60,7 @@
             "path": "pages/cart/index",
             "style": {
                 "navigationBarTitleText": "购物车",
+                "enablePullDownRefresh": true,
                 "usingComponents": {
                     "cart-container": "/pages-car/pages/index"
                 },

+ 11 - 0
pages/cart/index.vue

@@ -20,6 +20,17 @@
                 }
             });
         },
+        onPullDownRefresh() {
+            // 更新购物车角标并调用子组件的刷新方法
+            this.$updateCartBadge();
+            if (this.$refs.cartContainer) {
+                // 如果 cartContainer 的 loadData 返回 Promise,可以通过 await 等待结束后停止下拉刷新,这里暂直接调用并停止
+                this.$refs.cartContainer.loadData();
+            }
+            setTimeout(() => {
+                uni.stopPullDownRefresh();
+            }, 1000);
+        },
         // 分享配置
         onShareAppMessage(res) {
             console.log(res, '分享');

+ 10 - 1
pages/sell/index.vue

@@ -1,6 +1,6 @@
 <template>
 	<view>
-		<sell-container></sell-container>
+		<sell-container ref="sellContainer"></sell-container>
 	</view>
 </template>
 
@@ -17,6 +17,15 @@ export default {
 	onShow() {
 		this.$updateCartBadge();
 	},
+	onPullDownRefresh() {
+		if (this.$refs.sellContainer) {
+			this.$refs.sellContainer.hasShareList();
+			this.$refs.sellContainer.getIndexCateInfo();
+		}
+		setTimeout(() => {
+			uni.stopPullDownRefresh();
+		}, 1000);
+	},
 	methods: {
 		
 	}