优化:商品详情购买处理按批购买

This commit is contained in:
wuhui_zzw 2023-09-21 13:38:08 +08:00
parent 3c62e8af7d
commit 525a6c1740
8 changed files with 115 additions and 31 deletions

View File

@ -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'];
}
}

View File

@ -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());
}

View File

@ -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),
];
}
}

View File

@ -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() ?? '',
];
}

View File

@ -33,4 +33,4 @@ $(document).ready(function ($) {
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
});
bk.getCarts(); // 页面初始加载购物车数据
bk.getCarts(); // 页面初始加载购物车数据

View File

@ -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',
];

View File

@ -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的倍数',
];

View File

@ -231,7 +231,21 @@
@endhookwrapper
<div v-if="minimum_order > 0" class="d-flex" >
<span class="title text-muted" style="width: auto!important;">{{__('product.minimum_order')}}</span> @{{ minimum_order }}
<span class="title text-muted" style="width: auto!important;">{{ __('product.sales_method') }}</span>
@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
</div>
<div class="d-flex" >
<span class="title text-muted" style="width: auto!important;">{{__('product.minimum_order')}}</span>@{{ 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
</div>
@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">
<div class="right" v-if="!isNumSelect">
@ -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();
}
}
},
}