价格增加百分比上浮

This commit is contained in:
liu
2026-08-06 14:52:56 +08:00
parent 07b08c8915
commit c6f69c5c55
19 changed files with 958 additions and 93 deletions
+54
View File
@@ -8,11 +8,18 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* 商品价格模型(同一商品按客户等级定价,联合键 product_id + level_id
*
* 计价类型:固定价(price 即实际单价)或成本百分比(实际单价 = 成本价 × (100 + percent) / 100
*/
class ProductPriceModel extends Model
{
use HasFactory;
/** 计价类型:固定价 */
public const int PRICE_TYPE_FIXED = 0;
/** 计价类型:成本百分比(按成本价上浮 percent 百分点) */
public const int PRICE_TYPE_PERCENT = 1;
protected $table = 'product_price';
protected $primaryKey = 'id';
@@ -20,14 +27,21 @@ class ProductPriceModel extends Model
'product_id',
'level_id',
'price',
'price_type',
'percent',
];
protected $casts = [
'product_id' => 'integer',
'level_id' => 'integer',
'price' => 'decimal:2',
'price_type' => 'integer',
'percent' => 'decimal:2',
];
/** 序列化时附带实际销售价(后台列表/小程序列表直接展示) */
protected $appends = ['actual_price'];
/**
* 所属商品
*/
@@ -51,4 +65,44 @@ class ProductPriceModel extends Model
{
return $query->where('product_id', $productId)->where('level_id', $levelId);
}
/**
* 计算实际销售价(统一换算入口,金额走 bcmath 保证两位小数精度)
*
* 固定价返回 price 原值;成本百分比返回 cost × (100 + percent) / 100(四舍五入保留两位)。
*
* @param string|int|float $price 固定价(decimal cast 后为 '5.50' 形式字符串)
* @param string|int|float $percent 成本上浮百分点(30 = 上浮 30%)
* @param string|int|float $costPrice 商品成本价(decimal cast 字符串)
* @return string 两位小数字符串,如 '13.05'
*/
public static function calcActualPrice(
int $priceType,
string|int|float $price,
string|int|float $percent,
string|int|float $costPrice,
): string {
if ($priceType === self::PRICE_TYPE_PERCENT) {
$multiplier = bcadd('100', (string) $percent, 4);
return bcdiv(bcmul((string) $costPrice, $multiplier, 4), '100', 2);
}
// 固定价:归一化为两位小数字符串
return bcadd((string) $price, '0', 2);
}
/**
* 实际销售价访问器(供 toArray 输出 actual_price
*
* 依赖 product 关系取成本价;prices 经商品 eager load 加载时逆向关系自动填充,无 N+1。
* 注意:单独序列化本模型且未加载 product 关系时会触发一次查询,成本价缺失按 0 兜底。
*/
protected function getActualPriceAttribute(): string
{
return self::calcActualPrice(
(int) $this->price_type,
(string) $this->price,
(string) $this->percent,
(string) ($this->product?->cost_price ?? 0),
);
}
}