goods
parent
9fcd37b646
commit
c923c50abe
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
return [];
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'GoodsSku' => '货品管理',
|
||||
'goods' => '商品管理',
|
||||
'sku' => '商品管理',
|
||||
],
|
||||
'fields' => [
|
||||
'sn' => '货号',
|
||||
'name' => '名称',
|
||||
'price' => '价格',
|
||||
'stock' => '库存',
|
||||
'spec' => '规格',
|
||||
]
|
||||
];
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Goods\Actions;
|
||||
|
||||
use Dcat\Admin\Grid\RowAction;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class RowGoodsSkuList extends RowAction
|
||||
{
|
||||
protected $title = '货品信息';
|
||||
|
||||
public function handle(Request $request)
|
||||
{
|
||||
return $this->response()->redirect(admin_route('goods-sku.index', ['goods' => $this->getKey()]));
|
||||
}
|
||||
}
|
||||
|
|
@ -27,8 +27,8 @@ class GoodsService
|
|||
$this->clearSku($goods);
|
||||
if ($goods->spec) {
|
||||
$spec = $goods->spec;
|
||||
$goods_price = $goods->price;
|
||||
$goods_name = $goods->name;
|
||||
$price = $goods->price;
|
||||
$name = $goods->name;
|
||||
|
||||
$specList = [];
|
||||
foreach ($spec as $item) {
|
||||
|
|
@ -44,13 +44,11 @@ class GoodsService
|
|||
}
|
||||
$cartesianList = $this->cartesianProduct($specList);
|
||||
foreach($cartesianList as $items) {
|
||||
$sub_goods_name = $goods_name;
|
||||
$sub_price = $goods_price;
|
||||
|
||||
$specPrice = array_sum(array_column($items, 'price'));
|
||||
$goods->skus()->create([
|
||||
'sn' => $this->generateSn(),
|
||||
'name' => $sub_goods_name,
|
||||
'price' => $sub_price,
|
||||
'name' => $name,
|
||||
'price' => $price + $specPrice,
|
||||
'stock' => $goods->stock,
|
||||
'spec' => $items,
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,11 @@ class GoodsBrandController extends AdminController
|
|||
{
|
||||
return Form::make(new GoodsBrand(), function (Form $form) {
|
||||
$form->text('name');
|
||||
$form->image('image')->autoUpload()->saveFullUrl()->move('goods/brand');
|
||||
$form->image('image')
|
||||
->autoUpload()
|
||||
->saveFullUrl()
|
||||
->move('goods/brand');
|
||||
// $form->oss('file')->dir('mv');
|
||||
|
||||
$form->disableResetButton();
|
||||
$form->disableCreatingCheck();
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@ namespace Peidikeji\Goods\Http\Controllers\Admin;
|
|||
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Grid\Displayers\Actions;
|
||||
use Dcat\Admin\Grid\Tools\Selector;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Show;
|
||||
use Peidikeji\Goods\Actions\RowGoodsSkuList;
|
||||
use Peidikeji\Goods\Models\Goods;
|
||||
use Peidikeji\Goods\Models\GoodsBrand;
|
||||
use Peidikeji\Goods\Models\GoodsCategory;
|
||||
|
|
@ -56,6 +58,10 @@ class GoodsController extends AdminController
|
|||
$grid->column('sold_count');
|
||||
|
||||
$grid->disableRowSelector();
|
||||
|
||||
$grid->actions(function (Actions $actions) {
|
||||
$actions->append(new RowGoodsSkuList());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\Goods\Http\Controllers\Admin;
|
||||
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Grid\Tools\Selector;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Layout\Content;
|
||||
use Dcat\Admin\Show;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Peidikeji\Goods\Models\Goods;
|
||||
use Peidikeji\Goods\Models\GoodsSku;
|
||||
|
||||
class GoodsSkuController extends Controller
|
||||
{
|
||||
protected $translation = 'peidikeji.dcat-admin-extension-goods::goods-sku';
|
||||
|
||||
public function index($goods, Content $content)
|
||||
{
|
||||
$goods = Goods::findOrFail($goods);
|
||||
$grid = Grid::make(new GoodsSku(), function (Grid $grid) use ($goods) {
|
||||
$grid->model()->where('goods_id', $goods->id);
|
||||
|
||||
$grid->selector(function (Selector $selector) use ($goods) {
|
||||
$specs = $goods->spec;
|
||||
foreach($specs as $key => $item) {
|
||||
$values = array_column($item['values'], 'value');
|
||||
$selector->selectOne('spec_' . $key, $item['name'], array_column($item['values'], 'value'), function ($q, $value) use ($values, $item) {
|
||||
$selected = array_values(Arr::only($values, $value));
|
||||
if (count($selected) > 0) {
|
||||
$q->jsonArray([['name' => $item['name'], 'value' => $selected[0]]]);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$grid->column('id');
|
||||
$grid->column('sn');
|
||||
$grid->column('name');
|
||||
$grid->column('price');
|
||||
$grid->column('stock');
|
||||
foreach($goods->spec as $key => $item) {
|
||||
$grid->column('spec_' . $key, $item['name'])->display(function () use ($item) {
|
||||
$filtered = current(array_filter($this->spec, fn($subItem) => $subItem['name'] === $item['name']));
|
||||
$value = data_get($filtered, 'value');
|
||||
$price = data_get($filtered, 'price');
|
||||
return '<span class="label bg-info">'.$value.'</span>';
|
||||
});
|
||||
}
|
||||
// $grid->column('spec')->view('peidikeji.dcat-admin-extension-goods::grid.attr');
|
||||
});
|
||||
return $content
|
||||
->translation($this->translation)
|
||||
->title(admin_trans_label())
|
||||
->description(trans('admin.list'))
|
||||
->body($grid);
|
||||
}
|
||||
|
||||
public function show($id, Content $content)
|
||||
{
|
||||
$info = GoodsSku::with(['goods'])->findOrFail($id);
|
||||
$show = Show::make($info, function (Show $show) {
|
||||
$show->field('sn');
|
||||
$show->field('name');
|
||||
$show->field('price');
|
||||
$show->field('stock');
|
||||
// $show->field('spec')->view('peidikeji.dcat-admin-extension-goods::grid.attr');
|
||||
$goods = $show->model()->goods;
|
||||
foreach($goods->spec as $key => $item) {
|
||||
$show->field('spec_' . $key, $item['name'])->as(function () use ($item) {
|
||||
$filtered = current(array_filter($this->spec, fn($subItem) => $subItem['name'] === $item['name']));
|
||||
$value = data_get($filtered, 'value');
|
||||
$price = data_get($filtered, 'price');
|
||||
return '<span class="label bg-info">'.$value.'</span>';
|
||||
})->unescape();
|
||||
}
|
||||
});
|
||||
return $content
|
||||
->translation($this->translation)
|
||||
->title(admin_trans_label())
|
||||
->description(trans('admin.show'))
|
||||
->body($show);
|
||||
}
|
||||
|
||||
protected function form($goods)
|
||||
{
|
||||
return Form::make(new GoodsSku(), function (Form $form) use ($goods) {
|
||||
$unqiue = Rule::unique('goods_sku', 'sn');
|
||||
if ($form->isEditing()) {
|
||||
$unqiue->ignore($form->model()->id);
|
||||
}
|
||||
$form->text('sn')->rules([$unqiue])->required();
|
||||
$form->text('name')->default($goods->name);
|
||||
$form->number('price')->min(0)->default($goods->price);
|
||||
$form->number('stock')->min(0)->default($goods->stock);
|
||||
$form->hidden('spec')->customFormat(fn($v) => json_encode($v));
|
||||
$form->hidden('goods_id')->default($goods->id);
|
||||
|
||||
$spec = $form->model()->spec;
|
||||
foreach($goods->spec as $key => $item) {
|
||||
$values = array_column($item['values'], 'value', 'value');
|
||||
$value = null;
|
||||
if ($spec) {
|
||||
$filtered = current(array_filter($spec, fn($subItem) => $subItem['name'] === $item['name']));
|
||||
$value = array_search($filtered['value'], $values);
|
||||
}
|
||||
$form->radio($item['name'], $item['name'])->options($values)->value($value);
|
||||
}
|
||||
|
||||
$form->saving(function (Form $form) use ($goods) {
|
||||
$info = $form->model();
|
||||
$spec = [];
|
||||
foreach($goods->spec as $item) {
|
||||
array_push($spec, ['name' => $item['name'], 'value' => $form->input($item['name'])]);
|
||||
$form->deleteInput($item['name']);
|
||||
}
|
||||
$form->input('spec', $spec);
|
||||
$query = GoodsSku::where('goods_id', $goods->id)->jsonArray($spec);
|
||||
if ($form->isEditing()) {
|
||||
$query->where('id', '!=', $info->id);
|
||||
}
|
||||
if ($query->exists()) {
|
||||
return $form->response()->error('该规格已经存在');
|
||||
}
|
||||
});
|
||||
|
||||
$form->disableCreatingCheck();
|
||||
$form->disableEditingCheck();
|
||||
$form->disableViewCheck();
|
||||
$form->disableResetButton();
|
||||
});
|
||||
}
|
||||
|
||||
public function edit($goods, $id, Content $content)
|
||||
{
|
||||
$goods = Goods::findOrFail($goods);
|
||||
return $content
|
||||
->translation($this->translation)
|
||||
->title(admin_trans_label())
|
||||
->description(trans('admin.edit'))
|
||||
->body($this->form($goods)->edit($id));
|
||||
}
|
||||
|
||||
public function create($goods, Content $content)
|
||||
{
|
||||
return $content
|
||||
->translation($this->translation)
|
||||
->title(admin_trans_label())
|
||||
->description(trans('admin.create'))
|
||||
->body($this->form(Goods::findOrFail($goods)));
|
||||
}
|
||||
|
||||
public function update($goods, $id)
|
||||
{
|
||||
return $this->form(Goods::findOrFail($goods))->update($id);
|
||||
}
|
||||
|
||||
public function store($goods)
|
||||
{
|
||||
return $this->form(Goods::findOrFail($goods))->store();
|
||||
}
|
||||
|
||||
public function destroy($goods, $id)
|
||||
{
|
||||
return $this->form(Goods::findOrFail($goods))->destroy($id);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,4 +8,6 @@ Route::resource('goods/category', GoodsCategoryController::class);
|
|||
Route::resource('goods/brand', GoodsBrandController::class);
|
||||
Route::resource('goods/type', GoodsTypeController::class);
|
||||
|
||||
Route::resource('goods/{goods}/sku', GoodsSkuController::class)->names('goods-sku');
|
||||
|
||||
Route::resource('goods', GoodsController::class);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace Peidikeji\Goods\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
|
||||
class GoodsSku extends Model
|
||||
{
|
||||
|
|
@ -20,4 +21,22 @@ class GoodsSku extends Model
|
|||
{
|
||||
return $this->belongsTo(Goods::class, 'goods_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Mysql Json 查询
|
||||
* 数据库存储格式: [{"name": "颜色", "price": 0, "value": "白色"}, {"name": "内存", "price": 0, "value": "32G"}]
|
||||
*
|
||||
* @param Builder $q
|
||||
* @param array $params [{"name": "颜色", "value": "白色"}, {"name": "内存", "value": "32G"}]
|
||||
*/
|
||||
public function scopeJsonArray($q, $params)
|
||||
{
|
||||
foreach($params as $item) {
|
||||
foreach($item as $key => $value) {
|
||||
$value = is_string($value) ? '"'.$value.'"' : $value;
|
||||
$q->whereRaw("json_contains(spec->>\"$[*].".$key."\", '".$value."')");
|
||||
}
|
||||
}
|
||||
return $q;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue