添加批零端购物车
parent
9a119e311e
commit
4b73ad7570
|
|
@ -58,7 +58,53 @@ class OrderController extends Controller
|
||||||
$product = DealerProduct::online()->findOrFail($input['product_id']);
|
$product = DealerProduct::online()->findOrFail($input['product_id']);
|
||||||
try {
|
try {
|
||||||
DB::beginTransaction();
|
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();
|
DB::commit();
|
||||||
} catch (BizException $e) {
|
} catch (BizException $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -238,12 +238,19 @@ Route::group([
|
||||||
Route::post('user-products/offline-out', [Dealer\UserProductController::class, 'offlineOutQty']);
|
Route::post('user-products/offline-out', [Dealer\UserProductController::class, 'offlineOutQty']);
|
||||||
Route::post('user-products/offline-out-revoke/{log}', [Dealer\UserProductController::class, 'revokeQtyLog']);
|
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/total-amount', [Dealer\OrderController::class, 'totalAmount']);
|
||||||
//订单列表
|
//订单列表
|
||||||
Route::get('orders', [Dealer\OrderController::class, 'index']);
|
Route::get('orders', [Dealer\OrderController::class, 'index']);
|
||||||
//下单
|
//下单
|
||||||
Route::post('orders', [Dealer\OrderController::class, 'store']);
|
Route::post('orders', [Dealer\OrderController::class, 'store']);
|
||||||
|
Route::post('orders-new', [Dealer\OrderController::class, 'newStore']);
|
||||||
//订单详情
|
//订单详情
|
||||||
Route::get('orders/{order}', [Dealer\OrderController::class, 'show']);
|
Route::get('orders/{order}', [Dealer\OrderController::class, 'show']);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -104,6 +104,15 @@ class User extends Model implements AuthorizableContract, AuthenticatableContrac
|
||||||
return $this->hasMany(ShoppingCartItem::class);
|
return $this->hasMany(ShoppingCartItem::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 属于此用户的批零购物车商品
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function dealerShoppingCartItems()
|
||||||
|
{
|
||||||
|
return $this->hasMany(DealerShoppingCartItem::class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 属于此用户的收货地址
|
* 属于此用户的收货地址
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,13 @@ use Illuminate\Database\QueryException;
|
||||||
class OrderService
|
class OrderService
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 计算订单价格
|
* 获取单个商品实际价格
|
||||||
*
|
*
|
||||||
|
* @param User $user
|
||||||
* @param DealerProduct $product
|
* @param DealerProduct $product
|
||||||
* @param integer $number
|
* @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;
|
$salePrice = $product->price;
|
||||||
|
|
@ -45,9 +45,19 @@ class OrderService
|
||||||
break;
|
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
|
* @param integer $shippingAddressId
|
||||||
* @return DealerOrder $order
|
* @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);
|
$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);
|
$consignor = $this->getConsignor($user, $totalAmount);
|
||||||
|
|
||||||
|
|
@ -97,22 +143,6 @@ class OrderService
|
||||||
}
|
}
|
||||||
} while (true);
|
} 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;
|
return $order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue