6
0
Fork 0

添加批零端购物车

release
vine_liutk 2022-02-14 14:39:32 +08:00
parent 9a119e311e
commit 4b73ad7570
7 changed files with 279 additions and 23 deletions

View File

@ -58,7 +58,53 @@ class OrderController extends Controller
$product = DealerProduct::online()->findOrFail($input['product_id']);
try {
DB::beginTransaction();
$order = $orderService->createOrder($request->user(), $product, $input['num'], $input['shipping_address_id']);
$order = $orderService->quickCreateOrder($request->user(), $product, $input['num'], $input['shipping_address_id']);
DB::commit();
} catch (BizException $e) {
DB::rollBack();
throw $e;
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('下单失败,请稍后再试');
}
return OrderResource::make($order);
}
/**
* 新下单接口
*/
public function newStore(Request $request, OrderService $orderService)
{
$isQuick = $request->filled('product');
$rules = $isQuick ? [
'product.id' => ['bail', 'required', 'int'],
'product.quantity' => ['bail', 'required', 'int', 'min:1'],
'shipping_address_id' => ['bail', 'required', 'int'],
] : [
'shopping_cart' => ['bail', 'required', 'array'],
'shipping_address_id' => ['bail', 'required', 'int'],
];
$input = $request->validate($rules, [], [
'product.id' => '商品',
'product.quantity' => '数量',
'shopping_cart' => '购物车商品',
'shipping_address_id' => '收货地址',
]);
try {
DB::beginTransaction();
if ($isQuick) {
$product = DealerProduct::online()->findOrFail($input['product']['id']);
$order = $orderService->quickCreateOrder($request->user(), $product, $input['product']['quantity'], $input['shipping_address_id']);
} else {
$order = $orderService->cartCreateOrder($request->user(), $input['shopping_cart'], $input['shipping_address_id']);
}
DB::commit();
} catch (BizException $e) {
DB::rollBack();

View File

@ -0,0 +1,101 @@
<?php
namespace App\Endpoint\Api\Http\Controllers\Dealer;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Models\DealerProduct;
use App\Services\Dealer\OrderService;
use Illuminate\Http\Request;
class ShoppingCartItemController extends Controller
{
/**
* 购物车商品列表
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function index(Request $request, OrderService $orderService)
{
$user = $request->user();
$items = $user->dealerShoppingCartItems()->latest('id')->get();
$items->load('product');
$totalQty = $items->sum('quantity');
$data = [];
foreach ($items as $item) {
$data[] = [
'id'=>$item->id,
'name' =>$item->name,
'cover'=>$item->cover,
'sell_price'=>$item->sell_price,
'dealer_price' =>$orderService->getSalePrice($user, $item->product, $totalQty),
'quantity'=>$item->quantity,
];
}
return response()->json(['data'=>$data]);
}
/**
* 加入购物车
*/
public function store(Request $request)
{
$input = $request->validate([
'product_id' => ['bail', 'required', 'int'],
'quantity' => ['bail', 'required', 'int', 'min:1'],
]);
$product = DealerProduct::online()->findOrFail($input['product_id']);
$shoppingCartItem = $request->user()->dealerShoppingCartItems()->firstOrCreate([
'product_id' => $product->id,
], [
'name' => $product->name,
'cover' => $product->cover,
'sell_price' => $product->price,
'quantity' => $input['quantity'],
]);
if (!$shoppingCartItem->wasRecentlyCreated) {
$shoppingCartItem->increment('quantity', $input['quantity']);
}
return response()->noContent();
}
/**
* 购物车变动
*/
public function update($id, Request $request)
{
$input = $request->validate([
'quantity' => ['bail', 'required', 'int', 'min:1'],
]);
$shoppingCartItem = $request->user()->dealerShoppingCartItems()->findOrFail($id);
$product = DealerProduct::online()->findOrFail($shoppingCartItem->product_id);
$shoppingCartItem->update(array_merge($input, [
'name' => $product->name,
'cover' => $product->cover,
'sell_price' => $product->price,
]));
return response()->noContent();
}
/**
* 移出购物车
*/
public function delete(Request $request)
{
$input = $request->validate([
'ids' => ['bail', 'required', 'array'],
]);
$request->user()->dealerShoppingCartItems()->whereIn('id', $input['ids'])->delete();
return response()->noContent();
}
}

View File

@ -238,12 +238,19 @@ Route::group([
Route::post('user-products/offline-out', [Dealer\UserProductController::class, 'offlineOutQty']);
Route::post('user-products/offline-out-revoke/{log}', [Dealer\UserProductController::class, 'revokeQtyLog']);
//购物车
Route::apiResource('shopping-cart-items', Dealer\ShoppingCartItemController::class)->only(
['index', 'store', 'update']
);
Route::delete('shopping-cart-items', [Dealer\ShoppingCartItemController::class, 'delete']);
//计算商品下单价格
Route::get('orders/total-amount', [Dealer\OrderController::class, 'totalAmount']);
//订单列表
Route::get('orders', [Dealer\OrderController::class, 'index']);
//下单
Route::post('orders', [Dealer\OrderController::class, 'store']);
Route::post('orders-new', [Dealer\OrderController::class, 'newStore']);
//订单详情
Route::get('orders/{order}', [Dealer\OrderController::class, 'show']);

View File

@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class DealerShoppingCartItem extends Model
{
use HasFactory;
protected $fillable = [
'product_id',
'user_id',
'name',
'cover',
'sell_price',
'quantity',
];
public function product()
{
return $this->belongsTo(DealerProduct::class, 'product_id');
}
}

View File

@ -104,6 +104,15 @@ class User extends Model implements AuthorizableContract, AuthenticatableContrac
return $this->hasMany(ShoppingCartItem::class);
}
/**
* 属于此用户的批零购物车商品
*
*/
public function dealerShoppingCartItems()
{
return $this->hasMany(DealerShoppingCartItem::class);
}
/**
* 属于此用户的收货地址
*/

View File

@ -18,13 +18,13 @@ use Illuminate\Database\QueryException;
class OrderService
{
/**
* 计算订单价格
* 获取单个商品实际价格
*
* @param User $user
* @param DealerProduct $product
* @param integer $number
* @return string
*/
public function totalAmount(User $user, DealerProduct $product, int $number = 0)
public function getSalePrice(User $user, DealerProduct $product, int $number = 0)
{
//获取等级规则,判断当前用户等级是否配置等级价格
$salePrice = $product->price;
@ -45,9 +45,19 @@ class OrderService
break;
}
}
// dd($salePrice, $number);
return $salePrice;
}
return bcmul($salePrice, $number, 2);
/**
* 计算订单价格
*
* @param DealerProduct $product
* @param integer $number
* @return string
*/
public function totalAmount(User $user, DealerProduct $product, int $number = 0)
{
return bcmul($this->getSalePrice($user, $product, $number), $number, 2);
}
/**
@ -59,7 +69,7 @@ class OrderService
* @param integer $shippingAddressId
* @return DealerOrder $order
*/
public function createOrder(User $user, DealerProduct $product, int $number = 0, int $shippingAddressId)
public function quickCreateOrder(User $user, DealerProduct $product, int $number = 0, int $shippingAddressId)
{
//判断是否满足当前等级最低补货价
$totalAmount = $this->totalAmount($user, $product, $number);
@ -69,6 +79,42 @@ class OrderService
}
}
$order = $this->createOrder($user, $totalAmount, $shippingAddressId);
//保存订单商品-----一个订单对应一个商品
$order->products()->create([
'order_id' => $order->id,
'product_id'=> $product->id,
'name'=> $product->name,
'subtitle'=> $product->subtitle,
'cover'=> $product->cover,
'price' => $product->price,
'sale_price'=> bcdiv($totalAmount, $number, 2),
'qty'=> $number,
]);
if (!$order->consignor) {//如果订单分配给公司,则直接确认
$this->confirmOrder($order);
}
return $order;
}
public function cartCreateOrder(User $user, $cartIds, int $shippingAddressId)
{
return null; //
}
/**
* 创建订单
*
* @param User $user
* @param [type] $totalAmount
* @param integer $shippingAddressId
* @return DealerOrder $order
*/
protected function createOrder(User $user, $totalAmount, int $shippingAddressId)
{
//找到发货人
$consignor = $this->getConsignor($user, $totalAmount);
@ -97,22 +143,6 @@ class OrderService
}
} while (true);
//保存订单商品-----一个订单对应一个商品
$order->products()->create([
'order_id' => $order->id,
'product_id'=> $product->id,
'name'=> $product->name,
'subtitle'=> $product->subtitle,
'cover'=> $product->cover,
'price' => $product->price,
'sale_price'=> bcdiv($totalAmount, $number, 2),
'qty'=> $number,
]);
if (!$order->consignor) {//如果订单分配给公司,则直接确认
$this->confirmOrder($order);
}
return $order;
}

View File

@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateDealerShoppingCartItemsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('dealer_shopping_cart_items', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->comment('用户ID');
$table->unsignedBigInteger('product_id')->comment('商品ID');
$table->string('name')->comment('商品名称');
$table->string('cover')->nullable()->comment('封面图');
$table->unsignedDecimal('sell_price', 10, 2)->default(0.00)->comment('销售价格:元');
$table->unsignedDecimal('dealer_price', 10, 2)->default(0.00)->comment('经销商价格:元');
$table->unsignedInteger('quantity')->default(0)->comment('购买数量');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('dealer_shopping_cart_items');
}
}