Commit 99504707 by 程默

Merge branch 'nativehome_tst' of http://code.mayi888.com/chengmo/mayi-mp-shop into nativehome_tst

parents c6b56e48 e8c31a8e
const app = getApp();
export default {
computed: {
getBorderRadius() {
return this.datas.componentData.borderRadius == undefined
? 0.625
: this.datas.componentData.borderRadius;
},
goodsSort() {
return this.datas.componentData.goodsSort || 0;
},
// 会员价
vipPrice() {
return this.datas.componentData.vipPrice || false;
},
whetherFindDistributionCommission() {
return this.datas.componentData.whetherFindDistributionCommission ? 1 : 0;
},
categoryId() {
return this.datas.componentData.categoryId
? this.datas.componentData.categoryId
: "";
},
// 关注人数样式
followerColor() {
return this.datas.componentData.followerColor
? this.datas.componentData.followerColor
: "#ff9933";
},
// 佣金文字颜色
commissionColor() {
return this.datas.componentData.commissionColor
? this.datas.componentData.commissionColor
: "#ff9051";
},
//佣金背景颜色
commissionBgColor() {
return this.datas.componentData.commissionBgColor
? this.datas.componentData.commissionBgColor
: "";
},
// 按钮图标
btnIcon() {
return this.datas.componentData.btnIcon
? this.datas.componentData.btnIcon
: "";
},
// 按钮类型
btnType() {
return this.datas.componentData.btnType
? this.datas.componentData.btnType
: 6;
},
// 按钮颜色
btnColor() {
return this.datas.componentData.btnColor
? this.datas.componentData.btnColor
: "var(--main-color)";
},
// 按钮文案
btnTest() {
return this.datas.componentData.btnTest
? this.datas.componentData.btnTest
: "立即购买";
},
getItemNum() {
return this.datas.componentData.goodsList;
},
getPaddingList() {
return this.datas.componentData.paddingList;
},
getColumnWidth() {
if (this.datas.componentData.columnNum == 1) {
return "100%";
} else if (this.datas.componentData.columnNum == 2) {
return "50%";
} else {
return "33.3%";
}
},
getPayFontSize() {
if (this.datas.componentData.columnNum == 1) {
return "12px";
} else if (this.datas.componentData.columnNum == 2) {
return "10px";
} else {
return "8px";
}
},
getListPadding() {
if (this.datas.componentData.columnNum == 1) {
return "";
} else if (this.datas.componentData.columnNum == 2) {
return (
"0 " +
this.datas.componentData.proGap / 2 +
"px" +
" 0 " +
this.datas.componentData.proGap / 2 +
"px"
);
} else {
return "33.3%";
}
},
whetherShowSoldOutGoods() {
// 商城端接口的获取商城配置信息
// if (this.render) {
// return this.$store.state.setShopConfig.whetherShowSoldOutGoods || 1;
// } else {
// return 1;
// }
return 1;
},
goodsType() {
return this.datas.componentData.goodsType || 0;
},
// 展示标题图片
titleIcon() {
return app.DFSImg(this.datas.componentData.titleIcon, 400, 400) || "";
},
// 展示角标
angleSign() {
return this.datas.componentData.angleSign || false;
},
// 角标尺寸
angleSignSize() {
return this.datas.componentData.angleSignSize || 25;
},
// 展示角标图片
angleSignImg() {
return this.datas.componentData.angleSignImg || "";
},
// 展示营销标签
marketingTag() {
return this.datas.componentData.marketingTag || false;
},
// 展示营销标签类型
marketingStyle() {
return this.datas.componentData.marketingStyle || 0;
},
// 营销标签列表
marketingTagList() {
return this.datas.componentData.marketingTagList || [];
},
cardShadowSize() {
return this.datas.componentData.cardShadowSize
? this.datas.componentData.cardShadowSize
: 3;
}
}
};
\ No newline at end of file
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
<span class="tagName">{{ item.tagName }}</span> <span class="tagName">{{ item.tagName }}</span>
</div> </div>
</div> </div>
<image :src="info.coverUrl" mode="widthFix"></image> <image :src="info.coverUrl" mode="widthFix" lazy-load></image>
</div> </div>
<div class="infoText"> <div class="infoText">
<p <p
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
<span class="tagName">{{ item.tagName }}</span> <span class="tagName">{{ item.tagName }}</span>
</div> </div>
</div> </div>
<image :src="info.coverUrl" mode="widthFix"></image> <image :src="info.coverUrl" lazy-load mode="widthFix"></image>
</div> </div>
</div> </div>
</template> </template>
......
...@@ -84,6 +84,10 @@ ...@@ -84,6 +84,10 @@
<div v-if="item.componentCode == 'merchants-list' && item.componentInfo.visible == 1"> <div v-if="item.componentCode == 'merchants-list' && item.componentInfo.visible == 1">
<merchants-list :class="'merchants-list' +index" :datas="item"></merchants-list> <merchants-list :class="'merchants-list' +index" :datas="item"></merchants-list>
</div> </div>
<div v-if="item.componentCode == 'spell-group' && item.componentInfo.visible == 1">
<spell-group :datas="item"></spell-group>
</div>
</div> </div>
<bottomCont></bottomCont> <bottomCont></bottomCont>
</div> </div>
...@@ -105,6 +109,7 @@ import text from '@/components/content/text' ...@@ -105,6 +109,7 @@ import text from '@/components/content/text'
import imgText from '@/components/content/imgText' import imgText from '@/components/content/imgText'
import coupon from '@/components/activity/coupon' import coupon from '@/components/activity/coupon'
import integralTurntable from '@/components/activity/integralTurntable' import integralTurntable from '@/components/activity/integralTurntable'
import spellGroup from '@/components/activity/spellGroup'
import { setTabBarActive, checkTabbarPage,themeColor } from "../../utils/mayi.js"; import { setTabBarActive, checkTabbarPage,themeColor } from "../../utils/mayi.js";
import { throttle } from "../../utils/index.js" import { throttle } from "../../utils/index.js"
const app = getApp(); const app = getApp();
...@@ -134,7 +139,8 @@ export default { ...@@ -134,7 +139,8 @@ export default {
coupon, coupon,
integralTurntable, integralTurntable,
transverseLabel, transverseLabel,
information information,
spellGroup
}, },
onShareAppMessage(res) { onShareAppMessage(res) {
let shareVal={}; let shareVal={};
......
...@@ -19,7 +19,8 @@ ...@@ -19,7 +19,8 @@
"photo-gallery":"/static/nativeComponents/PhotoGallery/index", "photo-gallery":"/static/nativeComponents/PhotoGallery/index",
"live-broadcast":"/static/nativeComponents/LiveBroadcast/index", "live-broadcast":"/static/nativeComponents/LiveBroadcast/index",
"share-picture":"/static/nativeComponents/SharePicture/index", "share-picture":"/static/nativeComponents/SharePicture/index",
"merchants-list":"/static/nativeComponents/MerchantsList/index" "merchants-list":"/static/nativeComponents/MerchantsList/index",
"spell-group-heap-item":"/static/nativeComponents/spellGroup/heapItem/index"
}, },
"enablePullDownRefresh":true, "enablePullDownRefresh":true,
"backgroundColor":"#f5f5f5" "backgroundColor":"#f5f5f5"
......
const app = getApp();
const { goodsApi, DFSImg, $themeToLink, $themeAddToCard } = app;
const componentOptions = {
// 组件选项
options: {
multipleSlots: true
},
behaviors: [],
properties: {
datas: {
type: Object
},
items: {
type: Object
},
indexs: {
type: Number
}
},
// 组件数据
data: {
isPageHidden: false, // 页面是否处于隐藏状态
timeData: {}
},
// 数据监听器
observers: {},
// 组件方法
methods: {
init() {},
getSaleTime(val) {
return new Date(val.replace(/-/g, "/")).getTime() - new Date().getTime();
},
showVipPrice(index) {
// 索引 0 显示价格 1显示名称
let showFlag = false;
let vipPrice = this.items["minPriceAfterRecommendedCardPriceTable"];
if (vipPrice && Number(vipPrice) < Number(this.items["minPrice"])) {
showFlag = true;
}
console.log(showFlag, "------------760");
return showFlag;
},
showVipTag(index) {
// 索引 0 显示价格 1显示名称
let showFlag = false;
let vipPrice = this.items["minPriceAfterRecommendedCardPriceTable"];
let showTag = this.items["recommendedCardMinPricePriceTableName"];
if (
vipPrice &&
showTag &&
Number(vipPrice) <= Number(this.items["minPrice"])
) {
showFlag = true;
}
return showFlag;
},
onChange(e) {
this.setData({ timeData: e.detail });
},
onclickProduct() {
let { goodsType } = this.data.datas.componentData;
let {
productId,
terminalProductId,
terminalGoodsMixId
} = this.data.items;
let linkVal = "";
if (goodsType == 0) {
linkVal = `/goods/${productId}?terminalProductId=${terminalProductId}`;
} else if (goodsType == 1) {
linkVal = `/pointShop/goodsDetail?productId${productId}&terminalProductId=${terminalProductId}&terminalGoodsMixId=${terminalGoodsMixId}`;
}
$themeToLink({
type: 1,
link: linkVal
});
},
onclickBuynow() {
let { btnType } = this.data.datas.componentData;
let {
minProductGoodsMixid,
minProductGoodsId,
minGoodsId
} = this.data.items;
let linkVal = "";
if (btnType < 6) {
// 加入购物车
console.log("加入购物车");
$themeAddToCard(this.data.items);
} else {
// 进入确认订单
linkVal = `/order/orderConfirm?productGoodsMixId=${minProductGoodsMixid}&productGoodsId=${minProductGoodsId}&goodsId=${minGoodsId}&qty=1&goodsString=null&source=3`;
}
console.log(linkVal, "-------90");
$themeToLink({ type: 1, link: linkVal });
},
toMerchants() {
let { orgId } = this.data.items;
$themeToLink({ type: 1, link: `/merchantsDetail/${orgId}` });
},
},
// 组件生命周期
lifetimes: {
created() {},
attached() {
this.init();
},
ready() {},
moved() {},
detached() {}
},
definitionFilter() {},
// 页面生命周期
pageLifetimes: {
// 页面被展示
show() {
const { isPageHidden } = this.data;
// show事件发生前,页面不是处于隐藏状态时
if (!isPageHidden) {
return;
}
// 重新执行定时器等操作
},
// 页面被隐藏
hide() {
this.setData({
isPageHidden: true
});
// 清除定时器等操作
},
// 页面尺寸变化时
resize() {}
}
};
Component(componentOptions)
{
"component": true,
"usingComponents": {
"van-count-down":"/static/vant/count-down/index"
}
}
<!-- 商品列表item -->
<view
class="goodsItem {{datas.componentData.style==='rowList'?'goodsRowList':''}} {{datas.componentData.style==='heap'?'goodsRowList goodsHeapItem':''}}"
style="--proGap2:{{datas.componentData.proGap*2}}rpx;"
bindtap="onclickProduct"
>
<view class="goods-item-child {{datas.componentData['borderColorShow']?'goods-item-child-bd':''}}" style="border-radius:{{datas.componentData.borderRadius}}em;--border_color:{{datas.componentData['borderColor']}};box-shadow:{{datas.componentData['cardShadow']?'0rpx 0rpx 10rpx '+datas.componentData['cardShadowSize']*2+'rpx #ccc':''}};">
<!-- 商品图片 -->
<view class="imgBox" style="background-color:{{datas.componentData['backgroundColorShow']?datas.componentData['backgroundColor']:''}}">
<view
class="goodsPicture"
wx:if="{{items!=null}}"
style="padding:{{datas.componentData.imgSize}}"
>
<!-- 显示拼团数 -->
<view class="have-group" wx:if="{{datas.componentData['haveGroupShow']&& (items && items['groupBuyFlag'] == '1')}}">{{items.haveGroupNum?items.haveGroupNum:0}}人已团</view>
<!-- 商品角标 -->
<view
class="angleSign"
style="width:{{datas.componentData.angleSignSize}}%;height:{{datas.componentData.angleSignSize}}%;"
wx:if="{{datas.componentData['angleSign'] && datas.componentData['angleSignImg']}}"
>
<image mode="widthFix" src="{{datas.componentData['angleSignImg']}}" />
</view>
<!-- 商品主图 -->
<image
lazy-load
mode="{{datas.componentData.style==='rowList' || datas.componentData.style==='heap'?'aspectFit':'widthFix'}}"
class="productImgUrl"
wx:if="{{datas.componentData.goodsImgType == 1}}"
src="{{items.productImgUrl}}"
/>
<image
lazy-load
mode="{{datas.componentData.style==='rowList' || datas.componentData.style==='heap'?'aspectFit':'widthFix'}}"
class="productImgUrl"
wx:else
src="{{items.coverImage}}"
/>
<!-- 售罄遮罩 -->
<view class="whiteBg" wx:if="{{items&&items.oversoldFlag==0&&items.totalQty-0<=0}}">
<view class="cover">
<image mode="aspectFit" src="http://mayi-newshop.oss-cn-shanghai.aliyuncs.com/public/png/f254fe62-6dda-46f6-a2f4-a7b2aa0474df.png" />
</view>
</view>
</view>
</view>
<!-- 商品详情 -->
<view class="info" style="text-align:{{datas.componentData['initcharAlign']}};">
<view class="info-top flex">
<view
class="name"
wx:if="{{datas.componentData['nameShow']}}"
style="color:{{datas.componentData['nameColor']}};font-weight:{{datas.componentData['nameFontWeight']}};font-size:{{datas.componentData['nameFontSize']}}em;height:2.8em;"
>
{{items!=null?items['productName']:'名称'}}
</view>
<view
class="follower-wrap"
wx:if="{{datas.componentData['followerShow']}}"
style="padding-left:{{datas.componentData.columnNum == 3 ? '0' : '20rpx'}}"
>
<view class="follower-num" style="color:{{datas.componentData['followerColor']?datas.componentData['followerColor']:'#ff9933'}};">
{{items!=null? items['totalCollectionCount']:0}}
</view>
<view class="follower-text">关注人数</view>
</view>
</view>
<!-- 已售 -->
<view class="Sold">
<text wx:if="{{datas.componentData['alSaleShow']}}">已售{{items!=null ? items['totalSalesCount'] :0}}件</text>
<text wx:if="{{datas.componentData['alSaleShow'] && datas.componentData['collectShow']}}">/</text>
<text wx:if="{{datas.componentData['collectShow']}}">剩余{{items!=null && items['qty']!=undefined ? (items['qty'] > 0 ? items['qty']: items.oversoldFlag==1?'数量充足':'数量不足') : ''}}<text wx:if="{{items!=null && (items['qty'] ? items['qty'] >= 0 : items['saleQty'] >= 0) && items.oversoldFlag!=1}}">件</text>
</text>
</view>
<!-- 标签 -->
<view class="marketing flex" wx:if="{{datas.componentData['marketingTag']&&datas.componentData['marketingStyle']==0&&items.marketingTag}}">
<view
class="item"
wx:for="{{items.marketingTag}}"
wx:key="index"
>
{{item.label}}
</view>
</view>
<!-- 底部 -->
<view class="bottom" wx:if="{{datas.componentData['goodsType'] !=1}}">
<!-- 价格 -->
<view class="priceItem flex">
<view
class="price flex"
style="color:{{datas.componentData['priceColor']}};font-size:{{datas.componentData['priceFontSize']}}em;"
wx:if="{{datas.componentData['priceShow']}}"
>
<text wx:if="{{items!=null && (items['groupBuyFlag'] == '0' ||items['groupBuyFlag'] == '1')}}">
¥{{items!=null ? items['goodsMinPrice']:0}}
</text>
<text style="font-size:24rpx;color:#999;text-decoration:line-through;" wx:if="{{items!=null&&datas.componentData['priceMarking']&&items['minGoodsSuggestedRetailPrice']&&(items['goodsMinPrice']-0<items['minGoodsSuggestedRetailPrice']-0)&&datas.componentData['columnNum']<3}}">
¥{{items['minGoodsSuggestedRetailPrice']}}
</text>
</view>
<view class="vipPrice2 flex" wx:if="{{datas.componentData.vipPrice}}">
<view class="left" wx:if="{{items.showVipPrice==true}}">
¥{{items['minPriceAfterRecommendedCardPriceTable']}}
</view>
<view class="vipIcon line-clamp1" wx:if="{{items.showVipTag==true}}">
{{items["recommendedCardMinPricePriceTableName"]}}
</view>
</view>
</view>
<!-- 收益样式一 -->
<block wx:if="{{items!=null&&items['minProductGoodsCommission']&&items['minProductGoodsCommission']-0>0.01}}">
<view
class="showCommission"
style="color:{{datas.componentData.commissionColor}};border-color:{{datas.componentData.commissionColor}};"
wx:if="{{datas.componentData.commissionStyle==0}}"
>
<view class="commission-box" style="background-color:{{datas.componentData.commissionBgColor}}">
<text>收益</text>
<text>¥{{items['minProductGoodsCommission']}}</text>
</view>
</view>
</block>
<view wx:if="{{(items&&items.totalQty-0>0||items&&items.oversoldFlag==1)&& datas.componentData['paynow']}}" catchtap="onclickBuynow">
<text wx:if="{{datas.componentData.btnType<6}}" style="color:{{datas.componentData.btnColor}}" class="buy-now-icon iconfont-common {{datas.componentData.btnIcon}}"></text>
<view
wx:else
class="buy-now"
style="background-color:{{datas.componentData.btnColor}};font-size:24rpx;"
>
{{datas.componentData.btnTest}}
</view>
</view>
</view>
<!-- 底部展示标签列表 -->
<block wx:if="{{items!=null}}">
<view class="marketing flex" wx:if="{{datas.componentData.marketingTag&&datas.componentData.marketingStyle==1&&items.marketingTag}}">
<view
class="item"
wx:for="{{items.marketingTag}}"
wx:key="index"
>
{{item.label}}
</view>
</view>
</block>
<!-- 收益样式二 -->
<block wx:if="{{items!=null&&items['minProductGoodsCommission']&&items['minProductGoodsCommission']-0>0.01}}">
<view
class="showCommissionTwo flex"
wx:if="{{datas.componentData.commissionStyle==1}}"
style="color:{{datas.componentData.commissionColor}};border-color:{{datas.componentData.commissionColor}};"
>
<view class="commission-box" style="background-color:{{datas.componentData.commissionBgColor}}">
<text class="iconfont-common common-iconfenxiang"></text>
<text style="padding:0 8rpx;">赚¥</text>
<text style="font-size:32rpx;">{{items['minProductGoodsCommission']}}</text>
</view>
</view>
</block>
</view>
</view>
</view>
@import "/static/font/common_icon.wxss";
.flex{
display: flex;
}
.goods-item-child-bd{
border: 1px solid var(--border_color);
}
image{
width: 100%;
display: block;
}
.goodsItem{
margin-bottom: var(--proGap2);
white-space: initial;
}
.goods-item-child {
position: relative;
overflow: hidden;
background: #fff;
}
.goodsRowList .goods-item-child{
display: flex;
align-items: flex-start;
}
.goodsRowList .goods-item-child .imgBox{
width: auto;
width: 180rpx;
height: 180rpx;
margin: 20rpx;
overflow: hidden;
border-radius: 12rpx;
-webkit-border-radius: 12rpx;
-moz-border-radius: 12rpx;
-ms-border-radius: 12rpx;
-o-border-radius: 12rpx;
}
.goodsRowList .goods-item-child .info{
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.goodsHeapItem{
width: 100%;
}
.merchantsEntrance{
padding: 8rpx 20rpx;
}
.merchantsEntrance .left{
align-items: center;
}
.merchantsEntrance .left .logo{
width: 52rpx;
height: 52rpx;
border-radius: 8rpx;
-webkit-border-radius: 8rpx;
-moz-border-radius: 8rpx;
-ms-border-radius: 8rpx;
-o-border-radius: 8rpx;
overflow: hidden;
background: #f5f5f5;
margin-right: 20rpx;
}
.imgBox{
position: relative;
overflow: hidden;
width: 100%;
margin: 0 auto;
}
.goodsPicture{
width: 100%;
height: 100%;
position: relative;
box-sizing: border-box;
}
.goodsPicture .have-group{
position: absolute;
bottom: 20rpx;
left: 12rpx;
padding: 8rpx 16rpx;
background-color: rgba(0,0,0,.6);
color: white;
font-size: 24rpx;
border-radius: 8rpx;
-webkit-border-radius: 8rpx;
-moz-border-radius: 8rpx;
-ms-border-radius: 8rpx;
-o-border-radius: 8rpx;
}
.goodsPicture .productImgUrl{
width: 100%;
height: 100%;
}
.goodsPicture .saleWay{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
display: flex;
justify-content: center;
z-index: 2;
color: #fff;
}
.goodsPicture .saleWay .saleWayBg{
background: var(--main-color);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0.5;
}
.goodsPicture .saleWay .saleTime{
position: relative;
z-index: 2;
padding: 4rpx 0;
}
.goodsPicture .saleWay .saleTime text{
color: #fff;
}
.goodsPicture .angleSign{
position: absolute;
top: 0;
left: 0;
}
.whiteBg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(#fff, 0.7);
}
.whiteBg .cover {
position: absolute;
top: 20px;
left: 20px;
right: 20px;
bottom: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 50%;
background-size: cover;
}
.whiteBg .cover img {
width: 100%;
height: 100%;
object-fit: contain;
}
.info{
padding: 10rpx 20rpx 24rpx;
position: relative;
background-color: white;
}
.info .info-top{
overflow: hidden;
justify-content: space-between;
}
.info .name{
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
line-height: 1.4em;
position: relative;
}
.info .follower-wrap{
position: relative;
font-size: 0.8em;
color: #999;
text-align: center;
height: 70rpx;
border-left: 1px solid #999;
}
.info .follower-wrap .follower-num{
text-align: center;
font-size: 1em;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.info .follower-wrap .follower-text{
color: #999;
font-size: 0.7em;
text-align: center;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.vipPrice1{
align-items: flex-end;
margin-top: 12rpx;
font-size: 24rpx;
}
.vipPrice1 .vipIcon{
min-width: 64rpx;
padding: 2rpx 4rpx;
height: 28rpx;
background: #333;
font-size: 20rpx;
line-height: 28rpx;
text-align: center;
color: #d7c7a1;
border-top-left-radius: 4rpx;
border-bottom-left-radius: 12rpx;
}
.vipPrice1 .right{
height: 28rpx;
color: #333;
font-weight: bold;
background: linear-gradient( 227deg, rgba(212, 195, 142, 1), rgba(252, 232, 162, 1) );
border-radius: 0rpx 12rpx 12rpx 0rpx;
font-size: 20rpx;
text-align: center;
padding: 0 8rpx 0 4rpx;
-webkit-border-radius: 0rpx 12rpx 12rpx 0rpx;
-moz-border-radius: 0rpx 12rpx 12rpx 0rpx;
-ms-border-radius: 0rpx 12rpx 12rpx 0rpx;
-o-border-radius: 0rpx 12rpx 12rpx 0rpx;
}
.priceItem {
align-items: flex-end;
}
.priceItem .price{
align-items: center;
}
.vipPrice2{
align-items: flex-end;
margin-top: 12rpx;
font-size: 24rpx;
}
.vipPrice2 .left{
color: #333;
font-weight: bold;
margin-left: 8rpx;
}
.vipPrice2 .vipIcon{
margin-left: 8rpx;
min-width: 64rpx;
padding: 2rpx 8rpx;
height: 28rpx;
background: #333;
font-size: 20rpx;
line-height: 28rpx;
text-align: center;
color: #d7c7a1;
border-radius: 12rpx;
border-top-left-radius: 2rpx;
-webkit-border-radius: 12rpx;
-moz-border-radius: 12rpx;
-ms-border-radius: 12rpx;
-o-border-radius: 12rpx;
}
.Sold{
overflow: hidden;
color: #999;
}
.Sold text{
font-size: 24rpx;
}
.buy-now-icon{
color: var(--main-color);
}
.buy-now {
color: #ffffff;
position: absolute;
right: 0;
bottom: 0;
border-radius: 30rpx;
background-color: var(--main-color);
width: 140rpx;
white-space: nowrap;
padding: 8rpx 20rpx;
display: flex;
justify-content: center;
align-items: center;
-webkit-border-radius: 30rpx;
-moz-border-radius: 30rpx;
-ms-border-radius: 30rpx;
-o-border-radius: 30rpx;
}
.buy-now-icon {
position: absolute;
right: 0;
bottom: 0;
font-size: 36rpx;
}
.showCommission {
width: auto;
display: inline-block;
margin-top: 8rpx;
border: 1px solid transparent;
border-radius: 12rpx;
font-size: 10px;
overflow: hidden;
-webkit-border-radius: 12rpx;
-moz-border-radius: 12rpx;
-ms-border-radius: 12rpx;
-o-border-radius: 12rpx;
}
.showCommission .commission-box {
box-sizing: border-box;
padding: 0 10rpx;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.showCommissionTwo {
align-items: center;
justify-content: center;
margin-top: 16rpx;
width: 100%;
height: 52rpx;
font-size: 24rpx;
border: 1px solid transparent;
border-radius: 26px;
overflow: hidden;
}
.showCommissionTwo .commission-box {
width: 100%;
height: 100%;
padding-left: 20rpx;
display: flex;
justify-content: center;
align-items: center;
}
.showCommissionTwo i {
font-size: 28rpx;
margin-right: 8rpx;
}
.marketing {
align-items: center;
flex-wrap: wrap;
}
.marketing .item {
margin-top: 8rpx;
margin-right: 8rpx;
font-size: 20rpx;
padding: 0 12rpx;
border: 2rpx solid #ff5500;
color: #ff5500;
border-radius: 40rpx;
-webkit-border-radius: 40rpx;
-moz-border-radius: 40rpx;
-ms-border-radius: 40rpx;
-o-border-radius: 40rpx;
}
.bottom {
position: relative;
}
.price {
font-weight: 600;
margin-top: 12rpx;
}
\ No newline at end of file
import TouchEvent from "./utils/touchEvent";
const componentOptions = {
// 组件选项
options: {
multipleSlots: true
},
behaviors: [],
properties: {
datas: {
type:Object
},
goodsList: {
type:Array
}
},
// 组件数据
data: {
isPageHidden: false, // 页面是否处于隐藏状态
isLoading: false,
swiperCurIndex: 0,
slideClass: "",
lockSwipe: false
},
// 数据监听器
observers: {},
// 组件生命周期
lifetimes: {
created() {
new TouchEvent(this, "touchCard", {
swipe: evt => {
//在touch结束触发,evt.direction代表滑动的方向 ['Up','Right','Down','Left']
if (evt.direction === "Left") this.next(evt);
if (evt.direction === "Right") this.prev(evt);
}
});
},
attached() {}
},
// 组件方法
methods: {
next(e) {
if (this.data.lockSwipe) return;
this.data.lockSwipe = true;
if (-this.data.swiperCurIndex >= this.data.goodsList.length - 1) {
return (this.data.lockSwipe = false);
}
const index = e.currentTarget.dataset["index"];
this.setData(
{ ["goodsList[" + index + "].slideClass"]: " ani-slide-up" },
() => {
this.setData({
swiperCurIndex: --this.data.swiperCurIndex
});
}
);
setTimeout(() => {
this.data.lockSwipe = false;
this.setData({
["goodsList[" + index + "].slideClass"]: ""
});
}, 590);
},
prev(e) {
const index = e.currentTarget.dataset["index"] - 1;
if (this.data.lockSwipe || index < 0) return;
this.data.lockSwipe = true;
this.setData({
["goodsList[" + index + "].slideClass"]: " ani-slide-down",
swiperCurIndex: ++this.data.swiperCurIndex
});
setTimeout(() => {
this.data.lockSwipe = false;
this.setData({
["goodsList[" + index + "].slideClass"]: ""
});
}, 590);
}
},
definitionFilter() {},
// 页面生命周期
pageLifetimes: {
// 页面被展示
show() {
const { isPageHidden } = this.data;
// show事件发生前,页面不是处于隐藏状态时
if (!isPageHidden) {
return;
}
// 重新执行定时器等操作
},
// 页面被隐藏
hide() {
this.setData({
isPageHidden: true
});
// 清除定时器等操作
},
// 页面尺寸变化时
resize() {}
}
};
Component(componentOptions);
{
"component": true,
"usingComponents": {
"goods-item": "../GoodsItem/index"
}
}
<view class="container center">
<view class="card-swiper">
<view
wx:for="{{goodsList}}"
wx:key="index"
data-index="{{index}}"
class="{{'card-swiper-item curdistance' + (swiperCurIndex + index) + (!!item.slideClass? item.slideClass: '')}}"
bindtouchstart="touchCard.start"
bindtouchmove="touchCard.move"
bindtouchend="touchCard.end"
bindtouchcancel="touchCard.cancel"
>
<goods-item
style="width:100%"
datas="{{datas}}"
items="{{goodsList[index]}}"
indexs="{{index}}"
></goods-item>
</view>
</view>
</view>
.container{
width: 100%;
height: 200rpx;
padding: 0 0 20rpx;
}
/**index.wxss**/
.card-swiper{
position: relative;
width: 100%;
height: 100%;
color: #666;
font-size: 28rpx;
}
.card-swiper-item{
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 92%;
transition: all .3s ease-out;
z-index: 0;
display: none;
overflow: hidden;
}
.card-swiper .card-swiper-item.curdistance0{
z-index: 10;
display: flex;
}
.card-swiper .card-swiper-item.curdistance1{
display: flex;
z-index: 9;
transform: scale(.95);
opacity: .7;
left: 40rpx;
}
.card-swiper .card-swiper-item.curdistance2{
display: flex;
z-index: 8;
transform: scale(.9);
opacity: .4;
left: 80rpx;
}
.ani-slide-up{
display: flex;
animation: slideUp .6s ease-out;
z-index: 11;
/* transform: rotate(25deg); */
}
.ani-slide-down{
display: flex;
animation: slideUp .6s ease-in;
animation-direction: reverse;
}
@keyframes slideUp{
0% {
}
70% {
opacity: 1;
}
100% {
transform: translateX(-1000rpx);
opacity: 0;
-webkit-transform: translateX(-1000rpx);
-moz-transform: translateX(-1000rpx);
-ms-transform: translateX(-1000rpx);
-o-transform: translateX(-1000rpx);
}
}
\ No newline at end of file
var defaultOption = {
touchStart: function () { },
touchMove: function () { },
touchEnd: function () { },
touchCancel: function () { },
multipointStart: function () { },
multipointEnd: function () { },
tap: function () { },
doubleTap: function () { },
longTap: function () { },
singleTap: function () { },
rotate: function () { },
pinch: function () { },
pressMove: function () { },
swipe: function () { }
}
export default class YrobotTouch {
constructor(pageOBJ, name, option = {}) {
this.preV = { x: null, y: null };
this.pinchStartLen = null;
this.scale = 1;
this.isDoubleTap = false;
this.delta = null;
this.last = null;
this.now = null;
this.tapTimeout = null;
this.singleTapTimeout = null;
this.longTapTimeout = null;
this.swipeTimeout = null;
this.x1 = this.x2 = this.y1 = this.y2 = null;
this.preTapPosition = { x: null, y: null };
this.lastZoom = 1;
this.tempZoom = 1;
try {
if (this._checkBeforeCreate(pageOBJ, name)) {
this._name = name
this._option = { ...defaultOption, ...option }
pageOBJ[name] = this
this._bindFunc(pageOBJ)
}
} catch (error) {
console.error(error)
}
}
_checkBeforeCreate(pageOBJ, name) {
if (!pageOBJ || !name) {
throw new Error('YrobotTouch实例化时,必须传入page对象和引用名')
return false
}
if (pageOBJ[name]) {
throw new Error('YrobotTouch实例化error: ' + name + ' 已经存在page中')
return false
}
return true
}
_bindFunc(pageOBJ) {
let funcNames = ['start', 'move', 'end', 'cancel']
for (let funcName of funcNames)
pageOBJ[this._name + '.' + funcName] = this[funcName].bind(this)
}
start(evt) {
if (!evt.touches) return;
this.now = Date.now();
this.x1 = evt.touches[0].pageX == null ? evt.touches[0].x : evt.touches[0].pageX;
this.y1 = evt.touches[0].pageY == null ? evt.touches[0].y : evt.touches[0].pageY;
this.delta = this.now - (this.last || this.now);
this._option.touchStart(evt);
if (this.preTapPosition.x !== null) {
this.isDoubleTap = (this.delta > 0 && this.delta <= 250 && Math.abs(this.preTapPosition.x - this.x1) < 30 && Math.abs(this.preTapPosition.y - this.y1) < 30);
}
this.preTapPosition.x = this.x1;
this.preTapPosition.y = this.y1;
this.last = this.now;
let preV = this.preV,
len = evt.touches.length;
if (len > 1) {
this._cancelLongTap();
this._cancelSingleTap();
let otx = evt.touches[1].pageX == null ? evt.touches[1].x : evt.touches[1].pageX;
let oty = evt.touches[1].pageY == null ? evt.touches[1].y : evt.touches[1].pageY;
let v = { x: otx - this.x1, y: oty - this.y1 };
preV.x = v.x;
preV.y = v.y;
this.pinchStartLen = getLen(preV);
this._option.multipointStart(evt);
}
this.longTapTimeout = setTimeout(function () {
evt.type = "longTap";
this._option.longTap(evt);
}.bind(this), 750);
}
move(evt) {
if (!evt.touches) return;
let preV = this.preV,
len = evt.touches.length,
currentX = evt.touches[0].pageX == null ? evt.touches[0].x : evt.touches[0].pageX,
currentY = evt.touches[0].pageY == null ? evt.touches[0].y : evt.touches[0].pageY;
this.isDoubleTap = false;
if (len > 1) {
let otx = evt.touches[1].pageX == null ? evt.touches[1].x : evt.touches[1].pageX;
let oty = evt.touches[1].pageY == null ? evt.touches[1].y : evt.touches[1].pageY;
let v = { x: otx - currentX, y: oty - currentY };
if (preV.x !== null) {
if (this.pinchStartLen > 0) {
evt.singleZoom = getLen(v) / this.pinchStartLen;
evt.zoom = evt.singleZoom * this.lastZoom;
this.tempZoom = evt.zoom;
evt.type = "pinch";
this._option.pinch(evt);
}
evt.angle = getRotateAngle(v, preV);
evt.type = "rotate";
this._option.rotate(evt);
}
preV.x = v.x;
preV.y = v.y;
} else {
if (this.x2 !== null) {
evt.deltaX = currentX - this.x2;
evt.deltaY = currentY - this.y2;
} else {
evt.deltaX = 0;
evt.deltaY = 0;
}
this._option.pressMove(evt);
}
this._option.touchMove(evt);
this._cancelLongTap();
this.x2 = currentX;
this.y2 = currentY;
if (len > 1) {
// evt.preventDefault();
}
}
end(evt) {
if (!evt.changedTouches) return;
this._cancelLongTap();
let self = this;
evt.direction = this._swipeDirection(this.x1, this.x2, this.y1, this.y2); //在结束钩子都加入方向判断,但触发swipe瞬时必须位移大于30
if (evt.touches.length < 2) {
this.lastZoom = this.tempZoom;
this._option.multipointEnd(evt);
}
this._option.touchEnd(evt);
//swipe
if ((this.x2 && Math.abs(this.x1 - this.x2) > 30) ||
(this.y2 && Math.abs(this.y1 - this.y2) > 30)) {
// evt.direction = this._swipeDirection(this.x1, this.x2, this.y1, this.y2);
this.swipeTimeout = setTimeout(function () {
evt.type = "swipe";
self._option.swipe(evt);
}, 0)
} else {
this.tapTimeout = setTimeout(function () {
evt.type = "tap";
self._option.tap(evt);
// trigger double tap immediately
if (self.isDoubleTap) {
evt.type = "doubleTap";
self._option.doubleTap(evt);
clearTimeout(self.singleTapTimeout);
self.isDoubleTap = false;
}
}, 0)
if (!self.isDoubleTap) {
self.singleTapTimeout = setTimeout(function () {
self._option.singleTap(evt);
}, 250);
}
}
this.preV.x = 0;
this.preV.y = 0;
this.scale = 1;
this.pinchStartLen = null;
this.x1 = this.x2 = this.y1 = this.y2 = null;
}
cancel(evt) {
clearTimeout(this.singleTapTimeout);
clearTimeout(this.tapTimeout);
clearTimeout(this.longTapTimeout);
clearTimeout(this.swipeTimeout);
this._option.touchCancel(evt);
}
_cancelLongTap() {
clearTimeout(this.longTapTimeout);
}
_cancelSingleTap() {
clearTimeout(this.singleTapTimeout);
}
_swipeDirection(x1, x2, y1, y2) {
return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
}
destroy() {
if (this.singleTapTimeout) clearTimeout(this.singleTapTimeout);
if (this.tapTimeout) clearTimeout(this.tapTimeout);
if (this.longTapTimeout) clearTimeout(this.longTapTimeout);
if (this.swipeTimeout) clearTimeout(this.swipeTimeout);
this._option.rotate = null;
this._option.touchStart = null;
this._option.multipointStart = null;
this._option.multipointEnd = null;
this._option.pinch = null;
this._option.swipe = null;
this._option.tap = null;
this._option.doubleTap = null;
this._option.longTap = null;
this._option.singleTap = null;
this._option.pressMove = null;
this._option.touchMove = null;
this._option.touchEnd = null;
this._option.touchCancel = null;
this.preV = this.pinchStartLen = this.scale = this.isDoubleTap = this.delta = this.last = this.now = this.tapTimeout = this.singleTapTimeout = this.longTapTimeout = this.swipeTimeout = this.x1 = this.x2 = this.y1 = this.y2 = this.preTapPosition = this.rotate = this.touchStart = this.multipointStart = this.multipointEnd = this.pinch = this.swipe = this.tap = this.doubleTap = this.longTap = this.singleTap = this.pressMove = this.touchMove = this.touchEnd = this.touchCancel = null;
return null;
}
}
function getLen(v) {
return Math.sqrt(v.x * v.x + v.y * v.y);
}
function dot(v1, v2) {
return v1.x * v2.x + v1.y * v2.y;
}
function getAngle(v1, v2) {
let mr = getLen(v1) * getLen(v2);
if (mr === 0) return 0;
let r = dot(v1, v2) / mr;
if (r > 1) r = 1;
return Math.acos(r);
}
function cross(v1, v2) {
return v1.x * v2.y - v2.x * v1.y;
}
function getRotateAngle(v1, v2) {
let angle = getAngle(v1, v2);
if (cross(v1, v2) > 0) {
angle *= -1;
}
return angle * 180 / Math.PI;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment