moshaorui 5 months ago
parent
commit
e45c6defcf

+ 74 - 0
app/Admin/Controllers/BaseProductCategoryController.php

@@ -0,0 +1,74 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+use App\Admin\Repositories\BaseProductCategory;
+use Dcat\Admin\Form;
+use Dcat\Admin\Grid;
+use Dcat\Admin\Http\Controllers\AdminController;
+use Dcat\Admin\Layout\Content;
+use App\Admin\Repositories\BaseProductParameter;
+
+class BaseProductCategoryController extends AdminController
+{
+
+    public function index(Content $content)
+    {
+        return $content
+            ->header('Product Category')
+            ->description('')
+            ->body($this->grid());
+    }
+
+
+    /**
+     * Make a grid builder.
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+        return Grid::make(BaseProductCategory::with('baseProductParameter'), function (Grid $grid) {
+            $grid->column('id','ID')->bold()->sortable();
+            $grid->column('name')->tree(true,true);
+            $grid->column('parent_id');
+            $grid->column('baseProductParameter.name','Parameter Name');
+            $grid->column('order')->orderable();
+            $grid->column('enabled')->switch();
+            $grid->column('created_at');
+            $grid->column('updated_at')->sortable();
+            $grid->filter(function (Grid\Filter $filter) {
+                $filter->like('name');
+            });
+            $grid->disableViewButton();
+            $grid->showQuickEditButton();
+            $grid->enableDialogCreate();
+            $grid->disableEditButton();
+            $grid->quickSearch('name');
+        });
+
+    }
+
+
+    /**
+     * Make a form builder.
+     *
+     * @return Form
+     */
+    protected function form()
+    {
+        return Form::make(new BaseProductCategory(), function (Form $form) {
+            $form->display('id', 'ID');
+            $form->select('parent_id', trans('Parent'))
+                ->options(BaseProductCategory::selectOptions())
+                ->saving(function ($v) {
+                    return (int) $v;
+                });
+            $form->text('name')->required();
+            $form->select('parameter_id', 'parameter')->options(BaseProductParameter::selectOptions())->required();
+            $form->switch('enabled')->default(1);
+          //  $form->display('created_at');
+          //  $form->display('updated_at');
+        });
+    }
+}

+ 218 - 0
app/Admin/Controllers/BaseProductController.php

@@ -0,0 +1,218 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+use App\Admin\Repositories\BaseProduct;
+use App\Models\BaseProduct as baseProductModel;
+use Dcat\Admin\Admin;
+use Dcat\Admin\Form;
+use Dcat\Admin\Form\NestedForm;
+use Dcat\Admin\Grid;
+use Dcat\Admin\Show;
+use Dcat\Admin\Http\Controllers\AdminController;
+use App\Admin\Repositories\BaseProductCategory;
+use App\Admin\Repositories\BaseProductImage;
+use Illuminate\Http\Request;
+use App\Libraries\CommonHelper;
+class BaseProductController extends AdminController
+{
+
+    /**
+     * Make a grid builder.
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+        return Grid::make(BaseProduct::with(['baseProductCategory','images']), function (Grid $grid) {
+            $grid->column('id','ID')->sortable();
+            $grid->column('title');
+            $grid->column('sku');
+            $grid->column('base_product_category.name','Category Name');
+            $grid->column('issuance_date');
+            $grid->column('images')->display(function ($images) {
+                $images = $images->toArray();
+                $dataImages = array_column($images, 'image_url');
+                return CommonHelper::displayImage($dataImages,80);
+            });
+            $grid->column('order')->orderable();
+            $grid->column('enabled')->switch();
+            $grid->column('created_at');
+            $grid->column('updated_at')->sortable();
+            // 筛选
+            $grid->filter(function (Grid\Filter $filter) {
+                $filter->equal('sku');
+                $filter->like('title');
+                $filter->equal('category_id','Category')->select(BaseProductCategory::selectOptions());
+                $filter->equal('enabled', 'enabled')->select([
+                    1 => 'Yes',
+                    0 => 'No',
+                ]);
+            });
+            //排序
+           $grid->model()->orderBy("order",'asc')->orderBy('id', 'desc');
+        });
+    }
+
+
+
+    /**
+     * Make a show builder.
+     *
+     * @param mixed $id
+     *
+     * @return Show
+     */
+    protected function detail($id)
+    {
+        return Show::make($id, BaseProduct::with(['baseProductCategory','images']), function (Show $show) {
+            $show->field('id');
+            $show->field('title');
+            $show->field('keywords');
+            $show->field('description');
+            $show->field('sku');
+            $show->field('base_product_category.name','Category Name');
+            $show->field('issuance_date');
+            $show->field('parameters')->as(function ($items) {
+                if (is_array($items)) {
+                    // 创建表格的表头
+                    $table = '<table class="table">';
+                    $table .= '<tr><th>key</th><th>value</th></tr>';
+                    // 遍历数组并将数据填充到表格中
+                    foreach ($items as $item) {
+                        $table .= '<tr>';
+                        $table .= '<td>' . $item['key'] . '</td>';    // 商品名称
+                        $table .= '<td>' . $item['value'] . '</td>'; // 数量
+                        $table .= '</tr>';
+                    }
+                    $table .= '</table>';
+                    return $table;
+                }
+
+                return ''; // 当没有数组数据时
+            })->unescape();
+            $show->field('images')->as(function ($images) {
+                // 开始生成 HTML
+                $dataImages = array_column($images, 'image_url');
+                return CommonHelper::displayImage($dataImages,150);
+            })->unescape();
+            $show->field('content');
+            $show->field('created_at');
+            $show->field('updated_at');
+            $show->field('order');
+            $show->field('enabled')->using([
+                '0' => 'No',   // 显示的状态名称
+                '1' => 'Yes',
+            ]);
+        });
+    }
+
+
+    /**
+     * Make a form builder.
+     *
+     * @return Form
+     */
+    protected function form()
+    {
+        return Form::make(BaseProduct::with('images'), function (Form $form) {
+            $form->display('id');
+            $form->select('category_id', 'Category Name')
+                ->options(BaseProductCategory::selectOptions())
+                ->required();
+            $form->text('title')->required();
+            $form->text('keywords');
+            $form->textarea('description');
+            $form->text('sku')->required();
+            $form->date('issuance_date');
+            $form->table('parameters','Parameters', function (Form\NestedForm $table) {
+                $table->text('key')->required();
+                $table->text('value')->required();
+            });
+            // 多图上传
+            $form->multipleImage('images', 'images')
+                ->sortable() // 可拖动排序
+                ->removable() // 可移除图片
+                ->autoUpload() // 自动上传
+                ->customFormat(function () {
+                    // 数据格式化为数组['1.jpg','2.jpg']
+                    return array_column($this->images, 'image_url');
+                })
+                ->saving(function ($paths) {
+                    $paths =  array_column($paths, 'id');
+                    return $paths;
+                });
+            $form->editor('content');
+            //$form->number('order');
+            $form->switch('enabled')->default(1);
+            //插入JS
+            $this->addParametersJs();
+            //保存后执行
+            $form->saved(function (Form $form) {
+                $productId =  $form->getKey();
+                $images = explode(',',$form->input('images'));
+                //删除旧的图片记录
+                BaseProductImage::deleteByProductId($productId);
+                //插入新的图片记录
+                BaseProductImage::saveProductImages($productId, $images);
+            });
+        });
+    }
+
+    /*
+     * 以json型式返回产品参数
+     */
+    public static function parameter(Request $request)
+    {
+        $id = $request->query('q');
+        $content = BaseProductCategory::getParameter($id);
+        return $content;
+    }
+
+    /**
+     * 分类与参数联动JS
+     * @return void
+     */
+    private function addParametersJs()
+    {
+        $prefix = config('admin.route.prefix');
+        //插入JS
+        Admin::script(
+            <<<JS
+var fill_param = function (key,val) {
+    lastForm = $(".has-many-table-parameters-form:last");
+    lastForm.find('input').eq(0).val(key);
+    lastForm.find('input').eq(1).val(val);
+}
+
+$('select[name="category_id"]').on('change', function() {
+    var category_id = $(this).val();
+    // 清空现有的表格行
+    $('.has-many-table-parameters-form').remove();
+    if (category_id > 0) {
+        $.ajax({
+            url: '/{$prefix}/base-product/parameter',
+            data: { q: category_id},
+            dataType: 'json',
+            type: 'GET',              // GET
+            success: function(data) { // success
+                if (Array.isArray(data) && data.length === 0) {
+                    return null;
+                }
+                // 动态添加新数据到表格
+                $.each(data, function(index, item) {
+                    $(".has-many-table-parameters").find(".add").click();
+                    fill_param(item.key,item.value);
+                });
+            },
+            error: function(error) {  // 错误时执行的代码
+                console.log('error:', error);
+            }
+        });
+    }
+
+});
+JS
+        );
+    }
+}

