Fastadmin分类列表美化实战:3步搞定折叠功能+批量添加(附完整代码)
Fastadmin分类列表深度优化从折叠功能到批量添加的完整解决方案Fastadmin作为一款高效的PHP后台开发框架其默认分类列表视图在实际项目中往往需要根据业务需求进行定制化调整。本文将分享一套完整的优化方案通过三个核心步骤实现分类列表的折叠功能和批量添加功能显著提升后台管理效率。1. 理解Fastadmin分类列表的默认行为Fastadmin的默认分类列表视图采用平面化展示方式所有层级的分类项都直接呈现在同一列表中。这种设计虽然简单直接但在处理多层级分类结构时存在几个明显痛点层级关系不直观子分类与父分类之间仅通过缩进区分视觉辨识度低操作效率低下无法快速折叠/展开特定分支必须滚动浏览整个列表批量操作缺失添加多个同类目项时需要重复提交表单// 默认的表格初始化代码示例 table.bootstrapTable({ url: $.fn.bootstrapTable.defaults.extend.index_url, columns: [ [{field: id, title: ID}, {field: name, title: 名称}] ] });通过分析源码可以发现Fastadmin的分类列表主要依赖Bootstrap Table组件实现这为我们后续的扩展优化提供了良好的基础。2. 实现分类列表的折叠功能2.1 前端交互逻辑设计折叠功能的核心在于控制表格行的显示/隐藏状态。我们需要为每个有子项的父分类添加控制按钮并实现以下交互逻辑点击父分类名称或旁边的图标时切换其所有子项的可见状态不同层级的分类项应有明显的视觉区分无子项的分类应采用特殊样式标记// 在Controller.api.formatter中添加名称格式化方法 name: function(value, row, index) { let indent ; if(row.level 0) { indent nbsp;nbsp;.repeat(row.level * 2); } let className row.haschild ? has-child : no-child; return ${indent}a hrefjavascript:; classtoggle-btn ${className} >/* 层级缩进样式 */ .table tr[data-level1] td:first-child { padding-left: 20px; } .table tr[data-level2] td:first-child { padding-left: 40px; } /* 子项控制按钮样式 */ .btn-toggle { transition: all 0.3s ease; } .btn-toggle.collapsed i:before { content: \f078; /* FontAwesome下箭头 */ } .btn-toggle:not(.collapsed) i:before { content: \f077; /* FontAwesome上箭头 */ } /* 无子项分类的特殊样式 */ .text-muted { color: #999 !important; }2.3 完整的事件绑定与状态管理实现折叠功能的关键JavaScript代码需要处理以下场景初始化时隐藏所有子项可选点击切换按钮时更新相关行的显示状态保持展开/折叠状态的持久化可选// 在Controller的index方法中添加事件处理 $(document).on(click, .toggle-btn, function() { const rowId $(this).data(id); const $row $(this).closest(tr); const isHidden $row.hasClass(hidden-child); // 切换当前行的子项显示状态 $(tr[data-pid rowId ]).toggleClass(hidden, isHidden); $row.toggleClass(hidden-child, !isHidden); // 更新图标状态 $(this).find(i).toggleClass(fa-chevron-up, isHidden) .toggleClass(fa-chevron-down, !isHidden); });3. 批量添加功能的实现方案3.1 前端表单改造批量添加功能需要在原有添加表单基础上进行扩展添加多行文本输入区域提供格式提示和示例优化表单验证逻辑!-- 修改后的add.html表单部分 -- div classform-group label classcontrol-label col-sm-2分类名称:/label div classcol-sm-8 textarea classform-control namebatch_names rows5 placeholder每行输入一个分类名称#10;例如#10;电子产品#10;家用电器#10;数码配件/textarea div classhelp-block支持批量添加每行输入一个分类名称/div /div /div3.2 后端处理逻辑优化后端控制器需要改造以支持批量添加接收多行文本输入并解析过滤空行和重复项批量插入数据库// 在Category控制器中修改add方法 public function add() { if ($this-request-isPost()) { $params $this-request-post(); // 处理批量添加 if (!empty($params[batch_names])) { $names explode(\n, $params[batch_names]); $names array_map(trim, $names); $names array_filter($names); $successCount 0; foreach ($names as $name) { $data [ name $name, pid $params[pid] ?? 0, createtime time(), updatetime time() ]; if ($this-model-allowField(true)-save($data)) { $successCount; } } $this-success(成功添加.$successCount.个分类); } // 原有单条添加逻辑... } // 显示表单... }3.3 数据验证与错误处理为确保数据质量需要添加以下验证逻辑名称非空验证同级分类名称唯一性检查批量操作的事务支持// 增强的验证逻辑 foreach ($names as $name) { if (empty($name)) continue; $exists $this-model-where([ name $name, pid $params[pid] ?? 0 ])-count(); if ($exists) { continue; // 或记录错误信息 } // 保存逻辑... }4. 高级优化与扩展功能4.1 分类拖拽排序增强Fastadmin默认支持拖拽排序我们可以在此基础上进行优化限制只能在同层级内拖拽拖拽后自动刷新折叠状态添加动画效果提升用户体验// 增强拖拽排序处理 table.on(dragsort.bs.table, function(e, row, rows) { // 确保只允许同层级排序 if (row.pid ! rows[0].pid) { return false; } // 执行默认排序逻辑 Table.api.dragsort(table, row, rows, function(data) { // 排序完成后刷新表格但保持当前展开状态 var expanded $(.toggle-btn:not(.collapsed)).map(function() { return $(this).data(id); }).get(); table.bootstrapTable(refresh, { silent: true, query: function(p) { p.expanded expanded; return p; } }); }); });4.2 分类导入导出功能为方便数据迁移可以添加以下扩展功能Excel格式的批量导入当前分类树的导出功能导入模板下载// 导出功能示例 public function export() { $list $this-model-order(weigh DESC,id ASC)-select(); $spreadsheet new \PhpOffice\PhpSpreadsheet\Spreadsheet(); $sheet $spreadsheet-getActiveSheet(); // 设置表头 $sheet-setCellValue(A1, ID) -setCellValue(B1, 父级ID) -setCellValue(C1, 分类名称); // 填充数据 $row 2; foreach ($list as $item) { $sheet-setCellValue(A.$row, $item[id]) -setCellValue(B.$row, $item[pid]) -setCellValue(C.$row, $item[name]); $row; } // 输出Excel文件 header(Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet); header(Content-Disposition: attachment;filename分类导出.xlsx); $writer new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet); $writer-save(php://output); exit; }4.3 性能优化建议当分类数量较大时需要注意以下性能优化点实现懒加载子分类添加分页支持优化数据库查询// 懒加载示例 public function children() { $pid $this-request-get(pid/d, 0); $list $this-model-where(pid, $pid)-select(); return json([list $list]); }// 前端懒加载实现 $(document).on(click, .toggle-btn, function() { const $row $(this).closest(tr); const rowId $row.data(id); if ($row.hasClass(loaded)) { // 已加载则直接切换显示 $(tr[data-pid rowId ]).toggle(); } else { // 未加载则发起请求 $.get(category/children, {pid: rowId}, function(data) { // 插入子行并标记为已加载 $row.addClass(loaded); }); } });