Files
xdd-uniapp-new/pkg_product/views/seckill.vue
T

657 lines
16 KiB
Vue

<template>
<view class="views-seckill pkg-product-list" :style="{'backgroundImage':`url(${webUrl}/20221222155058686606.png)`}">
<!-- <view class="search-box flex jc-between ai-center">-->
<!-- <input type="text" v-model="keyword" placeholder="搜索商品" placeholder-style="color:#949494" @confirm="search">-->
<!-- <image class="icon" :src="webUrl+'/20220903142935869059.png'" mode="scaleToFill" @click="search"></image>-->
<!-- </view>-->
<view class="img-box flex jc-between ai-end">
<image
:src="webUrl+'/20221222155145987590.png'"
class="img-seckill"
mode="scaleToFill"
/>
<image
:src="webUrl+'/20221222155206016851.png'"
class="img-rule"
mode="scaleToFill"
@click="changeRule"
/>
</view>
<!-- 规则富文本弹窗 -->
<view class="dialog-mask" v-show="showRule">
<view class="dialog">
<image
:src="webUrl+'/20221230200935413332.png'"
class="icon-close"
mode="scaleToFill"
@click="changeRule"
/>
<view class="dialog-body">
<view class="flex jc-center">
<image class="title" :src="webUrl+'/20221230201151585898.png'" mode="scaleToFill"/>
</view>
<rich-text class="content" :nodes="ruleContent"/>
</view>
</view>
</view>
<view class="top-list flex">
<view class="item flex-0" v-for="(item,index) in topList" :key="index" @click="goGoodsConByProductID(item)">
<view class="header flex jc-between ai-center">
<image class="img-rush" :src="webUrl+'/20221222155118237514.png'" mode="scaleToFill"/>
<view class="end-time flex ai-center">
<count-down-unit
:isDay="true"
isSecond
:dayText="'天'"
:hourText="':'"
:minuteText="':'"
:secondText="false"
:datatime="item.limitEndTimeMillis"
/>
</view>
</view>
<view class="content flex ai-end">
<image
:src="item.image"
class="img-cover flex-0"
mode="scaleToFill"
/>
<view class="info-box flex flex-col jc-between">
<view class="more-t">{{ item.title }}</view>
<view class="line-price flex jc-between ai-center">
<view>{{ item.price }}</view>
<view class="btn flex jc-center ai-center">立即抢</view>
</view>
</view>
</view>
</view>
</view>
<view class="nav-box flex ai-center">
<view class="img-section">
<image
:src="webUrl+'/20230311090049756844.png'"
class="img-hot flex-0"
mode="scaleToFill"
/>
</view>
<view class="nav-line flex">
<view
v-for="(item,index) in seckillTime"
:key="index"
:class="{'active':index === seckillTimeIndex}"
class="nav-item flex-0 flex flex-col jc-end ai-center"
@click="navChange(index)"
>
<view class="time">{{ item.time }}</view>
<view class="tag">{{ item.state }}</view>
</view>
</view>
</view>
<view class="list-box">
<template v-if="list.length > 0">
<view
v-for="(item, index) in list"
:key="index"
class="item flex"
@click="goGoodsConByProductID(item,seckillTime[seckillTimeIndex].status)"
>
<image
:src="item.image"
class="img-cover flex-0"
mode="scaleToFill"
/>
<view class="content flex flex-col jc-between">
<view class="top-section">
<view class="more-t">{{ item.title }}</view>
</view>
<view class="line-price">
<!-- <view class="line-price flex jc-between ai-center">
<view class="flex ai-end">
<view>秒杀价</view>
<view class="price">{{ item.price }}</view>
</view>
<view
v-if="seckillTime[seckillTimeIndex].status > 1"
class="advance flex jc-center ai-center"
>
即将开始
</view>
</view>
<view
v-if="seckillTime[seckillTimeIndex].status === 1"
:style="{'backgroundImage':`url(${webUrl}/20221222155107931036.png)`}"
class="path-box flex jc-between ai-center"
>
<view class="sale flex ai-center">已抢{{ item.sales }}</view>
<view class="btn">立即抢购</view>
</view> -->
<view class="number-wrap">
<view class="number flex">
<view class="bg">
已抢{{ item.sales }}
</view>
<text class="txt"></text>
</view>
</view>
<view class="price-wrap flex">
<view class="price-txt">
秒杀价
<text class="txt">{{ item.price }}</text>
</view>
<view class="btn">
<image
:src="webUrl + '/page/seckill/btn.png'"
class="btn-img"
/>
</view>
</view>
</view>
</view>
</view>
</template>
<no-good-data v-else />
</view>
</view>
</template>
<script>
import CountDownUnit from '@/pkg_product/components/CountDownUnit.vue'
import {getSeckillRule, getSeckillTopList, getYxStoreSeckillIndex, getYxStoreSeckillPageList} from '@/api/goods'
import {secKillShareImage} from '@/api/share'
import {mapGetters} from 'vuex'
import cookie from '@/utils/store/cookie'
import {userBindParent} from '@/api/user'
import {getUrlParam} from '@/utils/common.js'
import NoGoodData from '@/components/good/NoData'
import { pageListenMixins } from '@/mixins/pageListenMixins'
export default {
name: 'Seckill',
components: {
CountDownUnit,
NoGoodData
},
mixins: [pageListenMixins],
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
showRule: false,
seckillTime: [],
seckillTimeIndex: 0,
page: 1,
list: [],
topList: [],
endReach: false,
timeId: null,
nextList: [],
ruleContent: null,
partnerId: null,
pageKeyId: Object.freeze('seckillIndex')
}
},
computed: mapGetters(['userInfo', 'isLogin']),
onShareAppMessage() {
uni.updateShareMenu({
isPrivateMessage: false,
withShareTicket: false
})
return new Promise(async (resolve, reject) => {
const {status, data} = await secKillShareImage()
if (status === 200) {
resolve({
title: '探寻有趣有味的生活方式',
path: '/pkg_product/views/seckill?partnerId=' + this.userInfo.uid,
imageUrl: data
})
}
})
},
onLoad(options) {
if (options.partnerId) {
this.partnerId = options.partnerId || null
} else {
let obj = uni.getEnterOptionsSync()
if (options.scene != null || obj.query.scene != null) {
let query = options ? decodeURIComponent(options.scene) : decodeURIComponent(obj.query.scene)
this.partnerId = getUrlParam(query, 'partnerId') || null
}
}
if (this.partnerId) {
cookie.set('spread', this.partnerId)
userBindParent({spread: parseInt(this.partnerId)})
}
this.fetchSession()
getSeckillRule().then(({data}) => this.ruleContent = data)
getSeckillTopList(1, 10).then(({data}) => this.topList = data.records)
},
onReachBottom() {
if (this.endReach) return
this.page++
this.fetchList()
},
methods: {
changeRule(){
this.showRule=!this.showRule
},
navChange(index) {
if (this.seckillTimeIndex === index) return
this.seckillTimeIndex = index
this.page = 1
this.list = []
this.timeId = this.seckillTime[this.seckillTimeIndex].id
this.endReach = false
this.fetchList()
},
fetchSession() {
getYxStoreSeckillIndex().then(({ data }) => {
if (data.seckillTime.length === 0) return
this.seckillTime = data.seckillTime.filter(item => item.status > 0)
this.timeId = this.seckillTime[this.seckillTimeIndex].id
this.fetchList()
if (this.seckillTime.length > this.seckillTimeIndex) {
getYxStoreSeckillPageList(1, 10, this.seckillTime[this.seckillTimeIndex + 1].id).then(({ data }) => {
this.nextList = data
})
}
})
},
fetchList() {
getYxStoreSeckillPageList(this.page, 10, this.timeId).then(({ data }) => {
if (data.length > 0) {
data.map(item => this.list.push(item));
} else {
this.endReach = true
}
})
},
goGoodsConByProductID(item, status) {
if (status > 1) {
uni.showToast({
title: '此商品秒杀活动还未开始哦',
icon: 'none'
})
return
}
this.$yrouter.push({
path: '/pages/shop/GoodsCon/index',
query: {
id: item.productId,
activityId: item.id,
from: 'kill'
}
})
}
}
}
</script>
<style scoped lang="less">
@import "@/assets/css/product.less";
.views-seckill {
//padding-top: 40rpx;
background-size: 750rpx 360rpx;
background-repeat: no-repeat;
.dialog-mask {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
background: rgba(51, 51, 51, 0.5);
z-index: 999;
view {
box-sizing: border-box;
}
.dialog {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 560rpx;
height: 800rpx;
padding: 40rpx;
background: #fff;
border-radius: 20rpx;
.icon-close {
position: absolute;
right: 30rpx;
top: 30rpx;
width: 24rpx;
height: 24rpx;
}
.dialog-body {
.title {
width: 192rpx;
height: 40rpx;
vertical-align: middle;
}
.content {
height: 660rpx;
margin-top: 20rpx;
color: #333;
font-size: 28rpx;
line-height: 48rpx;
overflow-y: auto;
}
}
}
}
.img-box {
//margin-top: 40rpx;
padding: 40rpx 32rpx 0;
.img-seckill {
width: 224.65rpx;
height: 46.34rpx;
}
.img-rule {
width: 80rpx;
height: 42rpx;
}
}
::-webkit-scrollbar {
display: none;
}
.top-list {
margin-top: 34rpx;
padding: 0 32rpx;
overflow-x: auto;
.item {
width: 486rpx;
height: 280rpx;
margin-right: 20rpx;
padding: 20rpx;
border-radius: 12rpx;
box-sizing: border-box;
background: #FFF;
.header {
.img-rush {
width: 112rpx;
height: 34rpx;
}
.end-time {
.text-tip {
color: #E62113;
font-size: 22rpx;
}
/deep/ .time {
display: flex;
align-items: center;
padding: 4rpx 10rpx 4rpx 15rpx;
border-radius: 4rpx;
font-size: 26rpx;
background-color: #E02619;
color: #fff;
box-shadow: 1px 1px 1px rgba(0,0,0,0.16);
.styleAll {
margin: 0 12rpx;
}
.unit {
display: inline-flex;
justify-content: center;
align-items: center;
}
}
}
}
.content {
margin-top: 20rpx;
.img-cover {
width: 180rpx;
height: 180rpx;
margin-right: 12rpx;
}
.info-box {
height: 180rpx;
}
.more-t {
margin-top: 8rpx;
font-size: 28rpx;
line-height: 40rpx;
font-weight: bold;
color: #333333;
}
.line-price {
width: 256rpx;
height: 48rpx;
padding-left: 12rpx;
border: 2rpx solid #FFA833;
border-radius: 24rpx;
box-sizing: border-box;
color: #FF6725;
font-size: 30rpx;
.btn {
width: 114rpx;
height: 48rpx;
border-radius: 24rpx;
background: #FFA833;
color: #fff;
font-size: 24rpx;
}
}
}
}
}
.nav-box {
width: 686rpx;
height: 96rpx;
box-sizing: border-box;
margin: 34rpx auto 0;
border-radius: 20rpx 20rpx 0px 0px;
background: #FCE4DB;
.img-section {
position: relative;
height: 48rpx;
padding: 0 24rpx 0 20rpx;
border-right: 2rpx solid #fff;
.img-hot {
position: relative;
top: -12rpx;
width: 108rpx;
height: 74rpx;
}
}
.nav-line {
width: 558rpx;
box-sizing: border-box;
padding-left: 22rpx;
padding-bottom: 14rpx;
overflow-x: auto;
.nav-item {
width: 90rpx;
height: 96rpx;
margin-right: 10rpx;
.time {
font-size: 26rpx;
font-weight: bold;
line-height: 38rpx;
color: #B17961;
}
.tag {
font-size: 20rpx;
line-height: 30rpx;
color: #B17961;
}
}
.active {
.time {
color: #EB524A;
font-size: 32rpx;
line-height: 48rpx;
}
.tag {
color: #FF564A;
}
}
}
}
.list-box {
margin: 0 32rpx;
padding-bottom: 20rpx;
.item {
//height: 244rpx;
margin-bottom: 20rpx;
padding: 20rpx;
box-sizing: border-box;
background: #fff;
.img-cover {
width: 200rpx;
height: 200rpx;
margin-right: 16rpx;
border-radius: 8rpx;
}
.content {
height: 200rpx;
.more-t {
width: 430rpx;
font-size: 28rpx;
font-weight: bold;
line-height: 40rpx;
color: #333333;
}
.company {
//margin-top: 8rpx;
font-size: 24rpx;
font-weight: 500;
line-height: 34rpx;
color: #999999;
}
.line-price {
color: #FF564A;
font-size: 22rpx;
.price {
margin-left: 8rpx;
font-size: 32rpx;
font-weight: bold;
line-height: 1;
color: #DA0000;
}
.advance {
width: 140rpx;
height: 46rpx;
border-radius: 8rpx;
background: #FF564A;
color: #fff;
font-size: 24rpx;
}
}
.path-box {
width: 378rpx;
height: 48rpx;
box-sizing: border-box;
margin-top: 6rpx;
padding: 0 44rpx 0 14rpx;
background-size: 378rpx 48rpx;
background-repeat: no-repeat;
.sale {
width: 208rpx;
height: 36rpx;
box-sizing: border-box;
padding: 0 10rpx;
background: #FCEAEE;
color: #FF564A;
font-size: 22rpx;
}
.btn {
color: #fff;
font-size: 24rpx;
}
}
}
}
}
}
.line-price {
.number-wrap {
display: flex;
.number {
height: 24px;
padding: 0 20rpx 0 0;
border-radius: 12px;
line-height: 24px;
color: #fff;
font-size: 12px;
font-weight: bold;
background: rgba(250,181,176,0.39);
box-shadow: 1px 1px 1px rgba(0,0,0,0.16);
.bg {
z-index: 1;
height: 100%;
padding: 0 4px 0 12px;
margin: 0 2px 0 0;
border-radius: 12px;
background-color: #E92727;
}
}
}
.price-wrap {
align-items: flex-end;
.price-txt {
flex: 1;
height: 24px;
padding: 4px 8px;
color: #fff;
font-size: 12px;
background: linear-gradient(270deg, #FFFFFE 0%, #EB5015 100%);
border-radius: 4px;
.txt {
font-size: 18px;
font-weight: bold;
}
}
.btn {
margin: 0 0 0 -16px;
.btn-img {
width: 42px;
height: 43px;
}
}
}
}
</style>