dcodegroup/laravel-dsg-table 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

dcodegroup/laravel-dsg-table

Composer 安装命令:

composer require dcodegroup/laravel-dsg-table

包简介

Convention-based data tables for DSG Table with a single API endpoint

README 文档

README

Convention-based data tables for Laravel, designed to work with dsg-vue tables.

Instead of creating a dedicated API controller for every table, this package gives you:

  • One endpoint that resolves table classes by name
  • Table classes that define authorisation, query logic, and column definitions
  • Column builders that output the field arrays expected by DsgTable
  • make:table to scaffold new tables quickly

Requirements

  • PHP 8.2+
  • Laravel 10, 11, 12, or 13

Installation

composer require dcodegroup/laravel-dsg-table

Publish the config file:

php artisan vendor:publish --tag=dsg-table-config

Quick start

1. Register the route

In your API routes file:

use Illuminate\Support\Facades\Route;

Route::dsgTable(
    name: 'api.dsg-table',
    middleware: ['api', 'auth:sanctum'],
);

This registers a single GET endpoint:

GET /dsg-table/{tableName}/{param?}

For example, GET /dsg-table/users resolves to App\Tables\UsersTable.

Alternatively, set route.auto_register to true in config and the package will register the route for you using the values in config/dsg-table.php.

2. Create a table class

php artisan make:table users

This creates app/Tables/UsersTable.php:

<?php

namespace App\Tables;

use App\Models\User;
use Dcodegroup\LaravelDsgTable\Columns\ActionsColumn;
use Dcodegroup\LaravelDsgTable\Columns\Column;
use Dcodegroup\LaravelDsgTable\Columns\SlotColumn;
use Dcodegroup\LaravelDsgTable\Contracts\TableInterface;
use Illuminate\Auth\Access\Response;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Gate;
use Spatie\QueryBuilder\AllowedFilter;
use Spatie\QueryBuilder\QueryBuilder;

class UsersTable implements TableInterface
{
    public function authorisation(mixed $arguments = null): Response|bool
    {
        return Gate::authorize('viewAny', User::class);
    }

    public function resourceCollection(mixed $param = null): AnonymousResourceCollection
    {
        $query = QueryBuilder::for(User::class)
            ->allowedFilters(['active', 'email'])
            ->allowedSorts(['full_name', 'email', 'updated_at'])
            ->defaultSort('-updated_at');

        return JsonResource::collection(
            $query->paginate(request('per_page', 15))
        );
    }

    public function fields(): Collection
    {
        return collect([
            SlotColumn::make('active', __('user.columns.status'))->toArray(),
            Column::make('full_name', __('user.columns.name'))->isSortable()->toArray(),
            Column::make('email', __('user.columns.email'))->isSortable()->toArray(),
            Column::make('updated_at', __('user.columns.updated_at'))->isSortable()->toArray(),
            ActionsColumn::make()->toArray(),
        ]);
    }
}

3. Pass fields to your frontend

In your page controller:

use Dcodegroup\LaravelDsgTable\Facades\DsgTable;

return inertia('Admin/Users/Index', [
    'fields' => DsgTable::fields('users'),
]);

Or in a Blade view:

<DsgTable
    :get-url="{{ json_encode(route('api.dsg-table', ['tableName' => 'users'])) }}"
    :fields='@json(DsgTable::fields("users"))'
/>

4. Render the table in Vue

<script setup>
import { DsgTable, DsgTablePerPage } from '@dsg/table';
</script>

<template>
  <DsgTable
    ref="dsgTableRef"
    :get-url="route('api.dsg-table', { tableName: 'users' })"
    :fields="fields"
    @dsg-table:action-edit="(event, data) => editUser(data)"
    @dsg-table:action-delete="(event, data) => deleteUser(data)"
  >
    <template #dsg-field--active="data">
      <!-- Custom slot for the "active" column -->
    </template>

    <template #dsg-table--footer-left-extras="slotProps">
      <DsgTablePerPage :per-page="slotProps.perPage" />
    </template>
  </DsgTable>
</template>

How table resolution works

Given a table name in the URL, the factory resolves a class using convention over configuration:

URL segment Config Resolved class
users namespace App\Tables, suffix Table App\Tables\UsersTable
account-users same App\Tables\AccountUsersTable

Table names use kebab-case in the URL and resolve to StudlyCase class names.

