游客结账后端部分

This commit is contained in:
TL 2023-01-05 10:04:24 +08:00
parent 94c3094c18
commit 2b8cbdf1ac
9 changed files with 168 additions and 53 deletions

View File

@ -25,7 +25,7 @@ class ShopAuthenticate extends Middleware
$this->authenticate($request, $guards);
$customer = current_customer();
if ($customer->status != 1) {
if ($customer && $customer->status != 1) {
Auth::guard(Customer::AUTH_GUARD)->logout();
return redirect(shop_route('login.index'));
}
@ -58,6 +58,9 @@ class ShopAuthenticate extends Middleware
*/
protected function unauthenticated($request, array $guards)
{
if (system_setting('base.guest_checkout', 1)) {
return;
}
throw new AuthenticationException(
trans('common.unauthenticated'), $guards, $this->redirectTo($request)
);

View File

@ -10,7 +10,7 @@ class Cart extends Base
use HasFactory;
protected $fillable = [
'customer_id', 'shipping_address_id', 'shipping_method_code', 'payment_address_id', 'payment_method_code', 'extra'
'customer_id', 'session_id', 'shipping_address_id', 'guest_shipping_address', 'shipping_method_code', 'payment_address_id', 'guest_payment_address', 'payment_method_code', 'extra'
];
public function customer(): BelongsTo

View File

@ -18,7 +18,7 @@ class CartProduct extends Base
{
use HasFactory;
protected $fillable = ['customer_id', 'selected', 'product_id', 'product_sku_id', 'quantity'];
protected $fillable = ['customer_id', 'session_id', 'selected', 'product_id', 'product_sku_id', 'quantity'];
public function sku(): BelongsTo
{

View File

@ -78,6 +78,8 @@ class AddressRepo
}
if ($customer) {
return $customer->addresses()->with('country')->get();
} else {
return collect();
}
}
}

View File

@ -31,8 +31,13 @@ class CartRepo
if (is_numeric($customer)) {
$customer = Customer::query()->find($customer);
}
$customerId = $customer->id;
$cart = Cart::query()->where('customer_id', $customerId)->first();
$customerId = $customer->id ?? 0;
$sessionId = session()->getId();
if ($customerId) {
$cart = Cart::query()->where('customer_id', $customerId)->first();
} else {
$cart = Cart::query()->where('session_id', $sessionId)->first();
}
$defaultAddress = AddressRepo::listByCustomer($customer)->first();
$defaultAddressId = $defaultAddress->id ?? 0;
@ -42,6 +47,7 @@ class CartRepo
$shippingMethodCode = $shippingMethod->code ?? '';
$cart = Cart::query()->create([
'customer_id' => $customerId,
'session_id' => $sessionId,
'shipping_address_id' => $defaultAddressId,
'shipping_method_code' => $shippingMethodCode ? $shippingMethodCode . '.0' : '',
'payment_address_id' => $defaultAddressId,
@ -58,6 +64,8 @@ class CartRepo
}
$cart->loadMissing(['shippingAddress', 'paymentAddress']);
$cart->extra = json_decode($cart->extra, true);
$cart->guest_shipping_address = json_decode($cart->guest_shipping_address, true);
$cart->guest_payment_address = json_decode($cart->guest_payment_address, true);
return $cart;
}
@ -72,8 +80,12 @@ class CartRepo
if (is_numeric($customer)) {
$customer = Customer::query()->find($customer);
}
$customerId = $customer->id;
Cart::query()->where('customer_id', $customerId)->delete();
$customerId = $customer->id ?? 0;
if ($customer) {
Cart::query()->where('customer_id', $customerId)->delete();
} else {
Cart::query()->where('session_id', session()->getId())->delete();
}
self::selectedCartProductsBuilder($customerId)->delete();
}
@ -110,9 +122,15 @@ class CartRepo
*/
public static function allCartProductsBuilder($customerId): Builder
{
return CartProduct::query()
->with(['product.description', 'sku.product.description'])
->where('customer_id', $customerId)
->orderByDesc('id');
$builder = CartProduct::query()
->with(['product.description', 'sku.product.description']);
if ($customerId) {
$builder->where('customer_id', $customerId);
} else {
$builder->where('session_id', session()->getId());
}
$builder->orderByDesc('id');
return $builder;
}
}

