211 lines
6.0 KiB
PHP
211 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace App\Traits;
|
|
|
|
use App\Models\ProductSku;
|
|
use App\Models\ProductSpu;
|
|
use Illuminate\Support\Arr;
|
|
|
|
trait SkuInfo
|
|
{
|
|
/**
|
|
* sku名称规则
|
|
*
|
|
* @param string $name
|
|
* @param array $spec
|
|
* @return void
|
|
*/
|
|
protected static function createName(string $name = '', array $spec = [])
|
|
{
|
|
return trim($name.' '.implode(' ', $spec));
|
|
}
|
|
|
|
/**
|
|
* 售价规则
|
|
*
|
|
* @param integer $price
|
|
* @param integer $specPrice
|
|
* @return void
|
|
*/
|
|
protected static function createSellPrice(float $price, float $specPrice)
|
|
{
|
|
return bcadd($price, $specPrice, 2);
|
|
}
|
|
|
|
/**
|
|
* 市场价规则
|
|
*
|
|
* @param float $price
|
|
* @param float $specPrice
|
|
* @return void
|
|
*/
|
|
protected static function createMarketPrice(float $price, float $specPrice)
|
|
{
|
|
return bcadd($price, 0, 2);
|
|
}
|
|
|
|
/**
|
|
* 成本价规则
|
|
*
|
|
* @param float $price
|
|
* @param float $specPrice
|
|
* @return void
|
|
*/
|
|
protected static function createCostPrice(float $price, float $specPrice)
|
|
{
|
|
return bcadd($price, 0, 2);
|
|
}
|
|
|
|
/**
|
|
* 会员价规则
|
|
*
|
|
* @param float|null $price
|
|
* @param float $specPrice
|
|
* @return void
|
|
*/
|
|
protected static function createVipPrice(?float $price, float $specPrice)
|
|
{
|
|
return !is_null($price) ? bcadd($price, $specPrice, 2) : null;
|
|
}
|
|
|
|
/**
|
|
* 生成规则笛卡尔积
|
|
*
|
|
* @param ProductSpu $spu
|
|
* @return array
|
|
*/
|
|
public static function specCross(ProductSpu $spu): array
|
|
{
|
|
$skuSpecs = [];
|
|
foreach ($spu->specs as $spec) {
|
|
$_items = [];
|
|
foreach ($spec->items as $item) {
|
|
$_items[] = [
|
|
'id' => $spec->id,
|
|
'name'=>$item['name'],
|
|
'price'=>$item['value'],
|
|
];
|
|
}
|
|
$skuSpecs[] = $_items;
|
|
}
|
|
//生成规格笛卡尔集
|
|
return Arr::crossJoin(...$skuSpecs);
|
|
}
|
|
|
|
/**
|
|
* 根据SPEC和spu返回 skuInfo
|
|
*
|
|
* @param [type] $skuSpec
|
|
* @param ProductSpu $spu
|
|
* @return array
|
|
*/
|
|
protected static function createInfo(array $skuSpec, ProductSpu $spu): array
|
|
{
|
|
return [
|
|
'spu_id' => $spu->id,
|
|
'name' => static::createName($spu->name, $skuSpec['specs']),
|
|
'subtitle' => $spu->subtitle,
|
|
'category_id' => $spu->category_id,
|
|
'cover' => $spu->cover,
|
|
'images' => $spu->images,
|
|
'description' => $spu->description,
|
|
'sell_price' => static::createSellPrice((float) $spu->sell_price, (float) $skuSpec['price']),
|
|
'market_price' => static::createMarketPrice((float) $spu->market_price, (float) $skuSpec['price']),
|
|
'cost_price' => static::createCostPrice((float) $spu->cost_price, (float) $skuSpec['price']),
|
|
'vip_price' => static::createVipPrice($spu->vip_price, (float) $skuSpec['price']),
|
|
'media' => $spu->media,
|
|
'weight' => $spu->weight,
|
|
'attrs' => $spu->attrs,
|
|
'specs' => $skuSpec['specs'],
|
|
'buynote_id' => $spu->buynote_id,
|
|
'shipping_template_id'=> $spu->shipping_template_id,
|
|
'verify_state' => 0, //默认为正常
|
|
];
|
|
}
|
|
|
|
public static function createBySpu(ProductSpu $spu)
|
|
{
|
|
$nowTime = now();
|
|
$insertData = [];
|
|
//根据规格笛卡尔集生成预插入数据
|
|
foreach (static::specCross($spu) as $skuSpec) {
|
|
$_skuSpecs = [];
|
|
$_price = 0;
|
|
foreach ($skuSpec as $value) {
|
|
$_skuSpecs[$value['id']] = $value['name'];
|
|
$_price += $value['price'];
|
|
}
|
|
$_data = static::createInfo([
|
|
'specs'=>$_skuSpecs,
|
|
'price'=>$_price,
|
|
], $spu, 'create');
|
|
|
|
//批量插入时特殊单独处理数据
|
|
$_data['sell_price'] = (int) bcmul($_data['sell_price'], 100);
|
|
$_data['market_price'] = (int) bcmul($_data['market_price'], 100);
|
|
$_data['cost_price'] = (int) bcmul($_data['cost_price'], 100);
|
|
$_data['vip_price'] = !is_null($_data['vip_price']) ? (int) bcmul($_data['vip_price'], 100) : null;
|
|
|
|
$_data['images'] = json_encode($_data['images']);
|
|
$_data['attrs'] = json_encode($_data['attrs']);
|
|
$_data['specs'] = json_encode($_data['specs']);
|
|
|
|
//初始化时添加额外的数据
|
|
$_data['stock'] = $spu->stock;
|
|
$_data['sales'] = $spu->sales;
|
|
$_data['created_at'] = $nowTime;
|
|
$_data['updated_at'] = $nowTime;
|
|
$insertData[] = $_data;
|
|
}
|
|
count($insertData)>0 && ProductSku::insert($insertData);
|
|
}
|
|
|
|
/**
|
|
* 根据规格生成商品
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function createBySpec(array $skuSpec, ProductSpu $spu)
|
|
{
|
|
$data = static::createInfo($skuSpec, $spu);
|
|
ProductSku::create($data);
|
|
}
|
|
|
|
/**
|
|
* 根据skuID同步主商品
|
|
*
|
|
* @param integer|null $id
|
|
* @return void
|
|
*/
|
|
public static function syncSpuById(int $id= null)
|
|
{
|
|
static::syncSpu(ProductSku::with('spu')->findOrFail($id));
|
|
}
|
|
|
|
/**
|
|
* 同步主商品
|
|
*
|
|
* @param ProductSku $sku
|
|
* @return void
|
|
*/
|
|
public static function syncSpu(ProductSku $sku)
|
|
{
|
|
$_price = 0;
|
|
foreach ($sku->specs as $id => $value) {
|
|
$spuSpec = $sku->spu->specs->first(function ($item) use ($id) {
|
|
return $item->id == $id;
|
|
});
|
|
foreach ($spuSpec->items as $item) {
|
|
if ($item['name'] == $value) {
|
|
$_price += $item['value'];
|
|
}
|
|
}
|
|
}
|
|
|
|
$sku->update(static::createInfo([
|
|
'specs'=>$sku->specs,
|
|
'price'=>$_price,
|
|
], $sku->spu));
|
|
}
|
|
}
|