125 lines
4.1 KiB
PHP
125 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace Peidikeji\Goods;
|
|
|
|
use Peidikeji\Goods\Models\{Goods, GoodsSku};
|
|
use Illuminate\Support\Str;
|
|
|
|
class GoodsService
|
|
{
|
|
public static function make(...$params)
|
|
{
|
|
return new static(...$params);
|
|
}
|
|
|
|
public function generateSn()
|
|
{
|
|
return (string)Str::uuid();
|
|
}
|
|
|
|
public function clearSku(Goods $goods)
|
|
{
|
|
GoodsSku::where('goods_id', $goods->id)->delete();
|
|
}
|
|
|
|
/**
|
|
* 根据规格生成SKU
|
|
*
|
|
* @param Goods $goods 商品
|
|
* @param array $options {spec: 指定规格, price: 基础价格, name: 基础名称, stock: 默认库存, name_add: 是否在名称上面追加属性值, price_add: 是否在价格上面追加属性的加价, force: 是否覆盖原有的货品}
|
|
*/
|
|
public function generateSku(Goods $goods, $options = [])
|
|
{
|
|
$spec = data_get($options, 'spec', $goods->spec);
|
|
$price = data_get($options, 'price', $goods->price);
|
|
$name = data_get($options, 'name', $goods->name);
|
|
$stock = data_get($options, 'stock', $goods->stock);
|
|
$nameAdd = !!data_get($options, 'name_add', false);
|
|
$priceAdd = !!data_get($options, 'price_add', false);
|
|
$force = !!data_get($options, 'force', false);
|
|
if ($spec) {
|
|
$specList = [];
|
|
foreach ($spec as $item) {
|
|
$items = [];
|
|
foreach($item['values'] as $value) {
|
|
array_push($items, [
|
|
'name' => $item['name'],
|
|
'value' => $value['value'],
|
|
'price' => floatval($value['price']),
|
|
]);
|
|
}
|
|
array_push($specList, $items);
|
|
}
|
|
$cartesianList = $this->cartesianProduct($specList);
|
|
foreach($cartesianList as $items) {
|
|
$specPrice = $priceAdd ? $price + array_sum(array_column($items, 'price')) : $price;
|
|
$specName = $nameAdd ? $name . ' ' . implode(' ', array_column($items, 'value')) : $name;
|
|
$exists = $goods->skus()->jsonArray($items)->exists();
|
|
$attributes = [
|
|
'name' => $specName,
|
|
'price' => $specPrice,
|
|
'stock' => $stock,
|
|
'spec' => $items,
|
|
];
|
|
if ($exists) {
|
|
if ($force) {
|
|
$goods->skus()->jsonArray($items)->update($attributes);
|
|
}
|
|
} else {
|
|
$attributes['sn'] = $this->generateSn();
|
|
$goods->skus()->create($attributes);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function cartesianProduct($sets)
|
|
{
|
|
// 保存结果
|
|
$result = [];
|
|
if (count($sets) === 1) {
|
|
// 保存临时数据
|
|
$tmp = array();
|
|
// 结果与下一个集合计算笛卡尔积
|
|
foreach($sets[0] as $set) {
|
|
$item = [];
|
|
if (isset($set['value'])) {
|
|
array_push($item, $set);
|
|
} else {
|
|
$item = $set;
|
|
}
|
|
array_push($item, $set);
|
|
$tmp[] = $item;
|
|
}
|
|
// 将笛卡尔积写入结果
|
|
$result = $tmp;
|
|
return $result;
|
|
}
|
|
// 循环遍历集合数据
|
|
for($i = 0; $i < count($sets) -1 ; $i++) {
|
|
// 初始化
|
|
if($i==0){
|
|
$result = $sets[$i];
|
|
}
|
|
// 保存临时数据
|
|
$tmp = array();
|
|
// 结果与下一个集合计算笛卡尔积
|
|
foreach($result as $res) {
|
|
foreach($sets[$i+1] as $set) {
|
|
$item = [];
|
|
if (isset($res['value'])) {
|
|
array_push($item, $res);
|
|
} else {
|
|
$item = $res;
|
|
}
|
|
array_push($item, $set);
|
|
$tmp[] = $item;
|
|
}
|
|
}
|
|
// 将笛卡尔积写入结果
|
|
$result = $tmp;
|
|
}
|
|
return $result;
|
|
}
|
|
}
|