286 lines
11 KiB
PHP
286 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Goods;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Resources\GoodsSkuResource;
|
|
use App\Imports\CombinationGoodsImport;
|
|
use App\Models\BusinessOrderItem;
|
|
use App\Models\CombinationGood;
|
|
use App\Models\DeveloperConfig;
|
|
use App\Models\Goods;
|
|
use App\Models\GoodsSku;
|
|
use App\Utils\GeneratorUtils;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Maatwebsite\Excel\Facades\Excel;
|
|
|
|
class GoodsCombinationController extends Controller
|
|
{
|
|
public function index(Request $request)
|
|
{
|
|
// ToDo
|
|
$sortField = $request->input('sort_field', 'id');//stock sale_stock order_goods_num
|
|
$sortValue = $request->input('sort_value', 'desc');
|
|
$fields = implode(',', [
|
|
'shop_id',
|
|
'external_sku_id',
|
|
'SUM(goods_number) - SUM(already_cancel_number) as number',
|
|
]);
|
|
$orderRestTime = DeveloperConfig::query()
|
|
->where('key', DeveloperConfig::$ORDER_RESET_TIME)
|
|
->value('value');
|
|
if (is_null($orderRestTime)) {
|
|
$orderRestTime = date('Y-m-d 07:00:00');
|
|
}
|
|
|
|
$businessOrderItems = BusinessOrderItem::query()
|
|
->select(DB::raw($fields))
|
|
->with([
|
|
'shop:id,name',
|
|
'goodsSku:id,external_sku_id,is_combination',
|
|
'goodsSku.combinationGoods:id,goods_sku_id,item_id,item_num'
|
|
])
|
|
->where('created_at', '>', $orderRestTime)
|
|
->where('external_sku_id', '<>', '')
|
|
->groupBy(['shop_id', 'external_sku_id'])
|
|
->orderByDesc('number')
|
|
->get()
|
|
->toArray();
|
|
$ids = $externals = [];
|
|
foreach ($businessOrderItems as $businessOrderItem) {
|
|
if (is_null($businessOrderItem['goods_sku'])) {
|
|
continue;
|
|
}
|
|
$id = $businessOrderItem['goods_sku']['id'];
|
|
if (isset($ids[$id])) {
|
|
$ids[$id] += (int)$businessOrderItem['number'];
|
|
} else {
|
|
$ids[$id] = (int)$businessOrderItem['number'];
|
|
}
|
|
|
|
$externals[$id][] = $businessOrderItem;
|
|
}
|
|
arsort($ids);
|
|
|
|
// 可通过子商品查找主商品
|
|
$goodsSkusBuilder = GoodsSku::query()
|
|
->with([
|
|
'combinationGoods:id,goods_sku_id,item_id,item_num',
|
|
'combinationGoods.goodsSkuItem:id,name,goods_id,title,stock,sale_stock,external_sku_id,updated_at,yesterday_num,reference_price,status',
|
|
'combinationGoods.goodsSkuItem.goods:id,title,img_url',
|
|
])
|
|
->where('is_combination', 1)
|
|
->filter();
|
|
if ($sortField == "order_goods_num") {
|
|
$finalIds = [];
|
|
asort($ids);
|
|
foreach ($ids as $id => $number) {
|
|
$finalIds[] = $id;
|
|
}
|
|
|
|
$idField = implode(',', $finalIds);
|
|
$goodsSkusBuilder->orderByRaw("FIELD(id,{$idField}) {$sortValue}");
|
|
} else {
|
|
$goodsSkusBuilder->orderBy($sortField, $sortValue);
|
|
}
|
|
$skus = $goodsSkusBuilder
|
|
->paginate($request->get('per_page'));
|
|
foreach ($skus as &$item) {
|
|
$items = [];
|
|
if (isset($externals[$item['id']])) {
|
|
$item['order_detail'] = $externals[$item['id']];
|
|
$item['order_goods_num'] = $ids[$item['id']];
|
|
} else {
|
|
$item['order_detail'] = [];
|
|
$item['order_goods_num'] = 0;
|
|
}
|
|
|
|
$number = BusinessOrderItem::query()
|
|
->where('external_sku_id', $item['external_sku_id'])
|
|
->sum('goods_number');
|
|
$cancelNumber = BusinessOrderItem::query()
|
|
->where('external_sku_id', $item['external_sku_id'])
|
|
->sum('already_cancel_number');
|
|
$item['total_orders_num'] = $number - $cancelNumber;
|
|
foreach ($item['combinationGoods'] as $combinationItem) {
|
|
$title = !empty($combinationItem['goodsSkuItem']['name']) ? $combinationItem['goodsSkuItem']['name'] :
|
|
(!empty($combinationItem['goodsSkuItem']['goods']) ? $combinationItem['goodsSkuItem']['goods']['title']
|
|
. " " . $combinationItem['goodsSkuItem']['title'] : $combinationItem['goodsSkuItem']['title']);
|
|
$items[] = [
|
|
'cost' => 0,
|
|
'external_sku_id' => $combinationItem['goodsSkuItem']['external_sku_id'],
|
|
'goods_id' => $combinationItem['goodsSkuItem']['goods_id'],
|
|
'id' => $combinationItem['id'],
|
|
'is_combination' => 0,
|
|
'num' => $combinationItem['item_num'],
|
|
'reference_price' => $combinationItem['goodsSkuItem']['reference_price'],
|
|
'status' => $combinationItem['goodsSkuItem']['status'],
|
|
'stock' => $combinationItem['goodsSkuItem']['stock'],
|
|
'sale_stock' => $combinationItem['goodsSkuItem']['sale_stock'],
|
|
'thumb_url' => null,
|
|
'img_url' => null,//图片暂时去掉
|
|
'title' => $title,
|
|
'updated_at' => $combinationItem['goodsSkuItem']['updated_at'],
|
|
'yesterday_num' => $combinationItem['goodsSkuItem']['yesterday_num'],
|
|
'order_goods_num' => '请在商品列表查看',
|
|
'order_detail' => [],
|
|
'total_orders_num' => '不显示',
|
|
];
|
|
}
|
|
$item['children'] = $items;
|
|
unset($item['combinationGoods']);
|
|
}
|
|
$rolesName = $request->user()->getRoleNames()->toArray();
|
|
$data = ["manage" => ["is_admin" => in_array($rolesName[0]
|
|
, ["运营", "超级管理员", "管理员", "系统管理员", "店铺运营"]) ? 1 : 0]];
|
|
|
|
return GoodsSkuResource::collection($skus)->additional($data);
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$validator = Validator::make($request->all(), [
|
|
'title' => 'required',
|
|
'external_sku_id' => 'sometimes',
|
|
'combination_goods.*' => 'required',
|
|
'combination_goods.*.item_id' => 'required',
|
|
'combination_goods.*.item_num' => 'required|gt:0',
|
|
]);
|
|
if ($validator->fails()) {
|
|
$this->setValidatorFailResponse($validator->getMessageBag()->getMessages());
|
|
|
|
return response($this->res, $this->res['httpCode']);
|
|
}
|
|
$externalSkuId = $request->input('external_sku_id') ??
|
|
GeneratorUtils::generateCombinationGoodNumber($request->combination_goods);
|
|
$hasCodeSku = GoodsSku::query()->where("external_sku_id", $externalSkuId)->first();
|
|
if (!empty($hasCodeSku) && $hasCodeSku->id != $request->input('id')) {
|
|
throw new \Exception("该组合商品编码已存在");
|
|
}
|
|
DB::beginTransaction();
|
|
try {
|
|
$combinationGoods = $request->input('combination_goods');
|
|
$itemIds = array_column($combinationGoods, 'item_id');
|
|
$skus = GoodsSku::query()
|
|
->whereIn('id', $itemIds)
|
|
->get()
|
|
->pluck(null, 'id')
|
|
->toArray();
|
|
$stock = [];
|
|
$saleStock = [];
|
|
foreach ($combinationGoods as $item) {
|
|
if (!empty($skus[$item['item_id']])) {
|
|
$stock[] = (int)($skus[$item['item_id']]['stock'] / $item['item_num']);
|
|
$saleStock[] = (int)($skus[$item['item_id']]['sale_stock'] / $item['item_num']);
|
|
}
|
|
}
|
|
$stock = min($stock);
|
|
$saleStock = min($saleStock);
|
|
|
|
$status = $saleStock ? (5 < $saleStock ? 1 : 2) : 0;
|
|
if ($id = $request->input('id')) {
|
|
$sku = GoodsSku::query()->findOrFail($id);
|
|
} else {
|
|
$sku = new GoodsSku();
|
|
$sku->goods_id = 0;
|
|
$sku->is_combination = 1;
|
|
}
|
|
|
|
|
|
$sku->status = $status;
|
|
$sku->title = $request->input('title');
|
|
$sku->name = $request->input('title');
|
|
$sku->sku_code = $externalSkuId;
|
|
$sku->external_sku_id = $externalSkuId;
|
|
$sku->stock = $stock;
|
|
$sku->sale_stock = $saleStock;
|
|
$sku->save();
|
|
CombinationGood::query()
|
|
->where('goods_sku_id', $sku->id)
|
|
->delete();
|
|
foreach ($combinationGoods as $item) {
|
|
CombinationGood::query()->create(['goods_sku_id' => $sku->id, 'item_id' => $item['item_id'], 'item_num' => $item['item_num']]);
|
|
}
|
|
DB::commit();
|
|
} catch (\Exception $exception) {
|
|
DB::rollBack();
|
|
$this->res = [
|
|
'httpCode' => 400,
|
|
'errorCode' => 400500,
|
|
'errorMessage' => $exception->getMessage(),
|
|
];
|
|
}
|
|
|
|
return response($this->res, $this->res['httpCode']);
|
|
}
|
|
|
|
public function show(Request $request, $id)
|
|
{
|
|
$sku = GoodsSku::query()
|
|
->with([
|
|
'combinationGoods:id,goods_sku_id,item_id,item_num',
|
|
'combinationGoods.goodsSkuItem:id,title,goods_id',
|
|
'combinationGoods.goodsSkuItem.goods:id,title',
|
|
])
|
|
->findOrFail($id);
|
|
$items = [];
|
|
foreach ($sku['combinationGoods'] as $item) {
|
|
$items[] = [
|
|
'id' => $item['goodsSkuItem']['id'],
|
|
'title' => $item['goodsSkuItem']['goods']['title'] . $item['goodsSkuItem']['title'],
|
|
];
|
|
}
|
|
$sku['skus'] = $items;
|
|
|
|
return new GoodsSkuResource($sku);
|
|
}
|
|
|
|
public function destroy(Request $request, $id)
|
|
{
|
|
|
|
}
|
|
|
|
public function goodsSkus(Request $request, $title)
|
|
{
|
|
$skus = GoodsSku::query()
|
|
->where('name', 'like', '%' . $title . '%')
|
|
->where('is_combination', 0)
|
|
->with('goods:id,title')
|
|
->get(['id', 'title', 'goods_id', "name"]);
|
|
foreach ($skus as &$sku) {
|
|
if (!empty($sku['name'])) {
|
|
$sku['title'] = $sku['name'];
|
|
} else {
|
|
$sku['title'] = ($sku['goods']['title'] ?? "") . $sku['title'];
|
|
}
|
|
}
|
|
|
|
return GoodsSkuResource::collection($skus);
|
|
}
|
|
|
|
public function import(Request $request)
|
|
{
|
|
if (!$request->hasFile('combinationGoods')) {
|
|
$this->res = [
|
|
'httpCode' => 404,
|
|
'errorCode' => 404404,
|
|
'errorMessage' => 'not found file',
|
|
];
|
|
}
|
|
try {
|
|
$import = new CombinationGoodsImport();
|
|
$path = $request->file('combinationGoods');
|
|
Excel::import($import, $path);
|
|
} catch (ValidationException $exception) {
|
|
$this->setValidatorFailResponse($exception->validator->getMessageBag()->getMessages());
|
|
}
|
|
|
|
return response($this->res, $this->res['httpCode']);
|
|
}
|
|
}
|