<template>
|
|
<view class="product"
|
|
@touchstart="onTouchstart"
|
|
@touchmove="onTouchmove"
|
|
@touchend="onTouchend"
|
|
>
|
|
<image class="product-img" :src="data.image" mode="aspectFill"></image>
|
|
<view class="flex flex-column product-info">
|
|
<view class="product-info-top">
|
|
<view class="product-name text-ellipsis-2">{{ data.name }}</view>
|
|
<view class="product-desc text-ellipsis">{{ data.desc }}</view>
|
|
</view>
|
|
<view class="flex product-info-bottom">
|
|
<view class="product-detail">
|
|
<view class="flex product-price">
|
|
<view class="product-price-val">
|
|
<text>¥</text>
|
|
<text class="highlight">{{ priceInt }}</text>
|
|
<text>{{ `${priceFrac}起` }}</text>
|
|
</view>
|
|
<view class="product-price-bef" v-if="data.originalPrice">
|
|
{{ `¥${data.originalPrice}` }}
|
|
</view>
|
|
</view>
|
|
<view class="product-registered">
|
|
{{ `${data.registered}人已报名` }}
|
|
</view>
|
|
</view>
|
|
<button class="btn" @click="onRegistrate">报名</button>
|
|
</view>
|
|
</view>
|
|
|
|
<button class="flex btn-collect"
|
|
:style="collectBtnStyle"
|
|
@click.stop="onCollect"
|
|
@touchstart.stop="() => {}"
|
|
>
|
|
<view>{{ isCollected ? '移除收藏' : '收藏' }}</view>
|
|
</button>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
data: {
|
|
type: Object,
|
|
default() {
|
|
return {}
|
|
}
|
|
},
|
|
isCollected: {
|
|
type: Boolean,
|
|
default: false,
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
isMove: false,
|
|
startClientX: null,
|
|
displayX: 0,
|
|
}
|
|
},
|
|
computed: {
|
|
priceInt() {
|
|
return parseInt(this.data.currentPrice)
|
|
},
|
|
priceFrac() {
|
|
return (this.data.currentPrice % this.priceInt).toFixed(2).slice(1)
|
|
},
|
|
collectBtnStyle() {
|
|
const width = this.isCollected ? 80 : 56
|
|
const background = this.isCollected ? '#26334E' : '#FF9035'
|
|
|
|
let display = Math.ceil(this.displayX / this.collectBtnWidth * 100)
|
|
|
|
display > 100 && (display = 100)
|
|
|
|
const translateX = 100 - display
|
|
|
|
return `width: ${width}px; transform: translateX(${translateX}%); background: ${background};`
|
|
}
|
|
},
|
|
methods: {
|
|
onTouchstart(e) {
|
|
const clientX = e.changedTouches[0].clientX
|
|
|
|
this.isMove = false
|
|
this.startClientX = clientX
|
|
this.displayX = 0
|
|
},
|
|
onTouchmove(e) {
|
|
const clientX = e.changedTouches[0].clientX
|
|
|
|
if (clientX < this.startClientX) {
|
|
this.displayX = this.startClientX - clientX
|
|
} else {
|
|
this.displayX = 0
|
|
}
|
|
|
|
this.isMove = true
|
|
},
|
|
onTouchend() {
|
|
if (this.displayX < 100) {
|
|
this.displayX = 0
|
|
}
|
|
|
|
this.isMove = false
|
|
},
|
|
showCollectBtn() {
|
|
this.displayX = 100
|
|
},
|
|
hiddenCollectBtn() {
|
|
this.displayX = 0
|
|
},
|
|
onCollect() {
|
|
console.log('onCollect')
|
|
|
|
if (this.isCollected) {
|
|
// todo: fetch cancel collect
|
|
uni.showToast({
|
|
icon: 'success',
|
|
title: '已移除收藏',
|
|
});
|
|
} else {
|
|
// todo: fetch collect
|
|
uni.showToast({
|
|
icon: 'success',
|
|
title: '已收藏',
|
|
});
|
|
}
|
|
this.hiddenCollectBtn()
|
|
},
|
|
onRegistrate() {
|
|
this.$utils.navigateTo(`/pages_order/product/productDetail?id=${this.data.id}`)
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.product {
|
|
position: relative;
|
|
height: 464rpx;
|
|
background: #FFFFFF;
|
|
border: 2rpx solid #FFFFFF;
|
|
border-radius: 32rpx;
|
|
overflow: hidden;
|
|
font-size: 0;
|
|
|
|
&-img {
|
|
width: 100%;
|
|
height: 220rpx;
|
|
}
|
|
|
|
&-info {
|
|
height: 244rpx;
|
|
padding: 16rpx 16rpx 24rpx 16rpx;
|
|
box-sizing: border-box;
|
|
justify-content: space-between;
|
|
|
|
&-top {
|
|
|
|
}
|
|
|
|
&-bottom {
|
|
width: 100%;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
}
|
|
|
|
&-name {
|
|
font-size: 28rpx;
|
|
font-weight: 500;
|
|
color: #000000;
|
|
}
|
|
|
|
&-desc {
|
|
margin-top: 8rpx;
|
|
font-size: 24rpx;
|
|
color: #8B8B8B;
|
|
}
|
|
|
|
&-detail {
|
|
|
|
}
|
|
|
|
&-price {
|
|
justify-content: flex-start;
|
|
align-items: baseline;
|
|
column-gap: 12rpx;
|
|
|
|
&-val {
|
|
font-size: 24rpx;
|
|
font-weight: 500;
|
|
color: #FF4800;
|
|
|
|
.highlight {
|
|
font-size: 32rpx;
|
|
}
|
|
|
|
}
|
|
|
|
&-bef {
|
|
text-decoration: line-through;
|
|
font-size: 24rpx;
|
|
color: #8B8B8B;
|
|
}
|
|
}
|
|
|
|
&-registered {
|
|
font-size: 24rpx;
|
|
color: #8B8B8B;
|
|
}
|
|
|
|
.btn {
|
|
padding: 11rpx 16rpx;
|
|
font-size: 26rpx;
|
|
font-weight: 500;
|
|
color: #FFFFFF;
|
|
background: #00A9FF;
|
|
border-radius: 24rpx;
|
|
}
|
|
|
|
}
|
|
|
|
.btn-collect {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
row-gap: 8rpx;
|
|
// width: 112rpx;
|
|
height: 100%;
|
|
font-size: 24rpx;
|
|
line-height: 1;
|
|
color: #FFFFFF;
|
|
// background: #FF9035;
|
|
}
|
|
|
|
</style>
|