蒸馏厂/可消耗

可消耗是一个基于laravel 5.*的行政面板。此包为您提供了一些实现,以便添加您应用程序的内容管理系统。您可以覆盖一切。此CMS提供了一些工具,以便您可以轻松且正确地开发内容管理系统。

安装: 8,752

依赖: 2

建议者: 0

安全性: 0

星标: 29

观察者: 9

分支: 8

开放问题: 0

语言:CSS

2.24.1 2019-07-10 15:33 UTC

README

Scrutinizer Code Quality Code Coverage Build Status Total Downloads Latest Stable Version License

可消耗

可消耗是一个基于laravel 5.6.*的行政面板。此包为您提供了一些实现,以便添加您应用程序的内容管理系统。您可以覆盖一切。此CMS提供了一些工具,以便您可以轻松且正确地开发内容管理系统。

目录

  1. 需求
  2. 安装
  3. 配置
  4. 菜单
  5. 状态
    1. 数据表
    2. 订单
    3. 导出
    4. 导入
    5. 表单
  6. 组件
    1. Admin BaseComponent
    2. Admin ModelBaseController
    3. AdminBaseController
  7. 模型
  8. 全局作用域
    1. 状态
  9. 权限
  10. 视图
  11. 资产(CSS和JavaScript)
    1. Sass
    2. 图片
    3. JavaScript
    4. Gulp
  12. 创建新的后端模块
  13. 案例研究
    1. 生成迁移
    2. 生成模型
    3. 生成组件
    4. 将控制器添加到路由文件中
    5. 添加到菜单中

需求

要使用此项目,您必须安装

  1. Php 7.1.3或更高版本
  2. 启用mpcrypt
  3. Composer https://getcomposer.org.cn/download/
  4. Sass (gem install sass)
  5. NodeJs版本v9.4.0

安装

在您的composer.json中添加

    "require": {
        "distilleries/expendable": "2.*",
    }

运行composer update

将应用程序覆盖添加到bootstrap/app.php

$app = new \Distilleries\Expendable\Fondation\Application(
    realpath(__DIR__ . '/../')
);


$app->bind('path.storage', function ($app) {
    $path = env('STORAGE_PATH', base_path() . DIRECTORY_SEPARATOR . 'storage');

    return $path;
});

我添加了一个绑定事件来覆盖存储路径。如果您想覆盖它,只需在您的.env中添加STORAGE_PATH=。如果您不想覆盖它,只需将其放在您的.env中。

将服务提供程序添加到config/app.php

    'providers' => [
        
        /*
         * Package Service Providers...
         */
        Laravel\Tinker\TinkerServiceProvider::class,
        Distilleries\FormBuilder\FormBuilderServiceProvider::class,
        Distilleries\DatatableBuilder\DatatableBuilderServiceProvider::class,
        Distilleries\PermissionUtil\PermissionUtilServiceProvider::class,
        Maatwebsite\Excel\ExcelServiceProvider::class,
        Distilleries\Expendable\ExpendableServiceProvider::class,
        Distilleries\Expendable\ExpendableRouteServiceProvider::class,


    ]

并且外观(也在config/app.php中)替换laravel外观Mail

    'aliases' => [
        /**
         * Vendor facade
         *
         */
       
     'FormBuilder'    => \Distilleries\FormBuilder\Facades\FormBuilder::class,
     'Form'           => Collective\Html\FormFacade::class,
     'HTML'           => Collective\Html\HtmlFacade::class,
     'Datatable'      => \Distilleries\DatatableBuilder\Facades\DatatableBuilder::class,
     'PermissionUtil' => \Distilleries\PermissionUtil\Facades\PermissionUtil::class,
     'Excel'          => \Maatwebsite\Excel\Facades\Excel::class,
    ]

用新的外观替换旧的服务外观Mail。

发布配置

php artisan vendor:publish --provider="Distilleries\Expendable\ExpendableServiceProvider"