+ 71 - 0
app/Admin/Controllers/BaseProductParameterController.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Admin\Controllers;
+
+use App\Admin\Repositories\BaseProductParameter;
+use Dcat\Admin\Form;
+use Dcat\Admin\Grid;
+use Dcat\Admin\Layout\Content;
+use Dcat\Admin\Show;
+use Dcat\Admin\Http\Controllers\AdminController;
+use Dcat\Admin\Form\NestedForm;
+
+class BaseProductParameterController extends AdminController
+{
+    public function index(Content $content)
+    {
+        return $content
+            ->header('Product Parameter')
+            ->description('')
+            ->body($this->grid());
+    }
+
+
+    /**
+     * Make a grid builder.
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+        return Grid::make(new BaseProductParameter(), function (Grid $grid) {
+            $grid->column('id','ID')->sortable();
+            $grid->column('name');
+            $grid->column('order')->orderable();
+            $grid->column('enabled')->switch();
+            $grid->column('created_at');
+            $grid->column('updated_at')->sortable();
+            $grid->filter(function (Grid\Filter $filter) {
+                $filter->equal('id');
+            });
+            $grid->disableViewButton();
+            $grid->showQuickEditButton();
+            $grid->enableDialogCreate();
+            $grid->disableEditButton();
+            $grid->quickSearch('name');
+            //排序
+            $grid->model()->orderBy("order",'asc')->orderBy('id', 'asc');
+        });
+    }
+
+
+    /**
+     * Make a form builder.
+     *
+     * @return Form
+     */
+    protected function form()
+    {
+        return Form::make(new BaseProductParameter(), function (Form $form) {
+            $form->display('id');
+            $form->text('name')->required();
+            $form->table('content','Parameters', function (NestedForm $table) {
+                $table->text('key')->required();
+                $table->text('value')->required();
+            })->default([
+                ['key' => 'color', 'value' => 'white'],
+            ]);
+            $form->switch('enabled')->default(1);
+        });
+    }
+}

+ 29 - 0
app/Admin/Repositories/BaseProduct.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Admin\Repositories;
+
+use App\Models\BaseProduct as Model;
+use Dcat\Admin\Form;
+use Dcat\Admin\Repositories\EloquentRepository;
+
+class BaseProduct extends EloquentRepository
+{
+    /**
+     * Model.
+     *
+     * @var string
+     */
+    protected $eloquentClass = Model::class;
+
+    /*
+     * 重写删除方法
+     */
+    public function delete(Form $form, array $originalData)
+    {
+        collect(explode(',', $form->getKey()))->filter()->each(function ($id) {
+            Model::find($id)->images()->delete();
+            Model::find($id)->delete();
+        });
+        return true;
+    }
+}

+ 41 - 0
app/Admin/Repositories/BaseProductCategory.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Admin\Repositories;
+
+use App\Models\BaseProductCategory as Model;
+use App\Models\BaseProductParameter;
+use Dcat\Admin\Repositories\EloquentRepository;
+use Dcat\Admin\Traits\HasDateTimeFormatter;
+use Dcat\Admin\Traits\ModelTree;
+
+class BaseProductCategory extends EloquentRepository
+{
+
+    /**
+     * Model.
+     *
+     * @var string
+     */
+    protected $eloquentClass = Model::class;
+
+
+
+
+    // 调用模型方法
+    public static function selectOptions(\Closure $closure = null)
+    {
+       $selectOptions =  Model::class::selectOptions($closure);
+        return $selectOptions;
+    }
+
+
+    public static function getParameter($categoryId)
+    {
+        $categoryRow =  Model::Class::find($categoryId);
+        if ($categoryRow->baseProductParameter) {
+            return $categoryRow->baseProductParameter->content;
+        } else {
+            return "[]";
+        }
+    }
+}

+ 44 - 0
app/Admin/Repositories/BaseProductImage.php

