优化:商品详情页面订单金额统计优化 和支付页面一致

This commit is contained in:
wuhui_zzw 2023-08-18 11:19:22 +08:00
parent 8d7c37509f
commit be017fdb7e
4 changed files with 168 additions and 40 deletions

View File

@ -2,10 +2,19 @@
namespace Beike\Shop\Http\Controllers;
use Beike\Models\Cart;
use Beike\Models\CartProduct;
use Beike\Models\Product;
use Beike\Models\ProductSku;
use Beike\Repositories\AddressRepo;
use Beike\Repositories\CartRepo;
use Beike\Repositories\PluginRepo;
use Beike\Repositories\ProductRepo;
use Beike\Services\ShippingMethodService;
use Beike\Shop\Http\Resources\ProductDetail;
use Beike\Shop\Http\Resources\ProductSimple;
use Beike\Shop\Services\CartService;
use Beike\Shop\Services\CheckoutService;
use Illuminate\Http\Request;
class ProductController extends Controller
@ -22,6 +31,7 @@ class ProductController extends Controller
$product = ProductRepo::getProductDetail($product);
$data = [
'product_id' => $product->id,
'product' => (new ProductDetail($product))->jsonSerialize(),
'relations' => ProductRepo::getProductsByIds($relationIds)->jsonSerialize(),
];
@ -56,4 +66,76 @@ class ProductController extends Controller
return view('search', $data);
}
/**
* Common: 计算当前商品订单金额信息
* Author: wu-hui
* Time: 2023/08/18 10:37
* @param Request $request
* @return array|\Illuminate\Http\JsonResponse
* @throws \Exception
*/
public function computeOrderMoney(Request $request){
// 参数获取
$list = json_decode($request->list,TRUE) ?? '';
if(!is_array($list)) return json_fail(trans('shop/products.buy_sku_error'));
// 生成模拟数据
$diyData = [];
foreach($list as $item){
$diyData[] = [
'id' => 0,
'selected' => 1,
'product_id' => $item['product_id'],
'product_sku_id' => $item['product_sku_id'],
'quantity' => $item['quantity'],
'product' => Product::where('id',40)->first()->toArray(),
'sku' => ProductSku::where('id',641)->first()->toArray(),
];
}
$cartItems = collect($diyData)->mapInto(CartProduct::class);
$cartList = CartService::cartListHandle($cartItems);
// 价格计算
$customer = current_customer();
$customerId = $customer->id ?? 0;
$sessionId = session()->getId();
$defaultAddress = AddressRepo::listByCustomer($customer)->first();
$defaultAddressId = $defaultAddress->id ?? 0;
$shippingMethod = PluginRepo::getShippingMethods()->first();
$paymentMethod = PluginRepo::getPaymentMethods()->first();
$shippingMethodCode = $shippingMethod->code ?? '';
$cart = collect([[
'customer_id' => $customerId,
'session_id' => $sessionId,
'shipping_address_id' => $defaultAddressId,
'shipping_method_code' => $shippingMethodCode ? $shippingMethodCode . '.0' : '',
'payment_address_id' => $defaultAddressId,
'payment_method_code' => $paymentMethod->code ?? '',
// "id" => 28,
// "customer_id" => 0,
// "session_id" => "Chwm3kGAY5YX4CC58yTKWREvSoplb9gFXl2UNnsb",
// "shipping_address_id" => 0,
// "guest_shipping_address" => null,
// "shipping_method_code" => "",
// "payment_address_id" => 0,
// "guest_payment_address" => null,
// "payment_method_code" => "paypal",
// "extra" => null,
// "created_at" => "2023-08-18 01:35:12",
// "updated_at" => "2023-08-18 01:35:12",
// "shipping_address" => null,
// "payment_address" => null,
]])->mapInto(Cart::class);
$cart = $cart[0];
// 计算
$checkoutService = new CheckoutService();
$totalClass = hook_filter('service.checkout.total_service','Beike\Shop\Services\TotalService');
$checkoutService->totalService = (new $totalClass($cart,$cartList));
$checkoutData = $checkoutService->checkoutData();
$totals = $checkoutData['totals'];
return json_success(trans('common.success'),$totals);
}
}

View File

@ -65,6 +65,7 @@ Route::prefix('/')
Route::get('products/search', [ProductController::class, 'search'])->name('products.search');
Route::get('products/{product}', [ProductController::class, 'show'])->name('products.show');
Route::post('products/computeOrderMoney', [ProductController::class, 'computeOrderMoney'])->name('products.computeOrderMoney');
Route::get('register', [RegisterController::class, 'index'])->name('register.index');
Route::post('register', [RegisterController::class, 'store'])->name('register.store');

View File

