...
|
...
|
@@ -27,10 +27,9 @@ let $yohoPage = $('.yoho-page'), |
|
|
$choseArea,
|
|
|
$goodNum,
|
|
|
$btnMinus,
|
|
|
$btnPlus,
|
|
|
$thumbImg,
|
|
|
$choseBtnSure,
|
|
|
$noChoose,
|
|
|
$chooseInfo;
|
|
|
$choseBtnSure;
|
|
|
|
|
|
class ChosePanel {
|
|
|
constructor() {
|
...
|
...
|
@@ -50,6 +49,12 @@ class ChosePanel { |
|
|
}
|
|
|
Object.assign(this, opt);
|
|
|
|
|
|
// 数据组装
|
|
|
if (this.data) {
|
|
|
this._goodsList = this.data.goodsList || [];
|
|
|
this._sizeList = (this.data.sizeList || []).slice();
|
|
|
}
|
|
|
|
|
|
this._render();
|
|
|
return new Promise((resolve, reject) => {
|
|
|
this._resolve = resolve;
|
...
|
...
|
@@ -72,7 +77,7 @@ class ChosePanel { |
|
|
$yohoPage.append(html);
|
|
|
}
|
|
|
|
|
|
this._setVariable();
|
|
|
this._setSelector();
|
|
|
this._initBlockStatus();
|
|
|
innerScroll.disableScroll($choseArea);
|
|
|
}
|
...
|
...
|
@@ -87,38 +92,25 @@ class ChosePanel { |
|
|
*/
|
|
|
_initBlockStatus() {
|
|
|
// 获取sku列表中库存小于最小购买数量的属性,如果在其他sku中它们没有满足购买数量条件的可以灰色
|
|
|
let noStorageSkus = this.skus.filter(sku => sku.storage < this.minBuyNum);
|
|
|
|
|
|
$chosePanel.find('.thumb').attr('src', this.data.cartInfo.defaultThumb);
|
|
|
let noStorageSkus = this._sizeList.filter(sku => sku.storage_number < 1); // TODO 测试数据恢复
|
|
|
|
|
|
$('.block').removeClass('zero-stock');
|
|
|
noStorageSkus.forEach(sku => {
|
|
|
for (let propType in sku.prop) {
|
|
|
if (propType) {
|
|
|
let prop = sku.prop[propType];
|
|
|
let zeroStock = !this.skus.some(_ => _.prop[propType].valId === prop.valId &&
|
|
|
_.storage >= this.minBuyNum);
|
|
|
let $block = $(`.block[data-prop-id="${propType}"][data-value-id="${prop.valId}"]`);
|
|
|
|
|
|
if (zeroStock) {
|
|
|
noStorageSkus.forEach(item => {
|
|
|
let $block = $(`.block[data-sku='${item.product_sku}']`);
|
|
|
|
|
|
$block.addClass('zero-stock');
|
|
|
} else {
|
|
|
$block.removeClass('zero-stock');
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
});
|
|
|
}
|
|
|
|
|
|
_setVariable() {
|
|
|
_setSelector() {
|
|
|
$chosePanel = $('.chose-panel');
|
|
|
$choseArea = $('.chose-panel .main .chose-items');
|
|
|
$goodNum = $('#good-num');
|
|
|
$btnMinus = $('.btn-minus');
|
|
|
$btnPlus = $('.btn-plus');
|
|
|
$thumbImg = $('.thumb-img');
|
|
|
$choseBtnSure = $('#chose-btn-sure');
|
|
|
$noChoose = $('.not-choose');
|
|
|
$chooseInfo = $('.choosed-info');
|
|
|
$choseBtnSure = $('.btn-sure-buynow');
|
|
|
}
|
|
|
|
|
|
_regEvents() {
|
...
|
...
|
@@ -163,7 +155,7 @@ class ChosePanel { |
|
|
let $block = $(e.currentTarget);
|
|
|
|
|
|
if ($block.hasClass('chosed')) {
|
|
|
$block.removeClass('chosed');
|
|
|
return;
|
|
|
} else {
|
|
|
$block.addClass('chosed').siblings().removeClass('chosed');
|
|
|
}
|
...
|
...
|
@@ -176,20 +168,18 @@ class ChosePanel { |
|
|
_numClick(e) {
|
|
|
let buyNum;
|
|
|
|
|
|
if (this.modes.disableNum) {
|
|
|
buyNum = $(e.currentTarget).hasClass('btn-minus') ? this.data.buyNumber - 1 : this.data.buyNumber + 1;
|
|
|
if (buyNum < 1) {
|
|
|
$btnMinus.find('.operator').addClass('disabled');
|
|
|
return;
|
|
|
}
|
|
|
buyNum = $(e.currentTarget).hasClass('btn-minus') ? this.buyNum - 1 : this.buyNum + 1;
|
|
|
if (this._checkSku(buyNum)) {
|
|
|
this.buyNum = buyNum;
|
|
|
$goodNum.val(this.buyNum);
|
|
|
if (this.modes.discount) {
|
|
|
if (buyNum <= this.minBuyNum) {
|
|
|
$('.btn-minus').addClass('discount-gray');
|
|
|
} else if (buyNum === 1) {
|
|
|
$btnMinus.find('.operator').addClass('disabled');
|
|
|
} else {
|
|
|
$('.btn-minus').removeClass('discount-gray');
|
|
|
}
|
|
|
$btnMinus.find('.operator').removeClass('disabled');
|
|
|
}
|
|
|
if (this._checkSku(buyNum)) {
|
|
|
this.data.buyNumber = buyNum;
|
|
|
$goodNum.val(buyNum);
|
|
|
}
|
|
|
}
|
|
|
|
...
|
...
|
@@ -208,218 +198,82 @@ class ChosePanel { |
|
|
* 点击确定
|
|
|
*/
|
|
|
_choseBtnSureClick() {
|
|
|
// let selectSku = this._checkSku(this.buyNum);
|
|
|
//
|
|
|
// if (selectSku) {
|
|
|
// this.close();
|
|
|
// this._resolve && this._resolve({
|
|
|
// sku: selectSku,
|
|
|
// buyNum: this.buyNum,
|
|
|
// buyNow: buyNow
|
|
|
// });
|
|
|
// return false;
|
|
|
// }
|
|
|
|
|
|
// todo mock
|
|
|
this.close();
|
|
|
let skuId = this._checkSku();
|
|
|
|
|
|
if (skuId) {
|
|
|
this._resolve && this._resolve({
|
|
|
sku: {skuId: 693031},
|
|
|
buyNum: 1,
|
|
|
sku: {skuId},
|
|
|
buyNum: this.data.buy_number || 1,
|
|
|
buyNow: true
|
|
|
});
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 验证选择sku的购买数量是否通过
|
|
|
* 验证选择是否通过
|
|
|
*/
|
|
|
_checkSku(buyNum) {
|
|
|
if ($('.block.chosed.zero-stock').length) {
|
|
|
return false;
|
|
|
}
|
|
|
let validSelects = this.props
|
|
|
.filter(prop => !$(`.block[data-prop-id="${prop.type}"]`).hasClass('chosed'))
|
|
|
.map(prop => {
|
|
|
return prop.name;
|
|
|
});
|
|
|
_checkSku() {
|
|
|
let skcChosed = $('.size-row.skc').find('.block.chosed');
|
|
|
let skuChosed = $('.size-row.sku').find('.block.chosed');
|
|
|
|
|
|
if (validSelects.length) {
|
|
|
tip.show(`请选择${validSelects.join('和')}~`);
|
|
|
if (!skcChosed.length) {
|
|
|
tip.show(`请选择${ this.data._fullData.skcTitle || '颜色'}`);
|
|
|
return false;
|
|
|
}
|
|
|
let selectSku = this._getSelectSku();
|
|
|
|
|
|
if (!selectSku) {
|
|
|
tip.show('无法选择该属性的商品');
|
|
|
if (!skuChosed.length) {
|
|
|
tip.show(`请选择${ this.data._fullData.skuTitle || '尺码'}`);
|
|
|
return false;
|
|
|
}
|
|
|
if (this.modes.limit && buyNum > this.maxBuyNum) {
|
|
|
tip.show('您选择数量大于限购数量~');
|
|
|
if (skuChosed.length && skuChosed.hasClass('zero-stock')) {
|
|
|
return false;
|
|
|
}
|
|
|
if (buyNum > selectSku.storage) {
|
|
|
tip.show('您选择的数量超过了最大库存量~');
|
|
|
return false;
|
|
|
}
|
|
|
return selectSku;
|
|
|
|
|
|
let skuId = skuChosed.data('sku');
|
|
|
|
|
|
return skuId;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 选择属性
|
|
|
*/
|
|
|
_selectBlock($selectBlock) {
|
|
|
let that = this;
|
|
|
let propId = $selectBlock.data('prop-id'),
|
|
|
valueId = $selectBlock.data('value-id');
|
|
|
let chosed = $($selectBlock).hasClass('chosed');
|
|
|
let prop = $selectBlock.data('prop');
|
|
|
|
|
|
if ($('.block.chosed').length === 0) {
|
|
|
this._initBlockStatus();
|
|
|
} else {
|
|
|
// 根据选择的属性值筛选出符合条件的sku列表,然后遍历其他属性如果在sku列表中不存在该属性值,则灰色
|
|
|
let filterSkus = this.skus.filter(sku => (!chosed || sku.prop[propId].valId === valueId) &&
|
|
|
sku.storage >= this.minBuyNum);
|
|
|
let filterProps = this.props.filter(prop => prop.type !== propId);
|
|
|
|
|
|
filterProps.forEach(prop => {
|
|
|
$(`.block[data-prop-id="${prop.type}"]`).each((i, ele) => {
|
|
|
let $block = $(ele);
|
|
|
let valId = $block.data('value-id');
|
|
|
let existsSku = filterSkus.some(sku => sku.prop[prop.type].valId === valId);
|
|
|
let fsku = that.skus.filter(sku => sku.prop[propId].valId === valueId &&
|
|
|
sku.prop[prop.type].valId === valId);
|
|
|
let limitTip = '';
|
|
|
|
|
|
if (!existsSku) {
|
|
|
$block.addClass('zero-stock');
|
|
|
if (fsku.length && fsku[0].limitBuyTip) {
|
|
|
limitTip = fsku[0].limitBuyTip;
|
|
|
}
|
|
|
} else {
|
|
|
$block.removeClass('zero-stock');
|
|
|
return this._initBlockStatus();
|
|
|
}
|
|
|
|
|
|
$block.data('limittip', limitTip);
|
|
|
});
|
|
|
if (prop === 'skc') {
|
|
|
let id = $selectBlock.data('id');
|
|
|
let goods = this._goodsList.filter(item => {
|
|
|
return item.goods_id === id;
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// this._refreshBlockStatus();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 选择属性后刷新其他属性的状态
|
|
|
*/
|
|
|
_refreshBlockStatus() {
|
|
|
let selectSku = this._getSelectSku();
|
|
|
let $zeroChose = $('.block.chosed.zero-stock');
|
|
|
|
|
|
// 设置底部按钮文字
|
|
|
if ($zeroChose.length) {
|
|
|
let tipText = '已售罄';
|
|
|
|
|
|
if ($zeroChose.data('limittip')) {
|
|
|
tipText = $zeroChose.data('limittip');
|
|
|
}
|
|
|
|
|
|
$choseBtnSure.css('background-color', '#c0c0c0').text(tipText);
|
|
|
} else {
|
|
|
$choseBtnSure.css('background-color', '#eb0313').text(this.setting.buttonText.text);
|
|
|
}
|
|
|
|
|
|
// 设置默认购买数量
|
|
|
this.buyNum = this._defaultBuyNum();
|
|
|
$goodNum.val(this.buyNum);
|
|
|
if (this.modes.discount) {
|
|
|
$btnMinus.addClass('discount-gray');
|
|
|
}
|
|
|
|
|
|
// 根据颜色属性设置缩略图
|
|
|
let $colorBlock = $('.block.chosed[data-prop-id="color"]');
|
|
|
|
|
|
if ($colorBlock.length) {
|
|
|
let colorSkus = this.skus.filter(sku => sku.prop.color &&
|
|
|
sku.prop.color.valId === $colorBlock.data('value-id'));
|
|
|
|
|
|
if (colorSkus.length) {
|
|
|
let thumb = colorSkus[0].thumb;
|
|
|
|
|
|
if (!thumb) {
|
|
|
thumb = this.data.cartInfo.defaultThumb;
|
|
|
}
|
|
|
$chosePanel.find('.thumb').attr('src', thumb);
|
|
|
}
|
|
|
}
|
|
|
let frag = '';
|
|
|
|
|
|
// 设置选择属性提示
|
|
|
let valueList = Array.from($('.block.chosed').map((index, ele) => {
|
|
|
return $(ele).text();
|
|
|
}));
|
|
|
goods[0].size_list.forEach(item => {
|
|
|
frag += `<li class='block ${item.storage_number < 1 ? 'zero-stock' : ''}'
|
|
|
data-sku='${item.product_sku}' data-prop='sku'>${item.size_name}</li>`;
|
|
|
});
|
|
|
$('.size-row.sku').html(frag);
|
|
|
|
|
|
if (valueList.length) {
|
|
|
$noChoose.addClass('hide');
|
|
|
$chooseInfo.removeClass('hide');
|
|
|
$chooseInfo.text(`已选:${valueList.join('、')}`);
|
|
|
} else {
|
|
|
$noChoose.removeClass('hide');
|
|
|
$chooseInfo.addClass('hide');
|
|
|
// todo 颜色图修改
|
|
|
$goodNum.val(1);
|
|
|
this.data.buy_number = 1;
|
|
|
$choseBtnSure.css('background-color', '#d0021b').text('确定');
|
|
|
}
|
|
|
|
|
|
if (selectSku) {
|
|
|
let numText;
|
|
|
|
|
|
if (selectSku.limitNum) {
|
|
|
if (selectSku.limitNum) {
|
|
|
numText = `限购${selectSku.limitNum}件`;
|
|
|
if (prop === 'sku') {
|
|
|
if ($selectBlock.hasClass('zero-stock')) {
|
|
|
$choseBtnSure.css('background-color', '#c0c0c0').text('已售罄');
|
|
|
} else {
|
|
|
numText = '';
|
|
|
$goodNum.val(1);
|
|
|
this.data.buy_number = 1;
|
|
|
$btnMinus.find('.operator').addClass('disabled');
|
|
|
$btnPlus.find('.operator').removeClass('disabled');
|
|
|
$choseBtnSure.css('background-color', '#d0021b').text('确定');
|
|
|
}
|
|
|
} else if (this.modes.soonSoldOut) {
|
|
|
numText = '即将售罄';
|
|
|
} else if (selectSku.storage < 4 && selectSku.storage > 0) {
|
|
|
numText = `剩余${selectSku.storage}件`;
|
|
|
} else {
|
|
|
numText = '';
|
|
|
}
|
|
|
$chosePanel.find('.left-num').text(numText);
|
|
|
$chosePanel.find('.size-info').text(selectSku.sizeInfo).removeClass('hide');
|
|
|
$chosePanel.find('.size-rec').text(selectSku.sizeRec || '').removeClass('hide');
|
|
|
} else {
|
|
|
$chosePanel.find('.left-num').text('');
|
|
|
$chosePanel.find('.size-info').text('').addClass('hide');
|
|
|
$chosePanel.find('.size-rec').text('').addClass('hide');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 根据已选择的属性值获得符合条件的sku
|
|
|
*/
|
|
|
_getSelectSku() {
|
|
|
let selectValues,
|
|
|
selectSku;
|
|
|
|
|
|
if ($('.block.chosed').length !== this.props.length) {
|
|
|
return;
|
|
|
}
|
|
|
selectValues = Array.from($('.block.chosed').map((index, ele) => {
|
|
|
let $block = $(ele);
|
|
|
|
|
|
return {
|
|
|
propId: $block.data('prop-id'),
|
|
|
valueId: $block.data('value-id')
|
|
|
};
|
|
|
}));
|
|
|
selectSku = this.skus.filter(sku => {
|
|
|
return selectValues
|
|
|
.map(value => {
|
|
|
return sku.prop[value.propId].valId === value.valueId;
|
|
|
})
|
|
|
.filter(match => match).length === this.props.length;
|
|
|
});
|
|
|
if (selectSku.length >= 1) {
|
|
|
return selectSku[0];
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
...
|
...
|
|