2017 © Pedro Peláez
 

project administrator

Admin system based on Laravel 5.2

image

forone/administrator

Admin system based on Laravel 5.2

  • Monday, October 16, 2017
  • by forone
  • Repository
  • 50 Watchers
  • 465 Stars
  • 1,681 Installations
  • JavaScript
  • 0 Dependents
  • 0 Suggesters
  • 150 Forks
  • 7 Open issues
  • 16 Versions
  • 1 % Grown

The README.md

实在招不到人,在此打个广告,招Laravel工程师,请联系 mani@nxdai.com 或 1283233833, (*1)

框架Demo地址:Demo, (*2)

Demo账号:admin@admin.com 密码:admin, (*3)

Demo源码:源码, (*4)

ForoneAdministrator 是一款基于Laravel5.2封装的后台管理系统,集成了Entrust权限管理,并针对业务的增删改查进行了视图和业务层的封装,有助于进行后台管理系统的快速研发。, (*5)

效果图

PC端

, (*6)

移动端

, (*7)

, (*8)

, (*9)

安装初始化

系统要求:, (*10)

  • Laravel 5.2+
  • PHP 5.5.9+

由于不可抗力因素,最好在compoer.json里加入如下配置后再开始安装,设置国内的composer镜像同时也可设置直接从国内git服务器上下载。 由于使用的entrust还处于dev状态,所以需要将composer.json里的minimum-stability 设置为 dev, (*11)

"repositories": [
  {"type": "git", "url": "http://git.nxdai.com/mani/ForoneAdministrator.git"},
  {"type": "composer", "url": "http://packagist.phpcomposer.com"},
  {"packagist": false}
],
"minimum-stability" : "dev"

由于启用了 "minimum-stability" : "dev",Laravel的dev版本会导致paginate出错,请在composer.json里将laravel版本设置为确定的版本号,例如5.1.4, (*12)

使用composer进行安装 5.2.x版本, (*13)

composer require forone/administrator:5.2.x-dev

编辑 config/app.php 注册 providersaliases, (*14)

'providers' => [
    Collective\Html\HtmlServiceProvider::class,
    Forone\Providers\ForoneServiceProvider::class,
]
'aliases' => [
    'Form' => Collective\Html\FormFacade::class,
    'Html' => Collective\Html\HtmlFacade::class,
    'Entrust'   => Zizaco\Entrust\EntrustFacade::class,
]

发布资源,运行下面命令会自动生成默认的配置文件并复制静态文件和数据库文件, (*15)

php artisan vendor:publish

修改.env通过环境变量设置初始管理员账号密码, (*16)

ADMIN_EMAIL默认为admin@admin.com ADMIN_PASSWORD默认为admin, (*17)

系统初始化, (*18)

php artisan forone:init

用户表默认使用admins表,用户模型使用Forone类的Admin模型,在laravel自带的auth.app内配置model项,, (*19)

'model' => 'Forone\Admin'

5.2.0之后laravel版本,在用户模型内请务必删除继承的AuthorizableContract类,否则会报错, (*20)

App\User添加Entrust的Trait,以便使用一些封装的方法, (*21)

use Authenticatable, CanResetPassword, EntrustUserTrait;

使用EntrustUserTrait的时候注意需要引入该类:, (*22)

use Zizaco\Entrust\Traits\EntrustUserTrait;

现在就可以使用.env里的管理员账号密码登陆了, (*23)

, (*24)

forone配置

return [
    'site_config'                 => [
        'site_name'   => '站点名称',
        'title'       => '站点标题',
        'description' => '站点描述',
        'logo'        => '站点logo地址'
    ],
    'RedirectAfterLoginPath'      => 'admin/roles', // 登录后跳转页面
    'RedirectIfAuthenticatedPath' => 'admin/roles', // 如果授权后直接跳转到指定页面

    'menus'                       => [
        '系统设置' => [
            'icon'       => 'mdi-toggle-radio-button-on', //菜单icon
            'permission' => 'admin',                      //菜单显示所需权限,多权限以数组的方式添加 ['admin','test']
            'children'   => [                             //菜单的子菜单数组
                '角色管理'  => [
                    'uri' => 'roles',                     //菜单对应的uri
                ],
                '权限管理'  => [
                    'uri' => 'permissions',
                ],
                '管理员管理' => [
                    'uri' => 'admins',
                ]
            ],
        ],
    ],

    'qiniu'                       => [
        'host'       => 'http://share.u.qiniudn.com',               //your qiniu host url
        'access_key' => '-S31BNj77Ilqwk5IN85PIBoGg8qlbkqwULiraG0x', //for test
        'secret_key' => 'QoVdaBFZITDp9hD7ytvUKOMAgohKaB8oa11FJdxN', //for test
        'bucket'     => 'share'
    ]
];