配置

    return [
        'login_uri'           => 'admin/login',
        'logout_action'       => 'Distilleries\Expendable\Http\Controllers\Admin\LoginController@getLogout',
        'admin_base_uri'      => 'admin',
        'config_file_assets'  => base_path().'/package.json',
        'folder_whitelist'    => [
            'moximanager'
        ],
        'listener'            => [
            '\Distilleries\Expendable\Listeners\UserListener'
        ],
        'mail'                => [
            'actions' => [
                'emails.password'
            ]
        ],
        'menu'                => \Distilleries\Expendable\Config\MenuConfig::menu([], 'beginning'),
        'menu_left_collapsed' => false,
        'state'               => [
            'Distilleries\DatatableBuilder\Contracts\DatatableStateContract' => [
               'color'    => 'bg-green-haze',
               'icon'     => 'th-list',
               'libelle'  => 'expendable::menu.datatable',
               'position' => 0,
               'action'   => 'getIndex'
           ],
           'Distilleries\Expendable\Contracts\OrderStateContract'           => [
               'color'    => 'bg-grey-cascade',
               'icon'     => 'resize-vertical',
               'libelle'  => 'expendable::menu.order_state',
               'position' => 1,
               'action'   => 'getOrder'
           ],
           'Distilleries\Expendable\Contracts\ExportStateContract'          => [
               'color'    => 'bg-blue-hoki',
               'icon'     => 'save-file',
               'libelle'  => 'expendable::menu.export',
               'position' => 2,
               'action'   => 'getExport'
           ],
           'Distilleries\Expendable\Contracts\ImportStateContract'          => [
               'color'    => 'bg-red-sunglo',
               'icon'     => 'open-file',
               'libelle'  => 'expendable::menu.import',
               'position' => 3,
               'action'   => 'getImport'
           ],
           'Distilleries\FormBuilder\Contracts\FormStateContract'           => [
               'color'    => 'bg-yellow',
               'icon'     => 'pencil',
               'libelle'  => 'expendable::menu.add_state',
               'position' => 4,
               'action'   => 'getEdit'
           ],
        ]
    ];

菜单

我使用一个函数来轻松合并默认组件与应用程序的组件。

默认情况下,您可以在左侧菜单中找到

  1. 电子邮件
    1. 电子邮件列表
    2. 添加电子邮件
  2. 用户
    1. 用户列表
    2. 添加用户
  3. 角色
    1. 角色列表
    2. 添加角色
  4. 权限
    1. 关联权限
    2. 服务列表
    3. 添加服务
    4. 同步所有服务
  5. 语言
    1. 语言列表
    2. 添加语言

默认情况下,您可以在菜单任务中找到

  1. 生成新的组件
  2. 同步所有服务

要添加新项目很容易

        'menu' => \Distilleries\Expendable\Config\MenuConfig::menu([
                'left' => [
                    [
                        'icon'    => 'send',
                        'action'  => 'Admin\ContactController@getIndex',
                        'libelle' => 'Contact',
                        'submenu' => [
                            [
                                'icon'    => 'th-list',
                                'libelle' => 'List of Contact',
                                'action'  => 'Admin\ContactController@getIndex',
                            ],
                            [
                                'icon'    => 'pencil',
                                'libelle' => 'Add Contact',
                                'action'  => 'Admin\ContactController@getEdit',
                            ]
                        ]
                    ],
                ],
    
                'tasks' => [
                    [
                        'icon'    => 'console',
                        'action'  => 'Admin\TestController@getIndex',
                        'libelle' => 'Test',
    
                    ],
                ]
            ], 'beginning'),

方法\Distilleries\Expendable\Config\MenuConfig::menu接受两个参数

  1. 包含菜单内容的数组['left'=>[],'tasks'=>[]]
  2. 第二个参数是一个字符串beginningend,用于定义合并的方向。

左侧菜单示例

menu_left

任务菜单示例

tasks

状态

状态是您控制器的一部分,您在其中定义一系列操作。默认情况下,我实现了四个状态

  1. 数据表
  2. 订单
  3. 导出
  4. 导入
  5. 表单

要显示状态菜单,我提供了一个接口类Distilleries\Expendable\Contracts\StateDisplayerContract

 	$this->app->singleton('Distilleries\Expendable\Contracts\StateDisplayerContract', function ($app)
    {
        return new StateDisplayer($app['view'],$app['config']);
    });

