Files
lgp-admin-plus-api/app/Service/business/PackageQuoteService.php
2026-08-19 08:16:49 +08:00

99 lines
3.3 KiB
PHP
Raw 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\Service\business;
/**
* 套餐报价与补差价
*
* 后台存倍率=1 的基准分;小程序展示/下单再乘用户倍率。
* 清单应付用「套餐价 + 当前明细合计 原价快照」,删行、换规格、加散件都落在这一条公式里。
*/
class PackageQuoteService
{
private static mixed $_instance;
public static function getInstance(): null|static
{
$name = get_called_class();
if (!isset(self::$_instance[$name])) {
self::$_instance[$name] = new static();
}
return self::$_instance[$name];
}
/**
* 后台改搭配:原价变了就把差额补到套餐报价上,不允许报负价
*/
public function applyOriginalDiff(int $oldOriginal, int $newOriginal, int $packageAmount): int
{
return max(0, $packageAmount + ($newOriginal - $oldOriginal));
}
/**
* 基准价乘用户倍率,仍回整数分
*/
public function applyMultiplier(int $cents, mixed $multiplier = 1): int
{
if ($cents <= 0) {
return 0;
}
$price = PriceService::getInstance();
$yuan = $price->centsToYuan($cents);
return $price->yuanToCents($yuan, $multiplier);
}
/**
* 套餐清单应付
*
* 未绑套餐:应付 = 当前明细合计。
* 已绑套餐:应付 = 套餐价快照 + 当前合计 原价快照(删除的套餐行会从原价里扣掉)。
*
* @param array<int, array{unit_price?:int,quantity?:int}> $items
* @return array{package_amount:int,original_amount:int,diff_amount:int,payable_amount:int,items_amount:int}
*/
public function listPayable(int $packageId, int $packageAmount, int $originalAmount, array $items): array
{
$itemsAmount = 0;
foreach ($items as $item) {
$qty = max(1, (int) ($item['quantity'] ?? 1));
$itemsAmount += (int) ($item['unit_price'] ?? 0) * $qty;
}
if ($packageId <= 0) {
return [
'package_amount' => 0,
'original_amount' => $itemsAmount,
'diff_amount' => 0,
'payable_amount' => $itemsAmount,
'items_amount' => $itemsAmount,
];
}
$payable = max(0, $packageAmount + $itemsAmount - $originalAmount);
return [
'package_amount' => $packageAmount,
'original_amount' => $originalAmount,
'diff_amount' => $payable - $packageAmount,
'payable_amount' => $payable,
'items_amount' => $itemsAmount,
];
}
/**
* 给金额数组补 *_text 元字段,方便前端直接渲染
*
* @param array<string, int> $amounts
* @return array<string, int|string>
*/
public function withText(array $amounts, bool $showPrice = true): array
{
$price = PriceService::getInstance();
foreach (['package_amount', 'original_amount', 'diff_amount', 'payable_amount', 'items_amount', 'discount_amount'] as $key) {
if (!array_key_exists($key, $amounts)) {
continue;
}
$cents = (int) $amounts[$key];
$amounts[$key . '_text'] = $showPrice ? $price->centsToYuan($cents) : PriceService::MASK;
}
return $amounts;
}
}