302 行
10 KiB
PHP
302 行
10 KiB
PHP
<?php
|
|
|
|
namespace app\admin\controller\shopro\traits;
|
|
|
|
use app\admin\model\shopro\goods\Goods as GoodsModel;
|
|
use app\admin\model\shopro\goods\Sku as SkuModel;
|
|
use app\admin\model\shopro\goods\SkuPrice as SkuPriceModel;
|
|
use addons\shopro\traits\StockWarning as StockWarningTrait;
|
|
|
|
trait SkuPrice
|
|
{
|
|
use StockWarningTrait;
|
|
|
|
/**
|
|
* 编辑规格
|
|
*
|
|
* @param GoodsModel $goods
|
|
* @param array $sku
|
|
* @param string $type
|
|
* @return void
|
|
*/
|
|
private function editSku($goods, $type = 'add')
|
|
{
|
|
if ($goods['is_sku']) {
|
|
// 多规格
|
|
$this->editMultiSku($goods, $type);
|
|
} else {
|
|
$this->editSimSku($goods, $type);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 添加编辑单规格
|
|
*
|
|
* @param GoodsModel $goods
|
|
* @param string $type
|
|
* @return void
|
|
*/
|
|
protected function editSimSku($goods, $type = 'add')
|
|
{
|
|
$params = $this->request->only([
|
|
'stock',
|
|
'stock_warning',
|
|
'sn',
|
|
'weight',
|
|
'cost_price',
|
|
'original_price',
|
|
'price'
|
|
]);
|
|
|
|
$data = [
|
|
"goods_sku_ids" => null,
|
|
"goods_sku_text" => null,
|
|
"image" => null,
|
|
"goods_id" => $goods->id,
|
|
"stock" => $params['stock'] ?? 0,
|
|
"stock_warning" => isset($params['stock_warning']) && is_numeric($params['stock_warning'])
|
|
? $params['stock_warning'] : null,
|
|
"sn" => $params['sn'] ?? "",
|
|
"weight" => isset($params['weight']) ? floatval($params['weight']) : 0,
|
|
"cost_price" => $params['cost_price'] ?? 0,
|
|
"original_price" => $params['original_price'] ?? 0,
|
|
"price" => $params['price'] ?? 0,
|
|
"status" => 'up'
|
|
];
|
|
|
|
if ($type == 'edit') {
|
|
// 查询
|
|
$skuPrice = SkuPriceModel::where('goods_id', $goods->id)->order('id', 'asc')->find();
|
|
if ($skuPrice) {
|
|
// 删除多余的这个商品的其他规格以及规格项(防止多规格改为了单规格,遗留一批多余的 sku_price)
|
|
SkuPriceModel::where('goods_id', $goods->id)->where('id', '<>', $skuPrice->id)->delete();
|
|
SkuModel::where('goods_id', $goods->id)->delete();
|
|
}
|
|
|
|
unset($data['stock']); // 移除库存(库存只能通过补货增加)
|
|
}
|
|
|
|
if (!isset($skuPrice) || !$skuPrice) {
|
|
$skuPrice = new SkuPriceModel();
|
|
}
|
|
|
|
$skuPrice->save($data);
|
|
if ($type == 'add') {
|
|
// 增加补货记录
|
|
$this->addStockLog($skuPrice, 0, $data['stock'], $type);
|
|
|
|
// 检测库存预警
|
|
$this->checkStockWarning($skuPrice, $type);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 添加编辑多规格
|
|
*
|
|
* @param GoodsModel $goods
|
|
* @param string $type
|
|
* @return void
|
|
*/
|
|
protected function editMultiSku($goods, $type = 'add')
|
|
{
|
|
$params = $this->request->only([
|
|
'skus',
|
|
'sku_prices'
|
|
]);
|
|
$skus = $params['skus'] ?? [];
|
|
$skuPrices = $params['sku_prices'] ?? [];
|
|
|
|
$this->checkMultiSku($skus, $skuPrices);
|
|
|
|
// 编辑保存规格项
|
|
$optionsMap = $this->saveSkus($goods, $skus);
|
|
|
|
if ($type == 'edit') {
|
|
// 编辑旧商品,先删除老的不用的 skuPrice
|
|
$oldSkuPriceIds = array_column($skuPrices, 'id');
|
|
// 删除当前商品老的除了在基础上修改的skuPrice
|
|
SkuPriceModel::where('goods_id', $goods->id)
|
|
->whereNotIn('id', $oldSkuPriceIds)->delete();
|
|
|
|
// 删除失效的库存预警记录
|
|
$this->delNotStockWarning($oldSkuPriceIds, $goods->id);
|
|
}
|
|
|
|
$min_price = min(array_column($skuPrices, 'price')); // 规格最小价格
|
|
$originPrices = array_filter(array_column($skuPrices, 'original_price'));
|
|
$min_original_price = $originPrices ? min($originPrices) : 0; // 规格最小划线价格
|
|
foreach ($skuPrices as $key => &$skuPrice) {
|
|
$skuPrice['goods_sku_ids'] = $this->getRealOptionIds($skuPrice['optionTempIds'], $optionsMap);
|
|
$skuPrice['goods_id'] = $goods->id;
|
|
$skuPrice['goods_sku_text'] = is_array($skuPrice['goods_sku_text']) ? join(',', $skuPrice['goods_sku_text']) : $skuPrice['goods_sku_text'];
|
|
$skuPrice['stock_warning'] = isset($skuPrice['stock_warning']) && is_numeric($skuPrice['stock_warning'])
|
|
? $skuPrice['stock_warning'] : null; // null 为关闭商品库存预警, 采用默认库存预警
|
|
|
|
// 移除无用 属性
|
|
if ($type == 'add') {
|
|
// 添加直接移除 id
|
|
unset($skuPrice['id']);
|
|
}
|
|
unset($skuPrice['optionTempIds']); // 前端临时规格 id,查找真实 id 用
|
|
unset($skuPrice['temp_id']); // 前端临时 id
|
|
unset($skuPrice['createtime'], $skuPrice['updatetime']); // 删除时间戳
|
|
|
|
$skuPriceModel = new SkuPriceModel();
|
|
if (isset($skuPrice['id']) && $skuPrice['id']) {
|
|
// type == 'edit'
|
|
unset($skuPrice['stock']); // 编辑商品 不能编辑库存,只能通过补货
|
|
$skuPriceModel = $skuPriceModel->find($skuPrice['id']);
|
|
}
|
|
|
|
if ($skuPriceModel) {
|
|
$skuPriceModel->allowField(true)->save($skuPrice);
|
|
|
|
if ($type == 'add') {
|
|
// 增加补货记录
|
|
$this->addStockLog($skuPriceModel, 0, $skuPrice['stock'], 'add'); // 记录库存记录
|
|
|
|
// 检测库存预警
|
|
$this->checkStockWarning($skuPriceModel, $type);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// 重新赋值最小价格和原价
|
|
$goods->original_price = $min_original_price; // 最小价格规格对应的原价
|
|
$goods->price = $min_price;
|
|
$goods->save();
|
|
}
|
|
|
|
|
|
/**
|
|
* 校验多规格是否填写完整
|
|
*
|
|
* @param array $skus
|
|
* @param array $skuPrices
|
|
* @return void
|
|
*/
|
|
private function checkMultiSku($skus, $skuPrices)
|
|
{
|
|
if (count($skus) < 1) {
|
|
error_stop('请填写规格列表');
|
|
}
|
|
foreach ($skus as $key => $sku) {
|
|
if (count($sku['children']) <= 0) {
|
|
error_stop('主规格至少要有一个子规格');
|
|
}
|
|
if (!isset($sku['name']) || empty(trim($sku['name']))) {
|
|
error_stop('主规格名称不能为空');
|
|
}
|
|
|
|
// 验证子规格不能为空
|
|
foreach ($sku['children'] as $k => $child) {
|
|
if (!isset($child['name']) || empty(trim($child['name']))) {
|
|
error_stop('子规格名称不能为空');
|
|
}
|
|
}
|
|
}
|
|
|
|
if (count($skuPrices) < 1) {
|
|
error_stop('请填写规格价格');
|
|
}
|
|
|
|
foreach ($skuPrices as &$price) {
|
|
// 校验多规格属性
|
|
$this->svalidate($price, '.sku_params');
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* 根据前端临时 temp_id 获取真实的数据库 id
|
|
*
|
|
* @param string $newGoodsSkuIds
|
|
* @param array $optionsMap
|
|
* @return string
|
|
*/
|
|
private function getRealOptionIds($optionTempIds, $optionsMap)
|
|
{
|
|
$newIds = [];
|
|
$ids = explode(',', $optionTempIds);
|
|
foreach ($ids as $id) {
|
|
$newIds[] = $optionsMap[$id];
|
|
}
|
|
return join(',', $newIds);
|
|
}
|
|
|
|
|
|
/**
|
|
* 差异更新 规格规格项(多的删除,少的添加)
|
|
*
|
|
* @param array $skus
|
|
* @return array
|
|
*/
|
|
private function saveSkus($goods, $skus)
|
|
{
|
|
$optionsMap = [];
|
|
$saveSkuIds = [];
|
|
// 添加主规格
|
|
foreach ($skus as &$sku) {
|
|
$skuId = isset($sku['id']) ? (int)$sku['id'] : 0;
|
|
if ($skuId > 0) {
|
|
// 更新
|
|
SkuModel::where('id', $skuId)->update([
|
|
'name' => $sku['name'],
|
|
'image' => $sku['image'] ?? null,
|
|
'parent_id' => 0,
|
|
'goods_id' => $goods->id,
|
|
'weigh' => $sku['weigh'],
|
|
]);
|
|
} else {
|
|
// 新增
|
|
$skuModel = new SkuModel();
|
|
$skuModel->save([
|
|
'name' => $sku['name'],
|
|
'image' => $sku['image'] ?? null,
|
|
'parent_id' => 0,
|
|
'goods_id' => $goods->id,
|
|
'weigh' => $sku['weigh'],
|
|
]);
|
|
$skuId = $skuModel->id;
|
|
}
|
|
$saveSkuIds[] = $skuId;
|
|
|
|
foreach ($sku['children'] as &$option) {
|
|
$optionId = isset($option['id']) ? (int)$option['id'] : 0;
|
|
if ($optionId > 0) {
|
|
// 更新
|
|
SkuModel::where('id', $optionId)->update([
|
|
'name' => $option['name'],
|
|
'image' => $option['image'] ?? null,
|
|
'weigh' => $option['weigh'],
|
|
'parent_id' => $skuId,
|
|
'goods_id' => $goods->id,
|
|
]);
|
|
} else {
|
|
// 新增
|
|
$skuModel = new SkuModel();
|
|
$skuModel->save([
|
|
'name' => $option['name'],
|
|
'image' => $option['image'] ?? null,
|
|
'weigh' => $option['weigh'],
|
|
'parent_id' => $skuId,
|
|
'goods_id' => $goods->id
|
|
]);
|
|
$optionId = $skuModel->id;
|
|
}
|
|
|
|
$optionsMap[$option['temp_id']] = $optionId;
|
|
$saveSkuIds[] = $optionId;
|
|
}
|
|
}
|
|
// 差异删除不需要的主规格
|
|
SkuModel::where('goods_id', $goods->id)->whereNotIn('id', $saveSkuIds)->delete();
|
|
|
|
return $optionsMap;
|
|
}
|
|
}
|