Files
xdd-uniapp-new/pkg_product/views/seckill.vue
T
2023-11-20 15:54:00 +08:00

560 lines
14 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 class="img-seckill" :src="webUrl+'/20221222155145987590.png'" mode="scaleToFill"/>
<image class="img-rule" :src="webUrl+'/20221222155206016851.png'" mode="scaleToFill" @click="changeRule"/>
</view>
<view class="dialog-mask" v-show="showRule">
<view class="dialog">
<image class="icon-close" :src="webUrl+'/20221230200935413332.png'" 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 class="content">{{ ruleContent }}</view>-->
</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">
<text class="text-tip">倒计时:</text>
<count-down-unit :isDay="true" isSecond :dayText="'天'" :hourText="':'" :minuteText="':'"
:secondText="false"
:datatime="item.limitEndTimeMillis"></count-down-unit>
</view>
</view>
<view class="content flex ai-end">
<image class="img-cover flex-0" :src="item.image"
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 class="img-hot flex-0" :src="webUrl+'/20230311090049756844.png'" mode="scaleToFill"/>
</view>
<view class="nav-line flex">
<view class="nav-item flex-0 flex flex-col jc-end ai-center" :class="{'active':index===seckillTimeIndex}"
v-for="(item,index) in seckillTime" :key="index" @click="navChange(index)">
<view class="time">{{ item.time }}</view>
<view class="tag">{{ item.state }}</view>
</view>
</view>
</view>
<view class="list-box">
<view class="item flex" v-for="(item,index) in list" :key="index"
@click="goGoodsConByProductID(item,seckillTime[seckillTimeIndex].status)">
<image class="img-cover flex-0" :src="item.image"
mode="scaleToFill"/>
<view class="content flex flex-col jc-between">
<view class="top-section">
<!-- style="height: 150rpx"-->
<view class="more-t">{{ item.title }}</view>
<view class="company">{{ item.unitName }}</view>
</view>
<view>
<view class="line-price flex jc-between ai-center">
<view class="flex ai-end">
<view>秒杀价</view>
<view class="price">{{ item.price }}</view>
</view>
<view class="advance flex jc-center ai-center" v-if="seckillTime[seckillTimeIndex].status>1">即将开始
</view>
</view>
<view class="path-box flex jc-between ai-center"
:style="{'backgroundImage':`url(${webUrl}/20221222155107931036.png)`}"
v-if="seckillTime[seckillTimeIndex].status===1">
<view class="sale flex ai-center">已抢{{ item.sales }}</view>
<view class="btn">立即抢购</view>
</view>
</view>
</view>
</view>
</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";
export default {
name: "seckill",
components: {
CountDownUnit
},
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
}
},
computed: mapGetters(["userInfo", "isLogin"]),
onShareAppMessage() {
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;
font-size: 26rpx;
.timeTxt {
color: #E62113;
}
.unit {
display: inline-flex;
justify-content: center;
align-items: center;
width: 26rpx;
height: 32rpx;
margin: 0 2rpx;
background: #E02619;
color: #fff;
box-shadow: 2rpx 2rpx 2rpx rgba(0, 0, 0, 0.16);
border-radius: 4rpx;
font-weight: bold;
}
}
}
}
.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;
}
}
}
}
}
}
</style>