You can resolve a table manually anywhere in your app:

use Dcodegroup\LaravelDsgTable\Facades\DsgTable;

$table = DsgTable::get('users');
$fields = DsgTable::fields('users');
$data = $table->resourceCollection();

Table interface

Every table class must implement TableInterface:

Method Purpose
authorisation($arguments) Authorise the current user before returning data. Receives the optional {param} route segment.
resourceCollection($param) Build and return the paginated AnonymousResourceCollection for the table rows.
fields() Return a Collection of column definition arrays for the table header.

When a request hits the endpoint, the controller runs:

$table = DsgTable::get($tableName);
$table->authorisation($param);
return $table->resourceCollection($param);

Configuration

All options live in config/dsg-table.php.

Table class location

'tables_namespace' => 'App\\Tables',
'tables_path' => app_path('Tables'),
'class_suffix' => 'Table',

Point these at wherever you want table classes to live in your project. The namespace and path should match your PSR-4 autoloading setup.

Route defaults

'route' => [
    'auto_register' => false,
    'prefix' => 'dsg-table',
    'name' => 'dsg-table',
    'middleware' => ['api'],
    'param' => true,
],

When calling Route::dsgTable(), any argument you omit falls back to these config values.

Column CSS defaults

'columns' => [
    'data_class' => [
        'default' => 'px-3 py-4 text-sm text-gray-500 wrap-break-word',
        'slot' => 'px-3 py-4 text-sm text-gray-500 wrap-break-word',
        'actions' => 'actions',
    ],
],

Set any value to null to omit dataClass from the column output.

Columns

The package provides three column builders. Each returns an array via ->toArray() that matches the shape expected by DsgTable.

Column

Standard text/data columns.

Column::make('email')
    ->isSortable()
    ->width('200px')
    ->toArray();

Column::make('email', 'Email address', 'text-sm font-medium')
    ->isSortable(sortField: 'email')
    ->toArray();

Available methods:

Method Description
isSortable($sortable, $sortField) Add a sortField key for server-side sorting
dataClass($class) Set or replace the cell CSS class. Pass null to remove.
appendDataClass($class) Append a CSS class to the existing value
withoutDataClass() Remove dataClass from the output
width($width) Set column width
style($style) Set inline style
type($type) Set column type
overrideDisplay($field) Use a different field name for display

SlotColumn

Columns rendered via a Vue slot on DsgTable. The slot name follows the pattern dsg-field--{field}.

SlotColumn::make('active', __('user.columns.status'))->toArray();
<template #dsg-field--active="data">
  <DsgBadge :label="data.rowData.active.value" />
</template>

Uses the slot key from columns.data_class config by default.

ActionsColumn

The actions column, typically rendered by DsgTable with built-in view/edit/delete buttons.

ActionsColumn::make(
    title: '',
    width: '100px',
    dataClass: 'actions',
)->toArray();

Uses the actions key from columns.data_class config by default.

Optional route parameter

When route.param is enabled (the default), the endpoint accepts an optional third segment:

GET /dsg-table/account-users/42

This resolves to AccountUsersTable and passes 42 as $param to both authorisation() and resourceCollection(). Useful for scoped tables such as users belonging to a specific account.

Disable it when registering the route:

Route::dsgTable(withParam: false);

Scaffolding

Generate a new table class:

php artisan make:table users
php artisan make:table account-users

The command reads tables_namespace, tables_path, and class_suffix from config.

Custom stub

Publish the stub to customise the generated class:

php artisan vendor:publish --tag=dsg-table-stubs

This copies the stub to stubs/dsg-table.stub in your project root. The make:table command will use your published stub when it exists.

Extending the factory

The default TableFactory reads namespace and suffix from config. To customise resolution logic, bind your own factory in a service provider:

use Dcodegroup\LaravelDsgTable\Support\AbstractTableFactory;

$this->app->singleton(AbstractTableFactory::class, function () {
    return new class extends AbstractTableFactory
    {
        protected function tablesNamespace(): string
        {
            return 'App\\Support\\DataTables\\Tables';
        }

        protected function classSuffix(): string
        {
            return 'Vuetable';
        }
    };
});

The DsgTable facade and TableController will use your binding automatically.

License

MIT. See LICENSE for details.

统计信息

  • 总下载量: 2
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-16

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固