chore(admin-ui): add admin pagination template and styles
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Models\SystemConfig;
|
use App\Models\SystemConfig;
|
||||||
|
use Illuminate\Pagination\Paginator;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
@@ -21,6 +22,10 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
|
// Admin: unify pagination view for back-office pages.
|
||||||
|
// 说明:不改变业务逻辑,仅统一分页 HTML 结构与样式基线(Ant Design Pro-ish)。
|
||||||
|
Paginator::defaultView('pagination.admin');
|
||||||
|
|
||||||
// 从数据库 system_configs 自动注入可配置项到 config(),用于“总台可治理/可配置”的运营闭环。
|
// 从数据库 system_configs 自动注入可配置项到 config(),用于“总台可治理/可配置”的运营闭环。
|
||||||
//
|
//
|
||||||
// 安全阀:
|
// 安全阀:
|
||||||
|
|||||||
@@ -133,6 +133,75 @@
|
|||||||
padding:0;
|
padding:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 可复用:Pagination(中后台分页,参考 Ant Design Pro) */
|
||||||
|
.adm-pagination{
|
||||||
|
margin-top:16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.adm-pagination-inner{
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
justify-content:space-between;
|
||||||
|
gap:12px;
|
||||||
|
flex-wrap:wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.adm-page-list{
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
gap:6px;
|
||||||
|
flex-wrap:wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.adm-page-btn,
|
||||||
|
.adm-page-num,
|
||||||
|
.adm-page-ellipsis{
|
||||||
|
display:inline-flex;
|
||||||
|
align-items:center;
|
||||||
|
justify-content:center;
|
||||||
|
min-width:32px;
|
||||||
|
height:32px;
|
||||||
|
padding:0 10px;
|
||||||
|
border-radius:10px;
|
||||||
|
border:1px solid var(--adm-border-color, #e5e7eb);
|
||||||
|
background:var(--adm-bg-container, #ffffff);
|
||||||
|
color:var(--adm-text, #0f172a);
|
||||||
|
text-decoration:none;
|
||||||
|
box-shadow:var(--adm-shadow-sm, 0 1px 2px rgba(15, 23, 42, 0.06));
|
||||||
|
}
|
||||||
|
|
||||||
|
.adm-page-ellipsis{
|
||||||
|
border-color:transparent;
|
||||||
|
background:transparent;
|
||||||
|
box-shadow:none;
|
||||||
|
min-width:auto;
|
||||||
|
padding:0 6px;
|
||||||
|
color:var(--adm-text-muted, #94a3b8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.adm-page-num.is-active{
|
||||||
|
border-color:rgba(22, 119, 255, .45);
|
||||||
|
background:rgba(22, 119, 255, .08);
|
||||||
|
color:var(--adm-text, #0f172a);
|
||||||
|
font-weight:700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.adm-page-btn:hover,
|
||||||
|
.adm-page-num:hover{
|
||||||
|
text-decoration:none;
|
||||||
|
border-color:rgba(22, 119, 255, .35);
|
||||||
|
background:rgba(22, 119, 255, .06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.adm-page-btn.is-disabled{
|
||||||
|
opacity:.55;
|
||||||
|
cursor:not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.adm-page-meta{
|
||||||
|
margin-left:auto;
|
||||||
|
}
|
||||||
|
|
||||||
.list-card-header{
|
.list-card-header{
|
||||||
padding:14px 16px;
|
padding:14px 16px;
|
||||||
display:flex;
|
display:flex;
|
||||||
|
|||||||
@@ -312,5 +312,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pagination-wrap">{{ $plans->links() }}</div>
|
<div class="pagination-wrap">{{ $plans->links('pagination.admin') }}</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -1553,5 +1553,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pagination-wrap">{{ $orders->links() }}</div>
|
<div class="pagination-wrap">{{ $orders->links('pagination.admin') }}</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -414,5 +414,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pagination-wrap">{{ $subscriptions->links() }}</div>
|
<div class="pagination-wrap">{{ $subscriptions->links('pagination.admin') }}</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
44
resources/views/pagination/admin.blade.php
Normal file
44
resources/views/pagination/admin.blade.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
@if ($paginator->hasPages())
|
||||||
|
<nav role="navigation" aria-label="分页导航" class="adm-pagination">
|
||||||
|
<div class="adm-pagination-inner">
|
||||||
|
{{-- Previous Page Link --}}
|
||||||
|
@if ($paginator->onFirstPage())
|
||||||
|
<span class="adm-page-btn is-disabled" aria-disabled="true">上一页</span>
|
||||||
|
@else
|
||||||
|
<a class="adm-page-btn" href="{{ $paginator->previousPageUrl() }}" rel="prev">上一页</a>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
{{-- Pagination Elements --}}
|
||||||
|
<div class="adm-page-list">
|
||||||
|
@foreach ($elements as $element)
|
||||||
|
{{-- "Three Dots" Separator --}}
|
||||||
|
@if (is_string($element))
|
||||||
|
<span class="adm-page-ellipsis">{{ $element }}</span>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
{{-- Array Of Links --}}
|
||||||
|
@if (is_array($element))
|
||||||
|
@foreach ($element as $page => $url)
|
||||||
|
@if ($page == $paginator->currentPage())
|
||||||
|
<span class="adm-page-num is-active" aria-current="page">{{ $page }}</span>
|
||||||
|
@else
|
||||||
|
<a class="adm-page-num" href="{{ $url }}">{{ $page }}</a>
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Next Page Link --}}
|
||||||
|
@if ($paginator->hasMorePages())
|
||||||
|
<a class="adm-page-btn" href="{{ $paginator->nextPageUrl() }}" rel="next">下一页</a>
|
||||||
|
@else
|
||||||
|
<span class="adm-page-btn is-disabled" aria-disabled="true">下一页</span>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="adm-page-meta">
|
||||||
|
<span class="muted muted-xs">第 {{ $paginator->currentPage() }} / {{ $paginator->lastPage() }} 页</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
@endif
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class AdminPaginationViewShouldRenderWithAdminClassesTest extends TestCase
|
||||||
|
{
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
protected function loginAsPlatformAdmin(): void
|
||||||
|
{
|
||||||
|
$this->seed();
|
||||||
|
|
||||||
|
$this->post('/admin/login', [
|
||||||
|
'email' => 'platform.admin@demo.local',
|
||||||
|
'password' => 'Platform@123456',
|
||||||
|
])->assertRedirect('/admin');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_admin_pagination_view_should_render_with_admin_classes(): void
|
||||||
|
{
|
||||||
|
$this->loginAsPlatformAdmin();
|
||||||
|
|
||||||
|
// 构造一个简单的分页器,直接渲染 links(),避免依赖 seed 数据量。
|
||||||
|
$p = new \Illuminate\Pagination\LengthAwarePaginator(
|
||||||
|
collect([1, 2, 3, 4, 5, 6]),
|
||||||
|
6,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
['path' => '/admin/products']
|
||||||
|
);
|
||||||
|
|
||||||
|
$html = (string) $p->links();
|
||||||
|
|
||||||
|
// 护栏:自定义分页模板必须输出统一的 admin pagination class。
|
||||||
|
$this->assertStringContainsString('adm-pagination', $html);
|
||||||
|
$this->assertStringContainsString('adm-page-num', $html);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user