View File

@ -44,7 +44,7 @@ class OrderRepo
public static function getListByCustomer($customer): LengthAwarePaginator
{
$builder = self::getListBuilder(['customer' => $customer])->orderByDesc('created_at');
return $builder->paginate(perPage());
return $builder->paginate();
}
@ -69,7 +69,7 @@ class OrderRepo
public static function filterOrders(array $filters = []): LengthAwarePaginator
{
$builder = self::getListBuilder($filters)->orderByDesc('created_at');
return $builder->paginate(perPage());
return $builder->paginate();
}
@ -134,11 +134,14 @@ class OrderRepo
*/
public static function getOrderByNumber($number, $customer)
{
return Order::query()
$builder = Order::query()
->with(['orderProducts', 'orderTotals', 'orderHistories'])
->where('number', $number)
->where('customer_id', $customer->id)
->first();
->where('number', $number);
if ($customer) {
$builder->where('customer_id', $customer->id);
}
;
return $builder->first();
}
@ -175,11 +178,16 @@ class OrderRepo
$totals = $data['totals'] ?? [];
$orderTotal = collect($totals)->where('code', 'order_total')->first();
$shippingAddressId = $current['shipping_address_id'] ?? 0;
$paymentAddressId = $current['payment_address_id'] ?? 0;
if (current_customer()) {
$shippingAddressId = $current['shipping_address_id'] ?? 0;
$paymentAddressId = $current['payment_address_id'] ?? 0;
$shippingAddress = Address::query()->findOrFail($shippingAddressId);
$paymentAddress = Address::query()->findOrFail($paymentAddressId);
$shippingAddress = Address::query()->findOrFail($shippingAddressId);
$paymentAddress = Address::query()->findOrFail($paymentAddressId);
} else {
$shippingAddress = (Object)($current['guest_shipping_address'] ?? []);
$paymentAddress = (Object)($current['guest_payment_address'] ?? []);
}
$shippingMethodCode = $current['shipping_method_code'] ?? '';
$paymentMethodCode = $current['payment_method_code'] ?? '';
@ -190,12 +198,12 @@ class OrderRepo
$order = new Order([
'number' => self::generateOrderNumber(),
'customer_id' => $customer->id,
'customer_group_id' => $customer->customer_group_id,
'shipping_address_id' => $shippingAddress->id,
'payment_address_id' => $paymentAddress->id,
'customer_name' => $customer->name,
'email' => $customer->email,
'customer_id' => $customer->id ?? 0,
'customer_group_id' => $customer->customer_group_id ?? 0,
'shipping_address_id' => $shippingAddress->id ?? 0,
'payment_address_id' => $paymentAddress->id ?? 0,
'customer_name' => $customer->name ?? '',
'email' => $customer ? $customer->email : $shippingAddress->email,
'calling_code' => $customer->calling_code ?? 0,
'telephone' => $customer->telephone ?? '',
'total' => $orderTotal['amount'],
@ -211,26 +219,20 @@ class OrderRepo
'shipping_calling_code' => $shippingAddress->calling_code ?? 0,
'shipping_telephone' => $shippingAddress->phone ?? '',
'shipping_country' => $shippingAddress->country->name ?? '',
'shipping_country_id' => $shippingAddress->country->id ?? 0,
'shipping_zone' => $shippingAddress->zone,
'shipping_zone_id' => $shippingAddress->zone_id ?? 0,
'shipping_city' => $shippingAddress->city,
'shipping_address_1' => $shippingAddress->address_1,
'shipping_address_2' => $shippingAddress->address_2,
'shipping_zipcode' => $shippingAddress->zipcode,
'payment_method_code' => $paymentMethodCode,
'payment_method_name' => trans($paymentMethodCode),
'payment_customer_name' => $paymentAddress->name,
'payment_calling_code' => $paymentAddress->calling_code ?? 0,
'payment_telephone' => $paymentAddress->phone ?? '',
'payment_country' => $paymentAddress->country->name ?? '',
'payment_country_id' => $paymentAddress->country->id ?? 0,
'payment_zone' => $paymentAddress->zone,
'payment_zone_id' => $paymentAddress->zone_id ?? 0,
'payment_city' => $paymentAddress->city,
'payment_address_1' => $paymentAddress->address_1,
'payment_address_2' => $paymentAddress->address_2,
'payment_zipcode' => $paymentAddress->zipcode,
]);
$order->saveOrFail();