此类检查控制器上的接口使用情况,并使用配置expendable::state显示标志和状态名称。如果您想更改状态显示,只需提供一个新的类来实现契约Distilleries\Expendable\Contracts\StateDisplayerContract

为了显示所有元素,我使用了一个布局管理器。您可以重写它来显示您想要的。

 	  $this->app->singleton('Distilleries\Expendable\Contracts\LayoutManagerContract', function ($app)
    {
        return new LayoutManager($app['config']->get('expendable'), $app['view'], $app['files'], app('Distilleries\Expendable\Contracts\StateDisplayerContract'));
    });

1. 数据表

datatable

数据表状态用于显示内容列表,如果需要,还可以进行筛选。要使用它,您必须实现接口Distilleries\DatatableBuilder\Contracts\DatatableStateContract

  public function getIndexDatatable();
  public function getDatatable();
  • getIndexDatatable用于初始化数据表。
  • getDatatable用于获取JSON数据。

您可以使用特性

use \Distilleries\Expendable\States\DatatableStateTrait;

在这个特性中,您有一个用于显示数据表和数据的泛型实现。此特性需要使用您控制器的两个属性

  1. $datatable,它是一个EloquentDatatable实例(来自DatatableBuilder)。
  2. model,它是一个Model实例(来自laravel)。

在构造函数中注入它们

    public function __construct(\Address $model, AddressDatatable $datatable)
    {
        $this->datatable  = $datatable;
        $this->model      = $model;
    }

2. 排序

向组件添加基本排序功能。

处理控制器

  • 必须实现\Distilleries\Expendable\Contracts\OrderStateContract
  • 方法在\Distilleries\Expendable\States\OrderStateTrait中实现

处理模型

  • 必须实现\Distilleries\Expendable\Contracts\OrderContract

方法

  • orderLabel()必须返回在订单页面显示的字符串(使用模型属性)
  • orderFieldName()必须返回模型持久化排序的字段名称

3. 导出

export

导出状态是从模型之间导出数据。要使用它,您必须实现接口Distilleries\Expendable\Contracts\ExportStateContract

     public function getExport();
     public function postExport();
  • getExport用于显示选择日期和导出类型的表单。
  • postExport处理导出并返回文件。

您可以使用特性

use \Distilleries\Expendable\States\ExportStateTrait;

在这个特性中,您有一个用于导出数据的泛型实现。此特性需要使用您控制器的属性

  1. model,它是一个Eloquant实例(来自laravel)。

在构造函数中注入它们

    public function __construct(\Address $model)
    {
        $this->model      = $model;
    }

您可以通过添加这些方法到服务提供程序并更改实例化的类来更改提供数据导出的类。

    $this->app->singleton('Distilleries\Expendable\Contracts\CsvExporterContract', function ($app)
    {
        return new CsvExporter;
    });
    $this->app->singleton('Distilleries\Expendable\Contracts\ExcelExporterContract', function ($app)
    {
        return new ExcelExporter;
    });
    $this->app->singleton('Distilleries\Expendable\Contracts\PdfExporterContract', function ($app)
    {
        return new PdfExporter;
    });

4. 导入

import

导入状态是将数据从文件导入到模型。要使用它,您必须实现接口Distilleries\Expendable\Contracts\ImportStateContract

     public function getImport();
     public function postImport();
  • getImport用于显示提供文件的表单。
  • postImport处理导入并返回。

您可以使用特性

use \Distilleries\Expendable\States\ImportStateTrait;

在这个特性中,您有一个用于导出数据的泛型实现。此特性需要使用您控制器的属性

  1. model,它是一个Eloquant实例(来自laravel)。

在构造函数中注入它们

    public function __construct(\Address $model)
    {
        $this->model      = $model;
    }

您可以通过在服务提供程序中添加这些方法并更改实例化的类来更改提供数据导入的类。

    $this->app->singleton('CsvImporterContract', function ($app)
    {
        return new CsvImporter;
    });
    
    $this->app->singleton('XlsImporterContract', function ($app)
    {
        return new XlsImporter;
    });
    
    $this->app->singleton('XlsxImporterContract', function ($app)
    {
        return new XlsImporter;
    });

5. 表单

form

表单状态为您提供了一个部分来添加或编辑元素,以及一个部分来查看元素而不编辑。

