1、安装yii2
composer自行安装,请参考yii安装
下面是我安装yii2 composer命令,供参考
php composer.phar create-project yiisoft/yii2-app-advanced 你的项目路径
2、配置数据库
2.1、配置数据
修改common/config/main-local.php的配置,以mysql为例,如下图
图中的host、dbname、username和password要相应的改为你自己的。
2.2、 创建user数据表,我们后面要实现后台登陆
说明:user表和menu表的创建可以参考我们后面下载的组件yii2-admin里面的sql,具体目录位于
vendor\mdmsoft\yii2-admin\migrations\schema-mysql.sql
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT "自增ID",
`username` varchar(255) NOT NULL COMMENT "用户名",
`auth_key` varchar(32) NOT NULL COMMENT "自动登录key",
`password_hash` varchar(255) NOT NULL COMMENT "加密密码",
`password_reset_token` varchar(255) DEFAULT NULL COMMENT "重置密码token",
`email` varchar(255) NOT NULL COMMENT "邮箱",
`role` smallint(6) NOT NULL DEFAULT "10" COMMENT "角色等级",
`status` smallint(6) NOT NULL DEFAULT "10" COMMENT "状态",
`created_at` int(11) NOT NULL COMMENT "创建时间",
`updated_at` int(11) NOT NULL COMMENT "更新时间",
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT="用户表";
2.3、 访问frontend站点,先注册个用户
注册成功后,右上角会显示登陆的状态,我们后面会用到这个注册的用户
接下来我们要开始配置后台的模板了。
3、利用AdminLTE渲染后台模板
后台的模板我们采用利用 AdminLTE(Backend theme for Yii2 Framework)
插播一曲:AdminLTE是一个完全响应管理模板。基于Bootstrap3框架,易定制模板。适合多种屏幕分辨率,从小型移动设备到大型台式机。
内置了多个页面,包括仪表盘、邮箱、日历、锁屏、登录及注册、404错误、500错误等页面。
3.1、 安装AdminLTE
https://github.com/dmstr/yii2-adminlte-asset
打开上面的链接,按照操作步骤进行安装
这里我简述下自己的安装步骤,在自己项目的根目录,编辑composer.json增加下面一行
"dmstr/yii2-adminlte-asset": "^2.1",
如下图:
然后cd到你自己项目的根目录,运行
composer update
3.2、 利用AdminLTE的demo模板,搭建帅气上档次的管理后台
拷贝 vendor/dmstr/yii2-adminlte-asset/example-views/yiisoft/yii2-app 目录下的layouts和site目录以及文件
覆盖掉backend/views/目录下的lauouts和site对应的文件,刷新下后台的界面,是不是有一种很成功的感觉。
4、完善rbac权限管理
4.1、 配置简短路由
backend/config/main.php文件的compontents加上下面的配置
"urlManager" => [
//用于表明urlManager是否启用URL美化功能,在Yii1.1中称为path格式URL,
// Yii2.0中改称美化。
// 默认不启用。但实际使用中,特别是产品环境,一般都会启用。
"enablePrettyUrl" => true,
// 是否启用严格解析,如启用严格解析,要求当前请求应至少匹配1个路由规则,
// 否则认为是无效路由。
// 这个选项仅在 enablePrettyUrl 启用后才有效。
"enableStrictParsing" => false,
// 是否在URL中显示入口脚本。是对美化功能的进一步补充。
"showScriptName" => false,
// 指定续接在URL后面的一个后缀,如 .html 之类的。仅在 enablePrettyUrl 启用时有效。
"suffix" => "",
"rules" => [
"<controller:\w+>/<id:\d+>"=>"<controller>/view",
"<controller:\w+>/<action:\w+>"=>"<controller>/<action>"
],
],
4.2、 配置web server
如果你用apache作为你的web服务器,可以参考下面的配置
在应用的目录 backend/web下面创建.htaccess文件并添加如下内容,这个文件你都创建不下来,看来是真需要再磨练磨练哦
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
当然,前提是你的apache必须要开启rewrite模块。nginx用户,修改你的server段,参考如下
server {
listen 80;
server_name yourdomain;
root /var/www/yourdirectory/backend/web;
index index.php index.html;
charset utf-8;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
配置好了记得重启你的web server哦,我们校验下“隐藏index.php”的配置是否正确
http://localhost/gii 可以正常打开即没问题。
4.3、 创建权限控制所需要的数据表
默认yii2都给我们准备好了,打开 vendor/yiisoft/yii2/rbac/migrations/schema-mysql.sql 文件,依次创建数据表
提示一下,手动创建数据表的时候不要光顾着复制粘贴,要指定charset和engine.如果你用migrate创建那就不说什么了。
`auth_assignment`;
`auth_item_child`;
`auth_item`;
`auth_rule`;
另外补充菜单menu表,需要的自行创建
说明:user表和menu表的创建可以参考 vendor\mdmsoft\yii2-admin\migrations\schema-mysql.sql
CREATE TABLE `menu` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL,
`parent` int(11) DEFAULT NULL,
`route` varchar(256) DEFAULT NULL,
`order` int(11) DEFAULT NULL,
`data` text,
PRIMARY KEY (`id`),
KEY `parent` (`parent`),
CONSTRAINT `menu_ibfk_1` FOREIGN KEY (`parent`) REFERENCES `menu` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
4.4、 下载安装 yii2-admin
参考 https://github.com/mdmsoft/yii2-admin 按照步骤一步一步安装即可,同adminlte的安装
安装好了可以在 vendor 目录下看到 mdmsoft 目录
这里我简述下自己的安装步骤,在自己项目的根目录,编辑composer.json增加下面一行
"mdmsoft/yii2-admin": "~2.0"
如下图:
然后cd到你自己项目的根目录,运行
composer update
4.5、 权限配置
打开backend/config/main.php 修改配置
"modules" => [
"admin" => [
"class" => "mdm\admin\Module",
],
],
"aliases" => [
"@mdm/admin" => "@vendor/mdmsoft/yii2-admin",
],
//这里必须添加authManager配置项
"components" => [
...
//components数组中加入authManager组件,有PhpManager和DbManager两种方式,
//PhpManager将权限关系保存在文件里,这里使用的是DbManager方式,将权限关系保存在数据库.
"authManager" => [
"class" => 'yii\rbac\DbManager', //这里记得用单引号而不是双引号
"defaultRoles" => ["guest"],
],
...
],
//as access位置不要添加错了
'as access' => [
'class' => 'mdm\admin\components\AccessControl',
'allowActions' => [
//这里是允许访问的action
//controller/action
]
],
4.5、 校验权限模块是否有效
如果此时你不小心刷新了页面你会发现,不管你访问什么页面,都会提示你403了,也就是没权限进行操作了!
也就证明了我们权限添加是正确的。但是,如此一来我们也就不方便往下进行了。为了继续,我们先屏蔽掉权限,也就是先让权限失效,只需要配置as access中允许所有操作都可以访问即可。
'as access' => [
'class' => 'mdm\admin\components\AccessControl',
'allowActions' => [
//这里是允许访问的action
'*'
]
],
需要提醒你的是,我们后面对权限完善了以后,记得把*改回来!
现在我们再通过路由访问我们刚刚添加好的权限模块 http://localhost/admin/route
嗯,界面是有的了,下面我们加快脚步验收下我们的权限这块到底成还是不成呢?
一般来说到这一步就ok的了。后面的可以自己摸索着添加路由分配权限了。下面我们在左侧菜单上把权限的栏目加上,代码可直接复制,放置于 <section class="sidebar"></section>标签内即可
<ul class="sidebar-menu tree" data-widget="tree">
<li class="treeview">
<a href="#">
<i class="fa fa-gears"></i> <span>权限控制</span>
<i class="fa fa-angle-left pull-right"></i>
</a>
<ul class="treeview-menu">
<li class="treeview">
<a href="/admin">管理员</a>
<ul class="treeview-menu">
<li><a href="/user"><i class="fa fa-circle-o"></i> 后台用户</a></li>
<li class="treeview">
<a href="/admin/role">
<i class="fa fa-circle-o"></i> 权限 <i class="fa fa-angle-left pull-right"></i>
</a>
<ul class="treeview-menu">
<li><a href="/admin/route"><i class="fa fa-circle-o"></i> 路由</a></li>
<li><a href="/admin/permission"><i class="fa fa-circle-o"></i> 权限</a></li>
<li><a href="/admin/role"><i class="fa fa-circle-o"></i> 角色</a></li>
<li><a href="/admin/assignment"><i class="fa fa-circle-o"></i> 分配</a></li>
<li><a href="/admin/menu"><i class="fa fa-circle-o"></i> 菜单</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
我们看下效果图,这样一来,我们对权限进行操作就十分的方便了
如此,我们的权限控制基本告一段落了,关于权限需要说明的是:
你应该先添加路由,然后添加权限名称,后再对角色或个人进行权限的独立分配。这一点还请新手谨记!
先看图预览下大致效果,不然怎么激起你们好学的心。
首先我们先访问路由页面 /admin/route/index ,尽可能的把左侧的全部选中,移动到右侧,最后记得给当前用户分配相关的可访问权限哦。
接下来访问菜单列表 /admin/menu/index 点击添加菜单,如果这个时候你没有访问权限,你可以修改配置文件的 as access 项 allowActions选项为 “*”,暂时允许当前用户访问任意权限,记得一定要在添加完权限的时候去掉 as access 的设置,不然权限失效了可别回来找我。
这里我们先填写上图中标红的四个字段
举个例子:我们要添加一级菜单"权限管理"
名称请填写"权限管理",因为是一级菜单,父级名称请留空,路由我们这里选择"/admin/default/index",注意了,这里要添加的路由,一定要是路由页面 /admin/route/index右侧罗列出来的。
映射,其实就是排序高低的问题,比如说我添加了两个菜单,映射值为1的就在上面 值为2的就在1的下面,我们这里填写数字1。"数据"这一项我们后面再说。按照刚刚介绍的这种方式添加吧,举一个添加二级菜单"权限控制"的例子
只需要把父级名称这里填写我们刚刚添加成功的一级名称"权限管理"即可。其他照旧。不会操作的多看两遍,这里最好把权限管理的几个菜单全部添加完毕,因为接下来我们需要而且你可以多练练手。
到此我们已经会添加菜单了。
我们来看下一步,利用我们之前搭建的后台框架进行展现。
use mdm\admin\components\MenuHelper;
echo dmstr\widgets\Menu::widget( [
'options' => ['class' => 'sidebar-menu tree', 'data-widget'=> 'tree'],
'items' => MenuHelper::getAssignedMenu(Yii::$app->user->id),
] );
是不是很简单,What?我的怎么没有dmstr这玩意,不好意思,已经说的很多遍,需要先看上文再有这个菜单的结合。
ok,刷新页面看看你的菜单,虽然我们还没完全实现我们想要的功能,不过到此你应该能看到你的菜单展现了。
接下来将进入我们的重点以及难点,我们要实现菜单前面的小图标且完成菜单可隐藏控制。
还记得我们一开始创建菜单的时候,唯一没进行填写的选项"数据"吗?以“博客管理”这个二级菜单为例,我们在“数据”这一项这样填写
{"icon": "book", "visible": true}
这句话是什么意思呢?注意这个"数据"项我们填写的是一段json代码,这里我们现在只定制了两个key: icon和visible,icon是菜单小图标,可选项参考这里,visible是“显示”的意思,可以显示或者隐藏菜单项。我们刚刚也说了,这两个key是我们自己定制的,既然如此,那我们自然也需要写程序实现相应的功能。
找到菜单输出的地方(left.php),我们对mdm\admin\components\MenuHelper::getAssignedMenu方法完善一下。代码如下:
<?php
use mdm\admin\components\MenuHelper;
$callback = function($menu){
$data = json_decode($menu['data'], true);
$items = $menu['children'];
$return = [
'label' => $menu['name'],
'url' => [$menu['route']],
];
//处理我们的配置
if ($data) {
//visible
isset($data['visible']) && $return['visible'] = $data['visible'];
//icon
isset($data['icon']) && $data['icon'] && $return['icon'] = $data['icon'];
//other attribute e.g. class...
$return['options'] = $data;
}
//没配置图标的显示默认图标,默认图标大家可以自己随便修改
(!isset($return['icon']) || !$return['icon']) && $return['icon'] = 'circle-o';
$items && $return['items'] = $items;
return $return;
};
//这里我们对一开始写的菜单menu进行了优化
echo dmstr\widgets\Menu::widget( [
'options' => ['class' => 'sidebar-menu tree', 'data-widget'=> 'tree'],
'items' => MenuHelper::getAssignedMenu(Yii::$app->user->id, null, $callback),
] );
?>
可以看出我们已经完美的实现了给菜单添加小图标和设置菜单隐藏的问题。如果你有其他的属性需要进行配置,可以自行扩展。
到这里基本上就结束了,另外新版的会有一个jQuery的版本问题,新增菜单的父级名称跟路由列表搜索列表的suggest会一个js方法未定义,是jQuery版本过高导致的,当前新的使用的是3.x的版本,把它降到2.x的版本就OK了。把下面这2个jQuery替换成2.x的版本
vendor/bower-asset/jquery/dist/jquery.js
vendor/bower-asset/jquery/dist/jquery.min.js
下面是本次需要添加的表的sql清单
DROP TABLE IF EXISTS `auth_assignment`;
DROP TABLE IF EXISTS `auth_item_child`;
DROP TABLE IF EXISTS `auth_item`;
DROP TABLE IF EXISTS `auth_rule`;
CREATE TABLE `auth_rule`
(
`name` VARCHAR(64) NOT NULL,
`data` BLOB,
`created_at` INTEGER,
`updated_at` INTEGER,
PRIMARY KEY (`name`)
) ENGINE INNODB DEFAULT CHARSET=utf8;
CREATE TABLE `auth_item`
(
`name` VARCHAR(64) NOT NULL,
`type` SMALLINT NOT NULL,
`description` TEXT,
`rule_name` VARCHAR(64),
`data` BLOB,
`created_at` INTEGER,
`updated_at` INTEGER,
PRIMARY KEY (`name`),
FOREIGN KEY (`rule_name`) REFERENCES `auth_rule` (`name`) ON DELETE SET NULL ON UPDATE CASCADE,
KEY `type` (`type`)
) ENGINE INNODB DEFAULT CHARSET=utf8;
CREATE TABLE `auth_item_child`
(
`parent` VARCHAR(64) NOT NULL,
`child` VARCHAR(64) NOT NULL,
PRIMARY KEY (`parent`, `child`),
FOREIGN KEY (`parent`) REFERENCES `auth_item` (`name`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`child`) REFERENCES `auth_item` (`name`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE INNODB DEFAULT CHARSET=utf8;
CREATE TABLE `auth_assignment`
(
`item_name` VARCHAR(64) NOT NULL,
`user_id` VARCHAR(64) NOT NULL,
`created_at` INTEGER,
PRIMARY KEY (`item_name`, `user_id`),
FOREIGN KEY (`item_name`) REFERENCES `auth_item` (`name`) ON DELETE CASCADE ON UPDATE CASCADE,
KEY `auth_assignment_user_id_idx` (`user_id`)
) ENGINE INNODB DEFAULT CHARSET=utf8;
drop table if exists `menu`;
drop table if exists `user` cascade;
create table `menu`
(
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` varchar(128),
`parent` int(11),
`route` varchar(256),
`order` int(11),
`data` blob,
foreign key (`parent`) references `menu`(`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
create table `user`
(
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` varchar(32) NOT NULL,
`auth_key` varchar(32) NOT NULL,
`password_hash` varchar(256) NOT NULL,
`password_reset_token` varchar(256),
`email` varchar(256) NOT NULL,
`status` integer not null default 10,
`created_at` integer not null,
`updated_at` integer not null
)ENGINE=InnoDB DEFAULT CHARSET=utf8;