Merge branch 'feature/task1.0.0_xg' into 'feature/task1.0.0'

feat: 首页秒杀模块,秒杀页面

See merge request yanxuan-frontend/shop-pc!18
merge-requests/19/head
肖广 3 years ago
commit 8d75c38eca

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 160 KiB

@ -9,7 +9,7 @@
<div class="home"> <div class="home">
<Banner /> <Banner />
<div class="home-wrap"> <div class="home-wrap">
<Seckil v-if="true || seckillData.activityTimeVO" :data="seckillData" /> <Seckil v-if="seckillData.activityTimeVO" :data="seckillData" />
</div> </div>
</div> </div>
</template> </template>

@ -7,7 +7,7 @@
--> -->
<template> <template>
<div class="home-sckill flex"> <div class="home-sckill flex" @click="onJumpSeckill">
<div class="home-sckill-bar" :style="{ backgroundImage: `url(${bkgUrl})` }"> <div class="home-sckill-bar" :style="{ backgroundImage: `url(${bkgUrl})` }">
<strong class="home-sckill-title">限时秒杀</strong> <strong class="home-sckill-title">限时秒杀</strong>
<div class="home-sckill-wrap"> <div class="home-sckill-wrap">
@ -36,6 +36,7 @@
<div <div
v-for="(itemChild, indexChild) in item" v-for="(itemChild, indexChild) in item"
:key="itemChild.productId" :key="itemChild.productId"
@click.stop="onJumpGoodsDetail(itemChild.productId)"
class="carousel-goods-box flex flex-middle" class="carousel-goods-box flex flex-middle"
> >
<div <div
@ -117,12 +118,19 @@ export default {
this.goodsList.push(goodsListItem); this.goodsList.push(goodsListItem);
} }
}, },
onJumpSeckill() {
this.$router.push("/seckill");
},
onJumpGoodsDetail(id) {
this.$router.push(`/goods/detail/${id}`);
},
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.home-sckill { .home-sckill {
height: 260px; height: 260px;
cursor: pointer;
.home-sckill-bar { .home-sckill-bar {
width: 190px; width: 190px;
height: 100%; height: 100%;

@ -1,22 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-05-04 17:25:41
* @LastEditors: ch
* @LastEditTime: 2022-05-04 17:26:08
* @Description: file content
-->
<template>
<div>我是秒杀首页</div>
</template>
<script>
export default {
data(){
return {
}
}
}
</script>
<style lang="scss" scoped>
</style>

@ -0,0 +1,329 @@
<!--
* @Author: ch
* @Date: 2022-05-04 17:25:41
* @LastEditors: ch
* @LastEditTime: 2022-05-04 17:26:08
* @Description: file content
-->
<template>
<div class="sckill">
<!-- 秒杀时间段 -->
<div
class="sckill-header"
:style="{ backgroundImage: `url(${bkgSckill})` }"
>
<div class="sckill-header-tabbar flex">
<div
v-for="item in tabList"
:key="item.id"
@click="onTabSelect(item.id)"
class="sckill-header-tabbar__item flex flex-middle flex-center"
:class="{
'sckill-header-tabbar__item--active':
item.id === query.activityTimeId,
}"
>
<strong class="header-tabbar-item__time">18:00</strong>
<div class="header-tabbar-item__tip">抢购中</div>
</div>
</div>
</div>
<div class="sckill-bar flex flex-middle flex-center">
<p>本场秒杀即将开抢距开始还剩</p>
<div class="sckill-bar-countdown flex flex-middle">
<div class="sckill-bar-countdown__time">{{ countdown.hour }}</div>
<span class="sckill-bar-countdown--mark">:</span>
<div class="sckill-bar-countdown__time">{{ countdown.minute }}</div>
<span class="sckill-bar-countdown--mark">:</span>
<div class="sckill-bar-countdown__time">{{ countdown.second }}</div>
</div>
</div>
<!-- 秒杀商品列表 -->
<div v-loading="loading" class="sckill-products flex flex-wrap">
<div
v-for="item in goodsList"
:key="item.productId"
@click="onJumpGoodsDetail(item.productId)"
class="sckill-products-wrap"
>
<img
:src="item.productMainPicture"
class="sckill-products-wrap__cover"
/>
<div class="sckill-products-wrap__content">
<p class="products-wrap-content__title">{{ item.productName }}</p>
<div class="products-wrap-content__price">
<strong>{{ item.activityPrice }}</strong>
<del>{{ item.originalPrice }}</del>
</div>
<div
class="products-wrap-content__footer flex flex-middle flex-between"
>
<div class="wrap-content-footer__stock">
<el-progress :percentage="40" :show-text="false"></el-progress>
<p>仅剩{{ item.stock }}</p>
</div>
<div class="wrap-content-footer__btn">立即抢购</div>
</div>
</div>
</div>
</div>
<!-- 分页 -->
<div class="sckill-pagination flex flex-right">
<el-pagination
background
:current-page="currentPage"
:page-size="query.length"
layout="prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
</el-pagination>
<el-button class="btn-confirm">确定</el-button>
</div>
</div>
</template>
<script>
import { ApiGetSeckillTimes, ApiGetSeckillGoods } from "@/plugins/api/seckill";
export default {
name: "Sckill",
data() {
return {
bkgSckill: require("~/assets/img/sckill/bkg-large.png"),
tabList: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }], //
goodsList: [], //
total: 0,
currentPage: 0,
loading: false,
query: {
pageIndex: 1,
length: 12,
activityTimeId: 1,
},
};
},
computed: {
countdown() {
return {
hour: "01",
minute: "32",
second: "09",
};
},
},
created() {
this.getSeckillTimes();
},
methods: {
async getSeckillTimes() {
const { result } = await ApiGetSeckillTimes();
if (result && result.length > 0) {
this.tabList = result;
this.query.activityTimeId = result[0].id;
this.getGoodsList();
}
},
async getGoodsList() {
this.loading = true;
const { result } = await ApiGetSeckillGoods({ ...this.query });
this.loading = false;
if (result) {
this.total = result.total;
this.goodsList = result.records;
}
},
onJumpGoodsDetail(id) {
this.$router.push(`/goods/detail/${id}`);
},
handleSizeChange(size) {
this.query.length = size;
this.getGoodsList();
},
handleCurrentChange(page) {
this.query.pageIndex = page;
this.getGoodsList();
},
onTabSelect(id) {
this.query.activityTimeId = id;
Object.assign(this.query, {
pageIndex: 1,
length: 10,
});
},
},
};
</script>
<style lang="scss" scoped>
.sckill {
background: #f8f8f8;
padding-bottom: 42px;
.sckill-header {
position: relative;
width: 100%;
height: 156px;
background-size: 100% 100%;
.sckill-header-tabbar {
position: absolute;
left: 50%;
bottom: 0;
transform: translate(-50%);
height: 60px;
border-radius: 4px 4px 0px 0px;
overflow: hidden;
cursor: pointer;
.sckill-header-tabbar__item {
width: 240px;
font-size: 12px;
background: #ffffff;
color: #666666;
.header-tabbar-item__time {
font-size: 18px;
color: #333333;
margin-right: 22px;
}
.header-tabbar-item__tip {
width: 69px;
height: 22px;
text-align: center;
border: 1px solid #999999;
border-radius: 2px;
}
&--active {
background: linear-gradient(270deg, #ffa25a 0%, #ff7f39 100%);
color: #ffffff;
.header-tabbar-item__time {
font-size: 24px;
color: #ffffff;
}
.header-tabbar-item__tip {
border-color: #ffffff;
}
}
}
}
}
.sckill-bar {
height: 60px;
line-height: 60px;
text-align: center;
font-size: 14px;
color: #666666;
.sckill-bar-countdown {
margin-left: 25px;
font-weight: bold;
&__time {
width: 22px;
height: 22px;
line-height: 22px;
text-align: center;
font-size: 14px;
color: #ffffff;
background: #2f3430;
}
&--mark {
display: block;
margin: 0 7px;
color: #2f3430;
}
}
}
.sckill-products,
.sckill-pagination {
@include layout-box;
}
.sckill-products {
.sckill-products-wrap {
width: 24%;
background: #ffffff;
margin: 15px 0 60px 0;
&:not(:nth-child(4n)) {
margin-right: calc(4% / 3);
}
.sckill-products-wrap__cover {
width: 100%;
height: 288px;
}
.sckill-products-wrap__content {
padding: 20px 16px;
.products-wrap-content__title {
@include ellipsis;
color: #333333;
font-size: 16px;
margin-bottom: 10px;
}
.products-wrap-content__price {
font-size: 12px;
color: #999999;
margin-bottom: 7px;
strong {
font-size: 18px;
color: #ff512b;
margin-right: 14px;
}
}
.products-wrap-content__footer {
.wrap-content-footer__stock {
font-size: 12px;
color: #666666;
/deep/.el-progress {
width: 100px;
height: 6px;
background: #dddddd;
border-radius: 4px;
margin-bottom: 8px;
}
}
.wrap-content-footer__btn {
width: 100px;
height: 36px;
line-height: 36px;
text-align: center;
background: #ff512b;
font-size: 14px;
color: #ffffff;
}
}
}
}
}
.sckill-pagination {
margin-top: 60px;
/deep/.el-pagination {
.btn-prev,
.btn-next {
width: 32px;
height: 32px;
background: #ffffff;
border-radius: 2px;
border: 1px solid rgba(0, 0, 0, 0.2);
}
.el-pagination__jump {
color: #333333;
}
.el-pager {
.number {
width: 32px;
height: 32px;
line-height: 32px;
font-size: 14px;
background: #ffffff;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 2px;
}
.active {
color: #ffffff;
background: #ff512b;
border: none;
}
}
}
.btn-confirm {
width: 81px;
height: 32px;
border-radius: 2px;
margin-left: 14px;
}
}
}
</style>

@ -23,5 +23,5 @@ const BASE_URL = `${ENV.base_url}/mall/marketing`;
* 获取当天秒杀时段 * 获取当天秒杀时段
*/ */
export const ApiGetSeckillGoods = (params) => export const ApiGetSeckillGoods = (params) =>
ToAsyncAwait(axios.get(`${BASE_URL}/app/activity/product`, params)); ToAsyncAwait(axios.get(`${BASE_URL}/app/activity/product`, { params }));

Loading…
Cancel
Save