Authored by yyq

edit

Component({
properties: {
item: {
type: Object,
value: {},
observer: '_itemChange'
},
index: {
type: Number,
value: 0
},
isEditing: {
type: Boolean,
value: false,
observer: '_editChange'
},
},
methods: {
_itemChange(item) {
if (item) {
this.selected = item.selected;
}
},
_editChange(isEdit) {
let item = {...this.data.item};
if (!isEdit && this.selected) {
item.selected = this.selected;
this.setData({item: item});
}
},
chooseBundleAction() {
let item = {...this.data.item};
if (this.data.isEditing) {
item.selected = item.selected === 'Y' ? 'N' : 'Y';
this.triggerEvent('removeGoodsListInEdit', item);
this.setData({item});
} else {
this.triggerEvent('chooseGoodsBundle', item);
}
},
editBundleNum(e) {
this.triggerEvent('editBundleNum', e.detail);
}
}
});
... ...
{
"component": true,
"usingComponents": {
"cart-edit": "/components/cart/edit/edit"
}
}
... ...
<view class="bundle-head" wx:if="{{item.pool_type === 3 && item.pool_batch_no}}">
<view class='bundle-title'>
<view class="choose-btn" bindtap="chooseBundleAction">
<text class="iconfont icon-duihao-fill" wx:if="{{item.selected === 'Y'}}"></text>
<text class="iconfont icon-round" wx:else></text>
</view>
<view class="bundle-tag">优惠套装</view>
<view class="bundle-name">{{item.pool_title}}</view>
<view class='bundle-buy-num' wx:if="{{!isEditing}}">x {{item.pool_buy_number}}</view>
</view>
<view class="edit-wrap" wx:if="{{isEditing}}">
<view class="bundle-edit-title">优惠数量</view>
<view class="bundle-edit-num">
<cart-edit goods="{{item}}" type="{{'bundle'}}" bind:editGoodsNum="editBundleNum"></cart-edit>
</view>
<view class='bundle-buy-num'>x {{item.pool_buy_number}}</view>
</view>
</view>
... ...
@import "../../../iconfont.wxss";
.bundle-title {
height: 80rpx;
line-height: 80rpx;
border-bottom: 1rpx solid #f0f0f0;
font-size: 0;
}
.bundle-title > view {
display: inline-block;
font-size: 24rpx;
}
.bundle-title .choose-btn {
width: 90rpx;
text-align: center;
}
.bundle-title .iconfont {
font-size: 40rpx;
}
.bundle-title .bundle-tag {
line-height: 1;
padding: 5rpx 7rpx;
border-radius: 4rpx;
background-color: #d0021b;
color: #fff;
margin-right: 10rpx;
}
.bundle-buy-num {
position: absolute;
right: 30rpx;
font-size: 26rpx;
color: #b0b0b0;
}
.edit-wrap {
padding: 16rpx 90rpx;
padding-right: 0;
border-bottom: 1rpx solid #f0f0f0;
font-size: 0;
margin-top: -4rpx;
background-color: #fff;
}
.edit-wrap > view {
display: inline-block;
font-size: 26rpx;
line-height: 80rpx;
vertical-align: middle;
}
.edit-wrap .bundle-edit-title {
width: 170rpx;
}
... ...
... ... @@ -17,10 +17,13 @@ Component({
}
if (this.data.type === 'bundle') {
goods.min_buy_number = 1;
goods.min_buy_number = goods.min_buy_number || 1;
goods.buy_number = goods.pool_buy_number;
goods.storage_number = goods.pool_storage_number;
} else {
if (goods.batch_no && goods.bundle_activity_id) {
goods.noNumEdit = true;
}
goods.colorSize = `颜色:${goods.factory_goods_name} 尺码:${goods.size_name}`;
}
... ... @@ -36,8 +39,50 @@ Component({
this.setData({goods});
},
itemTapped() {
this.triggerEvent('itemTapped', this.data.item);
showToast(title) {
wx.showToast({
title: title,
icon: 'none',
duration: 1000
});
},
editGoodsNum(e) {
let info = {...this.data.goods};
let increment = -1;
let buyNum;
if (e.target.dataset.type === 'plus') {
info.isAdd = true;
increment = -increment;
}
if (this.data.type === 'bundle') {
info.pool_buy_number -= -increment;
buyNum = info.pool_buy_number;
} else {
info.buy_number -= -increment;
buyNum = info.buy_number;
}
if (buyNum - info.storage_number > 0) {
return this.showToast('对不起,没有更多库存了');
} else if (buyNum - info.min_buy_number < 0) {
if (info.min_buy_number > 1) {
return this.showToast(`最低${info.min_buy_number}件起`);
}
return;
}
console.log(info);
this.triggerEvent('editGoodsNum', info);
},
editTabAction(e) {
if (this.editTimer) {
clearTimeout(this.editTimer);
}
this.editTimer = setTimeout(() => {
this.editGoodsNum(e);
}, 200);
}
}
});
... ...
<view class="goods-edit-wrap">
<view class="num-edit">
<view class="cut-btn opt-btn {{goods.cutBtnHide ? 'disable' : ''}}"></view>
<view class="num-edit" wx:if="{{!goods.noNumEdit}}">
<view class="cut-btn opt-btn {{goods.cutBtnHide ? 'disable' : ''}}" data-type="cut" bindtap="editTabAction"></view>
<view class="buy-num">
<text>{{goods.buy_number}}</text>
</view>
<view class="plus-btn opt-btn {{goods.plusBtnHide ? 'disable' : ''}}"></view>
<view class="plus-btn opt-btn {{goods.plusBtnHide ? 'disable' : ''}}" data-type="plus" bindtap="editTabAction"></view>
</view>
<view class="color-size" wx:if="{{goods.colorSize}}">
<text class="color-size-text">{{goods.colorSize}}</text>
... ...
... ... @@ -67,6 +67,7 @@
height: 70rpx;
line-height: 70rpx;
border-top: 1rpx solid #e0e0e0;
margin-top: -1rpx;
position: relative;
}
... ...
... ... @@ -13,7 +13,8 @@ Component({
},
isEditing: {
type: Boolean,
value: false
value: false,
observer: '_editChange'
},
isInvalid: {
type: Boolean,
... ... @@ -23,6 +24,7 @@ Component({
methods: {
_itemChange(item) {
if (item) {
this.selected = item.selected;
item.mark_price = item.sales_price;
switch (item.goods_type) {
... ... @@ -58,8 +60,33 @@ Component({
this.setData({item});
}
},
itemTapped() {
this.triggerEvent('itemTapped', this.data.item);
_editChange(isEdit) {
let item = {...this.data.item};
if (isEdit) {
if (item.selected === 'Y') {
this.triggerEvent('removeGoodsListInEdit', item);
}
} else if (this.selected) {
item.selected = this.selected;
this.setData({item: item});
}
},
chooseItemAction() {
let item = {...this.data.item};
if (this.data.isEditing) {
item.selected = item.selected === 'Y' ? 'N' : 'Y';
this.triggerEvent('removeGoodsListInEdit', item);
this.setData({item});
} else {
this.triggerEvent('chooseGoodsItem', item);
}
},
editGoodsNum(e) {
this.triggerEvent('editGoodsNum', e.detail);
}
}
});
... ...
<wxs src="../../../wxs/helper.wxs" module="helper" />
<view class="goods-item" bindtap="itemTapped">
<view class="choose-btn">
<view class="goods-item">
<view class="choose-btn" bindtap="chooseItemAction">
<block wx:if="{{item.goods_type !== 'gift' && !item.batch_no && !item.bundle_activity_id && !isInvalid}}">
<text class="iconfont icon-duihao-fill" wx:if="{{item.selected === 'Y'}}"></text>
<text class="iconfont icon-round" wx:else></text>
... ... @@ -44,7 +44,7 @@
</view>
<view class="info-edit" wx:if="{{isEditing}}">
<view class="edit-block">
<cart-edit goods="{{item}}"></cart-edit>
<cart-edit goods="{{item}}" bind:editGoodsNum="editGoodsNum"></cart-edit>
<view class="price">
<text class="sale-price">¥ {{helper.round(item.sales_price)}}</text>
<text wx:if="{{item.mark_price}}" class="mark-price">¥ {{helper.round(item.mark_price)}}</text>
... ...
function AllGoodsSelect() {
let index = 0;
let isSelectAll = true;
let lowStorage = false;
let goodsList = [];
this.check = function(list) {
(list || []).map(item => {
if (!item.bLackStorage && item.goods_type !== 'gift' && item.selected !== 'Y') {
goodsList.push(item);
// 购物车商品唯一key
item.indexKey = `${item.product_sku}_${index++}`;
if (item.buy_number - item.storage_number > 0 ) {
lowStorage = true;
} else if (item.goods_type !== 'gift' && item.selected !== 'Y') {
isSelectAll = false;
}
});
};
this.val = function() {
this.isSelectAll = function() {
return isSelectAll;
};
this.hasLowStorage = function() {
return lowStorage;
}
this.getAllGoodsList = function() {
return goodsList;
}
return this;
}
... ... @@ -123,7 +141,7 @@ function _processGiftList(list, isGift) {
* @param params
* @returns {*}
*/
const formatOrdinaryCartData = (data) => {
const formatOrdinaryCartData = (data, needAllGoods) => {
data = data || {};
data = data.ordinary_cart_data || {};
... ... @@ -172,7 +190,7 @@ const formatOrdinaryCartData = (data) => {
let goodsList = data.goods_list;
if (goodsList && goodsList.length) {
isEmptyCart = false;
allGoodsSelect.check(item.goods_list);
allGoodsSelect.check(goodsList);
ordinaryCart.goodsList = goodsList;
}
... ... @@ -194,8 +212,11 @@ const formatOrdinaryCartData = (data) => {
isEmptyCart = false;
}
ordinaryCart.isValidGoodsSelectAll = allGoodsSelect.val();
ordinaryCart.shoppingCartData = data.shopping_cart_data;
ordinaryCart.isSelectAll = allGoodsSelect.isSelectAll();
ordinaryCart.hasLowStorage = allGoodsSelect.hasLowStorage();
needAllGoods && (ordinaryCart.allGoodsList = allGoodsSelect.getAllGoodsList());
if (data.promotion_info && data.promotion_info.length) {
ordinaryCart.promotionInfo = data.promotion_info;
... ... @@ -208,6 +229,40 @@ console.log(ordinaryCart);
};
}
const changeGoodsListData = (list, selected, buyNum) => {
let glist = [];
if (['Y', 'N'].indexOf(selected) < 0) {
selected = false;
}
(list || []).map(item => {
if (!item.lowStorage && item.goods_type !== 'gift') {
glist.push({
buy_number: item.buy_number || 0,
goods_type: item.goods_type || '',
product_sku: item.product_sku || '',
promotion_id: item.promotion_id || 0,
selected: selected || item.selected,
activity_id: item.bundle_activity_id || 0,
batch_no: item.batch_no || 0,
});
}
});
return glist;
}
const changeGoodsBundleData = (bundle, selected, buyNum) => {
if (!bundle || !bundle.goods_list.length) {
return [];
}
return changeGoodsListData(bundle.goods_list, selected, buyNum);
}
export default {
formatOrdinaryCartData
formatOrdinaryCartData,
changeGoodsListData,
changeGoodsBundleData
};
... ...
... ... @@ -13,5 +13,70 @@ export default {
method: 'app.Shopping.queryCart'
}, params)
});
},
/**
* 选中/取消选中并查询购物车
* @param params
* @returns {*}
*/
selectAndQueryCart(params) {
return api.get({
url: '',
data: Object.assign({
method: 'app.Shopping.selectedAndQryCart',
is_support_mlp: 'Y',
shopping_key: ''
}, params)
});
},
/**
* 编辑购物车商品数量
* @param params
* @param isAdd
* @returns {*}
*/
editCartGoodsNum(params, isAdd) {
if (isAdd) {
Object.assign(params, {
method: 'app.Shopping.increase',
increase_number: 1,
shopping_key: ''
});
} else {
Object.assign(params, {
method: 'app.Shopping.decrease',
decrease_number: 1,
shopping_key: ''
});
}
return api.get({
url: '',
data: params
});
},
/**
* 编辑购物车套餐数量
* @param params
* @param isAdd
* @returns {*}
*/
editCartBundleNum(params, isAdd) {
if (isAdd) {
Object.assign(params, {
method: 'app.Shopping.incrBundle',
increase_number: 1,
});
} else {
Object.assign(params, {
method: 'app.Shopping.decrBundle',
decrease_number: 1,
});
}
return api.get({
url: '',
data: params
});
}
};
... ...
import wx from '../../utils/wx';
import cartModel from '../../models/cart/cart';
import cartHandle from '../../models/cart/cart-handle';
const app = getApp();
const router = global.router;
const reverseSelected = {
Y: 'N',
N: 'Y'
};
Page({
data: {
isEditing: false
... ... @@ -15,21 +21,207 @@ Page({
this.getCartData();
},
onHide: function () {
if (this.data.isEditing) {
this.editCartStatus({clearEditing: true});
}
},
showToast(title) {
wx.showToast({
title: title,
icon: 'none',
duration: 2000
});
},
showModal(title) {
return wx.showModal({
title: '',
content: title,
cancelText: '取消',
confirmText: '确认',
confirmColor: '#d0021b'
});
},
goShopping() {
router.go('home');
},
handleOrdinaryCartData(data) {
let resData = cartHandle.formatOrdinaryCartData(data, true);
this._allGoodsList = resData.allGoodsList;
delete resData.allGoodsList;
this.setData(resData);
return resData;
},
getCartData() {
cartModel.getCartData({uid: app.getUid()})
.then(res => {
cartModel.getCartData({uid: app.getUid()}).then(res => {
if (res.code === 200 && res.data) {
return this.handleOrdinaryCartData(res.data);
} else {
return Promise.reject();
}
}).catch(() => {});
},
editCartStatus(e) {
let isEditing = !this.data.isEditing;
if (e.clearEditing) {
isEditing = false;
}
this._removeGoodsList = {};
this.setData({isEditing});
},
editCart(list, selected, buyNum) {
list = cartHandle.changeGoodsListData(list, selected, buyNum);
if (!list.length) {
return Promise.resolve({});
}
return cartModel.selectAndQueryCart({
product_sku_list: JSON.stringify(list),
uid: app.getUid()
}).then(res => {
if (res.code === 200 && res.data) {
this.setData(cartHandle.formatOrdinaryCartData(res.data));
return this.handleOrdinaryCartData(res.data);
} else {
return Promise.reject();
}
}).catch(() => {});
},
removeCartGoods(list) {
list = cartHandle.changeGoodsListData(list);
if (!list.length) {
return Promise.resolve({});
}
return cartModel.removeAndQueryCart({
product_sku_list: JSON.stringify(list),
uid: app.getUid()
}).then(res => {
if (res && res.code === 200) {
return this.handleOrdinaryCartData(res.data);
}
});
},
chooseGoodsItem(e) {
let item = e.detail;
if (item.selected !== 'Y' && item.buy_number - item.storage_number > 0) {
return this.showToast('您勾选的商品库存不足');
}
item.selected = reverseSelected[item.selected] || 'Y';
this.editCart([item]);
},
chooseGoodsBundle(e) {
let bundle = e.detail;
if (bundle.selected !== 'Y' && bundle.pool_buy_number - bundle.pool_storage_number > 0) {
return this.showToast('您勾选的商品库存不足');
}
let selected = reverseSelected[bundle.selected] || 'Y';
this.editCart(bundle.goods_list, selected);
},
editGoodsNum(e) {
let goods = e.detail;
if (goods) {
return cartModel.editCartGoodsNum({
product_sku: goods.product_sku,
uid: app.getUid()
}, goods.isAdd).then(res => {
if (res && res.code === 200) {
this.editCart([goods], 'Y');
}
})
.catch(() => {});
}
},
editCartAction() {
this.setData({isEditing: !this.data.isEditing});
editBundleNum(e) {
let bundle = e.detail;
if (bundle) {
return cartModel.editCartBundleNum({
activity_id: bundle.pool_id,
batch_no: bundle.pool_batch_no,
uid: app.getUid()
}, bundle.isAdd).then(res => {
if (res && res.code === 200) {
this.editCart(bundle.goods_list, 'Y');
}
})
}
},
removeGoodsListInEdit(e) {
let info = e.detail;
if (info.goods_list) {
let list = info.goods_list || [];
list.map(item => {
this._removeGoodsList[item.indexKey] = info.selected === 'Y' ? item : false;
});
} else {
this._removeGoodsList[info.indexKey] = info.selected === 'Y' ? info : false;
}
},
mutilRemoveGoods() {
let removeList = [];
this._removeGoodsList = this._removeGoodsList || [];
for (let i in this._removeGoodsList) {
if (this._removeGoodsList.hasOwnProperty(i) && this._removeGoodsList[i]) {
removeList.push(this._removeGoodsList[i]);
};
}
if (!removeList.length) {
return this.showToast('请勾选您要删除的商品');
}
this.showModal('是否删除选中的全部商品?').then(res => {
if (!res.confirm) {
return;
}
return this.removeCartGoods(removeList);
});
},
cleanInvalidGoods() {
this.showModal('是否确认清空所有失效商品?').then(res => {
if (!res.confirm) {
return;
}
let invalidGoods = this.data.invalidGoodsList;
let invalidList = [];
if (invalidGoods && invalidGoods.length) {
invalidGoods.map(list => {
invalidList.push.apply(invalidList, list);
})
}
return this.removeCartGoods(invalidList);
});
},
selectAllGoods() {
let isSelectAll = this.data.isSelectAll;
if (this.data.isEditing) {
// TODO;
return;
}
this.editCart(this._allGoodsList, isSelectAll ? 'N' : 'Y').then(res => {
if (!isSelectAll && res && res.hasLowStorage) {
this.showToast('您全选的商品中存在库存不足商品,已帮您自动取消勾选成功');
}
});
}
});
... ...
... ... @@ -2,6 +2,7 @@
"navigationBarTitleText": "购物车",
"usingComponents": {
"cart-item": "/components/cart/item/item",
"cart-edit": "/components/cart/edit/edit"
"cart-edit": "/components/cart/edit/edit",
"cart-bundle-head": "/components/cart/bundle/head"
}
}
... ...
... ... @@ -24,7 +24,7 @@
<text class="iconfont icon-top" bindtap='tapPriceDownTipsAction'></text>
</view>
<view wx:else class="shipping-cost-tips">{{shippingCostTips}}</view>
<view class="edit-cart-btn" bindtap="editCartAction">{{isEditing ? '完成' : '编辑商品'}}</view>
<view class="edit-cart-btn" bindtap="editCartStatus">{{isEditing ? '完成' : '编辑商品'}}</view>
</view>
</view>
... ... @@ -58,13 +58,13 @@
<view class="footer-wrap">
<view class="footer-fixed">
<view class="select-all-btn">
<view class="select-all-btn" bindtap="selectAllGoods">
<text class="iconfont icon-duihao-fill" wx:if="{{isSelectAll}}"></text>
<text class="iconfont icon-round" wx:else></text>
<text>全选</text>
</view>
<view class="settlement-block">
<view class="delete-btn footer-option-btn" bindtap="delChoosedAction" wx:if="{{isEditing}}">
<view class="delete-btn footer-option-btn" bindtap="mutilRemoveGoods" wx:if="{{isEditing}}">
<text>删除</text>
</view>
<block wx:else>
... ...
<template name="cartGoodsList">
<block wx:if="{{goodsList.length}}">
<block wx:for="{{goodsList}}" wx:key="unique">
<cart-item item="{{item}}" index="{{index}}" isEditing="{{isEditing}}" isInvalid="{{isInvalid}}"></cart-item>
<cart-item item="{{item}}" index="{{index}}" isEditing="{{isEditing}}" isInvalid="{{isInvalid}}" bind:chooseGoodsItem="chooseGoodsItem" bind:removeGoodsListInEdit="removeGoodsListInEdit" bind:editGoodsNum="editGoodsNum"></cart-item>
</block>
</block>
</template>
... ...
... ... @@ -17,24 +17,7 @@
</block>
</block>
<view class="bundle-goods" wx:if="{{item.pool_type === 3 && item.pool_batch_no}}">
<view class='bundle-title'>
<view class="choose-btn">
<text class="iconfont icon-duihao-fill" wx:if="{{item.selected === 'Y'}}"></text>
<text class="iconfont icon-round" wx:else></text>
</view>
<view class="bundle-tag">优惠套装</view>
<view class="bundle-name">{{item.pool_title}}</view>
<view class='bundle-buy-num' wx:if="{{!isEditing}}">x {{item.pool_buy_number}}</view>
</view>
<view class="edit-wrap" wx:if="{{isEditing}}">
<view class="bundle-edit-title">优惠数量</view>
<view class="bundle-edit-num">
<cart-edit goods="{{item}}" type="{{'bundle'}}"></cart-edit>
</view>
<view class='bundle-buy-num'>x {{item.pool_buy_number}}</view>
</view>
</view>
<cart-bundle-head item="{{item}}" index="{{index}}" isEditing="{{isEditing}}" bind:chooseGoodsBundle="chooseGoodsBundle" bind:removeGoodsListInEdit="removeGoodsListInEdit" bind:editBundleNum="editBundleNum"></cart-bundle-head>
<template is="cartGoodsList" data="{{goodsList: item.goods_list, isEditing}}"/>
... ...
... ... @@ -8,39 +8,6 @@
border-bottom: 1rpx solid #f0f0f0;
}
.goods-pool-list .bundle-title {
height: 80rpx;
line-height: 80rpx;
border-bottom: 1rpx solid #f0f0f0;
font-size: 0;
}
.goods-pool-list .bundle-title > view {
display: inline-block;
font-size: 24rpx;
}
.goods-pool-list .bundle-title .choose-btn {
width: 90rpx;
text-align: center;
}
.goods-pool-list .bundle-title .bundle-tag {
line-height: 1;
padding: 5rpx 7rpx;
border-radius: 4rpx;
background-color: #d0021b;
color: #fff;
margin-right: 10rpx;
}
.goods-pool-list .bundle-goods .bundle-buy-num {
position: absolute;
right: 30rpx;
font-size: 26rpx;
color: #b0b0b0;
}
.goods-pool-list .edit-wrap {
padding: 16rpx 90rpx;
padding-right: 0;
... ...
... ... @@ -5,7 +5,7 @@
<template is="cartGoodsList" data="{{goodsList: invalidGoodsList, isInvalid: true}}"/>
<view class="clean-invalid-wrap">
<text class="clean-invalid-btn" bindtap="cleanInvalidAction">清空无效商品</text>
<text class="clean-invalid-btn" bindtap="cleanInvalidGoods">清空无效商品</text>
</view>
<view class="split-line"></view>
... ...