84 lines
2.9 KiB
PHP
84 lines
2.9 KiB
PHP
<?php
|
||
|
||
namespace App\Services;
|
||
|
||
use App\Models\CartModel;
|
||
use App\Models\CustomerLevelModel;
|
||
use App\Models\ProductModel;
|
||
use App\Models\StoreModel;
|
||
|
||
/**
|
||
* 购物车共享服务:商品列表/详情附加购物车数量、悬浮球汇总(种数/总数量/总金额)
|
||
*
|
||
* 汇总口径(与 Mini/CartController::index 一致,勿偏离):
|
||
* - total_count = 购物车全部行数(含已下架等不可购项)
|
||
* - total_quantity / total_amount = 仅统计可购项(商品在上架且门店已设等级),
|
||
* 金额 = Σ 数量 × 等级上浮价(CustomerLevelModel::calcLevelPrice)
|
||
*/
|
||
class CartService
|
||
{
|
||
/**
|
||
* 门店购物车行映射:product_id => ['id' => 购物车行ID, 'quantity' => 数量字符串]
|
||
* (商品列表/详情附加 cart_id/cart_quantity 用;行ID供直接加减/删除操作)
|
||
*
|
||
* @return array<int, array{id: int, quantity: string}>
|
||
*/
|
||
public function cartRowMap(int $storeId): array
|
||
{
|
||
return CartModel::query()
|
||
->where('store_id', $storeId)
|
||
->get(['id', 'product_id', 'quantity'])
|
||
->keyBy('product_id')
|
||
->map(static fn (CartModel $row): array => [
|
||
'id' => (int) $row->id,
|
||
'quantity' => (string) $row->quantity,
|
||
])
|
||
->all();
|
||
}
|
||
|
||
/**
|
||
* 购物车悬浮球汇总:种数/总数量/总金额(未登录或空购物车返回零值结构)
|
||
*
|
||
* @return array{total_count: int, total_quantity: string, total_amount: string}
|
||
*/
|
||
public function summary(?StoreModel $store): array
|
||
{
|
||
$empty = ['total_count' => 0, 'total_quantity' => '0.00', 'total_amount' => '0.00'];
|
||
if ($store === null) {
|
||
return $empty;
|
||
}
|
||
|
||
$rows = CartModel::query()
|
||
->where('store_id', $store->id)
|
||
->get(['id', 'product_id', 'quantity']);
|
||
if ($rows->isEmpty()) {
|
||
return $empty;
|
||
}
|
||
|
||
$products = ProductModel::query()
|
||
->where('status', ProductModel::STATUS_ON)
|
||
->whereIn('id', $rows->pluck('product_id')->all())
|
||
->get(['id', 'cost_price'])
|
||
->keyBy('id');
|
||
$level = $store->level_id > 0 ? $store->level : null;
|
||
|
||
$totalQuantity = '0.00';
|
||
$totalAmount = '0.00';
|
||
foreach ($rows as $row) {
|
||
$product = $products->get($row->product_id);
|
||
if ($product === null || $level === null) {
|
||
continue;
|
||
}
|
||
$price = CustomerLevelModel::calcLevelPrice($product->cost_price, $level->percent);
|
||
$totalQuantity = bcadd($totalQuantity, (string) $row->quantity, 2);
|
||
$totalAmount = bcadd($totalAmount, bcmul($price, (string) $row->quantity, 2), 2);
|
||
}
|
||
|
||
return [
|
||
'total_count' => $rows->count(),
|
||
'total_quantity' => $totalQuantity,
|
||
'total_amount' => $totalAmount,
|
||
];
|
||
}
|
||
}
|