1
0
Code Issues Pull Requests Packages Projects Releases Wiki Activity GitHub Gitee

通过微信开发者工具 商城模板 创建新小程序

This commit is contained in:
2023-03-06 23:52:24 +08:00
parent ada464a8cc
commit c21ff901d5
393 changed files with 52952 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
import Toast from 'tdesign-miniprogram/toast/index';
const shortageImg =
'https://cdn-we-retail.ym.tencent.com/miniapp/cart/shortage.png';
Component({
isSpecsTap: false, // 标记本次点击事件是否因为点击specs触发由于底层goods-card组件没有catch specs点击事件只能在此处加状态来避免点击specs时触发跳转商品详情
externalClasses: ['wr-class'],
properties: {
storeGoods: {
type: Array,
observer(storeGoods) {
for (const store of storeGoods) {
for (const activity of store.promotionGoodsList) {
for (const goods of activity.goodsPromotionList) {
goods.specs = goods.specInfo.map((item) => item.specValue); // 目前仅展示商品已选规格的值
}
}
for (const goods of store.shortageGoodsList) {
goods.specs = goods.specInfo.map((item) => item.specValue); // 目前仅展示商品已选规格的值
}
}
this.setData({ _storeGoods: storeGoods });
},
},
invalidGoodItems: {
type: Array,
observer(invalidGoodItems) {
invalidGoodItems.forEach((goods) => {
goods.specs = goods.specInfo.map((item) => item.specValue); // 目前仅展示商品已选规格的值
});
this.setData({ _invalidGoodItems: invalidGoodItems });
},
},
thumbWidth: { type: null },
thumbHeight: { type: null },
},
data: {
shortageImg,
isShowSpecs: false,
currentGoods: {},
isShowToggle: false,
_storeGoods: [],
_invalidGoodItems: [],
},
methods: {
// 删除商品
deleteGoods(e) {
const { goods } = e.currentTarget.dataset;
this.triggerEvent('delete', { goods });
},
// 清空失效商品
clearInvalidGoods() {
this.triggerEvent('clearinvalidgoods');
},
// 选中商品
selectGoods(e) {
const { goods } = e.currentTarget.dataset;
this.triggerEvent('selectgoods', {
goods,
isSelected: !goods.isSelected,
});
},
changeQuantity(num, goods) {
this.triggerEvent('changequantity', {
goods,
quantity: num,
});
},
changeStepper(e) {
const { value } = e.detail;
const { goods } = e.currentTarget.dataset;
let num = value;
if (value > goods.stack) {
num = goods.stack;
}
this.changeQuantity(num, goods);
},
input(e) {
const { value } = e.detail;
const { goods } = e.currentTarget.dataset;
const num = value;
this.changeQuantity(num, goods);
},
overlimit(e) {
const text =
e.detail.type === 'minus'
? '该商品数量不能减少了哦'
: '同一商品最多购买999件';
Toast({
context: this,
selector: '#t-toast',
message: text,
});
},
// 去凑单/再逛逛
gotoBuyMore(e) {
const { promotion, storeId = '' } = e.currentTarget.dataset;
this.triggerEvent('gocollect', { promotion, storeId });
},
// 选中门店
selectStore(e) {
const { storeIndex } = e.currentTarget.dataset;
const store = this.data.storeGoods[storeIndex];
const isSelected = !store.isSelected;
if (store.storeStockShortage && isSelected) {
Toast({
context: this,
selector: '#t-toast',
message: '部分商品库存不足',
});
return;
}
this.triggerEvent('selectstore', {
store,
isSelected,
});
},
// 展开/收起切换
showToggle() {
this.setData({
isShowToggle: !this.data.isShowToggle,
});
},
// 展示规格popup
specsTap(e) {
this.isSpecsTap = true;
const { goods } = e.currentTarget.dataset;
this.setData({
isShowSpecs: true,
currentGoods: goods,
});
},
hideSpecsPopup() {
this.setData({
isShowSpecs: false,
});
},
goGoodsDetail(e) {
if (this.isSpecsTap) {
this.isSpecsTap = false;
return;
}
const { goods } = e.currentTarget.dataset;
this.triggerEvent('goodsclick', { goods });
},
gotoCoupons() {
wx.navigateTo({ url: '/pages/coupon/coupon-list/index' });
},
},
});

View File

@@ -0,0 +1,11 @@
{
"component": true,
"usingComponents": {
"t-toast": "tdesign-miniprogram/toast/toast",
"t-icon": "tdesign-miniprogram/icon/icon",
"t-stepper": "tdesign-miniprogram/stepper/stepper",
"swipeout": "/components/swipeout/index",
"goods-card": "../../components/goods-card/index",
"specs-popup": "../../components/specs-popup/index"
}
}

View File