要使用它,您必须实现接口Distilleries\FormBuilder\Contracts\FormStateContract

    public function getEdit($id);
    public function postEdit();
    public function getView($id);
  • getEdit用于显示用于编辑或添加新项目的表单。
  • postEdit处理保存或更新。
  • getView显示不可编辑的表单。

您可以使用特性

use \Distilleries\Expendable\States\FormStateTrait;

在这个特性中,您有一个用于显示表单、保存和显示视图的泛型实现。此特性需要使用您控制器的两个属性

  1. model,它是一个Eloquant实例(来自laravel)。
  2. form,它是一个Form实例(来自FormBuilder)。

在构造函数中注入它们

     public function __construct(\Address $model, AddressForm $form)
    {
        $this->form      = $form;
        $this->model     = $model;
    }

组件

组件只是控制器、表单、数据表、模型的组合。要创建新的组件,您可以进入/admin/component/edit并填写表单,或者使用命令行

php artisan expendable:component.make app/controllers/Admin/TestController

您可以使用帮助来检查选项。

在后台,您有所有这些选项

要了解所有字段类型,您可以查看文档

component

Admin BaseComponent

默认情况下,如果您选中所有由 Distilleries\Expendable\Http\Controllers\Admin\Base\BaseComponent 生成的状态,则会从该状态生成控制器继承。此控制器实现了所有状态接口。

    use Distilleries\DatatableBuilder\Contracts\DatatableStateContract;
    use Distilleries\Expendable\Contracts\ExportStateContract;
    use Distilleries\Expendable\Contracts\ImportStateContract;
    use Distilleries\Expendable\States\DatatableStateTrait;
    use Distilleries\Expendable\States\ExportStateTrait;
    use Distilleries\Expendable\States\FormStateTrait;
    use Distilleries\Expendable\States\ImportStateTrait;
    use Distilleries\FormBuilder\Contracts\FormStateContract;
    
    class BaseComponent extends ModelBaseController implements FormStateContract, DatatableStateContract, ExportStateContract, ImportStateContract {
    
        use FormStateTrait;
        use ExportStateTrait;
        use DatatableStateTrait;
        use ImportStateTrait;
    
        // ------------------------------------------------------------------------------------------------
        // ------------------------------------------------------------------------------------------------
        // ------------------------------------------------------------------------------------------------
    
        public function getIndex()
        {
            return $this->getIndexDatatable();
        }
    }

Admin ModelBaseController

如果您不想使用所有状态,并且使用一个模型,只需扩展 Distilleries\Expendable\Http\Controllers\Admin\Base\ModelBaseController

示例

    use Distilleries\Expendable\Contracts\LayoutManagerContract;
    use Distilleries\Expendable\Models\BaseModel;
    use Illuminate\Http\Request;
    
    class ModelBaseController extends BaseController {
    
        /**
         * @var \Distilleries\Expendable\Models\BaseModel $model
         * Injected by the constructor
         */
        protected $model;
    
        // ------------------------------------------------------------------------------------------------
    
        public function __construct(BaseModel $model, LayoutManagerContract $layoutManager)
        {
            parent::__construct($layoutManager);
            $this->model = $model;
        }
	
        // ------------------------------------------------------------------------------------------------
        // ------------------------------------------------------------------------------------------------
        // ------------------------------------------------------------------------------------------------

        public function putDestroy(Request $request)
        {
            $validation = \Validator::make($request->all(), [
                'id' => 'required'
            ]);
            if ($validation->fails())
            {
                return redirect()->back()->withErrors($validation)->withInput($request->all());
            }
    
            $data = $this->model->find($request->get('id'));
            $data->delete();
    
            return redirect()->to(action('\\'.get_class($this) . '@getIndex'));
        }
    }

Admin BaseController

如果您不想使用所有状态并且不使用模型,只需扩展 Distilleries\Expendable\Http\Controllers\Admin\Base\BaseController。您只需注入 LayoutManagerContract

