Authored by yyq

品牌、店铺领券

... ... @@ -228,3 +228,51 @@ exports.isFavoriteBrand = (req, res, next) => {
res.json(result);
}).catch(next);
};
/**
* 用户店铺优惠券领取状态
* @param {[type]} req [description]
* @param {[type]} res [description]
* @return {[type]} [description]
*/
exports.shopCouponSync = (req, res, next) => {
let uid = req.user.uid;
let id = req.query.id;
if (!req.xhr) {
return next();
}
if (!id || !uid) {
return res.json({code: 400, message: '用户未登录或缺少参数'});
}
list.getUserCoupunStatus(id, uid, 'shop').then(result => {
res.json(result);
});
};
/**
* 用户品牌优惠券领取状态
* @param {[type]} req [description]
* @param {[type]} res [description]
* @return {[type]} [description]
*/
exports.brandCouponSync = (req, res, next) => {
let uid = req.user.uid;
let id = req.query.id;
if (!req.xhr) {
return next();
}
if (!id || !uid) {
return res.json({code: 400, message: '用户未登录或缺少参数'});
}
list.getUserCoupunStatus(id, uid, 'brand').then(result => {
res.json(result);
});
};
... ...
... ... @@ -283,9 +283,12 @@ const getBrandData = (params, extra, channel) => {
headerModel.requestHeaderData(channel),
searchApi.getSortList(queryBase),
searchApi.getProductList(Object.assign(searchParams, {order: order}, queryBase))
];
if (queryBase.brand) {
apiMethod.push(searchApi.getBrandCouponAsync(queryBase.brand));
}
return Promise.all(apiMethod).then(result => {
let finalResult = {
headerData: Object.assign(result[0].headerData, {
... ... @@ -338,6 +341,11 @@ const getBrandData = (params, extra, channel) => {
_.unset(finalResult, 'brand.filters.brand');
}
if (result[3] && result[3].data) {
finalResult.brand.coupon = searchHandler.handleBrandShopCoupons(
_.get(result[3], 'data.coupons', []), {brandId: extra.brandId});
}
finalResult.criteo = {skn: searchHandler.getCriteo(_.get(finalResult.brand, 'goods'))};
let seo = searchHandler.getBrandSeo(channel, extra);
... ... @@ -547,7 +555,7 @@ const getShopData = (shopId, channel, params, shopInfo) => {
shop_id: shopId
}, params)), // 搜索店铺商品
searchApi.getShopBrands(shopId), // 店铺品牌数据
shopApi.shopCouponListAsync(792) // 店铺优惠券数据
shopApi.shopCouponListAsync(shopId) // 店铺优惠券数据
]).then(result => {
let finalResult = {};
... ... @@ -618,26 +626,7 @@ const getShopData = (shopId, channel, params, shopInfo) => {
}
if (result[4].data && !_.isEmpty(result[4].data)) {
let data = result[4].data,
length = data.length || 0;
if (length) {
_.forEach(data, value => {
Object.assign(value, {
coupon_id: crypto.encryption('', `${value.coupon_id}`),
money: +value.money
});
});
if (length === 1) {
data[0].showUnit = true;
}
finalResult.coupon = {
list: data,
length: length,
showNextBtn: length > 3
};
}
finalResult.coupon = searchHandler.handleBrandShopCoupons(result[4].data, {shopId: shopId});
}
// 根据品牌获取分类 (腾讯云测试没有该接口,暂时不调用分类)
... ... @@ -911,7 +900,8 @@ const getBaseShopData = (params, extra, channel, shopId) => {
return Promise.all([
getBrandData(params, extra, channel),
searchApi.getShopDecorator(shopId), // 店铺装修数据
searchApi.getShopInfo(shopId, extra.uid)
searchApi.getShopInfo(shopId, extra.uid),
shopApi.shopCouponListAsync(shopId) // 店铺优惠券数据
]).then(result => {
let brand = result[0] || {};
... ... @@ -951,6 +941,11 @@ const getBaseShopData = (params, extra, channel, shopId) => {
Object.assign(resData, shopHandler.setShopSeo(shopName));
}
if (result[3].data && !_.isEmpty(result[3].data)) {
_.set(resData, 'brand.coupon',
searchHandler.handleBrandShopCoupons(result[3].data, {shopId: shopId}));
}
// 临时删除seo信息
_.unset(resData, 'title');
_.unset(resData, 'keywords');
... ... @@ -960,6 +955,38 @@ const getBaseShopData = (params, extra, channel, shopId) => {
});
};
const getUserCoupunStatus = (id, uid, type) => {
if (type === 'shop') {
return shopApi.shopCouponListAsync(id, uid).then(result => {
if (result.data) {
_.forEach(result.data, value => {
Object.assign(value, {
coupon_id: crypto.encryption('', `${value.coupon_id}`),
money: +value.money
});
});
}
return result;
});
} else {
return searchApi.getBrandCouponAsync(id, uid).then(result => {
if (result.data) {
result.data = _.get(result, 'data.coupons', []);
_.forEach(result.data, value => {
Object.assign(value, {
coupon_id: crypto.encryption('', `${value.coupon_id}`),
money: +value.money
});
});
}
return result;
});
}
};
module.exports = {
getListData,
getListNewData,
... ... @@ -973,5 +1000,6 @@ module.exports = {
getShopData,
getShopGoodsData,
getShopListData,
getBaseShopData
getBaseShopData,
getUserCoupunStatus
};
... ...
... ... @@ -227,6 +227,20 @@ const getWeekNew = (params) => {
return api.get('', finalParams);
};
const getBrandCouponAsync = (brandId, uid) => {
let extra = {code: 200};
if (!uid) {
extra.cache = true;
}
return api.get('', {
method: 'app.brand.getBrandIntro',
brand_id: brandId,
uid: uid
}, extra);
};
/**
* 根据关键词搜索品牌店铺信息 TODO
* @return
... ... @@ -515,6 +529,7 @@ module.exports = {
getBrandFolder,
getBrandSeries,
getWeekNew,
getBrandCouponAsync,
getBrandShop,
getSuggest,
getBrandData,
... ...
... ... @@ -8,6 +8,7 @@
'use strict';
const _ = require('lodash');
const helpers = global.yoho.helpers;
const crypto = global.yoho.crypto;
const queryString = require('querystring');
const indexUrl = {
boys: helpers.urlFormat('/'),
... ... @@ -1514,3 +1515,34 @@ exports.getSearchParams = params => {
exports.handleFilterBrands = (brands, params) => {
return formatterFilterBrands(brands, null, params);
};
exports.handleBrandShopCoupons = (data, params) => {
let resData = {};
let length;
data = data || [];
params = params || {};
length = data.length || 0;
if (length) {
_.forEach(data, value => {
Object.assign(value, {
coupon_id: crypto.encryption('', `${value.coupon_id}`),
money: +value.money
});
});
if (length === 1) {
data[0].showUnit = true;
}
Object.assign(resData, {
list: data,
length: length,
showNextBtn: length > 3
}, params);
}
return resData;
};
... ...
... ... @@ -83,6 +83,9 @@ router.get('/list/new', list.new);
router.get('/index/brand', list.brand);
router.get('/index/about', list.brandAbout);
router.get('/shop/couponsync', list.shopCouponSync);
router.get('/brand/couponsync', list.brandCouponSync);
router.get('/shoplist', list.shopList); // 店铺列表页
router.post('/shop/togglecollect', favorite.collectShop); // 店铺收藏
router.post('/index/isFavoriteShop', favorite.isFavShop); // 判断用户是否收藏品牌
... ...
... ... @@ -57,6 +57,8 @@
</div>
<div class="list-right pull-right">
{{> list/top-coupon}}
{{# sortIntro}}
<div class="sort-intro clearfix">
<div class="texts pull-left">
... ...
{{# coupon}}
<div class="top-coupon-wrap num{{length}}">
<div class="top-coupon-wrap num{{length}}"{{# shopId}} data-shop="{{.}}"{{/ shopId}}{{# brandId}} data-brand="{{.}}"{{/ brandId}}>
<div class="coupon-title"></div>
<ul class="coupon-list clearfix">
{{# list}}
... ... @@ -9,7 +9,7 @@
<p class="limit-text">{{coupon_name}}</p>
<p class="term">有效日期:{{couponValidity}}</p>
</div>
<div class="pick-btn" data-id={{coupon_id}} data-name="{{coupon_name}} data-time={{couponValidity}}">点击领取</div>
<div class="pick-btn" data-id={{coupon_id}} data-money="{{money}}" data-name="{{coupon_name}}" data-time="{{couponValidity}}">点击领取</div>
</li>
{{/ list}}
</ul>
... ...
... ... @@ -24,46 +24,42 @@ var couponPickConfig = {
btns: [{
id: 1,
name: '去购物啦',
btnClass: ['black', 'btn-close'],
cb: function() {
}
btnClass: ['black', 'btn-close']
}, {
id: 2,
name: '查看优惠券',
btnClass: ['btn-close'],
cb: function() {
window.open('//www.yohobuy.com/home/coupons');
}
}]
},
got: {
content: '您已领取过优惠券',
content: '<i class="iconfont">&#xe61f;</i>您已领取过优惠券',
subContent: ['快去选购心仪的潮品吧'],
className: 'top-coupon-dialog',
btns: [{
id: 1,
name: '去使用',
btnClass: ['btn-close'],
cb: function() {
}
btnClass: ['btn-close']
}]
},
expired: {
content: '优惠券已失效',
content: '<i class="iconfont">&#xe61f;</i>优惠券已失效',
className: 'top-coupon-dialog',
btns: [{
name: '去购物啦',
btnClass: ['black', 'btn-close'],
cb: function() {
}
btnClass: ['black', 'btn-close']
}, {
name: '查看优惠券',
btnClass: ['btn-close'],
cb: function() {
window.open('//www.yohobuy.com/home/coupons');
}
}]
},
failed: {
content: '领取失败',
content: '<i class="iconfont">&#xe61f;</i>领取失败',
subContents: ['请刷新重试,', '多次无效请联系客服'],
className: 'top-coupon-dialog',
btns: [{
... ... @@ -76,7 +72,7 @@ var couponPickConfig = {
}]
},
over: {
content: '优惠券已领光',
content: '<i class="iconfont">&#xe61f;</i>优惠券已领光',
subContents: ['尝试领取其它优惠券吧'],
className: 'top-coupon-dialog',
btns: [{
... ... @@ -84,21 +80,73 @@ var couponPickConfig = {
name: '关闭',
btnClass: ['btn-close']
}]
},
notLogged: {
content: '<i class="iconfont">&#xe61f;</i>领取失败',
subContents: ['您当前处于未登录状态', '请登录后尝试领取优惠券'],
className: 'top-coupon-dialog',
btns: [{
id: 1,
name: '关闭',
btnClass: ['btn-close']
}]
}
};
$pickBtn.each(function() {
var $this = $(this),
data = $this.data();
// 获取优惠券信息
function getCouponInfo() {
$pickBtn.each(function() {
var $this = $(this),
data = $this.data();
couponObj[data.id] = {
id: data.id || '',
dom: $this,
money: data.money || 0,
name: data.name || '',
time: data.time || '',
status: 1 // 1:可领取,2:已领光,3:已领取
};
});
}
// 设置优惠券领取状态
function setPicked(info) {
if (info) {
info.dom.text('已领取');
info.status = 3;
}
}
// 同步优惠券领取状态
function syncCouponStatus() {
var data = $couponWrap.data(),
url = '/product';
couponObj[data.id] = {
dom: $this,
money: data.money,
name: data.name,
time: data.time,
status: 1 // 1:可领取,2:已领光,3:已领取
};
});
url += data.shop ? '/shop' : '/brand';
$.ajax({
type: 'GET',
url: url + '/couponsync',
data: {id: data.shop || data.brand}
}).then(function(result) {
var i, coup, info;
if (result.code === 200) {
info = result.data || [];
for (i = 0; i < info.length; i++) {
coup = couponObj[info[i].coupon_id];
if (coup) {
coup.status = info[i].status;
if (coup.status === 3) {
setPicked(coup);
}
}
}
}
});
}
// 根据配置执行展示弹窗
function couponAlert(opt) {
... ... @@ -107,64 +155,90 @@ function couponAlert(opt) {
newAlert.show();
}
$pickBtn.click(function() {
var id = $(this).data('id'),
couponInfo = couponObj[id];
// 领取优惠券
function pickCoupon(info) {
var that = this;
if (!couponInfo) { // 优惠券号异常错误提示
return couponAlert(couponPickConfig.failed);
} else if (couponInfo.status === 2) { // 优惠券已领光提示
return couponAlert(couponPickConfig.over);
} else if (couponInfo.status === 3) { // 优惠券已领取提示
return couponAlert(couponPickConfig.got);
if (that.picking || !info.id) {
return;
}
// 防止重复触发
that.picking = true;
$.ajax({
type: 'GET',
url: '/coupon/sendcoupon',
data: {id: id}
data: {id: info.id}
}).then(function(data) {
var info;
var opt;
that.picking = false;
switch (data.code) {
case 200:
info = $.extend({subContents: [
'¥' + couponInfo.money,
couponInfo.name,
'有效日期: ' + couponInfo.time
setPicked(info);
opt = $.extend({subContents: [
'<span class="price">¥ ' + info.money + '</span>',
info.name,
'有效日期: ' + info.time
]}, couponPickConfig.success);
break;
case 401:
info = couponPickConfig.got;
break;
case 315:
info = $.extend({subContents: [
'有效日期: ' + couponInfo.time
opt = $.extend({subContents: [
'有效日期: ' + info.time
]}, couponPickConfig.expired);
break;
case 400:
opt = couponPickConfig.notLogged;
break;
case 401:
setPicked(info);
opt = couponPickConfig.got;
break;
default:
info = couponPickConfig.failed;
opt = couponPickConfig.failed;
break;
}
couponAlert(info);
couponAlert(opt);
});
});
}
$nextBtn.click(function() {
var $this = $(this);
// 初始化与事件绑定
if ($couponWrap && $couponWrap.length) {
getCouponInfo();
if ($this.hasClass('next-end')) {
return;
}
syncCouponStatus();
$pickBtn.click(function() {
var id = $(this).data('id'),
couponInfo = couponObj[id];
indexNum++;
if (!couponInfo) { // 优惠券号异常错误提示
return couponAlert(couponPickConfig.failed);
} else if (couponInfo.status === 2) { // 优惠券已领光提示
return couponAlert(couponPickConfig.over);
} else if (couponInfo.status === 3) { // 优惠券已领取提示
return couponAlert(couponPickConfig.got);
}
$couponItem.eq(0).animate({
'margin-left': -itemWidth * indexNum
pickCoupon(couponInfo);
});
if (indexNum >= $couponItem.length - 3) {
$this.addClass('next-end');
}
});
$nextBtn.click(function() {
var $this = $(this);
if ($this.hasClass('next-end')) {
return;
}
indexNum++;
$couponItem.eq(0).animate({
'margin-left': -itemWidth * indexNum
});
if (indexNum >= $couponItem.length - 3) {
$this.addClass('next-end');
}
});
}
... ...
... ... @@ -12,6 +12,7 @@ require('../common');
require('../plugins/filter');
require('../plugins/sort-pager');
require('./detail/latest-walk');
require('./index/top-coupon');
// 品牌
require('./index/brand');
... ...
... ... @@ -4,6 +4,7 @@
margin-bottom: 20px;
font-size: 0;
position: relative;
user-select: none;
> * {
cursor: default;
... ... @@ -221,6 +222,14 @@
line-height: 1.5;
text-align: center;
color: #555;
.price {
font-size: 30px;
color: #d1061e;
line-height: 1;
margin-bottom: 16px;
display: inline-block;
}
}
.btns {
... ...