Dcat Admin —— 一款颜值极高的后台系统构建工具,简单高效,开箱即用
Dcat Admin
前言
首先得感谢一下社区的大佬@z-song,这个项目是基于laravel-admin二次开发的,laravel-admin也是我搬砖至今用过的对后端程序员最友好的后台构建工具,没有之一,包括Laravel nova
也没有这个用的爽快。初次接触laravel-admin我就被大佬的设计惊艳到了,就有一种原来后台原来还能这样写的感觉。大家可以把这个项目视为laravel-admin的船新版本哈哈哈。
这个项目从commit的第一个版本开始,到现在已经接近一年时间,这一年不敢说是潜心开发,但也是耗费了许多心思和精力在这个项目里面,上头的时候甚至写到半夜两三点。因为想呈现出一个高品质的产品给大家,所以就一直未敢发布,一直在默默的反复打磨抠细节到了现在,希望能写出真正有用的东西。
现在也终于到了可以跟大家见面的时刻了,正式版即将在近期发布,希望这个项目可以帮到大家!欢迎大家安装体验,如果对这个项目有兴趣也欢迎参与进来!
如有问题大家可以在GITHUB issue区或QQ群中反馈,我会及时解决。
QQ交流群:704661955
简介
Dcat Admin
是一个基于laravel-admin二次开发而成的后台构建工具,只需极少的代码即可构建出一个功能完善且颜值极高的后台系统。。
DEMO在线预览| 文档(持续完善中…) | Github(如果喜欢这个项目请点个star吧,感谢支持)
正式版本已发布 Dcat Admin v1.0.0 发布 - 对后端开发者友好的高颜值后台系统构建工具,简单高效,开箱即用
环境要求
php
:7.1+
laravel
:5.5 ~ 7.*
进度
目前这个项目的第一个版本的功能已全部开发完毕(包含laravel-admin最新版本
的几乎所有功能和其他新增功能),文档目前还在补充当中,等文档差不多了就会发布正式版,预计是4月初。
正式版本发布之后大家可以放心使用,现在已基本没有问题,如果有问题我也会及时解决。另外也不用担心没人维护的问题,这个项目我会持续维护和更新下去,当然如果支持的人多我会更新得更勤快哈哈哈。
接下来的工作重点是编写单元测试用例和完善文档,这个项目将会有完善的单元测试用例和完善的文档,一个高品质的项目稳定性是必须的!
这里不得不吹一下
laravel dusk
,用起来真的太爽了,可以模拟很多真人操作浏览器的动作。跑测试用例时时还可以弹出浏览器,可以直观的看到单测逻辑运行的效果,结合组件功能,让编写模拟浏览器操作的相关逻辑变得更简单,还增加了很多趣味性。
设计方向与适合人群
laravel-admin并没有采用现在流行的前后端分离的模式开发,依然是用后端渲染页面,前端框架用的是bootstrap3
+jQuery2
,这个特点既是laravel-admin的强大优势,同时也是它的弱点。
优势
采用bootstrap
+jQuery
实现后台构建工具的优势就是,它对后端程序员极度友好,后端程序员用这个技术栈可以很高效率地搭建出一个完善的后台系统,而且上手简单,学习成本很低。基本上就是只要你会jQuery
和Laravel
,那么从开发到维护和扩展都是非常轻松的事。
弱点
而所谓弱点,就是从技术的角度来看,bootstrap
+ jQuery
的组合已经是比较落伍的技术栈,甚至可能很多精通大前端的同学们可能也已经看不上这个技术栈了,现在流行的前端框架是vue
和react
。
设计方向
Dcat Admin
的优势与缺点与laravel-admin是一脉相承的,我们并不太追求前端技术的新颖,而更注重易用性和高效率。白猫黑猫只要能抓到老鼠就是好猫,你看我香不香就行了,不是吗?所以这个项目的设计方向已经很明确:
注重后端开发体验和高效率,注重界面的美观,注重代码的简洁和优雅。
适合人群
分析了这个项目的优缺点之后,这个项目的适合人群也是显而易见了。
- 1.适合个人站长,可满足轻松、快速建站的需求
- 2.适合PHP初学者,上手简单学习成本低
- 3.适合有快速建站需求,主要以满足功能为主,不注重技术选型的项目。例如外包项目、公司内部办公系统等等
如果你是抱着学习前端技术或追求的是前端技术的新颖的心态,那么这个项目并不适合你,你可能更适合去用laravel nova
。我这里的意思也并不是说laravel nova
不好用,只是相对于laravel admin
而言,它的学习成本会更高,易用程度也有所不及,对开发人员的技术水平有更高的要求,如果说得不对欢迎指正,大家轻喷哈。
与 Laravel-admin 的不同
下面列一些本项目与laravel-admin
的主要不同点
1.界面
本项目前端页面采用AdminLTE3(bootstrap4 + jQuery3)构建,如大家所见,界面更加美观,bootstrap4
的开发体验也会更好一些,比bootstrap3
强不少。
UI设计参考了
vuexy
,配色是我本人自己调的。
2.松散耦合的页面构建与数据操作设计
Dcat Admin
构建页面不再直接依赖于Model
,页面的构建与数据的读写是分开的。换句话说,构建页面是不需要关心数据的读写的,我把对数据的读写操作抽象成清晰易懂的接口,只需实现这些简单、清晰的接口就能轻松切换数据源。
当然为了方便我也保留了直接使用Model
的功能,毕竟大多数时候直接使用Model
也能满足我们的需求。
3.无刷新页面JS按需加载
laravel-admin
有一个让人很不爽缺点就是不支持前端静态资源的按需加载,所有静态资源都必须一次性加载完毕,这就意味着你的系统不能随意引入JS组件,否则会影响素有页面的加载速度!
而在这个项目中我仍然采用PJAX
构建无刷新页面,但是增加了支持按需加载前端文件的功能,每个页面只需加载这个页面需要用的的JS文件
和CSS文件
。
这个功能对于开发体验来说没有任何影响,依然是按以前的方法引入script
代码,只不过加载前端文件的代码可以放在控制器中执行。
示例:假设你想定义一个卡片组件,这个组件需要引入一些前端静态资源文件
use Illuminate\Contracts\Support\Renderable;
use Admin;
class Card implements Renderable
{
public static $js = [
'xxx/js/card.min.js',
];
public static $css = [
'xxx/css/card.min.css',
];
public function script()
{
return <<<JS
console.log('所有JS脚本都加载完了');
$('xxx').card();
JS
}
public function render()
{
// 在这里可以引入你的js或css文件
Admin::js(static::$js);
Admin::css(static::$css);
// 需要在页面执行的JS代码
// 通过 Admin::script 设置的JS代码会自动在所有JS脚本都加载完毕后执行
Admin::script($this->script());
return view('...')->render();
}
}
在控制器中使用
use Dcat\Admin\Layout\Content;
use Card;
class HomeController
{
public function index(Content $content)
{
// 使用上面的Card组件
// Card组件需要用到的静态文件只会在当前请求加载
// 其他请求不会加载
return $content->body(new Card());
}
}
4.构建无菜单栏页面
有时候我们会需要构建一个没有菜单栏和顶部导航栏的完整页面(如登陆页面,或需要在IFRAME中加载的页面等等
)。这时候就可以用Content::full
这个方法了,通过此方法构建的页面是可以使用Dcat Admin
中的所有的功能和组件的,可以显著地提高效率。
示例:构建登陆页面
use Dcat\Admin\Layout\Content;
class AuthController extends Controller
{
public function getLogin(Content $content)
{
if ($this->guard()->check()) {
return redirect($this->redirectPath());
}
// 使用full方法构建登陆页面
return $content->full()->body(view($this->view));
}
...
}
下面是登陆功能的模板内容,因为控制器中使用了Content::full
方法构建页面,所以不需要在模板中写head
,也不需要关心引入哪些静态资源,只需写当前页面的HTML即可,并且还可以使用Dcat Admin
中的所有功能,如下面用到的表单提交功能。
<style>
html body {background: #fff;}
</style>
<link rel="stylesheet" href="{{ admin_asset('@admin/css/pages/authentication.css') }}">
<section class="row flexbox-container">
<!-- 这里是你的登陆页面HTML代码 -->
...
</section>
<script>
Dcat.ready(function () {
// ajax表单提交
$('#login-form').form({
validate: true,
success: function (data) {
if (! data.status) {
Dcat.error(data.message);
return false;
}
Dcat.success(data.message);
location.href = data.redirect;
return false;
}
});
});
</script>
这个登陆页面使用了ajax
表单提交功能,并且附带了按钮loading
效果,比原来的登陆功能用户体验更好,大家可以点这里体验。
5.表单弹窗
在Dcat Admin
中构建非IFRAME表单弹窗只需增加非常简单的数行代码,同时兼顾用户体验和开发体验。
表单构建控制器
use Dcat\Admin\Form;
use Dcat\Admin\Models\Repositories\Role;
class RoleController extends AdminController
{
public function form()
{
return Form::make(new Role('permissions'), function (Form $form) {
$roleTable = config('admin.database.roles_table');
$connection = config('admin.database.connection');
$id = $form->grtKey();
$form->display('id', 'ID');
$form->text('slug')
->required()
->creationRules(['required', "unique:{$connection}.{$roleTable}"])
->updateRules(['required', "unique:{$connection}.{$roleTable},slug,$id"]);
$form->text('name')->required();
$form->display('created_at');
$form->display('updated_at');
});
}
...
}
在任意界面中构建你的表单弹窗
use App\Http\Controllers\Controller;
use Dcat\Admin\Form;
use Dcat\Admin\Layout\Content;
class ModalFormController extends Controller
{
public function index(Content $content)
{
return $content->body($this->build());
}
protected function build()
{
// 新增模式弹窗
Form::dialog('新增角色')
->click('.create-form') // 绑定点击按钮
->url('auth/roles/create') // 表单页面链接,此参数会被按钮中的 “data-url” 属性替换。。
->width('700px') // 指定弹窗宽度,可填写百分比,默认 720px
->height('650px') // 指定弹窗高度,可填写百分比,默认 690px
->success('Dcat.reload()'); // 新增成功后刷新页面
// 编辑模式弹窗
Form::dialog('编辑角色')
->click('.edit-form')
->success('Dcat.reload()'); // 编辑成功后刷新页面
// 当需要在同个“class”的按钮中绑定不同的链接时,把链接放到按钮的“data-url”属性中即可
$editPage = admin_base_path('auth/roles/1/edit');
return <<<HTML
<div style='padding:30px 0'>
<span class='btn btn-outline-primary create-form'> 新增表单弹窗 </span>
<span class='btn btn-primary edit-form' data-url='{$editPage}'> 编辑表单弹窗 </span>
</div>
HTML;
}
}
效果
6.简单易用的统计卡片
系统内置了常用的统计卡片功能,可以非常方便的展示统计数据,体验。
卡片编写示例
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-large-1">{$content}</h2>
<span class="mb-0 mr-1 text-80">{$this->title}</span>
</div>
HTML
);
}
}
使用卡片
use NewUsers;
class MetricCardController extends Controller
{
use PreviewCode;
public function index(Content $content)
{
return $content
->body(function (Row $row) {
$row->column(4, new TotalUsers());
$row->column(4, new NewUsers());
$row->column(4, new NewDevices());
});
}
}
7.无限层级结构数据表格
这个功能可以用于分页展示层级结构数据,适合展示数据量大的层级结构数据,体验
效果
8.组合表头
此功能可以用于构建双表头表格,非常适合与展示报表功能,体验
效果
更多不同
因为不同的细节实在太多,限于篇幅,更多的不同点这里不再赘述,正式版发布后大家可以在文档中查看。
11 Comments
旧版本中对laravel5.5版本的兼容有点问题,新版本中已经修复了这个问题~