68 lines
1.8 KiB
PHP
68 lines
1.8 KiB
PHP
<?php
|
||
|
||
namespace App\Service\business;
|
||
|
||
use App\Models\business\PriceSheetModel;
|
||
use App\Service\common\UtilsService;
|
||
|
||
/**
|
||
* 规格库存:stock=-1 表示不限,兼容历史数据全是不限。
|
||
*/
|
||
class StockService
|
||
{
|
||
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];
|
||
}
|
||
|
||
/**
|
||
* 加入清单 / 下单前校验。sheetId=0 时跳过(还没选规格)。
|
||
*/
|
||
public function assertAvailable(int $sheetId, int $quantity): void
|
||
{
|
||
if ($sheetId <= 0) {
|
||
return;
|
||
}
|
||
$sheet = PriceSheetModel::where('id', $sheetId)->where('deleted_at', 0)->first();
|
||
if (empty($sheet)) {
|
||
UtilsService::getInstance()->errorThrow('规格不存在');
|
||
}
|
||
$stock = (int) ($sheet['stock'] ?? -1);
|
||
if ($stock < 0) {
|
||
return;
|
||
}
|
||
if ($stock < $quantity) {
|
||
UtilsService::getInstance()->errorThrow('库存不足(剩余 ' . $stock . ')');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 下单成功后扣库存;不限库存不写库。
|
||
*/
|
||
public function deduct(int $sheetId, int $quantity): void
|
||
{
|
||
if ($sheetId <= 0 || $quantity <= 0) {
|
||
return;
|
||
}
|
||
$sheet = PriceSheetModel::where('id', $sheetId)->where('deleted_at', 0)->first();
|
||
if (empty($sheet)) {
|
||
return;
|
||
}
|
||
$stock = (int) ($sheet['stock'] ?? -1);
|
||
if ($stock < 0) {
|
||
return;
|
||
}
|
||
$next = max(0, $stock - $quantity);
|
||
PriceSheetModel::where('id', $sheetId)->update([
|
||
'stock' => $next,
|
||
'updated_at' => time(),
|
||
]);
|
||
}
|
||
}
|