@@ -0,0 +1,152 @@
<wxs src="./index.wxs" module="handlePromotion" />
<wxs src="./utils.wxs" module="utils" />
<view class="cart-group">
<view class="goods-wrap" wx:for="{{_storeGoods}}" wx:for-item="store" wx:for-index="si" wx:key="storeId">
<view class="cart-store">
<t-icon
size="40rpx"
color="{{store.isSelected ? '#FA4126' : '#BBBBBB'}}"
name="{{store.isSelected ? 'check-circle-filled' : 'circle'}}"
class="cart-store__check"
bindtap="selectStore"
data-store-index="{{si}}"
/>
<view class="cart-store__content">
<view class="store-title">
<t-icon prefix="wr" size="40rpx" color="#333333" name="store" />
<view class="store-name">{{store.storeName}}</view>
</view>
<view class="get-coupon" catch:tap="gotoCoupons">优惠券</view>
</view>
</view>
<block wx:for="{{store.promotionGoodsList}}" wx:for-item="promotion" wx:for-index="promoindex" wx:key="promoindex">
<view
class="promotion-wrap"
wx:if="{{handlePromotion.hasPromotion(promotion.promotionCode)}}"
bindtap="gotoBuyMore"
data-promotion="{{promotion}}"
data-store-id="{{store.storeId}}"
>
<view class="promotion-title">
<view class="promotion-icon">{{promotion.tag}}</view>
<view class="promotion-text">{{promotion.description}}</view>
</view>
<view class="promotion-action action-btn" hover-class="action-btn--active">
<view class="promotion-action-label"> {{promotion.isNeedAddOnShop == 1 ? '去凑单' : '再逛逛'}} </view>
<t-icon name="chevron-right" size="32rpx" color="#BBBBBB" />
</view>
</view>
<view
class="goods-item"
wx:for="{{promotion.goodsPromotionList}}"
wx:for-item="goods"
wx:for-index="gi"
wx:key="extKey"
>
<swipeout right-width="{{ 72 }}">
<view class="goods-item-info">
<view class="check-wrap" catchtap="selectGoods" data-goods="{{goods}}">
<t-icon
size="40rpx"
color="{{goods.isSelected ? '#FA4126' : '#BBBBBB'}}"
name="{{goods.isSelected ? 'check-circle-filled' : 'circle'}}"
class="check"
/>
</view>
<view class="goods-sku-info">
<goods-card
layout="horizontal-wrap"
thumb-width="{{thumbWidth}}"
thumb-height="{{thumbHeight}}"
centered="{{true}}"
data="{{goods}}"
data-goods="{{goods}}"
catchspecs="specsTap"
catchclick="goGoodsDetail"
>
<view slot="thumb-cover" class="stock-mask" wx:if="{{goods.shortageStock || goods.stockQuantity <= 3}}">
仅剩{{goods.stockQuantity}}件
</view>
<view slot="append-body" class="goods-stepper">
<view class="stepper-tip" wx:if="{{goods.shortageStock}}">库存不足</view>
<t-stepper
classname="stepper-info"
value="{{goods.quantity}}"
min="{{1}}"
max="{{999}}"
data-goods="{{goods}}"
data-gi="{{gi}}"
data-si="{{si}}"
catchchange="changeStepper"
catchblur="input"
catchoverlimit="overlimit"
theme="filled"
/>
</view>
</goods-card>
</view>
</view>
<view slot="right" class="swiper-right-del" bindtap="deleteGoods" data-goods="{{goods}}"> 删除 </view>
</swipeout>
</view>
<view
class="promotion-line-wrap"
wx:if="{{handlePromotion.hasPromotion(promotion.promotionCode) && promoindex != (store.promotionGoodsList.length - 2)}}"
>
<view class="promotion-line" />
</view>
</block>
<block wx:if="{{store.shortageGoodsList.length>0}}">
<view
class="goods-item"
wx:for="{{store.shortageGoodsList}}"
wx:for-item="goods"
wx:for-index="gi"
wx:key="extKey"
>
<swipeout right-width="{{ 72 }}">
<view class="goods-item-info">
<view class="check-wrap">
<view class="unCheck-icon" />
</view>
<view class="goods-sku-info">
<goods-card
layout="horizontal-wrap"
thumb-width="{{thumbWidth}}"
thumb-height="{{thumbHeight}}"
centered="{{true}}"
data="{{goods}}"
data-goods="{{goods}}"
catchspecs="specsTap"
catchclick="goGoodsDetail"
>
<view slot="thumb-cover" class="no-storage-mask" wx:if="{{goods.stockQuantity <=0}}">
<view class="no-storage-content">无货</view>
</view>
</goods-card>
</view>
</view>
<view slot="right" class="swiper-right-del" bindtap="deleteGoods" data-goods="{{goods}}"> 删除 </view>
</swipeout>
</view>
<view
class="promotion-line-wrap"
wx:if="{{handlePromotion.hasPromotion(promotion.promotionCode) && promoindex != (store.promotionGoodsList.length - 2)}}"
>
<view class="promotion-line" />
</view>
</block>
</view>
</view>
<specs-popup
show="{{isShowSpecs}}"
title="{{currentGoods.title || ''}}"
price="{{currentGoods.price || ''}}"
thumb="{{utils.imgCut(currentGoods.thumb, 180, 180)}}"
specs="{{currentGoods.specs || []}}"
zIndex="{{999}}"
bindclose="hideSpecsPopup"
/>
<t-toast id="t-toast" />