@@ -0,0 +1,44 @@
+<?php
+
+namespace App\Admin\Repositories;
+
+use App\Models\BaseProductImage as Model;
+use Dcat\Admin\Repositories\EloquentRepository;
+use Carbon\Carbon;
+
+class BaseProductImage extends EloquentRepository
+{
+    /**
+     * Model.
+     *
+     * @var string
+     */
+    protected $eloquentClass = Model::class;
+
+
+    public static function deleteByProductId($productId)
+    {
+        Model::where('product_id', $productId)->delete();
+    }
+
+    public static function saveProductImages($productId, $imageUrls)
+    {
+        if (empty($productId) || empty($imageUrl)) {
+            return false;
+        }
+        // 准备数据集合
+        $data = [];
+        foreach ($imageUrls as $imageUrl) {
+            $data[] = [
+                'product_id' => $productId,
+                'image_url' => $imageUrl,
+                'created_at' => Carbon::now(),
+                'updated_at' => Carbon::now(),
+            ];
+        }
+        // 批量插入
+        return Model::insert($data);
+    }
+
+
+}

+ 25 - 0
app/Admin/Repositories/BaseProductParameter.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace App\Admin\Repositories;
+
+use App\Models\BaseProductParameter as Model;
+use Dcat\Admin\Repositories\EloquentRepository;
+
+class BaseProductParameter extends EloquentRepository
+{
+    /**
+     * Model.
+     *
+     * @var string
+     */
+    protected $eloquentClass = Model::class;
+
+    /*
+     * Select options for filter
+     */
+    public static function selectOptions() {
+        return Model::query()->where('enabled','=','1')->get()->pluck('name', 'id');
+    }
+
+
+}

+ 16 - 0
app/Admin/Repositories/Test.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Admin\Repositories;
+
+use App\Models\Test as Model;
+use Dcat\Admin\Repositories\EloquentRepository;
+
+class Test extends EloquentRepository
+{
+    /**
+     * Model.
+     *
+     * @var string
+     */
+    protected $eloquentClass = Model::class;
+}

+ 9 - 2
app/Admin/routes.php

@@ -11,7 +11,14 @@ Route::group([
     'namespace'  => config('admin.route.namespace'),
     'middleware' => config('admin.route.middleware'),
 ], function (Router $router) {
-
+    //主页
     $router->get('/', 'HomeController@index');
-
+    $router->resource('test', 'TestController');
+    //产品
+    $router->get('base-product/parameter', 'BaseProductController@parameter');
+    $router->resource('base-product', 'BaseProductController');
+    //分类
+    $router->resource('product-category', 'BaseProductCategoryController');
+    //参数
+    $router->resource('product-parameter', 'BaseProductParameterController');
 });

+ 9 - 0
app/Distributor/Controllers/AuthController.php

@@ -0,0 +1,9 @@
+<?php
+
+namespace App\Distributor\Controllers;
+
+use Dcat\Admin\Http\Controllers\AuthController as BaseAuthController;
+
+class AuthController extends BaseAuthController
+{
+}

+ 36 - 0
app/Distributor/Controllers/HomeController.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Distributor\Controllers;
+
+use App\Distributor\Metrics\Examples;
+use App\Http\Controllers\Controller;
+use Dcat\Admin\Http\Controllers\Dashboard;
+use Dcat\Admin\Layout\Column;
+use Dcat\Admin\Layout\Content;
+use Dcat\Admin\Layout\Row;
+
+class HomeController extends Controller
+{
+    public function index(Content $content)
+    {
+        return $content
+            ->header('Dashboard')
+            ->description('Description...')
+            ->body(function (Row $row) {
+                $row->column(6, function (Column $column) {
+                    $column->row(Dashboard::title());
+                    $column->row(new Examples\Tickets());
+                });
+
+                $row->column(6, function (Column $column) {
+                    $column->row(function (Row $row) {
+                        $row->column(6, new Examples\NewUsers());
+                        $row->column(6, new Examples\NewDevices());
+                    });
+
+                    $column->row(new Examples\Sessions());
+                    $column->row(new Examples\ProductOrders());
+                });
+            });
+    }
+}

+ 100 - 0
app/Distributor/Metrics/Examples/NewDevices.php

@@ -0,0 +1,100 @@
+<?php
+
+namespace App\Distributor\Metrics\Examples;
+
+use Dcat\Admin\Admin;
+use Dcat\Admin\Widgets\Metrics\Donut;
+
+class NewDevices extends Donut
+{
+    protected $labels = ['Desktop', 'Mobile'];
+
+    /**
+     * 初始化卡片内容
+     */
+    protected function init()
+    {
+        parent::init();
+
+        $color = Admin::color();
+        $colors = [$color->primary(), $color->alpha('blue2', 0.5)];
+
+        $this->title('New Devices');
+        $this->subTitle('Last 30 days');
+        $this->chartLabels($this->labels);
+        // 设置图表颜色
+        $this->chartColors($colors);
+    }
+
+    /**
+     * 渲染模板
+     *
+     * @return string
+     */
+    public function render()
+    {
+        $this->fill();
+
+        return parent::render();
+    }
+
+    /**
+     * 写入数据.
+     *
+     * @return void
+     */
+    public function fill()
+    {
+        $this->withContent(44.9, 28.6);
+
+        // 图表数据
+        $this->withChart([44.9, 28.6]);
+    }
+
+    /**
+     * 设置图表数据.
+     *
+     * @param array $data
+     *
+     * @return $this
+     */
+    public function withChart(array $data)
+    {
+        return $this->chart([
+            'series' => $data
+        ]);
+    }
+
+    /**
+     * 设置卡片头部内容.
+     *
+     * @param mixed $desktop
+     * @param mixed $mobile
+     *
+     * @return $this
+     */
+    protected function withContent($desktop, $mobile)
+    {
+        $blue = Admin::color()->alpha('blue2', 0.5);
+
+        $style = 'margin-bottom: 8px';
+        $labelWidth = 120;
+
+        return $this->content(
+            <<<HTML
+<div class="d-flex pl-1 pr-1 pt-1" style="{$style}">
+    <div style="width: {$labelWidth}px">
+        <i class="fa fa-circle text-primary"></i> {$this->labels[0]}
+    </div>
+    <div>{$desktop}</div>
+</div>
+<div class="d-flex pl-1 pr-1" style="{$style}">
+    <div style="width: {$labelWidth}px">
+        <i class="fa fa-circle" style="color: $blue"></i> {$this->labels[1]}
+    </div>
+    <div>{$mobile}</div>
+</div>
+HTML
+        );
+    }
+}

