6
0
Fork 0
jiqu-library-server/app/Traits/SkuInfo.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);
}
/**
* 市场价规则
*
* @param float $price
* @param float $specPrice
* @return void
*/
protected static function createMarketPrice(float $price, float $specPrice)
{
return bcadd($price, 0);
}
/**
* 成本价规则
*
* @param float $price
* @param float $specPrice
* @return void
*/
protected static function createCostPrice(float $price, float $specPrice)
{
return bcadd($price, 0);
}
/**
* 会员价规则
*
* @param float|null $price
* @param float $specPrice
* @return void
*/
protected static function createVipPrice(?float $price, float $specPrice)
{
return !is_null($price) ? bcadd($price, $specPrice) : 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));
}
}