完成主商品后台管理添加
parent
8a37aae51a
commit
feb96bab97
|
|
@ -1,93 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Repositories\ProductAttr;
|
||||
use App\Models\ProductAttrGroup;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Show;
|
||||
|
||||
class ProductAttrController extends AdminController
|
||||
{
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
* @return Grid
|
||||
*/
|
||||
protected function grid()
|
||||
{
|
||||
$builder = ProductAttr::with('group');
|
||||
return Grid::make($builder, function (Grid $grid) {
|
||||
$grid->column('id')->sortable();
|
||||
$grid->column('group.name');
|
||||
$grid->column('name');
|
||||
$grid->column('attrs')->label();
|
||||
$grid->column('created_at')->sortable();
|
||||
|
||||
//排序
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
/** 操作 **/
|
||||
//新增
|
||||
if (Admin::user()->can('dcat.admin.product_attrs.create')) {
|
||||
$grid->disableCreateButton(false);
|
||||
$grid->enableDialogCreate();
|
||||
}
|
||||
|
||||
//修改
|
||||
$grid->showQuickEditButton(Admin::user()->can('dcat.admin.product_attrs.edit'));
|
||||
//删除以及自定义操作
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableDelete(Admin::user()->cannot('dcat.admin.product_attrs.destroy'));
|
||||
});
|
||||
|
||||
/** 查询 **/
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->where('group', function ($query) {
|
||||
$query->whereIn('group_id', ProductAttrGroup::descendantsAndSelf($this->input, ['id'])->pluck('id'));
|
||||
}, __('product-attr.fields.group.name'))->select(ProductAttrGroup::selectOptions())->width(3);
|
||||
$filter->like('name')->width(3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a show builder.
|
||||
*
|
||||
* @param mixed $id
|
||||
*
|
||||
* @return Show
|
||||
*/
|
||||
protected function detail($id)
|
||||
{
|
||||
return Show::make($id, new ProductAttr(), function (Show $show) {
|
||||
$show->field('id');
|
||||
$show->field('group_id');
|
||||
$show->field('attrs');
|
||||
$show->field('created_at');
|
||||
$show->field('updated_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a form builder.
|
||||
*
|
||||
* @return Form
|
||||
*/
|
||||
protected function form()
|
||||
{
|
||||
return Form::make(new ProductAttr(), function (Form $form) {
|
||||
$form->display('id');
|
||||
$form->select('group_id')->options(ProductAttrGroup::selectOptions());
|
||||
$form->text('name')->required();
|
||||
$form->list('attrs');
|
||||
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Repositories\ProductAttrGroup;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\ProductAttr;
|
||||
use App\Models\ProductAttrGroup as ProductAttrGroupModel;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Show;
|
||||
|
||||
class ProductAttrGroupController extends AdminController
|
||||
{
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
* @return Grid
|
||||
*/
|
||||
protected function grid()
|
||||
{
|
||||
return Grid::make(new ProductAttrGroup(), function (Grid $grid) {
|
||||
$grid->column('id')->sortable();
|
||||
$grid->column('name')->tree();
|
||||
$grid->column('parent_id');
|
||||
$grid->column('created_at')->sortable();
|
||||
|
||||
//排序
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
/** 操作 **/
|
||||
//新增
|
||||
if (Admin::user()->can('dcat.admin.product_attr_groups.create')) {
|
||||
$grid->disableCreateButton(false);
|
||||
$grid->enableDialogCreate();
|
||||
}
|
||||
//修改
|
||||
$grid->showQuickEditButton(Admin::user()->can('dcat.admin.product_attr_groups.edit'));
|
||||
//删除以及自定义操作
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableDelete(Admin::user()->cannot('dcat.admin.product_attr_groups.destroy'));
|
||||
});
|
||||
|
||||
/** 查询 **/
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->equal('name')->width(3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a show builder.
|
||||
*
|
||||
* @param mixed $id
|
||||
*
|
||||
* @return Show
|
||||
*/
|
||||
protected function detail($id)
|
||||
{
|
||||
return Show::make($id, new ProductAttrGroup(), function (Show $show) {
|
||||
$show->field('id');
|
||||
$show->field('name');
|
||||
$show->field('parent_id');
|
||||
$show->field('created_at');
|
||||
$show->field('updated_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a form builder.
|
||||
*
|
||||
* @return Form
|
||||
*/
|
||||
protected function form()
|
||||
{
|
||||
return Form::make(new ProductAttrGroup(), function (Form $form) {
|
||||
$form->display('id');
|
||||
$form->select('parent_id')->options(ProductAttrGroupModel::selectOptions());
|
||||
$form->text('name');
|
||||
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
});
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
//如果有子分类或者分类下有文章则不允许删除
|
||||
if (ProductAttrGroupModel::descendantsOf($id, ['id'])->count() > 0
|
||||
|| ProductAttr::where('category_id', $id)->count() > 0) {
|
||||
throw new BizException(__('product-attr-group.options.deny_message'));
|
||||
}
|
||||
return parent::destroy($id);
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ use Dcat\Admin\Grid;
|
|||
use Dcat\Admin\Grid\Column;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Show;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ProductCategoryController extends AdminController
|
||||
{
|
||||
|
|
@ -129,4 +130,17 @@ class ProductCategoryController extends AdminController
|
|||
}
|
||||
return parent::destroy($id);
|
||||
}
|
||||
|
||||
public function list(Request $request)
|
||||
{
|
||||
$parent_id = (int) $request->input('q');
|
||||
$query = ProductCategoryModel::select('id', 'name as text');
|
||||
if ($parent_id) {
|
||||
$query->where('parent_id', $parent_id);
|
||||
} else {
|
||||
$query->whereNull('parent_id');
|
||||
}
|
||||
$data = $query->get();
|
||||
return response()->json($data);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Renderable\ProductAttrTable;
|
||||
use App\Admin\Repositories\ProductGroup;
|
||||
use App\Models\ProductGroup as ProductGroupModel;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Show;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ProductGroupController extends AdminController
|
||||
{
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
* @return Grid
|
||||
*/
|
||||
protected function grid()
|
||||
{
|
||||
return Grid::make(new ProductGroup(), function (Grid $grid) {
|
||||
$grid->column('id')->sortable();
|
||||
$grid->column('name');
|
||||
$grid->column('attrs')->display(function ($value) {
|
||||
return collect($value)->pluck('title');
|
||||
})->label();
|
||||
$grid->column('specs')->display(function ($value) {
|
||||
return collect($value)->pluck('title');
|
||||
})->label();
|
||||
$grid->column('created_at')->sortable();
|
||||
|
||||
//排序
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
/** 操作 **/
|
||||
//新增
|
||||
if (Admin::user()->can('dcat.admin.product_groups.create')) {
|
||||
$grid->disableCreateButton(false);
|
||||
$grid->enableDialogCreate();
|
||||
}
|
||||
|
||||
//修改
|
||||
$grid->showQuickEditButton(Admin::user()->can('dcat.admin.product_groups.edit'));
|
||||
//删除以及自定义操作
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableDelete(Admin::user()->cannot('dcat.admin.product_groups.destroy'));
|
||||
});
|
||||
|
||||
/** 查询 **/
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->like('name')->width(3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a show builder.
|
||||
*
|
||||
* @param mixed $id
|
||||
*
|
||||
* @return Show
|
||||
*/
|
||||
protected function detail($id)
|
||||
{
|
||||
return Show::make($id, new ProductGroup(), function (Show $show) {
|
||||
$show->field('id');
|
||||
$show->field('name');
|
||||
$show->field('created_at');
|
||||
$show->field('updated_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a form builder.
|
||||
*
|
||||
* @return Form
|
||||
*/
|
||||
protected function form()
|
||||
{
|
||||
return Form::make(new ProductGroup(), function (Form $form) {
|
||||
$form->display('id');
|
||||
$form->text('name')->required();
|
||||
$form->table('attrs', function ($table) {
|
||||
$table->text('title');
|
||||
$table->textarea('value');
|
||||
});
|
||||
$form->table('specs', function ($table) {
|
||||
$table->text('title');
|
||||
$table->textarea('value');
|
||||
});
|
||||
// $form->multipleSelectTable('attrs')
|
||||
// ->from(ProductAttrTable::make(['id'=>$form->getKey()]));
|
||||
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
});
|
||||
}
|
||||
|
||||
public function details(Request $request)
|
||||
{
|
||||
$group_id = (int) $request->input('group_id');
|
||||
$group = ProductGroupModel::where('id', $group_id)->first();
|
||||
$data = [];
|
||||
if ($group) {
|
||||
foreach ($group->attrs as $attr) {
|
||||
$data['attrs'][] = [
|
||||
'name' => $attr['title'],
|
||||
'attrs'=> array_map(function ($value) {
|
||||
return [
|
||||
'name'=>$value,
|
||||
'value'=>'',
|
||||
];
|
||||
}, explode(',', str_replace("\r\n", ',', trim($attr['value'])))),
|
||||
];
|
||||
}
|
||||
foreach ($group->specs as $spec) {
|
||||
$data['specs'][] = [
|
||||
'name' => $spec['title'],
|
||||
'specs'=> array_map(function ($value) {
|
||||
return [
|
||||
'name'=>$value,
|
||||
'value'=>'',
|
||||
];
|
||||
}, explode(',', str_replace("\r\n", ',', trim($spec['value'])))),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Repositories\ProductSpec;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Show;
|
||||
|
||||
class ProductSpecController extends AdminController
|
||||
{
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
* @return Grid
|
||||
*/
|
||||
protected function grid()
|
||||
{
|
||||
return Grid::make(new ProductSpec(), function (Grid $grid) {
|
||||
$grid->column('id')->sortable();
|
||||
$grid->column('name');
|
||||
$grid->column('items')->label();
|
||||
$grid->column('created_at')->sortable();
|
||||
|
||||
//排序
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
/** 操作 **/
|
||||
//新增
|
||||
if (Admin::user()->can('dcat.admin.product_specs.create')) {
|
||||
$grid->disableCreateButton(false);
|
||||
$grid->enableDialogCreate();
|
||||
}
|
||||
//修改
|
||||
$grid->showQuickEditButton(Admin::user()->can('dcat.admin.product_specs.edit'));
|
||||
//删除以及自定义操作
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableDelete(Admin::user()->cannot('dcat.admin.product_specs.destroy'));
|
||||
});
|
||||
|
||||
/** 查询 **/
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->equal('name')->width(3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a show builder.
|
||||
*
|
||||
* @param mixed $id
|
||||
*
|
||||
* @return Show
|
||||
*/
|
||||
protected function detail($id)
|
||||
{
|
||||
return Show::make($id, new ProductSpec(), function (Show $show) {
|
||||
$show->field('id');
|
||||
$show->field('name');
|
||||
$show->field('items');
|
||||
$show->field('created_at');
|
||||
$show->field('updated_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a form builder.
|
||||
*
|
||||
* @return Form
|
||||
*/
|
||||
protected function form()
|
||||
{
|
||||
return Form::make(new ProductSpec(), function (Form $form) {
|
||||
$form->display('id');
|
||||
$form->text('name')->required();
|
||||
$form->list('items');
|
||||
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Repositories\ProductSpu;
|
||||
use App\Models\ProductCategory;
|
||||
use App\Models\ProductGroup;
|
||||
use Carbon\Carbon;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
|
|
@ -28,9 +28,8 @@ class ProductSpuController extends AdminController
|
|||
$grid->column('sell_price');
|
||||
$grid->column('market_price');
|
||||
$grid->column('cost_price');
|
||||
$grid->column('user_price');
|
||||
$grid->column('vip_price');
|
||||
$grid->column('weight');
|
||||
$grid->column('is_sell');
|
||||
$grid->column('created_at')->sortable();
|
||||
|
||||
//排序
|
||||
|
|
@ -42,9 +41,10 @@ class ProductSpuController extends AdminController
|
|||
$grid->disableCreateButton(false);
|
||||
}
|
||||
//修改
|
||||
$grid->showQuickEditButton(Admin::user()->can('dcat.admin.product_spus.edit'));
|
||||
// $grid->showQuickEditButton(Admin::user()->can('dcat.admin.product_spus.edit'));
|
||||
//删除以及自定义操作
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableEdit(Admin::user()->cannot('dcat.admin.product_spus.edit'));
|
||||
$actions->disableDelete(Admin::user()->cannot('dcat.admin.product_spus.destroy'));
|
||||
});
|
||||
|
||||
|
|
@ -75,11 +75,10 @@ class ProductSpuController extends AdminController
|
|||
$show->field('sell_price');
|
||||
$show->field('market_price');
|
||||
$show->field('cost_price');
|
||||
$show->field('user_price');
|
||||
$show->field('vip_price');
|
||||
$show->field('media');
|
||||
$show->field('weight');
|
||||
$show->field('attrs');
|
||||
$show->field('is_sell');
|
||||
$show->field('created_at');
|
||||
$show->field('updated_at');
|
||||
});
|
||||
|
|
@ -95,10 +94,12 @@ class ProductSpuController extends AdminController
|
|||
return Form::make(new ProductSpu(), function (Form $form) {
|
||||
$form->display('id');
|
||||
|
||||
if ($form->isEditing()) {
|
||||
return;
|
||||
|
||||
if ($form->isCreating()) {
|
||||
$form->select('one_category')->options(admin_route('api.product_categories'))->load('two_category', admin_route('api.product_categories'));
|
||||
$form->select('two_category')->load('category_id', admin_route('api.product_categories'));
|
||||
$form->select('category_id')->required();
|
||||
}
|
||||
$form->select('category_id')->options(ProductCategory::selectOptions())->required();
|
||||
$form->text('name')->required();
|
||||
$form->text('subtitle');
|
||||
$form->image('cover')
|
||||
|
|
@ -114,12 +115,14 @@ class ProductSpuController extends AdminController
|
|||
$form->editor('description');
|
||||
$form->number('weight');
|
||||
|
||||
$form->currency('sell_price')->symbol('¥');
|
||||
$form->currency('market_price')->symbol('¥');
|
||||
$form->currency('cost_price')->symbol('¥');
|
||||
$form->currency('user_price')->symbol('¥');
|
||||
$form->switch('is_sell');
|
||||
$form->currency('sell_price')->symbol('¥')->default(0);
|
||||
$form->currency('market_price')->symbol('¥')->default(0);
|
||||
$form->currency('cost_price')->symbol('¥')->default(0);
|
||||
$form->currency('vip_price')->symbol('¥');
|
||||
$form->select('attr_group')->options(ProductGroup::all()->pluck('name', 'id'));
|
||||
$form->selectAttr('attrs')->listen('attr_group');
|
||||
|
||||
$form->ignore(['one_category', 'two_category', 'attr_group']);
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Extensions\Form\Product;
|
||||
|
||||
use Dcat\Admin\Form\Field;
|
||||
|
||||
class SelectAttr extends Field
|
||||
{
|
||||
protected $view = 'admin.form.product-select-attr';
|
||||
|
||||
protected $listen = '';
|
||||
|
||||
protected static $js = [
|
||||
'/vendor/vue/vue.js',
|
||||
// 'https://cdn.jsdelivr.net/npm/vue/dist/vue.js' // 这里可以将vue.js下载下来引入
|
||||
];
|
||||
|
||||
public function listen($listen = '')
|
||||
{
|
||||
$this->listen = $listen;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$this->addVariables(['listen' => $this->listen]);
|
||||
return parent::render();
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化保存值
|
||||
*
|
||||
* @param [type] $data
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareInputValue($value)
|
||||
{
|
||||
$attrs = $value;
|
||||
//过滤空值;
|
||||
if ($attrs) {
|
||||
$attrs =json_decode($attrs, true);
|
||||
foreach ($attrs as $key=> &$attr) {
|
||||
$attr['attrs'] = array_filter(array_map(function ($item) {
|
||||
if (!empty($item['value'])) {
|
||||
return $item;
|
||||
}
|
||||
}, $attr['attrs']));
|
||||
//如果该组无值,则删除该组
|
||||
if (count($attr['attrs']) < 1) {
|
||||
unset($attrs[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化渲染值
|
||||
*
|
||||
* @param [type] $value
|
||||
* @return void
|
||||
*/
|
||||
protected function formatFieldData($data)
|
||||
{
|
||||
$value = parent::formatFieldData($data);
|
||||
// dd($value);
|
||||
return json_encode($value);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Extensions\Form\Product;
|
||||
|
||||
use Dcat\Admin\Form\Field;
|
||||
|
||||
class SelectSpec extends Field
|
||||
{
|
||||
protected $view = 'admin.form.product-select-spec';
|
||||
|
||||
protected $listen = '';
|
||||
|
||||
protected static $js = [
|
||||
'/vendor/vue/vue.js',
|
||||
// 'https://cdn.jsdelivr.net/npm/vue/dist/vue.js' // 这里可以将vue.js下载下来引入
|
||||
];
|
||||
|
||||
public function listen($listen = '')
|
||||
{
|
||||
$this->listen = $listen;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$this->addVariables(['listen' => $this->listen]);
|
||||
return parent::render();
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化保存值
|
||||
*
|
||||
* @param [type] $data
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareInputValue($value)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化渲染值
|
||||
*
|
||||
* @param [type] $value
|
||||
* @return void
|
||||
*/
|
||||
protected function formatFieldData($data)
|
||||
{
|
||||
$value = parent::formatFieldData($data);
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Renderable;
|
||||
|
||||
use App\Models\ProductAttr;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Grid\LazyRenderable;
|
||||
|
||||
class ProductAttrTable extends LazyRenderable
|
||||
{
|
||||
public function grid(): Grid
|
||||
{
|
||||
$id = $this->id;
|
||||
return Grid::make(new ProductAttr(), function (Grid $grid) {
|
||||
$grid->disableRowSelector(false);
|
||||
$grid->column('name');
|
||||
$grid->column('attrs')->label();
|
||||
$grid->quickSearch(['name']);
|
||||
$grid->disableActions();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Repositories;
|
||||
|
||||
use App\Models\ProductAttr as Model;
|
||||
use Dcat\Admin\Repositories\EloquentRepository;
|
||||
|
||||
class ProductAttr extends EloquentRepository
|
||||
{
|
||||
/**
|
||||
* Model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eloquentClass = Model::class;
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Repositories;
|
||||
|
||||
use App\Models\ProductAttrGroup as Model;
|
||||
use Dcat\Admin\Repositories\EloquentRepository;
|
||||
|
||||
class ProductAttrGroup extends EloquentRepository
|
||||
{
|
||||
/**
|
||||
* Model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eloquentClass = Model::class;
|
||||
}
|
||||
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
namespace App\Admin\Repositories;
|
||||
|
||||
use App\Models\ProductSpec as Model;
|
||||
use App\Models\ProductGroup as Model;
|
||||
use Dcat\Admin\Repositories\EloquentRepository;
|
||||
|
||||
class ProductSpec extends EloquentRepository
|
||||
class ProductGroup extends EloquentRepository
|
||||
{
|
||||
/**
|
||||
* Model.
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
use App\Admin\Extensions\Form\Product\SelectAttr;
|
||||
use App\Admin\Extensions\Form\Product\SelectSpec;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Form\Field\Editor;
|
||||
|
|
@ -38,7 +40,8 @@ Form::resolving(function (Form $form) {
|
|||
$form->disableViewButton();
|
||||
$form->disableViewCheck();
|
||||
});
|
||||
|
||||
Form::extend('selectAttr', SelectAttr::class);
|
||||
Form::extend('selectSpec', SelectSpec::class);
|
||||
|
||||
Editor::resolving(function (Editor $editor) {
|
||||
// 设置默认配置
|
||||
|
|
|
|||
|
|
@ -35,17 +35,14 @@ Route::group([
|
|||
'index', 'create', 'store', 'edit', 'update', 'destroy',
|
||||
])->names('product_categories');
|
||||
|
||||
$router->resource('product-specs', 'ProductSpecController')->only([
|
||||
$router->resource('product-groups', 'ProductGroupController')->only([
|
||||
'index', 'create', 'store', 'edit', 'update', 'destroy',
|
||||
])->names('product_specs');
|
||||
|
||||
$router->resource('product-attr-groups', 'ProductAttrGroupController')->only([
|
||||
'index', 'create', 'store', 'edit', 'update', 'destroy',
|
||||
])->names('product_attr_groups');
|
||||
|
||||
$router->resource('product-attrs', 'ProductAttrController')->only([
|
||||
'index', 'create', 'store', 'edit', 'update', 'destroy',
|
||||
])->names('product_attrs');
|
||||
])->names('product_groups');
|
||||
|
||||
$router->resource('product-spus', 'ProductSpuController')->names('product_spus');
|
||||
|
||||
|
||||
/** api接口 **/
|
||||
$router->get('api/product-categories', 'ProductCategoryController@list')->name('api.product_categories');
|
||||
$router->get('api/product-group-details', 'ProductGroupController@details')->name('api.product_group_details');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class JsonArray implements CastsAttributes
|
|||
*/
|
||||
public function get($model, string $key, $value, array $attributes)
|
||||
{
|
||||
$value = json_decode($value);
|
||||
$value = json_decode($value, true);
|
||||
|
||||
return is_array($value) ? $value : [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Casts\JsonArray;
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ProductAttr extends Model
|
||||
{
|
||||
use HasDateTimeFormatter;
|
||||
protected $table = 'product_attrs';
|
||||
|
||||
protected $casts = [
|
||||
'attrs'=> JsonArray::class,
|
||||
];
|
||||
|
||||
public function group()
|
||||
{
|
||||
return $this->belongsTo(ProductAttrGroup::class, 'group_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
|
||||
use Dcat\Admin\Traits\ModelTree;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Kalnoy\Nestedset\NodeTrait;
|
||||
|
||||
class ProductAttrGroup extends Model
|
||||
{
|
||||
use NodeTrait;
|
||||
use ModelTree;
|
||||
use HasDateTimeFormatter;
|
||||
protected $table = 'product_attr_groups';
|
||||
|
||||
// 排序字段名称,默认值为 order
|
||||
protected $orderColumn = 'sort';
|
||||
|
||||
// 标题字段名称,默认值为 title
|
||||
protected $titleColumn = 'name';
|
||||
|
||||
public function getDefaultParentId()
|
||||
{
|
||||
return $this->parent_id;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,15 +4,14 @@ namespace App\Models;
|
|||
|
||||
use App\Casts\JsonArray;
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ProductSpec extends Model
|
||||
class ProductGroup extends Model
|
||||
{
|
||||
use HasDateTimeFormatter;
|
||||
protected $table = 'product_specs';
|
||||
|
||||
protected $casts = [
|
||||
'items' => JsonArray::class,
|
||||
'attrs' => JsonArray::class,
|
||||
'specs' => JsonArray::class,
|
||||
];
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateProductSpecsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('product_specs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name')->column('规格名称');
|
||||
$table->json('items')->nullable()->comment('规格可选值');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('product_specs');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateProductAttrGroupsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('product_attr_groups', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name')->comment('名称');
|
||||
$table->integer('sort')->default(0)->comment('排序');
|
||||
$table->nestedSet();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('product_attr_groups');
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
|||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateProductAttrsTable extends Migration
|
||||
class CreateProductGroupsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
|
|
@ -13,11 +13,11 @@ class CreateProductAttrsTable extends Migration
|
|||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('product_attrs', function (Blueprint $table) {
|
||||
Schema::create('product_groups', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('group_id')->nullable()->comment('属性分组');
|
||||
$table->string('name')->comment('名称');
|
||||
$table->json('attrs')->nullable()->comment('属性');
|
||||
$table->json('specs')->nullable()->comment('规格');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
|
@ -29,6 +29,6 @@ class CreateProductAttrsTable extends Migration
|
|||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('product_attrs');
|
||||
Schema::dropIfExists('product_groups');
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'ProductAttrGroup' => '属性分组',
|
||||
'product-attr-groups' => '属性分组',
|
||||
],
|
||||
'fields' => [
|
||||
'name' => '名称',
|
||||
'parent_id' => '上级',
|
||||
],
|
||||
'options' => [
|
||||
'deny' => '删除失败',
|
||||
'deny_message'=>'请先删除该分类下的子分类或者属性',
|
||||
],
|
||||
];
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'ProductAttr' => '属性管理',
|
||||
'product-attrs' => '属性管理',
|
||||
],
|
||||
'fields' => [
|
||||
'group' => [
|
||||
'name' => '属性分组',
|
||||
],
|
||||
'group_id' => '属性分组',
|
||||
'attrs' => '属性',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'ProductGroup' => '商品分组',
|
||||
'product-groups' => '商品分组',
|
||||
],
|
||||
'fields' => [
|
||||
'name' => '名称',
|
||||
'attrs' => '属性',
|
||||
'specs' => '规格',
|
||||
'title'=>'名称',
|
||||
'value' => '值',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'ProductSpec' => '商品规格',
|
||||
'product-specs' => '商品规格',
|
||||
],
|
||||
'fields' => [
|
||||
'name' => '规格名称',
|
||||
'items' => '规格可选值',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -6,6 +6,8 @@ return [
|
|||
'product-spus' => '主商品',
|
||||
],
|
||||
'fields' => [
|
||||
'one_category'=>'一级分类',
|
||||
'two_category'=>'二级分类',
|
||||
'category_id'=>'商品分类',
|
||||
'name' => '商品名称',
|
||||
'subtitle' => '商品副标题',
|
||||
|
|
@ -15,11 +17,11 @@ return [
|
|||
'sell_price' => '销售价格',
|
||||
'market_price' => '市场价格',
|
||||
'cost_price' => '成本价格',
|
||||
'user_price' => '会员价格',
|
||||
'vip_price' => '会员价格',
|
||||
'media' => '媒体地址',
|
||||
'weight' => '重量:g',
|
||||
'attrs' => '属性文本',
|
||||
'is_sell' => '在售状态',
|
||||
'attr_group'=>'商品分组',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
<div class="{{$viewClass['form-group']}}">
|
||||
|
||||
<label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
|
||||
|
||||
<div class="{{$viewClass['field']}}">
|
||||
|
||||
@include('admin::form.error')
|
||||
|
||||
<div class="{{ $class }}" style="width: 100%; height: 100%;">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<template v-for="(n, attrIndex) in attr_group.length">
|
||||
<div class="form-group row form-field" initialized="1" >
|
||||
<label class="text-capitalize control-label" style="font-weight: bold;">@{{attr_group[attrIndex].name}}</label>
|
||||
<table class="table table-hover">
|
||||
<tbody class="kv-table">
|
||||
<tr v-for="(attr) in attr_group[attrIndex].attrs">
|
||||
<td>
|
||||
<div class="form-group ">
|
||||
<div class="col-sm-12">
|
||||
<div class="help-block with-errors"></div>
|
||||
<input name="" class="form-control" v-model="attr.name" disabled>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="form-group ">
|
||||
<div class="col-sm-12">
|
||||
<div class="help-block with-errors"></div>
|
||||
<input name="" class="form-control" v-model="attr.value">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
<input type="hidden" name="{{ $name }}" :value="getAttrs">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@include('admin::form.help-block')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script init="{!! $selector !!}">
|
||||
|
||||
var vm = new Vue({
|
||||
el: '#' + id,
|
||||
data: {
|
||||
attr_group:[],
|
||||
},
|
||||
created() {
|
||||
this.createStart();
|
||||
},
|
||||
computed: {
|
||||
getAttrs() {
|
||||
return JSON.stringify(this.attr_group);
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
createStart(){//初始化数据
|
||||
var selectAttrValue = (new Function("return " + '{!! $value !!}'))();
|
||||
if(selectAttrValue && selectAttrValue.length > 0){
|
||||
for(j = 0, len=selectAttrValue.length; j < len; j++){
|
||||
this.attr_group.push(selectAttrValue[j]);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
function getTypeAttrs(group_id){
|
||||
var url_path = "{{ admin_route('api.product_group_details') }}";
|
||||
var goods_id = 0;
|
||||
|
||||
$.ajax({
|
||||
type: 'get',
|
||||
dataType: 'json',
|
||||
url: url_path,
|
||||
data: {
|
||||
'group_id':group_id,
|
||||
},
|
||||
success: function (result) {
|
||||
vm.attr_group = [];
|
||||
if(result.attrs.length > 0){
|
||||
for(j = 0, len=result.attrs.length; j < len; j++){
|
||||
vm.attr_group.push(result.attrs[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
$("[name='{{ $listen }}']").on('change', function(){
|
||||
var group_id = this.options[this.options.selectedIndex].value;
|
||||
// alert(group_id);
|
||||
getTypeAttrs(group_id);
|
||||
})
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<div class="{{$viewClass['form-group']}}">
|
||||
|
||||
<label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
|
||||
|
||||
<div class="{{$viewClass['field']}}">
|
||||
|
||||
@include('admin::form.error')
|
||||
|
||||
<div class="{{ $class }}" style="width: 100%; height: 100%;">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<template v-for="(n, specIndex) in spec_group.length">
|
||||
<div class="form-group row form-field" initialized="1" >
|
||||
<label class="text-capitalize control-label" style="font-weight: bold;">@{{spec_group[specIndex].name}}</label>
|
||||
<table class="table table-hover">
|
||||
<tbody class="kv-table">
|
||||
<tr v-for="(spec) in spec_group[specIndex].specs">
|
||||
<td>
|
||||
<div class="form-group ">
|
||||
<div class="col-sm-12">
|
||||
<div class="help-block with-errors"></div>
|
||||
<input name="" class="form-control" v-model="spec.name" disabled>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="form-group ">
|
||||
<div class="col-sm-12">
|
||||
<div class="help-block with-errors"></div>
|
||||
<input name="" class="form-control" v-model="spec.value">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
<input type="hidden" name="{{ $name }}" :value="getSpecs">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@include('admin::form.help-block')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script init="{!! $selector !!}">
|
||||
|
||||
var vm = new Vue({
|
||||
el: '#' + id,
|
||||
data: {
|
||||
spec_group:[]
|
||||
},
|
||||
computed: {
|
||||
getSpecs() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
function getTypeSpecs(group_id){
|
||||
var url_path = "{{ admin_route('api.product_group_details') }}";
|
||||
var goods_id = 0;
|
||||
|
||||
$.ajax({
|
||||
type: 'get',
|
||||
dataType: 'json',
|
||||
url: url_path,
|
||||
data: {
|
||||
'group_id':group_id,
|
||||
},
|
||||
success: function (result) {
|
||||
vm.spec_group = [];
|
||||
if(result.specs.length > 0){
|
||||
for(j = 0, len=result.specs.length; j < len; j++){
|
||||
vm.spec_group.push(result.specs[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
$("[name='{{ $listen }}']").on('change', function(){
|
||||
var group_id = this.options[this.options.selectedIndex].value;
|
||||
// alert(group_id);
|
||||
getTypeSpecs(group_id);
|
||||
})
|
||||
|
||||
</script>
|
||||
Loading…
Reference in New Issue