+ 108 - 0
app/Distributor/Metrics/Examples/NewUsers.php

@@ -0,0 +1,108 @@
+<?php
+
+namespace App\Distributor\Metrics\Examples;
+
+use Dcat\Admin\Widgets\Metrics\Line;
+use Illuminate\Http\Request;
+
+class NewUsers extends Line
+{
+    /**
+     * 初始化卡片内容
+     *
+     * @return void
+     */
+    protected function init()
+    {
+        parent::init();
+
+        $this->title('New Users');
+        $this->dropdown([
+            '7' => 'Last 7 Days',
+            '28' => 'Last 28 Days',
+            '30' => 'Last Month',
+            '365' => 'Last Year',
+        ]);
+    }
+
+    /**
+     * 处理请求
+     *
+     * @param Request $request
+     *
+     * @return mixed|void
+     */
+    public function handle(Request $request)
+    {
+        $generator = function ($len, $min = 10, $max = 300) {
+            for ($i = 0; $i <= $len; $i++) {
+                yield mt_rand($min, $max);
+            }
+        };
+
+        switch ($request->get('option')) {
+            case '365':
+                // 卡片内容
+                $this->withContent(mt_rand(1000, 5000).'k');
+                // 图表数据
+                $this->withChart(collect($generator(30))->toArray());
+                break;
+            case '30':
+                // 卡片内容
+                $this->withContent(mt_rand(400, 1000).'k');
+                // 图表数据
+                $this->withChart(collect($generator(30))->toArray());
+                break;
+            case '28':
+                // 卡片内容
+                $this->withContent(mt_rand(400, 1000).'k');
+                // 图表数据
+                $this->withChart(collect($generator(28))->toArray());
+                break;
+            case '7':
+            default:
+                // 卡片内容
+                $this->withContent('89.2k');
+                // 图表数据
+                $this->withChart([28, 40, 36, 52, 38, 60, 55,]);
+        }
+    }
+
+    /**
+     * 设置图表数据.
+     *
+     * @param array $data
+     *
+     * @return $this
+     */
+    public function withChart(array $data)
+    {
+        return $this->chart([
+            'series' => [
+                [
+                    'name' => $this->title,
+                    'data' => $data,
+                ],
+            ],
+        ]);
+    }
+
+    /**
+     * 设置卡片内容.
+     *
+     * @param string $content
+     *
+     * @return $this
+     */
+    public function withContent($content)
+    {
+        return $this->content(
+            <<<HTML
+<div class="d-flex justify-content-between align-items-center mt-1" style="margin-bottom: 2px">
+    <h2 class="ml-1 font-lg-1">{$content}</h2>
+    <span class="mb-0 mr-1 text-80">{$this->title}</span>
+</div>
+HTML
+        );
+    }
+}

+ 114 - 0
app/Distributor/Metrics/Examples/ProductOrders.php

@@ -0,0 +1,114 @@
+<?php
+
+namespace App\Distributor\Metrics\Examples;
+
+use Dcat\Admin\Widgets\Metrics\Round;
+use Illuminate\Http\Request;
+
+class ProductOrders extends Round
+{
+    /**
+     * 初始化卡片内容
+     */
+    protected function init()
+    {
+        parent::init();
+
+        $this->title('Product Orders');
+        $this->chartLabels(['Finished', 'Pending', 'Rejected']);
+        $this->dropdown([
+            '7' => 'Last 7 Days',
+            '28' => 'Last 28 Days',
+            '30' => 'Last Month',
+            '365' => 'Last Year',
+        ]);
+    }
+
+    /**
+     * 处理请求
+     *
+     * @param Request $request
+     *
+     * @return mixed|void
+     */
+    public function handle(Request $request)
+    {
+        switch ($request->get('option')) {
+            case '365':
+            case '30':
+            case '28':
+            case '7':
+            default:
+                // 卡片内容
+                $this->withContent(23043, 14658, 4758);
+
+                // 图表数据
+                $this->withChart([70, 52, 26]);
+
+                // 总数
+                $this->chartTotal('Total', 344);
+        }
+    }
+
+    /**
+     * 设置图表数据.
+     *
+     * @param array $data
+     *
+     * @return $this
+     */
+    public function withChart(array $data)
+    {
+        return $this->chart([
+            'series' => $data,
+        ]);
+    }
+
+    /**
+     * 卡片内容.
+     *
+     * @param int $finished
+     * @param int $pending
+     * @param int $rejected
+     *
+     * @return $this
+     */
+    public function withContent($finished, $pending, $rejected)
+    {
+        return $this->content(
+            <<<HTML
+<div class="col-12 d-flex flex-column flex-wrap text-center" style="max-width: 220px">
+    <div class="chart-info d-flex justify-content-between mb-1 mt-2" >
+          <div class="series-info d-flex align-items-center">
+              <i class="fa fa-circle-o text-bold-700 text-primary"></i>
+              <span class="text-bold-600 ml-50">Finished</span>
+          </div>
+          <div class="product-result">
+              <span>{$finished}</span>
+          </div>
+    </div>
+
+    <div class="chart-info d-flex justify-content-between mb-1">
+          <div class="series-info d-flex align-items-center">
+              <i class="fa fa-circle-o text-bold-700 text-warning"></i>
+              <span class="text-bold-600 ml-50">Pending</span>
+          </div>
+          <div class="product-result">
+              <span>{$pending}</span>
+          </div>
+    </div>
+
+     <div class="chart-info d-flex justify-content-between mb-1">
+          <div class="series-info d-flex align-items-center">
+              <i class="fa fa-circle-o text-bold-700 text-danger"></i>
+              <span class="text-bold-600 ml-50">Rejected</span>
+          </div>
+          <div class="product-result">
+              <span>{$rejected}</span>
+          </div>
+    </div>
+</div>
+HTML
+        );
+    }
+}

+ 117 - 0
app/Distributor/Metrics/Examples/Sessions.php