示例

    use Distilleries\Expendable\Contracts\LayoutManagerContract;
    use Distilleries\Expendable\Http\Controllers\Controller;

    class BaseController extends Controller {
 
        protected $layoutManager;
	
        protected $layout = 'expendable::admin.layout.default';
    
        // ------------------------------------------------------------------------------------------------
    
        public function __construct(LayoutManagerContract $layoutManager)
        {
            $this->layoutManager = $layoutManager;
            $this->setupLayout();
        }
    
        // ------------------------------------------------------------------------------------------------
        // ------------------------------------------------------------------------------------------------
        // ------------------------------------------------------------------------------------------------
    
        protected function setupLayout()
        {
            $this->layoutManager->setupLayout($this->layout);
            $this->setupStateProvider();
            $this->initStaticPart();
    
    
        }
    
        // ------------------------------------------------------------------------------------------------
    
        protected function setupStateProvider()
        {
            $interfaces = class_implements($this);
            $this->layoutManager->initInterfaces($interfaces, get_class($this));
    
        }
    
        // ------------------------------------------------------------------------------------------------
    
        protected function initStaticPart()
        {
            $this->layoutManager->initStaticPart(function ($layoutManager)
            {
    
                $menu_top  = $layoutManager->getView()->make('expendable::admin.menu.top');
                $menu_left = $layoutManager->getView()->make('expendable::admin.menu.left');
    
    
                $layoutManager->add([
                    'state.menu' => $layoutManager->getState()->getRenderStateMenu(),
                    'menu_top'   => $menu_top,
                    'menu_left'  => $menu_left
                ]);
            });
        }
    }

模型

默认情况下,您可以扩展 \Distilleries\Expendable\Models\BaseModel,该模型扩展了 \Illuminate\Database\Eloquent\Model。在其上,您可以使用一些方法

    public static function getChoice();
    public function scopeSearch($query, $searchQuery);
    public function getAllColumnsNames();
    public function scopeBetweenCreate($query, $start, $end);
    public function scopeBetweenupdate($query, $start, $end);

全局作用域

我提供了一些可在模型上使用的全局作用域。

状态

如果您只想在连接时显示一个元素,请使用此作用域。模型检查用户是否未连接,并且状态等于在线(1)。

要使用它,请将特性添加到您的模型中 use \Distilleries\Expendable\Models\StatusTrait;

权限

权限系统基于您所有控制器中的公共方法。要生成所有服务的列表,请使用“同步所有服务”(/admin/service/synchronize)。它使用所有控制器并获取公共操作。

如果您转到“关联权限”,您将看到具有所有方法的控制器列表

services

在此页面上,您可以允许角色对方法。默认情况下,Expendable 使用 Distilleries\PermissionUtil 包并在其内核中添加正确的中间件。您无需进行配置。如果未允许角色,应用程序将抛出错误 403

    if(!PermissionUtil::hasAccess('Controller@action')){
        App::abort(403, Lang::get('expendable::errors.unthorized'));
    }

视图

要覆盖视图,请使用命令行发布它们

php artisan vendor:publish --provider="Distilleries\Expendable\ExpendableServiceProvider"  --tag="views"

资产(CSS和JavaScript)

所有资产都在 resources/assets 文件夹中。

Sass

要使用 sass 文件,只需在您的 admin 文件 scss 中添加 bootstrap 和 application.admin.scss。如果您查看 Xyz 存储库,您将有一个名为 assets 的文件夹。我使用了相同的结构。

   //
   // Third-parties
   //
   
   @import "../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap";
   @import "../../../../node_modules/font-awesome/scss/font-awesome";
   
   //
   // Expendable
   //
   
   @import "../../../../vendor/distilleries/expendable/src/resources/assets/backend/sass/application.admin";
   @import "../../../../vendor/distilleries/expendable/src/resources/assets/backend/sass/admin/layout/themes/grey";

图片

当它们在 sass 文件中发现时,图像将由 mix 脚本复制

JavaScript

JavaScript 由 mix 编译

Composer

我在更新我的库时,更新了我的 composer json 以添加 npm 安装和 gulp 生成

    "post-update-cmd": [
      "php artisan clear-compiled",
      "php artisan optimize",
      "php artisan down",
      "npm install",
      "php artisan migrate --force",
      "npm run production",
      "php artisan up"
    ],

创建新的后端模块

  1. 生成迁移
  2. 生成模型
  3. 生成组件
  4. 在路由文件中添加您的控制器

