Authored by yyq

usercenter coupon

'use strict';
let couponsModel = require('../models/coupons-model');
let couponsModel = require('../models/coupon-service');
const index = (req, res, next)=>{
let uid = req.user.uid;
req.ctx(couponsModel).couponsData(uid, req.query).then(result => {
req.ctx(couponsModel).getCouponData(uid, req.query).then(result => {
res.render('coupons', result);
}).catch(next);
};
... ...
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
getCouponList(uid, type, page, extra) {
extra = extra || {};
let reqData = {
method: 'app.coupons.get',
uid: uid,
type: type || 'notuse',
page: page || 1,
limit: extra.limit || 10
};
if (extra.filter) {
reqData.filter = extra.filter;
}
return this.get({data: reqData});
}
getCouponNum(uid) {
return this.get({data: {
method: 'app.coupons.getCouponNums',
uid: uid
}});
}
};
... ...
const _ = require('lodash');
const CouponApi = require('./coupon-api');
const helpers = global.yoho.helpers;
const setPager = require(`${global.utils}/pager`).setPager;
const COUPON_BASE_URI = '/home/coupons';
const COUPON_TYPE = {
UNUSED: 'notuse',
USED: 'use',
INVALID: 'overtime'
};
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
_setShowNum(num) {
num = num > 0 ? num : 0;
num = num > 99 ? '99+' : num;
return num ? `(${num})` : '';
}
_setCouponTabs(nums, type) {
nums = nums || {};
return [
{
active: type === COUPON_TYPE.UNUSED,
url: helpers.urlFormat(COUPON_BASE_URI),
name: `可用${this._setShowNum(nums[COUPON_TYPE.UNUSED])}`
},
{
active: type === COUPON_TYPE.USED,
url: helpers.urlFormat(COUPON_BASE_URI, {type: COUPON_TYPE.USED}),
name: `已使用${this._setShowNum(nums[COUPON_TYPE.USED])}`
},
{
active: type === COUPON_TYPE.INVALID,
url: helpers.urlFormat(COUPON_BASE_URI, {type: COUPON_TYPE.INVALID}),
name: `已失效${this._setShowNum(nums[COUPON_TYPE.INVALID])}`
}
];
}
getCouponData(uid, params) {
params = params || {};
const page = parseInt(`0${params.page}`, 10) || 1;
const type = params.type || COUPON_TYPE.UNUSED;
const couponApiCase = new CouponApi(this.ctx);
let resData = {};
return Promise.all([
couponApiCase.getCouponList(uid, params.type, page, params),
couponApiCase.getCouponNum(uid)
]).then(result => {
Object.assign(resData, _.get(result, '[0].data', {}));
if (resData.couponList && resData.couponList.length) {
_.forEach(resData.couponList, value => {
if (type === COUPON_TYPE.USED) {
value.isUsed = true;
} else if (type === COUPON_TYPE.INVALID) {
if (value.is_overtime === 'Y') {
value.isOvertime = true;
} else {
value.isUseless = true;
}
} else {
value.toUse = helpers.urlFormat('', {cpc_id: value.coupon_id, coupon_code: value.coupon_code,
phrase: encodeURIComponent('以下商品可使用 【' + value.coupon_name + '】优惠券')}, 'list');
}
});
} else {
resData.couponList = false;
}
resData.tabs = this._setCouponTabs(_.get(result, '[1].data', {}), type);
if (_.get(resData, 'tabs[0].active') && resData.filters) {
const filterUrl = helpers.urlFormat(COUPON_BASE_URI,
Object.assign({}, params, {filter: '__filter__', page: 1}));
let filter = params.filter || 0;
_.forEach(resData.filters, value => {
if ((+filter === +value.filter_id)) {
value.active = true;
value.url = 'javascript:;'; // eslint-disable-line
} else {
value.url = filterUrl.replace('__filter__', value.filter_id);
}
});
} else {
resData.filters = false;
}
let total = _.get(resData, 'total', 0);
let pageTotal = _.get(resData, 'pageNum') || 1;
resData.pager = Object.assign({
count: total,
curPage: page,
totalPages: pageTotal
}, setPager(pageTotal, params));
return resData;
});
}
};
... ...
... ... @@ -12,73 +12,54 @@
<button class="code-sure-btn right">兑换</button>
<input type="text" class="code-input right" placeholder="请输入优惠券码">
</div>
{{#if filters}}
<div class="type-wrap">
<label class="active">全部优惠券</label>
<label>店铺券</label>
<label>活动券</label>
<label>运费券</label>
{{# filters}}
<a href="{{url}}" class="type-item{{#if active}} active{{/if}}">{{filter_name}}</a>
{{/ filters}}
</div>
{{/if}}
</div>
<div class="coupons-wrap clearfix">
<div class="coupon-item">
<div class="border">
<div class="due-tig"></div>
<div class="worth">
<p>¥<span class="price">100</span><br><span class="conditions">满499可用</span></p>
{{# couponList}}
<div class="coupon-item{{#if isUsed}} used{{/if}}{{#if isOvertime}} over-time{{/if}}{{#if isUseless}} useless{{/if}}">
<div class="border">
{{#isY is_overdue_soon}}
<div class="due-tig"></div>
{{/isY}}
<div class="worth">
{{#isEqual catalog 300}}
<p><span class="freight">{{../coupon_value_str}}</span></p>
{{^}}
<p>¥<span class="price">{{../coupon_value_str}}</span><br><span class="conditions">{{../use_rule}}</span></p>
{{/isEqual}}
</div>
<div class="coupon-info">
<p class="name"><span class="type type-{{catalog}}">[{{catalog_name}}]</span>{{coupon_name}}</p>
<p class="time">{{coupon_validity}}</p>
{{#if notes}}
<label class="explain">
使用说明 >
<p class="explain-wrap">
{{# notes}}
{{{.}}}<br>
{{/ notes}}
</p>
</label>
{{/if}}
</div>
{{# toUse}}
<a href="{{.}}" class="use-now-btn" target="_blank">立即使用</a>
{{/ toUse}}
</div>
<div class="coupon-info">
<p class="name"><span class="type type-s">[店铺券]</span> Adidas Origins店铺使用</p>
<p class="time">2018.1.12-2018.5.20</p>
<label class="explain">
使用说明 >
<p class="explain-wrap">
全场通用,特例商品暂不支持使用优惠券<br>可以与其他类型叠加使用,同店铺只能使用一张,不同店铺可以叠加使用
</p>
</label>
</div>
<a href="" class="use-now-btn">立即使用</a>
</div>
</div>
<div class="coupon-item used">
<div class="border">
<div class="worth">
<p>¥<span class="price">100</span><br><span class="conditions">满499可用</span></p>
</div>
<div class="coupon-info">
<p class="name"><span class="type type-a">[店铺券]</span> Adidas Origins店铺使用</p>
<p class="time">2018.1.12-2018.5.20</p>
<label class="explain">使用说明 ></label>
</div>
<a href="" class="use-now-btn">立即使用</a>
</div>
</div>
<div class="coupon-item over-time">
<div class="border">
<div class="worth">
<p><span class="freight">普通</span></p>
</div>
<div class="coupon-info">
<p class="name"><span class="type type-d">[运费券]</span> 8月份运费券</p>
<p class="time">2018.1.12-2018.5.20</p>
<label class="explain">使用说明 ></label>
</div>
<a href="" class="use-now-btn">立即使用</a>
</div>
</div>
<div class="coupon-item useless">
<div class="border">
<div class="worth">
<p><span class="freight">顺丰</span></p>
</div>
<div class="coupon-info">
<p class="name"><span class="type type-d">[运费券]</span> 8月份运费券</p>
<p class="time">2018.1.12-2018.5.20</p>
<label class="explain">使用说明 ></label>
</div>
<a href="" class="use-now-btn">立即使用</a>
</div>
</div>
{{/ couponList}}
{{#unless couponList}}
<p class="empty-tip">您没有优惠券</p>
{{/unless}}
</div>
{{> pager}}
</div>
</div>
</div>
... ...
... ... @@ -4,7 +4,7 @@
<label class="type-item type-200" data-type="200">活动券</label>
<label class="type-item type-300" data-type="300">运费券</label>
</div>
<div class="head-msg fw300">{{headMsg}}</div>
<div class="head-msg fw300">{{{headMsg}}}</div>
<div class="list-content">
{{#each usableCoupon}}
<div class="list-{{@key}} type-content clearfix">
... ...
... ... @@ -557,15 +557,15 @@ coupon = {
that.$couponUsableWrap.html(couponUsableTpl(data));
that.setTabItemNum('usable', data.usableNum);
usedText = data.usableNum ? `可用${data.usableNum}` : '';
usedText = data.usableNum ? `${data.usableNum}张可用` : '';
// 更新使用数量
usedNum = that.$couponWrap.find('.coupon-item.active').length;
if (hasCode) {
usedText = usedNum ? `已选${usedNum}张` : usedText;
order.couponCode = data.usedCouponCode;
compute(0); // 重新计算价格
usedText = usedNum ? `已选${usedNum}张` : usedText;
} else {
usedText += usedNum ? ` 已推荐${usedNum}张` : '';
}
... ... @@ -616,7 +616,7 @@ coupon = {
}
if (!this.$codeUseTip) {
this.$codeUseTip = $('.code-use-tip', this.$el);
this.$codeUseTip = $('.code-use-tip', this.$couponWrap);
}
this.$codeUseTip.text(tip);
... ... @@ -748,6 +748,8 @@ coupon = {
} else {
that.$couponCodeUse.removeClass('sure-convert-btn');
}
that.showCodeUseTip();
}).on('click', '.sure-convert-btn', function() {
that.useCode(that.$couponCode.val());
}).on('click', '.usable-wrap .coupon-item', function() {
... ...
var $ = require('yoho-jquery');
var yas = require('../common/data-yas');
var yas = require('../common/data-yas'),
dialog = require('../common/dialog');
var $couponCodeUse = $('.code-sure-btn'),
$codeInput = $('.code-input');
require('../common');
... ... @@ -10,3 +14,29 @@ $('.use-now-btn').click(function() {
yas.yasEvent('YB_COUPON_IMMEDIATE_USE_C', {COUPON_ID: couponid});
}
});
$codeInput.keyup(function() {
if ($.trim($(this).val())) {
$couponCodeUse.addClass('sure-convert-btn');
} else {
$couponCodeUse.removeClass('sure-convert-btn');
}
});
$couponCodeUse.click(function() {
var code = $.trim($codeInput.val());
if ($(this).hasClass('sure-convert-btn') && code) {
$.ajax({
type: 'GET',
url: '/cart/ensure/couponcode',
data: {code: code}
}).then(function(data) {
if (data.code === 200) {
window.location.reload();
} else {
new dialog.Alert(data.message || '兑换失败,请稍后再试').show();
}
});
}
});
... ...
... ... @@ -1214,7 +1214,7 @@
.name {
max-width: 90%;
height: 36px;
line-height: 1.3;
line-height: 1.4;
font-size: 13px;
color: #444;
overflow: hidden;
... ... @@ -1222,6 +1222,15 @@
.type {
font-weight: bold;
margin-right: 4px;
}
.type-100 {
color: #efaf46;
}
.type-200 {
color: #fc5960;
}
.time {
... ...
... ... @@ -38,6 +38,10 @@
padding: 0;
border: 0;
}
.sure-convert-btn {
background: #444;
}
}
.tabs {
... ... @@ -76,7 +80,7 @@
font-size: 0;
border-bottom: 1px solid #e0e0e0;
> label {
.type-item {
min-width: 90px;
height: 30px;
line-height: 28px;
... ... @@ -90,7 +94,7 @@
cursor: pointer;
}
> label:first-child {
.type-item:first-child {
margin-left: 0;
}
... ... @@ -110,6 +114,10 @@
font-size: 0;
}
.empty-tip {
font-size: 12px;
}
.coupon-item {
width: 354px;
height: 100px;
... ... @@ -199,7 +207,7 @@
.name {
max-width: 90%;
height: 36px;
line-height: 1.3;
line-height: 1.4;
font-size: 13px;
color: #444;
overflow: hidden;
... ... @@ -207,6 +215,15 @@
.type {
font-weight: bold;
margin-right: 4px;
}
.type-100 {
color: #efaf46;
}
.type-200 {
color: #fc5960;
}
.time {
... ...