@@ -0,0 +1,117 @@
+<?php
+
+namespace App\Distributor\Metrics\Examples;
+
+use Dcat\Admin\Admin;
+use Dcat\Admin\Widgets\Metrics\Bar;
+use Illuminate\Http\Request;
+
+class Sessions extends Bar
+{
+    /**
+     * 初始化卡片内容
+     */
+    protected function init()
+    {
+        parent::init();
+
+        $color = Admin::color();
+
+        $dark35 = $color->dark35();
+
+        // 卡片内容宽度
+        $this->contentWidth(5, 7);
+        // 标题
+        $this->title('Avg Sessions');
+        // 设置下拉选项
+        $this->dropdown([
+            '7' => 'Last 7 Days',
+            '28' => 'Last 28 Days',
+            '30' => 'Last Month',
+            '365' => 'Last Year',
+        ]);
+        // 设置图表颜色
+        $this->chartColors([
+            $dark35,
+            $dark35,
+            $color->primary(),
+            $dark35,
+            $dark35,
+            $dark35
+        ]);
+    }
+
+    /**
+     * 处理请求
+     *
+     * @param Request $request
+     *
+     * @return mixed|void
+     */
+    public function handle(Request $request)
+    {
+        switch ($request->get('option')) {
+            case '7':
+            default:
+                // 卡片内容
+                $this->withContent('2.7k', '+5.2%');
+
+                // 图表数据
+                $this->withChart([
+                    [
+                        'name' => 'Sessions',
+                        'data' => [75, 125, 225, 175, 125, 75, 25],
+                    ],
+                ]);
+        }
+    }
+
+    /**
+     * 设置图表数据.
+     *
+     * @param array $data
+     *
+     * @return $this
+     */
+    public function withChart(array $data)
+    {
+        return $this->chart([
+            'series' => $data,
+        ]);
+    }
+
+    /**
+     * 设置卡片内容.
+     *
+     * @param string $title
+     * @param string $value
+     * @param string $style
+     *
+     * @return $this
+     */
+    public function withContent($title, $value, $style = 'success')
+    {
+        // 根据选项显示
+        $label = strtolower(
+            $this->dropdown[request()->option] ?? 'last 7 days'
+        );
+
+        $minHeight = '183px';
+
+        return $this->content(
+            <<<HTML
+<div class="d-flex p-1 flex-column justify-content-between" style="padding-top: 0;width: 100%;height: 100%;min-height: {$minHeight}">
+    <div class="text-left">
+        <h1 class="font-lg-2 mt-2 mb-0">{$title}</h1>
+        <h5 class="font-medium-2" style="margin-top: 10px;">
+            <span class="text-{$style}">{$value} </span>
+            <span>vs {$label}</span>
+        </h5>
+    </div>
+
+    <a href="#" class="btn btn-primary shadow waves-effect waves-light">View Details <i class="feather icon-chevrons-right"></i></a>
+</div>
+HTML
+        );
+    }
+}

+ 116 - 0
app/Distributor/Metrics/Examples/Tickets.php

@@ -0,0 +1,116 @@
+<?php
+
+namespace App\Distributor\Metrics\Examples;
+
+use Dcat\Admin\Widgets\Metrics\RadialBar;
+use Illuminate\Http\Request;
+
+class Tickets extends RadialBar
+{
+    /**
+     * 初始化卡片内容
+     */
+    protected function init()
+    {
+        parent::init();
+
+        $this->title('Tickets');
+        $this->height(400);
+        $this->chartHeight(300);
+        $this->chartLabels('Completed Tickets');
+        $this->dropdown([
+            '7' => 'Last 7 Days',
+            '28' => 'Last 28 Days',
+            '30' => 'Last Month',
+            '365' => 'Last Year',
+        ]);
+    }
+
+    /**
+     * 处理请求
+     *
+     * @param Request $request
+     *
+     * @return mixed|void
+     */
+    public function handle(Request $request)
+    {
+        switch ($request->get('option')) {
+            case '365':
+            case '30':
+            case '28':
+            case '7':
+            default:
+                // 卡片内容
+                $this->withContent(162);
+                // 卡片底部
+                $this->withFooter(29, 63, '1d');
+                // 图表数据
+                $this->withChart(83);
+        }
+    }
+
+    /**
+     * 设置图表数据.
+     *
+     * @param int $data
+     *
+     * @return $this
+     */
+    public function withChart(int $data)
+    {
+        return $this->chart([
+            'series' => [$data],
+        ]);
+    }
+
+    /**
+     * 卡片内容
+     *
+     * @param string $content
+     *
+     * @return $this
+     */
+    public function withContent($content)
+    {
+        return $this->content(
+            <<<HTML
+<div class="d-flex flex-column flex-wrap text-center">
+    <h1 class="font-lg-2 mt-2 mb-0">{$content}</h1>
+    <small>Tickets</small>
+</div>
+HTML
+        );
+    }
+
+    /**
+     * 卡片底部内容.
+     *
+     * @param string $new
+     * @param string $open
+     * @param string $response
+     *
+     * @return $this
+     */
+    public function withFooter($new, $open, $response)
+    {
+        return $this->footer(
+            <<<HTML
+<div class="d-flex justify-content-between p-1" style="padding-top: 0!important;">
+    <div class="text-center">
+        <p>New Tickets</p>
+        <span class="font-lg-1">{$new}</span>
+    </div>
+    <div class="text-center">
+        <p>Open Tickets</p>
+        <span class="font-lg-1">{$open}</span>
+    </div>
+    <div class="text-center">
+        <p>Response Time</p>
+        <span class="font-lg-1">{$response}</span>
+    </div>
+</div>
+HTML
+        );
+    }
+}

+ 129 - 0
app/Distributor/Metrics/Examples/TotalUsers.php

