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

feat: 秒杀活动倒计时

See merge request yanxuan-frontend/shop-pc!26
merge-requests/27/head
肖广 3 years ago
commit 1f305f8721

@ -25,4 +25,10 @@ const CATEGROY_LEVEL = {
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">
<Banner />
<div class="home-wrap">
<Seckil v-if="seckillData.activityTimeVO" :data="seckillData" />
<Seckil
v-if="seckillData.activityTimeVO"
:data="seckillData"
:current="currentTime"
@refresh="handleSeckillRefresh"
/>
</div>
</div>
</template>
<script>
import { ApiGetHomeSeckill } from "@/plugins/api/seckill";
import { ApiGetHomeSeckill, ApiGetCurrentTime } from "@/plugins/api/seckill";
import Banner from "./module/Banner.vue";
import Seckil from "./module/Seckill.vue";
export default {
components: { Banner, Seckil },
async asyncData() {
//
const { result } = await ApiGetHomeSeckill();
const { result: seckillData } = await ApiGetHomeSeckill();
//
const { result: currentTime } = await ApiGetCurrentTime();
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>
<style lang="scss" scoped>

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

@ -27,7 +27,11 @@
/>
</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>
<div class="seckill-bar-countdown flex flex-middle">
<div class="seckill-bar-countdown__time">{{ countdown.hour }}</div>
@ -84,8 +88,11 @@
</div>
</template>
<script>
import { ApiGetSeckillTimes, ApiGetSeckillGoods } from "@/plugins/api/seckill";
import { FormatDate } from "@/plugins/utils";
import {
ApiGetSeckillTimes,
ApiGetSeckillGoods,
ApiGetCurrentTime,
} from "@/plugins/api/seckill";
import TabBar from "./module/TabBar.vue";
export default {
@ -102,37 +109,47 @@ export default {
query: {
pageIndex: 1,
length: 16,
activityTimeId: 1,
activityTimeId: 0,
},
ticking: false,
isSticky: false,
currentTabItem: null, //
timeInterval: null, //
seckillTip: "", //
seckillTime: 0, //
};
},
computed: {
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 {
hour: "01",
minute: "32",
second: "09",
hour: hour < 10 ? `0${hour}` : `${hour}`,
minute: minute < 10 ? `0${minute}` : `${minute}`,
second: second < 10 ? `0${second}` : `${second}`,
};
},
//
currentTabItem() {
const tabItem = this.tabList.find(
(item) => item.id === this.query.activityTimeId
);
return tabItem || null;
},
//
seckillTip() {
if (this.currentTabItem) {
return this.currentTabItem.isInProgress
? "本场正在秒杀中,好物转瞬即逝,不要错过哦~距结束仅剩"
: "本场秒杀即将开抢,距开始还剩";
}
return "";
watch: {
"query.activityTimeId": {
immediate: true,
handler(val) {
if (val === 0) {
return;
}
clearImmediate(this.timeInterval);
const tabItem = this.tabList.find((item) => item.id === val);
if (tabItem) {
this.currentTabItem = tabItem;
const { activityStartTime, activityEndTime } = tabItem;
this.setTimerInterval({
startTime: activityStartTime,
endTime: activityEndTime,
});
}
},
},
},
@ -145,6 +162,7 @@ export default {
},
destroyed() {
window.removeEventListener("scroll", this.scrollEventMethod);
clearInterval(this.timeInterval);
},
methods: {
scrollEventMethod() {
@ -177,6 +195,39 @@ export default {
this.goodsList = result.records;
}
},
//
async setTimerInterval({ startTime, endTime }) {
//
const { result } = await ApiGetCurrentTime();
const current = result || Date.now();
startTime = new Date(startTime).getTime();
endTime = new Date(endTime).getTime();
if (current > endTime) {
//
this.getSeckillTimes();
return;
}
if (startTime < current && endTime > current) {
//
this.seckillTime = endTime - current;
this.seckillTip = "本场正在秒杀中,好物转瞬即逝,不要错过哦~距结束仅剩";
} else {
//
this.seckillTime = startTime - current;
this.seckillTip = "本场秒杀即将开抢,距开始还剩";
}
this.timeInterval = setInterval(() => {
if (this.seckillTime <= 0) {
clearInterval(this.timeInterval);
this.getSeckillTimes();
return;
}
this.seckillTime -= 1e3;
}, 1e3);
},
onJumpGoodsDetail(id) {
this.$router.push(`/goods/detail/${id}`);
},
@ -194,6 +245,7 @@ export default {
pageIndex: 1,
length: 16,
});
this.getGoodsList();
},
},
};

@ -25,3 +25,9 @@ const BASE_URL = `${ENV.base_url}/mall/marketing`;
export const ApiGetSeckillGoods = (params) =>
ToAsyncAwait(axios.get(`${BASE_URL}/app/activity/product`, { params }));
/**
* 获取当前服务器时间
*/
export const ApiGetCurrentTime = () =>
ToAsyncAwait(axios.get(`${BASE_URL}/app/activity/timestamp`));

Loading…
Cancel
Save