@ -11,7 +11,10 @@
namespace Beike\Shop\Services;
use Beike\Models\Cart;
use Beike\Models\CartProduct;
use Beike\Models\Product;
use Beike\Models\ProductSku;
use Beike\Repositories\CartRepo;
use Beike\Shop\Http\Resources\CartDetail;
use Exception;
@ -27,18 +30,22 @@ class CartService
* @param bool $selected
* @return array
*/
public static function list($customer, bool $selected = false): array
{
if (self::$cartList !== null) {
return self::$cartList;
}
public static function list($customer, bool $selected = false): array{
if (self::$cartList !== null) return self::$cartList;
$cartBuilder = CartRepo::allCartProductsBuilder($customer->id ?? 0);
if ($selected) {
$cartBuilder->where('selected', true);
}
if ($selected) $cartBuilder->where('selected', true);
$cartItems = $cartBuilder->get();
return self::cartListHandle($cartItems);
}
/**
* Common: 处理指定的购物车商品
* Author: wu-hui
* Time: 2023/08/17 17:28
* @param $cartItems
* @return mixed
*/
public static function cartListHandle($cartItems){
$cartItems = $cartItems->filter(function ($item) {
$description = $item->sku->product->description ?? '';
$product = $item->product ?? null;
@ -57,7 +64,6 @@ class CartService
return $description && $product;
});
$productQuantitySumList = [];
foreach($cartItems as $item) {
$productId = $item->product_id;
@ -206,4 +212,5 @@ class CartService
return hook_filter('service.cart.data', $data);
}
}

View File

@ -308,7 +308,7 @@
</div>
{{--价格实时计算--}}
<ul class="totals">
<li>
{{--<li>
<span>{{ __('shop/products.product_total') }}</span>
<span>@{{ product_total }}</span>
</li>
@ -319,7 +319,13 @@
<li>
<span>{{ __('shop/products.order_total') }}</span>
<span>@{{ order_tota }}</span>
</li>--}}
<li v-for="(item,index) in totals">
<span>@{{ item.title }}</span>
<span>@{{ item.amount_format }}</span>
</li>
</ul>
<button
style="width: 16em;"
@ -490,6 +496,7 @@
skus: @json($product['skus']),
variables: @json($product['variables'] ?? []),
},
product_id: "{{$product_id}}",
price_setting: @json($product['price_setting'] ?? 'sku'),
numPrices: @json($product['numPrices'] ?? []),
centerDialogVisable: false, // 设置显示框的状态
@ -519,26 +526,52 @@
},
// 多规格批量购买
add_buy_sku:{},
totals: {},// 支付金额统计
},
watch: {
quantity: function (newval, oldval) {
let price = 0;
if (this.numPrices.light == 0) {
price = this.product.price
} else {
price = this.numPrices[0].price
this.numPrices.forEach(v => {
if (this.quantity > v.num) {
}
price = v.price
})
}
let _this = this;
let list = {};
list[0] = {
product_id: _this.product_id,
product_sku_id: this.product.id,
quantity: this.quantity,
};
_this.computeOrderMoney(list);
this.product_total = (price * this.quantity).toFixed(2)
this.shipping_fee = (this.product_total * 0.1).toFixed(2)
this.order_tota = (this.product_total * 1 + this.shipping_fee * 1).toFixed(2)
// let price = 0;
// if (this.numPrices.light == 0) {
// price = this.product.price
// } else {
// price = this.numPrices[0].price
// this.numPrices.forEach(v => {
// if (this.quantity > v.num) {
// }
// price = v.price
// })
// }
//
// this.product_total = (price * this.quantity).toFixed(2)
// this.shipping_fee = (this.product_total * 0.1).toFixed(2)
// this.order_tota = (this.product_total * 1 + this.shipping_fee * 1).toFixed(2)
},
add_buy_sku: {
deep: true,//true为进行深度监听,false为不进行深度监听
handler(){
let _this = this;
let list = {};
Object.values(this.add_buy_sku).forEach((item,index) =>{
list[index] = {
product_id: _this.product_id,
product_sku_id: item.id,
quantity: item.quantity,
};
})
_this.computeOrderMoney(list);
}
}
},
created() {
if (this.price_setting === 'num') {
@ -765,29 +798,34 @@
};
});
_this.add_buy_sku[product.id] = product;
_this.$forceUpdate();
},
// 多规格 - 某个规格的购买数量改变
skuQuantityChange(event,skuIndex){
let _this = this;
_this.add_buy_sku[skuIndex].quantity = event.target.value || 0;
// // 计算金额
// let addBuySku = Object.values(_this.add_buy_sku);
// let product_total = parseInt(0),
// shipping_fee = parseInt(0),
// order_tota = parseInt(0);
// addBuySku.forEach((item,index) =>{
// product_total += parseFloat((parseFloat(item.price) * parseInt(item.quantity)).toFixed(2))
// shipping_fee += parseFloat((parseFloat(product_total) * 0.1).toFixed(2))
// order_tota += parseFloat((parseFloat(product_total) + parseFloat(shipping_fee)).toFixed(2))
// })
// _this.product_total = product_total;
// _this.shipping_fee = shipping_fee;
// _this.order_tota = order_tota;
let stock = _this.add_buy_sku[skuIndex].stock || 0;
let quantity = event.target.value || 0;
quantity = quantity > stock ? stock : quantity;// 不能超过库存
_this.add_buy_sku[skuIndex].quantity = quantity;
// 处理深度监听失败的问题
_this.add_buy_sku = Object.assign({}, _this.add_buy_sku);
_this.$forceUpdate();
}
},
// 计算当前订单总额
computeOrderMoney(list){
let _this = this;
$http.post(`products/computeOrderMoney`, {
list: JSON.stringify(list),
}).then((res) => {
if(res.status === 'success'){
_this.totals = res.data;
_this.$forceUpdate();
}
})
}
}
});