@@ -0,0 +1,129 @@
+<?php
+
+namespace App\Distributor\Metrics\Examples;
+
+use Dcat\Admin\Widgets\Metrics\Card;
+use Illuminate\Contracts\Support\Renderable;
+use Illuminate\Http\Request;
+
+class TotalUsers extends Card
+{
+    /**
+     * 卡片底部内容.
+     *
+     * @var string|Renderable|\Closure
+     */
+    protected $footer;
+
+    /**
+     * 初始化卡片.
+     */
+    protected function init()
+    {
+        parent::init();
+
+        $this->title('Total Users');
+        $this->dropdown([
+            '7' => 'Last 7 Days',
+            '28' => 'Last 28 Days',
+            '30' => 'Last Month',
+            '365' => 'Last Year',
+        ]);
+    }
+
+    /**
+     * 处理请求.
+     *
+     * @param Request $request
+     *
+     * @return void
+     */
+    public function handle(Request $request)
+    {
+        switch ($request->get('option')) {
+            case '365':
+                $this->content(mt_rand(600, 1500));
+                $this->down(mt_rand(1, 30));
+                break;
+            case '30':
+                $this->content(mt_rand(170, 250));
+                $this->up(mt_rand(12, 50));
+                break;
+            case '28':
+                $this->content(mt_rand(155, 200));
+                $this->up(mt_rand(5, 50));
+                break;
+            case '7':
+            default:
+                $this->content(143);
+                $this->up(15);
+        }
+    }
+
+    /**
+     * @param int $percent
+     *
+     * @return $this
+     */
+    public function up($percent)
+    {
+        return $this->footer(
+            "<i class=\"feather icon-trending-up text-success\"></i> {$percent}% Increase"
+        );
+    }
+
+    /**
+     * @param int $percent
+     *
+     * @return $this
+     */
+    public function down($percent)
+    {
+        return $this->footer(
+            "<i class=\"feather icon-trending-down text-danger\"></i> {$percent}% Decrease"
+        );
+    }
+
+    /**
+     * 设置卡片底部内容.
+     *
+     * @param string|Renderable|\Closure $footer
+     *
+     * @return $this
+     */
+    public function footer($footer)
+    {
+        $this->footer = $footer;
+
+        return $this;
+    }
+
+    /**
+     * 渲染卡片内容.
+     *
+     * @return string
+     */
+    public function renderContent()
+    {
+        $content = parent::renderContent();
+
+        return <<<HTML
+<div class="d-flex justify-content-between align-items-center mt-1" style="margin-bottom: 2px">
+    <h2 class="ml-1 font-lg-1">{$content}</h2>
+</div>
+<div class="ml-1 mt-1 font-weight-bold text-80">
+    {$this->renderFooter()}
+</div>
+HTML;
+    }
+
+    /**
+     * 渲染卡片底部内容.
+     *
+     * @return string
+     */
+    public function renderFooter()
+    {
+        return $this->toString($this->footer);
+    }
+}

+ 26 - 0
app/Distributor/bootstrap.php

@@ -0,0 +1,26 @@
+<?php
+
+use Dcat\Admin\Admin;
+use Dcat\Admin\Grid;
+use Dcat\Admin\Form;
+use Dcat\Admin\Grid\Filter;
+use Dcat\Admin\Show;
+
+/**
+ * Dcat-admin - admin builder based on Laravel.
+ * @author jqh <https://github.com/jqhph>
+ *
+ * Bootstraper for Admin.
+ *
+ * Here you can remove builtin form field:
+ *
+ * extend custom field:
+ * Dcat\Admin\Form::extend('php', PHPEditor::class);
+ * Dcat\Admin\Grid\Column::extend('php', PHPEditor::class);
+ * Dcat\Admin\Grid\Filter::extend('php', PHPEditor::class);
+ *
+ * Or require js and css assets:
+ * Admin::css('/packages/prettydocs/css/styles.css');
+ * Admin::js('/packages/prettydocs/js/main.js');
+ *
+ */

+ 27 - 0
app/Distributor/routes.php

@@ -0,0 +1,27 @@
+<?php
+
+use Illuminate\Routing\Router;
+use Illuminate\Support\Facades\Route;
+use Dcat\Admin\Admin;
+use App\Http\Middleware\DistAuth;
+use Illuminate\Http\Request;
+
+/**
+ * 原后台框架路由
+ */
+Admin::routes();
+
+Route::group([
+    'prefix'     => config('admin.route.prefix'),
+    'namespace'  => config('admin.route.namespace'),
+    'middleware' => config('admin.route.middleware'),
+], function (Router $router) {
+
+    $router->get('/', 'HomeController@index');
+
+});
+
+
+
+
+

+ 1 - 0
app/Http/Kernel.php

@@ -63,5 +63,6 @@ class Kernel extends HttpKernel
         'signed' => \App\Http\Middleware\ValidateSignature::class,
         'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
         'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
+        'distauth' => \App\Http\Middleware\DistAuth::class,
     ];
 }

+ 26 - 0
app/Libraries/CommonHelper.php

@@ -0,0 +1,26 @@
+<?php
+
+// app/Libraries/CommonHelper.php
+namespace App\Libraries;
+
+class CommonHelper
+{
+
+    /*
+     * $images 格式:['image.jpg','image2.jpg']
+     * 返回显示的HTML
+     */
+    public static function displayImage($images,$size=150)
+    {
+        $html = '<div style="display: flex; flex-wrap: wrap; gap: 5px;">';
+        foreach ($images as $image) {
+            $html .= "<div style='flex: 1 0 {$size}px; max-width: {$size}px; max-height: {$size}px; padding: 5px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); display: flex; align-items: center; justify-content: center;'>
+                    <img  data-action='preview-img' src='" . asset('storage/' . $image) . "' style='max-width: 100%; max-height: 100%; object-fit: contain;'>
+                  </div>";
+        }
+        $html .= '</div>';
+        return $html;
+    }
+
+}
+

+ 41 - 0
app/Models/BaseProduct.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Models;
+
+use Dcat\Admin\Traits\HasDateTimeFormatter;
+
+use Dcat\Admin\Traits\ModelTree;
+use Illuminate\Database\Eloquent\Model;
+use Spatie\EloquentSortable\Sortable;
+use Spatie\EloquentSortable\SortableTrait;
+
+class BaseProduct extends Model implements Sortable
+{
+    use HasDateTimeFormatter;
+    use SortableTrait;
+
+    protected $table = 'base_product';
+
+    // 可选:你可以在这里自定义排序配置
+    public $sortable = [
+        'order_column_name' => 'order',  // 排序字段
+        'sort_when_creating' => true,    // 创建时自动排序
+    ];
+
+    protected $casts = [
+        'created_at' => 'datetime:Y-m-d H:i:s',
+        'updated_at' => 'datetime:Y-m-d H:i:s',
+        'parameters' => 'json', // 将 attributes 字段转换为数组
+    ];
+
+    public function baseProductCategory()
+    {
+        return $this->hasOne(BaseProductCategory::class,'id','category_id');
+    }
+
+    // 一对多关联
+    public function images()
+    {
+        return $this->hasMany(BaseProductImage::class, 'product_id');
+    }
+}

