diff --git a/beike/Models/Product.php b/beike/Models/Product.php index bfe5faa1..dd594ccb 100644 --- a/beike/Models/Product.php +++ b/beike/Models/Product.php @@ -40,8 +40,11 @@ class Product extends Base public function getNumPricesByNum($num) { $descNumPrices = array_reverse($this->numprices->toArray()); + $multiple = 1; + if($this->sales_method == 'batches') $multiple = (int)$this->piece_to_batch; + foreach($descNumPrices as $numprice){ - if($num >= $numprice['num']){ + if($num >= ($numprice['num'] * $multiple)){ return $numprice['price']; } } diff --git a/beike/Shop/Http/Controllers/CartController.php b/beike/Shop/Http/Controllers/CartController.php index 84f323ea..9caca756 100644 --- a/beike/Shop/Http/Controllers/CartController.php +++ b/beike/Shop/Http/Controllers/CartController.php @@ -96,6 +96,7 @@ class CartController extends Controller */ public function update(CartRequest $request, $cartId): array { + // return json_fail("错误"); try { $customer = current_customer(); $quantity = (int) $request->get('quantity'); @@ -107,7 +108,6 @@ class CartController extends Controller $data = hook_filter('cart.update.data', $data); return json_success(trans('common.updated_success'), $data); - } catch (\Exception $e) { return json_fail($e->getMessage()); } diff --git a/beike/Shop/Http/Resources/NumPricesDetail.php b/beike/Shop/Http/Resources/NumPricesDetail.php index f2f884c3..8adcdc0e 100644 --- a/beike/Shop/Http/Resources/NumPricesDetail.php +++ b/beike/Shop/Http/Resources/NumPricesDetail.php @@ -13,15 +13,15 @@ namespace Beike\Shop\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; -class NumPricesDetail extends JsonResource -{ - public function toArray($request): array - { +class NumPricesDetail extends JsonResource{ + + public function toArray($request): array{ return [ 'id' => $this->id, - 'num' => $this->num, + 'num' => $this->sales_method == 'piece' ? $this->num : $this->num * $this->piece_to_batch, 'price' => $this->price, 'price_format' => currency_format($this->price), ]; + } } diff --git a/beike/Shop/Http/Resources/ProductDetail.php b/beike/Shop/Http/Resources/ProductDetail.php index 183c8f5b..e1c1970c 100644 --- a/beike/Shop/Http/Resources/ProductDetail.php +++ b/beike/Shop/Http/Resources/ProductDetail.php @@ -31,31 +31,45 @@ class ProductDetail extends JsonResource ]; } + $salesMethod = $this->sales_method ?? 'piece';// 销售方式:piece=按件卖,batches=按批卖 + $pieceToBatch = $this->piece_to_batch ?? 1;// 按批卖,每批等于多少件 + + + $this->numprices = $this->numprices->map(function($numprices) use ($salesMethod,$pieceToBatch){ + $numprices->sales_method = $salesMethod; + $numprices->piece_to_batch = $pieceToBatch; + + return $numprices; + }); + + return [ 'id' => $this->id, - 'name' => $this->description->name ?? '', - 'unit' => $this->description->unit ?? '', - 'description' => $this->description->content ?? '', - 'meta_title' => $this->description->meta_title ?? '', - 'meta_keywords' => $this->description->meta_keywords ?? '', + 'name' => $this->description->name ?? '', + 'unit' => $this->description->unit ?? '', + 'description' => $this->description->content ?? '', + 'meta_title' => $this->description->meta_title ?? '', + 'meta_keywords' => $this->description->meta_keywords ?? '', 'meta_description' => $this->description->meta_description ?? '', - 'brand_id' => $this->brand->id ?? 0, - 'brand_name' => $this->brand->name ?? '', - 'video' => $this->video ?? '', - 'images' => array_map(function ($image) { + 'brand_id' => $this->brand->id ?? 0, + 'brand_name' => $this->brand->name ?? '', + 'video' => $this->video ?? '', + 'images' => array_map(function($image){ return [ - 'preview' => image_resize($image, 500, 500), - 'popup' => image_resize($image, 800, 800), - 'thumb' => image_resize($image, 150, 150), + 'preview' => image_resize($image,500,500), + 'popup' => image_resize($image,800,800), + 'thumb' => image_resize($image,150,150), ]; - }, $this->images ?? []), + },$this->images ?? []), 'attributes' => $attributes, 'variables' => $this->decodeVariables($this->variables), 'skus' => SkuDetail::collection($this->skus)->jsonSerialize(), 'in_wishlist' => $this->inCurrentWishlist->id ?? 0, - 'active' => (bool) $this->active, + 'active' => (bool)$this->active, 'price_setting' => $this->price_setting ?? '', 'minimum_order' => $this->minimum_order ?? 0, + 'sales_method' => $this->sales_method ?? 'piece', + 'piece_to_batch' => $this->piece_to_batch ?? 1, 'numPrices' => NumPricesDetail::collection($this->numprices)->jsonSerialize() ?? '', ]; } diff --git a/resources/beike/shop/default/js/app.js b/resources/beike/shop/default/js/app.js index 9776a8b2..93ed5f01 100644 --- a/resources/beike/shop/default/js/app.js +++ b/resources/beike/shop/default/js/app.js @@ -33,4 +33,4 @@ $(document).ready(function ($) { const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl)) }); -bk.getCarts(); // 页面初始加载购物车数据 \ No newline at end of file +bk.getCarts(); // 页面初始加载购物车数据 diff --git a/resources/lang/en/product.php b/resources/lang/en/product.php index 01e74f3b..035b7434 100644 --- a/resources/lang/en/product.php +++ b/resources/lang/en/product.php @@ -37,4 +37,8 @@ return [ 'one_batch_is_equal_to' => 'one batch is equal to', 'piece' => 'piece', 'batches' => 'batches', + 'pieces_per_batch' => ':num :unit per batch', + 'sales_method_piece_unit' => 'Sell by :unit', + 'total_num' => ':num :unit in total', + 'multiple_error' => 'The purchase quantity must be a multiple of :num', ]; diff --git a/resources/lang/zh_cn/product.php b/resources/lang/zh_cn/product.php index 8bfa4fbb..b7ac2a06 100644 --- a/resources/lang/zh_cn/product.php +++ b/resources/lang/zh_cn/product.php @@ -38,4 +38,8 @@ return [ 'one_batch_is_equal_to' => '1批等于', 'piece' => '件', 'batches' => '批', + 'pieces_per_batch' => '每批:num:unit', + 'sales_method_piece_unit' => '按:unit卖', + 'total_num' => '共:num:unit', + 'multiple_error' => '采购数量必须是:num的倍数', ]; diff --git a/themes/default/product/product.blade.php b/themes/default/product/product.blade.php index bcd554a6..b6ca6f7c 100644 --- a/themes/default/product/product.blade.php +++ b/themes/default/product/product.blade.php @@ -231,7 +231,21 @@ @endhookwrapper
- {{__('product.minimum_order')}}: @{{ minimum_order }} + {{ __('product.sales_method') }}: + @if($product['sales_method'] == 'piece') + {{ __('product.sales_method_piece_unit',['unit'=>$product['unit']]) }} + @else + {{ __('product.sales_method_batches') }}({{ __('product.pieces_per_batch',['num'=>$product['piece_to_batch'],'unit'=>$product['unit']]) }}) + @endif +
+ +
+ {{__('product.minimum_order')}}:@{{ minimum_order }} + @if($product['sales_method'] == 'piece') + {{ $product['unit'] }} + @else + {{ __('product.batches') }}({{__('product.total_num',['num'=>($product['piece_to_batch'] * $product['minimum_order']),'unit'=>$product['unit']])}}) + @endif
@if(!empty($product['unit'])) @@ -329,7 +343,7 @@ class="form-control" :disabled="skuValue.stock <= skuValue.quantity" onkeyup="this.value=this.value.replace(/\D/g,'')" - v-model="add_buy_sku[skuIndex].quantity" + :value="add_buy_sku[skuIndex].quantity" @input="skuQuantityChange($event,skuIndex)" name="quantity">
@@ -604,6 +618,8 @@ price_setting: @json($product['price_setting'] ?? 'sku'), numPrices: @json($product['numPrices'] ?? []), minimum_order: @json($product['minimum_order'] ?? 0), + sales_method: @json($product['sales_method'] ?? 'piece'), + piece_to_batch: @json($product['piece_to_batch'] ?? 0), centerDialogVisable: false, // 设置显示框的状态 registerForm: { // 添加的信息 contacts: '', @@ -833,6 +849,8 @@ let _this = this; let params = {}; // 判断:当前商品如果是单规格则使用旧版本下单流程 为多规格则使用新版本下单流程 + let minimum_order_error = '{{ __('product.minimum_order_error') }}'; + let multiple_error = '{{ __('product.multiple_error') }}'; if(Object.keys(_this.source.skus).length > 1){ // 多规格 if (Object.keys(_this.add_buy_sku).length <= 0) { @@ -849,8 +867,15 @@ return; } // 判断:当前商品购买数量是否大于等于最小起订量 - if(_this.minimum_order > total){ - layer.msg('{{ __('product.minimum_order_error',['num'=>$product['minimum_order']]) }}'); + let minimum_order = _this.sales_method === 'batches' ? _this.minimum_order * _this.piece_to_batch : _this.minimum_order; + if(minimum_order > total){ + layer.msg(minimum_order_error.replace(':num',minimum_order)); + return; + } + // 判断:当前销售方式是批量销售,购买数量必须是N的倍数 + let multiple_num = _this.sales_method === 'batches' ? parseInt(_this.piece_to_batch) : 1; + if(parseInt(total % multiple_num) != 0){ + layer.msg(multiple_error.replace(':num',multiple_num)); return; } // 请求参数 @@ -866,8 +891,15 @@ return; } // 判断:当前商品购买数量是否大于等于最小起订量 - if(_this.minimum_order > _this.quantity){ - layer.msg('{{ __('product.minimum_order_error',['num'=>$product['minimum_order']]) }}'); + let minimum_order = _this.sales_method === 'batches' ? _this.minimum_order * _this.piece_to_batch : _this.minimum_order; + if(minimum_order > _this.quantity){ + layer.msg(minimum_order_error.replace(':num',minimum_order)); + return; + } + // 判断:当前销售方式是批量销售,购买数量必须是N的倍数 + let multiple_num = _this.sales_method === 'batches' ? parseInt(_this.piece_to_batch) : 1; + if(parseInt(_this.quantity % multiple_num) != 0){ + layer.msg(multiple_error.replace(':num',multiple_num)); return; } // 请求参数 @@ -880,7 +912,6 @@ // 公共参数加入 params.products_country_id = _this.country_id; params.change_logistics_id = _this.change_logistics_id; - // 提交内容 bk.addCart(params, null, () => { if (isIframe) { @@ -936,8 +967,11 @@ let _this = this; let stock = _this.add_buy_sku[skuIndex].stock || 0; let quantity = event.target.value || 0; + // 处理批量购买操作 + if(_this.sales_method === 'batches') quantity = _this.computeQuantity(quantity,_this.add_buy_sku[skuIndex].quantity); + // 判断是否超过库存 quantity = quantity > stock ? stock : quantity;// 不能超过库存 - _this.add_buy_sku[skuIndex].quantity = typeof quantity != 'number' ? quantity.replace(/\D/g,'') : quantity; + _this.add_buy_sku[skuIndex].quantity = typeof quantity != 'number' ? quantity.replace(/\D/g, '') : quantity; // 处理深度监听失败的问题 _this.add_buy_sku = Object.assign({}, _this.add_buy_sku); @@ -948,11 +982,35 @@ let _this = this; let stock = _this.product.quantity || 0;// 库存 let quantity = event.target.value || 0;// 购买数量 + // 处理批量购买操作 + if(_this.sales_method === 'batches') quantity = _this.computeQuantity(quantity,_this.quantity); + // 判断是否超过库存 quantity = quantity > stock ? stock : quantity;// 不能超过库存 _this.quantity = typeof quantity != 'number' ? quantity.replace(/\D/g,'') : quantity; _this.$forceUpdate(); }, + // 处理批量购买的增减 + computeQuantity(quantity,oldQuantity){ + let _this = this; + // 判断:当前操作是增加还是减少 + quantity = typeof quantity != 'number' ? quantity.replace(/\D/g,'') : quantity; + oldQuantity = typeof oldQuantity != 'number' ? oldQuantity.replace(/\D/g,'') : oldQuantity; + let status = oldQuantity < quantity;// 是添加还是减少:旧数量少于当前数量=添加;旧数量大于当前数量=减少 + let diff = oldQuantity - quantity;// 新旧数据之间的差距 + if(parseInt(diff) == 1 || parseInt(diff) == -1){ + // 点击操作按钮 增减1 + console.log('点击操作按钮 增减1'); + if(status) quantity = parseInt(quantity) + parseInt(_this.piece_to_batch) - parseInt(1); + else quantity = parseInt(quantity) - parseInt(_this.piece_to_batch) + parseInt(1); + }else{ + // 输入数字 增减数量不确定 + console.log('输入数字 增减数量不确定'); + + } + + return quantity; + }, // 计算当前订单总额 computeOrderMoney(){ let _this = this; @@ -988,7 +1046,8 @@ _this.change_logistics_id = info.id; _this.computeOrderMoney(); } - } + }, + }