From c923c50abe567a824b24b2d02b9f51a60d96c52e Mon Sep 17 00:00:00 2001
From: panliang <1163816051@qq.com>
Date: Tue, 2 Aug 2022 15:32:47 +0800
Subject: [PATCH] goods
---
.../goods/resources/lang/en/goods-sku.php | 3 +
.../goods/resources/lang/zh_CN/goods-sku.php | 16 ++
.../goods/src/Actions/RowGoodsSkuList.php | 16 ++
packages/goods/src/GoodsService.php | 12 +-
.../Admin/GoodsBrandController.php | 6 +-
.../Controllers/Admin/GoodsController.php | 6 +
.../Controllers/Admin/GoodsSkuController.php | 170 ++++++++++++++++++
packages/goods/src/Http/routes.php | 2 +
packages/goods/src/Models/GoodsSku.php | 19 ++
9 files changed, 242 insertions(+), 8 deletions(-)
create mode 100644 packages/goods/resources/lang/en/goods-sku.php
create mode 100644 packages/goods/resources/lang/zh_CN/goods-sku.php
create mode 100644 packages/goods/src/Actions/RowGoodsSkuList.php
create mode 100644 packages/goods/src/Http/Controllers/Admin/GoodsSkuController.php
diff --git a/packages/goods/resources/lang/en/goods-sku.php b/packages/goods/resources/lang/en/goods-sku.php
new file mode 100644
index 0000000..0b67a5f
--- /dev/null
+++ b/packages/goods/resources/lang/en/goods-sku.php
@@ -0,0 +1,3 @@
+ [
+ 'GoodsSku' => '货品管理',
+ 'goods' => '商品管理',
+ 'sku' => '商品管理',
+ ],
+ 'fields' => [
+ 'sn' => '货号',
+ 'name' => '名称',
+ 'price' => '价格',
+ 'stock' => '库存',
+ 'spec' => '规格',
+ ]
+];
diff --git a/packages/goods/src/Actions/RowGoodsSkuList.php b/packages/goods/src/Actions/RowGoodsSkuList.php
new file mode 100644
index 0000000..5e6641a
--- /dev/null
+++ b/packages/goods/src/Actions/RowGoodsSkuList.php
@@ -0,0 +1,16 @@
+response()->redirect(admin_route('goods-sku.index', ['goods' => $this->getKey()]));
+ }
+}
diff --git a/packages/goods/src/GoodsService.php b/packages/goods/src/GoodsService.php
index 9276ccc..6bc81ec 100644
--- a/packages/goods/src/GoodsService.php
+++ b/packages/goods/src/GoodsService.php
@@ -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,
]);
diff --git a/packages/goods/src/Http/Controllers/Admin/GoodsBrandController.php b/packages/goods/src/Http/Controllers/Admin/GoodsBrandController.php
index 65df6eb..89c4864 100644
--- a/packages/goods/src/Http/Controllers/Admin/GoodsBrandController.php
+++ b/packages/goods/src/Http/Controllers/Admin/GoodsBrandController.php
@@ -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();
diff --git a/packages/goods/src/Http/Controllers/Admin/GoodsController.php b/packages/goods/src/Http/Controllers/Admin/GoodsController.php
index 4263b2d..4c9f517 100644
--- a/packages/goods/src/Http/Controllers/Admin/GoodsController.php
+++ b/packages/goods/src/Http/Controllers/Admin/GoodsController.php
@@ -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());
+ });
});
}
diff --git a/packages/goods/src/Http/Controllers/Admin/GoodsSkuController.php b/packages/goods/src/Http/Controllers/Admin/GoodsSkuController.php
new file mode 100644
index 0000000..8584747
--- /dev/null
+++ b/packages/goods/src/Http/Controllers/Admin/GoodsSkuController.php
@@ -0,0 +1,170 @@
+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 ''.$value.'';
+ });
+ }
+ // $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 ''.$value.'';
+ })->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);
+ }
+}
diff --git a/packages/goods/src/Http/routes.php b/packages/goods/src/Http/routes.php
index 8337ee7..40d661d 100644
--- a/packages/goods/src/Http/routes.php
+++ b/packages/goods/src/Http/routes.php
@@ -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);
diff --git a/packages/goods/src/Models/GoodsSku.php b/packages/goods/src/Models/GoodsSku.php
index 994e9c9..2468221 100644
--- a/packages/goods/src/Models/GoodsSku.php
+++ b/packages/goods/src/Models/GoodsSku.php
@@ -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;
+ }
}