+ 46 - 0
app/Models/BaseProductCategory.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Models;
+
+use Dcat\Admin\Traits\HasDateTimeFormatter;
+
+use Dcat\Admin\Traits\ModelTree;
+use Illuminate\Database\Eloquent\Model;
+use Spatie\EloquentSortable\Sortable;
+
+class BaseProductCategory extends Model implements Sortable
+{
+    use HasDateTimeFormatter,
+        ModelTree {
+        ModelTree::boot as treeBoot;
+    }
+
+    protected $casts = [
+        'created_at' => 'datetime:Y-m-d H:i:s',
+        'updated_at' => 'datetime:Y-m-d H:i:s',
+    ];
+
+    //名称
+    protected $titleColumn = 'name';
+    //排序
+    protected $orderColumn = 'order';
+    //父级
+    protected $parentColumn = 'parent_id';
+
+    protected $table = 'base_product_category';
+
+    /*
+     * 关联产品参数
+     */
+    public function baseProductParameter()
+    {
+        return $this->hasOne(BaseProductParameter::class,'id','parameter_id');
+    }
+
+
+    public static function selectOptions(\Closure $closure = null)
+    {
+        $options = (new static())->withQuery($closure)->buildSelectOptions();
+        return collect($options)->all();
+    }
+}

+ 23 - 0
app/Models/BaseProductImage.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace App\Models;
+
+use Dcat\Admin\Traits\HasDateTimeFormatter;
+use Illuminate\Database\Eloquent\Model;
+
+class BaseProductImage extends Model
+{
+	use HasDateTimeFormatter;
+    protected $table = 'base_product_image';
+
+    protected $casts = [
+        'created_at' => 'datetime:Y-m-d H:i:s',
+        'updated_at' => 'datetime:Y-m-d H:i:s',
+    ];
+
+    // 反向关联,属于某个产品
+    public function product()
+    {
+        return $this->belongsTo(BaseProduct::class, 'id');
+    }
+}

+ 35 - 0
app/Models/BaseProductParameter.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace App\Models;
+
+
+use Dcat\Admin\Traits\HasDateTimeFormatter;
+
+use Dcat\Admin\Traits\ModelTree;
+use Illuminate\Database\Eloquent\Model;
+use Spatie\EloquentSortable\Sortable;
+use Spatie\EloquentSortable\SortableTrait;
+use Illuminate\Database\Eloquent\Builder;
+
+class BaseProductParameter extends Model implements Sortable
+{
+    use SortableTrait;
+
+    protected $table = 'base_product_parameter';
+
+
+
+    protected $casts = [
+        'created_at' => 'datetime:Y-m-d H:i:s',
+        'updated_at' => 'datetime:Y-m-d H:i:s',
+        'content' => 'json', // 将 attributes 字段转换为数组
+    ];
+
+
+    // 可选:你可以在这里自定义排序配置
+    public $sortable = [
+        'order_column_name' => 'order',  // 排序字段
+        'sort_when_creating' => true,    // 创建时自动排序
+    ];
+
+}

+ 9 - 0
app/Models/DistAdminMenu.php

@@ -0,0 +1,9 @@
+<?php
+
+namespace App\Models;
+use Dcat\Admin\Models\Menu;
+
+class DistAdminMenu extends Menu
+{
+    protected $table = 'dist_admin_menu';
+}

+ 6 - 6
config/admin.php

