二、 数据表格
- 排序
// 排序 $grid->model()->orderBy('created_at', 'desc'); // FIELD排序 // 指定FIELD排序 $grid->model()->orderByRaw(DB::raw('FIELD(use_in, 1,0,2) asc')); // 指定顺序排序 DB::name('user')->orderByRaw(DB::raw('FIELD(use_in, 1,0,2) asc')); - 过滤
// 快速筛选样式 $filter->panel(); // 过滤设置宽度 $filter->equal('id')->width(1); // 过滤添加下拉 $filter->equal('hotel_id', '所属酒店')->select(Hotel::query()->pluck('name', 'id')->toArray())->width(3); // 过滤添加下拉使用(find_in_set) $ArticlesList = Articles::where('type', 1)->pluck('title', 'id')->toArray(); $filter->findInSet('aid')->select($ArticlesList); // 模糊匹配 $filter->like('name')->width(2); // 省市区联动 $filter->distpicker('hotel.province_id', 'hotel.city_id', 'hotel.district_id', '地域选择')->width(4); // 过滤添加快捷筛选 $filter->scope('today', '今日')->whereDate('pay_date', today()); $filter->scope('yesterday', '昨日')->whereDate('pay_date', today()->subDay()); $filter->scope('this_week', '本周')->whereBetween('pay_date', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()]); $filter->between('pay_date', '日期')->date()->width(3); // 过滤添加单选框 $filter->equal('status')->radio([1 => '正常', 2 => '禁用']); // 指定角色的管理员 $adminList = Administrator::query() ->whereHas('roles', function ($query) { // whereHas 筛选「关联了 role_id=3 角色」的管理员 $query->where('role_id', 3); }) ->pluck('name', 'id') ->toArray(); $filter->equal('admin_id')->select($adminList)->width(2); // select筛选 $filter ->where('warehouse_id', function ($query) { /** @var ProductModel $this */ if ($this->input === '') { // 选全部,不做筛选 return; } else { // 是:查warehouse_id≠0的所有值 $query->where('warehouse_id', '!=', 0); } }, '是否平台产品') ->select([ // 可选:添加全部选项,提升用户体验 '' => '全部', 1 => '是' ]) ->width(2); - 表头
// 左右滚动条 $grid->scrollbarX(); // 每页默认条数 $grid->paginate(10); // 禁用创建按钮 $grid->disableCreateButton(); // 启用弹窗创建 $grid->enableDialogCreate(); // 禁用编辑按钮 $grid->disableEditButton(); // 显示快速编辑按钮 $grid->showQuickEditButton(); // 禁用删除按钮 $grid->disableDeleteButton(); // 禁用详情按钮 $grid->disableViewButton(); // 禁用批量操作选项 $grid->disableBatchActions(); // 禁用快速删除选项 $grid->disableQuickDeleteButton(); // 禁用快速删除选项 $grid->disableQuickEditButton(); // 禁用行选择器 $grid->disableRowSelector(); // 禁用列选择器 $grid->disableColumnSelector(); // 指定表格操作列样式 $grid->setActionClass(Grid\Displayers\Actions::class); // 开启字段选择器功能 $grid->showColumnSelector(); // 设置默认隐藏字段 $grid->hideColumns(['field1', ...]); // 过滤条件 $grid->model()->where('type', 1); // 默认分页数 $grid->paginate(perPage: 10); // 固定列 // 第二个参数可不传,默认为 - 1 $grid->fixColumns(固定从头开始的列数, 固定从后往前数的列数); // 自定义工具栏添加按钮 $grid->tools(function (Grid\Tools $tools) { $tools->append(Modal::make() // 大号弹窗 ->lg() // 弹窗标题 ->title('追加订单') // 按钮 ->button('<button class="btn btn-primary"><i class="feather icon-plus"></i> 追加订单</button>') // 弹窗内容 ->body(HotelOrderAdd::make())); }); // 动态操作按钮 $grid->actions(function (Grid\Displayers\Actions $actions) { $actions->append(new IncreaseStock()); if (!Admin::user()->isAdministrator()) { /** @var ProductModel $this */ if(empty($this->warehouse_id)){ $actions->disableDelete(); $actions->disableEdit(); } } }); // 关联表 return Grid::make(Articles::with('categories'), function (Grid $grid) { …… }); // 导出 $grid->export()->filename('销售额统计'); - 字段
// 可排序 $grid->column('id')->sortable(); // 缩略图尺寸 $grid->column('image')->image('', 50, 50); // 字数限制 $grid->column('describe')->limit(100); // 标签话 $grid->column('tags')->label(); // 可编辑 $grid->column('views')->sortable()->editable(); // 可编辑单选框 $grid->column('status')->radio([1 => '正常', 2 => '禁用'])->sortable(); // 可编辑复选框 $grid->column('status')->checkbox([1 => '正常', 2 => '禁用'])->sortable(); // 可编辑下拉 $grid->column('status')->select([1 => '正常', 2 => '禁用'])->sortable(); // 可编辑开关 $grid->column('status')->switch()->sortable(); // 字段渲染 $grid->column('type')->using([1 => '新闻', 2 => '快讯', 3 => '专题']); // 字段动态显示 $grid->column('aid')->display(function ($value) { /** @var \App\Models\Read $this */ if ($this->type != 3) {// 文章或快讯 return \App\Models\Articles::where('id', $value)->value('title'); }else{// 专题 return \App\Models\Topic::where('id', $value)->value('title'); } }); // 复制字段内容 $grid->column('图片路径')->display(function(){ return <<<HTML <div class="input-group"> <input type="text" id="image-path-{$this->getKey()}" class="form-control " value="{$this->image_urls}" readonly> <button class="btn btn-success" type="button" onclick="copyImagePath('{$this->getKey()}')"> <i class="feather icon-copy"></i> </button> </div> <!-- 复制功能的 JS 脚本 --> <script> function copyImagePath(rowKey) { // 获取输入框元素 const input = document.getElementById('image-path-' + rowKey); // 选中内容并复制 input.select(); document.execCommand('copy'); // 提示复制成功(使用 Dcat Admin 内置的消息提示) Dcat.success('图片路径已复制到剪贴板!'); } </script> HTML; }) ->help('点击按钮可复制当前行的图片路径') ->width(200); // 列表异步加载弹窗数据表格简洁 use Dcat\Admin\Widgets\Table; $grid->column('aid') ->display('查看') // 设置按钮名称 ->modal(function ($modal) { $modal->title('新闻列表'); // 解决$this报错问题 /** @var \App\Models\Topic $this */ $freezerList = []; if (!empty($this->freezer_info)) { $freezerInfo = json_decode($this->freezer_info, true); foreach ($freezerInfo as $key => $item) { $freezerList[] = [ ($key+1), $item['code'], ]; } } return Table::make(['序号','编号'], $freezerList); }); // 列表异步加载弹窗数据表格 $grid->column('aid') ->display('查看') // 设置按钮名称 ->modal(function ($modal) { $modal->title('新闻列表'); // 允许在闭包内返回异步加载类的实例 return App\Admin\Renderable\Topic::make(['type' => 1, 'aid' => $this->aid]); }); // 列表异步加载下拉数据表格简洁 $grid->column('product_snapshot')->display('套餐商品') ->expand(function () { /** @var PackageOrderModel $this */ $titles = [ '序号', '商品ID', '商品名称', '商品图片', '商品单价', '商品数量', ]; $snapshotRaw = json_decode($this->product_snapshot, true) ?? []; $snapshot = []; foreach (array_values($snapshotRaw) as $index => $item) { $snapshot[] = [ $index + 1, // 序号从 1 开始 $item['product_id'] ?? '-', $item['name'] ?? '-', $item['photo'] ? '<img data-action="preview-img" src="'.$item['photo'].'" style="max-width:100px;max-height:100px;cursor:pointer" class="img img-thumbnail">' : '-', $item['unit_price'] ?? '-', $item['quantity'] ?? '-', ]; } return Table::make($titles, $snapshot) ?? '-'; }); // 列表异步加载下拉数据表格简洁 $grid->column('product_snapshot')->display('套餐商品') ->expand(function () { return App\Admin\Renderable\Topic::make(['type' => 1, 'aid' => $this->aid]); }); // App\Admin\Renderable\Topic.php <?php namespace App\Admin\Renderable; use App\Models\Articles; use Dcat\Admin\Support\LazyRenderable; use Dcat\Admin\Widgets\Table; class Topic extends LazyRenderable { public function render() { // 获取其他自定义参数 $type = $this->type; $aid = $this->aid; // 方式一 $data = Articles::whereIn('id', explode(',', $aid)) ->where('type', $type) ->select('id', 'title', 'published_at', 'created_at') ->get()->toArray(); // 方式二 $data = []; $res = Articles::whereIn('id', explode(',', $aid)) ->where('type', $type) ->get()->toArray(); foreach ($res as $k=>$v) { $data[] = [ $v['id'], $v['title'], $v['published_at'], $v['created_at'], ]; } $titles = [ 'ID', '标题', '发布时间', '创建时间']; return Table::make($titles, $data); } } // 剩余时间 $grid->column('last_time', '剩余时间')->display(function ($value) { // 1. 获取 end_time 的 Carbon 对象(Laravel 模型自动转换,无需手动处理) /** @var MushroomModel $this */ $endTime = $this->end_time; // 2. 空值处理:无结束时间返回占位符 if (empty($endTime)) { return '-'; } // 3. 确保是 Carbon 对象(兼容手动赋值的字符串时间) if (!($endTime instanceof Carbon)) { $endTime = Carbon::parse($endTime); } // 4. 判断是否已过期(Carbon 语义化方法) if ($endTime->isPast()) { return '<span style="color: #ff4d4f;">已过期</span>'; } // 5. 计算剩余时间(Carbon 便捷方法) $now = Carbon::now(); // 当前时间(自动适配时区) $diffDays = $endTime->diffInDays($now); // 剩余天数 $diffHours = $endTime->diffInHours($now) % 24; // 剩余小时(扣除天数后) $diffMinutes = $endTime->diffInMinutes($now) % 60; // 剩余分钟(扣除小时后) // $diffSeconds = $endTime->diffInSeconds($now) % 60; // 剩余秒数(可选) // 6. 拼接人性化剩余时间(只显示非零部分) $remainingTime = ''; if ($diffDays > 0) { $remainingTime .= $diffDays . '天'; } // if ($diffHours > 0) { // $remainingTime .= $diffHours . '时'; // } // if ($diffMinutes > 0) { // $remainingTime .= $diffMinutes . '分'; // } // 可选:显示秒数 // if ($diffSeconds > 0) { // $remainingTime .= $diffSeconds . '秒'; // } // 7. 绿色标注剩余时间 return '<span style="color: #52c41a;">剩余' . $remainingTime . '</span>'; });