Commit 65b96a15 by 李嘉林

限时活动组件

parent 03634695
import { requestPOST, requestGET } from "@/utils/request.js";
export default {
getSingleItemActivityV2(data) {
return requestPOST(`${process.env.OLSHOP_URL}/promotion/v2/query_single_item_activity_detail`, data);
},
// 根据列表查询活动
query_single_item_activity_list_by_ids(data) {
return requestPOST(`${process.env.OLSHOP_URL}/promotion/query_single_item_activity_list_by_ids`, data);
},
};
\ No newline at end of file
......@@ -3,6 +3,7 @@ import App from './App'
import Store from './store/index'
import "../static/nicon/iconfont.css"
import goodsApi from "./api/goods"
import promoteApi from "./api/promote";
import { DFSImg } from "@/utils/index";
import { $themeToLink } from "@/utils/mayi"
......@@ -43,4 +44,5 @@ mpApp.$themeToLink = $themeToLink
// api
mpApp.goodsApi = goodsApi;
mpApp.promoteApi = promoteApi;
mpApp.DFSImg = DFSImg;
......@@ -15,6 +15,9 @@
<div v-else-if="item.componentCode == 'cube-nav'">
<cube-nav :datas="item"></cube-nav>
</div>
<div v-else-if="item.componentCode == 'time-limited-discount'">
<time-limited-discount :datas="item"></time-limited-discount>
</div>
</div>
</scroll-view>
<!-- <image
......
......@@ -2,6 +2,7 @@
"usingComponents": {
"banner": "/static/nativeComponents/Banner/index",
"goods-list": "/static/nativeComponents/GoodsList/index",
"time-limited-discount": "/static/nativeComponents/TimeLimitedDiscount/index",
"waterfall-flow": "/static/nativeComponents/module/WaterfallFlow/index",
"van-button": "/static/vant/button/index",
"area-navigation":"/static/nativeComponents/AreaNavigation/index",
......
const app = getApp();
const { $themeToLink } = app;
const componentOptions = {
// 组件选项
options: {
multipleSlots: true
},
behaviors: [],
properties: {
datas: {
type: Object
},
countDownShow: {
type: Boolean
},
num: {
type: Number
}
},
// 组件数据
data: {
isPageHidden: false, // 页面是否处于隐藏状态
hideItem: false,
timeData: {}
},
// 数据监听器
observers: {},
// 组件方法
methods: {
init() {},
onChange(e) {
let { isStart, startTime } = this.data.datas;
isStart =
new Date(startTime.replace(/-/g, "/")).getTime() > new Date().getTime()
? true
: false;
this.setData({ timeData: e.detail, "datas.isStart": isStart });
},
toActivity() {
$themeToLink({ type: 1, link: `/brandTopics/${this.data.datas.id}` });
}
},
// 组件生命周期
lifetimes: {
created() {},
attached() {
this.init();
},
ready() {},
moved() {},
detached() {}
},
definitionFilter() {},
// 页面生命周期
pageLifetimes: {
// 页面被展示
show() {
const { isPageHidden } = this.data;
// show事件发生前,页面不是处于隐藏状态时
if (!isPageHidden) {
return;
}
// 重新执行定时器等操作
},
// 页面被隐藏
hide() {
this.setData({
isPageHidden: true
});
// 清除定时器等操作
},
// 页面尺寸变化时
resize() {}
}
};
Component(componentOptions)
{
"component": true,
"usingComponents": {
"van-count-down": "/static/vant/count-down/index"
}
}
<!-- 活动列表item -->
<view
class="activityListItem"
wx:if="{{!hideItem||!datas.isEnd}}"
bindtap="toActivity"
>
<view class="title">
{{datas.singleItemActivityName}}
</view>
<view class="cover">
<image mode="center" src="{{datas.singleItemActivityCoverImage}}"></image>
</view>
<view class="countDown flex" wx:if="{{countDownShow}}">
<van-count-down
use-slot
time="{{datas.isStart?datas.startTimeTimeStamp:datas.endTimeTimeStamp}}"
class="countDown"
bind:change="onChange"
>
<view class="time">
<text class="colon">距{{datas.isStart?'开始':'结束'}}</text>
<text class="block">{{ timeData.days }}</text>
<text class="colon">天</text>
<text class="block">{{ timeData.hours }}</text>
<text class="colon">时</text>
<text class="block">{{ timeData.minutes }}</text>
<text class="colon">分</text>
<text class="block">{{ timeData.seconds }}</text>
<text class="colon">秒</text>
</view>
</van-count-down>
</view>
</view>
.activityListItem {
margin-bottom: 20rpx;
padding: 20rpx 0;
background: #fff;
border-radius: 8rpx;
-webkit-border-radius: 8rpx;
-moz-border-radius: 8rpx;
-ms-border-radius: 8rpx;
-o-border-radius: 8rpx;
}
.title {
padding: 8rpx 20rpx;
font-size: 34rpx;
color: #333;
font-weight: bold;
text-align: left;
}
.cover {
margin: 8rpx 0;
width: 100%;
height: 300rpx;
overflow: hidden;
}
.cover image {
width: 100%;
}
.countDown {
padding: 4rpx 10rpx;
justify-content: flex-end;
font-size: 24rpx;
color: #666;
}
.countDown .block {
display: inline-block;
width: 40rpx;
height: 40rpx;
text-align: center;
line-height: 40rpx;
border-radius: 4rpx;
background: #333;
color: #fff;
-webkit-border-radius: 4rpx;
-moz-border-radius: 4rpx;
-ms-border-radius: 4rpx;
-o-border-radius: 4rpx;
}
.time{
display: flex;
align-items: center;
justify-content: flex-end;
margin-right: 10rpx;
}
.colon{
font-size: 30rpx;
}
.block{
margin: 0 10rpx;
color: #fff;
}
\ No newline at end of file
let d = null;
const app = getApp();
const { promoteApi, DFSImg, $themeToLink } = app;
// 倒计时方法
if (typeof xcsoft == "undefined") var xcsoft = new function() {}();
xcsoft.countdown = function(a, b, c) {
d = new Object();
var e = 0;
if (typeof a == "object") {
var f = parseInt(new Date().getTime() / 1000);
var g = a.startTime ? parseInt(a.startTime) : 0;
g = g == 0 ? f : g;
var h = a.endTime;
var x = g - f;
d.decimal = parseInt(a.msec ? a.msec : 0);
} else {
var f = 0;
var x = 0;
d.decimal = 0;
var h = a;
var i = h.toString();
if (i.indexOf(".") > 0) {
d.decimal = i.split(".")[1];
if (d.decimal > 3) {
d.decimal = 3;
}
}
}
d.time = h;
d.finish = false;
if (isNaN(h)) {
var j = h.substring(0, 19);
j = j.replace(/-/g, "/");
d.time = new Date(j).getTime() / 1000;
}
var k = d.decimal == 0 ? 100 : 100;
d.day = 0;
d.hour = 0;
d.minute = 0;
d.second = 0;
d.t = setInterval(function() {
e = new Date().getTime();
f = parseInt(e / 1000 + x);
var l = d.time - f;
if (l <= 0) {
e = 0;
l = 0;
}
if (l >= 0) {
d = xcsoft.getTimeObject(d, l);
}
if (d.decimal == 1) {
d.msecZero = d.msec = parseInt(10 - (e % 1000) / 100);
if (d.msec == 10 || l == 0) {
d.msecZero = d.msec = 0;
}
} else if (d.decimal == 2) {
d.msecZero = d.msec = parseInt(100 - (e % 1000) / 10);
if (d.msec < 10) {
d.msecZero = "0" + d.msec;
} else if (d.msec == 100 || l == 0) {
d.msec = 0;
d.msecZero = "0" + d.msec;
}
} else {
d.msecZero = d.msec = parseInt(1000 - e % 1000);
if (d.msec < 10) {
d.msecZero = "00" + d.msec;
} else if (d.msec < 100) {
d.msecZero = "0" + d.msec;
} else if (d.msec == 1000 || l == 0) {
d.msec = 0;
d.msecZero = "00" + d.msec;
}
}
if (b) {
b(d);
}
if (l <= 0 || d.stop == true) {
clearInterval(d.t);
d.finish = true;
if (c) c(d);
}
}, k);
};
xcsoft.getTimeObject = function(a, l) {
var b = 60;
var c = b * b;
var d = 24 * c;
a.days = Math.floor(l / d);
a.year = Math.floor(a.days / 365);
a.day = Math.floor(a.days % 365);
a.hour = Math.floor((l % d) / c);
a.minute = Math.floor((l - (a.days * d + a.hour * c)) / b);
a.second = Math.floor(l % b);
a.dayZero = a.day < 10 ? "0" + a.day : a.day;
a.daysZero = a.days < 10 ? "0" + a.days : a.days;
a.hourZero = a.hour < 10 ? "0" + a.hour : a.hour;
a.minuteZero = a.minute < 10 ? "0" + a.minute : a.minute;
a.secondZero = a.second < 10 ? "0" + a.second : a.second;
return a;
};
const componentOptions = {
// 组件选项
options: {
multipleSlots: true
},
behaviors: [],
properties: {
datas: {
type: Object
}
},
// 组件数据
data: {
isPageHidden: false, // 页面是否处于隐藏状态
timeData: {},
isLoading: true,
deleteFlag: false, //活动未禁用
newTime: new Date().getTime(),
timer: null,
hideAll: false,
days: 0,
hours: 0,
minute: 0,
second: 0
},
// 数据监听器
observers: {},
// 组件方法
methods: {
init() {
let { goodsList, activityCode, selectActivityValue, dimension } = this.data.datas.componentData;
let { deleteFlag, endTimeData } = this.data;
if (activityCode == "") {
return;
}
let query = {
singleItemActivityId: activityCode,
whetherShowSoldOutGoods: 1
};
promoteApi.getSingleItemActivityV2(query).then(res => {
if (res.data.code == 200) {
let copyData = res.data.data;
deleteFlag = copyData.activityStatus != 2 ? true : false;
if (dimension == 0 && copyData.goodsItems.length == 0) {
deleteFlag = true;
}
endTimeData = new Date(copyData.endTime.replace(/-/g, "/")).getTime() - new Date().getTime();
console.log(endTimeData, "----------------------150");
this.setData({ endTime: endTimeData });
let _this = this;
this.setData({ deleteFlag });
console.log("------------155")
// setTimeout(() => {
// xcsoft.countdown(_this.data.datas.componentData.endTime, function (time) {
// console.log("--------------157")
// let { days, hours, minute, second } = _this.data;
// days = time.dayZero;
// hours = time.hourZero;
// minute = time.minuteZero;
// second = time.secondZero;
// // _this.setData({ days, hours, minute, second });
// }, function(time) {
// //倒计时结束后的操作
// });
// setTimeout(() => {
// this.setData({ isLoading: true });
// }, 100);
// }, 100);
copyData.goodsItems.forEach((item, index) => {
item.productImgUrl = DFSImg(item.imgUrl);
item.minPrice = parseFloat(item.discountPrice);
item.maxPrice = parseFloat(item.salePrice);
});
this.setData({
goodsList: copyData.goodsItems,
selectActivityValue: copyData.singleItemActivityName
});
}
});
},
initArticityList() {
let ids = [];
let { actList } = this.data.datas.componentData;
let { isLoading } = this.data;
if (actList.length > 0) {
ids = actList.map(item => {
return item.id;
});
}
if (ids.length == 0) {
this.setData({ isLoading:true });
return;
}
promoteApi.query_single_item_activity_list_by_ids(ids).then(res => {
if (res.data.code == 200) {
let list = res.data.data ||[];
if (list.length > 0) {
let hideNum = 0;
list.forEach((item, index) => {
if (new Date(item.endTime.replace(/-/g, "/")).getTime() - new Date().getTime() <= 0) {
item.isEnd = true;
hideNum += 1;
} else {
item.isEnd = false;
}
item.startTimeTimeStamp = new Date(item.startTime.replace(/-/g, "/")).getTime() - new Date().getTime();
item.endTimeTimeStamp = new Date(item.endTime.replace(/-/g, "/")).getTime() - new Date().getTime();
item.singleItemActivityCoverImage = DFSImg(item.singleItemActivityCoverImage);
item.isStart = new Date(item.startTime.replace(/-/g, "/")).getTime() > new Date().getTime() ? true : false;
})
this.setData({ "datas.componentData.actList": list });
if (hideNum == actList.length) {
this.setData({ hideAll:true });
}
}
}
});
},
onChange(e) {
this.setData({ timeData: e.detail });
},
onclickProduct(e) {
console.log(e.currentTarget.dataset.items,'-------------------------226');
let { terminalProductId, terminalGoodsMixId, productId } = e.currentTarget.dataset.items;
$themeToLink({ type: 1, link: `/goods/${productId}?limitedLime=true&endTime=${this.data.datas.componentData.endTime}&terminalProductId="${terminalProductId}&terminalGoodsMixId=${terminalGoodsMixId}` });
},
onclickOrder(e) {
let { terminalGoodsMixId, terminalGoodsId, goodsId } = e.currentTarget.dataset.items;
$themeToLink({
type: 1,
link: `/order/orderConfirm?productGoodsMixId=${terminalGoodsMixId}&productGoodsId=${terminalGoodsId}&goodsId=${goodsId}&qty=1&goodsString=null`
});
}
},
// 组件生命周期
lifetimes: {
created() {},
attached() {
let { dimension } = this.data.datas.componentData;
if (dimension == 0) {
this.init();
} else if (dimension == 1) {
this.initArticityList();
}
},
ready() {},
moved() {},
detached() {}
},
definitionFilter() {},
// 页面生命周期
pageLifetimes: {
// 页面被展示
show() {
const { isPageHidden } = this.data;
// show事件发生前,页面不是处于隐藏状态时
if (!isPageHidden) {
return;
}
// 重新执行定时器等操作
},
// 页面被隐藏
hide() {
this.setData({
isPageHidden: true
});
// 清除定时器等操作
},
// 页面尺寸变化时
resize() {}
}
};
Component(componentOptions)
{
"component": true,
"usingComponents": {
"activity-list-item":"./activityListItem/index",
"van-count-down": "/static/vant/count-down/index"
}
}
<!-- 限时活动 -->
<view class="time-limited-discount" style="padding-top:{{datas.componentData.paddingList[0].value*2}}rpx;padding-bottom:{{datas.componentData.paddingList[1].value*2}}rpx;padding-left:{{datas.componentData.paddingList[2].value*2}}rpx;padding-right:{{datas.componentData.paddingList[3].value*2}}rpx;--backgroundColor:{{datas.componentData.backgroundColor}}">
<!-- 标题 -->
<view class="tops {{datas.componentData['countDownShow']?'hideCountDown':''}}">
<view class="topInfo">
<view class="title">
{{datas.componentData.dimension ==0?datas.componentData.selectActivityValue:datas.componentData.actTitle}}
</view>
<view class="subheading" wx:if="{{datas.componentData['countDownShow']&&datas.componentData.dimension==0}}">
<view wx:if="{{datas.componentData['endTime']&&endTime>0}}">
<van-count-down
use-slot
time="{{endTime}}"
class="countDown"
bind:change="onChange"
>
<text class="endTime days">{{ timeData.days }}</text>
<text class="endTimedot">天</text>
<text class="endTime hours">{{ timeData.hours }}</text>
<text class="endTimedot">:</text>
<text class="endTime minute">{{ timeData.minutes }}</text>
<text class="endTimedot">:</text>
<text class="endTime second">{{ timeData.seconds }}</text>
</van-count-down>
</view>
<view class="countDown" wx:elif="{{isLoading}}">
活动已结束
</view>
</view>
</view>
</view>
<!-- 内容 -->
<!-- 网格模式 -->
<view class="goods" wx:if="{{datas.componentData.style==='list'}}">
<view class="goodsList">
<view
class="goodsItem {{datas.componentData.columnNum==2?'style2':'style3'}}"
wx:for="{{datas.componentData.goodsList}}"
wx:key="index"
style="width:{{100/datas.componentData.columnNum}}%"
>
<view class="goods-item-child {{datas.componentData.columnNum==1?'goods-item-child-flex':''}}">
<view class="imgBox slidebox1">
<view
class="goodsPicture"
bindtap="onclickProduct"
data-items="{{datas.componentData.goodsList[index]}}"
style="padding:{{datas.componentData.imgSize}}"
>
<image mode="widthFix" src="{{datas.componentData.goodsList[index]['productImgUrl']}}"></image>
<view class="whiteBg" wx:if="{{datas.componentData.goodsList[index].oversoldFlag==0&&datas.componentData.goodsList[index].saleQty-0<=0}}">
<view class="cover">
<text>商品</text>
<text>售罄</text>
</view>
</view>
</view>
</view>
<view class="info">
<view class="name">
{{datas.componentData.goodsList[index]!=null?datas.componentData.goodsList[index]['productName']:'名称'}}
</view>
<view class="allPrice">
<view>
<!-- <text class="price" wx:if="{{((hours-0)+(minute-0)+(second-0))!=0}}">¥{{datas.componentData.goodsList[index]!=null?datas.componentData.goodsList[index]['minPrice']:0}}</text>
<text class="price" wx:else>¥{{datas.componentData.goodsList[index]!=null?datas.componentData.goodsList[index]['minPrice']:0}}</text>
<text class="delPrice" wx:if="{{((hours-0)+(minute-0)+(second-0))!=0}}">¥{{datas.componentData.goodsList[index]!=null?datas.componentData.goodsList[index]['maxPrice']:0}}</text> -->
<view class="price">¥{{datas.componentData.goodsList[index]!=null?datas.componentData.goodsList[index]['minPrice']:0}}</view>
<view class="delPrice">¥{{datas.componentData.goodsList[index]!=null?datas.componentData.goodsList[index]['maxPrice']:0}}</view>
</view>
<view
class="btn"
style="background:#333;"
data-items="{{datas.componentData.goodsList[index]}}"
catchtap="onclickOrder"
>
立即抢购
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 横向滑动 -->
<view class="goods1" wx:elif="{{datas.componentData.style==='across'}}">
<view
class="goods-item"
wx:for="{{datas.componentData.goodsList}}"
wx:key="index"
>
<view class="items">
<view class="imgBox slidebox2">
<view
class="goodsPicture"
wx:if="{{datas.componentData.goodsList[index]!=null}}"
style="padding:{{datas.componentData.imgSize}}"
data-items="{{datas.componentData.goodsList[index]}}"
bindtap="onclickProduct"
>
<image mode="widthFix" src="{{datas.componentData.goodsList[index]['productImgUrl']}}"></image>
<view class="whiteBg" wx:if="{{datas.componentData.goodsList[index].oversoldFlag==0&&datas.componentData.goodsList[index].saleQty-0<=0}}">
<view class="cover">
<text>商品</text>
<text>售罄</text>
</view>
</view>
</view>
</view>
<view class="info">
<!-- <text class="price" wx:if="{{((hours-0)+(minute-0)+(second-0))!=0}}">¥{{datas.componentData.goodsList[index]!=null?datas.componentData.goodsList[index]['minPrice']:0}}</text>
<text class="price" wx:else>¥{{datas.componentData.goodsList[index]!=null?datas.componentData.goodsList[index]['minPrice']:0}}</text>
<text class="delPrice" wx:if="{{((hours-0)+(minute-0)+(second-0))!=0}}">¥{{datas.componentData.goodsList[index]!=null?datas.componentData.goodsList[index]['maxPrice']:0}}</text> -->
<view class="price">¥{{datas.componentData.goodsList[index]!=null?datas.componentData.goodsList[index]['minPrice']:0}}</view>
<view class="delPrice">¥{{datas.componentData.goodsList[index]!=null?datas.componentData.goodsList[index]['maxPrice']:0}}</view>
</view>
</view>
</view>
</view>
<!-- 活动列表 -->
<block wx:if="{{datas.componentData.dimension == 1 && isLoading}}">
<activity-list-item
wx:for="{{datas.componentData.actList}}"
wx:key="index"
datas="{{item}}"
num="{{index}}"
countDownShow="{{datas.componentData['countDownShow']}}"
></activity-list-item>
</block>
</view>
.time-limited-discount {
background: var(--backgroundColor);
font-size: 32rpx;
}
.tops {
padding: 8rpx 0;
}
.hideCountDown {
display: flex;
justify-content: space-between;
align-items: center;
}
.topInfo {
width: 100%;
display: flex;
justify-content: space-between;
align-content: center;
}
.topInfo .title {
font-size: 38rpx;
color: #333;
font-weight: bold;
text-align: left;
}
.topInfo .subheading {
position: relative;
display: flex;
align-items: center;
}
.subheading.countDown {
display: flex;
justify-content: space-around;
align-items: center;
}
.endTime {
padding: 4rpx 10rpx;
border-radius: 6rpx;
background: #6a6b6b;
color: #fff;
font-weight: bold;
-webkit-border-radius: 6rpx;
-moz-border-radius: 6rpx;
-ms-border-radius: 6rpx;
-o-border-radius: 6rpx;
}
.endTimedot {
padding: 0 10rpx;
}
.goods {
width: 100%;
}
.goodsList {
display: flex;
align-items: flex-start;
}
.goodsItem {
box-sizing: border-box;
}
.goods-item-child {
border-radius: 5px;
overflow: hidden;
background: #fff;
margin: 0 10rpx;
}
.goods-item-child .info {
padding: 10rpx 20rpx 12rpx;
}
.goods-item-child .info .name {
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
line-height: 44rpx;
font-size: 32rpx;
height: 92rpx;
}
.goods-item-child .info .allPrice {
display: flex;
justify-content: space-between;
align-items: center;
}
.price {
font-weight: 600;
margin-top: 10rpx;
color: #ff3434;
font-size: 32rpx;
}
.delPrice {
text-decoration: line-through;
margin-top: 10rpx;
color: #999;
}
.goods-item-child .info .allPrice .btn {
font-size: 24rpx;
background: #333;
padding: 8rpx;
color: #fff;
border-radius: 10rpx;
-webkit-border-radius: 10rpx;
-moz-border-radius: 10rpx;
-ms-border-radius: 10rpx;
-o-border-radius: 10rpx;
}
.goods-item-child-flex {
display: flex;
justify-content: space-between;
align-items: center;
}
.imgBox {
position: relative;
overflow: hidden;
width: 100%;
height: 40vw;
display: flex;
align-items: center;
justify-content: center;
}
.imgBox .goodsPicture{
width: 100%;
}
.goods-item-child-flex .imgBox {
width: 30%;
padding-bottom: 30%;
}
.goods-item-child-flex .info {
width: 70%;
}
.goodsPicture .whiteBg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(#fff, 0.7);
}
.goodsPicture .whiteBg .cover {
position: absolute;
top: 40rpx;
left: 40rpx;
right: 40rpx;
bottom: 40rpx;
display: flex;
background: rgba(#333, 0.6);
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 50%;
}
.goodsPicture .whiteBg .cover text {
color: #fff;
font-weight: bold;
letter-spacing: 6rpx;
text-align: center;
}
.goods1 {
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
-webkit-overflow-scrolling: touch; /* ios5+ */
}
.goods1 .goods-item {
display: inline-block;
vertical-align: top;
white-space: initial;
margin-right: 20rpx;
width: 40%;
}
.goods1 .goods-item .items {
border-radius: 5px;
overflow: hidden;
background: #ffffff;
}
.goods1 .goods-item .info {
text-align: center;
}
.goods1 .goods-item .slidebox2 {
box-sizing: border-box;
-moz-box-sizing: border-box; /* Firefox */
-webkit-box-sizing: border-box; /* Safari */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment