Authored by huangyCode

Merge branch 'feature/group-buy' of http://git.yoho.cn/fe/yohobuywap-node into feature/group-buy

... ... @@ -16,7 +16,9 @@ class GroupApi extends global.yoho.BaseModel {
content_code: param.contentCode,
platform: 'iphone'
},
param: {code: 200}
param: {
code: 200
}
}).then((result) => {
result = result.data;
... ... @@ -103,7 +105,10 @@ class GroupApi extends global.yoho.BaseModel {
* @param groupNo
* @returns {Promise|Promise<T>}
*/
groupDetail({groupNo, uid} = {}) {
groupDetail({
groupNo,
uid
} = {}) {
return this.get({
url: '',
data: {
... ... @@ -111,7 +116,9 @@ class GroupApi extends global.yoho.BaseModel {
groupNo,
method: 'app.activity.groupDetail'
},
param: {code: 200}
param: {
code: 200
}
}).then((result) => {
result = result.data;
... ... @@ -127,7 +134,12 @@ class GroupApi extends global.yoho.BaseModel {
* @param page
* @returns {Promise|Promise<T>}
*/
activityRecommend({activityId, uid, limit = 20, page = 1} = {}) {
activityRecommend({
activityId,
uid,
limit = 20,
page = 1
} = {}) {
return this.get({
url: '',
data: {
... ... @@ -137,7 +149,9 @@ class GroupApi extends global.yoho.BaseModel {
activityId,
method: 'app.collage.productList.detail',
},
param: {code: 200}
param: {
code: 200
}
}).then((result) => {
result = result.data;
... ...
... ... @@ -44,8 +44,8 @@ class GroupService extends global.yoho.BaseModel {
// 3. 已经加入团--应好友邀请
// 4. 团已达成--你已加入一起购买成功
// 5. 团已达成--你来晚了没能加入
// 6. 拼团失败--过期未达成
// 7. 拼团失败--过期未达成
// 6. 拼团失败--过期未达成[非自己所开团]
// 7. 拼团失败--过期未达成[自己所开团]
let yourJoinItem = detail.yourJoinItem;
let lackNum = detail.lackNum;
let membershipItems = detail.membershipItems;
... ...
<div class="group-progress">
{{#data}}
{{#data}}
<div class="group-progress" data-page-go="{{pageGo}}" data-left-time="{{leftTime}}">
<div class="card">
<div class="inner-card go-join" data-product-skn="{{yourJoinItem.productSkn}}"
data-activity-id="{{activityId}}" data-group-no="{{groupNo}}" data-page-go="{{pageGo}}">
... ... @@ -30,45 +30,46 @@
{{#ifcond pageGo '===' 1}}
<div class="status-tip">还差<span class="red">{{lackNum}}</span>拼团成功,剩余时间</div>
{{> group/progress-countdown}}
<div class="status-btn positive">邀请小伙伴拼团{{#ifcond joinLimit '==' 1}}(仅限新人){{/ifcond}}</div>
<div class="status-btn positive invite-join">邀请小伙伴拼团{{#ifcond joinLimit '==' 1}}(仅限新人){{/ifcond}}</div>
{{/ifcond}}
{{#ifcond pageGo '===' 2}}
<div class="status-tip">还差<span class="red">{{lackNum}}</span>拼团成功,剩余时间</div>
{{> group/progress-countdown}}
<div class="status-btn positive">去参团</div>
<div class="status-btn positive join-group">去参团</div>
{{/ifcond}}
{{#ifcond pageGo '===' 3}}
<div class="status-tip">还差<span class="red">{{lackNum}}</span>拼团成功,剩余时间</div>
{{> group/progress-countdown}}
<div class="status-btn positive">邀请小伙伴拼团{{#ifcond joinLimit '==' 1}}(仅限新人){{/ifcond}}</div>
<div class="status-btn positive invite-join">邀请小伙伴拼团{{#ifcond joinLimit '==' 1}}(仅限新人){{/ifcond}}</div>
{{/ifcond}}
{{#ifcond pageGo '===' 4}}
<div class="status-text">拼团成功</div>
<div class="status-btn">查看更多拼团活动</div>
<a href="../group/list?activityId={{activityId}}" class="status-btn">查看更多拼团活动</a>
{{/ifcond}}
{{#ifcond pageGo '===' 5}}
<div class="status-text">你来晚了 你的好友拼团已经成功</div>
<div class="status-btn positive">我也要开团</div>
<div class="status-text">你来晚了</div>
<div class="status-text-tip">你的好友拼团已经成功</div>
<a href="../group/detail?activityId={{activityId}}&productSkn={{yourJoinItem.productSkn}}"
class="status-btn positive squeeze">我也要开团</a>
{{/ifcond}}
{{#ifcond pageGo '===' 6}}
<div class="status-text">拼团失败</div>
<div class="status-btn">查看更多拼团活动</div>
<a href="../group/list?activityId={{activityId}}" class="status-btn">查看更多拼团活动</a>
{{/ifcond}}
{{#ifcond pageGo '===' 7}}
<div class="status-text">拼团失败</div>
<div class="status-btn">查看更多拼团活动</div>
<a href="../group/list?activityId={{activityId}}" class="status-btn">查看更多拼团活动</a>
{{/ifcond}}
<a class="tip" href="http://m.yohobuy.com/activity/group">支付开团-支付参团-凑齐人数发货-凑不齐退款 玩法介绍》</a>
<a class="tip" href="https://m.yohobuy.com/activity/feature/1555.html">支付开团-支付参团-凑齐人数发货-凑不齐退款 玩法介绍》</a>
</div>
</div>
{{/data}}
<div class="divide"></div>
<div class="banner official-account"></div>
<div class="divide zero-margin"></div>
... ... @@ -95,4 +96,6 @@
{{/@root.data.recommend.collageProductVoList}}
</div>
<a href="../group"><img class="browse-more" src="https://cdn.yoho.cn/uploads/1544494149810/more.png"></img></a>
<div class="h5-share-clipboard"></div>
</div>
{{/data}}
... ...
<div class="count-down">
<span class="digit-square">1</span>
<span class="digit-square">1</span> :
<span class="digit-square">1</span>
<span class="digit-square">1</span> :
<span class="digit-square">1</span>
<span class="digit-square">1</span>
<span class="digit-square h1">0</span>
<span class="digit-square h2">0</span> :
<span class="digit-square m1">0</span>
<span class="digit-square m2">0</span> :
<span class="digit-square s1">0</span>
<span class="digit-square s2">0</span>
</div>
... ...
... ... @@ -21,6 +21,6 @@
{{/each}}
</ul>
</div>
<div class="cancelBtn">取消</div>
<div class="cancel-btn">取消</div>
</div>
{{/ filter}}
\ No newline at end of file
... ...
... ... @@ -2,9 +2,11 @@ import 'scss/activity/group/group-progress.page.scss';
import $ from 'yoho-jquery';
import Page from 'js/yoho-page';
import Clipboard from 'clipboard';
import share from 'js/common/share';
import sharePlugin from 'js/common/share';
import tip from 'js/plugin/tip';
import dialog from 'js/plugin/dialog';
import lazyLoad from 'yoho-jquery-lazyload';
import yoSdk from 'yoho-activity-sdk';
class GroupProgress extends Page {
constructor() {
... ... @@ -15,20 +17,123 @@ class GroupProgress extends Page {
$productItem: $('.product-item'),
$copyAccount: $('.official-account'),
$goJoin: $('.go-join'),
$joinGroup: $('.join-group'),
$inviteJoin: $('.invite-join'),
$countdown: $('.count-down')
};
this.timer = '';
this.init();
}
init() {
lazyLoad(this.selector.$page.find('img.lazy'));
share({});
this.bindEvents();
this.shareInfo();
this.countdown();
}
bindEvents() {
this.selector.$productItem.on('click', this.goDetail.bind(this));
this.selector.$goJoin.on('click', this.goJoin.bind(this));
this.selector.$joinGroup.on('click', this.joinGroup.bind(this));
this.selector.$inviteJoin.on('click', this.inviteJoin.bind(this));
}
shareInfo() {
sharePlugin({
title: '有货福利团xx元包邮xxx商品',
imgUrl: '',
link: '',
desc: 'x人团更优惠,正品保证,全场包邮',
copyDeac: '【有货福利团 】x人团,xx元包邮xxx商品>>'
});
let clipboardShare = new Clipboard('.h5-share-clipboard', {
text: function() {
return '【有货福利团 】x人团,xx元包邮xxx商品>>';
}
});
clipboardShare.on('success', function(e) {
tip.show('复制成功,发送给好友为您助力', 3500);
e.clearSelection();
});
}
inviteJoin() {
if (/QQ/i.test(navigator.userAgent) ||
/MicroMessenger/i.test(navigator.userAgent)) {
dialog.showDialog({hasClass: 'group-guide-mask'});
} else if (yoSdk.env === 'h5') {
$('.h5-share-clipboard').trigger('click');
}
}
countdown() {
let pageGo = this.selector.$page.data('page-go');
let leftTime = this.selector.$page.data('left-time');
if (pageGo === 1 || pageGo === 2 || pageGo === 3) {
this._startTimer(leftTime);
}
}
_startTimer(leftTime) {
let _this = this;
this.timer = setInterval(function() {
let formatTime = _this._formatDate(--leftTime);
let digitSelector = ['h1', 'h2', 'm1', 'm2', 's1', 's2'];
digitSelector.forEach(key => {
_this.selector.$countdown.find(`.${key}`).html(formatTime[key]);
});
if (!leftTime || leftTime < 0) {
clearInterval(this.timer);
setTimeout(function() {
window.location.reload();
}, 2000);
}
}, 1000);
}
_formatDate(secs) {
let _format = m => {
if (m < 10) {
return [0, m];
} else {
let h1 = Math.floor(m / 10);
let h2 = m - h1 * 10;
return [h1, h2];
}
};
// 秒数
let second = Math.floor(secs);
// 小时位
let hr = Math.floor(second / 3600);
let hrFormat = _format(hr);
// 分钟位
let min = Math.floor((second - hr * 3600) / 60);
let minFormat = _format(min);
// 秒位
let sec = (second - hr * 3600 - min * 60);
let secFormat = _format(sec);
return {
h1: hrFormat[0],
h2: hrFormat[1],
m1: minFormat[0],
m2: minFormat[1],
s1: secFormat[0],
s2: secFormat[1]
};
}
goDetail(e) {
... ... @@ -53,6 +158,15 @@ class GroupProgress extends Page {
window.location.href = path;
}
joinGroup() {
dialog.showDialog({
dialogText: 'TODO 弹出商品信息选择等',
hasFooter: {
centerBtnText: '确认'
}
});
}
// 暂时屏蔽
copyAccount() {
let clipboard = new Clipboard('.official-account', {
... ...
... ... @@ -3,6 +3,7 @@ import Swiper from 'yoho-swiper';
import $ from 'yoho-jquery';
import Page from 'js/yoho-page';
import filter from 'js/plugin/filter';
let innerScroll = require('js/plugin/inner-scroll');
// import lazyLoad from 'yoho-jquery-lazyload';
// import tip from 'js/plugin/tip';
... ... @@ -21,11 +22,13 @@ class Group extends Page {
};
this.navInfo = {
new: {
order: 's_t_desc',
reload: true,
page: 1,
end: false
},
popularity: {
order: 'h_v_desc',
reload: true,
page: 0,
end: false
... ... @@ -86,7 +89,7 @@ class Group extends Page {
let listHeight = this.selector.groupListContent.height();
let windowHeight = $(window).height();
// 商品列表超过一屏时
// 商品列表超过一屏时固定tab
if (listHeight > windowHeight || listHeight === windowHeight) {
if (!this.selector.tabSection.hasClass('float')) {
this.selector.tabSection.addClass('float');
... ... @@ -94,59 +97,71 @@ class Group extends Page {
}
}
}
// 筛选tab切换
filterTabChange(e) {
let $this = $(e.currentTarget);
let navType = $this.data('type');
let currentChannel = this.selectedChannel;
let nav = this.navInfo[navType];
// 筛选状态设置
// 点击项为筛选
if ($this.hasClass('filter')) {
if ($this.hasClass('active')) {
$('.filter-mask').addClass('hide');
$this.removeClass('active');
} else {
$this.addClass('active');
filter.showFilter();
innerScroll.disableScroll($('body'));
}
} else {
this.selector.filterTab.children('li').removeClass('active');
$this.addClass('active');
this.filterTab[currentChannel].$pre = $this;
}
// 最新和人气
if ($this.hasClass('new') || $this.hasClass('popularity')) {
nav.reload = true;
nav.order = $this.data('order');
this.filterTab[currentChannel].order = nav.order;
}
// 价格切换排序状态
if ($this.hasClass('price')) {
$this.find('.icon > .iconfont').toggleClass('cur');
nav.reload = true;
nav.order = nav.order === 's_p_asc' ? 's_p_desc' : 's_p_asc'; // 切换排序
this.filterTab[currentChannel].order = nav.order;
}
// 最新和人气
if ($this.hasClass('new') || $this.hasClass('popularity')) {
// 点击项为激活项时
if (navType === this.filterTab[currentChannel].$pre.data('type')) {
return;
}
nav.reload = true;
nav.order = $this.data('order');
this.filterTab[currentChannel].order = nav.order;
}
// 价格切换排序状态
if ($this.hasClass('price')) {
$this.find('.icon > .iconfont').toggleClass('cur');
nav.reload = true;
nav.order = nav.order === 's_p_asc' ? 's_p_desc' : 's_p_asc'; // 切换排序
this.filterTab[currentChannel].order = nav.order;
}
this.filterTab[currentChannel].$pre = $this;
this.search();
// 根据条件重置筛选页面及商品列表
this.filterInit();
this.search();
}
}
// 团切换
groupTabChange(e) {
let target = $(e.target);
let channel = target.data('channel');
let navInfo = this.navInfo;
let filterTab = this.filterTab[channel];
if (this.selectedChannel === channel) {
return;
}
this.selectedChannel = channel;
// 切换tab
if (!target.hasClass('active')) {
this.selector.groupTab.find('.tiptext').removeClass('active');
target.addClass('active');
}
this.selectedChannel = channel;
// 筛选tab状态重置
for (let i in navInfo) {
... ... @@ -154,7 +169,7 @@ class Group extends Page {
navInfo[i].reload = true;
navInfo[i].end = false;
if (navInfo[i].hasOwnProperty('order')) {
if (i === 'price') {
navInfo[i].order = 's_p_asc';
}
}
... ... @@ -162,6 +177,7 @@ class Group extends Page {
this.selector.filterTab.children('li').removeClass('active');
filterTab.$pre.addClass('active');
// 价格筛选状态设置
if (filterTab.$pre.hasClass('price')) {
navInfo.price.order = filterTab.order;
... ... @@ -172,6 +188,9 @@ class Group extends Page {
filterTab.$pre.find('.icon > .down').addClass('cur');
}
}
// 根据条件重置筛选页面及商品列表
this.filterInit();
this.search();
}
... ... @@ -200,7 +219,7 @@ class Group extends Page {
search() {
let params = this.filterTab[this.selectedChannel];
console.log(params, this.navInfo.price);
console.log('searchParam', params);
// let setting;
... ... @@ -223,28 +242,28 @@ class Group extends Page {
// 筛选初始化
filterInit() {
let $filterMask;
let requestParams = this.filterTab[this.selectedChannel];
let requestParams = {
...this.filterTab[this.selectedChannel]
};
let filterTab = this.selector.filterTab;
let search = this.search.bind(this);
delete requestParams.$pre;
console.log(requestParams);
console.log('initParam', requestParams);
$.ajax({
type: 'GET',
url: '/activity/group/filter',
data: requestParams,
success: function(data) {
$filterMask && $filterMask.remove();
$('.filter-mask').remove();
$('.group').append(data);
$filterMask = $('.filter-mask');
// 初始化filter&注册filter回调
filter.initFilter({
fCbFn: this.search,
fCbFn: search,
hCbFn: function() {
filterTab.children('.filter').removeClass('active');
innerScroll.enableScroll($('body'));
},
missStatus: true
});
... ...
... ... @@ -10,12 +10,21 @@
}
.status-text {
margin-top: 60px;
font-size: 36px;
color: #444;
text-align: center;
font-weight: bold;
}
.status-text-tip {
margin-top: 16px;
font-size: 24px;
color: #b0b0b0;
letter-spacing: -0.68px;
text-align: center;
}
.status-btn {
display: inline-block;
height: 80px;
... ... @@ -33,6 +42,10 @@
background: #d0021b;
margin-top: 60px;
}
&.squeeze {
margin-top: 50px;
}
}
.inner-card {
... ... @@ -42,6 +55,7 @@
width: 600px;
height: 282px;
background: #fff;
z-index: 1;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
}
... ... @@ -276,3 +290,19 @@
}
}
}
.dialog-wrapper .dialog-box.group-guide-mask {
width: 284px;
height: 278px;
background: url("img/activity/group/share-tip.png");
background-size: 100% 100%;
margin: 0 !important;
border: 0;
right: 92px;
top: 28px !important;
left: auto;
> * {
display: none !important;
}
}
... ...
... ... @@ -80,7 +80,7 @@
top: 0;
right: 0;
left: 0;
z-index: 2;
z-index: 9999;
height: 100%;
background: rgba(0, 0, 0, 0.1);
}
... ... @@ -93,7 +93,7 @@
height: 80px;
line-height: 80px;
text-align: center;
z-index: 2;
z-index: 9999;
background-color: #444;
color: #fff;
}
... ... @@ -104,7 +104,7 @@
right: 0;
left: 0;
bottom: 80px;
z-index: 2;
z-index: 9999;
background: #fff;
color: #000;
font-size: 28px;
... ... @@ -159,7 +159,7 @@
overflow: auto;
-webkit-overflow-scrolling: touch;
width: 50%;
height: 880px;
height: 100%;
> li {
overflow: hidden;
... ...
const _ = require('lodash');
const toArray = (obj) => {
if (_.isArray(obj)) {
return obj;
}
let arr = [];
_.forEach(obj, (v, k) => {
if (_.isObject(v)) {
v._key = k;
} else {
v = {
_key: k,
_value: v
};
}
arr.push(v);
});
return arr;
};
/**
* 按照数组中指定字段排序二维数组
*
* @param array list 需要排序的数组
* @param string key 字段名称
* @param boolean 有 desc 时候降序排列,默认为false
*/
const _sortListByField = (list, key, desc) => {
let array = toArray(list);
return array.sort(function(a, b) {
a = a._key.split(',')[0] * 1;
b = b._key.split(',')[0] * 1;
return desc ? a < b : a > b;
});
};
/**
* 处理筛选数据
* @param list
... ... @@ -86,7 +48,7 @@ exports.processFilter = (list, options) => {
dataType: 'gender',
sortNum: '0'
},
group_sort: {
sort: {
name: '所有品类',
title: '品类',
dataId: 'relation_parameter',
... ... @@ -113,7 +75,7 @@ exports.processFilter = (list, options) => {
dataType: 'size',
sortNum: '5'
},
ageLevel: {
age_level: {
name: '所有人群',
title: '人群',
dataId: 'id',
... ... @@ -139,10 +101,6 @@ exports.processFilter = (list, options) => {
return;
}
if ((options.hideSize && key === 'size') || (options.hideSort && key === 'group_sort')) {
return;
}
classify.dataType = filtersType[key].dataType;
classify.name = filtersType[key].name;
classify.title = filtersType[key].title;
... ... @@ -153,41 +111,24 @@ exports.processFilter = (list, options) => {
name: filtersType[key].name
});
// 折扣,价格区间,需要排序
if (key === 'discount' || key === 'priceRange') {
item = _sortListByField(item, 'name');
}
// 测试数据
// let itemList = [];
// for (let i = 0; i < 12; i++) {
// itemList.push({
// itemId: '1,3',
// itemName: 'MEN'
// });
// }
let itemList = item.allItemList || item.itemList;
_.forEach(item.itemList, (sub) => {
_.forEach(itemList, (sub) => {
let subs = {};
subs.dataId = sub.itemId;
subs.name = sub.itemName;
// if (key === 'discount') {
// subs.dataId = sub._key;
// } else if (key === 'priceRange') {
// subs.dataId = sub._key;
// } else if (filtersType[key].dataId === 'key') {
// subs.dataId = index;
// } else if (filtersType[key].dataId === 'relation_parameter') {
// subs.dataId = sub.relation_parameter['sort']; // eslint-disable-line
// } else {
// subs.dataId = sub[filtersType[key].dataId];
// }
// if (key === 'priceRange') {
// subs.name = sub._value.replace('¥', '¥');
// } else if (filtersType[key].subsName === 'flag') {
// subs.name = sub;
// } else {
// subs.name = sub[filtersType[key].subsName];
// if (key === 'discount') {
// subs.name = subs.name + '折商品';
// }
// }
if (options[classify.dataType] + '' === subs.dataId + '') {
subs.chosed = true;
classify.subs[0].chosed = false;
... ... @@ -195,9 +136,7 @@ exports.processFilter = (list, options) => {
classify.subs.push(subs);
});
filters.classify[filtersType[key].sortNum] = classify;
});
return filters;
};
... ...