61 lines
1.9 KiB
PHP
61 lines
1.9 KiB
PHP
<?php
|
||
|
||
namespace App\Services;
|
||
|
||
/**
|
||
* 参考重量估算:订货量 × 单品规格折算(斤),仅作参考,实际称重以人工录入为准
|
||
*/
|
||
class WeightEstimator
|
||
{
|
||
/**
|
||
* 估算参考重量(斤,3 位小数)
|
||
*
|
||
* 计价单位本身是重量单位时订货量即重量;否则从规格(如「10斤/箱」「500g/袋」)
|
||
* 解析每件重量再乘订货量;规格无法解析时计 0
|
||
*/
|
||
public static function estimate(string $spec, string $unit, string $quantity): string
|
||
{
|
||
return bcmul($quantity === '' ? '0' : $quantity, self::perUnitJin($spec, $unit), 3);
|
||
}
|
||
|
||
/**
|
||
* 单个计价单位折算重量(斤)
|
||
*/
|
||
private static function perUnitJin(string $spec, string $unit): string
|
||
{
|
||
// 按重量计价的单位:订货量本身就是重量
|
||
$unitWeight = self::toJin('1', $unit);
|
||
if ($unitWeight !== null) {
|
||
return $unitWeight;
|
||
}
|
||
|
||
// 从规格解析每件重量(如「10斤/箱」「500g/袋」「1.5kg/箱」)
|
||
if (preg_match('/(\d+(?:\.\d+)?)\s*(公斤|千克|kg|克|斤|g)/iu', $spec, $matches) === 1) {
|
||
$parsed = self::toJin($matches[1], $matches[2]);
|
||
if ($parsed !== null) {
|
||
return $parsed;
|
||
}
|
||
}
|
||
|
||
// 规格中的裸数字按斤计(如「10/箱」);无法解析计 0
|
||
if (preg_match('/\d+(?:\.\d+)?/', $spec, $matches) === 1) {
|
||
return $matches[0];
|
||
}
|
||
|
||
return '0';
|
||
}
|
||
|
||
/**
|
||
* 数值按单位折算为斤;非重量单位返回 null(1斤=500g,1公斤/千克/kg=2斤)
|
||
*/
|
||
private static function toJin(string $value, string $unit): ?string
|
||
{
|
||
return match (mb_strtolower(trim($unit))) {
|
||
'斤' => $value,
|
||
'公斤', '千克', 'kg' => bcmul($value, '2', 3),
|
||
'克', 'g' => bcdiv($value, '500', 3),
|
||
default => null,
|
||
};
|
||
}
|
||
}
|