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

Feature/task1.0.0

See merge request yanxuan-frontend/shop-pc!28
merge-requests/30/merge
肖广 3 years ago
commit 6b14d5e35a

@ -25,4 +25,10 @@ const CATEGROY_LEVEL = {
TWO: 2, TWO: 2,
}; };
export { TOKEN_KEY, ORDER_STATUS, SEX_TYPE, CATEGROY_LEVEL }; // 秒杀活动状态
const SECKILL_STATUS = {
NOT_START: 1, // 未开始
GOING: 2, // 进行中
};
export { TOKEN_KEY, ORDER_STATUS, SEX_TYPE, CATEGROY_LEVEL, SECKILL_STATUS };

@ -9,24 +9,41 @@
<div class="home"> <div class="home">
<Banner /> <Banner />
<div class="home-wrap"> <div class="home-wrap">
<Seckil v-if="seckillData.activityTimeVO" :data="seckillData" /> <Seckil
v-if="seckillData.activityTimeVO"
:data="seckillData"
:current="currentTime"
@refresh="handleSeckillRefresh"
/>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { ApiGetHomeSeckill } from "@/plugins/api/seckill"; import { ApiGetHomeSeckill, ApiGetCurrentTime } from "@/plugins/api/seckill";
import Banner from "./module/Banner.vue"; import Banner from "./module/Banner.vue";
import Seckil from "./module/Seckill.vue"; import Seckil from "./module/Seckill.vue";
export default { export default {
components: { Banner, Seckil }, components: { Banner, Seckil },
async asyncData() { async asyncData() {
// //
const { result } = await ApiGetHomeSeckill(); const { result: seckillData } = await ApiGetHomeSeckill();
//
const { result: currentTime } = await ApiGetCurrentTime();
return { return {
seckillData: result, currentTime,
seckillData,
}; };
}, },
methods: {
//
async handleSeckillRefresh() {
const { result: seckillData } = await ApiGetHomeSeckill();
const { result: currentTime } = await ApiGetCurrentTime();
this.seckillData = seckillData;
this.currentTime = currentTime;
},
},
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

@ -66,7 +66,6 @@
</template> </template>
<script> <script>
import _ from "lodash"; import _ from "lodash";
import { FormatDate } from "@/plugins/utils";
const CAROUSEL_COUNT = 5; // const CAROUSEL_COUNT = 5; //
@ -77,6 +76,10 @@ export default {
type: Object, type: Object,
default: () => ({}), default: () => ({}),
}, },
current: {
type: Number,
default: 0,
},
}, },
data() { data() {
return { return {
@ -93,15 +96,13 @@ export default {
immediate: true, immediate: true,
handler(val) { handler(val) {
const { const {
currentTime,
activityProductListVO: products, activityProductListVO: products,
activityTimeVO: { activityEndTime, activityStartTime }, activityTimeVO: { activityStartTime, activityEndTime },
} = val; } = val;
if (products && products.length > 0) { if (products && products.length > 0) {
this.getFormatData(products); this.setCarouselData(products);
} }
this.getSeckillData({ this.setTimerInterval({
currentTime,
startTime: activityStartTime, startTime: activityStartTime,
endTime: activityEndTime, endTime: activityEndTime,
}); });
@ -111,12 +112,14 @@ export default {
computed: { computed: {
// //
countdown() { countdown() {
const date = FormatDate(this.seckillTime, "hh:mm:ss"); const data = parseInt(this.seckillTime / 1e3);
const [hour, minute, second] = date.split(":"); const hour = Math.floor(data / 60 / 60);
const minute = Math.floor((data / 60) % 60);
const second = Math.floor(data % 60);
return { return {
hour, hour: hour < 10 ? `0${hour}` : `${hour}`,
minute, minute: minute < 10 ? `0${minute}` : `${minute}`,
second, second: second < 10 ? `0${second}` : `${second}`,
}; };
}, },
}, },
@ -125,7 +128,7 @@ export default {
}, },
methods: { methods: {
// //
getFormatData(list) { setCarouselData(list) {
const listCopy = _.cloneDeep(list); const listCopy = _.cloneDeep(list);
const part = Math.ceil(listCopy.length / CAROUSEL_COUNT); const part = Math.ceil(listCopy.length / CAROUSEL_COUNT);
if (part === 1) { if (part === 1) {
@ -137,28 +140,26 @@ export default {
this.goodsList.push(goodsListItem); this.goodsList.push(goodsListItem);
} }
}, },
//
getSeckillData({ current, startTime, endTime }) { //
current = new Date(current); setTimerInterval({ startTime, endTime }) {
startTime = new Date(startTime); startTime = new Date(startTime).getTime();
endTime = new Date(endTime); endTime = new Date(endTime).getTime();
if (current > startTime && current < endTime) { if (this.current > startTime && this.current < endTime) {
// //
this.seckillText = "距结束"; this.seckillText = "距结束";
this.seckillTime = endTime - current; this.seckillTime = endTime - this.current;
} else { } else {
// //
this.seckillText = "距开始"; this.seckillText = "距开始";
this.seckillTime = startTime - current; this.seckillTime = startTime - this.current;
} }
this.setCountDownInterval();
},
//
setCountDownInterval() {
this.timeInterval = setInterval(() => { this.timeInterval = setInterval(() => {
if (this.seckillTime <= 0) { if (this.seckillTime <= 0) {
clearInterval(this.timeInterval); clearInterval(this.timeInterval);
this.$emit("refresh");
return;
} }
this.seckillTime -= 1000; this.seckillTime -= 1000;
}, 1e3); }, 1e3);

@ -9,9 +9,9 @@
<div class="seckill"> <div class="seckill">
<div v-show="isSticky" class="seckill-header-sticky"> <div v-show="isSticky" class="seckill-header-sticky">
<TabBar <TabBar
v-model="query.activityTimeId" :tab-id="query.activityTimeId"
:list="tabList" :list="tabList"
@tab-click="getGoodsList" @tab-change="handleTabChange"
/> />
</div> </div>
<!-- 秒杀时间段 --> <!-- 秒杀时间段 -->
@ -21,13 +21,17 @@
> >
<div class="seckill-header-tabbar"> <div class="seckill-header-tabbar">
<TabBar <TabBar
v-model="query.activityTimeId" :tab-id="query.activityTimeId"
:list="tabList" :list="tabList"
@tab-click="getGoodsList" @tab-change="handleTabChange"
/> />
</div> </div>
</div> </div>
<div class="seckill-bar flex flex-middle flex-center"> <!-- 倒计时展示 -->
<div
v-if="tabList.length > 0"
class="seckill-bar flex flex-middle flex-center"
>
<p>{{ seckillTip }}</p> <p>{{ seckillTip }}</p>
<div class="seckill-bar-countdown flex flex-middle"> <div class="seckill-bar-countdown flex flex-middle">
<div class="seckill-bar-countdown__time">{{ countdown.hour }}</div> <div class="seckill-bar-countdown__time">{{ countdown.hour }}</div>
@ -81,16 +85,23 @@
</el-pagination> </el-pagination>
<el-button class="btn-confirm">确定</el-button> <el-button class="btn-confirm">确定</el-button>
</div> </div>
<DialogEnd :visible="seckillEndVisible" @close="handleClose" />
</div> </div>
</template> </template>
<script> <script>
import { ApiGetSeckillTimes, ApiGetSeckillGoods } from "@/plugins/api/seckill"; import {
import { FormatDate } from "@/plugins/utils"; ApiGetSeckillTimes,
ApiGetSeckillGoods,
ApiGetCurrentTime,
} from "@/plugins/api/seckill";
import { SECKILL_STATUS } from "@/constants";
import TabBar from "./module/TabBar.vue"; import TabBar from "./module/TabBar.vue";
import DialogEnd from "./module/DialogEnd.vue";
const PAGE_SIZE = 16;
export default { export default {
name: "Sckill", name: "Sckill",
components: { TabBar }, components: { TabBar, DialogEnd },
data() { data() {
return { return {
bkgSckill: require("~/assets/img/sckill/bkg-large.png"), bkgSckill: require("~/assets/img/sckill/bkg-large.png"),
@ -101,38 +112,49 @@ export default {
loading: false, loading: false,
query: { query: {
pageIndex: 1, pageIndex: 1,
length: 16, length: PAGE_SIZE,
activityTimeId: 1, activityTimeId: 0,
}, },
ticking: false, ticking: false,
isSticky: false, isSticky: false,
timeInterval: null, //
seckillTip: "", //
seckillTime: 0, //
seckillEndVisible: false, //
seckillStatus: SECKILL_STATUS.NOT_START, //
}; };
}, },
computed: { computed: {
countdown() { countdown() {
const data = parseInt(this.seckillTime / 1e3);
const hour = Math.floor(data / 60 / 60);
const minute = Math.floor((data / 60) % 60);
const second = Math.floor(data % 60);
return { return {
hour: "01", hour: hour < 10 ? `0${hour}` : `${hour}`,
minute: "32", minute: minute < 10 ? `0${minute}` : `${minute}`,
second: "09", second: second < 10 ? `0${second}` : `${second}`,
}; };
}, },
},
// watch: {
currentTabItem() { //
const tabItem = this.tabList.find( "query.activityTimeId": {
(item) => item.id === this.query.activityTimeId immediate: true,
); handler(val) {
return tabItem || null; if (val === 0) {
}, return;
}
// clearImmediate(this.timeInterval);
seckillTip() { const tabItem = this.tabList.find((item) => item.id === val);
if (this.currentTabItem) { if (tabItem) {
return this.currentTabItem.isInProgress const { activityStartTime, activityEndTime } = tabItem;
? "本场正在秒杀中,好物转瞬即逝,不要错过哦~距结束仅剩" this.setTimerInterval({
: "本场秒杀即将开抢,距开始还剩"; startTime: activityStartTime,
} endTime: activityEndTime,
return ""; });
}
},
}, },
}, },
@ -145,6 +167,7 @@ export default {
}, },
destroyed() { destroyed() {
window.removeEventListener("scroll", this.scrollEventMethod); window.removeEventListener("scroll", this.scrollEventMethod);
clearInterval(this.timeInterval);
}, },
methods: { methods: {
scrollEventMethod() { scrollEventMethod() {
@ -177,6 +200,64 @@ export default {
this.goodsList = result.records; this.goodsList = result.records;
} }
}, },
//
async setTimerInterval({ startTime, endTime }) {
clearInterval(this.timeInterval);
//
const { result } = await ApiGetCurrentTime();
const current = result || Date.now();
startTime = new Date(startTime).getTime();
endTime = new Date(endTime).getTime();
if (current > endTime) {
//
this.getSeckillTimes();
this.queryDataReset();
return;
}
if (startTime < current && endTime > current) {
//
this.seckillTime = endTime - current;
this.seckillTip = "本场正在秒杀中,好物转瞬即逝,不要错过哦~距结束仅剩";
this.seckillStatus = SECKILL_STATUS.GOING;
} else {
//
this.seckillTime = startTime - current;
this.seckillTip = "本场秒杀即将开抢,距开始还剩";
this.seckillStatus = SECKILL_STATUS.NOT_START;
}
this.timeInterval = setInterval(() => {
if (this.seckillTime <= 0) {
clearInterval(this.timeInterval);
//
if (
this.tabList.length === 1 &&
this.seckillStatus === SECKILL_STATUS.GOING
) {
this.seckillEndVisible = true;
return;
}
// activityTimeIdwatch
this.query.activityTimeId = 0;
this.getSeckillTimes();
return;
}
this.seckillTime -= 1e3;
}, 1e3);
},
//
queryDataReset() {
Object.assign(this.query, {
pageIndex: 1,
length: PAGE_SIZE,
});
},
onJumpGoodsDetail(id) { onJumpGoodsDetail(id) {
this.$router.push(`/goods/detail/${id}`); this.$router.push(`/goods/detail/${id}`);
}, },
@ -188,12 +269,15 @@ export default {
this.query.pageIndex = page; this.query.pageIndex = page;
this.getGoodsList(); this.getGoodsList();
}, },
handleTabSelect(id) { handleTabChange(id) {
this.query.activityTimeId = id; this.query.activityTimeId = id;
Object.assign(this.query, { this.queryDataReset();
pageIndex: 1, this.getGoodsList();
length: 16, },
});
//
handleClose() {
this.$router.push("/");
}, },
}, },
}; };
@ -256,7 +340,7 @@ export default {
.seckill-products-wrap { .seckill-products-wrap {
width: 24%; width: 24%;
background: #ffffff; background: #ffffff;
margin: 15px 0 60px 0; margin-bottom: 16px;
cursor: pointer; cursor: pointer;
&:not(:nth-child(4n)) { &:not(:nth-child(4n)) {
margin-right: calc(4% / 3); margin-right: calc(4% / 3);

@ -0,0 +1,71 @@
<template>
<el-dialog
center
width="17%"
:visible.sync="dialogVisible"
:show-close="false"
:close-on-press-escape="false"
:close-on-click-modal="false"
>
<div class="flex flex-column flex-middle">
<div class="dialog-body-wrap">
<p>本期秒杀活动已结束</p>
<p>感谢你的参与</p>
</div>
<UiButton type="yellow_gradual" :radius="true" @click="onClose"
>好的</UiButton
>
</div>
</el-dialog>
</template>
<script>
import UiButton from "@/components/UiButton";
export default {
name: "SeckillDialogEnd",
components: { UiButton },
props: {
visible: {
type: Boolean,
default: false,
},
},
computed: {
dialogVisible: {
get() {
return this.visible;
},
set(val) {
this.$emit("update:visible", val);
},
},
},
methods: {
onClose() {
this.$emit("close");
this.dialogVisible = false;
},
},
};
</script>
<style lang="scss" scoped>
/deep/.el-dialog {
.el-dialog__header {
display: none;
}
.el-dialog__body {
padding: 41px 0;
.dialog-body-wrap {
width: 145px;
font-size: 16px;
line-height: 20px;
text-align: center;
color: rgba(0, 0, 0, 0.9);
margin-bottom: 20px;
}
.ui-button {
width: 164px;
height: 30px;
}
}
}
</style>

@ -6,7 +6,7 @@
@click="onTabClick(item.id)" @click="onTabClick(item.id)"
class="sckill-header-tabbar__item flex flex-middle flex-center" class="sckill-header-tabbar__item flex flex-middle flex-center"
:class="{ :class="{
'sckill-header-tabbar__item--active': item.id === value, 'sckill-header-tabbar__item--active': item.id === tabId,
}" }"
> >
<strong class="header-tabbar-item__time">{{ item.timeName }}</strong> <strong class="header-tabbar-item__time">{{ item.timeName }}</strong>
@ -24,7 +24,7 @@ export default {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
value: { tabId: {
type: Number, type: Number,
default: 0, default: 0,
}, },
@ -32,11 +32,10 @@ export default {
methods: { methods: {
onTabClick(id) { onTabClick(id) {
// tab // tab
if (id === this.value) { if (id === this.tabId) {
return; return;
} }
this.$emit("input", id); this.$emit("tab-change", id);
this.$emit("tab-click");
}, },
}, },
}; };

@ -25,3 +25,9 @@ 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 }));
/**
* 获取当前服务器时间
*/
export const ApiGetCurrentTime = () =>
ToAsyncAwait(axios.get(`${BASE_URL}/app/activity/timestamp`));

Loading…
Cancel
Save