vhall-mini-sdk 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/gift/gift-display/gift-display.js +118 -0
- package/dist/components/gift/gift-display/gift-display.json +3 -0
- package/dist/components/gift/gift-display/gift-display.wxml +16 -0
- package/dist/components/gift/gift-display/gift-display.wxss +1 -0
- package/dist/components/gift/gift-sender/gift-sender.js +63 -0
- package/dist/components/gift/gift-sender/gift-sender.json +6 -0
- package/dist/components/gift/gift-sender/gift-sender.wxml +19 -0
- package/dist/components/gift/gift-sender/gift-sender.wxss +1 -0
- package/dist/components/lottery/lottery-accept/index.js +249 -0
- package/dist/components/lottery/lottery-accept/index.json +4 -0
- package/dist/components/lottery/lottery-accept/index.wxml +49 -0
- package/dist/components/lottery/lottery-accept/index.wxss +1 -0
- package/dist/components/lottery/lottery-history/index.js +36 -0
- package/dist/components/lottery/lottery-history/index.json +3 -0
- package/dist/components/lottery/lottery-history/index.wxml +28 -0
- package/dist/components/lottery/lottery-history/index.wxss +1 -0
- package/dist/components/lottery/lottery-shake/lottery-shake.js +328 -0
- package/dist/components/lottery/lottery-shake/lottery-shake.json +1 -0
- package/dist/components/lottery/lottery-shake/lottery-shake.wxml +52 -0
- package/dist/components/lottery/lottery-shake/lottery-shake.wxss +1 -0
- package/dist/components/lottery/lottery-slot/lottery-slot.js +230 -0
- package/dist/components/lottery/lottery-slot/lottery-slot.json +1 -0
- package/dist/components/lottery/lottery-slot/lottery-slot.wxml +62 -0
- package/dist/components/lottery/lottery-slot/lottery-slot.wxss +1 -0
- package/dist/components/lottery/lottery-wheel/lottery-wheel.js +153 -0
- package/dist/components/lottery/lottery-wheel/lottery-wheel.json +4 -0
- package/dist/components/lottery/lottery-wheel/lottery-wheel.wxml +91 -0
- package/dist/components/lottery/lottery-wheel/lottery-wheel.wxss +1 -0
- package/dist/components/lottery/lottery-winners/index.js +101 -0
- package/dist/components/lottery/lottery-winners/index.json +4 -0
- package/dist/components/lottery/lottery-winners/index.wxml +39 -0
- package/dist/components/lottery/lottery-winners/index.wxss +1 -0
- package/dist/components/lottery/lottery.js +388 -0
- package/dist/components/lottery/lottery.json +11 -0
- package/dist/components/lottery/lottery.wxml +78 -0
- package/dist/components/lottery/lottery.wxss +1 -0
- package/dist/components/lottery/wheel.json +49 -0
- package/dist/components/mall-reward/common/reward-card.wxss +0 -0
- package/dist/components/mall-reward/duration-icon/index.js +101 -0
- package/dist/components/mall-reward/duration-icon/index.json +3 -0
- package/dist/components/mall-reward/duration-icon/index.wxml +7 -0
- package/dist/components/mall-reward/duration-icon/index.wxss +1 -0
- package/dist/components/mall-reward/f-count-down/index.js +61 -0
- package/dist/components/mall-reward/f-count-down/index.json +3 -0
- package/dist/components/mall-reward/f-count-down/index.wxml +9 -0
- package/dist/components/mall-reward/f-count-down/index.wxss +1 -0
- package/dist/components/mall-reward/f-empty/index.js +11 -0
- package/dist/components/mall-reward/f-empty/index.json +3 -0
- package/dist/components/mall-reward/f-empty/index.wxml +8 -0
- package/dist/components/mall-reward/f-empty/index.wxss +1 -0
- package/dist/components/mall-reward/f-history/index.js +84 -0
- package/dist/components/mall-reward/f-history/index.json +4 -0
- package/dist/components/mall-reward/f-history/index.wxml +38 -0
- package/dist/components/mall-reward/f-history/index.wxss +1 -0
- package/dist/components/mall-reward/f-open/index.js +36 -0
- package/dist/components/mall-reward/f-open/index.json +3 -0
- package/dist/components/mall-reward/f-open/index.wxml +10 -0
- package/dist/components/mall-reward/f-open/index.wxss +1 -0
- package/dist/components/mall-reward/f-receive/index.js +36 -0
- package/dist/components/mall-reward/f-receive/index.json +3 -0
- package/dist/components/mall-reward/f-receive/index.wxml +9 -0
- package/dist/components/mall-reward/f-receive/index.wxss +1 -0
- package/dist/components/mall-reward/index.js +374 -0
- package/dist/components/mall-reward/index.json +8 -0
- package/dist/components/mall-reward/index.wxml +4 -0
- package/dist/components/mall-reward/index.wxss +0 -0
- package/dist/components/mall-reward/main-popup/index.js +46 -0
- package/dist/components/mall-reward/main-popup/index.json +12 -0
- package/dist/components/mall-reward/main-popup/index.wxml +16 -0
- package/dist/components/mall-reward/main-popup/index.wxss +1 -0
- package/dist/components/praise/praise.js +150 -0
- package/dist/components/praise/praise.json +5 -0
- package/dist/components/praise/praise.wxml +17 -0
- package/dist/components/praise/praise.wxss +1 -0
- package/dist/components/product/product-card/product-card.js +109 -0
- package/dist/components/product/product-card/product-card.json +3 -0
- package/dist/components/product/product-card/product-card.wxml +47 -0
- package/dist/components/product/product-card/product-card.wxss +1 -0
- package/dist/components/product/product-detail/product-detail.js +127 -0
- package/dist/components/product/product-detail/product-detail.json +3 -0
- package/dist/components/product/product-detail/product-detail.wxml +57 -0
- package/dist/components/product/product-detail/product-detail.wxss +1 -0
- package/dist/components/product/product-item/product-item.js +56 -0
- package/dist/components/product/product-item/product-item.json +3 -0
- package/dist/components/product/product-item/product-item.wxml +35 -0
- package/dist/components/product/product-item/product-item.wxss +1 -0
- package/dist/components/product/product-list/product-list.js +67 -0
- package/dist/components/product/product-list/product-list.json +6 -0
- package/dist/components/product/product-list/product-list.wxml +16 -0
- package/dist/components/product/product-list/product-list.wxss +1 -0
- package/dist/components/product/product-order/product-order.js +394 -0
- package/dist/components/product/product-order/product-order.json +3 -0
- package/dist/components/product/product-order/product-order.wxml +75 -0
- package/dist/components/product/product-order/product-order.wxss +1 -0
- package/dist/pubComponents/popup/popup.wxss +1 -0
- package/dist/sdk/config/index.js +1 -0
- package/dist/sdk/plugins/InteractServer.js +1 -0
- package/dist/sdk/plugins/LotteryServer.js +1 -0
- package/dist/sdk/plugins/MallRewardServer.js +1 -0
- package/dist/sdk/plugins/ProductServer.js +1 -0
- package/lib/components/player/components/controls/controls.wxml +6 -3
- package/lib/components/player/components/controls/controls.wxss +1 -1
- package/lib/components/player/player.wxml +26 -24
- package/lib/components/player/player.wxss +1 -1
- package/lib/sdk/main/index.js +2 -2
- package/lib/shared/mpUtils.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { appendParamsToPath } from '../../../shared/utils.js';
|
|
2
|
+
|
|
3
|
+
Component({
|
|
4
|
+
properties: {
|
|
5
|
+
// SDK实例
|
|
6
|
+
sdkInstance: {
|
|
7
|
+
type: Object,
|
|
8
|
+
value: null,
|
|
9
|
+
observer: function(newVal) {
|
|
10
|
+
if (newVal) {
|
|
11
|
+
this.initStoreListener();
|
|
12
|
+
// 初始加载商品数据
|
|
13
|
+
const productServer = newVal.get('productServer');
|
|
14
|
+
if (productServer) {
|
|
15
|
+
productServer.getProductList();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
data: {
|
|
22
|
+
// 商品列表数据
|
|
23
|
+
products: []
|
|
24
|
+
},
|
|
25
|
+
lifetimes: {
|
|
26
|
+
attached() {
|
|
27
|
+
},
|
|
28
|
+
detached() {
|
|
29
|
+
// 组件卸载时移除store监听
|
|
30
|
+
if (this.unsub) {
|
|
31
|
+
this.unsub();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
methods: {
|
|
36
|
+
// 初始化store监听
|
|
37
|
+
initStoreListener() {
|
|
38
|
+
if (this.unsub) {
|
|
39
|
+
this.unsub();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this.unsub = this.properties.sdkInstance.store.get({
|
|
43
|
+
productList: (val) => {
|
|
44
|
+
if (val) {
|
|
45
|
+
// 只显示 push_status == 1 的商品
|
|
46
|
+
const filteredProducts = val.filter(product => product.push_status === 1);
|
|
47
|
+
// 最多显示3个商品卡片
|
|
48
|
+
const products = filteredProducts.slice(0, 3);
|
|
49
|
+
this.setData({
|
|
50
|
+
products: products
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
// 点击商品卡片(打开详情)
|
|
57
|
+
onCardClick(e) {
|
|
58
|
+
const index = parseInt(e.currentTarget.dataset.index);
|
|
59
|
+
const product = this.data.products[index];
|
|
60
|
+
if (product) {
|
|
61
|
+
this.triggerEvent('cardClick', product);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
// 点击购买按钮(走购买逻辑)
|
|
65
|
+
onBuyClick(e) {
|
|
66
|
+
const index = parseInt(e.currentTarget.dataset.index);
|
|
67
|
+
const product = this.data.products[index];
|
|
68
|
+
if (!product) {
|
|
69
|
+
console.error('商品数据不存在');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 检查是否已抢光或待开价
|
|
74
|
+
if (product.sale_status === 0 || product.covered_status === 1) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 检查 buy_type
|
|
79
|
+
if (product.buy_type === 4 && product?.mini_program_config?.mini_program_path) {
|
|
80
|
+
// 跳转到小程序路径
|
|
81
|
+
const webinarId = this.properties.sdkInstance.store.get('webinarId');
|
|
82
|
+
console.log("跳转小程序路径:", appendParamsToPath(product?.mini_program_config?.mini_program_path, { webinarId }))
|
|
83
|
+
wx.navigateTo({
|
|
84
|
+
url: appendParamsToPath(product?.mini_program_config?.mini_program_path, { webinarId })
|
|
85
|
+
});
|
|
86
|
+
} else if (product.buy_type === 1) {
|
|
87
|
+
// 触发购买事件,由父组件显示下单弹窗
|
|
88
|
+
this.triggerEvent('buyClick', product);
|
|
89
|
+
} else {
|
|
90
|
+
// 提示无法购买
|
|
91
|
+
wx.showToast({
|
|
92
|
+
title: '无法购买,请联系主办方',
|
|
93
|
+
icon: 'none',
|
|
94
|
+
duration: 2000
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
// 点击关闭按钮(通过改变本地数据关闭卡片)
|
|
99
|
+
onCloseCard(e) {
|
|
100
|
+
const productId = e.currentTarget.dataset.productId;
|
|
101
|
+
|
|
102
|
+
// 从本地数据中移除该商品
|
|
103
|
+
const updatedProducts = this.data.products.filter(product => product.goods_id !== productId);
|
|
104
|
+
this.setData({
|
|
105
|
+
products: updatedProducts
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<view class="product-card-container">
|
|
2
|
+
<block wx:for="{{products}}" wx:key="{{item.goods_id}}">
|
|
3
|
+
<view
|
|
4
|
+
class="product-card {{(item.sale_status === 0 || item.covered_status === 1) ? 'product-card-disabled' : ''}} {{products.length > 1 ? 'product-card-small' : ''}}"
|
|
5
|
+
>
|
|
6
|
+
<!-- 讲解中徽章 -->
|
|
7
|
+
<view class="product-card-badge">
|
|
8
|
+
<image class="product-card-badge-icon" src="https://cnstatic01.e.vhall.com/common-static/saas-wap/static/img/live.b07d13f4.gif" mode="heightFix"></image>
|
|
9
|
+
讲解中
|
|
10
|
+
</view>
|
|
11
|
+
|
|
12
|
+
<!-- 关闭按钮 -->
|
|
13
|
+
<view class="product-card-close" bindtap="onCloseCard" data-product-id="{{item.goods_id}}">x</view>
|
|
14
|
+
|
|
15
|
+
<!-- 商品图片(点击打开详情) -->
|
|
16
|
+
<view class="product-card-image" bindtap="onCardClick" data-index="{{index}}">
|
|
17
|
+
<image class="product-card-img"
|
|
18
|
+
src="{{item.cover_img || 'https://cnstatic01.e.vhall.com/common-static/images/default_avatar.png'}}"
|
|
19
|
+
mode="aspectFill"
|
|
20
|
+
></image>
|
|
21
|
+
<!-- 已抢光遮罩层 -->
|
|
22
|
+
<view wx:if="{{item.sale_status === 0}}" class="product-card-mask">
|
|
23
|
+
<text class="product-card-mask-text">已抢光</text>
|
|
24
|
+
</view>
|
|
25
|
+
</view>
|
|
26
|
+
|
|
27
|
+
<!-- 商品信息 -->
|
|
28
|
+
<view class="product-card-info">
|
|
29
|
+
<!-- 商品名称(点击打开详情) -->
|
|
30
|
+
<text class="product-card-title" bindtap="onCardClick" data-index="{{index}}">{{item.name || '商品名称'}}</text>
|
|
31
|
+
|
|
32
|
+
<!-- 价格和购买按钮 -->
|
|
33
|
+
<view class="product-card-price-container" bindtap="onBuyClick" data-index="{{index}}">
|
|
34
|
+
|
|
35
|
+
<block wx:if="{{item.covered_status === 1}}">
|
|
36
|
+
<text class="product-card-price">¥?</text>
|
|
37
|
+
</block>
|
|
38
|
+
<block wx:else>
|
|
39
|
+
<text class="product-card-price">¥{{item.discount_price || item.price || 0}}</text>
|
|
40
|
+
</block>
|
|
41
|
+
|
|
42
|
+
<image class="buy-icon" src="//cnstatic01.e.vhall.com/common-static/saas-wap/static/img/rob.4306d2b5.png" mode="heightFix" ></image>
|
|
43
|
+
</view>
|
|
44
|
+
</view>
|
|
45
|
+
</view>
|
|
46
|
+
</block>
|
|
47
|
+
</view>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.product-card-container{align-items:flex-end;bottom:180rpx;display:flex;flex-direction:column;gap:16rpx;position:fixed;right:20rpx;z-index:999}.product-card{animation:slideIn .3s ease-out forwards;background-color:#fff;border-radius:12rpx;box-shadow:0 4rpx 12rpx rgba(0,0,0,.15);opacity:0;overflow:hidden;position:relative;transform:translateX(100%);width:240rpx}.product-card:first-child{animation-delay:0s}.product-card:nth-child(2){animation-delay:.1s}.product-card:nth-child(3){animation-delay:.2s}@keyframes slideIn{0%{opacity:0;transform:translateX(100%)}to{opacity:1;transform:translateX(0)}}.product-card-badge{background-color:rgba(0,0,0,.6);border-radius:30rpx;color:#fff;font-size:.71rem;left:8rpx;padding:4rpx 20rpx;position:absolute;top:8rpx;z-index:10}.product-card-badge .product-card-badge-icon{height:20rpx}.product-card-close{color:#fff;font-size:1.14rem;padding:0 14rpx;position:absolute;right:0rpx;top:0rpx;z-index:10}.product-card-image{height:240rpx;position:relative;width:100%}.product-card-image .product-card-img{height:100%;object-fit:cover;width:100%}.product-card-info{padding:12rpx}.product-card-title{color:#333;display:block;font-size:.86rem;font-weight:500;margin-bottom:12rpx;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.product-card-price-container{align-items:center;background:#fb2626;border-radius:8rpx;color:#fff;display:flex;height:50rpx;justify-content:space-between;margin-top:12rpx;padding-left:10rpx}.product-card-buy{background-color:#ff4d4f;border-radius:6rpx;color:#fff;cursor:pointer;font-size:.71rem;padding:8rpx 16rpx}.product-card-mask{align-items:center;background-color:rgba(0,0,0,.4);bottom:0;display:flex;justify-content:center;left:0;position:absolute;right:0;top:0}.product-card-mask-text{border-radius:20rpx;color:#fff;font-size:.86rem;padding:8rpx 16rpx}.product-card-disabled{opacity:.7}.product-card-disabled .product-card-price{color:#fff}.product-card-disabled .product-card-price-container{opacity:.6}.buy-icon{display:block;height:100%}.product-card-small{width:180rpx}.product-card-small .product-card-image{height:180rpx}.product-card-small .product-card-price-container{height:40rpx}.product-card-small .product-card-badge{font-size:.64rem;padding:3rpx 16rpx}.product-card-small .product-card-close{font-size:1rem;padding:0 10rpx}.product-card-small .buy-icon{display:none}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { appendParamsToPath } from '../../../shared/utils.js';
|
|
2
|
+
Component({
|
|
3
|
+
properties: {
|
|
4
|
+
// 商品数据
|
|
5
|
+
product: {
|
|
6
|
+
type: Object,
|
|
7
|
+
value: {}
|
|
8
|
+
},
|
|
9
|
+
// 是否显示
|
|
10
|
+
show: {
|
|
11
|
+
type: Boolean,
|
|
12
|
+
value: false
|
|
13
|
+
},
|
|
14
|
+
// SDK实例
|
|
15
|
+
sdkInstance: {
|
|
16
|
+
type: Object,
|
|
17
|
+
value: null,
|
|
18
|
+
observer: function(newVal) {
|
|
19
|
+
if (newVal) {
|
|
20
|
+
this.initStoreListener();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
data: {
|
|
26
|
+
// 当前显示的图片索引
|
|
27
|
+
currentImageIndex: 0
|
|
28
|
+
},
|
|
29
|
+
lifetimes: {
|
|
30
|
+
attached() {
|
|
31
|
+
// 组件挂载时初始化store监听
|
|
32
|
+
if (this.properties.sdkInstance) {
|
|
33
|
+
this.initStoreListener();
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
detached() {
|
|
37
|
+
// 组件卸载时移除store监听
|
|
38
|
+
if (this.unsub) {
|
|
39
|
+
this.unsub();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
observers: {
|
|
44
|
+
// 监听显示状态变化
|
|
45
|
+
show: function(show) {
|
|
46
|
+
if (show) {
|
|
47
|
+
// 重置数据
|
|
48
|
+
this.setData({
|
|
49
|
+
currentImageIndex: 0
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
methods: {
|
|
55
|
+
// 初始化store监听
|
|
56
|
+
initStoreListener() {
|
|
57
|
+
if (this.unsub) {
|
|
58
|
+
this.unsub();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
this.unsub = this.properties.sdkInstance.store.get({
|
|
62
|
+
productList: (val) => {
|
|
63
|
+
if (val && this.properties.product && this.properties.product.goods_id) {
|
|
64
|
+
// 检查当前商品是否在列表中
|
|
65
|
+
const currentProduct = val.find(item => item.goods_id === this.properties.product.goods_id);
|
|
66
|
+
if (currentProduct) {
|
|
67
|
+
// 如果商品在列表中,更新商品数据
|
|
68
|
+
this.setData({
|
|
69
|
+
product: currentProduct
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
},
|
|
76
|
+
// 关闭商品详情
|
|
77
|
+
closeDetail() {
|
|
78
|
+
this.setData({
|
|
79
|
+
show: false
|
|
80
|
+
});
|
|
81
|
+
this.triggerEvent('close');
|
|
82
|
+
},
|
|
83
|
+
// 购买商品
|
|
84
|
+
buyProduct() {
|
|
85
|
+
const product = this.data.product;
|
|
86
|
+
|
|
87
|
+
if (!product) {
|
|
88
|
+
console.error('商品数据不存在');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 检查是否已抢光或待开价
|
|
93
|
+
if (product.sale_status === 0 || product.covered_status === 1) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// 检查 buy_type
|
|
98
|
+
if (product.buy_type === 4 && product?.mini_program_config?.mini_program_path) {
|
|
99
|
+
// 跳转到小程序路径
|
|
100
|
+
const webinarId = this.properties.sdkInstance.store.get('webinarId');
|
|
101
|
+
console.log("跳转小程序路径:", appendParamsToPath(product?.mini_program_config?.mini_program_path, { webinarId }))
|
|
102
|
+
wx.navigateTo({
|
|
103
|
+
url: appendParamsToPath(product?.mini_program_config?.mini_program_path, { webinarId })
|
|
104
|
+
});
|
|
105
|
+
this.closeDetail();
|
|
106
|
+
} else if (product.buy_type === 1) {
|
|
107
|
+
// 先关闭详情弹框
|
|
108
|
+
this.closeDetail();
|
|
109
|
+
// 触发购买事件,由父组件显示下单弹窗
|
|
110
|
+
this.triggerEvent('buy', product);
|
|
111
|
+
} else {
|
|
112
|
+
// 提示无法购买
|
|
113
|
+
wx.showToast({
|
|
114
|
+
title: '无法购买,请联系主办方',
|
|
115
|
+
icon: 'none',
|
|
116
|
+
duration: 2000
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
// 图片滑动切换
|
|
121
|
+
bindchange(e) {
|
|
122
|
+
this.setData({
|
|
123
|
+
currentImageIndex: e.detail.current
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<view wx:if="{{show}}" class="product-detail-container">
|
|
2
|
+
<view class="product-detail-content">
|
|
3
|
+
<!-- 图片轮播 -->
|
|
4
|
+
<view class="product-images">
|
|
5
|
+
<view class="close-btn" bindtap="closeDetail">×</view>
|
|
6
|
+
<swiper
|
|
7
|
+
class="swiper"
|
|
8
|
+
current="{{currentImageIndex}}"
|
|
9
|
+
bindchange="bindchange"
|
|
10
|
+
indicator-dots="false"
|
|
11
|
+
autoplay="false"
|
|
12
|
+
circular="true"
|
|
13
|
+
>
|
|
14
|
+
<block wx:for="{{product.images}}" wx:key="{{index}}">
|
|
15
|
+
<swiper-item class="swiper-item">
|
|
16
|
+
<view class="product-image">
|
|
17
|
+
<image class="product-detail-img" src="{{item.img_url}}" mode="aspectFill"></image>
|
|
18
|
+
</view>
|
|
19
|
+
</swiper-item>
|
|
20
|
+
</block>
|
|
21
|
+
</swiper>
|
|
22
|
+
<view class="image-indicator">
|
|
23
|
+
{{currentImageIndex + 1}}/{{product.images ? product.images.length : 1}}
|
|
24
|
+
</view>
|
|
25
|
+
</view>
|
|
26
|
+
|
|
27
|
+
<!-- 商品信息 -->
|
|
28
|
+
<view class="product-info">
|
|
29
|
+
<!-- 价格 -->
|
|
30
|
+
<block wx:if="{{product.covered_status === 1}}">
|
|
31
|
+
<text class="covered-price">¥?待开价</text>
|
|
32
|
+
</block>
|
|
33
|
+
<block wx:else>
|
|
34
|
+
<view class="price-container">
|
|
35
|
+
<text class="discount-price">¥{{product.discount_price || product.price || 0}}</text>
|
|
36
|
+
<text wx:if="{{product.discount_price && product.price && product.discount_price !== product.price}}" class="original-price">¥{{product.price}}</text>
|
|
37
|
+
</view>
|
|
38
|
+
</block>
|
|
39
|
+
|
|
40
|
+
<!-- 商品名称 -->
|
|
41
|
+
<text class="product-title">{{product.name || '商品名称'}}</text>
|
|
42
|
+
|
|
43
|
+
<!-- 商品描述 -->
|
|
44
|
+
<text class="product-desc">{{product.description || ''}}</text>
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
<!-- 购买按钮 -->
|
|
49
|
+
<view
|
|
50
|
+
class="buy-btn {{product.sale_status === 0 || product.covered_status === 1 ? 'disabled' : ''}}"
|
|
51
|
+
bindtap="buyProduct"
|
|
52
|
+
>
|
|
53
|
+
{{product.sale_status === 0 ? '已抢光' : product.covered_status === 1 ? '待开价' : '购买'}}
|
|
54
|
+
</view>
|
|
55
|
+
</view>
|
|
56
|
+
</view>
|
|
57
|
+
</view>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.product-detail-container{align-items:flex-end;background-color:rgba(0,0,0,.5);bottom:0;display:flex;left:0;position:fixed;right:0;top:0;z-index:9999}.product-detail-content{background-color:#fff;border-radius:20rpx 20rpx 0 0;max-height:90vh;overflow:hidden;width:100%}.product-images{background-color:#f5f5f5;height:750rpx;position:relative}.swiper{height:100%}.swiper-item{align-items:center;display:flex;height:100%;justify-content:center}.product-image{height:100%;width:100%}.product-image .product-detail-img{height:100%;object-fit:contain;width:100%}.image-indicator{border-radius:20rpx;bottom:20rpx;font-size:.86rem;padding:8rpx 16rpx}.close-btn,.image-indicator{background-color:rgba(0,0,0,.6);color:#fff;position:absolute;right:20rpx}.close-btn{align-items:center;border-radius:50%;display:flex;font-size:1.29rem;height:60rpx;justify-content:center;top:20rpx;width:60rpx;z-index:10}.product-info{padding:30rpx}.price-container{align-items:baseline;display:flex;margin-bottom:30rpx}.discount-price{color:#fb2626;font-size:1.43rem;margin-right:20rpx}.original-price{color:#999;font-size:1rem;text-decoration:line-through}.product-title{-webkit-line-clamp:2;color:#333;font-size:1.14rem;font-weight:700;line-height:1.71rem;margin-bottom:20rpx}.product-desc,.product-title{-webkit-box-orient:vertical;display:block;display:-webkit-box;overflow:hidden;text-overflow:ellipsis}.product-desc{-webkit-line-clamp:3;color:#666;font-size:1rem;line-height:1.43rem;margin-bottom:30rpx}.covered-price{color:#999;font-size:1.14rem;margin-bottom:30rpx}.buy-btn{align-items:center;background-color:#fb2626;border-radius:45rpx;color:#fff;display:flex;font-size:1.14rem;font-weight:700;height:90rpx;justify-content:center;margin-top:20rpx;width:100%}.buy-btn.disabled{background-color:#ccc;color:#999;cursor:not-allowed}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { appendParamsToPath } from '../../../shared/utils.js';
|
|
2
|
+
Component({
|
|
3
|
+
properties: {
|
|
4
|
+
// 商品数据
|
|
5
|
+
product: {
|
|
6
|
+
type: Object,
|
|
7
|
+
value: {}
|
|
8
|
+
},
|
|
9
|
+
// 商品序号
|
|
10
|
+
index: {
|
|
11
|
+
type: Number,
|
|
12
|
+
value: 0
|
|
13
|
+
},
|
|
14
|
+
webinarId: {
|
|
15
|
+
type: String,
|
|
16
|
+
value: 0
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
data: {
|
|
20
|
+
// 组件内部数据
|
|
21
|
+
},
|
|
22
|
+
methods: {
|
|
23
|
+
// 点击商品
|
|
24
|
+
onProductClick() {
|
|
25
|
+
this.triggerEvent('openDetail', this.properties.product);
|
|
26
|
+
},
|
|
27
|
+
// 点击购买按钮
|
|
28
|
+
onBuyClick(e) {
|
|
29
|
+
const product = this.properties.product;
|
|
30
|
+
// 检查是否已抢光或待开价
|
|
31
|
+
if (product.sale_status === 0 || product.covered_status === 1) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 检查 buy_type
|
|
36
|
+
if (product.buy_type === 4 && product?.mini_program_config?.mini_program_path) {
|
|
37
|
+
// 跳转到小程序路径
|
|
38
|
+
const webinarId = this.properties.webinarId;
|
|
39
|
+
console.log("跳转小程序路径:", appendParamsToPath(product?.mini_program_config?.mini_program_path, { webinarId }))
|
|
40
|
+
wx.navigateTo({
|
|
41
|
+
url: appendParamsToPath(product?.mini_program_config?.mini_program_path, { webinarId })
|
|
42
|
+
});
|
|
43
|
+
} else if (product.buy_type === 1) {
|
|
44
|
+
// 触发购买事件,由父组件显示下单弹窗
|
|
45
|
+
this.triggerEvent('buyClick', product);
|
|
46
|
+
} else {
|
|
47
|
+
// 提示无法购买
|
|
48
|
+
wx.showToast({
|
|
49
|
+
title: '无法购买,请联系主办方',
|
|
50
|
+
icon: 'none',
|
|
51
|
+
duration: 2000
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<view class="product-item" bindtap="onProductClick">
|
|
2
|
+
<view class="product-image">
|
|
3
|
+
<view class="product-index">{{index + 1}}</view>
|
|
4
|
+
<image src="{{product.cover_img || 'https://cnstatic01.e.vhall.com/common-static/images/default_avatar.png'}}" mode="aspectFill"></image>
|
|
5
|
+
<view wx:if="{{product.sale_status === 0}}" class="product-mask">
|
|
6
|
+
<text class="product-mask-text">已抢光</text>
|
|
7
|
+
</view>
|
|
8
|
+
<!-- 讲解中标识 -->
|
|
9
|
+
<view wx:if="{{product.push_status === 1}}" class="product-badge">
|
|
10
|
+
<image src="https://cnstatic01.e.vhall.com/common-static/saas-wap/static/img/live.b07d13f4.gif" mode="heightFix" style="height: 20rpx; margin-right: 8rpx;"></image>
|
|
11
|
+
<text class="product-badge-text">讲解中</text>
|
|
12
|
+
</view>
|
|
13
|
+
</view>
|
|
14
|
+
<view class="product-info">
|
|
15
|
+
<view>
|
|
16
|
+
<text class="product-name">{{product.name }}</text>
|
|
17
|
+
<text class="product-desc">{{product.description }}</text>
|
|
18
|
+
</view>
|
|
19
|
+
<!-- 价格显示逻辑 -->
|
|
20
|
+
<block wx:if="{{product.covered_status === 1}}">
|
|
21
|
+
<text class="covered-price">¥?待开价</text>
|
|
22
|
+
</block>
|
|
23
|
+
<block wx:else>
|
|
24
|
+
<view wx:if="{{product.discount_price && product.price && product.discount_price !== product.price}}" class="price-container">
|
|
25
|
+
<text class="product-discount-price">¥{{product.discount_price}}</text>
|
|
26
|
+
<text class="product-original-price">¥{{product.price}}</text>
|
|
27
|
+
</view>
|
|
28
|
+
<text wx:else class="product-price">¥{{product.discount_price || product.price || 0}}</text>
|
|
29
|
+
</block>
|
|
30
|
+
</view>
|
|
31
|
+
<!-- 购买按钮 -->
|
|
32
|
+
<view class="{{['buy-btn',(product.sale_status === 0 || product.covered_status === 1) ? 'disabled' : '']}}" catchtap="onBuyClick">
|
|
33
|
+
购买
|
|
34
|
+
</view>
|
|
35
|
+
</view>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.product-image{border-radius:10rpx;height:180rpx;margin-right:20rpx;overflow:hidden;position:relative;width:180rpx}.product-index{border-radius:8rpx 0 8rpx 0;color:#fff;font-size:1rem;height:40rpx;padding:0 16rpx;z-index:1}.product-index,.product-mask{align-items:center;background-color:rgba(0,0,0,.6);display:flex;justify-content:center;left:0;position:absolute;top:0}.product-mask{bottom:0;right:0;z-index:2}.product-mask-text{color:#fff;font-size:1rem}.buy-btn.disabled{cursor:not-allowed;opacity:.6}.covered-price{color:#999;font-size:1rem;margin-bottom:10rpx}.product-image image{height:100%;object-fit:cover;width:100%}.product-info{display:flex;flex:1;flex-direction:column;justify-content:space-between;width:0}.product-name{color:#333;font-size:1.12rem;line-height:1.43rem}.product-desc,.product-name{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden;text-overflow:ellipsis}.product-desc{color:#666;font-size:.9rem}.price-container{align-items:baseline;display:flex}.product-discount-price{color:#fb2626;font-size:1.14rem}.product-original-price{color:#999;font-size:.86rem;text-decoration:line-through}.product-price{color:#fb2626;font-size:1.14rem}.buy-btn{background-color:#fb2626;border-radius:40rpx;bottom:20rpx;color:#fff;font-size:.86rem;padding:10rpx 32rpx;position:absolute;right:20rpx}.product-item{border-bottom:1rpx solid #f0f0f0;cursor:pointer;display:flex;padding:20rpx 0;position:relative}.product-item:last-child{border-bottom:none}.product-sales{color:#999;font-size:.86rem}.product-badge{align-items:center;background-color:rgba(0,0,0,.6);bottom:0;color:#fff;display:flex;font-size:.71rem;justify-content:center;left:0;padding:8rpx;position:absolute;right:0;text-align:center;z-index:5}.product-badge-text{display:inline-block}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
Component({
|
|
2
|
+
properties: {
|
|
3
|
+
sdkInstance: {
|
|
4
|
+
type: Object,
|
|
5
|
+
value: null,
|
|
6
|
+
observer: function(newVal) {
|
|
7
|
+
if (newVal) {
|
|
8
|
+
this.initStoreListener();
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
data: {
|
|
14
|
+
// 组件内部数据
|
|
15
|
+
productList: [],
|
|
16
|
+
webinarId: ''
|
|
17
|
+
},
|
|
18
|
+
lifetimes: {
|
|
19
|
+
created() {
|
|
20
|
+
// 组件创建时
|
|
21
|
+
},
|
|
22
|
+
attached() {
|
|
23
|
+
// 组件挂载时
|
|
24
|
+
if (this.properties.sdkInstance) {
|
|
25
|
+
this.initStoreListener();
|
|
26
|
+
this.setData({
|
|
27
|
+
webinarId: this.properties.sdkInstance.store.get('webinarId'),
|
|
28
|
+
});
|
|
29
|
+
// // 初始加载商品数据
|
|
30
|
+
// const productServer = this.properties.sdkInstance.get('productServer');
|
|
31
|
+
// if (productServer) {
|
|
32
|
+
// productServer.getProductList();
|
|
33
|
+
// }
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
detached() {
|
|
37
|
+
// 组件卸载时
|
|
38
|
+
if (this.unsub) {
|
|
39
|
+
this.unsub();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
methods: {
|
|
44
|
+
// 初始化store监听
|
|
45
|
+
initStoreListener() {
|
|
46
|
+
if (this.unsub) {
|
|
47
|
+
this.unsub();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this.unsub = this.properties.sdkInstance.store.get({
|
|
51
|
+
productList: (val) => {
|
|
52
|
+
if (val) {
|
|
53
|
+
this.setData({ productList: val });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
// 打开商品详情
|
|
59
|
+
openProductDetail(e) {
|
|
60
|
+
this.triggerEvent('productClick', e.detail);
|
|
61
|
+
},
|
|
62
|
+
// 处理购买点击事件
|
|
63
|
+
onBuyClick(e) {
|
|
64
|
+
this.triggerEvent('buyClick', e.detail);
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<view class="product-container">
|
|
2
|
+
<view class="product-list">
|
|
3
|
+
<view wx:if="{{productList.length === 0}}" class="product-empty">暂无商品</view>
|
|
4
|
+
<view wx:else>
|
|
5
|
+
<product-item
|
|
6
|
+
webinarId="{{webinarId}}"
|
|
7
|
+
wx:for="{{productList}}"
|
|
8
|
+
wx:key="{{item.id}}"
|
|
9
|
+
index="{{index}}"
|
|
10
|
+
product="{{item}}"
|
|
11
|
+
bind:openDetail="openProductDetail"
|
|
12
|
+
bind:buyClick="onBuyClick"
|
|
13
|
+
/>
|
|
14
|
+
</view>
|
|
15
|
+
</view>
|
|
16
|
+
</view>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.product-container{height:100%}.product-list{box-sizing:border-box;height:100%;overflow-y:auto;padding:20rpx;width:100%}.product-empty{color:#999;font-size:1rem;padding:40rpx 0;text-align:center}
|