feat(admin-dashboard): sync trend/billing card height with recent orders
This commit is contained in:
@@ -120,6 +120,71 @@
|
|||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// 仪表盘:卡片高度对齐(趋势/收费工作台 与 最近平台订单对齐)
|
||||||
|
// 说明:运营端希望两列的高度视觉一致,减少右侧“短一截”的割裂感。
|
||||||
|
// 策略:以“最近平台订单”卡片的实际高度作为基准,将同列的趋势/收费工作台设置为同样的 minHeight(仅增不减)。
|
||||||
|
(function () {
|
||||||
|
var root = qs('[data-page="admin.dashboard"]');
|
||||||
|
if (!root) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var recent = qs('[data-role="dashboard-card-recent-platform-orders"]', root);
|
||||||
|
var trend = qs('[data-role="dashboard-card-trend"]', root);
|
||||||
|
var billing = qs('[data-role="dashboard-card-billing-workbench"]', root);
|
||||||
|
|
||||||
|
if (!recent || (!trend && !billing)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sync() {
|
||||||
|
try {
|
||||||
|
var h = recent.getBoundingClientRect().height;
|
||||||
|
if (!h || h <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 仅增不减:避免小屏/内容变少时出现“强行撑高”的奇怪滚动体验。
|
||||||
|
[trend, billing].forEach(function (el) {
|
||||||
|
if (!el) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var cur = el.getBoundingClientRect().height;
|
||||||
|
if (!cur || cur <= 0) {
|
||||||
|
cur = 0;
|
||||||
|
}
|
||||||
|
if (cur < h) {
|
||||||
|
el.style.minHeight = Math.round(h) + 'px';
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 首次 + 下一帧(等待图片/字体/表格渲染稳定)
|
||||||
|
sync();
|
||||||
|
try {
|
||||||
|
window.requestAnimationFrame(sync);
|
||||||
|
window.setTimeout(sync, 60);
|
||||||
|
window.setTimeout(sync, 200);
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
// 监听 resize
|
||||||
|
try {
|
||||||
|
window.addEventListener('resize', function () {
|
||||||
|
// 清空后重新计算(避免从大到小的缩放残留)
|
||||||
|
if (trend) {
|
||||||
|
trend.style.minHeight = '';
|
||||||
|
}
|
||||||
|
if (billing) {
|
||||||
|
billing.style.minHeight = '';
|
||||||
|
}
|
||||||
|
sync();
|
||||||
|
});
|
||||||
|
} catch (e) {}
|
||||||
|
})();
|
||||||
|
|
||||||
// 仪表盘:迷你图表(趋势图渐进增强)
|
// 仪表盘:迷你图表(趋势图渐进增强)
|
||||||
// 说明:不引入图表库,避免构建链;用 div bar 方式渲染。
|
// 说明:不引入图表库,避免构建链;用 div bar 方式渲染。
|
||||||
(function () {
|
(function () {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="two-col mb-20" data-role="analysis-skeleton">
|
<div class="two-col mb-20" data-role="analysis-skeleton">
|
||||||
<div class="card">
|
<div class="card" data-role="dashboard-card-trend">
|
||||||
<h3 class="mt-0">趋势</h3>
|
<h3 class="mt-0">趋势</h3>
|
||||||
<div class="muted">近7天|平台订单(按天)</div>
|
<div class="muted">近7天|平台订单(按天)</div>
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="two-col mb-20">
|
<div class="two-col mb-20">
|
||||||
<div class="card" id="billing-workbench">
|
<div class="card" id="billing-workbench" data-role="dashboard-card-billing-workbench">
|
||||||
<h3 class="mt-0">收费工作台(快捷治理)</h3>
|
<h3 class="mt-0">收费工作台(快捷治理)</h3>
|
||||||
<div class="muted">聚焦收费闭环的日常治理入口:订单 → 订阅 → 套餐。</div>
|
<div class="muted">聚焦收费闭环的日常治理入口:订单 → 订阅 → 套餐。</div>
|
||||||
|
|
||||||
@@ -298,7 +298,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="two-col mb-20" data-role="analysis-skeleton-row2">
|
<div class="two-col mb-20" data-role="analysis-skeleton-row2">
|
||||||
<div class="card">
|
<div class="card" data-role="dashboard-card-recent-platform-orders">
|
||||||
<div class="flex-between">
|
<div class="flex-between">
|
||||||
<h3 class="mt-0">最近平台订单</h3>
|
<h3 class="mt-0">最近平台订单</h3>
|
||||||
@php
|
@php
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class AdminDashboardCardsHeightSyncRolesShouldRenderTest 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_dashboard_should_render_height_sync_roles(): void
|
||||||
|
{
|
||||||
|
$this->loginAsPlatformAdmin();
|
||||||
|
|
||||||
|
$res = $this->get('/admin');
|
||||||
|
$res->assertOk();
|
||||||
|
|
||||||
|
$html = (string) $res->getContent();
|
||||||
|
|
||||||
|
$this->assertStringContainsString('data-role="dashboard-card-trend"', $html);
|
||||||
|
$this->assertStringContainsString('data-role="dashboard-card-billing-workbench"', $html);
|
||||||
|
$this->assertStringContainsString('data-role="dashboard-card-recent-platform-orders"', $html);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class AdminJsDashboardCardsHeightSyncShouldUseRecentOrdersHeightTest extends TestCase
|
||||||
|
{
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
public function test_admin_js_should_include_dashboard_height_sync_selectors(): void
|
||||||
|
{
|
||||||
|
$js = (string) file_get_contents(public_path('js/admin.js'));
|
||||||
|
|
||||||
|
$this->assertStringContainsString('dashboard-card-recent-platform-orders', $js);
|
||||||
|
$this->assertStringContainsString('dashboard-card-trend', $js);
|
||||||
|
$this->assertStringContainsString('dashboard-card-billing-workbench', $js);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user