案例研究

尝试创建一个博客文章组件。我使用的是 Xyz 的新安装

1. 生成迁移

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('posts', function(Blueprint $table)
		{
			$table->increments('id');
			$table->string('libelle');
			$table->text('content')->nullable();
			$table->tinyInteger('status');
			$table->timestamps();
		});
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('posts');
	}

}
php artisan migrate

2. 生成模型

    use Distilleries\Expendable\Models\BaseModel;
    
    class Post extends BaseModel {
        
        use \Distilleries\Expendable\Models\StatusTrait;
    
        protected $fillable = [
            'id',
            'libelle',
            'content',
            'status',
        ];
    }

3 生成组件

我使用后端生成器 /admin/component/edit

studies

数据表

<?php namespace App\Datatables;

use Distilleries\DatatableBuilder\EloquentDatatable;

class PostDatatable extends EloquentDatatable
{
    public function build()
    {
        $this
            ->add('id',null,trans('datatable.id'))
            ->add('libelle',null,trans('datatable.libelle'));

        $this->addDefaultAction();

    }
}

表单

此文件是生成的

<?php namespace App\Forms;

use Distilleries\FormBuilder\FormValidator;

class PostForm extends FormValidator
{
    public static $rules        = [];
    public static $rules_update = null;

    public function buildForm()
    {
        $this
            ->add('id', 'hidden')
            ->add('libelle', 'text')
            ->add('content', 'tinymce')
            ->add('status', 'choice');

         $this->addDefaultActions();
    }
}

您必须更新它以给出选择值和验证规则

<?php namespace App\Forms;

use Distilleries\Expendable\Helpers\StaticLabel;
use Distilleries\FormBuilder\FormValidator;

class PostForm extends FormValidator
{
    public static $rules = [
        'libelle' => 'required',
        'status'  => 'required|integer'
    ];
    public static $rules_update = null;

    public function buildForm()
    {
        $this
            ->add('id', 'hidden')
            ->add('libelle', 'text')
            ->add('status', 'choice', [
                'choices'     => StaticLabel::status(),
                'empty_value' => '-',
                'validation'  => 'required',
                'label'       => 'Status'
            ]);

         $this->addDefaultActions();
    }
}

控制器

<?php namespace App\Http\Controllers\Admin;

use Distilleries\Expendable\Contracts\LayoutManagerContract;
use Distilleries\Expendable\Http\Controllers\Admin\Base\BaseComponent;
use App\Forms\PostForm;
use App\Datatables\PostDatatable;

class PostController extends BaseComponent {

    // ------------------------------------------------------------------------------------------------
    // ------------------------------------------------------------------------------------------------
    // ------------------------------------------------------------------------------------------------

    public function __construct(PostDatatable $datatable, PostForm $form, \App\Post $model, LayoutManagerContract $layoutManager)
    {
       parent::__construct($model, $layoutManager);
       
       $this->datatable = $datatable;
       $this->form      = $form;
    }
}

4 在路由文件中添加您的控制器

我在路由文件中添加了 Route::controller('post', 'Admin\PostController');

    <?php
    
    use \Route;
    
    Route::get('/', 'HomeController@index');
    
    Route::group(array('middleware' => 'auth'), function ()
    {
    
        Route::group(array('before' => 'permission', 'prefix' => config('expendable::admin_base_uri')), function ()
        {
            Route::controller('post', 'Admin\PostController');
        });
    });

5 添加到菜单

config/expendable.php 中,id 添加 Post 条目

        'menu'  => \Distilleries\Expendable\Config\MenuConfig::menu([
            'left' => [
                [
                    'icon'    => 'pushpin',
                    'action'  => 'Admin\PostController@getIndex',
                    'libelle' => 'Post',
                    'submenu' => [
                        [
                            'icon'    => 'th-list',
                            'libelle' => 'List of Post',
                            'action'  => 'Admin\PostController@getIndex',
                        ],
                        [
                            'icon'    => 'pencil',
                            'libelle' => 'Add Post',
                            'action'  => 'Admin\PostController@getEdit',
                        ]
                    ]
                ],
            ]
        ], 'beginning'),