ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Laravel后台开发提速:dcat-admin实战全攻略

Laravel后台开发提速:dcat-admin实战全攻略 如果你这些年一直在用 PHP 做企业级项目那你大概率逃不过一个需求给甲方或者运营团队搭一套后台。我前年接了一个电商 ERP 改造项目后台光菜单就七八十个表单、列表、权限、操作日志、数据导出全都要。一开始我想着手写结果写了两个星期一个「商品管理」模块都还没磨完每天净在做重复的 CRUD。后来我换了 dcat-admin把所有模块重新过了一遍从数据表到能登录操作前后不到一个月而且稳定跑了一年多没出大毛病。今天就把这套框架的实战玩法拆开讲清楚从安装到权限、从列表到表单、再到各种坑的排查帮你少走弯路。这篇文章适合正在用 Laravel、又不想在后台开发上反复造轮子的朋友。不管你是刚接触后台框架的新手还是已经在用 laravel-admin、想迁移过来的老手这篇文章都会给你一些可以直接「抄作业」的方案。下面所有内容和命令我都基于实际项目验证过版本以 dcat-admin 2.x 为例PHP 环境为 7.4 以上。1. 为什么我对 dcat-admin 情有独钟先说说我为什么从一堆后台框架里选了它。当年市面上的选择其实不少自研的、laravel-admin、Nova、还有各种基于 Vue 的后台模板。挑来挑去最终还是 dcat-admin 最符合我的实际开发习惯。1.1 不只是 laravel-admin 的「升级版」很多人一听 dcat-admin第一反应是「这不就是 laravel-admin 的 fork 吗」。这话对了一半。它确实是 fork 出来的但它不仅换了 PHP 7 的语法而且把底层架构和前端交互都重写了一遍。最直观的感受是以前在 laravel-admin 里写复杂表单要绕不少弯子在 dcat-admin 里用 PHP 的typed property、closure、匿名类这些东西写起来非常顺手。再一个它的前端从原来的 AdminLTE 换成了 Element UI弹窗、表单校验、表格操作这些交互明显更现代化。我用 Element UI 本身就很熟所以定制起来几乎没有学习成本。它把前端常用的组件都用 PHP 类包了一层比如Text、Select、DateTime、Image你不需要直接写 Vue 代码但又能拿到 Vue 组件的灵活性这一点我很喜欢。1.2 和手写后台相比省下的是时间和坑有一说一手写后台不是不行但你要面对的是权限系统得自己设计做浅了不管用做深了工作量爆炸。菜单管理、路由、面包屑、标签页这些 UI 层面的东西样式调起来极其费时间。表单的增删改查、列表的搜索筛选、批量删除、导出这些逻辑代码每写一个模块就要重复一遍。dcat-admin 把这些全部收编成「约定优于配置」的形式。你只需要定义一个资源控制器里的grid()、form()、show()方法就可以拿到一整套完整可用的后台交互。我实际算过一笔账以前手写一个带权限和操作日志的模块至少要 2 到 3 天用 dcat-admin 一个下午能出两个模块而且代码量少一半以上。这里补一个对比表方便你根据自己团队情况选型对比维度手写后台laravel-admindcat-admin开发速度慢重复代码多快快且 PHP 7 更顺手前端交互自己写或套模板AdminLTE偏传统Element UI现代简洁二次开发难度全在你手里要改前端模板PHP 类封装完善上手容易权限系统自己设计自带 RBAC自带 RBAC且更细腻适合团队有专门前端配合PHP 全栈为主PHP 全栈为主前端友好我是强烈建议如果你的团队没有专门的前端资源又要在 Laravel 上快速交付后台管理系统直接用 dcat-admin 是性价比非常高的选择。2. 安装部署半小时从零跑起来我第一次装 dcat-admin 的时候走了不少弯路所以这块我给你标注清楚每一步要注意的坑。这里默认你已经装好了 Laravel 项目版本建议 Laravel 8 及以上PHP 7.4 及以上。2.1 环境要求先把地基打好dcat-admin 对 PHP 扩展有要求除了 Laravel 本身需要的openssl、pdo、mbstring之外还要确认fileinfo扩展是开着的。很多主机商的 PHP 默认不开fileinfo你装依赖的时候会报一下很奇怪的错误比如提示finfo_open()未定义其实都是这个扩展没开。另外PHP 的memory_limit建议设置到 512M 以上。这个在本地开发还好在线上用composer装依赖的时候经常因为有大量依赖包解析内存一不够就直接失败了。我遇到过好几次后来直接在php.ini里把memory_limit调到1G世界就清净了。数据库方面MySQL 5.7 以上或者 MariaDB 10.2 以上都行。dcat-admin 的迁移文件里用了一些json类型的字段所以数据库版本太低会不支持。我建议你本地直接用 MySQL 8.0线上也尽量保持同一版本避免开发和线上环境不一致。2.2 安装步骤跟着敲就行确定环境没问题后安装过程就很标准了composer require dcat/laravel-admin如果这一步因为网络原因失败可以把 Composer 镜像切到阿里云或腾讯云的源这里不展开讲。装完以后先发布资源文件和配置文件php artisan admin:publish接着执行安装命令php artisan admin:install这一步会做几件事生成配置文件config/admin.php、创建admin_users、admin_roles、admin_permissions、admin_menu等数据表还会写入一个默认管理员账号。默认账号密码是admin / admin第一次登录进去一定要改不然就是裸奔状态。最后启动本地服务php artisan serve访问http://127.0.0.1:8000/admin看到登录页就说明装好了。2.3 目录结构理解它你才能驾驭它装完以后你会在项目里看到几个关键的目录和文件理清它们的作用非常重要config/admin.php后台的所有核心配置比如路由前缀、皮肤、语言、上传驱动等。app/Admin/Controllers存放后台控制器每个资源模块对应一个控制器。app/Admin/routes.php后台路由文件所有的后台路由都在这里注册。database/migrationsdcat-admin 自带的迁移文件里面是后台基础表的表结构。我第一次用的时候没搞懂routes.php的作用直接在web.php里写后台路由结果后台的登录、权限过滤全都失效了排查半天才发现问题。所以提醒大家后台相关路由统一写在app/Admin/routes.php里因为这个文件已经被 dcat-admin 打包好了中间件和命名空间。3. 核心使用资源控制器是灵魂安装只是热身真正的核心是资源控制器。你在 dcat-admin 里做的所有模块本质都是「定义一个资源控制器」然后实现列表、表单、详情这几个方法。3.1 生成第一个资源以商品模块为例假设我有一张products表我需要给它做一个后台管理模块命令行敲一行就生成控制器php artisan admin:make ProductController --modelApp\Models\Product生成的文件在app/Admin/Controllers/ProductController.php。打开以后你会发现里面预定义了grid()、form()、show()三个方法分别对应列表页、新增/编辑页、详情页。然后在app/Admin/routes.php里注册路由$router-resource(auth/products, ProductController::class);这里前缀auth不是必须你可以改成你的业务分组比如shop/products。但要注意路由前缀一变菜单里的链接也要对应调整。访问/admin/auth/products一个能增删改查的页面就出来了。当然默认的长相比较朴素需要你根据业务去填充表单字段和列表字段。3.2 表单构建器字段类型与常用属性form()方法是我花时间最多的地方因为它决定了后台录入体验。dcat-admin 的表单字段非常多我常用的几个给你列一下protected function form() { return Form::make(new Product(), function (Form $form) { $form-display(id, ID); $form-text(name, 商品名称)-required(); $form-select(category_id, 分类)-options(Category::all()-pluck(name, id)); $form-decimal(price, 售价)-min(0)-step(0.01); $form-image(cover, 封面图)-disk(public)-uniqueName(); $form-switch(status, 上架状态)-default(1); $form-number(stock, 库存)-min(0); $form-datetime(publish_at, 上架时间); $form-textarea(description, 商品简介); }); }说几个关键细节uniqueName()会自动生成随机文件名避免上传图片重名覆盖。这个一定要加不然两个人传了同名图片后传的会把先传的顶掉。-required()只做前端校验后端不会强制校验。如果你想在服务端也校验需要自己在saving事件或者 Form 的saving()回调里加逻辑。我一开始以为前端必填就够了后来测试时直接用接口绕过页面提交空数据照样进了表后来才补上后端校验。select的options支持传集合数组也可以传一个闭包适合大数据量时做异步搜索。表单还有一个非常实用的能力saving回调。比如商品表里有一个status字段我并不是真的想存开关值而是想根据某些条件自动计算就可以这样写$form-saving(function (Form $form) { $form-status $form-stock 0 ? 1 : 0; });这个机制让我在做业务逻辑判断的时候根本不需要去动控制器里的store和update方法非常省事。3.3 列表筛选与数据展示把grid()用出花来列表页是运营每天盯着看的体验非常重要。grid()方法最大的优势是通过链式调用快速实现列显示、排序、筛选、搜索、行操作。以下是我通常的写法protected function grid() { return Grid::make(Product::with(category), function (Grid $grid) { $grid-column(id, ID)-sortable(); $grid-column(name, 商品名称)-copyable(); $grid-column(category.name, 分类); $grid-column(price, 售价)-sortable()-display(function ($price) { return ¥ . number_format($price, 2); }); $grid-column(cover, 封面)-image(, 60, 60); $grid-column(stock, 库存)-editable(); $grid-column(status, 状态)-switch(); $grid-column(created_at, 创建时间)-sortable(); $grid-filter(function (Grid\Filter $filter) { $filter-like(name, 商品名称); $filter-equal(category_id, 分类)-select(Category::all()-pluck(name, id)); $filter-between(created_at, 创建时间)-datetime(); }); $grid-actions(function (Grid\Displayers\Actions $actions) { $actions-disableView(); $actions-disableEdit(); }); $grid-tools(function (Grid\Tools $tools) { $tools-append(new \App\Admin\Actions\ProductExport()); }); }); }我挑几个重点说一下-copyable()点击列名就能复制内容对复制订单号、商品编码这种场景非常方便。-editable()表格行内直接改库存运营不用点进编辑页实测下来使用频率很高。-switch()行内开关改状态运维和运营都很喜欢。filter里面的like、equal、between是最常用的三类筛选。搜索栏会自动生成不用手写查询条件。display闭包是最灵活的地方。比如价格我想统一格式化直接用display()对当前列做加工如果想显示关联表数据$grid-column(category.name)会自动根据模型关联关系读取。这个小细节让我省了大量 join 查询。4. 权限与菜单RBAC 实战光能增删改查还不行一个真正能交付的系统必须有权限控制。dcat-admin 自带了 RBAC基于角色的访问控制把用户、角色、权限、菜单四张表打通了。4.1 角色与权限的配置流程逻辑非常简单创建角色给角色绑定权限再把用户分到对应角色下。实际项目里我一般是配合菜单一起做在「权限管理」里新建权限名称比如product.view对应的路由就是/auth/products*。在「角色管理」里新建角色「商品运营」然后把product.view、product.edit等权限勾上。在「用户管理」里把运营的账号分配给「商品运营」角色。这套流程在界面上点一点就能完成不需要写代码。但如果你的权限控制需要更细比如「只能看自己创建的商品」那光靠 RBAC 就不够了你要在grid()的查询回调里加数据权限$grid-model()-where(admin_user_id, auth(admin)-id());这一步是很多新手忽略的。RBAC 只能控制「能不能访问这个路由」不能控制「能看到哪些数据行」。数据行级别的权限需要结合业务去写在grid的 model 查询里我自己的经验是需求里出现「某角色只能看某部分数据」的次数非常多所以这个技巧越早掌握越好。4.2 菜单管理与路由绑定菜单在 dcat-admin 里也是一张表通过「菜单管理」界面维护。新增菜单时URL 栏直接填我们前面定义的路由地址比如/auth/products。菜单还支持无限极分类你可以按照业务模块拆分组商品管理、订单管理、用户管理、系统设置等等。还有一个实用功能是「面包屑」和「标签页」。标签页默认开启顶部会保留打开过的菜单标签类似浏览器多标签的效果。运营在后台来回切换模块时这个体验非常关键。如果你不想展示某些菜单可以在菜单管理里设置显示状态或者对于一些只做权限承载的「虚拟菜单」把它的类型设为「目录」不绑定具体页面。权限绑定菜单的时候有个容易踩的坑如果你希望某个菜单只对特定角色可见不要在菜单表的「权限」字段里只选角色而是要去「角色管理」里把该菜单对应的权限勾上。否则说不清是菜单问题还是权限问题排查起来很费劲。我第一次搭的时候就是菜单和权限各搞了一套结果账号登录进去看不到入口找问题找了一个多小时。5. 扩展与自定义当基础功能不够用的时候dcat-admin 自带的功能覆盖 80% 的常规后台需求但真正拿得出手的系统往往要写一些业务定制功能。这时候就要用到它的扩展机制和自定义能力。5.1 表单踩坑多图上传、富文本、地图选点表单控件里我使用频率比较高但默认文档讲得不够细的几个多图上传如果字段是一个「轮播图组」可以用multipleImage()。它返回的是 JSON 数组如果你想在列表页把所有图展示出来要在grid里把 JSON 解析成图片数组再渲染。我一开始没处理结果列表页直接显示一串 JSON 字符串非常难看。富文本dcat-admin 并没有默认集成一个完整的富文本编辑器需要装扩展包。我用过laravel-admin-ext/quill适配过来的版本也试过直接嵌入wangEditor的务实建议如果只是商品详情、公告这类富文本用wangEditor足够如果是复杂的后台内容排版再考虑引入markdown编辑器。地图选点这个如果你的业务不涉及门店或配送用不上但做同城业务的时候非常刚需。dcat-admin 社区里有高德地图的扩展装好以后需要在配置里填入高德 key不然地图不显示。这种周边扩展的坑比较多一定要先看扩展文档再看后台配置项不要想当然。5.2 自定义页面与路由有些页面不依赖具体数据表比如数据看板、报表页面。这种我建议直接在app/Admin/routes.php里注册一个普通路由然后写一个普通的控制器方法返回视图$router-get(/dashboard, [DashboardController::class, index]);然后在DashboardController里渲染你自己写的 Blade 模板或者直接写 HTML。这功能看似简单但很多人不知道结果非要去硬套资源控制器把不存在的「数据表」建出来完全没必要。如果你需要做一些异步操作接口比如批量审核、批量发货也可以在资源控制器的路由文件里额外加一个 POST 路由$router-post(products/batch-audit, [ProductController::class, batchAudit]);这样既不影响原来的资源路由又能保证接口的权限和后台中间件一致。加完路由后别忘记去「权限管理」里把对应路由加进权限否则会出现「有入口但访问 403」的情况我之前因为这一步漏了被测试吐槽了好几次。6. 常见问题排查与避坑实录最后这部分我把自己和身边朋友踩过的坑按照「现象、原因、解决办法」整理成速查表另外再挑几个重点详细展开。6.1 高频问题速查表现象常见原因解决办法安装 admin:install 失败数据库版本太低或迁移权限不足检查 MySQL 版本、给账号授权后台登录后一直跳回登录页session 配置问题或APP_KEY不存在执行php artisan key:generate检查.env的 session 驱动列表筛选搜索无效字段名拼写错误或模型缺少对应字段先dd($grid-model()-toSql())查看 SQL上传图片失败存储目录不可写或 disk 配置错误检查storage/app/public权限执行php artisan storage:link扩展安装后白屏扩展未执行php artisan admin:publish按扩展文档发布静态资源和配置修改菜单后无变化后台缓存未刷新在「系统设置」里清理缓存或php artisan cache:clear自定义表单字段不生效使用了不存在的字段名或未在模型fillable中声明检查模型$fillable字段名拼写这里再说一下 session 的问题。dcat-admin 默认使用 Laravel 的 session 机制如果你之前为了方便用 JWT 或者 API token 那套思路处理后台登录容易水土不服。后台登录依赖 session因此不要把后台路由和 API 路由混在一套中间件里。我的做法是API 走api前缀和auth:api中间件后台走admin前缀和 dcat-admin 的中间件两者互不干扰。6.2 我踩过的三个深坑写在最后第一个坑是模型关联没加括号。我在grid里写$grid-column(category.name)但商品模型里的关联方法名写成了Category大小写对不上结果列表页直接报Call to undefined relationship。这个排查不难但非常容易忽略写列名时一定要严格对模型关联方法的大小写。第二个坑是权限路由的批量添加。某个模块可能需要十几个接口如果一个一个去「权限管理」里新增效率太低。后来我直接在config/admin.php里预先定义权限或者用数据库 seeder 把权限批量插进去速度提升很多。建议你从一开始就把权限初始化做进 seeder 里别走界面慢慢点。第三个坑是自定义操作按钮没有权限控制。我开发了一个「一键同步库存」的按钮挂在grid的tools里结果任何登录账号都能点。后来我才意识到tools 里的按钮默认不受路由权限管控需要手动在按钮类里加authorized()判断或者给按钮绑定权限 slug。这个小问题在交付前的安全评审里差点被打回幸好发现得早。6.3 使用 dcat-admin 后的工作流建议最后说说我现在的标准工作流也许能对你有点启发拿到一个新模块需求我一般按五步走先设计好数据库表模型写好fillable和关联关系。使用admin:make生成控制器注册路由在后台菜单里加上入口。在form()里把所有字段拖出来先不求美观保证能正确保存数据。在grid()里按业务筛选条件把列表做出来顺便调好列显示和排序。给关键操作加上权限和操作日志然后让运营同事试用。这个流程走顺了一个常见的业务模块从建表到交付基本上一天以内就能搞定。剩下的事情基本就集中在复杂的联动逻辑、特殊报表和运维优化上这些才是真正需要花时间的地方。我个人在实际操作中的体会是后台框架这种东西你越用到后面越会觉得它不只是「增删改查」的脚手架而是一个能帮你隔离复杂度、统一开发规范的平台。遇到官方功能不满足的场景最先做的应该是翻翻社区扩展和源码里的trait大部分情况都能找到借鉴的写法。如果确实需要魔改优先考虑写自定义类去继承扩展而不是直接改 vendor 里的文件不然 Composer 一更新你所有改动都白费了。最后再分享一个小技巧对于那种字段特别多的表我习惯在form()里用 Fieldset 布局把基本信息、价格库存、SEO 分成几个折叠面板。这样后台录入体验清爽很多运营同事也很满意。她原话是「以前找一个字段要滚半天现在点一下就能看到」。这种细节看着不起眼但对一个后台系统的日常使用体验影响是很大的。
返回列表