Files
2026-08-27 18:13:43 +08:00

84 lines
2.9 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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,
];
}
}