View File

@ -27,10 +27,7 @@ class CartService
*/
public static function list($customer, bool $selected = false): array
{
if (empty($customer)) {
return [];
}
$cartBuilder = CartRepo::allCartProductsBuilder($customer->id);
$cartBuilder = CartRepo::allCartProductsBuilder($customer->id ?? 0);
if ($selected) {
$cartBuilder->where('selected', true);
}
@ -62,9 +59,12 @@ class CartService
if (empty($sku) || $quantity == 0) {
return null;
}
$cart = CartProduct::query()
->where('customer_id', $customerId)
->where('product_id', $productId)
if ($customerId) {
$builder = CartProduct::query()->where('customer_id', $customerId);
} else {
$builder = CartProduct::query()->where('session_id', session()->getId());
}
$cart = $builder->where('product_id', $productId)
->where('product_sku_id', $skuId)
->first();
@ -74,6 +74,7 @@ class CartService
} else {
$cart = CartProduct::query()->create([
'customer_id' => $customerId,
'session_id' => session()->getId(),
'product_id' => $productId,
'product_sku_id' => $skuId,
'quantity' => $quantity,
@ -127,8 +128,13 @@ class CartService
if (empty($cartId)) {
return;
}
CartProduct::query()->where('customer_id', $customer->id)
->where('id', $cartId)
$customerId = $customer->id ?? 0;
if ($customerId) {
$builder = CartProduct::query()->where('customer_id', $customerId);
} else {
$builder = CartProduct::query()->orWhere('session_id', session()->getId());
}
$builder->where('id', $cartId)
->delete();
}

View File

@ -11,9 +11,11 @@
namespace Beike\Shop\Services;
use Beike\Models\Country;
use Beike\Models\Order;
use Beike\Models\Address;
use Beike\Models\Customer;
use Beike\Models\Zone;
use Beike\Repositories\CartRepo;
use Beike\Repositories\OrderRepo;
use Illuminate\Support\Facades\DB;
@ -41,11 +43,11 @@ class CheckoutService
if (is_int($customer) || empty($customer)) {
$this->customer = current_customer();
}
if (empty($this->customer) || !($this->customer instanceof Customer)) {
throw new \Exception(trans('shop/carts.invalid_customer'));
}
// if (empty($this->customer) || !($this->customer instanceof Customer)) {
// // throw new \Exception(trans('shop/carts.invalid_customer'));
// }
$this->cart = CartRepo::createCart($this->customer);
$this->selectedProducts = CartRepo::selectedCartProducts($this->customer->id);
$this->selectedProducts = CartRepo::selectedCartProducts($this->customer->id ?? 0);
if ($this->selectedProducts->count() == 0) {
throw new \Exception(trans('shop/carts.empty_selected_products'));
}
@ -66,6 +68,9 @@ class CheckoutService
$paymentAddressId = $requestData['payment_address_id'] ?? 0;
$paymentMethodCode = $requestData['payment_method_code'] ?? '';
$guestShippingAddress = $requestData['guest_shipping_address'] ?? [];
$guestPaymentAddress = $requestData['guest_payment_address'] ?? [];
if ($shippingAddressId) {
$this->updateShippingAddressId($shippingAddressId);
}
@ -79,6 +84,12 @@ class CheckoutService
if ($paymentMethodCode) {
$this->updatePaymentMethod($paymentMethodCode);
}
if ($guestShippingAddress) {
$this->updateGuestShippingAddress($guestShippingAddress);
}
if ($guestPaymentAddress) {
$this->updateGuestPaymentAddress($guestPaymentAddress);
}
hook_action('after_checkout_update', ['request_data' => $requestData, 'cart' => $this->cart]);
@ -137,14 +148,24 @@ class CheckoutService
{
$current = $checkoutData['current'];
$shippingAddressId = $current['shipping_address_id'];
if (empty(Address::query()->find($shippingAddressId))) {
throw new \Exception(trans('shop/carts.invalid_shipping_address'));
}
if ($this->customer) {
$shippingAddressId = $current['shipping_address_id'];
if (empty(Address::query()->find($shippingAddressId))) {
throw new \Exception(trans('shop/carts.invalid_shipping_address'));
}
$paymentAddressId = $current['payment_address_id'];
if (empty(Address::query()->find($paymentAddressId))) {
throw new \Exception(trans('shop/carts.invalid_payment_address'));
$paymentAddressId = $current['payment_address_id'];
if (empty(Address::query()->find($paymentAddressId))) {
throw new \Exception(trans('shop/carts.invalid_payment_address'));
}
} else {
if (!$current['guest_shipping_address']) {
throw new \Exception(trans('shop/carts.invalid_shipping_address'));
}
if (!$current['guest_payment_address']) {
throw new \Exception(trans('shop/carts.invalid_payment_address'));
}
}
$shippingMethodCode = $current['shipping_method_code'];
@ -171,6 +192,16 @@ class CheckoutService
$this->cart->update(['payment_address_id' => $paymentAddressId]);
}
private function updateGuestShippingAddress($guestShippingAddress)
{
$this->cart->update(['guest_shipping_address' => self::formatAddress($guestShippingAddress)]);
}
private function updateGuestPaymentAddress($guestPaymentAddress)
{
$this->cart->update(['guest_payment_address' => self::formatAddress($guestPaymentAddress)]);
}
private function updateShippingMethod($shippingMethodCode)
{
$this->cart->update(['shipping_method_code' => $shippingMethodCode]);
@ -204,8 +235,10 @@ class CheckoutService
$data = [
'current' => [
'shipping_address_id' => $currentCart->shipping_address_id,
'guest_shipping_address' => $currentCart->guest_shipping_address,
'shipping_method_code' => $currentCart->shipping_method_code,
'payment_address_id' => $currentCart->payment_address_id,
'guest_payment_address' => $currentCart->guest_payment_address,
'payment_method_code' => $currentCart->payment_method_code,
'extra' => $currentCart->extra,
],
@ -221,4 +254,14 @@ class CheckoutService
return hook_filter('checkout.data', $data);
}
static public function formatAddress($address)
{
if (!$address) {
return [];
}
$address['country'] = Country::find($address['country_id'])->name;
$address['zone'] = Zone::find($address['zone_id'])->name;
return $address;
}
}

View File

@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (Schema::hasColumn('carts', 'session_id')) {
return;
}
Schema::table('carts', function (Blueprint $table) {
$table->string('session_id')->default('')->after('customer_id');
$table->json('guest_shipping_address')->nullable()->after('shipping_address_id');
$table->json('guest_payment_address')->nullable()->after('payment_address_id');
});
Schema::table('cart_products', function (Blueprint $table) {
$table->string('session_id')->default('')->after('customer_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
if (!Schema::hasColumn('carts', 'extra')) {
return;
}
}
};