Authored by 陈峰

Merge branch 'feature/yohood' into 'master'

Feature/yohood



See merge request !40
... ... @@ -13,8 +13,8 @@ const TABLE_ACT_PRIZE_PRODUCT_CONTENT = 'act_prize_product_content';
const TABLE_ACT_PRIZE_PRODUCT_USER = 'act_prize_product_user';
const MINUTE_TIMES = 60;
const PRODUCT_CACHE_TIMES = MINUTE_TIMES * 5; // 商品(列表&详情)缓存时间
const RECENT_CODE_CACHE_TIME = MINUTE_TIMES; // 最近获取记录缓存时间
const PRODUCT_CACHE_TIMES = MINUTE_TIMES / 6; // 商品(列表&详情)缓存时间
const RECENT_CODE_CACHE_TIME = MINUTE_TIMES / 12; // 最近获取记录缓存时间
const MAX_JOIN_TIMES = 5; // 最大活动参与次数
const MAX_RECOMEND_NUM = 10; // 最大推荐活动数目
const PAGE_SIZE = 10;
... ... @@ -303,7 +303,7 @@ module.exports = class extends global.yoho.BaseModel {
let info = await Promise.all([
mysqlCli.query(`select * from ${TABLE_ACT_PRIZE_PRODUCT}
where id = :actPrizeId limit 1;`, {actPrizeId}, {cache: MINUTE_TIMES / 2}),
where id = :actPrizeId limit 1;`, {actPrizeId}, {cache: PRODUCT_CACHE_TIMES}),
this.getUserJoinNum(actPrizeId, true).then(result => {
return result.data;
})
... ...
... ... @@ -38,8 +38,6 @@ const couponController = {
let data = await loadExcel(file.path);
console.log(data);
if (!data.length) {
return res.json({
code: 201,
... ... @@ -116,11 +114,16 @@ const couponController = {
async couponList(req, res) {
const pageNo = req.query.pageNo || 1;
const pageSize = req.query.pageSize || 20;
const status = req.query.status;
let totalCount = await req.ctx(CouponModel).allCouponNum();
let totalCount = await req.ctx(CouponModel).allCouponNum(status);
totalCount = totalCount[0].total;
let list = await req.ctx(CouponModel).couponList({pageNo, pageSize});
let list = await req.ctx(CouponModel).couponList({pageNo, pageSize, status});
_.each(list, item => {
item.createTime = timeFormat(item.createTime);
});
res.json({
code: 200,
... ...
... ... @@ -13,10 +13,15 @@ class CouponModel extends global.yoho.BaseModel {
super(ctx);
}
couponList({pageNo, pageSize}) {
couponList({pageNo, pageSize, status}) {
let str = '';
if (status === '0' || status === '1') {
str = `where status = ${status}`;
}
return mysqlCli.query(
`select id, coupon_name couponName, coupon_desc couponDesc, shop_name shopName, shop_logo_url shopLogoUrl, status, type, sort , create_time createTime
from ${TABLE_COUPON}
from ${TABLE_COUPON} ${str}
order by sort desc ,create_time desc
limit :start, :page;`, {
start: (pageNo - 1) * pageSize,
... ... @@ -80,22 +85,30 @@ class CouponModel extends global.yoho.BaseModel {
sort: obj.sort
});
console.log(insertId);
if (obj.type === 3) {
await mysqlCli.insert(
if (parseInt(obj.type) === 3) {
let id = await mysqlCli.insert(
`insert into ${TABLE_COUPON_NO} (coupon_id) values (:couponId);`,
{
couponId: insertId,
});
if (!id) {
return Promise.resolve({code: 204, result: false, message: '插入无码券失败'});
}
}
return Promise.resolve({code: 200, result: true});
}
}
allCouponNum() {
allCouponNum(status) {
let str = '';
if (status === '0' || status === '1') {
str = `where status = ${status}`;
}
return mysqlCli.query(
`select count(1) as total from ${TABLE_COUPON};`
`select count(1) as total from ${TABLE_COUPON} ${str};`
);
}
... ...
... ... @@ -10,6 +10,7 @@
<input class="form-imput" type="hidden" data-type="id" id="id" value="{{id}}">
<input id="type" type="hidden" value="{{type}}">
<input id="status" type="hidden" value="{{status}}">
<input id="couponDesc" type="hidden" value="{{couponDesc}}">
<div class="item form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="actName">
券名称<span class="required">*</span>
... ... @@ -28,7 +29,7 @@
</div>
<div class="item form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="actName">
商家名称<span class="required">*</span>
商家名称<span class="required">(选填)</span>
</label>
<div class="col-md-6 col-sm-6 col-xs-12">
<input class="form-control col-md-7 col-xs-12 form-imput"
... ... @@ -102,7 +103,7 @@
name="actVoteLimit"
type="text"
maxlength="10"
value="{{sort}}">
value="{{sort}}"><span style="color:#d44950">备注:排序权重数大的排在前面</span>
</div>
</div>
<div class="item form-group">
... ... @@ -110,7 +111,7 @@
class="required">*</span>
</label>
<div class="col-md-4 col-sm-4 col-xs-12">
<textarea class="form-control form-imput" data-type="couponDesc" rows="3" style="resize: none;height: 300px">{{couponDesc}}</textarea>
<textarea class="form-control form-imput" data-type="couponDesc" rows="3" style="resize: none;height: 300px"></textarea>
</div>
</div>
<div class="item form-group">
... ...
... ... @@ -6,7 +6,16 @@
<div class="x_panel">
<div class="x_title">
<a href="/admin/coupon/option" class="btn btn-primary">创建券</a>
<div class="clearfix"></div>
<div class="btn-group" style="vertical-align: top">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span id="dropdown-toggle-txt">全部 </span> <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li data-status="1"><a href="#">已上架</a></li>
<li data-status="0"><a href="#">已下架</a></li>
<li><a href="#">全部</a></li>
</ul>
</div>
</div>
<div class="x_content">
<div class="table-responsive">
... ... @@ -15,8 +24,8 @@
<tr class="headings">
<th class="column-title">ID</th>
<th class="column-title">券名称</th>
<th class="column-title">商铺名称</th>
<th class="column-title">商铺图标</th>
<th class="column-title">商家名称</th>
<th class="column-title">券图标</th>
<th class="column-title">上下架状态</th>
<th class="column-title">券类型</th>
<th class="column-title">排序权重</th>
... ...
... ... @@ -48,6 +48,7 @@ const couponController = {
},
async couponGet(req, res, next) {
console.log(req.body);
if (!req.body.params.userId) {
return res.json({
code: 200,
... ...
... ... @@ -199,6 +199,52 @@ const yohood = {
return req.ctx(YohoodModel).getShopProductsByShopId(shopId).then(result => {
return res.json(result);
});
},
async getCoupon(req, res) {
let {uid, couponId} = req.query;
console.log(uid, couponId);
if (!uid || !couponId) {
return res.json({
code: 400,
message: INVALID_PARAMS
});
}
let couponInfo = await req.ctx(YohoodModel).getCouponInfo(couponId);
let couponDetail = await req.ctx(YohoodModel).getCouponDetail(uid, couponId);
// console.log('couponDetail:', couponDetail);
// console.log('couponInfo', couponInfo.data[0].coupon_num);
if (couponDetail.code === 200 && couponDetail.data.length > 0) {
return res.json(couponDetail);
} else if (couponInfo.data[0].coupon_num > 0) {
let getCoupon = await req.ctx(YohoodModel).getOfflineStoreCoupon(uid, couponId);
// console.log('getCoupon:', getCoupon);
if (getCoupon.code === 200) {
couponDetail = await req.ctx(YohoodModel).getCouponDetail(uid, couponId);
return res.json(couponDetail);
} else if (getCoupon.code === 201) {
return res.json(couponDetail);
} else {
return res.json({
code: 203,
message: '领券失败'
});
}
} else {
return res.json({
code: 204,
message: '券已领完'
});
}
}
};
... ...
... ... @@ -49,7 +49,6 @@ class CouponModel extends global.yoho.BaseModel {
let noId = couponNolist[0].id;
// 如果type=2(一人一码) 则修改第一张待用券码的send状态
if (obj.type === 2) {
await mysqlCli.update(`UPDATE ${TABLE_COUPON_NO} SET send_flag = 1 where id = :id`, {id: noId});
... ...
... ... @@ -2,6 +2,8 @@
* Created by qiujun on 2018/7/19.
*/
const service = global.yoho.StoreAPI;
class YohoodModel extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
... ... @@ -36,6 +38,40 @@ class YohoodModel extends global.yoho.BaseModel {
}
});
}
/**
* 获取线下店优惠券
* @param uid
* @param couponId
*/
async getOfflineStoreCoupon(uid, couponId) {
return await service.get('coupon/sendCoupon.do', {
uid: uid,
couponId: couponId
});
}
/**
* 获取用户下的券信息
* @param uid
* @param couponId
*/
async getCouponDetail(uid, couponId) {
return await service.get('coupon/getCouponDetail.do', {
uid: uid,
couponId: couponId
});
}
/**
* 获取券信息
* @param couponId
*/
async getCouponInfo(couponId) {
return await service.get('coupon/getCoupon.do', {
couponId: couponId
});
}
}
... ...
... ... @@ -44,6 +44,7 @@ router.get('/yohood/getNewsDetail', yohood.getNewsDetail);
router.get('/yohood/getRecommend', yohood.getRecommend);
router.get('/yohood/getResource', yohood.getYohoBuyResource);
router.get('/yohood/getShopProduct', yohood.getYohoBuyShopProduct);
router.get('/yohood/getCoupon', yohood.getCoupon);
// coupon
router.get('/coupon/getCouponList', coupon.couponList);
... ... @@ -51,4 +52,5 @@ router.get('/coupon/getCouponSendFlags', coupon.couponSendFlag);
router.post('/coupon/couponGet', coupon.couponGet);
router.get('/coupon/couponUserOwner', coupon.couponUserOwner);
module.exports = router;
... ...
... ... @@ -25,6 +25,7 @@ module.exports = {
singleApi: 'http://api.yoho.cn/',
api: 'http://api.yoho.cn/',
store: 'http://192.168.102.47:8080/portal-gateway/wechat/',
service: 'http://service.yoho.cn/',
serviceNotify: 'http://service.yoho.cn/',
platformApi: 'http://172.16.6.210:8088/',
... ... @@ -128,6 +129,7 @@ if (isProduction) {
assetUrl: `/yoho-activity-platform/${pkg.version}/`,
domains: {
api: 'http://api.yoho.yohoops.org/',
store: 'https://openstore.yohobuy.com',
service: 'http://api.yoho.yohoops.org/',
global: 'http://api-global.yohobuy.com',
liveApi: 'http://api.live.yoho.cn/',
... ... @@ -184,7 +186,7 @@ if (isProduction) {
api: process.env.TEST_API || 'http://api-test1.yohops.com:9999/',
service: process.env.TEST_SERVICE || 'http://service-test1.yohops.com:9999/',
global: process.env.TEST_GLOBAL || 'http://global-test-soa.yohops.com:9999/',
store: process.env.TEST_STORE || 'http://192.168.102.210:8080/portal-gateway/',
store: process.env.TEST_STORE || 'http://192.168.102.210:8080/portal-gateway/wechat/',
liveApi: process.env.TEST_LIVE || 'http://testapi.live.yohops.com:9999/',
singleApi: process.env.TEST_SINGLE || 'http://api-test1.yohops.com:9999/',
platformApi: 'http://192.168.102.48:8088/'
... ...
... ... @@ -65,7 +65,9 @@ function initUpload() {
function bindEditPageEvent() {
initUpload();
function getStrFormat(strValue) {
return strValue.replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, '&nbsp;');
}
function packInfo() {
let resData = {};
let error;
... ... @@ -75,11 +77,14 @@ function bindEditPageEvent() {
let val = $this.val();
let data = $this.data();
if (!val && !error && data.type !== 'id' && data.type !== 'couponNo') {
if (!val && !error && data.type !== 'id' && data.type !== 'couponNo' && data.type !== 'shopName') {
error = data.empty || `请填写${data.type}`;
}
resData[data.type] = val;
if (data.type === 'couponDesc') {
resData[data.type] = getStrFormat(val);
} else {
resData[data.type] = val;
}
});
if (error) {
... ... @@ -109,6 +114,9 @@ function bindEditPageEvent() {
};
}
function initialStr(str) {
return str.replace(new RegExp('<br/>', 'gm'), '\r\n').replace(new RegExp('&nbsp;', 'gm'), '\s');
}
function radioInit() {
let type = $('#type').val();
let status = $('#status').val();
... ... @@ -127,6 +135,7 @@ function bindEditPageEvent() {
$('input[name=type]').each(function(index, el) {
$(el).attr('disabled', true);
});
$('textarea').val(initialStr($('#couponDesc').val()));
}
}
... ...
... ... @@ -34,14 +34,18 @@ function bind_table_pagination() {
});
}
};
let statusParam = null;
const fetchRender = (pageNo, pageSize) => {
let param = {pageNo, pageSize};
if (statusParam != null) {
param.status = statusParam;
}
$.ajax({
url: '/admin/api/coupon/list',
data: {
pageNo,
pageSize
}
data: param
})
.then(result => {
const list = result.data;
... ... @@ -62,9 +66,11 @@ function bind_table_pagination() {
} else if (item.type == 3) {
item.typeText = '不用码';
}
let status = item.status ? `<a class="btn btn-danger btn-status" data-id="${item.id}" data-status="0">下架</a>` : `<a class="btn btn-success btn-status" data-id="${item.id}" data-status="1">上架</a>`;
html += `
<tr class="even pointer">
<td class="">${item.id}</td>1
<td class="">${item.id}</td>
<td class="">${item.couponName}</td>
<td class="">${item.shopName}</td>
<td class=""><img src="${item.shopLogoUrl}" width="100" height="50"/></td>
... ... @@ -76,10 +82,11 @@ function bind_table_pagination() {
<form id="uploadForm_${item.id}" enctype="multipart/form-data">
<input id="up_excel" name="up_excel" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" style="display: inline-block; width: 80%;" type="file">
</form>
<button type="button" class="btn btn-danger btn-import" style="display: inline-block;" data-id="${item.id}">导入券码</button>
<button class="btn btn-danger btn-export-no" data-id="${item.id}">导出券码
<button type="button" class="btn btn-primary btn-import" style="display: inline-block;" data-id="${item.id}">导入券码</button>
<button class="btn btn-primary btn-export-no" data-id="${item.id}">导出领取信息
</button>
<a class="btn btn-danger btn-update" href="/admin/coupon/update?id=${item.id}">修改</a>
<a class="btn btn-info btn-update" href="/admin/coupon/update?id=${item.id}">修改</a>
` + status + `
<a class="btn btn-danger btn-delete" data-id="${item.id}">删除</a>
</td>
</tr>`;
... ... @@ -108,7 +115,6 @@ function bind_table_pagination() {
$('.btn-delete').click(function() {
let id = $(this).attr('data-id');
console.log(id);
$.ajax({
url: '/admin/api/coupon/delete?id=' + id,
method: 'get',
... ... @@ -124,9 +130,34 @@ function bind_table_pagination() {
}
});
});
$('.btn-status').click(function() {
$.ajax({
url: '/admin/api/coupon/modify',
method: 'post',
data: {
id: $(this).attr('data-id'),
status: parseInt($(this).attr('data-status'))
},
success: function() {
window.location.reload();
}
});
});
});
};
$('.dropdown-menu li').click(function() {
let status = $(this).attr('data-status');
if (status) {
statusParam = parseInt(status);
} else {
statusParam = null;
}
$('#dropdown-toggle-txt').text($(this).text() + ' ');
fetchRender(1, 20);
});
fetchRender(1, 20);
}
... ...