客户等级设置
This commit is contained in:
@@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Modules\SystemTool\Models\SysFileModel;
|
||||
|
||||
/**
|
||||
* 客户等级模型(同一商品按客户等级定价)
|
||||
* 客户等级模型(同一商品按等级上浮比例定价:售价 = 成本价 × (100 + percent) / 100)
|
||||
*/
|
||||
class CustomerLevelModel extends Model
|
||||
{
|
||||
@@ -25,12 +25,14 @@ class CustomerLevelModel extends Model
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'percent',
|
||||
'sort',
|
||||
'status',
|
||||
'icon_id'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'percent' => 'decimal:2',
|
||||
'sort' => 'integer',
|
||||
'status' => 'integer',
|
||||
'created_at' => 'datetime:Y-m-d H:i:s',
|
||||
@@ -65,10 +67,17 @@ class CustomerLevelModel extends Model
|
||||
}
|
||||
|
||||
/**
|
||||
* 该等级下的商品价格
|
||||
* 按等级上浮比例计算售价(统一换算入口,金额走 bcmath 保证两位小数精度)
|
||||
*
|
||||
* 售价 = 成本价 × (100 + percent) / 100(四舍五入保留两位)。
|
||||
*
|
||||
* @param string|int|float $costPrice 商品成本价(decimal cast 字符串)
|
||||
* @param string|int|float $percent 价格上浮比例(30 = 上浮 30%)
|
||||
* @return string 两位小数字符串,如 '13.05'
|
||||
*/
|
||||
public function prices(): HasMany
|
||||
public static function calcLevelPrice(string|int|float $costPrice, string|int|float $percent): string
|
||||
{
|
||||
return $this->hasMany(ProductPriceModel::class, 'level_id', 'id');
|
||||
$multiplier = bcadd('100', (string) $percent, 4);
|
||||
return bcdiv(bcmul((string) $costPrice, $multiplier, 4), '100', 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,11 @@ use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Modules\SystemTool\Models\SysFileModel;
|
||||
|
||||
/**
|
||||
* 商品档案模型(品名/规格包规/供应商/等级/多等级价格体系)
|
||||
* 商品档案模型(品名/规格包规/供应商/成本价;售价按客户等级上浮比例换算)
|
||||
*/
|
||||
class ProductModel extends Model
|
||||
{
|
||||
@@ -96,12 +95,4 @@ class ProductModel extends Model
|
||||
{
|
||||
return $this->belongsTo(SupplierModel::class, 'supplier_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 多等级价格(同一商品按客户等级定价)
|
||||
*/
|
||||
public function prices(): HasMany
|
||||
{
|
||||
return $this->hasMany(ProductPriceModel::class, 'product_id', 'id');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
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';
|
||||
|
||||
protected $fillable = [
|
||||
'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'];
|
||||
|
||||
/**
|
||||
* 所属商品
|
||||
*/
|
||||
public function product(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ProductModel::class, 'product_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 所属客户等级
|
||||
*/
|
||||
public function level(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CustomerLevelModel::class, 'level_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 按商品 + 等级筛选价格
|
||||
*/
|
||||
public function scopeForProductLevel($query, int $productId, int $levelId)
|
||||
{
|
||||
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),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user