Authored by jinhu.tung

modify product size and color

... ... @@ -250,6 +250,21 @@ const index = (req, res, next) => {
}).catch(next);
};
const getProductInfo = (req, res, next) => {
const productId = req.query.productId;
const skn = req.query.skn;
let uid;
if (req.user && req.user.uid) {
uid = req.user.uid;
}
Item.getProductInfo(productId, skn, uid).then(result => {
res.json(result);
}).catch(next);
};
module.exports = {
index // 组件demo页
index, // 组件demo页
getProductInfo
};
... ...
... ... @@ -92,6 +92,21 @@ let getProductItemData = (params, url, uid) => {
});
};
/**
* 获取商品尺寸,颜色,和缩略图
* @function getProductInfo
* @param { Number } productId 商品ID
* @param { String } uid 用户ID
* @param { Number } skn 商品skn
* @return { Object } 接口返回单个商品的基本信息
*/
const getProductInfo = (productId, uid, skn) => {
return itemAPI.getProductBaseAsync(productId, uid, skn).then(result => {
return itemFUN.setProductData(result);
});
};
module.exports = {
getProductItemData
getProductItemData,
getProductInfo
};
... ...
... ... @@ -20,6 +20,7 @@ router.get('/list/new', list.newPage); // 新品列表页
router.get(/\/pro_([\d]+)_([\d]+)\/(.*)/, item.index); // 商品详情routers
router.post('/item/togglecollect', fav.product); // 商品详情页
router.get('/item/getProductInfo', item.getProductInfo); // 商品详情信息
router.get('/shop/query/all', shop.indexQuery);
router.get('/shop/:domain/list', shop.list);
... ...
... ... @@ -216,4 +216,29 @@ exports.checkStorage = (req, res) => {
});
};
// 修改购物车商品颜色和尺寸
exports.modifyProduct = (req, res) => {
const uid = req.user && req.user.uid;
const shoppingKey = req.cookies._SPK;
// swapData => [{"buy_number":"1","selected":"Y","new_product_sku":"735172","old_product_sku":"735171"}]
const swapData = req.body.swapData;
// console.log("swap data....", {swapData, shoppingKey, uid})
cartModel.modifyProduct({swapData, shoppingKey, uid}).then((result) => {
// console.log('swap result...:', JSON.stringify(result, '', 4))
if (result.code === 200) {
cartModel.getCartData(shoppingKey, uid).then(cartData => {
res.json(_.merge(
cartModel.filterCartData(cartData, uid),
{code: cartData.code, message: result.message})
);
});
} else {
res.json(result);
}
});
};
... ...
... ... @@ -456,6 +456,30 @@ const modifyProductNum = (options) => {
});
};
const modifyProduct = (options) => {
let params = {
method: 'app.Shopping.swap'
};
_.merge(params, {
swap_data: options.swapData
});
if (options.uid) {
_.merge(params, {
uid: options.uid
});
}
if (options.shoppingKey) {
_.merge(params, {
shopping_key: options.shoppingKey
});
}
return api.get('', params);
};
module.exports = {
addToCart,
getCartData,
... ... @@ -463,5 +487,6 @@ module.exports = {
toggleSelectGoods,
removeGoods,
filterCartData,
modifyProductNum
modifyProductNum,
modifyProduct
};
... ...
... ... @@ -22,6 +22,7 @@ router.get('/cart/product/:productId/edit', cartCtrl.editProduct);
router.post('/cart/add', cartCtrl.addToCart);
router.post('/cart/toggleSelectGoods', cartCtrl.toggleSelectGoods);
router.get('/cart/checkStorage', cartCtrl.checkStorage);
router.put('/cart/updateProduct', cartCtrl.modifyProduct);
// 结算
router.get('/order', auth, order.index);
... ...
... ... @@ -16,41 +16,58 @@
<div class="content">
<div class="left">
<div class="default-color mb20">
<span class="color-label mr10">Color: </span><span>\{{defaultColor}}</span>
<span class="color-label mr10">Color: </span><span class="selected-color">\{{defaultColor}}</span>
</div>
<div class="colors-list mb20">
\{{#each colors}}
\{{#isEqual ../defaultColor color}}
<span class="color-item" style="background: \{{rgb}}">
<span class="color-item current-color \{{#unless selectable}}disabled\{{/unless}}"
style="background: \{{rgb}}"
data-imageurl="\{{image pic 100 134}}"
data-target="\{{proId}}-color-\{{@index}}"
data-title="\{{color}}">
<span class="inner"></span>
</span>
\{{^}}
<span class="color-item" style="background: \{{rgb}}"></span>
<span class="color-item \{{#unless selectable}}disabled\{{/unless}}"
style="background: \{{rgb}}"
data-imageurl="\{{image pic 100 134}}"
data-target="\{{proId}}-color-\{{@index}}"
data-title="\{{color}}">
<span class="inner"></span>
</span>
\{{/isEqual}}
\{{/each}}
</div>
<div class="default-size mb20">
<span class="size-label mr10">Size: </span><span>\{{defaultSize}}</span>
</div>
\{{#each colors}}
<div class="sizes-list \{{#isEqual ../defaultColor color}}current-sizes\{{/isEqual}}" id="\{{proId}}-color-\{{@index}}" style="display: \{{#isEqual ../defaultColor color}}block\{{^}}none\{{/isEqual}};">
<div class="default-size mb20">
<span class="size-label mr10">Size: </span><span>\{{../defaultSize}}</span>
</div>
<div class="sizes-list mb10">
\{{#each sizes}}
\{{#isEqual ../../defaultSize name}}
<span class="size-item mr10 mb10 current \{{#isEqual num 0}}disabled\{{/isEqual}}"
data-sku="\{{sku}}">\{{name}}</span>
\{{^}}
<span class="size-item mr10 mb10 \{{#isEqual num 0}}disabled\{{/isEqual}}"
data-sku="\{{sku}}">\{{name}}</span>
\{{/isEqual}}
\{{/each}}
</div>
</div>
\{{/each}}
<div class="sizes-list mb10">
\{{#each sizes}}
\{{#isEqual ../defaultSize this}}
<span class="size-item mr10 mb10 current">\{{this}}</span>
\{{^}}
<span class="size-item mr10 mb10">\{{this}}</span>
\{{/isEqual}}
\{{/each}}
</div>
<div class="actions">
<span class="btn mr20" id="confirm">确定</span>
<span class="btn disable" id="cancel">取消</span>
</div>
</div>
<div class="right">
<img src="\{{image defaultImg 100 134}}" class="img-preview"/>
<img src="\{{image defaultImg 100 134}}" class="img-preview" title="\{{defaultColor}}"/>
</div>
</div>
</div>
... ...
... ... @@ -3,6 +3,7 @@ var Cart = require('./cart/cart');
var Stepper = require('./cart/stepper');
$(function() {
var $this;
// 关闭info-bar
$('.info-bar .close').on('click', function() {
... ... @@ -51,8 +52,18 @@ $(function() {
});
Cart.sendToFavorite(selectedProducts);
}).delegate('.editable', 'click', function() {
$this = $(this);
// 编辑商品颜色和属性
Cart.editColorOrSize($(this).attr('data-productId'));
Cart.editColorOrSize(
$this.attr('data-productId'),
$this.attr('data-productSkn'),
$this.find('.default-color').text(),
$this.find('.default-size').text());
$('body').on('click', function() {
$('.edit-color-size').remove();
});
}).delegate('#checkout_btn', 'click', function(e) {
e.preventDefault();
Cart.checkStorage(function() {
... ...
... ... @@ -245,62 +245,132 @@ var Cart = {
},
// 编辑商品的颜色和尺寸
editColorOrSize: function(productId) {
editColorOrSize: function(productId, skn, defaultColor, defaultSize) {
var template;
var index = 0;
var colors;
var colorsLen;
var color;
Util.ajax({
url: '/shopping/cart/product/' + productId + '/edit',
success: function(res) {
if (res.code === '0') {
// helpers start
hbs.registerHelper('multiple', function(num1, num2) {
num1 = typeof num1 === 'number' ? num1 : parseFloat(num1, 10);
num2 = typeof num2 === 'number' ? num2 : parseFloat(num2, 10);
if (num1 && num2) {
return num1 * num2;
} else {
console.error('multiplication needs two number parameters');
}
});
// 前端处理后的集合
var filterSet = [];
var defaultImg;
var editTarget = $('#edit_' + productId);
hbs.registerHelper('isEqual', function(v1, v2, options) {
if (v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});
// 选择
var selectColor;
hbs.registerHelper('showStorage', function(leftNumber) {
leftNumber = typeof num1 === 'number' ? leftNumber : parseFloat(leftNumber, 10);
// sku
var newProductSku;
var oldProductSku;
if (leftNumber <= 3 && leftNumber >= 0) {
return '仅剩' + leftNumber + '件';
} else if (leftNumber < 0) {
return '库存不足';
$.ajax({
type: 'GET',
url: '/product/item/getProductInfo',
data: {
productId: productId,
skn: skn
},
success: function(res) {
// 没有res.code
if (res.colors) {
// 获取成功
colors = res.colors;
colorsLen = colors.length;
for (index; index < colorsLen; index++) {
color = colors[index];
// 迭代每一种颜色
filterSet.push({
proId: res.id,
color: color.color,
sizes: color.sizes,
pic: color.thumbs[0],
selectable: color.total > 0,
colorName: color.name
});
if (color.color === defaultColor) {
defaultImg = color.thumbs[0];
}
});
hbs.registerHelper('image', function(url, width, height, mode) {
mode = parseInt(mode, 10) ? mode : 2;
url = url || '';
return url.replace(/{width}/g, width).replace(/{height}/g, height).replace(/{mode}/g, mode);
});
}
}
// helpers end
// helpers start
hbs.registerHelper('isEqual', function(v1, v2, options) {
if (v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});
template = hbs.compile($('#edit-color-size-tpl').html());
hbs.registerHelper('image', function(url, width, height, mode) {
mode = parseInt(mode, 10) ? mode : 2;
url = url || '';
return url.replace(/{width}/g, width).replace(/{height}/g, height).replace(/{mode}/g, mode);
});
$('#edit_' + productId).append(
template({
colors: res.colors,
sizes: res.sizes,
defaultColor: res.defaultColor,
defaultSize: res.defaultSize,
defaultImg: res.defaultImg
})
);
}
// helpers end
template = hbs.compile($('#edit-color-size-tpl').html());
editTarget.append(
template({
colors: filterSet,
defaultColor: defaultColor,
defaultSize: defaultSize,
defaultImg: defaultImg
})
);
oldProductSku = editTarget.find('.current-sizes .current').attr('data-sku');
editTarget.delegate('#confirm', 'click', function(e) {
e.preventDefault();
Util.ajax({
url: '/shopping/cart/updateProduct',
type: 'PUT',
data: {
swapData: JSON.stringify([{
buy_number: '1',
selected: 'Y',
new_product_sku: newProductSku,
old_product_sku: oldProductSku
}])
},
success: function(newCartData) {
editTarget.find('.edit-color-size').remove();
Util.refreshCart(newCartData);
}
});
return false;
}).delegate('#cancel', 'click', function(e) {
e.preventDefault();
editTarget.find('.edit-color-size').remove();
return false;
}).delegate('.edit-color-size', 'click', function(e) {
e.preventDefault();
return false;
}).delegate('.color-item', 'click', function(e) {
e.preventDefault();
selectColor = $(this);
if (!selectColor.hasClass('current-color')) {
selectColor.addClass('current-color').siblings().removeClass('current-color');
selectColor.parent().siblings('.current-sizes').hide().removeClass('current-sizes');
editTarget.find('#' + selectColor.attr('data-target')).show().addClass('current-sizes')
.end()
.find('.right img').attr({
src: selectColor.attr('data-imageurl'),
title: selectColor.attr('data-title')
})
.end()
.find('.selected-color').text(selectColor.attr('data-title'));
}
return false;
}).delegate('.current-sizes .size-item', 'click', function() {
$(this).addClass('current').siblings('.current').removeClass('current');
newProductSku = $(this).attr('data-sku');
});
},
fail: function() {
new _alert('此商品无法编辑颜色和尺寸').show();
... ...
... ... @@ -56,6 +56,11 @@ var Util = {
return options.inverse(this);
});
hbs.registerHelper('round', function(num, fixedNum) {
num = typeof num === 'number' ? num : parseFloat(num, 10);
return num.toFixed(fixedNum);
});
hbs.registerHelper('showStorage', function(leftNumber) {
leftNumber = typeof num1 === 'number' ? leftNumber : parseFloat(leftNumber, 10);
... ...
... ... @@ -41,11 +41,13 @@
color: #fff;
}
.inner {
border: 2px solid #b0b0b0;
width: 18px;
height: 18px;
display: inline-block;
.current-color {
.inner {
border: 2px solid #b0b0b0;
width: 18px;
height: 18px;
display: inline-block;
}
}
.right {
... ...