, (*25)

权限控制

权限控制主要分两部分,一部分是控制菜单是否显示,通过菜单的permission属性即可完成,另一部分是控制路由,通过admin.permission中间件传参来进行控制即可,主要有两种使用场景:, (*26)

  • 在routes里进行权限控制,这种用法是直接使用middleware进行自动判定的,更多的别的路由过滤的用法请看entrust文档
Route::group(['prefix' => 'admin', 'middleware' => ['admin.auth', 'admin.permission:admin']], function () {
  • 在Controller里对Controller的所有请求进行权限控制
function __construct()
{
    parent::__construct('admins', '管理员');
    $this->middleware('admin.permission:admin|test'); //需要admin及test的权限才可以访问该Controller
}

, (*27)

1分钟完成分类管理模块

以最简单的模块为实例,假设数据库已建好,需要创建一个分类管理模块, (*28)

  1. 复制PermissionsController并粘贴更名为CategoriesController;复制views/permissions文件夹并粘贴更名为views/categories
  2. 编辑CategoriesController,修改以下几处:
    • 修改类名为文件名
    • 修改构造函数的uri和name为 parent::__construct('categories', '分类管理');
    • 批量修改PermissionCategory
    • 修改index里的数据列表显示项
    • Request类视情况调整
  3. 编辑views/categories/form.blade.php,修改输入项及描述名称
  4. 编辑routes.php添加路由 Route::resource('categories', 'CategoriesController');
  5. 编辑forone.php添加菜单 "分类管理"=>["uri"=>"categories"]

复杂的模块可能在index或者其它部分有更复杂的改动,总体上来说Controller的结构和基本功能代码及views的都可以复用, (*29)

, (*30)

视图控件

详细描述封装好的便于使用的数据控件, (*31)

, (*32)

数据列表

用法:{!! Html::datagrid($results) !!}, (*33)

数据:数据源为数组, (*34)

'columns' => [
    ['流水号', 'id', function ($id) {
        return '';
    }],
    ['金额', 'amount'],
    ['操作', 'buttons', 100, function () {
        $buttons = [
            ['查看']
        ];
        return $buttons;
    }],
]

数据项参数:, (*35)

  1. 列名称
  2. 数据项的属性,其中buttons是固定的按钮列使用属性
  3. 有以下几种情况:
    • 可以为空,就按默认情况显示
    • 可以为数字,为显示的列宽
    • 可以为函数,用以处理数据项并返回显示结果,包括根据不同权限返回不同结果等,作为函数的时候也可以直接返回html代码以显示任意内容
  4. 为函数,作为buttons项的时候,返回的按钮数组有以下几种情况:
    • 查看,编辑默认会跳转到查看和编辑页面
    • 启用,禁用默认会单独修改数据项的enabled字段
    • 点击按钮后需要修改某个字段为某个值,比如审核通过或者驳回之类: [['name'=>'审核','class'=>'btn-danger'],['tested'=>'true','other'=>'somevalue']] 第一个数组描述按钮的名称和样式,第二个数组描述需要更改的字段和值
    • 点击按钮后需要调用某个接口并传参数:[['name' => '审核', 'uri' => 'lastInstance.get', 'method' => 'GET','id'=>$project->id],[]],uri使用路由名称
    • 点击按钮后需要弹出某个弹出框,['配置','#modal'],就会弹出来id为modal的弹出框

, (*36)

数据列表头 - 新增、检索、过滤筛选等

用法:, (*37)

{!! Html::list_header([
    'new'=>true,
    'search'=>true,
    'title'=>'数据列表标题',
    'filters'=>$results['filters']
    ]) !!}

数据项参数:, (*38)

  1. new 表示是否显示新增按钮,点击后跳转到创建页面
  2. search 表示是否显示检索输入框,输入检索内容后,默认以keywords为参数传递到后端接口,相当于?keywords=xxx
  3. title 标题
  4. filters 数据源为数组,如下:
$results['filters'] = [
    'status' => [
        ['label' => '所有状态', 'value'=>''],
        ['label' => '状态1', 'value' => 0]
    ],
    'other' => [
        ['label' => '其它过滤', 'value'=>''],
        ['label' => '过滤1', 'value' => 0]
    ]
];

statusother是该数据项的字段名,它们对应的数组是显示出来供选择的选项,选择后会自动提交请求,相当于?status=''&other=''。 相应的在Controller的index方法里,添加很简单的代码即可实现分页的同时自动加上相应的参数,并根据参数过滤相应的内容,如下:, (*39)

$all = $request->except(['page']);
$paginate = Model::orderBy('id', 'desc');
//如果没有筛选条件直接返回分页数据
if (!sizeof($all)) {
    $paginate = $paginate->paginate();
}else{
    //遍历筛选条件
    foreach ($all as $key => $value) {
        if ($key == 'keywords') { //检索的关键词,定义检索关键词的检索语句
            $paginate->where('name', 'LIKE', '%'.$value.'%');
        }else{
            //可以根据不同的检索条件的不同值进行不同的语句组合,比如状态为7的数据加多筛选条件
            if ($key == 'status' && $value == 7) {
                $paginate->where($key, '=', 1)
                        ->where('time', '<', Carbon::now())
                        ->whereRaw(' `a` > `b` ')
                        ->orWhere($key, '=', $value);
            } else { //正常来说就只加where即可
                $paginate->where($key, '=', $value);
            }
        }
    }
    $paginate = $paginate->paginate();
}
$results = [
    'items' => $paginate->appends($all),
];

针对简单内容的筛选,基本上检索代码都可以直接Copy使用,仅需修改Model即可, (*40)

, (*41)

下拉列表选择

用法:, (*42)

Form::form_select('type_id', '标的类型', [
    ['label'=>'名称', 'value'=>'']
],0.5,false)

参数:, (*43)

  1. 字段名
  2. 数据项的Label名称
  3. 下拉列表数据,label表示显示出来的内容,value表示存储的时候使用的内容
  4. 长度,默认是bootstratp整行的一半,等同于col-md-6
  5. 是否用于modal,因为modal样式有些差异,所以加了这个参数

, (*44)

单选radio

用法:, (*45)

{!! Form::form_radio('risk_level', '风险等级', [
[0, 'A', true],
[1, 'B'],
[2, 'C'],
[3, 'D'],
[4, 'E'],
[5, 'F']
], 0.5) !!}

参数:, (*46)

  1. 字段名
  2. 数据项的Label名称
  3. 数据内容,包括
    • 存储时用的数据
    • 显示出来的名称
    • 是否默认选中
  4. 长度,默认是bootstratp整行的一半,等同于col-md-6,radio因为经常比较多,默认是1

, (*47)

时间控件

用法:, (*48)

{!! Form::form_time('time','开始时间','如 2015-06-06 08:00:00') !!}

参数:, (*49)

  1. 字段名
  2. label名称
  3. 提示文字

, (*50)

日期控件

用法:, (*51)

{!! Form::form_date('date','开始日期','如 2015-06-06') !!}

参数:, (*52)

  1. 字段名
  2. label名称
  3. 提示文字

, (*53)

单行文本输入

用法:, (*54)

{!! Form::form_text('column','字段名称','提示文字') !!}

, (*55)

多行文本输入

用法:, (*56)

{!! Form::form_area('column','字段名称','提示文字') !!}

, (*57)

单文件上传

用法:, (*58)

{!! Form::single_file_upload('field_name', 'label') !!}

参数:, (*59)

  1. 字段名
  2. 项名称
  3. 项宽度,默认0.5
  4. 上传平台,目前默认且仅支持qiniu

, (*60)

多文件上传

用法:, (*61)

{!! Form::multi_file_upload('field_name', 'label') !!}

参数:, (*62)

  1. 字段名
  2. 项名称
  3. 是否显示图片描述输入框
  4. 项宽度,默认0.5
  5. 上传平台,目前默认且仅支持qiniu

, (*63)

文件浏览器

用法:, (*64)

{!! Form::file_viewer('field_name', 'label') !!}

参数:, (*65)

  1. 字段名
  2. 项名称
  3. 项宽度,默认0.5

, (*66)

富文本编辑器

用法:, (*67)

{!! Form::ueditor('name', 'label') !!}

参数:, (*68)

  1. 字段名
  2. 项名称
  3. 项宽度,默认0.5

, (*69)

提高研发效率的几个自定义命令

  • php artisan forone:init 系统初始化命令,只可运行一次。
  • php artisan db:backup 通过iseed库自动备份当前数据库的数据到Seeder文件里,解决研发时测试数据同步或临时数据结构变更测试数据面临清空等问题。并可根据migrations的文件顺序进行合理的排序,避免由于依赖关系引起的后续数据填充问题。
  • php artisan db:clear 清空数据库,心情不爽的时候用一下,感觉棒棒哒。
  • php artisan db:upgrade 升级数据库,可能加了新的字段等,会自动填充Seeder文件里的数据,升级之前最好先备份下数据。
  • php artisan forone:copy 可复制一些文件到实际项目里,比如复制routes文件以便自定义route

The Versions