View File

@@ -0,0 +1,5 @@
var hasPromotion = function (code) {
return code && code !== 'EMPTY_PROMOTION';
};
module.exports.hasPromotion = hasPromotion;

View File

@@ -0,0 +1,335 @@
.cart-group {
border-radius: 8rpx;
}
.cart-group .goods-wrap {
margin-top: 40rpx;
background-color: #fff;
border-radius: 8rpx;
overflow: hidden;
}
.cart-group .goods-wrap:first-of-type {
margin-top: 0;
}
.cart-group .cart-store {
height: 96rpx;
background-color: #fff;
box-sizing: border-box;
display: flex;
align-items: center;
padding: 0rpx 24rpx 0rpx 36rpx;
}
.cart-group .cart-store .cart-store__check {
padding: 28rpx 32rpx 28rpx 0rpx;
}
.cart-group .cart-store__content {
box-sizing: border-box;
flex: auto;
display: flex;
align-items: center;
justify-content: space-between;
}
.cart-group .cart-store__content .store-title {
flex: auto;
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
display: flex;
align-items: center;
font-weight: bold;
overflow: hidden;
}
.cart-group .cart-store__content .store-title .wr-store {
font-size: 32rpx;
}
.cart-group .cart-store__content .store-title .store-name {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin-left: 12rpx;
}
.cart-group .cart-store__content .get-coupon {
width: 112rpx;
height: 40rpx;
border-radius: 20rpx;
background-color: #ffecf9;
line-height: 40rpx;
text-align: center;
font-size: 26rpx;
color: #fa4126;
}
.cart-group .promotion-wrap {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0rpx 24rpx 32rpx 36rpx;
background-color: #ffffff;
font-size: 24rpx;
line-height: 36rpx;
color: #222427;
}
.cart-group .promotion-wrap .promotion-title {
font-weight: bold;
flex: auto;
overflow: hidden;
margin-right: 20rpx;
display: flex;
align-items: center;
}
.cart-group .promotion-wrap .promotion-title .promotion-icon {
flex: none;
font-weight: normal;
display: inline-block;
padding: 0 8rpx;
color: #ffffff;
background: #fa4126;
font-size: 20rpx;
height: 32rpx;
line-height: 32rpx;
margin-right: 16rpx;
border-radius: 16rpx;
}
.cart-group .promotion-wrap .promotion-title .promotion-text {
flex: auto;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.cart-group .promotion-wrap .promotion-action {
flex: none;
color: #333333;
}
.cart-group .promotion-line-wrap {
background-color: #fff;
height: 2rpx;
display: flex;
justify-content: flex-end;
}
.cart-group .promotion-line-wrap .promotion-line {
width: 684rpx;
height: 2rpx;
background-color: #e6e6e6;
}
.cart-group .goods-item-info {
display: flex;
background-color: #fff;
align-items: flex-start;
}
.cart-group .goods-item-info .check-wrap {
margin-top: 56rpx;
padding: 20rpx 28rpx 20rpx 36rpx;
}
.cart-group .goods-item-info .check-wrap .unCheck-icon {
box-sizing: border-box;
width: 36rpx;
height: 36rpx;
border-radius: 20rpx;
background: #f5f5f5;
border: 2rpx solid #bbbbbb;
}
.cart-group .goods-item-info .goods-sku-info {
padding: 0rpx 32rpx 40rpx 0;
flex-grow: 1;
}
.cart-group .goods-item-info .goods-sku-info .stock-mask {
position: absolute;
color: #fff;
font-size: 24rpx;
bottom: 0rpx;
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 40rpx;
line-height: 40rpx;
text-align: center;
}
.cart-group .goods-item-info .goods-sku-info .goods-stepper {
position: absolute;
right: 0;
bottom: 8rpx;
}
.cart-group .goods-item-info .goods-sku-info .goods-stepper .stepper-tip {
position: absolute;
top: -36rpx;
right: 0;
height: 28rpx;
color: #ff2525;
font-size: 20rpx;
line-height: 28rpx;
}
.cart-group .shortage-line {
width: 662rpx;
height: 2rpx;
background-color: #e6e6e6;
margin: 0 auto;
}
.cart-group .shortage-goods-wrap {
background-color: #fff;
}
.cart-group .shortage-goods-wrap .shortage-tip-title {
height: 72rpx;
line-height: 72rpx;
padding-left: 28rpx;
font-size: 24rpx;
color: #999;
}
.stepper-info {
margin-left: auto;
}
.invalid-goods-wrap {
background-color: #fff;
border-radius: 8rpx;
margin-top: 40rpx;
}
.invalid-goods-wrap .invalid-head {
display: flex;
justify-content: space-between;
padding: 30rpx 20rpx;
font-size: 24rpx;
border-bottom: 2rpx solid #f6f6f6;
}
.invalid-goods-wrap .invalid-head .invalid-title {
color: #333;
font-size: 28rpx;
font-weight: 600;
}
.invalid-goods-wrap .invalid-head .invalid-clear {
color: #fa4126;
}
.invalid-goods-wrap .toggle {
display: flex;
height: 80rpx;
justify-content: center;
align-items: center;
font-size: 24rpx;
color: #fa4126;
}
.invalid-goods-wrap .toggle .m-r-6 {
margin-right: 6rpx;
}
.invalid-goods-wrap .toggle .top-icon {
display: inline-block;
width: 0;
height: 0;
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
border-bottom: 10rpx solid #fa4126;
}
.invalid-goods-wrap .toggle .down-icon {
display: inline-block;
width: 0;
height: 0;
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
border-top: 10rpx solid #fa4126;
}
.action-btn {
display: flex;
align-items: center;
}
.action-btn .action-btn-arrow {
font-size: 20rpx;
margin-left: 8rpx;
}
.action-btn--active {
opacity: 0.5;
}
.swiper-right-del {
height: calc(100% - 40rpx);
width: 144rpx;
background-color: #fa4126;
font-size: 28rpx;
color: white;
display: flex;
justify-content: center;
align-items: center;
}
.goods-stepper .stepper {
border: none;
border-radius: 0;
height: auto;
width: 168rpx;
overflow: visible;
}
.goods-stepper .stepper .stepper__minus,
.goods-stepper .stepper .stepper__plus {
width: 44rpx;
height: 44rpx;
background-color: #f5f5f5;
}
.goods-stepper .stepper .stepper__minus--hover,
.goods-stepper .stepper .stepper__plus--hover {
background-color: #f5f5f5;
}
.goods-stepper .stepper .stepper__minus .wr-icon,
.goods-stepper .stepper .stepper__plus .wr-icon {
font-size: 24rpx;
}
.goods-stepper .stepper .stepper__minus {
position: relative;
}
.goods-stepper .stepper .stepper__minus::after {
position: absolute;
display: block;
content: ' ';
left: -20rpx;
right: -5rpx;
top: -20rpx;
bottom: -20rpx;
background-color: transparent;
}
.goods-stepper .stepper .stepper__plus {
position: relative;
}
.goods-stepper .stepper .stepper__plus::after {
position: absolute;
display: block;
content: ' ';
left: -5rpx;
right: -20rpx;
top: -20rpx;
bottom: -20rpx;
background-color: transparent;
}
.goods-stepper .stepper .stepper__input {
width: 72rpx;
height: 44rpx;
background-color: #f5f5f5;
font-size: 24rpx;
color: #222427;
font-weight: 600;
border-left: none;
border-right: none;
min-height: 40rpx;
margin: 0 4rpx;
display: flex;
align-items: center;
}
.goods-sku-info .no-storage-mask {
position: absolute;
color: #fff;
bottom: 0rpx;
left: 0rpx;
background-color: rgba(0, 0, 0, 0.1);
height: 192rpx;
width: 192rpx;
border-radius: 8rpx;
display: flex;
justify-content: center;
align-items: center;
}
.no-storage-mask .no-storage-content {
width: 128rpx;
height: 128rpx;
border-radius: 64rpx;
background-color: rgba(0, 0, 0, 0.4);
text-align: center;
line-height: 128rpx;
font-size: 28rpx;
}

View File

@@ -0,0 +1,20 @@
module.exports.slice = function(arr) {
return arr.slice(0, 2);
};
module.exports.imgCut = function(url, width, height) {
if (url && (url.slice(0, 5) === 'http:' || url.slice(0, 6) === 'https:' || url.slice(0, 2) === '//')) {
var argsStr = 'imageMogr2/thumbnail/!' + width + 'x' + height + 'r';
if (url.indexOf('?') > -1) {
url = url + '&' + argsStr;
} else {
url = url + '?' + argsStr;
}
if (url.slice(0, 5) === 'http:') {
url = 'https://' + url.slice(5)
}
if (url.slice(0, 2) === '//') {
url = 'https:' + url
}
}
return url;
};