@@ -76,7 +76,7 @@ return [
     'route' => [
         'domain' => env('ADMIN_ROUTE_DOMAIN'),
 
-        'prefix' => env('ADMIN_ROUTE_PREFIX', 'admin'),
+        'prefix' => env('ADMIN_ROUTE_PREFIX', 'prime-control'),
 
         'namespace' => 'App\\Admin\\Controllers',
 
@@ -382,10 +382,10 @@ return [
     |--------------------------------------------------------------------------
     | 多应用
     |--------------------------------------------------------------------------
-    */ 
-    'multi_app'                 => [
-        // 'seller'    => true,
-        // 'reseller'  => true,
-        // 'brand'     => true,
+    */
+    'multi_app' => [
+        // 与新应用的配置文件名称一致
+        // 设置为true启用,false则是停用
+        'distributor' => true,
     ],
 ];

+ 354 - 0
config/distributor.php

@@ -0,0 +1,354 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin name
+    |--------------------------------------------------------------------------
+    |
+    | This value is the name of dcat-admin, This setting is displayed on the
+    | login page.
+    |
+    */
+    'name' => 'Distributor Admin',
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin logo
+    |--------------------------------------------------------------------------
+    |
+    | The logo of all admin pages. You can also set it as an image by using a
+    | `img` tag, eg '<img src="http://logo-url" alt="Admin logo">'.
+    |
+    */
+    'logo' => '<img src="/vendor/dcat-admin/images/logo.png" width="35"> &nbsp;Dcat Admin',
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin mini logo
+    |--------------------------------------------------------------------------
+    |
+    | The logo of all admin pages when the sidebar menu is collapsed. You can
+    | also set it as an image by using a `img` tag, eg
+    | '<img src="http://logo-url" alt="Admin logo">'.
+    |
+    */
+    'logo-mini' => '<img src="/vendor/dcat-admin/images/logo.png">',
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin favicon
+    |--------------------------------------------------------------------------
+    |
+    */
+    'favicon' => null,
+
+    /*
+	 |--------------------------------------------------------------------------
+	 | User default avatar
+	 |--------------------------------------------------------------------------
+	 |
+	 | Set a default avatar for newly created users.
+	 |
+	 */
+	'default_avatar' => '@admin/images/default-avatar.jpg',
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin route settings
+    |--------------------------------------------------------------------------
+    |
+    | The routing configuration of the admin page, including the path prefix,
+    | the controller namespace, and the default middleware. If you want to
+    | access through the root path, just set the prefix to empty string.
+    |
+    */
+    'route' => [
+        'domain' => env('ADMIN_ROUTE_DOMAIN'),
+
+        'prefix' => 'dist',
+
+        'namespace' => 'App\\Distributor\\Controllers',
+
+        'middleware' => ['web', 'admin','distauth'],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin install directory
+    |--------------------------------------------------------------------------
+    |
+    | The installation directory of the controller and routing configuration
+    | files of the administration page. The default is `app/Admin`, which must
+    | be set before running `artisan admin::install` to take effect.
+    |
+    */
+    'directory' => app_path('Distributor'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin html title
+    |--------------------------------------------------------------------------
+    |
+    | Html title for all pages.
+    |
+    */
+    'title' => 'Distributor',
+
+    /*
+    |--------------------------------------------------------------------------
+    | Assets hostname
+    |--------------------------------------------------------------------------
+    |
+   */
+    'assets_server' => env('ADMIN_ASSETS_SERVER'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Access via `https`
+    |--------------------------------------------------------------------------
+    |
+    | If your page is going to be accessed via https, set it to `true`.
+    |
+    */
+    'https' => env('ADMIN_HTTPS', false),
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin auth setting
+    |--------------------------------------------------------------------------
+    |
+    | Authentication settings for all admin pages. Include an authentication
+    | guard and a user provider setting of authentication driver.
+    |
+    | You can specify a controller for `login` `logout` and other auth routes.
+    |
+    */
+    'auth' => [
+        'enable' => true,
+
+        'controller' => App\Distributor\Controllers\AuthController::class,
+
+        'guard' => 'distributor',
+
+        'guards' => [
+            'distributor' => [
+                'driver'   => 'session',
+                'provider' => 'distributor',
+            ],
+        ],
+
+        'providers' => [
+            'distributor' => [
+                'driver' => 'eloquent',
+                'model'  => Dcat\Admin\Models\Administrator::class,
+            ],
+        ],
+
+        // Add "remember me" to login form
+        'remember' => true,
+
+        // All method to path like: auth/users/*/edit
+        // or specific method to path like: get:auth/users.
+        'except' => [
+            'auth/login',
+            'auth/logout',
+        ],
+
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | The global Grid setting
+    |--------------------------------------------------------------------------
+    */
+    'grid' => [
+
+        // The global Grid action display class.
+        'grid_action_class' => Dcat\Admin\Grid\Displayers\DropdownActions::class,
+
+        // The global Grid batch action display class.
+        'batch_action_class' => Dcat\Admin\Grid\Tools\BatchActions::class,
+
+        // The global Grid pagination display class.
+        'paginator_class' => Dcat\Admin\Grid\Tools\Paginator::class,
+
+        'actions' => [
+            'view' => Dcat\Admin\Grid\Actions\Show::class,
+            'edit' => Dcat\Admin\Grid\Actions\Edit::class,
+            'quick_edit' => Dcat\Admin\Grid\Actions\QuickEdit::class,
+            'delete' => Dcat\Admin\Grid\Actions\Delete::class,
+            'batch_delete' => Dcat\Admin\Grid\Tools\BatchDelete::class,
+        ],
+
+        // The global Grid column selector setting.
+        'column_selector' => [
+            'store' => Dcat\Admin\Grid\ColumnSelector\SessionStore::class,
+            'store_params' => [
+                'driver' => 'file',
+            ],
+        ],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin helpers setting.
+    |--------------------------------------------------------------------------
+    */
+    'helpers' => [
+        'enable' => true,
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin permission setting
+    |--------------------------------------------------------------------------
+    |
+    | Permission settings for all admin pages.
+    |
+    */
+    'permission' => [
+        // Whether enable permission.
+        'enable' => true,
+
+        // All method to path like: auth/users/*/edit
+        // or specific method to path like: get:auth/users.
+        'except' => [
+            '/',
+            'auth/login',
+            'auth/logout',
+            'auth/setting',
+        ],
+
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin menu setting
+    |--------------------------------------------------------------------------
+    |
+    */
+    'menu' => [
+        'cache' => [
+            // enable cache or not
+            'enable' => false,
+            'store'  => 'file',
+        ],
+
+        // Whether enable menu bind to a permission.
+        'bind_permission' => true,
+
+        // Whether enable role bind to menu.
+        'role_bind_menu' => true,
+
+        // Whether enable permission bind to menu.
+        'permission_bind_menu' => true,
+
+		'default_icon' => 'feather icon-circle',
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin upload setting
+    |--------------------------------------------------------------------------
+    |
+    | File system configuration for form upload files and images, including
+    | disk and upload path.
+    |
+    */
+    'upload' => [
+
+        // Disk in `config/filesystem.php`.
+        'disk' => 'public',
+
+        // Image and file upload path under the disk above.
+        'directory' => [
+            'image' => 'images',
+            'file'  => 'files',
+        ],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | dcat-admin database settings
+    |--------------------------------------------------------------------------
+    |
+    | Here are database settings for dcat-admin builtin model & tables.
+    |
+    */
+    'database' => [
+
+        // Database connection for following tables.
+        'connection' => '',
+
+        // User tables and model.
+        'users_table' => 'dist_admin_users',
+        'users_model' => Dcat\Admin\Models\Administrator::class,
+
+        // Role table and model.
+        'roles_table' => 'dist_admin_roles',
+        'roles_model' => Dcat\Admin\Models\Role::class,
+
+        // Permission table and model.
+        'permissions_table' => 'dist_admin_permissions',
+        'permissions_model' => Dcat\Admin\Models\Permission::class,
+
+        // Menu table and model.
+        'menu_table' => 'dist_admin_menu',
+        'menu_model' => App\Models\DistAdminMenu::class,
+
+        // Pivot table for table above.
+        'role_users_table'       => 'dist_admin_role_users',
+        'role_permissions_table' => 'dist_admin_role_permissions',
+        'role_menu_table'        => 'dist_admin_role_menu',
+        'permission_menu_table'  => 'dist_admin_permission_menu',
+        'settings_table'         => 'admin_settings',
+		'extensions_table'       => 'admin_extensions',
+		'extension_histories_table' => 'admin_extension_histories',
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Application layout
+    |--------------------------------------------------------------------------
+    |
+    | This value is the layout of admin pages.
+    */
+    'layout' => [
+        // default, blue, blue-light, green
+        'color' => 'default',
+
+		// sidebar-separate
+        'body_class' => [],
+
+        'horizontal_menu' => false,
+
+        'sidebar_collapsed' => false,
+
+        // light, primary, dark
+		'sidebar_style' => 'light',
+
+        'dark_mode_switch' => false,
+
+        // bg-primary, bg-info, bg-warning, bg-success, bg-danger, bg-dark
+        'navbar_color' => '',
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | The exception handler class
+    |--------------------------------------------------------------------------
+    |
+    */
+    'exception_handler' => Dcat\Admin\Exception\Handler::class,
+
+    /*
+    |--------------------------------------------------------------------------
+    | Enable default breadcrumb
+    |--------------------------------------------------------------------------
+    |
+    | Whether enable default breadcrumb for every page content.
+    */
+    'enable_default_breadcrumb' => true,
+];